From 3df0f8359c9e617657a3537441d61b6f32221bd6 Mon Sep 17 00:00:00 2001 From: Thibaut Mattio Date: Mon, 31 May 2021 16:14:17 +0200 Subject: [PATCH] Add preview web app --- .gitignore | 24 +- Makefile | 30 +- dune-project | 17 + ood-preview.opam | 36 + package-lock.json | 1079 +++++++++++++++++ package.json | 7 + preview/.ocamlformat | 18 + preview/.ocamlformat-ignore | 1 + preview/asset/dune | 16 + preview/asset/favicon.ico | Bin 0 -> 67646 bytes preview/asset/logo1.jpeg | Bin 0 -> 107566 bytes preview/asset/manifest.json | 15 + preview/asset/robots.txt | 2 + preview/bin/dune | 4 + preview/bin/server.ml | 3 + preview/bin/server.mli | 1 + preview/config/tailwind.config.js | 29 + preview/dune | 8 + preview/lib/ood_preview/dune | 30 + preview/lib/ood_preview/exn.ml | 1 + preview/lib/ood_preview/import.ml | 92 ++ preview/lib/ood_preview/ocamlorg.ml | 2 + preview/lib/ood_preview/paper.ml | 25 + preview/lib/ood_preview/success_story.ml | 51 + preview/lib/ood_preview_web/dune | 33 + .../ood_preview_web/handlers/page_handler.ml | 15 + preview/lib/ood_preview_web/navigation.ml | 26 + .../lib/ood_preview_web/ood_preview_web.ml | 11 + preview/lib/ood_preview_web/router.ml | 15 + preview/lib/ood_preview_web/templates/dune | 35 + .../templates/header_section_template.eml | 24 + .../templates/header_template.eml | 139 +++ .../templates/index_template.eml | 3 + .../templates/layout_template.eml | 21 + .../templates/papers_template.eml | 68 ++ .../templates/success_stories_template.eml | 21 + preview/script/watch.sh | 20 + preview/test/ood_preview_web/dune | 4 + .../test/ood_preview_web/page_handler_test.ml | 16 + 39 files changed, 1931 insertions(+), 11 deletions(-) create mode 100644 ood-preview.opam create mode 100644 package-lock.json create mode 100644 preview/.ocamlformat create mode 100644 preview/.ocamlformat-ignore create mode 100644 preview/asset/dune create mode 100644 preview/asset/favicon.ico create mode 100644 preview/asset/logo1.jpeg create mode 100644 preview/asset/manifest.json create mode 100644 preview/asset/robots.txt create mode 100644 preview/bin/dune create mode 100644 preview/bin/server.ml create mode 100644 preview/bin/server.mli create mode 100644 preview/config/tailwind.config.js create mode 100644 preview/dune create mode 100644 preview/lib/ood_preview/dune create mode 100644 preview/lib/ood_preview/exn.ml create mode 100644 preview/lib/ood_preview/import.ml create mode 100644 preview/lib/ood_preview/ocamlorg.ml create mode 100644 preview/lib/ood_preview/paper.ml create mode 100644 preview/lib/ood_preview/success_story.ml create mode 100644 preview/lib/ood_preview_web/dune create mode 100644 preview/lib/ood_preview_web/handlers/page_handler.ml create mode 100644 preview/lib/ood_preview_web/navigation.ml create mode 100644 preview/lib/ood_preview_web/ood_preview_web.ml create mode 100644 preview/lib/ood_preview_web/router.ml create mode 100644 preview/lib/ood_preview_web/templates/dune create mode 100644 preview/lib/ood_preview_web/templates/header_section_template.eml create mode 100644 preview/lib/ood_preview_web/templates/header_template.eml create mode 100644 preview/lib/ood_preview_web/templates/index_template.eml create mode 100644 preview/lib/ood_preview_web/templates/layout_template.eml create mode 100644 preview/lib/ood_preview_web/templates/papers_template.eml create mode 100644 preview/lib/ood_preview_web/templates/success_stories_template.eml create mode 100755 preview/script/watch.sh create mode 100644 preview/test/ood_preview_web/dune create mode 100644 preview/test/ood_preview_web/page_handler_test.ml diff --git a/.gitignore b/.gitignore index bdb234f..14fe699 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,24 @@ -_build -_opam +# Dune generated files +_build/ +*.install + +# Local OPAM switch +_opam/ + +# Merlin configuration files .merlin + +# Normal npm stuff +npm-debug.log +yarn-error.log +node_modules/ +.cache/ +dist/ +build/ + +# ReScript /lib/bs /lib/**/*.js -.vscode \ No newline at end of file + +# IDE related +.vscode* diff --git a/Makefile b/Makefile index 9a96851..6a8e9c9 100644 --- a/Makefile +++ b/Makefile @@ -7,24 +7,38 @@ $(eval $(ARGS):;@:) all: opam exec -- dune build --root . @install -.PHONY: dev -dev: ## Install development dependencies - opam switch create . --no-install -y +.PHONY: deps +deps: ## Install development dependencies + opam pin -n -y git@github.com:aantron/dream.git + opam pin -n -y git@github.com:tmattio/dream-cli.git + opam pin -n -y git@github.com:tmattio/dream-livereload.git opam install -y dune-release ocamlformat utop ocaml-lsp-server + npm install opam install --deps-only --with-test --with-doc -y . +.PHONY: create_switch +create_switch: + opam switch create . 4.10.2 --no-install + +.PHONY: switch +switch: create_switch deps ## Create an opam switch and install development dependencies + +.PHONY: lock +lock: ## Generate a lock file + opam lock -y . + .PHONY: build build: ## Build the project, including non installable libraries and executables opam exec -- dune build --root . -.PHONY: start -start: all ## Start the project - opam exec -- dune exec --root . src/bin/main.exe $(ARGS) - .PHONY: install install: all ## Install the packages on the system opam exec -- dune install --root . +.PHONY: preview +preview: all ## Run the produced executable + opam exec -- ./preview/script/watch.sh + .PHONY: test test: ## Run the unit tests opam exec -- dune runtest --root . @@ -43,7 +57,7 @@ servedoc: doc ## Open odoc documentation with default web browser .PHONY: fmt fmt: ## Format the codebase with ocamlformat - opam exec -- dune build --root . @fmt --auto-promote + opam exec -- dune build --root . --auto-promote @fmt .PHONY: watch watch: ## Watch for the filesystem and rebuild on every change diff --git a/dune-project b/dune-project index 83d8ec6..e7338c7 100644 --- a/dune-project +++ b/dune-project @@ -47,6 +47,23 @@ "The ood binary performs data linting, Netlify CMS configuration generation from types etc.") (depends lib-ood)) +(package + (name ood-preview) + (synopsis "Preview ood content") + (description "Preview ood content") + (depends + (ocaml + (>= 4.08.0)) + dune + crunch + dream + dream-cli + dream-livereload + yaml + omd + (alcotest :with-test) + (odoc :with-doc))) + (package (name netlify-cms) (synopsis "OCaml encoding of Netlify CMS Configuration Files") diff --git a/ood-preview.opam b/ood-preview.opam new file mode 100644 index 0000000..24e5875 --- /dev/null +++ b/ood-preview.opam @@ -0,0 +1,36 @@ +# This file is generated by dune, edit dune-project instead +opam-version: "2.0" +synopsis: "Preview ood content" +description: "Preview ood content" +maintainer: ["pf341@patricoferris.com"] +authors: ["Patrick Ferris"] +license: "ISC" +homepage: "https://github.com/patricoferris/ood" +bug-reports: "https://github.com/patricoferris/ood/issues" +depends: [ + "ocaml" {>= "4.08.0"} + "dune" {>= "2.8"} + "crunch" + "dream" + "dream-cli" + "dream-livereload" + "yaml" + "omd" + "alcotest" {with-test} + "odoc" {with-doc} +] +build: [ + ["dune" "subst"] {dev} + [ + "dune" + "build" + "-p" + name + "-j" + jobs + "@install" + "@runtest" {with-test} + "@doc" {with-doc} + ] +] +dev-repo: "git+https://github.com/patricoferris/ood.git" diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 0000000..8ff61c7 --- /dev/null +++ b/package-lock.json @@ -0,0 +1,1079 @@ +{ + "name": "ood", + "version": "0.0.0", + "lockfileVersion": 1, + "requires": true, + "dependencies": { + "@fullhuman/postcss-purgecss": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/@fullhuman/postcss-purgecss/-/postcss-purgecss-3.1.3.tgz", + "integrity": "sha512-kwOXw8fZ0Lt1QmeOOrd+o4Ibvp4UTEBFQbzvWldjlKv5n+G9sXfIPn1hh63IQIL8K8vbvv1oYMJiIUbuy9bGaA==", + "dev": true, + "requires": { + "purgecss": "^3.1.3" + } + }, + "@nodelib/fs.scandir": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.4.tgz", + "integrity": "sha512-33g3pMJk3bg5nXbL/+CY6I2eJDzZAni49PfJnL5fghPTggPvBd/pFNSgJsdAgWptuFu7qq/ERvOYFlhvsLTCKA==", + "dev": true, + "requires": { + "@nodelib/fs.stat": "2.0.4", + "run-parallel": "^1.1.9" + } + }, + "@nodelib/fs.stat": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.4.tgz", + "integrity": "sha512-IYlHJA0clt2+Vg7bccq+TzRdJvv19c2INqBSsoOLp1je7xjtr7J26+WXR72MCdvU9q1qTzIWDfhMf+DRvQJK4Q==", + "dev": true + }, + "@nodelib/fs.walk": { + "version": "1.2.6", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.6.tgz", + "integrity": "sha512-8Broas6vTtW4GIXTAHDoE32hnN2M5ykgCpWGbuXHQ15vEMqr23pB76e/GZcYsZCHALv50ktd24qhEyKr6wBtow==", + "dev": true, + "requires": { + "@nodelib/fs.scandir": "2.1.4", + "fastq": "^1.6.0" + } + }, + "@tailwindcss/aspect-ratio": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/@tailwindcss/aspect-ratio/-/aspect-ratio-0.2.1.tgz", + "integrity": "sha512-aDFi80aHQ3JM3symJ5iKU70lm151ugIGFCI0yRZGpyjgQSDS+Fbe93QwypC1tCEllQE8p0S7TUu20ih1b9IKLA==", + "dev": true + }, + "@tailwindcss/forms": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/@tailwindcss/forms/-/forms-0.3.2.tgz", + "integrity": "sha512-aj2/rJsGb2whAZ/BQWHWWQRSbhH0r/l1ozOByiv+ZNjBD84GMvb5dhAyfpeasFky+EJrAwX5eaqft8NQMZFWvA==", + "dev": true, + "requires": { + "mini-svg-data-uri": "^1.2.3" + } + }, + "@tailwindcss/typography": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/@tailwindcss/typography/-/typography-0.4.1.tgz", + "integrity": "sha512-ovPPLUhs7zAIJfr0y1dbGlyCuPhpuv/jpBoFgqAc658DWGGrOBWBMpAWLw2KlzbNeVk4YBJMzue1ekvIbdw6XA==", + "dev": true, + "requires": { + "lodash.castarray": "^4.4.0", + "lodash.isplainobject": "^4.0.6", + "lodash.merge": "^4.6.2", + "lodash.uniq": "^4.5.0" + } + }, + "acorn": { + "version": "7.4.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz", + "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==", + "dev": true + }, + "acorn-node": { + "version": "1.8.2", + "resolved": "https://registry.npmjs.org/acorn-node/-/acorn-node-1.8.2.tgz", + "integrity": "sha512-8mt+fslDufLYntIoPAaIMUe/lrbrehIiwmR3t2k9LljIzoigEPF27eLk2hy8zSGzmR/ogr7zbRKINMo1u0yh5A==", + "dev": true, + "requires": { + "acorn": "^7.0.0", + "acorn-walk": "^7.0.0", + "xtend": "^4.0.2" + } + }, + "acorn-walk": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-7.2.0.tgz", + "integrity": "sha512-OPdCF6GsMIP+Az+aWfAAOEt2/+iVDKE7oy6lJ098aoe59oAmK76qV6Gw60SbZ8jHuG2wH058GF4pLFbYamYrVA==", + "dev": true + }, + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "anymatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz", + "integrity": "sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==", + "dev": true, + "requires": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + } + }, + "at-least-node": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/at-least-node/-/at-least-node-1.0.0.tgz", + "integrity": "sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==", + "dev": true + }, + "autoprefixer": { + "version": "10.2.6", + "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.2.6.tgz", + "integrity": "sha512-8lChSmdU6dCNMCQopIf4Pe5kipkAGj/fvTMslCsih0uHpOrXOPUEVOmYMMqmw3cekQkSD7EhIeuYl5y0BLdKqg==", + "dev": true, + "requires": { + "browserslist": "^4.16.6", + "caniuse-lite": "^1.0.30001230", + "colorette": "^1.2.2", + "fraction.js": "^4.1.1", + "normalize-range": "^0.1.2", + "postcss-value-parser": "^4.1.0" + } + }, + "balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true + }, + "binary-extensions": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", + "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", + "dev": true + }, + "brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "braces": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "dev": true, + "requires": { + "fill-range": "^7.0.1" + } + }, + "browserslist": { + "version": "4.16.6", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.16.6.tgz", + "integrity": "sha512-Wspk/PqO+4W9qp5iUTJsa1B/QrYn1keNCcEP5OvP7WBwT4KaDly0uONYmC6Xa3Z5IqnUgS0KcgLYu1l74x0ZXQ==", + "dev": true, + "requires": { + "caniuse-lite": "^1.0.30001219", + "colorette": "^1.2.2", + "electron-to-chromium": "^1.3.723", + "escalade": "^3.1.1", + "node-releases": "^1.1.71" + } + }, + "bs-platform": { + "version": "9.0.2", + "resolved": "https://registry.npmjs.org/bs-platform/-/bs-platform-9.0.2.tgz", + "integrity": "sha512-Ye9JqJ4Oa7mcjjoOVRYI8Uc2Cf8N7jQLWDcdUplY7996d/YErSR7WitmV7XnSwr4EvdrbwjEsg1NxNjUQv3ChA==" + }, + "bytes": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.0.tgz", + "integrity": "sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg==", + "dev": true + }, + "camelcase-css": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/camelcase-css/-/camelcase-css-2.0.1.tgz", + "integrity": "sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA==", + "dev": true + }, + "caniuse-lite": { + "version": "1.0.30001231", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001231.tgz", + "integrity": "sha512-WAFFv31GgU4DiwNAy77qMo3nNyycEhH3ikcCVHvkQpPe/fO8Tb2aRYzss8kgyLQBm8mJ7OryW4X6Y4vsBCIqag==", + "dev": true + }, + "chalk": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz", + "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "chokidar": { + "version": "3.5.1", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.1.tgz", + "integrity": "sha512-9+s+Od+W0VJJzawDma/gvBNQqkTiqYTWLuZoyAsivsI4AaWTCzHG06/TMjsf1cYe9Cb97UCEhjz7HvnPk2p/tw==", + "dev": true, + "requires": { + "anymatch": "~3.1.1", + "braces": "~3.0.2", + "fsevents": "~2.3.1", + "glob-parent": "~5.1.0", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.5.0" + } + }, + "color": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/color/-/color-3.1.3.tgz", + "integrity": "sha512-xgXAcTHa2HeFCGLE9Xs/R82hujGtu9Jd9x4NW3T34+OMs7VoPsjwzRczKHvTAHeJwWFwX5j15+MgAppE8ztObQ==", + "dev": true, + "requires": { + "color-convert": "^1.9.1", + "color-string": "^1.5.4" + }, + "dependencies": { + "color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "requires": { + "color-name": "1.1.3" + } + }, + "color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", + "dev": true + } + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "color-string": { + "version": "1.5.5", + "resolved": "https://registry.npmjs.org/color-string/-/color-string-1.5.5.tgz", + "integrity": "sha512-jgIoum0OfQfq9Whcfc2z/VhCNcmQjWbey6qBX0vqt7YICflUmBCh9E9CiQD5GSJ+Uehixm3NUwHVhqUAWRivZg==", + "dev": true, + "requires": { + "color-name": "^1.0.0", + "simple-swizzle": "^0.2.2" + } + }, + "colorette": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/colorette/-/colorette-1.2.2.tgz", + "integrity": "sha512-MKGMzyfeuutC/ZJ1cba9NqcNpfeqMUcYmyF1ZFY6/Cn7CNSAKx6a+s48sqLqyAiZuaP2TcqMhoo+dlwFnVxT9w==", + "dev": true + }, + "commander": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/commander/-/commander-6.2.1.tgz", + "integrity": "sha512-U7VdrJFnJgo4xjrHpTzu0yrHPGImdsmD95ZlgYSEajAn2JKzDhDTPG9kBTefmObL2w/ngeZnilk+OV9CG3d7UA==", + "dev": true + }, + "concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", + "dev": true + }, + "css-unit-converter": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/css-unit-converter/-/css-unit-converter-1.1.2.tgz", + "integrity": "sha512-IiJwMC8rdZE0+xiEZHeru6YoONC4rfPMqGm2W85jMIbkFvv5nFTwJVFHam2eFrN6txmoUYFAFXiv8ICVeTO0MA==", + "dev": true + }, + "cssesc": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz", + "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==", + "dev": true + }, + "defined": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/defined/-/defined-1.0.0.tgz", + "integrity": "sha1-yY2bzvdWdBiOEQlpFRGZ45sfppM=", + "dev": true + }, + "detective": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/detective/-/detective-5.2.0.tgz", + "integrity": "sha512-6SsIx+nUUbuK0EthKjv0zrdnajCCXVYGmbYYiYjFVpzcjwEs/JMDZ8tPRG29J/HhN56t3GJp2cGSWDRjjot8Pg==", + "dev": true, + "requires": { + "acorn-node": "^1.6.1", + "defined": "^1.0.0", + "minimist": "^1.1.1" + } + }, + "didyoumean": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/didyoumean/-/didyoumean-1.2.1.tgz", + "integrity": "sha1-6S7f2tplN9SE1zwBcv0eugxJdv8=", + "dev": true + }, + "dlv": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/dlv/-/dlv-1.1.3.tgz", + "integrity": "sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA==", + "dev": true + }, + "electron-to-chromium": { + "version": "1.3.742", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.742.tgz", + "integrity": "sha512-ihL14knI9FikJmH2XUIDdZFWJxvr14rPSdOhJ7PpS27xbz8qmaRwCwyg/bmFwjWKmWK9QyamiCZVCvXm5CH//Q==", + "dev": true + }, + "escalade": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", + "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", + "dev": true + }, + "escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", + "dev": true + }, + "fast-glob": { + "version": "3.2.5", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.5.tgz", + "integrity": "sha512-2DtFcgT68wiTTiwZ2hNdJfcHNke9XOfnwmBRWXhmeKM8rF0TGwmC/Qto3S7RoZKp5cilZbxzO5iTNTQsJ+EeDg==", + "dev": true, + "requires": { + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.0", + "merge2": "^1.3.0", + "micromatch": "^4.0.2", + "picomatch": "^2.2.1" + } + }, + "fastq": { + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.11.0.tgz", + "integrity": "sha512-7Eczs8gIPDrVzT+EksYBcupqMyxSHXXrHOLRRxU2/DicV8789MRBRR8+Hc2uWzUupOs4YS4JzBmBxjjCVBxD/g==", + "dev": true, + "requires": { + "reusify": "^1.0.4" + } + }, + "fill-range": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "dev": true, + "requires": { + "to-regex-range": "^5.0.1" + } + }, + "fraction.js": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/fraction.js/-/fraction.js-4.1.1.tgz", + "integrity": "sha512-MHOhvvxHTfRFpF1geTK9czMIZ6xclsEor2wkIGYYq+PxcQqT7vStJqjhe6S1TenZrMZzo+wlqOufBDVepUEgPg==", + "dev": true + }, + "fs-extra": { + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz", + "integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==", + "dev": true, + "requires": { + "at-least-node": "^1.0.0", + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + } + }, + "fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", + "dev": true + }, + "fsevents": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", + "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", + "dev": true, + "optional": true + }, + "function-bind": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", + "dev": true + }, + "glob": { + "version": "7.1.7", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.7.tgz", + "integrity": "sha512-OvD9ENzPLbegENnYP5UUfJIirTg4+XwMWGaQfQTY0JenxNvvIKP3U3/tAQSPIu/lHxXYSZmpXlUHeqAIdKzBLQ==", + "dev": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "glob-base": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/glob-base/-/glob-base-0.3.0.tgz", + "integrity": "sha1-27Fk9iIbHAscz4Kuoyi0l98Oo8Q=", + "dev": true, + "requires": { + "glob-parent": "^2.0.0", + "is-glob": "^2.0.0" + }, + "dependencies": { + "glob-parent": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-2.0.0.tgz", + "integrity": "sha1-gTg9ctsFT8zPUzbaqQLxgvbtuyg=", + "dev": true, + "requires": { + "is-glob": "^2.0.0" + } + }, + "is-extglob": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-1.0.0.tgz", + "integrity": "sha1-rEaBd8SUNAWgkvyPKXYMb/xiBsA=", + "dev": true + }, + "is-glob": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-2.0.1.tgz", + "integrity": "sha1-0Jb5JqPe1WAPP9/ZEZjLCIjC2GM=", + "dev": true, + "requires": { + "is-extglob": "^1.0.0" + } + } + } + }, + "glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "requires": { + "is-glob": "^4.0.1" + } + }, + "graceful-fs": { + "version": "4.2.6", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.6.tgz", + "integrity": "sha512-nTnJ528pbqxYanhpDYsi4Rd8MAeaBA67+RZ10CM1m3bTAVFEDcd5AuA4a6W5YkGZ1iNXHzZz8T6TBKLeBuNriQ==", + "dev": true + }, + "has": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", + "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", + "dev": true, + "requires": { + "function-bind": "^1.1.1" + } + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, + "html-tags": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/html-tags/-/html-tags-3.1.0.tgz", + "integrity": "sha512-1qYz89hW3lFDEazhjW0yVAV87lw8lVkrJocr72XmBkMKsoSVJCQx3W8BXsC7hO2qAt8BoVjYjtAcZ9perqGnNg==", + "dev": true + }, + "inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "dev": true, + "requires": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "dev": true + }, + "is-arrayish": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.3.2.tgz", + "integrity": "sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ==", + "dev": true + }, + "is-binary-path": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "dev": true, + "requires": { + "binary-extensions": "^2.0.0" + } + }, + "is-core-module": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.4.0.tgz", + "integrity": "sha512-6A2fkfq1rfeQZjxrZJGerpLCTHRNEBiSgnu0+obeJpEPZRUooHgsizvzv0ZjJwOz3iWIHdJtVWJ/tmPr3D21/A==", + "dev": true, + "requires": { + "has": "^1.0.3" + } + }, + "is-dotfile": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/is-dotfile/-/is-dotfile-1.0.3.tgz", + "integrity": "sha1-pqLzL/0t+wT1yiXs0Pa4PPeYoeE=", + "dev": true + }, + "is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", + "dev": true + }, + "is-glob": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz", + "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==", + "dev": true, + "requires": { + "is-extglob": "^2.1.1" + } + }, + "is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true + }, + "jsonfile": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", + "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", + "dev": true, + "requires": { + "graceful-fs": "^4.1.6", + "universalify": "^2.0.0" + } + }, + "lodash": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", + "dev": true + }, + "lodash.castarray": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/lodash.castarray/-/lodash.castarray-4.4.0.tgz", + "integrity": "sha1-wCUTUV4wna3dTCTGDP3c9ZdtkRU=", + "dev": true + }, + "lodash.isplainobject": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz", + "integrity": "sha1-fFJqUtibRcRcxpC4gWO+BJf1UMs=", + "dev": true + }, + "lodash.merge": { + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", + "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", + "dev": true + }, + "lodash.toarray": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/lodash.toarray/-/lodash.toarray-4.4.0.tgz", + "integrity": "sha1-JMS/zWsvuji/0FlNsRedjptlZWE=", + "dev": true + }, + "lodash.topath": { + "version": "4.5.2", + "resolved": "https://registry.npmjs.org/lodash.topath/-/lodash.topath-4.5.2.tgz", + "integrity": "sha1-NhY1Hzu6YZlKCTGYlmC9AyVP0Ak=", + "dev": true + }, + "lodash.uniq": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.uniq/-/lodash.uniq-4.5.0.tgz", + "integrity": "sha1-0CJTc662Uq3BvILklFM5qEJ1R3M=", + "dev": true + }, + "merge2": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", + "dev": true + }, + "micromatch": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.4.tgz", + "integrity": "sha512-pRmzw/XUcwXGpD9aI9q/0XOwLNygjETJ8y0ao0wdqprrzDa4YnxLcz7fQRZr8voh8V10kGhABbNcHVk5wHgWwg==", + "dev": true, + "requires": { + "braces": "^3.0.1", + "picomatch": "^2.2.3" + } + }, + "mini-svg-data-uri": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/mini-svg-data-uri/-/mini-svg-data-uri-1.3.3.tgz", + "integrity": "sha512-+fA2oRcR1dJI/7ITmeQJDrYWks0wodlOz0pAEhKYJ2IVc1z0AnwJUsKY2fzFmPAM3Jo9J0rBx8JAA9QQSJ5PuA==", + "dev": true + }, + "minimatch": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", + "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "dev": true, + "requires": { + "brace-expansion": "^1.1.7" + } + }, + "minimist": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", + "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", + "dev": true + }, + "modern-normalize": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/modern-normalize/-/modern-normalize-1.1.0.tgz", + "integrity": "sha512-2lMlY1Yc1+CUy0gw4H95uNN7vjbpoED7NNRSBHE25nWfLBdmMzFCsPshlzbxHz+gYMcBEUN8V4pU16prcdPSgA==", + "dev": true + }, + "nanoid": { + "version": "3.1.23", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.1.23.tgz", + "integrity": "sha512-FiB0kzdP0FFVGDKlRLEQ1BgDzU87dy5NnzjeW9YZNt+/c3+q82EQDUwniSAUxp/F0gFNI1ZhKU1FqYsMuqZVnw==", + "dev": true + }, + "node-emoji": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/node-emoji/-/node-emoji-1.10.0.tgz", + "integrity": "sha512-Yt3384If5H6BYGVHiHwTL+99OzJKHhgp82S8/dktEK73T26BazdgZ4JZh92xSVtGNJvz9UbXdNAc5hcrXV42vw==", + "dev": true, + "requires": { + "lodash.toarray": "^4.4.0" + } + }, + "node-releases": { + "version": "1.1.72", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.72.tgz", + "integrity": "sha512-LLUo+PpH3dU6XizX3iVoubUNheF/owjXCZZ5yACDxNnPtgFuludV1ZL3ayK1kVep42Rmm0+R9/Y60NQbZ2bifw==", + "dev": true + }, + "normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "dev": true + }, + "normalize-range": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/normalize-range/-/normalize-range-0.1.2.tgz", + "integrity": "sha1-LRDAa9/TEuqXd2laTShDlFa3WUI=", + "dev": true + }, + "object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", + "dev": true + }, + "object-hash": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/object-hash/-/object-hash-2.2.0.tgz", + "integrity": "sha512-gScRMn0bS5fH+IuwyIFgnh9zBdo4DV+6GhygmWM9HyNJSgS0hScp1f5vjtm7oIIOiT9trXrShAkLFSc2IqKNgw==", + "dev": true + }, + "once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "dev": true, + "requires": { + "wrappy": "1" + } + }, + "parse-glob": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/parse-glob/-/parse-glob-3.0.4.tgz", + "integrity": "sha1-ssN2z7EfNVE7rdFz7wu246OIORw=", + "dev": true, + "requires": { + "glob-base": "^0.3.0", + "is-dotfile": "^1.0.0", + "is-extglob": "^1.0.0", + "is-glob": "^2.0.0" + }, + "dependencies": { + "is-extglob": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-1.0.0.tgz", + "integrity": "sha1-rEaBd8SUNAWgkvyPKXYMb/xiBsA=", + "dev": true + }, + "is-glob": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-2.0.1.tgz", + "integrity": "sha1-0Jb5JqPe1WAPP9/ZEZjLCIjC2GM=", + "dev": true, + "requires": { + "is-extglob": "^1.0.0" + } + } + } + }, + "path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", + "dev": true + }, + "path-parse": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", + "dev": true + }, + "picomatch": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.0.tgz", + "integrity": "sha512-lY1Q/PiJGC2zOv/z391WOTD+Z02bCgsFfvxoXXf6h7kv9o+WmsmzYqrAwY63sNgOxE4xEdq0WyUnXfKeBrSvYw==", + "dev": true + }, + "postcss": { + "version": "8.3.0", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.3.0.tgz", + "integrity": "sha512-+ogXpdAjWGa+fdYY5BQ96V/6tAo+TdSSIMP5huJBIygdWwKtVoB5JWZ7yUd4xZ8r+8Kvvx4nyg/PQ071H4UtcQ==", + "dev": true, + "requires": { + "colorette": "^1.2.2", + "nanoid": "^3.1.23", + "source-map-js": "^0.6.2" + } + }, + "postcss-functions": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/postcss-functions/-/postcss-functions-3.0.0.tgz", + "integrity": "sha1-DpTQFERwCkgd4g3k1V+yZAVkJQ4=", + "dev": true, + "requires": { + "glob": "^7.1.2", + "object-assign": "^4.1.1", + "postcss": "^6.0.9", + "postcss-value-parser": "^3.3.0" + }, + "dependencies": { + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "requires": { + "color-convert": "^1.9.0" + } + }, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + }, + "color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "requires": { + "color-name": "1.1.3" + } + }, + "color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", + "dev": true + }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "dev": true + }, + "postcss": { + "version": "6.0.23", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.23.tgz", + "integrity": "sha512-soOk1h6J3VMTZtVeVpv15/Hpdl2cBLX3CAw4TAbkpTJiNPk9YP/zWcD1ND+xEtvyuuvKzbxliTOIyvkSeSJ6ag==", + "dev": true, + "requires": { + "chalk": "^2.4.1", + "source-map": "^0.6.1", + "supports-color": "^5.4.0" + } + }, + "postcss-value-parser": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", + "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==", + "dev": true + }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, + "postcss-js": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/postcss-js/-/postcss-js-3.0.3.tgz", + "integrity": "sha512-gWnoWQXKFw65Hk/mi2+WTQTHdPD5UJdDXZmX073EY/B3BWnYjO4F4t0VneTCnCGQ5E5GsCdMkzPaTXwl3r5dJw==", + "dev": true, + "requires": { + "camelcase-css": "^2.0.1", + "postcss": "^8.1.6" + } + }, + "postcss-nested": { + "version": "5.0.5", + "resolved": "https://registry.npmjs.org/postcss-nested/-/postcss-nested-5.0.5.tgz", + "integrity": "sha512-GSRXYz5bccobpTzLQZXOnSOfKl6TwVr5CyAQJUPub4nuRJSOECK5AqurxVgmtxP48p0Kc/ndY/YyS1yqldX0Ew==", + "dev": true, + "requires": { + "postcss-selector-parser": "^6.0.4" + } + }, + "postcss-selector-parser": { + "version": "6.0.6", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.6.tgz", + "integrity": "sha512-9LXrvaaX3+mcv5xkg5kFwqSzSH1JIObIx51PrndZwlmznwXRfxMddDvo9gve3gVR8ZTKgoFDdWkbRFmEhT4PMg==", + "dev": true, + "requires": { + "cssesc": "^3.0.0", + "util-deprecate": "^1.0.2" + } + }, + "postcss-value-parser": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.1.0.tgz", + "integrity": "sha512-97DXOFbQJhk71ne5/Mt6cOu6yxsSfM0QGQyl0L25Gca4yGWEGJaig7l7gbCX623VqTBNGLRLaVUCnNkcedlRSQ==", + "dev": true + }, + "pretty-hrtime": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/pretty-hrtime/-/pretty-hrtime-1.0.3.tgz", + "integrity": "sha1-t+PqQkNaTJsnWdmeDyAesZWALuE=", + "dev": true + }, + "purgecss": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/purgecss/-/purgecss-3.1.3.tgz", + "integrity": "sha512-hRSLN9mguJ2lzlIQtW4qmPS2kh6oMnA9RxdIYK8sz18QYqd6ePp4GNDl18oWHA1f2v2NEQIh51CO8s/E3YGckQ==", + "dev": true, + "requires": { + "commander": "^6.0.0", + "glob": "^7.0.0", + "postcss": "^8.2.1", + "postcss-selector-parser": "^6.0.2" + } + }, + "queue-microtask": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", + "dev": true + }, + "quick-lru": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-5.1.1.tgz", + "integrity": "sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA==", + "dev": true + }, + "readdirp": { + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.5.0.tgz", + "integrity": "sha512-cMhu7c/8rdhkHXWsY+osBhfSy0JikwpHK/5+imo+LpeasTF8ouErHrlYkwT0++njiyuDvc7OFY5T3ukvZ8qmFQ==", + "dev": true, + "requires": { + "picomatch": "^2.2.1" + } + }, + "reduce-css-calc": { + "version": "2.1.8", + "resolved": "https://registry.npmjs.org/reduce-css-calc/-/reduce-css-calc-2.1.8.tgz", + "integrity": "sha512-8liAVezDmUcH+tdzoEGrhfbGcP7nOV4NkGE3a74+qqvE7nt9i4sKLGBuZNOnpI4WiGksiNPklZxva80061QiPg==", + "dev": true, + "requires": { + "css-unit-converter": "^1.1.1", + "postcss-value-parser": "^3.3.0" + }, + "dependencies": { + "postcss-value-parser": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", + "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==", + "dev": true + } + } + }, + "resolve": { + "version": "1.20.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.20.0.tgz", + "integrity": "sha512-wENBPt4ySzg4ybFQW2TT1zMQucPK95HSh/nq2CFTZVOGut2+pQvSsgtda4d26YrYcr067wjbmzOG8byDPBX63A==", + "dev": true, + "requires": { + "is-core-module": "^2.2.0", + "path-parse": "^1.0.6" + } + }, + "reusify": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", + "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", + "dev": true + }, + "run-parallel": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", + "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", + "dev": true, + "requires": { + "queue-microtask": "^1.2.2" + } + }, + "simple-swizzle": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/simple-swizzle/-/simple-swizzle-0.2.2.tgz", + "integrity": "sha1-pNprY1/8zMoz9w0Xy5JZLeleVXo=", + "dev": true, + "requires": { + "is-arrayish": "^0.3.1" + } + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + }, + "source-map-js": { + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-0.6.2.tgz", + "integrity": "sha512-/3GptzWzu0+0MBQFrDKzw/DvvMTUORvgY6k6jd/VS6iCR4RDTKWH6v6WPwQoUO8667uQEf9Oe38DxAYWY5F/Ug==", + "dev": true + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + }, + "tailwindcss": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-2.1.2.tgz", + "integrity": "sha512-T5t+wwd+/hsOyRw2HJuFuv0LTUm3MUdHm2DJ94GPVgzqwPPFa9XxX0KlwLWupUuiOUj6uiKURCzYPHFcuPch/w==", + "dev": true, + "requires": { + "@fullhuman/postcss-purgecss": "^3.1.3", + "bytes": "^3.0.0", + "chalk": "^4.1.0", + "chokidar": "^3.5.1", + "color": "^3.1.3", + "detective": "^5.2.0", + "didyoumean": "^1.2.1", + "dlv": "^1.1.3", + "fast-glob": "^3.2.5", + "fs-extra": "^9.1.0", + "html-tags": "^3.1.0", + "lodash": "^4.17.21", + "lodash.topath": "^4.5.2", + "modern-normalize": "^1.0.0", + "node-emoji": "^1.8.1", + "normalize-path": "^3.0.0", + "object-hash": "^2.1.1", + "parse-glob": "^3.0.4", + "postcss-functions": "^3", + "postcss-js": "^3.0.3", + "postcss-nested": "5.0.5", + "postcss-selector-parser": "^6.0.4", + "postcss-value-parser": "^4.1.0", + "pretty-hrtime": "^1.0.3", + "quick-lru": "^5.1.1", + "reduce-css-calc": "^2.1.8", + "resolve": "^1.20.0" + } + }, + "to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, + "requires": { + "is-number": "^7.0.0" + } + }, + "universalify": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz", + "integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==", + "dev": true + }, + "util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=", + "dev": true + }, + "wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", + "dev": true + }, + "xtend": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", + "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", + "dev": true + } + } +} diff --git a/package.json b/package.json index b9a29e1..35e398b 100644 --- a/package.json +++ b/package.json @@ -13,5 +13,12 @@ }, "dependencies": { "bs-platform": "9.0.2" + }, + "devDependencies": { + "@tailwindcss/aspect-ratio": "^0.2.0", + "@tailwindcss/forms": "^0.3.2", + "@tailwindcss/typography": "^0.4.0", + "autoprefixer": "^10.2.5", + "tailwindcss": "^2.1.2" } } diff --git a/preview/.ocamlformat b/preview/.ocamlformat new file mode 100644 index 0000000..651c8fd --- /dev/null +++ b/preview/.ocamlformat @@ -0,0 +1,18 @@ +profile = sparse +break-cases = nested +break-fun-decl = smart +cases-exp-indent = 2 +if-then-else = fit-or-vertical +parens-tuple = multi-line-only +parens-tuple-patterns = multi-line-only +parens-ite = false +infix-precedence = parens +break-infix-before-func = false +sequence-style = terminator +sequence-blank-line = compact +indicate-multiline-delimiters = no +ocp-indent-compat = true +wrap-comments = true +parse-docstrings = true +let-binding-spacing = compact +type-decl = sparse \ No newline at end of file diff --git a/preview/.ocamlformat-ignore b/preview/.ocamlformat-ignore new file mode 100644 index 0000000..3d42877 --- /dev/null +++ b/preview/.ocamlformat-ignore @@ -0,0 +1 @@ +lib/ood_preview_web/templates/*.eml \ No newline at end of file diff --git a/preview/asset/dune b/preview/asset/dune new file mode 100644 index 0000000..8566e0a --- /dev/null +++ b/preview/asset/dune @@ -0,0 +1,16 @@ +(rule + (target main.css) + (deps + (:data ../config/tailwind.config.js) + (source_tree ../node_modules) + (source_tree ../lib/ood_preview_web/templates) + (env_var NODE_ENV)) + (action + (chdir + %{workspace_root} + ; We use node_modules/tailwindcss/lib/cli.js instead of `npx tailwindcss` + ; because dune won't include node_modules/.bin in the build, no matter + ; what I do. + (run node node_modules/tailwindcss/lib/cli.js build -c + preview/config/tailwind.config.js -o %{target})))) + diff --git a/preview/asset/favicon.ico b/preview/asset/favicon.ico new file mode 100644 index 0000000000000000000000000000000000000000..a856608038a6571cacdd6d1f987ebe0678daa939 GIT binary patch literal 67646 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 literal 0 HcmV?d00001 diff --git a/preview/asset/manifest.json b/preview/asset/manifest.json new file mode 100644 index 0000000..ddeb963 --- /dev/null +++ b/preview/asset/manifest.json @@ -0,0 +1,15 @@ +{ + "short_name": "Ood preview", + "name": "Ood preview", + "icons": [ + { + "src": "favicon.ico", + "sizes": "128x128 64x64 32x32 24x24 16x16", + "type": "image/x-icon" + } + ], + "start_url": "/", + "display": "standalone", + "theme_color": "#000000", + "background_color": "#ffffff" +} \ No newline at end of file diff --git a/preview/asset/robots.txt b/preview/asset/robots.txt new file mode 100644 index 0000000..f89c874 --- /dev/null +++ b/preview/asset/robots.txt @@ -0,0 +1,2 @@ +# https://www.robotstxt.org/robotstxt.html +User-agent: * \ No newline at end of file diff --git a/preview/bin/dune b/preview/bin/dune new file mode 100644 index 0000000..652d562 --- /dev/null +++ b/preview/bin/dune @@ -0,0 +1,4 @@ +(executable + (name server) + (modules server) + (libraries ood_preview_web)) diff --git a/preview/bin/server.ml b/preview/bin/server.ml new file mode 100644 index 0000000..2544b7b --- /dev/null +++ b/preview/bin/server.ml @@ -0,0 +1,3 @@ +(** Main entry point for our application. *) + +let () = Ood_preview_web.run () diff --git a/preview/bin/server.mli b/preview/bin/server.mli new file mode 100644 index 0000000..85f012e --- /dev/null +++ b/preview/bin/server.mli @@ -0,0 +1 @@ +(** Main entry point for our application. *) diff --git a/preview/config/tailwind.config.js b/preview/config/tailwind.config.js new file mode 100644 index 0000000..77c1dc3 --- /dev/null +++ b/preview/config/tailwind.config.js @@ -0,0 +1,29 @@ +const defaultTheme = require("tailwindcss/defaultTheme"); + +module.exports = { + mode: "jit", + purge: ["**/*.eml"], + darkMode: false, // or 'media' or 'class' + theme: { + extend: { + colors: { + 'ocamlorange': '#c15540', + graylight: '#f5f5f5', + orangedark: '#ed7109', + orangedarker: '#dd6705', + yellowdark: '#ffb800', + }, + fontFamily: { + sans: ["Inter var", ...defaultTheme.fontFamily.sans], + }, + }, + }, + variants: { + extend: {}, + }, + plugins: [ + require("@tailwindcss/forms"), + require("@tailwindcss/typography"), + require("@tailwindcss/aspect-ratio"), + ], +}; \ No newline at end of file diff --git a/preview/dune b/preview/dune new file mode 100644 index 0000000..e61a3dd --- /dev/null +++ b/preview/dune @@ -0,0 +1,8 @@ +(env + (dev + (flags + (:standard -w +A-48-42-44 -warn-error +A-3)))) + +; Do not include node_modules in the build + +(data_only_dirs node_modules) diff --git a/preview/lib/ood_preview/dune b/preview/lib/ood_preview/dune new file mode 100644 index 0000000..48d4bfc --- /dev/null +++ b/preview/lib/ood_preview/dune @@ -0,0 +1,30 @@ +(library + (name ood_preview) + (libraries ood omd yaml) + (preprocess + (pps ppx_deriving_yaml))) + +(rule + (targets data.ml) + (deps + (source_tree ../../../data/)) + (action + (with-stdout-to + %{null} + (run + %{bin:ocaml-crunch} + -e + md + -e + yml + -e + gif + -e + jpg + -e + png + -m + plain + ../../../data + -o + %{targets})))) diff --git a/preview/lib/ood_preview/exn.ml b/preview/lib/ood_preview/exn.ml new file mode 100644 index 0000000..14941af --- /dev/null +++ b/preview/lib/ood_preview/exn.ml @@ -0,0 +1 @@ +exception Decode_error of string diff --git a/preview/lib/ood_preview/import.ml b/preview/lib/ood_preview/import.ml new file mode 100644 index 0000000..78b1b1b --- /dev/null +++ b/preview/lib/ood_preview/import.ml @@ -0,0 +1,92 @@ +module Result = struct + include Stdlib.Result + + let both a b = + match a with + | Error e -> + Error e + | Ok a -> + (match b with Error e -> Error e | Ok b -> Ok (a, b)) + + module Syntax = struct + let ( >>= ) t f = bind t f + + let ( >>| ) t f = map f t + + let ( let* ) = ( >>= ) + + let ( let+ ) = ( >>| ) + + let ( and+ ) = both + end + + open Syntax + + module List = struct + let map f t = + let rec loop acc = function + | [] -> + Ok (List.rev acc) + | x :: xs -> + f x >>= fun x -> loop (x :: acc) xs + in + loop [] t + + let all = + let rec loop acc = function + | [] -> + Ok (List.rev acc) + | t :: l -> + t >>= fun x -> loop (x :: acc) l + in + fun l -> loop [] l + + let concat_map = + let rec loop f acc = function + | [] -> + Ok (List.rev acc) + | x :: l -> + f x >>= fun y -> loop f (List.rev_append y acc) l + in + fun l f -> loop f [] l + + let rec iter f t = + match t with [] -> Ok () | x :: xs -> f x >>= fun () -> iter f xs + + let rec fold_left f init t = + match t with + | [] -> + Ok init + | x :: xs -> + f init x >>= fun init -> fold_left f init xs + + let rec iter_left f t = + match t with [] -> Ok () | x :: xs -> f x >>= fun () -> iter_left f xs + + let filter_map t f = + fold_left + (fun acc x -> f x >>| function None -> acc | Some y -> y :: acc) + [] + t + >>| List.rev + end +end + +module String = struct + include Stdlib.String + + let lsplit2_exn on s = + let i = index s on in + sub s 0 i, sub s (i + 1) (length s - i - 1) + + let lsplit2 on s = try Some (lsplit2_exn s on) with Not_found -> None + + let prefix s len = try sub s 0 len with Invalid_argument _ -> "" + + let suffix s len = + try sub s (length s - len) len with Invalid_argument _ -> "" + + let drop_prefix s len = sub s len (length s - len) + + let drop_suffix s len = sub s 0 (length s - len) +end diff --git a/preview/lib/ood_preview/ocamlorg.ml b/preview/lib/ood_preview/ocamlorg.ml new file mode 100644 index 0000000..edffce4 --- /dev/null +++ b/preview/lib/ood_preview/ocamlorg.ml @@ -0,0 +1,2 @@ +module Paper = Paper +module Exn = Exn diff --git a/preview/lib/ood_preview/paper.ml b/preview/lib/ood_preview/paper.ml new file mode 100644 index 0000000..5ac3d68 --- /dev/null +++ b/preview/lib/ood_preview/paper.ml @@ -0,0 +1,25 @@ +type t = Ood.Papers.Paper.t = + { title : string + ; publication : string + ; authors : string list + ; abstract : string + ; tags : string list + ; year : int + ; links : string list + } +[@@deriving yaml] + +let decode_or_raise f x = + match f x with Ok x -> x | Error (`Msg err) -> raise (Exn.Decode_error err) + +let decode s = + let yaml = decode_or_raise Yaml.of_string s in + match yaml with + | `O [ ("papers", `A xs) ] -> + List.map (decode_or_raise of_yaml) xs + | _ -> + raise (Exn.Decode_error "expected a list of papers") + +let all () = + let content = Data.read "papers.yml" |> Option.get in + decode content diff --git a/preview/lib/ood_preview/success_story.ml b/preview/lib/ood_preview/success_story.ml new file mode 100644 index 0000000..9fb0664 --- /dev/null +++ b/preview/lib/ood_preview/success_story.ml @@ -0,0 +1,51 @@ +open Import + +type metadata = Ood.Success_story.t = + { title : string + ; image : string option + ; url : string option + } +[@@deriving yaml] + +type t = + { title : string + ; image : string option + ; url : string option + ; body : string + } + +let extract_metadata_body s = + match Str.split (Str.regexp "---") s with + | [ metadata; body ] -> + metadata, String.trim body + | _ -> + Logs.app (fun m -> m "%s" s); + raise (Exn.Decode_error "expected metadata at the top of the file") + +let decode_or_raise f x = + match f x with Ok x -> x | Error (`Msg err) -> raise (Exn.Decode_error err) + +let decode_metadata s = + let yaml = decode_or_raise Yaml.of_string s in + decode_or_raise metadata_of_yaml yaml + +let all () = + let contents = + Data.file_list + |> List.filter_map (fun x -> + if String.prefix x 18 = "success_stories/en" then + Data.read x + else + None) + in + List.map + (fun content -> + let metadata, body = extract_metadata_body content in + let metadata = decode_metadata metadata in + let body = Omd.of_string body |> Omd.to_html in + { title = metadata.title + ; image = metadata.image + ; url = metadata.url + ; body + }) + contents diff --git a/preview/lib/ood_preview_web/dune b/preview/lib/ood_preview_web/dune new file mode 100644 index 0000000..7400cfa --- /dev/null +++ b/preview/lib/ood_preview_web/dune @@ -0,0 +1,33 @@ +(library + (name ood_preview_web) + (libraries ood_preview dream dream-cli dream-livereload)) + +(rule + (targets asset.ml) + (deps + ../../asset/main.css + (source_tree ../../asset)) + (action + (with-stdout-to + %{null} + (run + %{bin:ocaml-crunch} + -e + ico + -e + jpeg + -e + js + -e + svg + -e + txt + -e + css + -m + plain + ../../asset + -o + %{targets})))) + +(include_subdirs unqualified) diff --git a/preview/lib/ood_preview_web/handlers/page_handler.ml b/preview/lib/ood_preview_web/handlers/page_handler.ml new file mode 100644 index 0000000..ba2a821 --- /dev/null +++ b/preview/lib/ood_preview_web/handlers/page_handler.ml @@ -0,0 +1,15 @@ +let index _req = + Layout_template.render ~title:"Welcome to Dream!" Index_template.render + |> Dream.html + +let papers _req = + let papers = Ood_preview.Paper.all () in + Layout_template.render ~title:"Papers" (Papers_template.render papers) + |> Dream.html + +let success_stories _req = + let success_stories = Ood_preview.Success_story.all () in + Layout_template.render + ~title:"Success Stories" + (Success_stories_template.render success_stories) + |> Dream.html diff --git a/preview/lib/ood_preview_web/navigation.ml b/preview/lib/ood_preview_web/navigation.ml new file mode 100644 index 0000000..9de0e5a --- /dev/null +++ b/preview/lib/ood_preview_web/navigation.ml @@ -0,0 +1,26 @@ +type menu_item = + { label : string + ; url : string + ; icon : string + ; text : string + } + +type menu = + { header : string + ; entries : menu_item list + } + +type t = menu list + +let t = + [ { header = "Content" + ; entries = + [ { label = "Papers Archive"; url = "/papers"; icon = ""; text = "" } + ; { label = "Success Stories" + ; url = "/success-stories" + ; icon = "" + ; text = "" + } + ] + } + ] diff --git a/preview/lib/ood_preview_web/ood_preview_web.ml b/preview/lib/ood_preview_web/ood_preview_web.ml new file mode 100644 index 0000000..601436b --- /dev/null +++ b/preview/lib/ood_preview_web/ood_preview_web.ml @@ -0,0 +1,11 @@ +module Handlers = struct + module Page = Page_handler +end + +let run () = + Dream_cli.run ~debug:true + @@ Dream.logger + @@ Dream_livereload.inject_script () + @@ Router.router + @@ Dream_livereload.router + @@ Dream.not_found diff --git a/preview/lib/ood_preview_web/router.ml b/preview/lib/ood_preview_web/router.ml new file mode 100644 index 0000000..625df6a --- /dev/null +++ b/preview/lib/ood_preview_web/router.ml @@ -0,0 +1,15 @@ +let loader _root path _request = + match Asset.read path with + | None -> + Dream.empty `Not_Found + | Some asset -> + Dream.respond asset + +let routes = + [ Dream.get "/" Page_handler.index + ; Dream.get "/papers" Page_handler.papers + ; Dream.get "/success-stories" Page_handler.success_stories + ; Dream.get "/assets/**" (Dream.static ~loader "") + ] + +let router = Dream.router routes diff --git a/preview/lib/ood_preview_web/templates/dune b/preview/lib/ood_preview_web/templates/dune new file mode 100644 index 0000000..92f7467 --- /dev/null +++ b/preview/lib/ood_preview_web/templates/dune @@ -0,0 +1,35 @@ +(rule + (targets header_section_template.ml) + (deps header_section_template.eml) + (action + (run %{bin:dream_eml} %{deps} --workspace %{workspace_root}))) + +(rule + (targets header_template.ml) + (deps header_template.eml) + (action + (run %{bin:dream_eml} %{deps} --workspace %{workspace_root}))) + +(rule + (targets index_template.ml) + (deps index_template.eml) + (action + (run %{bin:dream_eml} %{deps} --workspace %{workspace_root}))) + +(rule + (targets layout_template.ml) + (deps layout_template.eml) + (action + (run %{bin:dream_eml} %{deps} --workspace %{workspace_root}))) + +(rule + (targets papers_template.ml) + (deps papers_template.eml) + (action + (run %{bin:dream_eml} %{deps} --workspace %{workspace_root}))) + +(rule + (targets success_stories_template.ml) + (deps success_stories_template.eml) + (action + (run %{bin:dream_eml} %{deps} --workspace %{workspace_root}))) diff --git a/preview/lib/ood_preview_web/templates/header_section_template.eml b/preview/lib/ood_preview_web/templates/header_section_template.eml new file mode 100644 index 0000000..ce6a7ca --- /dev/null +++ b/preview/lib/ood_preview_web/templates/header_section_template.eml @@ -0,0 +1,24 @@ +let render_subtitle = function +| Some x -> +

+ <%s x %> +

+| None -> "" + +let render_tag = function +| Some x -> +

+ <%s x %> +

+| None -> "" + +let render ?tag ?subtitle title = +
+
+ <%s! render_tag tag %> +

+ <%s! title %> +

+ <%s! render_subtitle subtitle %> +
+
\ No newline at end of file diff --git a/preview/lib/ood_preview_web/templates/header_template.eml b/preview/lib/ood_preview_web/templates/header_template.eml new file mode 100644 index 0000000..c1ba812 --- /dev/null +++ b/preview/lib/ood_preview_web/templates/header_template.eml @@ -0,0 +1,139 @@ +let render_menu_item menu_item = + let open Navigation in + class="-m-3 p-3 block rounded-md hover:bg-gray-50"> +

+ <%s menu_item.label %> +

+

+ <%s menu_item.text %> +

+
+ +let render_menu menu = + let open Navigation in +
+ + + + +
+ +let render = +
+
+
+ +
+ +
+ +
+ + +
+
\ No newline at end of file diff --git a/preview/lib/ood_preview_web/templates/index_template.eml b/preview/lib/ood_preview_web/templates/index_template.eml new file mode 100644 index 0000000..7e19e89 --- /dev/null +++ b/preview/lib/ood_preview_web/templates/index_template.eml @@ -0,0 +1,3 @@ +let render = +
+
\ No newline at end of file diff --git a/preview/lib/ood_preview_web/templates/layout_template.eml b/preview/lib/ood_preview_web/templates/layout_template.eml new file mode 100644 index 0000000..8b87460 --- /dev/null +++ b/preview/lib/ood_preview_web/templates/layout_template.eml @@ -0,0 +1,21 @@ +let render ~title inner = + + + + + + + + + + + <%s title %> + + + + <%s! Header_template.render %> +
+ <%s! inner %> +
+ + diff --git a/preview/lib/ood_preview_web/templates/papers_template.eml b/preview/lib/ood_preview_web/templates/papers_template.eml new file mode 100644 index 0000000..6063df9 --- /dev/null +++ b/preview/lib/ood_preview_web/templates/papers_template.eml @@ -0,0 +1,68 @@ +[@@@ocaml.warning "-27"] + +let render_paper_col (paper : Ood_preview.Paper.t) = + let open Ood_preview.Paper in + + +
+ <%s paper.title %> +
+ + +
???
+ + + <%i paper.year %> + + + + ??? + + + + <%s paper.abstract %> + + + +let render papers = + <%s! Header_section_template.render ~subtitle:"A selection of OCaml papers through the ages. Filter by the tags or do a search over all of the text." "Papers Archive" %> +
+
+
+
+
+
+ + + + + + + + + + + + <%s! List.map render_paper_col papers |> String.concat "" %> + +
+ Title + + Authors + + Year + + Tags + + Description +
+
+
+
+
+
\ No newline at end of file diff --git a/preview/lib/ood_preview_web/templates/success_stories_template.eml b/preview/lib/ood_preview_web/templates/success_stories_template.eml new file mode 100644 index 0000000..6f5e066 --- /dev/null +++ b/preview/lib/ood_preview_web/templates/success_stories_template.eml @@ -0,0 +1,21 @@ +let render_story (story : Ood_preview.Success_story.t) = + let open Ood_preview.Success_story in +
+
+

+ + <%s story.title %> + +

+
+
+ <%s! story.body %> +
+
+ +let render success_stories = + <%s! Header_section_template.render "Success Stories" %> +
+ <%s! List.map render_story success_stories |> String.concat "" %> +
diff --git a/preview/script/watch.sh b/preview/script/watch.sh new file mode 100755 index 0000000..f3c2026 --- /dev/null +++ b/preview/script/watch.sh @@ -0,0 +1,20 @@ +#!/usr/bin/env bash + +source_dirs="preview/lib preview/bin preview/asset preview/config lib/ data/" +args=${*:-"preview/bin/server.exe run"} +cmd="dune exec ${args}" + +function sigint_handler() { + kill "$(jobs -pr)" + exit 1 +} + +trap sigint_handler SIGINT + +while true; do + make build + $cmd & + fswatch -r -1 $source_dirs + printf "\nRestarting server.exe due to filesystem change\n" + kill "$(jobs -pr)" +done \ No newline at end of file diff --git a/preview/test/ood_preview_web/dune b/preview/test/ood_preview_web/dune new file mode 100644 index 0000000..57a0535 --- /dev/null +++ b/preview/test/ood_preview_web/dune @@ -0,0 +1,4 @@ +(test + (name page_handler_test) + (modules page_handler_test) + (libraries alcotest ood_preview_web)) diff --git a/preview/test/ood_preview_web/page_handler_test.ml b/preview/test/ood_preview_web/page_handler_test.ml new file mode 100644 index 0000000..0948f16 --- /dev/null +++ b/preview/test/ood_preview_web/page_handler_test.ml @@ -0,0 +1,16 @@ +(** Test suite for the Utils module. *) + +let test_case n = Alcotest.test_case n `Quick + +let () = + Alcotest.run + "ood-preview" + [ ( "GET /" + , [ test_case "returns successfully" (fun () -> + let req = Dream.request ~method_:`GET "/" in + let res = Dream.test Ood_preview_web.Handlers.Page.index req in + Dream.status res + |> Dream.status_to_int + |> Alcotest.(check int) "is 200" 200) + ] ) + ]