"
+ ],
+ "license": "MIT",
+ "repository": "jonathanong/ee-first",
+ "devDependencies": {
+ "istanbul": "0.3.9",
+ "mocha": "2.2.5"
+ },
+ "files": [
+ "index.js",
+ "LICENSE"
+ ],
+ "scripts": {
+ "test": "mocha --reporter spec --bail --check-leaks test/",
+ "test-cov": "istanbul cover node_modules/mocha/bin/_mocha -- --reporter dot --check-leaks test/",
+ "test-travis": "istanbul cover node_modules/mocha/bin/_mocha --report lcovonly -- --reporter spec --check-leaks test/"
+ }
+}
diff --git a/app/node_modules/emoji-regex/LICENSE-MIT.txt b/app/node_modules/emoji-regex/LICENSE-MIT.txt
new file mode 100644
index 0000000..a41e0a7
--- /dev/null
+++ b/app/node_modules/emoji-regex/LICENSE-MIT.txt
@@ -0,0 +1,20 @@
+Copyright Mathias Bynens
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
diff --git a/app/node_modules/emoji-regex/README.md b/app/node_modules/emoji-regex/README.md
new file mode 100644
index 0000000..6d63082
--- /dev/null
+++ b/app/node_modules/emoji-regex/README.md
@@ -0,0 +1,137 @@
+# emoji-regex [![Build status](https://travis-ci.org/mathiasbynens/emoji-regex.svg?branch=main)](https://travis-ci.org/mathiasbynens/emoji-regex)
+
+_emoji-regex_ offers a regular expression to match all emoji symbols and sequences (including textual representations of emoji) as per the Unicode Standard.
+
+This repository contains a script that generates this regular expression based on [Unicode data](https://github.com/node-unicode/node-unicode-data). Because of this, the regular expression can easily be updated whenever new emoji are added to the Unicode standard.
+
+## Installation
+
+Via [npm](https://www.npmjs.com/):
+
+```bash
+npm install emoji-regex
+```
+
+In [Node.js](https://nodejs.org/):
+
+```js
+const emojiRegex = require('emoji-regex/RGI_Emoji.js');
+// Note: because the regular expression has the global flag set, this module
+// exports a function that returns the regex rather than exporting the regular
+// expression itself, to make it impossible to (accidentally) mutate the
+// original regular expression.
+
+const text = `
+\u{231A}: ⌚ default emoji presentation character (Emoji_Presentation)
+\u{2194}\u{FE0F}: â†”ï¸ default text presentation character rendered as emoji
+\u{1F469}: 👩 emoji modifier base (Emoji_Modifier_Base)
+\u{1F469}\u{1F3FF}: 👩🿠emoji modifier base followed by a modifier
+`;
+
+const regex = emojiRegex();
+let match;
+while (match = regex.exec(text)) {
+ const emoji = match[0];
+ console.log(`Matched sequence ${ emoji } — code points: ${ [...emoji].length }`);
+}
+```
+
+Console output:
+
+```
+Matched sequence ⌚ — code points: 1
+Matched sequence ⌚ — code points: 1
+Matched sequence â†”ï¸ â€” code points: 2
+Matched sequence â†”ï¸ â€” code points: 2
+Matched sequence 👩 — code points: 1
+Matched sequence 👩 — code points: 1
+Matched sequence 👩🿠— code points: 2
+Matched sequence 👩🿠— code points: 2
+```
+
+## Regular expression flavors
+
+The package comes with three distinct regular expressions:
+
+```js
+// This is the recommended regular expression to use. It matches all
+// emoji recommended for general interchange, as defined via the
+// `RGI_Emoji` property in the Unicode Standard.
+// https://unicode.org/reports/tr51/#def_rgi_set
+// When in doubt, use this!
+const emojiRegexRGI = require('emoji-regex/RGI_Emoji.js');
+
+// This is the old regular expression, prior to `RGI_Emoji` being
+// standardized. In addition to all `RGI_Emoji` sequences, it matches
+// some emoji you probably don’t want to match (such as emoji component
+// symbols that are not meant to be used separately).
+const emojiRegex = require('emoji-regex/index.js');
+
+// This regular expression matches even more emoji than the previous
+// one, including emoji that render as text instead of icons (i.e.
+// emoji that are not `Emoji_Presentation` symbols and that aren’t
+// forced to render as emoji by a variation selector).
+const emojiRegexText = require('emoji-regex/text.js');
+```
+
+Additionally, in environments which support ES2015 Unicode escapes, you may `require` ES2015-style versions of the regexes:
+
+```js
+const emojiRegexRGI = require('emoji-regex/es2015/RGI_Emoji.js');
+const emojiRegex = require('emoji-regex/es2015/index.js');
+const emojiRegexText = require('emoji-regex/es2015/text.js');
+```
+
+## For maintainers
+
+### How to update emoji-regex after new Unicode Standard releases
+
+1. Update the Unicode data dependency in `package.json` by running the following commands:
+
+ ```sh
+ # Example: updating from Unicode v12 to Unicode v13.
+ npm uninstall @unicode/unicode-12.0.0
+ npm install @unicode/unicode-13.0.0 --save-dev
+ ````
+
+1. Generate the new output:
+
+ ```sh
+ npm run build
+ ```
+
+1. Verify that tests still pass:
+
+ ```sh
+ npm test
+ ```
+
+1. Send a pull request with the changes, and get it reviewed & merged.
+
+1. On the `main` branch, bump the emoji-regex version number in `package.json`:
+
+ ```sh
+ npm version patch -m 'Release v%s'
+ ```
+
+ Instead of `patch`, use `minor` or `major` [as needed](https://semver.org/).
+
+ Note that this produces a Git commit + tag.
+
+1. Push the release commit and tag:
+
+ ```sh
+ git push
+ ```
+
+ Our CI then automatically publishes the new release to npm.
+
+## Author
+
+| [![twitter/mathias](https://gravatar.com/avatar/24e08a9ea84deb17ae121074d0f17125?s=70)](https://twitter.com/mathias "Follow @mathias on Twitter") |
+|---|
+| [Mathias Bynens](https://mathiasbynens.be/) |
+
+## License
+
+_emoji-regex_ is available under the [MIT](https://mths.be/mit) license.
diff --git a/app/node_modules/emoji-regex/RGI_Emoji.d.ts b/app/node_modules/emoji-regex/RGI_Emoji.d.ts
new file mode 100644
index 0000000..89a651f
--- /dev/null
+++ b/app/node_modules/emoji-regex/RGI_Emoji.d.ts
@@ -0,0 +1,5 @@
+declare module 'emoji-regex/RGI_Emoji' {
+ function emojiRegex(): RegExp;
+
+ export = emojiRegex;
+}
diff --git a/app/node_modules/emoji-regex/RGI_Emoji.js b/app/node_modules/emoji-regex/RGI_Emoji.js
new file mode 100644
index 0000000..3fbe924
--- /dev/null
+++ b/app/node_modules/emoji-regex/RGI_Emoji.js
@@ -0,0 +1,6 @@
+"use strict";
+
+module.exports = function () {
+ // https://mths.be/emoji
+ return /\uD83C\uDFF4\uDB40\uDC67\uDB40\uDC62(?:\uDB40\uDC77\uDB40\uDC6C\uDB40\uDC73|\uDB40\uDC73\uDB40\uDC63\uDB40\uDC74|\uDB40\uDC65\uDB40\uDC6E\uDB40\uDC67)\uDB40\uDC7F|(?:\uD83E\uDDD1\uD83C\uDFFF\u200D\u2764\uFE0F\u200D(?:\uD83D\uDC8B\u200D)?\uD83E\uDDD1|\uD83D\uDC69\uD83C\uDFFF\u200D\uD83E\uDD1D\u200D(?:\uD83D[\uDC68\uDC69]))(?:\uD83C[\uDFFB-\uDFFE])|(?:\uD83E\uDDD1\uD83C\uDFFE\u200D\u2764\uFE0F\u200D(?:\uD83D\uDC8B\u200D)?\uD83E\uDDD1|\uD83D\uDC69\uD83C\uDFFE\u200D\uD83E\uDD1D\u200D(?:\uD83D[\uDC68\uDC69]))(?:\uD83C[\uDFFB-\uDFFD\uDFFF])|(?:\uD83E\uDDD1\uD83C\uDFFD\u200D\u2764\uFE0F\u200D(?:\uD83D\uDC8B\u200D)?\uD83E\uDDD1|\uD83D\uDC69\uD83C\uDFFD\u200D\uD83E\uDD1D\u200D(?:\uD83D[\uDC68\uDC69]))(?:\uD83C[\uDFFB\uDFFC\uDFFE\uDFFF])|(?:\uD83E\uDDD1\uD83C\uDFFC\u200D\u2764\uFE0F\u200D(?:\uD83D\uDC8B\u200D)?\uD83E\uDDD1|\uD83D\uDC69\uD83C\uDFFC\u200D\uD83E\uDD1D\u200D(?:\uD83D[\uDC68\uDC69]))(?:\uD83C[\uDFFB\uDFFD-\uDFFF])|(?:\uD83E\uDDD1\uD83C\uDFFB\u200D\u2764\uFE0F\u200D(?:\uD83D\uDC8B\u200D)?\uD83E\uDDD1|\uD83D\uDC69\uD83C\uDFFB\u200D\uD83E\uDD1D\u200D(?:\uD83D[\uDC68\uDC69]))(?:\uD83C[\uDFFC-\uDFFF])|\uD83D\uDC68(?:\uD83C\uDFFB(?:\u200D(?:\u2764\uFE0F\u200D(?:\uD83D\uDC8B\u200D\uD83D\uDC68(?:\uD83C[\uDFFB-\uDFFF])|\uD83D\uDC68(?:\uD83C[\uDFFB-\uDFFF]))|\uD83E\uDD1D\u200D\uD83D\uDC68(?:\uD83C[\uDFFC-\uDFFF])|[\u2695\u2696\u2708]\uFE0F|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD]))?|(?:\uD83C[\uDFFC-\uDFFF])\u200D\u2764\uFE0F\u200D(?:\uD83D\uDC8B\u200D\uD83D\uDC68(?:\uD83C[\uDFFB-\uDFFF])|\uD83D\uDC68(?:\uD83C[\uDFFB-\uDFFF]))|\u200D(?:\u2764\uFE0F\u200D(?:\uD83D\uDC8B\u200D)?\uD83D\uDC68|(?:\uD83D[\uDC68\uDC69])\u200D(?:\uD83D\uDC66\u200D\uD83D\uDC66|\uD83D\uDC67\u200D(?:\uD83D[\uDC66\uDC67]))|\uD83D\uDC66\u200D\uD83D\uDC66|\uD83D\uDC67\u200D(?:\uD83D[\uDC66\uDC67])|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFF\u200D(?:\uD83E\uDD1D\u200D\uD83D\uDC68(?:\uD83C[\uDFFB-\uDFFE])|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFE\u200D(?:\uD83E\uDD1D\u200D\uD83D\uDC68(?:\uD83C[\uDFFB-\uDFFD\uDFFF])|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFD\u200D(?:\uD83E\uDD1D\u200D\uD83D\uDC68(?:\uD83C[\uDFFB\uDFFC\uDFFE\uDFFF])|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFC\u200D(?:\uD83E\uDD1D\u200D\uD83D\uDC68(?:\uD83C[\uDFFB\uDFFD-\uDFFF])|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|(?:\uD83C\uDFFF\u200D[\u2695\u2696\u2708]|\uD83C\uDFFE\u200D[\u2695\u2696\u2708]|\uD83C\uDFFD\u200D[\u2695\u2696\u2708]|\uD83C\uDFFC\u200D[\u2695\u2696\u2708]|\u200D[\u2695\u2696\u2708])\uFE0F|\u200D(?:(?:\uD83D[\uDC68\uDC69])\u200D(?:\uD83D[\uDC66\uDC67])|\uD83D[\uDC66\uDC67])|\uD83C\uDFFF|\uD83C\uDFFE|\uD83C\uDFFD|\uD83C\uDFFC)?|(?:\uD83D\uDC69(?:\uD83C\uDFFB\u200D\u2764\uFE0F\u200D(?:\uD83D\uDC8B\u200D(?:\uD83D[\uDC68\uDC69])|\uD83D[\uDC68\uDC69])|(?:\uD83C[\uDFFC-\uDFFF])\u200D\u2764\uFE0F\u200D(?:\uD83D\uDC8B\u200D(?:\uD83D[\uDC68\uDC69])|\uD83D[\uDC68\uDC69]))|\uD83E\uDDD1(?:\uD83C[\uDFFB-\uDFFF])\u200D\uD83E\uDD1D\u200D\uD83E\uDDD1)(?:\uD83C[\uDFFB-\uDFFF])|\uD83D\uDC69\u200D\uD83D\uDC69\u200D(?:\uD83D\uDC66\u200D\uD83D\uDC66|\uD83D\uDC67\u200D(?:\uD83D[\uDC66\uDC67]))|\uD83D\uDC69(?:\u200D(?:\u2764\uFE0F\u200D(?:\uD83D\uDC8B\u200D(?:\uD83D[\uDC68\uDC69])|\uD83D[\uDC68\uDC69])|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFF\u200D(?:\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFE\u200D(?:\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFD\u200D(?:\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFC\u200D(?:\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFB\u200D(?:\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD]))|\uD83E\uDDD1(?:\u200D(?:\uD83E\uDD1D\u200D\uD83E\uDDD1|\uD83C[\uDF3E\uDF73\uDF7C\uDF84\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFF\u200D(?:\uD83C[\uDF3E\uDF73\uDF7C\uDF84\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFE\u200D(?:\uD83C[\uDF3E\uDF73\uDF7C\uDF84\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFD\u200D(?:\uD83C[\uDF3E\uDF73\uDF7C\uDF84\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFC\u200D(?:\uD83C[\uDF3E\uDF73\uDF7C\uDF84\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFB\u200D(?:\uD83C[\uDF3E\uDF73\uDF7C\uDF84\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD]))|\uD83D\uDC69\u200D\uD83D\uDC66\u200D\uD83D\uDC66|\uD83D\uDC69\u200D\uD83D\uDC69\u200D(?:\uD83D[\uDC66\uDC67])|\uD83D\uDC69\u200D\uD83D\uDC67\u200D(?:\uD83D[\uDC66\uDC67])|(?:\uD83D\uDC41\uFE0F\u200D\uD83D\uDDE8|\uD83E\uDDD1(?:\uD83C\uDFFF\u200D[\u2695\u2696\u2708]|\uD83C\uDFFE\u200D[\u2695\u2696\u2708]|\uD83C\uDFFD\u200D[\u2695\u2696\u2708]|\uD83C\uDFFC\u200D[\u2695\u2696\u2708]|\uD83C\uDFFB\u200D[\u2695\u2696\u2708]|\u200D[\u2695\u2696\u2708])|\uD83D\uDC69(?:\uD83C\uDFFF\u200D[\u2695\u2696\u2708]|\uD83C\uDFFE\u200D[\u2695\u2696\u2708]|\uD83C\uDFFD\u200D[\u2695\u2696\u2708]|\uD83C\uDFFC\u200D[\u2695\u2696\u2708]|\uD83C\uDFFB\u200D[\u2695\u2696\u2708]|\u200D[\u2695\u2696\u2708])|\uD83D\uDE36\u200D\uD83C\uDF2B|\uD83C\uDFF3\uFE0F\u200D\u26A7|\uD83D\uDC3B\u200D\u2744|(?:(?:\uD83C[\uDFC3\uDFC4\uDFCA]|\uD83D[\uDC6E\uDC70\uDC71\uDC73\uDC77\uDC81\uDC82\uDC86\uDC87\uDE45-\uDE47\uDE4B\uDE4D\uDE4E\uDEA3\uDEB4-\uDEB6]|\uD83E[\uDD26\uDD35\uDD37-\uDD39\uDD3D\uDD3E\uDDB8\uDDB9\uDDCD-\uDDCF\uDDD4\uDDD6-\uDDDD])(?:\uD83C[\uDFFB-\uDFFF])|\uD83D\uDC6F|\uD83E[\uDD3C\uDDDE\uDDDF])\u200D[\u2640\u2642]|(?:\u26F9|\uD83C[\uDFCB\uDFCC]|\uD83D\uDD75)(?:\uFE0F|\uD83C[\uDFFB-\uDFFF])\u200D[\u2640\u2642]|\uD83C\uDFF4\u200D\u2620|(?:\uD83C[\uDFC3\uDFC4\uDFCA]|\uD83D[\uDC6E\uDC70\uDC71\uDC73\uDC77\uDC81\uDC82\uDC86\uDC87\uDE45-\uDE47\uDE4B\uDE4D\uDE4E\uDEA3\uDEB4-\uDEB6]|\uD83E[\uDD26\uDD35\uDD37-\uDD39\uDD3D\uDD3E\uDDB8\uDDB9\uDDCD-\uDDCF\uDDD4\uDDD6-\uDDDD])\u200D[\u2640\u2642]|[\xA9\xAE\u203C\u2049\u2122\u2139\u2194-\u2199\u21A9\u21AA\u2328\u23CF\u23ED-\u23EF\u23F1\u23F2\u23F8-\u23FA\u24C2\u25AA\u25AB\u25B6\u25C0\u25FB\u25FC\u2600-\u2604\u260E\u2611\u2618\u2620\u2622\u2623\u2626\u262A\u262E\u262F\u2638-\u263A\u2640\u2642\u265F\u2660\u2663\u2665\u2666\u2668\u267B\u267E\u2692\u2694-\u2697\u2699\u269B\u269C\u26A0\u26A7\u26B0\u26B1\u26C8\u26CF\u26D1\u26D3\u26E9\u26F0\u26F1\u26F4\u26F7\u26F8\u2702\u2708\u2709\u270F\u2712\u2714\u2716\u271D\u2721\u2733\u2734\u2744\u2747\u2763\u27A1\u2934\u2935\u2B05-\u2B07\u3030\u303D\u3297\u3299]|\uD83C[\uDD70\uDD71\uDD7E\uDD7F\uDE02\uDE37\uDF21\uDF24-\uDF2C\uDF36\uDF7D\uDF96\uDF97\uDF99-\uDF9B\uDF9E\uDF9F\uDFCD\uDFCE\uDFD4-\uDFDF\uDFF5\uDFF7]|\uD83D[\uDC3F\uDCFD\uDD49\uDD4A\uDD6F\uDD70\uDD73\uDD76-\uDD79\uDD87\uDD8A-\uDD8D\uDDA5\uDDA8\uDDB1\uDDB2\uDDBC\uDDC2-\uDDC4\uDDD1-\uDDD3\uDDDC-\uDDDE\uDDE1\uDDE3\uDDE8\uDDEF\uDDF3\uDDFA\uDECB\uDECD-\uDECF\uDEE0-\uDEE5\uDEE9\uDEF0\uDEF3])\uFE0F|\uD83C\uDFF3\uFE0F\u200D\uD83C\uDF08|\uD83D\uDC69\u200D\uD83D\uDC67|\uD83D\uDC69\u200D\uD83D\uDC66|\uD83D\uDE35\u200D\uD83D\uDCAB|\uD83D\uDE2E\u200D\uD83D\uDCA8|\uD83D\uDC15\u200D\uD83E\uDDBA|\uD83E\uDDD1(?:\uD83C\uDFFF|\uD83C\uDFFE|\uD83C\uDFFD|\uD83C\uDFFC|\uD83C\uDFFB)?|\uD83D\uDC69(?:\uD83C\uDFFF|\uD83C\uDFFE|\uD83C\uDFFD|\uD83C\uDFFC|\uD83C\uDFFB)?|\uD83C\uDDFD\uD83C\uDDF0|\uD83C\uDDF6\uD83C\uDDE6|\uD83C\uDDF4\uD83C\uDDF2|\uD83D\uDC08\u200D\u2B1B|\u2764\uFE0F\u200D(?:\uD83D\uDD25|\uD83E\uDE79)|\uD83D\uDC41\uFE0F|\uD83C\uDFF3\uFE0F|\uD83C\uDDFF(?:\uD83C[\uDDE6\uDDF2\uDDFC])|\uD83C\uDDFE(?:\uD83C[\uDDEA\uDDF9])|\uD83C\uDDFC(?:\uD83C[\uDDEB\uDDF8])|\uD83C\uDDFB(?:\uD83C[\uDDE6\uDDE8\uDDEA\uDDEC\uDDEE\uDDF3\uDDFA])|\uD83C\uDDFA(?:\uD83C[\uDDE6\uDDEC\uDDF2\uDDF3\uDDF8\uDDFE\uDDFF])|\uD83C\uDDF9(?:\uD83C[\uDDE6\uDDE8\uDDE9\uDDEB-\uDDED\uDDEF-\uDDF4\uDDF7\uDDF9\uDDFB\uDDFC\uDDFF])|\uD83C\uDDF8(?:\uD83C[\uDDE6-\uDDEA\uDDEC-\uDDF4\uDDF7-\uDDF9\uDDFB\uDDFD-\uDDFF])|\uD83C\uDDF7(?:\uD83C[\uDDEA\uDDF4\uDDF8\uDDFA\uDDFC])|\uD83C\uDDF5(?:\uD83C[\uDDE6\uDDEA-\uDDED\uDDF0-\uDDF3\uDDF7-\uDDF9\uDDFC\uDDFE])|\uD83C\uDDF3(?:\uD83C[\uDDE6\uDDE8\uDDEA-\uDDEC\uDDEE\uDDF1\uDDF4\uDDF5\uDDF7\uDDFA\uDDFF])|\uD83C\uDDF2(?:\uD83C[\uDDE6\uDDE8-\uDDED\uDDF0-\uDDFF])|\uD83C\uDDF1(?:\uD83C[\uDDE6-\uDDE8\uDDEE\uDDF0\uDDF7-\uDDFB\uDDFE])|\uD83C\uDDF0(?:\uD83C[\uDDEA\uDDEC-\uDDEE\uDDF2\uDDF3\uDDF5\uDDF7\uDDFC\uDDFE\uDDFF])|\uD83C\uDDEF(?:\uD83C[\uDDEA\uDDF2\uDDF4\uDDF5])|\uD83C\uDDEE(?:\uD83C[\uDDE8-\uDDEA\uDDF1-\uDDF4\uDDF6-\uDDF9])|\uD83C\uDDED(?:\uD83C[\uDDF0\uDDF2\uDDF3\uDDF7\uDDF9\uDDFA])|\uD83C\uDDEC(?:\uD83C[\uDDE6\uDDE7\uDDE9-\uDDEE\uDDF1-\uDDF3\uDDF5-\uDDFA\uDDFC\uDDFE])|\uD83C\uDDEB(?:\uD83C[\uDDEE-\uDDF0\uDDF2\uDDF4\uDDF7])|\uD83C\uDDEA(?:\uD83C[\uDDE6\uDDE8\uDDEA\uDDEC\uDDED\uDDF7-\uDDFA])|\uD83C\uDDE9(?:\uD83C[\uDDEA\uDDEC\uDDEF\uDDF0\uDDF2\uDDF4\uDDFF])|\uD83C\uDDE8(?:\uD83C[\uDDE6\uDDE8\uDDE9\uDDEB-\uDDEE\uDDF0-\uDDF5\uDDF7\uDDFA-\uDDFF])|\uD83C\uDDE7(?:\uD83C[\uDDE6\uDDE7\uDDE9-\uDDEF\uDDF1-\uDDF4\uDDF6-\uDDF9\uDDFB\uDDFC\uDDFE\uDDFF])|\uD83C\uDDE6(?:\uD83C[\uDDE8-\uDDEC\uDDEE\uDDF1\uDDF2\uDDF4\uDDF6-\uDDFA\uDDFC\uDDFD\uDDFF])|[#\*0-9]\uFE0F\u20E3|\u2764\uFE0F|(?:\uD83C[\uDFC3\uDFC4\uDFCA]|\uD83D[\uDC6E\uDC70\uDC71\uDC73\uDC77\uDC81\uDC82\uDC86\uDC87\uDE45-\uDE47\uDE4B\uDE4D\uDE4E\uDEA3\uDEB4-\uDEB6]|\uD83E[\uDD26\uDD35\uDD37-\uDD39\uDD3D\uDD3E\uDDB8\uDDB9\uDDCD-\uDDCF\uDDD4\uDDD6-\uDDDD])(?:\uD83C[\uDFFB-\uDFFF])|(?:\u26F9|\uD83C[\uDFCB\uDFCC]|\uD83D\uDD75)(?:\uFE0F|\uD83C[\uDFFB-\uDFFF])|\uD83C\uDFF4|(?:[\u270A\u270B]|\uD83C[\uDF85\uDFC2\uDFC7]|\uD83D[\uDC42\uDC43\uDC46-\uDC50\uDC66\uDC67\uDC6B-\uDC6D\uDC72\uDC74-\uDC76\uDC78\uDC7C\uDC83\uDC85\uDC8F\uDC91\uDCAA\uDD7A\uDD95\uDD96\uDE4C\uDE4F\uDEC0\uDECC]|\uD83E[\uDD0C\uDD0F\uDD18-\uDD1C\uDD1E\uDD1F\uDD30-\uDD34\uDD36\uDD77\uDDB5\uDDB6\uDDBB\uDDD2\uDDD3\uDDD5])(?:\uD83C[\uDFFB-\uDFFF])|(?:[\u261D\u270C\u270D]|\uD83D[\uDD74\uDD90])(?:\uFE0F|\uD83C[\uDFFB-\uDFFF])|[\u270A\u270B]|\uD83C[\uDF85\uDFC2\uDFC7]|\uD83D[\uDC08\uDC15\uDC3B\uDC42\uDC43\uDC46-\uDC50\uDC66\uDC67\uDC6B-\uDC6D\uDC72\uDC74-\uDC76\uDC78\uDC7C\uDC83\uDC85\uDC8F\uDC91\uDCAA\uDD7A\uDD95\uDD96\uDE2E\uDE35\uDE36\uDE4C\uDE4F\uDEC0\uDECC]|\uD83E[\uDD0C\uDD0F\uDD18-\uDD1C\uDD1E\uDD1F\uDD30-\uDD34\uDD36\uDD77\uDDB5\uDDB6\uDDBB\uDDD2\uDDD3\uDDD5]|\uD83C[\uDFC3\uDFC4\uDFCA]|\uD83D[\uDC6E\uDC70\uDC71\uDC73\uDC77\uDC81\uDC82\uDC86\uDC87\uDE45-\uDE47\uDE4B\uDE4D\uDE4E\uDEA3\uDEB4-\uDEB6]|\uD83E[\uDD26\uDD35\uDD37-\uDD39\uDD3D\uDD3E\uDDB8\uDDB9\uDDCD-\uDDCF\uDDD4\uDDD6-\uDDDD]|\uD83D\uDC6F|\uD83E[\uDD3C\uDDDE\uDDDF]|[\u231A\u231B\u23E9-\u23EC\u23F0\u23F3\u25FD\u25FE\u2614\u2615\u2648-\u2653\u267F\u2693\u26A1\u26AA\u26AB\u26BD\u26BE\u26C4\u26C5\u26CE\u26D4\u26EA\u26F2\u26F3\u26F5\u26FA\u26FD\u2705\u2728\u274C\u274E\u2753-\u2755\u2757\u2795-\u2797\u27B0\u27BF\u2B1B\u2B1C\u2B50\u2B55]|\uD83C[\uDC04\uDCCF\uDD8E\uDD91-\uDD9A\uDE01\uDE1A\uDE2F\uDE32-\uDE36\uDE38-\uDE3A\uDE50\uDE51\uDF00-\uDF20\uDF2D-\uDF35\uDF37-\uDF7C\uDF7E-\uDF84\uDF86-\uDF93\uDFA0-\uDFC1\uDFC5\uDFC6\uDFC8\uDFC9\uDFCF-\uDFD3\uDFE0-\uDFF0\uDFF8-\uDFFF]|\uD83D[\uDC00-\uDC07\uDC09-\uDC14\uDC16-\uDC3A\uDC3C-\uDC3E\uDC40\uDC44\uDC45\uDC51-\uDC65\uDC6A\uDC79-\uDC7B\uDC7D-\uDC80\uDC84\uDC88-\uDC8E\uDC90\uDC92-\uDCA9\uDCAB-\uDCFC\uDCFF-\uDD3D\uDD4B-\uDD4E\uDD50-\uDD67\uDDA4\uDDFB-\uDE2D\uDE2F-\uDE34\uDE37-\uDE44\uDE48-\uDE4A\uDE80-\uDEA2\uDEA4-\uDEB3\uDEB7-\uDEBF\uDEC1-\uDEC5\uDED0-\uDED2\uDED5-\uDED7\uDEEB\uDEEC\uDEF4-\uDEFC\uDFE0-\uDFEB]|\uD83E[\uDD0D\uDD0E\uDD10-\uDD17\uDD1D\uDD20-\uDD25\uDD27-\uDD2F\uDD3A\uDD3F-\uDD45\uDD47-\uDD76\uDD78\uDD7A-\uDDB4\uDDB7\uDDBA\uDDBC-\uDDCB\uDDD0\uDDE0-\uDDFF\uDE70-\uDE74\uDE78-\uDE7A\uDE80-\uDE86\uDE90-\uDEA8\uDEB0-\uDEB6\uDEC0-\uDEC2\uDED0-\uDED6]/g;
+};
diff --git a/app/node_modules/emoji-regex/es2015/RGI_Emoji.d.ts b/app/node_modules/emoji-regex/es2015/RGI_Emoji.d.ts
new file mode 100644
index 0000000..bf0f154
--- /dev/null
+++ b/app/node_modules/emoji-regex/es2015/RGI_Emoji.d.ts
@@ -0,0 +1,5 @@
+declare module 'emoji-regex/es2015/RGI_Emoji' {
+ function emojiRegex(): RegExp;
+
+ export = emojiRegex;
+}
diff --git a/app/node_modules/emoji-regex/es2015/RGI_Emoji.js b/app/node_modules/emoji-regex/es2015/RGI_Emoji.js
new file mode 100644
index 0000000..ecf32f1
--- /dev/null
+++ b/app/node_modules/emoji-regex/es2015/RGI_Emoji.js
@@ -0,0 +1,6 @@
+"use strict";
+
+module.exports = () => {
+ // https://mths.be/emoji
+ return /\u{1F3F4}\u{E0067}\u{E0062}(?:\u{E0077}\u{E006C}\u{E0073}|\u{E0073}\u{E0063}\u{E0074}|\u{E0065}\u{E006E}\u{E0067})\u{E007F}|(?:\u{1F9D1}\u{1F3FF}\u200D\u2764\uFE0F\u200D(?:\u{1F48B}\u200D)?\u{1F9D1}|\u{1F469}\u{1F3FF}\u200D\u{1F91D}\u200D[\u{1F468}\u{1F469}])[\u{1F3FB}-\u{1F3FE}]|(?:\u{1F9D1}\u{1F3FE}\u200D\u2764\uFE0F\u200D(?:\u{1F48B}\u200D)?\u{1F9D1}|\u{1F469}\u{1F3FE}\u200D\u{1F91D}\u200D[\u{1F468}\u{1F469}])[\u{1F3FB}-\u{1F3FD}\u{1F3FF}]|(?:\u{1F9D1}\u{1F3FD}\u200D\u2764\uFE0F\u200D(?:\u{1F48B}\u200D)?\u{1F9D1}|\u{1F469}\u{1F3FD}\u200D\u{1F91D}\u200D[\u{1F468}\u{1F469}])[\u{1F3FB}\u{1F3FC}\u{1F3FE}\u{1F3FF}]|(?:\u{1F9D1}\u{1F3FC}\u200D\u2764\uFE0F\u200D(?:\u{1F48B}\u200D)?\u{1F9D1}|\u{1F469}\u{1F3FC}\u200D\u{1F91D}\u200D[\u{1F468}\u{1F469}])[\u{1F3FB}\u{1F3FD}-\u{1F3FF}]|(?:\u{1F9D1}\u{1F3FB}\u200D\u2764\uFE0F\u200D(?:\u{1F48B}\u200D)?\u{1F9D1}|\u{1F469}\u{1F3FB}\u200D\u{1F91D}\u200D[\u{1F468}\u{1F469}])[\u{1F3FC}-\u{1F3FF}]|\u{1F468}(?:\u{1F3FB}(?:\u200D(?:\u2764\uFE0F\u200D(?:\u{1F48B}\u200D\u{1F468}[\u{1F3FB}-\u{1F3FF}]|\u{1F468}[\u{1F3FB}-\u{1F3FF}])|\u{1F91D}\u200D\u{1F468}[\u{1F3FC}-\u{1F3FF}]|[\u2695\u2696\u2708]\uFE0F|[\u{1F33E}\u{1F373}\u{1F37C}\u{1F393}\u{1F3A4}\u{1F3A8}\u{1F3EB}\u{1F3ED}\u{1F4BB}\u{1F4BC}\u{1F527}\u{1F52C}\u{1F680}\u{1F692}\u{1F9AF}-\u{1F9B3}\u{1F9BC}\u{1F9BD}]))?|[\u{1F3FC}-\u{1F3FF}]\u200D\u2764\uFE0F\u200D(?:\u{1F48B}\u200D\u{1F468}[\u{1F3FB}-\u{1F3FF}]|\u{1F468}[\u{1F3FB}-\u{1F3FF}])|\u200D(?:\u2764\uFE0F\u200D(?:\u{1F48B}\u200D)?\u{1F468}|[\u{1F468}\u{1F469}]\u200D(?:\u{1F466}\u200D\u{1F466}|\u{1F467}\u200D[\u{1F466}\u{1F467}])|\u{1F466}\u200D\u{1F466}|\u{1F467}\u200D[\u{1F466}\u{1F467}]|[\u{1F33E}\u{1F373}\u{1F37C}\u{1F393}\u{1F3A4}\u{1F3A8}\u{1F3EB}\u{1F3ED}\u{1F4BB}\u{1F4BC}\u{1F527}\u{1F52C}\u{1F680}\u{1F692}\u{1F9AF}-\u{1F9B3}\u{1F9BC}\u{1F9BD}])|\u{1F3FF}\u200D(?:\u{1F91D}\u200D\u{1F468}[\u{1F3FB}-\u{1F3FE}]|[\u{1F33E}\u{1F373}\u{1F37C}\u{1F393}\u{1F3A4}\u{1F3A8}\u{1F3EB}\u{1F3ED}\u{1F4BB}\u{1F4BC}\u{1F527}\u{1F52C}\u{1F680}\u{1F692}\u{1F9AF}-\u{1F9B3}\u{1F9BC}\u{1F9BD}])|\u{1F3FE}\u200D(?:\u{1F91D}\u200D\u{1F468}[\u{1F3FB}-\u{1F3FD}\u{1F3FF}]|[\u{1F33E}\u{1F373}\u{1F37C}\u{1F393}\u{1F3A4}\u{1F3A8}\u{1F3EB}\u{1F3ED}\u{1F4BB}\u{1F4BC}\u{1F527}\u{1F52C}\u{1F680}\u{1F692}\u{1F9AF}-\u{1F9B3}\u{1F9BC}\u{1F9BD}])|\u{1F3FD}\u200D(?:\u{1F91D}\u200D\u{1F468}[\u{1F3FB}\u{1F3FC}\u{1F3FE}\u{1F3FF}]|[\u{1F33E}\u{1F373}\u{1F37C}\u{1F393}\u{1F3A4}\u{1F3A8}\u{1F3EB}\u{1F3ED}\u{1F4BB}\u{1F4BC}\u{1F527}\u{1F52C}\u{1F680}\u{1F692}\u{1F9AF}-\u{1F9B3}\u{1F9BC}\u{1F9BD}])|\u{1F3FC}\u200D(?:\u{1F91D}\u200D\u{1F468}[\u{1F3FB}\u{1F3FD}-\u{1F3FF}]|[\u{1F33E}\u{1F373}\u{1F37C}\u{1F393}\u{1F3A4}\u{1F3A8}\u{1F3EB}\u{1F3ED}\u{1F4BB}\u{1F4BC}\u{1F527}\u{1F52C}\u{1F680}\u{1F692}\u{1F9AF}-\u{1F9B3}\u{1F9BC}\u{1F9BD}])|(?:\u{1F3FF}\u200D[\u2695\u2696\u2708]|\u{1F3FE}\u200D[\u2695\u2696\u2708]|\u{1F3FD}\u200D[\u2695\u2696\u2708]|\u{1F3FC}\u200D[\u2695\u2696\u2708]|\u200D[\u2695\u2696\u2708])\uFE0F|\u200D(?:[\u{1F468}\u{1F469}]\u200D[\u{1F466}\u{1F467}]|[\u{1F466}\u{1F467}])|\u{1F3FF}|\u{1F3FE}|\u{1F3FD}|\u{1F3FC})?|(?:\u{1F469}(?:\u{1F3FB}\u200D\u2764\uFE0F\u200D(?:\u{1F48B}\u200D[\u{1F468}\u{1F469}]|[\u{1F468}\u{1F469}])|[\u{1F3FC}-\u{1F3FF}]\u200D\u2764\uFE0F\u200D(?:\u{1F48B}\u200D[\u{1F468}\u{1F469}]|[\u{1F468}\u{1F469}]))|\u{1F9D1}[\u{1F3FB}-\u{1F3FF}]\u200D\u{1F91D}\u200D\u{1F9D1})[\u{1F3FB}-\u{1F3FF}]|\u{1F469}\u200D\u{1F469}\u200D(?:\u{1F466}\u200D\u{1F466}|\u{1F467}\u200D[\u{1F466}\u{1F467}])|\u{1F469}(?:\u200D(?:\u2764\uFE0F\u200D(?:\u{1F48B}\u200D[\u{1F468}\u{1F469}]|[\u{1F468}\u{1F469}])|[\u{1F33E}\u{1F373}\u{1F37C}\u{1F393}\u{1F3A4}\u{1F3A8}\u{1F3EB}\u{1F3ED}\u{1F4BB}\u{1F4BC}\u{1F527}\u{1F52C}\u{1F680}\u{1F692}\u{1F9AF}-\u{1F9B3}\u{1F9BC}\u{1F9BD}])|\u{1F3FF}\u200D[\u{1F33E}\u{1F373}\u{1F37C}\u{1F393}\u{1F3A4}\u{1F3A8}\u{1F3EB}\u{1F3ED}\u{1F4BB}\u{1F4BC}\u{1F527}\u{1F52C}\u{1F680}\u{1F692}\u{1F9AF}-\u{1F9B3}\u{1F9BC}\u{1F9BD}]|\u{1F3FE}\u200D[\u{1F33E}\u{1F373}\u{1F37C}\u{1F393}\u{1F3A4}\u{1F3A8}\u{1F3EB}\u{1F3ED}\u{1F4BB}\u{1F4BC}\u{1F527}\u{1F52C}\u{1F680}\u{1F692}\u{1F9AF}-\u{1F9B3}\u{1F9BC}\u{1F9BD}]|\u{1F3FD}\u200D[\u{1F33E}\u{1F373}\u{1F37C}\u{1F393}\u{1F3A4}\u{1F3A8}\u{1F3EB}\u{1F3ED}\u{1F4BB}\u{1F4BC}\u{1F527}\u{1F52C}\u{1F680}\u{1F692}\u{1F9AF}-\u{1F9B3}\u{1F9BC}\u{1F9BD}]|\u{1F3FC}\u200D[\u{1F33E}\u{1F373}\u{1F37C}\u{1F393}\u{1F3A4}\u{1F3A8}\u{1F3EB}\u{1F3ED}\u{1F4BB}\u{1F4BC}\u{1F527}\u{1F52C}\u{1F680}\u{1F692}\u{1F9AF}-\u{1F9B3}\u{1F9BC}\u{1F9BD}]|\u{1F3FB}\u200D[\u{1F33E}\u{1F373}\u{1F37C}\u{1F393}\u{1F3A4}\u{1F3A8}\u{1F3EB}\u{1F3ED}\u{1F4BB}\u{1F4BC}\u{1F527}\u{1F52C}\u{1F680}\u{1F692}\u{1F9AF}-\u{1F9B3}\u{1F9BC}\u{1F9BD}])|\u{1F9D1}(?:\u200D(?:\u{1F91D}\u200D\u{1F9D1}|[\u{1F33E}\u{1F373}\u{1F37C}\u{1F384}\u{1F393}\u{1F3A4}\u{1F3A8}\u{1F3EB}\u{1F3ED}\u{1F4BB}\u{1F4BC}\u{1F527}\u{1F52C}\u{1F680}\u{1F692}\u{1F9AF}-\u{1F9B3}\u{1F9BC}\u{1F9BD}])|\u{1F3FF}\u200D[\u{1F33E}\u{1F373}\u{1F37C}\u{1F384}\u{1F393}\u{1F3A4}\u{1F3A8}\u{1F3EB}\u{1F3ED}\u{1F4BB}\u{1F4BC}\u{1F527}\u{1F52C}\u{1F680}\u{1F692}\u{1F9AF}-\u{1F9B3}\u{1F9BC}\u{1F9BD}]|\u{1F3FE}\u200D[\u{1F33E}\u{1F373}\u{1F37C}\u{1F384}\u{1F393}\u{1F3A4}\u{1F3A8}\u{1F3EB}\u{1F3ED}\u{1F4BB}\u{1F4BC}\u{1F527}\u{1F52C}\u{1F680}\u{1F692}\u{1F9AF}-\u{1F9B3}\u{1F9BC}\u{1F9BD}]|\u{1F3FD}\u200D[\u{1F33E}\u{1F373}\u{1F37C}\u{1F384}\u{1F393}\u{1F3A4}\u{1F3A8}\u{1F3EB}\u{1F3ED}\u{1F4BB}\u{1F4BC}\u{1F527}\u{1F52C}\u{1F680}\u{1F692}\u{1F9AF}-\u{1F9B3}\u{1F9BC}\u{1F9BD}]|\u{1F3FC}\u200D[\u{1F33E}\u{1F373}\u{1F37C}\u{1F384}\u{1F393}\u{1F3A4}\u{1F3A8}\u{1F3EB}\u{1F3ED}\u{1F4BB}\u{1F4BC}\u{1F527}\u{1F52C}\u{1F680}\u{1F692}\u{1F9AF}-\u{1F9B3}\u{1F9BC}\u{1F9BD}]|\u{1F3FB}\u200D[\u{1F33E}\u{1F373}\u{1F37C}\u{1F384}\u{1F393}\u{1F3A4}\u{1F3A8}\u{1F3EB}\u{1F3ED}\u{1F4BB}\u{1F4BC}\u{1F527}\u{1F52C}\u{1F680}\u{1F692}\u{1F9AF}-\u{1F9B3}\u{1F9BC}\u{1F9BD}])|\u{1F469}\u200D\u{1F466}\u200D\u{1F466}|\u{1F469}\u200D\u{1F469}\u200D[\u{1F466}\u{1F467}]|\u{1F469}\u200D\u{1F467}\u200D[\u{1F466}\u{1F467}]|(?:\u{1F441}\uFE0F\u200D\u{1F5E8}|\u{1F9D1}(?:\u{1F3FF}\u200D[\u2695\u2696\u2708]|\u{1F3FE}\u200D[\u2695\u2696\u2708]|\u{1F3FD}\u200D[\u2695\u2696\u2708]|\u{1F3FC}\u200D[\u2695\u2696\u2708]|\u{1F3FB}\u200D[\u2695\u2696\u2708]|\u200D[\u2695\u2696\u2708])|\u{1F469}(?:\u{1F3FF}\u200D[\u2695\u2696\u2708]|\u{1F3FE}\u200D[\u2695\u2696\u2708]|\u{1F3FD}\u200D[\u2695\u2696\u2708]|\u{1F3FC}\u200D[\u2695\u2696\u2708]|\u{1F3FB}\u200D[\u2695\u2696\u2708]|\u200D[\u2695\u2696\u2708])|\u{1F636}\u200D\u{1F32B}|\u{1F3F3}\uFE0F\u200D\u26A7|\u{1F43B}\u200D\u2744|(?:[\u{1F3C3}\u{1F3C4}\u{1F3CA}\u{1F46E}\u{1F470}\u{1F471}\u{1F473}\u{1F477}\u{1F481}\u{1F482}\u{1F486}\u{1F487}\u{1F645}-\u{1F647}\u{1F64B}\u{1F64D}\u{1F64E}\u{1F6A3}\u{1F6B4}-\u{1F6B6}\u{1F926}\u{1F935}\u{1F937}-\u{1F939}\u{1F93D}\u{1F93E}\u{1F9B8}\u{1F9B9}\u{1F9CD}-\u{1F9CF}\u{1F9D4}\u{1F9D6}-\u{1F9DD}][\u{1F3FB}-\u{1F3FF}]|[\u{1F46F}\u{1F93C}\u{1F9DE}\u{1F9DF}])\u200D[\u2640\u2642]|[\u26F9\u{1F3CB}\u{1F3CC}\u{1F575}][\uFE0F\u{1F3FB}-\u{1F3FF}]\u200D[\u2640\u2642]|\u{1F3F4}\u200D\u2620|[\u{1F3C3}\u{1F3C4}\u{1F3CA}\u{1F46E}\u{1F470}\u{1F471}\u{1F473}\u{1F477}\u{1F481}\u{1F482}\u{1F486}\u{1F487}\u{1F645}-\u{1F647}\u{1F64B}\u{1F64D}\u{1F64E}\u{1F6A3}\u{1F6B4}-\u{1F6B6}\u{1F926}\u{1F935}\u{1F937}-\u{1F939}\u{1F93D}\u{1F93E}\u{1F9B8}\u{1F9B9}\u{1F9CD}-\u{1F9CF}\u{1F9D4}\u{1F9D6}-\u{1F9DD}]\u200D[\u2640\u2642]|[\xA9\xAE\u203C\u2049\u2122\u2139\u2194-\u2199\u21A9\u21AA\u2328\u23CF\u23ED-\u23EF\u23F1\u23F2\u23F8-\u23FA\u24C2\u25AA\u25AB\u25B6\u25C0\u25FB\u25FC\u2600-\u2604\u260E\u2611\u2618\u2620\u2622\u2623\u2626\u262A\u262E\u262F\u2638-\u263A\u2640\u2642\u265F\u2660\u2663\u2665\u2666\u2668\u267B\u267E\u2692\u2694-\u2697\u2699\u269B\u269C\u26A0\u26A7\u26B0\u26B1\u26C8\u26CF\u26D1\u26D3\u26E9\u26F0\u26F1\u26F4\u26F7\u26F8\u2702\u2708\u2709\u270F\u2712\u2714\u2716\u271D\u2721\u2733\u2734\u2744\u2747\u2763\u27A1\u2934\u2935\u2B05-\u2B07\u3030\u303D\u3297\u3299\u{1F170}\u{1F171}\u{1F17E}\u{1F17F}\u{1F202}\u{1F237}\u{1F321}\u{1F324}-\u{1F32C}\u{1F336}\u{1F37D}\u{1F396}\u{1F397}\u{1F399}-\u{1F39B}\u{1F39E}\u{1F39F}\u{1F3CD}\u{1F3CE}\u{1F3D4}-\u{1F3DF}\u{1F3F5}\u{1F3F7}\u{1F43F}\u{1F4FD}\u{1F549}\u{1F54A}\u{1F56F}\u{1F570}\u{1F573}\u{1F576}-\u{1F579}\u{1F587}\u{1F58A}-\u{1F58D}\u{1F5A5}\u{1F5A8}\u{1F5B1}\u{1F5B2}\u{1F5BC}\u{1F5C2}-\u{1F5C4}\u{1F5D1}-\u{1F5D3}\u{1F5DC}-\u{1F5DE}\u{1F5E1}\u{1F5E3}\u{1F5E8}\u{1F5EF}\u{1F5F3}\u{1F5FA}\u{1F6CB}\u{1F6CD}-\u{1F6CF}\u{1F6E0}-\u{1F6E5}\u{1F6E9}\u{1F6F0}\u{1F6F3}])\uFE0F|\u{1F3F3}\uFE0F\u200D\u{1F308}|\u{1F469}\u200D\u{1F467}|\u{1F469}\u200D\u{1F466}|\u{1F635}\u200D\u{1F4AB}|\u{1F62E}\u200D\u{1F4A8}|\u{1F415}\u200D\u{1F9BA}|\u{1F9D1}(?:\u{1F3FF}|\u{1F3FE}|\u{1F3FD}|\u{1F3FC}|\u{1F3FB})?|\u{1F469}(?:\u{1F3FF}|\u{1F3FE}|\u{1F3FD}|\u{1F3FC}|\u{1F3FB})?|\u{1F1FD}\u{1F1F0}|\u{1F1F6}\u{1F1E6}|\u{1F1F4}\u{1F1F2}|\u{1F408}\u200D\u2B1B|\u2764\uFE0F\u200D[\u{1F525}\u{1FA79}]|\u{1F441}\uFE0F|\u{1F3F3}\uFE0F|\u{1F1FF}[\u{1F1E6}\u{1F1F2}\u{1F1FC}]|\u{1F1FE}[\u{1F1EA}\u{1F1F9}]|\u{1F1FC}[\u{1F1EB}\u{1F1F8}]|\u{1F1FB}[\u{1F1E6}\u{1F1E8}\u{1F1EA}\u{1F1EC}\u{1F1EE}\u{1F1F3}\u{1F1FA}]|\u{1F1FA}[\u{1F1E6}\u{1F1EC}\u{1F1F2}\u{1F1F3}\u{1F1F8}\u{1F1FE}\u{1F1FF}]|\u{1F1F9}[\u{1F1E6}\u{1F1E8}\u{1F1E9}\u{1F1EB}-\u{1F1ED}\u{1F1EF}-\u{1F1F4}\u{1F1F7}\u{1F1F9}\u{1F1FB}\u{1F1FC}\u{1F1FF}]|\u{1F1F8}[\u{1F1E6}-\u{1F1EA}\u{1F1EC}-\u{1F1F4}\u{1F1F7}-\u{1F1F9}\u{1F1FB}\u{1F1FD}-\u{1F1FF}]|\u{1F1F7}[\u{1F1EA}\u{1F1F4}\u{1F1F8}\u{1F1FA}\u{1F1FC}]|\u{1F1F5}[\u{1F1E6}\u{1F1EA}-\u{1F1ED}\u{1F1F0}-\u{1F1F3}\u{1F1F7}-\u{1F1F9}\u{1F1FC}\u{1F1FE}]|\u{1F1F3}[\u{1F1E6}\u{1F1E8}\u{1F1EA}-\u{1F1EC}\u{1F1EE}\u{1F1F1}\u{1F1F4}\u{1F1F5}\u{1F1F7}\u{1F1FA}\u{1F1FF}]|\u{1F1F2}[\u{1F1E6}\u{1F1E8}-\u{1F1ED}\u{1F1F0}-\u{1F1FF}]|\u{1F1F1}[\u{1F1E6}-\u{1F1E8}\u{1F1EE}\u{1F1F0}\u{1F1F7}-\u{1F1FB}\u{1F1FE}]|\u{1F1F0}[\u{1F1EA}\u{1F1EC}-\u{1F1EE}\u{1F1F2}\u{1F1F3}\u{1F1F5}\u{1F1F7}\u{1F1FC}\u{1F1FE}\u{1F1FF}]|\u{1F1EF}[\u{1F1EA}\u{1F1F2}\u{1F1F4}\u{1F1F5}]|\u{1F1EE}[\u{1F1E8}-\u{1F1EA}\u{1F1F1}-\u{1F1F4}\u{1F1F6}-\u{1F1F9}]|\u{1F1ED}[\u{1F1F0}\u{1F1F2}\u{1F1F3}\u{1F1F7}\u{1F1F9}\u{1F1FA}]|\u{1F1EC}[\u{1F1E6}\u{1F1E7}\u{1F1E9}-\u{1F1EE}\u{1F1F1}-\u{1F1F3}\u{1F1F5}-\u{1F1FA}\u{1F1FC}\u{1F1FE}]|\u{1F1EB}[\u{1F1EE}-\u{1F1F0}\u{1F1F2}\u{1F1F4}\u{1F1F7}]|\u{1F1EA}[\u{1F1E6}\u{1F1E8}\u{1F1EA}\u{1F1EC}\u{1F1ED}\u{1F1F7}-\u{1F1FA}]|\u{1F1E9}[\u{1F1EA}\u{1F1EC}\u{1F1EF}\u{1F1F0}\u{1F1F2}\u{1F1F4}\u{1F1FF}]|\u{1F1E8}[\u{1F1E6}\u{1F1E8}\u{1F1E9}\u{1F1EB}-\u{1F1EE}\u{1F1F0}-\u{1F1F5}\u{1F1F7}\u{1F1FA}-\u{1F1FF}]|\u{1F1E7}[\u{1F1E6}\u{1F1E7}\u{1F1E9}-\u{1F1EF}\u{1F1F1}-\u{1F1F4}\u{1F1F6}-\u{1F1F9}\u{1F1FB}\u{1F1FC}\u{1F1FE}\u{1F1FF}]|\u{1F1E6}[\u{1F1E8}-\u{1F1EC}\u{1F1EE}\u{1F1F1}\u{1F1F2}\u{1F1F4}\u{1F1F6}-\u{1F1FA}\u{1F1FC}\u{1F1FD}\u{1F1FF}]|[#\*0-9]\uFE0F\u20E3|\u2764\uFE0F|[\u{1F3C3}\u{1F3C4}\u{1F3CA}\u{1F46E}\u{1F470}\u{1F471}\u{1F473}\u{1F477}\u{1F481}\u{1F482}\u{1F486}\u{1F487}\u{1F645}-\u{1F647}\u{1F64B}\u{1F64D}\u{1F64E}\u{1F6A3}\u{1F6B4}-\u{1F6B6}\u{1F926}\u{1F935}\u{1F937}-\u{1F939}\u{1F93D}\u{1F93E}\u{1F9B8}\u{1F9B9}\u{1F9CD}-\u{1F9CF}\u{1F9D4}\u{1F9D6}-\u{1F9DD}][\u{1F3FB}-\u{1F3FF}]|[\u26F9\u{1F3CB}\u{1F3CC}\u{1F575}][\uFE0F\u{1F3FB}-\u{1F3FF}]|\u{1F3F4}|[\u270A\u270B\u{1F385}\u{1F3C2}\u{1F3C7}\u{1F442}\u{1F443}\u{1F446}-\u{1F450}\u{1F466}\u{1F467}\u{1F46B}-\u{1F46D}\u{1F472}\u{1F474}-\u{1F476}\u{1F478}\u{1F47C}\u{1F483}\u{1F485}\u{1F48F}\u{1F491}\u{1F4AA}\u{1F57A}\u{1F595}\u{1F596}\u{1F64C}\u{1F64F}\u{1F6C0}\u{1F6CC}\u{1F90C}\u{1F90F}\u{1F918}-\u{1F91C}\u{1F91E}\u{1F91F}\u{1F930}-\u{1F934}\u{1F936}\u{1F977}\u{1F9B5}\u{1F9B6}\u{1F9BB}\u{1F9D2}\u{1F9D3}\u{1F9D5}][\u{1F3FB}-\u{1F3FF}]|[\u261D\u270C\u270D\u{1F574}\u{1F590}][\uFE0F\u{1F3FB}-\u{1F3FF}]|[\u270A\u270B\u{1F385}\u{1F3C2}\u{1F3C7}\u{1F408}\u{1F415}\u{1F43B}\u{1F442}\u{1F443}\u{1F446}-\u{1F450}\u{1F466}\u{1F467}\u{1F46B}-\u{1F46D}\u{1F472}\u{1F474}-\u{1F476}\u{1F478}\u{1F47C}\u{1F483}\u{1F485}\u{1F48F}\u{1F491}\u{1F4AA}\u{1F57A}\u{1F595}\u{1F596}\u{1F62E}\u{1F635}\u{1F636}\u{1F64C}\u{1F64F}\u{1F6C0}\u{1F6CC}\u{1F90C}\u{1F90F}\u{1F918}-\u{1F91C}\u{1F91E}\u{1F91F}\u{1F930}-\u{1F934}\u{1F936}\u{1F977}\u{1F9B5}\u{1F9B6}\u{1F9BB}\u{1F9D2}\u{1F9D3}\u{1F9D5}]|[\u{1F3C3}\u{1F3C4}\u{1F3CA}\u{1F46E}\u{1F470}\u{1F471}\u{1F473}\u{1F477}\u{1F481}\u{1F482}\u{1F486}\u{1F487}\u{1F645}-\u{1F647}\u{1F64B}\u{1F64D}\u{1F64E}\u{1F6A3}\u{1F6B4}-\u{1F6B6}\u{1F926}\u{1F935}\u{1F937}-\u{1F939}\u{1F93D}\u{1F93E}\u{1F9B8}\u{1F9B9}\u{1F9CD}-\u{1F9CF}\u{1F9D4}\u{1F9D6}-\u{1F9DD}]|[\u{1F46F}\u{1F93C}\u{1F9DE}\u{1F9DF}]|[\u231A\u231B\u23E9-\u23EC\u23F0\u23F3\u25FD\u25FE\u2614\u2615\u2648-\u2653\u267F\u2693\u26A1\u26AA\u26AB\u26BD\u26BE\u26C4\u26C5\u26CE\u26D4\u26EA\u26F2\u26F3\u26F5\u26FA\u26FD\u2705\u2728\u274C\u274E\u2753-\u2755\u2757\u2795-\u2797\u27B0\u27BF\u2B1B\u2B1C\u2B50\u2B55\u{1F004}\u{1F0CF}\u{1F18E}\u{1F191}-\u{1F19A}\u{1F201}\u{1F21A}\u{1F22F}\u{1F232}-\u{1F236}\u{1F238}-\u{1F23A}\u{1F250}\u{1F251}\u{1F300}-\u{1F320}\u{1F32D}-\u{1F335}\u{1F337}-\u{1F37C}\u{1F37E}-\u{1F384}\u{1F386}-\u{1F393}\u{1F3A0}-\u{1F3C1}\u{1F3C5}\u{1F3C6}\u{1F3C8}\u{1F3C9}\u{1F3CF}-\u{1F3D3}\u{1F3E0}-\u{1F3F0}\u{1F3F8}-\u{1F407}\u{1F409}-\u{1F414}\u{1F416}-\u{1F43A}\u{1F43C}-\u{1F43E}\u{1F440}\u{1F444}\u{1F445}\u{1F451}-\u{1F465}\u{1F46A}\u{1F479}-\u{1F47B}\u{1F47D}-\u{1F480}\u{1F484}\u{1F488}-\u{1F48E}\u{1F490}\u{1F492}-\u{1F4A9}\u{1F4AB}-\u{1F4FC}\u{1F4FF}-\u{1F53D}\u{1F54B}-\u{1F54E}\u{1F550}-\u{1F567}\u{1F5A4}\u{1F5FB}-\u{1F62D}\u{1F62F}-\u{1F634}\u{1F637}-\u{1F644}\u{1F648}-\u{1F64A}\u{1F680}-\u{1F6A2}\u{1F6A4}-\u{1F6B3}\u{1F6B7}-\u{1F6BF}\u{1F6C1}-\u{1F6C5}\u{1F6D0}-\u{1F6D2}\u{1F6D5}-\u{1F6D7}\u{1F6EB}\u{1F6EC}\u{1F6F4}-\u{1F6FC}\u{1F7E0}-\u{1F7EB}\u{1F90D}\u{1F90E}\u{1F910}-\u{1F917}\u{1F91D}\u{1F920}-\u{1F925}\u{1F927}-\u{1F92F}\u{1F93A}\u{1F93F}-\u{1F945}\u{1F947}-\u{1F976}\u{1F978}\u{1F97A}-\u{1F9B4}\u{1F9B7}\u{1F9BA}\u{1F9BC}-\u{1F9CB}\u{1F9D0}\u{1F9E0}-\u{1F9FF}\u{1FA70}-\u{1FA74}\u{1FA78}-\u{1FA7A}\u{1FA80}-\u{1FA86}\u{1FA90}-\u{1FAA8}\u{1FAB0}-\u{1FAB6}\u{1FAC0}-\u{1FAC2}\u{1FAD0}-\u{1FAD6}]/gu;
+};
diff --git a/app/node_modules/emoji-regex/es2015/index.d.ts b/app/node_modules/emoji-regex/es2015/index.d.ts
new file mode 100644
index 0000000..823dfa6
--- /dev/null
+++ b/app/node_modules/emoji-regex/es2015/index.d.ts
@@ -0,0 +1,5 @@
+declare module 'emoji-regex/es2015' {
+ function emojiRegex(): RegExp;
+
+ export = emojiRegex;
+}
diff --git a/app/node_modules/emoji-regex/es2015/index.js b/app/node_modules/emoji-regex/es2015/index.js
new file mode 100644
index 0000000..1a4fc8d
--- /dev/null
+++ b/app/node_modules/emoji-regex/es2015/index.js
@@ -0,0 +1,6 @@
+"use strict";
+
+module.exports = () => {
+ // https://mths.be/emoji
+ return /\u{1F3F4}\u{E0067}\u{E0062}(?:\u{E0077}\u{E006C}\u{E0073}|\u{E0073}\u{E0063}\u{E0074}|\u{E0065}\u{E006E}\u{E0067})\u{E007F}|(?:\u{1F9D1}\u{1F3FF}\u200D\u2764\uFE0F\u200D(?:\u{1F48B}\u200D)?\u{1F9D1}|\u{1F469}\u{1F3FF}\u200D\u{1F91D}\u200D[\u{1F468}\u{1F469}])[\u{1F3FB}-\u{1F3FE}]|(?:\u{1F9D1}\u{1F3FE}\u200D\u2764\uFE0F\u200D(?:\u{1F48B}\u200D)?\u{1F9D1}|\u{1F469}\u{1F3FE}\u200D\u{1F91D}\u200D[\u{1F468}\u{1F469}])[\u{1F3FB}-\u{1F3FD}\u{1F3FF}]|(?:\u{1F9D1}\u{1F3FD}\u200D\u2764\uFE0F\u200D(?:\u{1F48B}\u200D)?\u{1F9D1}|\u{1F469}\u{1F3FD}\u200D\u{1F91D}\u200D[\u{1F468}\u{1F469}])[\u{1F3FB}\u{1F3FC}\u{1F3FE}\u{1F3FF}]|(?:\u{1F9D1}\u{1F3FC}\u200D\u2764\uFE0F\u200D(?:\u{1F48B}\u200D)?\u{1F9D1}|\u{1F469}\u{1F3FC}\u200D\u{1F91D}\u200D[\u{1F468}\u{1F469}])[\u{1F3FB}\u{1F3FD}-\u{1F3FF}]|(?:\u{1F9D1}\u{1F3FB}\u200D\u2764\uFE0F\u200D(?:\u{1F48B}\u200D)?\u{1F9D1}|\u{1F469}\u{1F3FB}\u200D\u{1F91D}\u200D[\u{1F468}\u{1F469}])[\u{1F3FC}-\u{1F3FF}]|\u{1F468}(?:\u{1F3FB}(?:\u200D(?:\u2764\uFE0F\u200D(?:\u{1F48B}\u200D\u{1F468}[\u{1F3FB}-\u{1F3FF}]|\u{1F468}[\u{1F3FB}-\u{1F3FF}])|\u{1F91D}\u200D\u{1F468}[\u{1F3FC}-\u{1F3FF}]|[\u2695\u2696\u2708]\uFE0F|[\u{1F33E}\u{1F373}\u{1F37C}\u{1F393}\u{1F3A4}\u{1F3A8}\u{1F3EB}\u{1F3ED}\u{1F4BB}\u{1F4BC}\u{1F527}\u{1F52C}\u{1F680}\u{1F692}\u{1F9AF}-\u{1F9B3}\u{1F9BC}\u{1F9BD}]))?|[\u{1F3FC}-\u{1F3FF}]\u200D\u2764\uFE0F\u200D(?:\u{1F48B}\u200D\u{1F468}[\u{1F3FB}-\u{1F3FF}]|\u{1F468}[\u{1F3FB}-\u{1F3FF}])|\u200D(?:\u2764\uFE0F\u200D(?:\u{1F48B}\u200D)?\u{1F468}|[\u{1F468}\u{1F469}]\u200D(?:\u{1F466}\u200D\u{1F466}|\u{1F467}\u200D[\u{1F466}\u{1F467}])|\u{1F466}\u200D\u{1F466}|\u{1F467}\u200D[\u{1F466}\u{1F467}]|[\u{1F33E}\u{1F373}\u{1F37C}\u{1F393}\u{1F3A4}\u{1F3A8}\u{1F3EB}\u{1F3ED}\u{1F4BB}\u{1F4BC}\u{1F527}\u{1F52C}\u{1F680}\u{1F692}\u{1F9AF}-\u{1F9B3}\u{1F9BC}\u{1F9BD}])|\u{1F3FF}\u200D(?:\u{1F91D}\u200D\u{1F468}[\u{1F3FB}-\u{1F3FE}]|[\u{1F33E}\u{1F373}\u{1F37C}\u{1F393}\u{1F3A4}\u{1F3A8}\u{1F3EB}\u{1F3ED}\u{1F4BB}\u{1F4BC}\u{1F527}\u{1F52C}\u{1F680}\u{1F692}\u{1F9AF}-\u{1F9B3}\u{1F9BC}\u{1F9BD}])|\u{1F3FE}\u200D(?:\u{1F91D}\u200D\u{1F468}[\u{1F3FB}-\u{1F3FD}\u{1F3FF}]|[\u{1F33E}\u{1F373}\u{1F37C}\u{1F393}\u{1F3A4}\u{1F3A8}\u{1F3EB}\u{1F3ED}\u{1F4BB}\u{1F4BC}\u{1F527}\u{1F52C}\u{1F680}\u{1F692}\u{1F9AF}-\u{1F9B3}\u{1F9BC}\u{1F9BD}])|\u{1F3FD}\u200D(?:\u{1F91D}\u200D\u{1F468}[\u{1F3FB}\u{1F3FC}\u{1F3FE}\u{1F3FF}]|[\u{1F33E}\u{1F373}\u{1F37C}\u{1F393}\u{1F3A4}\u{1F3A8}\u{1F3EB}\u{1F3ED}\u{1F4BB}\u{1F4BC}\u{1F527}\u{1F52C}\u{1F680}\u{1F692}\u{1F9AF}-\u{1F9B3}\u{1F9BC}\u{1F9BD}])|\u{1F3FC}\u200D(?:\u{1F91D}\u200D\u{1F468}[\u{1F3FB}\u{1F3FD}-\u{1F3FF}]|[\u{1F33E}\u{1F373}\u{1F37C}\u{1F393}\u{1F3A4}\u{1F3A8}\u{1F3EB}\u{1F3ED}\u{1F4BB}\u{1F4BC}\u{1F527}\u{1F52C}\u{1F680}\u{1F692}\u{1F9AF}-\u{1F9B3}\u{1F9BC}\u{1F9BD}])|(?:\u{1F3FF}\u200D[\u2695\u2696\u2708]|\u{1F3FE}\u200D[\u2695\u2696\u2708]|\u{1F3FD}\u200D[\u2695\u2696\u2708]|\u{1F3FC}\u200D[\u2695\u2696\u2708]|\u200D[\u2695\u2696\u2708])\uFE0F|\u200D(?:[\u{1F468}\u{1F469}]\u200D[\u{1F466}\u{1F467}]|[\u{1F466}\u{1F467}])|\u{1F3FF}|\u{1F3FE}|\u{1F3FD}|\u{1F3FC})?|(?:\u{1F469}(?:\u{1F3FB}\u200D\u2764\uFE0F\u200D(?:\u{1F48B}\u200D[\u{1F468}\u{1F469}]|[\u{1F468}\u{1F469}])|[\u{1F3FC}-\u{1F3FF}]\u200D\u2764\uFE0F\u200D(?:\u{1F48B}\u200D[\u{1F468}\u{1F469}]|[\u{1F468}\u{1F469}]))|\u{1F9D1}[\u{1F3FB}-\u{1F3FF}]\u200D\u{1F91D}\u200D\u{1F9D1})[\u{1F3FB}-\u{1F3FF}]|\u{1F469}\u200D\u{1F469}\u200D(?:\u{1F466}\u200D\u{1F466}|\u{1F467}\u200D[\u{1F466}\u{1F467}])|\u{1F469}(?:\u200D(?:\u2764\uFE0F\u200D(?:\u{1F48B}\u200D[\u{1F468}\u{1F469}]|[\u{1F468}\u{1F469}])|[\u{1F33E}\u{1F373}\u{1F37C}\u{1F393}\u{1F3A4}\u{1F3A8}\u{1F3EB}\u{1F3ED}\u{1F4BB}\u{1F4BC}\u{1F527}\u{1F52C}\u{1F680}\u{1F692}\u{1F9AF}-\u{1F9B3}\u{1F9BC}\u{1F9BD}])|\u{1F3FF}\u200D[\u{1F33E}\u{1F373}\u{1F37C}\u{1F393}\u{1F3A4}\u{1F3A8}\u{1F3EB}\u{1F3ED}\u{1F4BB}\u{1F4BC}\u{1F527}\u{1F52C}\u{1F680}\u{1F692}\u{1F9AF}-\u{1F9B3}\u{1F9BC}\u{1F9BD}]|\u{1F3FE}\u200D[\u{1F33E}\u{1F373}\u{1F37C}\u{1F393}\u{1F3A4}\u{1F3A8}\u{1F3EB}\u{1F3ED}\u{1F4BB}\u{1F4BC}\u{1F527}\u{1F52C}\u{1F680}\u{1F692}\u{1F9AF}-\u{1F9B3}\u{1F9BC}\u{1F9BD}]|\u{1F3FD}\u200D[\u{1F33E}\u{1F373}\u{1F37C}\u{1F393}\u{1F3A4}\u{1F3A8}\u{1F3EB}\u{1F3ED}\u{1F4BB}\u{1F4BC}\u{1F527}\u{1F52C}\u{1F680}\u{1F692}\u{1F9AF}-\u{1F9B3}\u{1F9BC}\u{1F9BD}]|\u{1F3FC}\u200D[\u{1F33E}\u{1F373}\u{1F37C}\u{1F393}\u{1F3A4}\u{1F3A8}\u{1F3EB}\u{1F3ED}\u{1F4BB}\u{1F4BC}\u{1F527}\u{1F52C}\u{1F680}\u{1F692}\u{1F9AF}-\u{1F9B3}\u{1F9BC}\u{1F9BD}]|\u{1F3FB}\u200D[\u{1F33E}\u{1F373}\u{1F37C}\u{1F393}\u{1F3A4}\u{1F3A8}\u{1F3EB}\u{1F3ED}\u{1F4BB}\u{1F4BC}\u{1F527}\u{1F52C}\u{1F680}\u{1F692}\u{1F9AF}-\u{1F9B3}\u{1F9BC}\u{1F9BD}])|\u{1F9D1}(?:\u200D(?:\u{1F91D}\u200D\u{1F9D1}|[\u{1F33E}\u{1F373}\u{1F37C}\u{1F384}\u{1F393}\u{1F3A4}\u{1F3A8}\u{1F3EB}\u{1F3ED}\u{1F4BB}\u{1F4BC}\u{1F527}\u{1F52C}\u{1F680}\u{1F692}\u{1F9AF}-\u{1F9B3}\u{1F9BC}\u{1F9BD}])|\u{1F3FF}\u200D[\u{1F33E}\u{1F373}\u{1F37C}\u{1F384}\u{1F393}\u{1F3A4}\u{1F3A8}\u{1F3EB}\u{1F3ED}\u{1F4BB}\u{1F4BC}\u{1F527}\u{1F52C}\u{1F680}\u{1F692}\u{1F9AF}-\u{1F9B3}\u{1F9BC}\u{1F9BD}]|\u{1F3FE}\u200D[\u{1F33E}\u{1F373}\u{1F37C}\u{1F384}\u{1F393}\u{1F3A4}\u{1F3A8}\u{1F3EB}\u{1F3ED}\u{1F4BB}\u{1F4BC}\u{1F527}\u{1F52C}\u{1F680}\u{1F692}\u{1F9AF}-\u{1F9B3}\u{1F9BC}\u{1F9BD}]|\u{1F3FD}\u200D[\u{1F33E}\u{1F373}\u{1F37C}\u{1F384}\u{1F393}\u{1F3A4}\u{1F3A8}\u{1F3EB}\u{1F3ED}\u{1F4BB}\u{1F4BC}\u{1F527}\u{1F52C}\u{1F680}\u{1F692}\u{1F9AF}-\u{1F9B3}\u{1F9BC}\u{1F9BD}]|\u{1F3FC}\u200D[\u{1F33E}\u{1F373}\u{1F37C}\u{1F384}\u{1F393}\u{1F3A4}\u{1F3A8}\u{1F3EB}\u{1F3ED}\u{1F4BB}\u{1F4BC}\u{1F527}\u{1F52C}\u{1F680}\u{1F692}\u{1F9AF}-\u{1F9B3}\u{1F9BC}\u{1F9BD}]|\u{1F3FB}\u200D[\u{1F33E}\u{1F373}\u{1F37C}\u{1F384}\u{1F393}\u{1F3A4}\u{1F3A8}\u{1F3EB}\u{1F3ED}\u{1F4BB}\u{1F4BC}\u{1F527}\u{1F52C}\u{1F680}\u{1F692}\u{1F9AF}-\u{1F9B3}\u{1F9BC}\u{1F9BD}])|\u{1F469}\u200D\u{1F466}\u200D\u{1F466}|\u{1F469}\u200D\u{1F469}\u200D[\u{1F466}\u{1F467}]|\u{1F469}\u200D\u{1F467}\u200D[\u{1F466}\u{1F467}]|(?:\u{1F441}\uFE0F\u200D\u{1F5E8}|\u{1F9D1}(?:\u{1F3FF}\u200D[\u2695\u2696\u2708]|\u{1F3FE}\u200D[\u2695\u2696\u2708]|\u{1F3FD}\u200D[\u2695\u2696\u2708]|\u{1F3FC}\u200D[\u2695\u2696\u2708]|\u{1F3FB}\u200D[\u2695\u2696\u2708]|\u200D[\u2695\u2696\u2708])|\u{1F469}(?:\u{1F3FF}\u200D[\u2695\u2696\u2708]|\u{1F3FE}\u200D[\u2695\u2696\u2708]|\u{1F3FD}\u200D[\u2695\u2696\u2708]|\u{1F3FC}\u200D[\u2695\u2696\u2708]|\u{1F3FB}\u200D[\u2695\u2696\u2708]|\u200D[\u2695\u2696\u2708])|\u{1F636}\u200D\u{1F32B}|\u{1F3F3}\uFE0F\u200D\u26A7|\u{1F43B}\u200D\u2744|(?:[\u{1F3C3}\u{1F3C4}\u{1F3CA}\u{1F46E}\u{1F470}\u{1F471}\u{1F473}\u{1F477}\u{1F481}\u{1F482}\u{1F486}\u{1F487}\u{1F645}-\u{1F647}\u{1F64B}\u{1F64D}\u{1F64E}\u{1F6A3}\u{1F6B4}-\u{1F6B6}\u{1F926}\u{1F935}\u{1F937}-\u{1F939}\u{1F93D}\u{1F93E}\u{1F9B8}\u{1F9B9}\u{1F9CD}-\u{1F9CF}\u{1F9D4}\u{1F9D6}-\u{1F9DD}][\u{1F3FB}-\u{1F3FF}]|[\u{1F46F}\u{1F93C}\u{1F9DE}\u{1F9DF}])\u200D[\u2640\u2642]|[\u26F9\u{1F3CB}\u{1F3CC}\u{1F575}][\uFE0F\u{1F3FB}-\u{1F3FF}]\u200D[\u2640\u2642]|\u{1F3F4}\u200D\u2620|[\u{1F3C3}\u{1F3C4}\u{1F3CA}\u{1F46E}\u{1F470}\u{1F471}\u{1F473}\u{1F477}\u{1F481}\u{1F482}\u{1F486}\u{1F487}\u{1F645}-\u{1F647}\u{1F64B}\u{1F64D}\u{1F64E}\u{1F6A3}\u{1F6B4}-\u{1F6B6}\u{1F926}\u{1F935}\u{1F937}-\u{1F939}\u{1F93D}\u{1F93E}\u{1F9B8}\u{1F9B9}\u{1F9CD}-\u{1F9CF}\u{1F9D4}\u{1F9D6}-\u{1F9DD}]\u200D[\u2640\u2642]|[\xA9\xAE\u203C\u2049\u2122\u2139\u2194-\u2199\u21A9\u21AA\u2328\u23CF\u23ED-\u23EF\u23F1\u23F2\u23F8-\u23FA\u24C2\u25AA\u25AB\u25B6\u25C0\u25FB\u25FC\u2600-\u2604\u260E\u2611\u2618\u2620\u2622\u2623\u2626\u262A\u262E\u262F\u2638-\u263A\u2640\u2642\u265F\u2660\u2663\u2665\u2666\u2668\u267B\u267E\u2692\u2694-\u2697\u2699\u269B\u269C\u26A0\u26A7\u26B0\u26B1\u26C8\u26CF\u26D1\u26D3\u26E9\u26F0\u26F1\u26F4\u26F7\u26F8\u2702\u2708\u2709\u270F\u2712\u2714\u2716\u271D\u2721\u2733\u2734\u2744\u2747\u2763\u27A1\u2934\u2935\u2B05-\u2B07\u3030\u303D\u3297\u3299\u{1F170}\u{1F171}\u{1F17E}\u{1F17F}\u{1F202}\u{1F237}\u{1F321}\u{1F324}-\u{1F32C}\u{1F336}\u{1F37D}\u{1F396}\u{1F397}\u{1F399}-\u{1F39B}\u{1F39E}\u{1F39F}\u{1F3CD}\u{1F3CE}\u{1F3D4}-\u{1F3DF}\u{1F3F5}\u{1F3F7}\u{1F43F}\u{1F4FD}\u{1F549}\u{1F54A}\u{1F56F}\u{1F570}\u{1F573}\u{1F576}-\u{1F579}\u{1F587}\u{1F58A}-\u{1F58D}\u{1F5A5}\u{1F5A8}\u{1F5B1}\u{1F5B2}\u{1F5BC}\u{1F5C2}-\u{1F5C4}\u{1F5D1}-\u{1F5D3}\u{1F5DC}-\u{1F5DE}\u{1F5E1}\u{1F5E3}\u{1F5E8}\u{1F5EF}\u{1F5F3}\u{1F5FA}\u{1F6CB}\u{1F6CD}-\u{1F6CF}\u{1F6E0}-\u{1F6E5}\u{1F6E9}\u{1F6F0}\u{1F6F3}])\uFE0F|\u{1F3F3}\uFE0F\u200D\u{1F308}|\u{1F469}\u200D\u{1F467}|\u{1F469}\u200D\u{1F466}|\u{1F635}\u200D\u{1F4AB}|\u{1F62E}\u200D\u{1F4A8}|\u{1F415}\u200D\u{1F9BA}|\u{1F9D1}(?:\u{1F3FF}|\u{1F3FE}|\u{1F3FD}|\u{1F3FC}|\u{1F3FB})?|\u{1F469}(?:\u{1F3FF}|\u{1F3FE}|\u{1F3FD}|\u{1F3FC}|\u{1F3FB})?|\u{1F1FD}\u{1F1F0}|\u{1F1F6}\u{1F1E6}|\u{1F1F4}\u{1F1F2}|\u{1F408}\u200D\u2B1B|\u2764\uFE0F\u200D[\u{1F525}\u{1FA79}]|\u{1F441}\uFE0F|\u{1F3F3}\uFE0F|\u{1F1FF}[\u{1F1E6}\u{1F1F2}\u{1F1FC}]|\u{1F1FE}[\u{1F1EA}\u{1F1F9}]|\u{1F1FC}[\u{1F1EB}\u{1F1F8}]|\u{1F1FB}[\u{1F1E6}\u{1F1E8}\u{1F1EA}\u{1F1EC}\u{1F1EE}\u{1F1F3}\u{1F1FA}]|\u{1F1FA}[\u{1F1E6}\u{1F1EC}\u{1F1F2}\u{1F1F3}\u{1F1F8}\u{1F1FE}\u{1F1FF}]|\u{1F1F9}[\u{1F1E6}\u{1F1E8}\u{1F1E9}\u{1F1EB}-\u{1F1ED}\u{1F1EF}-\u{1F1F4}\u{1F1F7}\u{1F1F9}\u{1F1FB}\u{1F1FC}\u{1F1FF}]|\u{1F1F8}[\u{1F1E6}-\u{1F1EA}\u{1F1EC}-\u{1F1F4}\u{1F1F7}-\u{1F1F9}\u{1F1FB}\u{1F1FD}-\u{1F1FF}]|\u{1F1F7}[\u{1F1EA}\u{1F1F4}\u{1F1F8}\u{1F1FA}\u{1F1FC}]|\u{1F1F5}[\u{1F1E6}\u{1F1EA}-\u{1F1ED}\u{1F1F0}-\u{1F1F3}\u{1F1F7}-\u{1F1F9}\u{1F1FC}\u{1F1FE}]|\u{1F1F3}[\u{1F1E6}\u{1F1E8}\u{1F1EA}-\u{1F1EC}\u{1F1EE}\u{1F1F1}\u{1F1F4}\u{1F1F5}\u{1F1F7}\u{1F1FA}\u{1F1FF}]|\u{1F1F2}[\u{1F1E6}\u{1F1E8}-\u{1F1ED}\u{1F1F0}-\u{1F1FF}]|\u{1F1F1}[\u{1F1E6}-\u{1F1E8}\u{1F1EE}\u{1F1F0}\u{1F1F7}-\u{1F1FB}\u{1F1FE}]|\u{1F1F0}[\u{1F1EA}\u{1F1EC}-\u{1F1EE}\u{1F1F2}\u{1F1F3}\u{1F1F5}\u{1F1F7}\u{1F1FC}\u{1F1FE}\u{1F1FF}]|\u{1F1EF}[\u{1F1EA}\u{1F1F2}\u{1F1F4}\u{1F1F5}]|\u{1F1EE}[\u{1F1E8}-\u{1F1EA}\u{1F1F1}-\u{1F1F4}\u{1F1F6}-\u{1F1F9}]|\u{1F1ED}[\u{1F1F0}\u{1F1F2}\u{1F1F3}\u{1F1F7}\u{1F1F9}\u{1F1FA}]|\u{1F1EC}[\u{1F1E6}\u{1F1E7}\u{1F1E9}-\u{1F1EE}\u{1F1F1}-\u{1F1F3}\u{1F1F5}-\u{1F1FA}\u{1F1FC}\u{1F1FE}]|\u{1F1EB}[\u{1F1EE}-\u{1F1F0}\u{1F1F2}\u{1F1F4}\u{1F1F7}]|\u{1F1EA}[\u{1F1E6}\u{1F1E8}\u{1F1EA}\u{1F1EC}\u{1F1ED}\u{1F1F7}-\u{1F1FA}]|\u{1F1E9}[\u{1F1EA}\u{1F1EC}\u{1F1EF}\u{1F1F0}\u{1F1F2}\u{1F1F4}\u{1F1FF}]|\u{1F1E8}[\u{1F1E6}\u{1F1E8}\u{1F1E9}\u{1F1EB}-\u{1F1EE}\u{1F1F0}-\u{1F1F5}\u{1F1F7}\u{1F1FA}-\u{1F1FF}]|\u{1F1E7}[\u{1F1E6}\u{1F1E7}\u{1F1E9}-\u{1F1EF}\u{1F1F1}-\u{1F1F4}\u{1F1F6}-\u{1F1F9}\u{1F1FB}\u{1F1FC}\u{1F1FE}\u{1F1FF}]|\u{1F1E6}[\u{1F1E8}-\u{1F1EC}\u{1F1EE}\u{1F1F1}\u{1F1F2}\u{1F1F4}\u{1F1F6}-\u{1F1FA}\u{1F1FC}\u{1F1FD}\u{1F1FF}]|[#\*0-9]\uFE0F\u20E3|\u2764\uFE0F|[\u{1F3C3}\u{1F3C4}\u{1F3CA}\u{1F46E}\u{1F470}\u{1F471}\u{1F473}\u{1F477}\u{1F481}\u{1F482}\u{1F486}\u{1F487}\u{1F645}-\u{1F647}\u{1F64B}\u{1F64D}\u{1F64E}\u{1F6A3}\u{1F6B4}-\u{1F6B6}\u{1F926}\u{1F935}\u{1F937}-\u{1F939}\u{1F93D}\u{1F93E}\u{1F9B8}\u{1F9B9}\u{1F9CD}-\u{1F9CF}\u{1F9D4}\u{1F9D6}-\u{1F9DD}][\u{1F3FB}-\u{1F3FF}]|[\u26F9\u{1F3CB}\u{1F3CC}\u{1F575}][\uFE0F\u{1F3FB}-\u{1F3FF}]|\u{1F3F4}|[\u270A\u270B\u{1F385}\u{1F3C2}\u{1F3C7}\u{1F442}\u{1F443}\u{1F446}-\u{1F450}\u{1F466}\u{1F467}\u{1F46B}-\u{1F46D}\u{1F472}\u{1F474}-\u{1F476}\u{1F478}\u{1F47C}\u{1F483}\u{1F485}\u{1F48F}\u{1F491}\u{1F4AA}\u{1F57A}\u{1F595}\u{1F596}\u{1F64C}\u{1F64F}\u{1F6C0}\u{1F6CC}\u{1F90C}\u{1F90F}\u{1F918}-\u{1F91C}\u{1F91E}\u{1F91F}\u{1F930}-\u{1F934}\u{1F936}\u{1F977}\u{1F9B5}\u{1F9B6}\u{1F9BB}\u{1F9D2}\u{1F9D3}\u{1F9D5}][\u{1F3FB}-\u{1F3FF}]|[\u261D\u270C\u270D\u{1F574}\u{1F590}][\uFE0F\u{1F3FB}-\u{1F3FF}]|[\u270A\u270B\u{1F385}\u{1F3C2}\u{1F3C7}\u{1F408}\u{1F415}\u{1F43B}\u{1F442}\u{1F443}\u{1F446}-\u{1F450}\u{1F466}\u{1F467}\u{1F46B}-\u{1F46D}\u{1F472}\u{1F474}-\u{1F476}\u{1F478}\u{1F47C}\u{1F483}\u{1F485}\u{1F48F}\u{1F491}\u{1F4AA}\u{1F57A}\u{1F595}\u{1F596}\u{1F62E}\u{1F635}\u{1F636}\u{1F64C}\u{1F64F}\u{1F6C0}\u{1F6CC}\u{1F90C}\u{1F90F}\u{1F918}-\u{1F91C}\u{1F91E}\u{1F91F}\u{1F930}-\u{1F934}\u{1F936}\u{1F977}\u{1F9B5}\u{1F9B6}\u{1F9BB}\u{1F9D2}\u{1F9D3}\u{1F9D5}]|[\u{1F3C3}\u{1F3C4}\u{1F3CA}\u{1F46E}\u{1F470}\u{1F471}\u{1F473}\u{1F477}\u{1F481}\u{1F482}\u{1F486}\u{1F487}\u{1F645}-\u{1F647}\u{1F64B}\u{1F64D}\u{1F64E}\u{1F6A3}\u{1F6B4}-\u{1F6B6}\u{1F926}\u{1F935}\u{1F937}-\u{1F939}\u{1F93D}\u{1F93E}\u{1F9B8}\u{1F9B9}\u{1F9CD}-\u{1F9CF}\u{1F9D4}\u{1F9D6}-\u{1F9DD}]|[\u{1F46F}\u{1F93C}\u{1F9DE}\u{1F9DF}]|[\u231A\u231B\u23E9-\u23EC\u23F0\u23F3\u25FD\u25FE\u2614\u2615\u2648-\u2653\u267F\u2693\u26A1\u26AA\u26AB\u26BD\u26BE\u26C4\u26C5\u26CE\u26D4\u26EA\u26F2\u26F3\u26F5\u26FA\u26FD\u2705\u2728\u274C\u274E\u2753-\u2755\u2757\u2795-\u2797\u27B0\u27BF\u2B1B\u2B1C\u2B50\u2B55\u{1F004}\u{1F0CF}\u{1F18E}\u{1F191}-\u{1F19A}\u{1F201}\u{1F21A}\u{1F22F}\u{1F232}-\u{1F236}\u{1F238}-\u{1F23A}\u{1F250}\u{1F251}\u{1F300}-\u{1F320}\u{1F32D}-\u{1F335}\u{1F337}-\u{1F37C}\u{1F37E}-\u{1F384}\u{1F386}-\u{1F393}\u{1F3A0}-\u{1F3C1}\u{1F3C5}\u{1F3C6}\u{1F3C8}\u{1F3C9}\u{1F3CF}-\u{1F3D3}\u{1F3E0}-\u{1F3F0}\u{1F3F8}-\u{1F407}\u{1F409}-\u{1F414}\u{1F416}-\u{1F43A}\u{1F43C}-\u{1F43E}\u{1F440}\u{1F444}\u{1F445}\u{1F451}-\u{1F465}\u{1F46A}\u{1F479}-\u{1F47B}\u{1F47D}-\u{1F480}\u{1F484}\u{1F488}-\u{1F48E}\u{1F490}\u{1F492}-\u{1F4A9}\u{1F4AB}-\u{1F4FC}\u{1F4FF}-\u{1F53D}\u{1F54B}-\u{1F54E}\u{1F550}-\u{1F567}\u{1F5A4}\u{1F5FB}-\u{1F62D}\u{1F62F}-\u{1F634}\u{1F637}-\u{1F644}\u{1F648}-\u{1F64A}\u{1F680}-\u{1F6A2}\u{1F6A4}-\u{1F6B3}\u{1F6B7}-\u{1F6BF}\u{1F6C1}-\u{1F6C5}\u{1F6D0}-\u{1F6D2}\u{1F6D5}-\u{1F6D7}\u{1F6EB}\u{1F6EC}\u{1F6F4}-\u{1F6FC}\u{1F7E0}-\u{1F7EB}\u{1F90D}\u{1F90E}\u{1F910}-\u{1F917}\u{1F91D}\u{1F920}-\u{1F925}\u{1F927}-\u{1F92F}\u{1F93A}\u{1F93F}-\u{1F945}\u{1F947}-\u{1F976}\u{1F978}\u{1F97A}-\u{1F9B4}\u{1F9B7}\u{1F9BA}\u{1F9BC}-\u{1F9CB}\u{1F9D0}\u{1F9E0}-\u{1F9FF}\u{1FA70}-\u{1FA74}\u{1FA78}-\u{1FA7A}\u{1FA80}-\u{1FA86}\u{1FA90}-\u{1FAA8}\u{1FAB0}-\u{1FAB6}\u{1FAC0}-\u{1FAC2}\u{1FAD0}-\u{1FAD6}]|[\u231A\u231B\u23E9-\u23EC\u23F0\u23F3\u25FD\u25FE\u2614\u2615\u2648-\u2653\u267F\u2693\u26A1\u26AA\u26AB\u26BD\u26BE\u26C4\u26C5\u26CE\u26D4\u26EA\u26F2\u26F3\u26F5\u26FA\u26FD\u2705\u270A\u270B\u2728\u274C\u274E\u2753-\u2755\u2757\u2795-\u2797\u27B0\u27BF\u2B1B\u2B1C\u2B50\u2B55\u{1F004}\u{1F0CF}\u{1F18E}\u{1F191}-\u{1F19A}\u{1F1E6}-\u{1F1FF}\u{1F201}\u{1F21A}\u{1F22F}\u{1F232}-\u{1F236}\u{1F238}-\u{1F23A}\u{1F250}\u{1F251}\u{1F300}-\u{1F320}\u{1F32D}-\u{1F335}\u{1F337}-\u{1F37C}\u{1F37E}-\u{1F393}\u{1F3A0}-\u{1F3CA}\u{1F3CF}-\u{1F3D3}\u{1F3E0}-\u{1F3F0}\u{1F3F4}\u{1F3F8}-\u{1F43E}\u{1F440}\u{1F442}-\u{1F4FC}\u{1F4FF}-\u{1F53D}\u{1F54B}-\u{1F54E}\u{1F550}-\u{1F567}\u{1F57A}\u{1F595}\u{1F596}\u{1F5A4}\u{1F5FB}-\u{1F64F}\u{1F680}-\u{1F6C5}\u{1F6CC}\u{1F6D0}-\u{1F6D2}\u{1F6D5}-\u{1F6D7}\u{1F6EB}\u{1F6EC}\u{1F6F4}-\u{1F6FC}\u{1F7E0}-\u{1F7EB}\u{1F90C}-\u{1F93A}\u{1F93C}-\u{1F945}\u{1F947}-\u{1F978}\u{1F97A}-\u{1F9CB}\u{1F9CD}-\u{1F9FF}\u{1FA70}-\u{1FA74}\u{1FA78}-\u{1FA7A}\u{1FA80}-\u{1FA86}\u{1FA90}-\u{1FAA8}\u{1FAB0}-\u{1FAB6}\u{1FAC0}-\u{1FAC2}\u{1FAD0}-\u{1FAD6}]|[#\*0-9\xA9\xAE\u203C\u2049\u2122\u2139\u2194-\u2199\u21A9\u21AA\u231A\u231B\u2328\u23CF\u23E9-\u23F3\u23F8-\u23FA\u24C2\u25AA\u25AB\u25B6\u25C0\u25FB-\u25FE\u2600-\u2604\u260E\u2611\u2614\u2615\u2618\u261D\u2620\u2622\u2623\u2626\u262A\u262E\u262F\u2638-\u263A\u2640\u2642\u2648-\u2653\u265F\u2660\u2663\u2665\u2666\u2668\u267B\u267E\u267F\u2692-\u2697\u2699\u269B\u269C\u26A0\u26A1\u26A7\u26AA\u26AB\u26B0\u26B1\u26BD\u26BE\u26C4\u26C5\u26C8\u26CE\u26CF\u26D1\u26D3\u26D4\u26E9\u26EA\u26F0-\u26F5\u26F7-\u26FA\u26FD\u2702\u2705\u2708-\u270D\u270F\u2712\u2714\u2716\u271D\u2721\u2728\u2733\u2734\u2744\u2747\u274C\u274E\u2753-\u2755\u2757\u2763\u2764\u2795-\u2797\u27A1\u27B0\u27BF\u2934\u2935\u2B05-\u2B07\u2B1B\u2B1C\u2B50\u2B55\u3030\u303D\u3297\u3299\u{1F004}\u{1F0CF}\u{1F170}\u{1F171}\u{1F17E}\u{1F17F}\u{1F18E}\u{1F191}-\u{1F19A}\u{1F1E6}-\u{1F1FF}\u{1F201}\u{1F202}\u{1F21A}\u{1F22F}\u{1F232}-\u{1F23A}\u{1F250}\u{1F251}\u{1F300}-\u{1F321}\u{1F324}-\u{1F393}\u{1F396}\u{1F397}\u{1F399}-\u{1F39B}\u{1F39E}-\u{1F3F0}\u{1F3F3}-\u{1F3F5}\u{1F3F7}-\u{1F4FD}\u{1F4FF}-\u{1F53D}\u{1F549}-\u{1F54E}\u{1F550}-\u{1F567}\u{1F56F}\u{1F570}\u{1F573}-\u{1F57A}\u{1F587}\u{1F58A}-\u{1F58D}\u{1F590}\u{1F595}\u{1F596}\u{1F5A4}\u{1F5A5}\u{1F5A8}\u{1F5B1}\u{1F5B2}\u{1F5BC}\u{1F5C2}-\u{1F5C4}\u{1F5D1}-\u{1F5D3}\u{1F5DC}-\u{1F5DE}\u{1F5E1}\u{1F5E3}\u{1F5E8}\u{1F5EF}\u{1F5F3}\u{1F5FA}-\u{1F64F}\u{1F680}-\u{1F6C5}\u{1F6CB}-\u{1F6D2}\u{1F6D5}-\u{1F6D7}\u{1F6E0}-\u{1F6E5}\u{1F6E9}\u{1F6EB}\u{1F6EC}\u{1F6F0}\u{1F6F3}-\u{1F6FC}\u{1F7E0}-\u{1F7EB}\u{1F90C}-\u{1F93A}\u{1F93C}-\u{1F945}\u{1F947}-\u{1F978}\u{1F97A}-\u{1F9CB}\u{1F9CD}-\u{1F9FF}\u{1FA70}-\u{1FA74}\u{1FA78}-\u{1FA7A}\u{1FA80}-\u{1FA86}\u{1FA90}-\u{1FAA8}\u{1FAB0}-\u{1FAB6}\u{1FAC0}-\u{1FAC2}\u{1FAD0}-\u{1FAD6}]\uFE0F|[\u261D\u26F9\u270A-\u270D\u{1F385}\u{1F3C2}-\u{1F3C4}\u{1F3C7}\u{1F3CA}-\u{1F3CC}\u{1F442}\u{1F443}\u{1F446}-\u{1F450}\u{1F466}-\u{1F478}\u{1F47C}\u{1F481}-\u{1F483}\u{1F485}-\u{1F487}\u{1F48F}\u{1F491}\u{1F4AA}\u{1F574}\u{1F575}\u{1F57A}\u{1F590}\u{1F595}\u{1F596}\u{1F645}-\u{1F647}\u{1F64B}-\u{1F64F}\u{1F6A3}\u{1F6B4}-\u{1F6B6}\u{1F6C0}\u{1F6CC}\u{1F90C}\u{1F90F}\u{1F918}-\u{1F91F}\u{1F926}\u{1F930}-\u{1F939}\u{1F93C}-\u{1F93E}\u{1F977}\u{1F9B5}\u{1F9B6}\u{1F9B8}\u{1F9B9}\u{1F9BB}\u{1F9CD}-\u{1F9CF}\u{1F9D1}-\u{1F9DD}]/gu;
+};
diff --git a/app/node_modules/emoji-regex/es2015/text.d.ts b/app/node_modules/emoji-regex/es2015/text.d.ts
new file mode 100644
index 0000000..ccc2f9a
--- /dev/null
+++ b/app/node_modules/emoji-regex/es2015/text.d.ts
@@ -0,0 +1,5 @@
+declare module 'emoji-regex/es2015/text' {
+ function emojiRegex(): RegExp;
+
+ export = emojiRegex;
+}
diff --git a/app/node_modules/emoji-regex/es2015/text.js b/app/node_modules/emoji-regex/es2015/text.js
new file mode 100644
index 0000000..8e9f985
--- /dev/null
+++ b/app/node_modules/emoji-regex/es2015/text.js
@@ -0,0 +1,6 @@
+"use strict";
+
+module.exports = () => {
+ // https://mths.be/emoji
+ return /\u{1F3F4}\u{E0067}\u{E0062}(?:\u{E0077}\u{E006C}\u{E0073}|\u{E0073}\u{E0063}\u{E0074}|\u{E0065}\u{E006E}\u{E0067})\u{E007F}|(?:\u{1F9D1}\u{1F3FF}\u200D\u2764\uFE0F\u200D(?:\u{1F48B}\u200D)?\u{1F9D1}|\u{1F469}\u{1F3FF}\u200D\u{1F91D}\u200D[\u{1F468}\u{1F469}])[\u{1F3FB}-\u{1F3FE}]|(?:\u{1F9D1}\u{1F3FE}\u200D\u2764\uFE0F\u200D(?:\u{1F48B}\u200D)?\u{1F9D1}|\u{1F469}\u{1F3FE}\u200D\u{1F91D}\u200D[\u{1F468}\u{1F469}])[\u{1F3FB}-\u{1F3FD}\u{1F3FF}]|(?:\u{1F9D1}\u{1F3FD}\u200D\u2764\uFE0F\u200D(?:\u{1F48B}\u200D)?\u{1F9D1}|\u{1F469}\u{1F3FD}\u200D\u{1F91D}\u200D[\u{1F468}\u{1F469}])[\u{1F3FB}\u{1F3FC}\u{1F3FE}\u{1F3FF}]|(?:\u{1F9D1}\u{1F3FC}\u200D\u2764\uFE0F\u200D(?:\u{1F48B}\u200D)?\u{1F9D1}|\u{1F469}\u{1F3FC}\u200D\u{1F91D}\u200D[\u{1F468}\u{1F469}])[\u{1F3FB}\u{1F3FD}-\u{1F3FF}]|(?:\u{1F9D1}\u{1F3FB}\u200D\u2764\uFE0F\u200D(?:\u{1F48B}\u200D)?\u{1F9D1}|\u{1F469}\u{1F3FB}\u200D\u{1F91D}\u200D[\u{1F468}\u{1F469}])[\u{1F3FC}-\u{1F3FF}]|\u{1F468}(?:\u{1F3FB}(?:\u200D(?:\u2764\uFE0F\u200D(?:\u{1F48B}\u200D\u{1F468}[\u{1F3FB}-\u{1F3FF}]|\u{1F468}[\u{1F3FB}-\u{1F3FF}])|\u{1F91D}\u200D\u{1F468}[\u{1F3FC}-\u{1F3FF}]|[\u2695\u2696\u2708]\uFE0F|[\u{1F33E}\u{1F373}\u{1F37C}\u{1F393}\u{1F3A4}\u{1F3A8}\u{1F3EB}\u{1F3ED}\u{1F4BB}\u{1F4BC}\u{1F527}\u{1F52C}\u{1F680}\u{1F692}\u{1F9AF}-\u{1F9B3}\u{1F9BC}\u{1F9BD}]))?|[\u{1F3FC}-\u{1F3FF}]\u200D\u2764\uFE0F\u200D(?:\u{1F48B}\u200D\u{1F468}[\u{1F3FB}-\u{1F3FF}]|\u{1F468}[\u{1F3FB}-\u{1F3FF}])|\u200D(?:\u2764\uFE0F\u200D(?:\u{1F48B}\u200D)?\u{1F468}|[\u{1F468}\u{1F469}]\u200D(?:\u{1F466}\u200D\u{1F466}|\u{1F467}\u200D[\u{1F466}\u{1F467}])|\u{1F466}\u200D\u{1F466}|\u{1F467}\u200D[\u{1F466}\u{1F467}]|[\u{1F33E}\u{1F373}\u{1F37C}\u{1F393}\u{1F3A4}\u{1F3A8}\u{1F3EB}\u{1F3ED}\u{1F4BB}\u{1F4BC}\u{1F527}\u{1F52C}\u{1F680}\u{1F692}\u{1F9AF}-\u{1F9B3}\u{1F9BC}\u{1F9BD}])|\u{1F3FF}\u200D(?:\u{1F91D}\u200D\u{1F468}[\u{1F3FB}-\u{1F3FE}]|[\u{1F33E}\u{1F373}\u{1F37C}\u{1F393}\u{1F3A4}\u{1F3A8}\u{1F3EB}\u{1F3ED}\u{1F4BB}\u{1F4BC}\u{1F527}\u{1F52C}\u{1F680}\u{1F692}\u{1F9AF}-\u{1F9B3}\u{1F9BC}\u{1F9BD}])|\u{1F3FE}\u200D(?:\u{1F91D}\u200D\u{1F468}[\u{1F3FB}-\u{1F3FD}\u{1F3FF}]|[\u{1F33E}\u{1F373}\u{1F37C}\u{1F393}\u{1F3A4}\u{1F3A8}\u{1F3EB}\u{1F3ED}\u{1F4BB}\u{1F4BC}\u{1F527}\u{1F52C}\u{1F680}\u{1F692}\u{1F9AF}-\u{1F9B3}\u{1F9BC}\u{1F9BD}])|\u{1F3FD}\u200D(?:\u{1F91D}\u200D\u{1F468}[\u{1F3FB}\u{1F3FC}\u{1F3FE}\u{1F3FF}]|[\u{1F33E}\u{1F373}\u{1F37C}\u{1F393}\u{1F3A4}\u{1F3A8}\u{1F3EB}\u{1F3ED}\u{1F4BB}\u{1F4BC}\u{1F527}\u{1F52C}\u{1F680}\u{1F692}\u{1F9AF}-\u{1F9B3}\u{1F9BC}\u{1F9BD}])|\u{1F3FC}\u200D(?:\u{1F91D}\u200D\u{1F468}[\u{1F3FB}\u{1F3FD}-\u{1F3FF}]|[\u{1F33E}\u{1F373}\u{1F37C}\u{1F393}\u{1F3A4}\u{1F3A8}\u{1F3EB}\u{1F3ED}\u{1F4BB}\u{1F4BC}\u{1F527}\u{1F52C}\u{1F680}\u{1F692}\u{1F9AF}-\u{1F9B3}\u{1F9BC}\u{1F9BD}])|(?:\u{1F3FF}\u200D[\u2695\u2696\u2708]|\u{1F3FE}\u200D[\u2695\u2696\u2708]|\u{1F3FD}\u200D[\u2695\u2696\u2708]|\u{1F3FC}\u200D[\u2695\u2696\u2708]|\u200D[\u2695\u2696\u2708])\uFE0F|\u200D(?:[\u{1F468}\u{1F469}]\u200D[\u{1F466}\u{1F467}]|[\u{1F466}\u{1F467}])|\u{1F3FF}|\u{1F3FE}|\u{1F3FD}|\u{1F3FC})?|(?:\u{1F469}(?:\u{1F3FB}\u200D\u2764\uFE0F\u200D(?:\u{1F48B}\u200D[\u{1F468}\u{1F469}]|[\u{1F468}\u{1F469}])|[\u{1F3FC}-\u{1F3FF}]\u200D\u2764\uFE0F\u200D(?:\u{1F48B}\u200D[\u{1F468}\u{1F469}]|[\u{1F468}\u{1F469}]))|\u{1F9D1}[\u{1F3FB}-\u{1F3FF}]\u200D\u{1F91D}\u200D\u{1F9D1})[\u{1F3FB}-\u{1F3FF}]|\u{1F469}\u200D\u{1F469}\u200D(?:\u{1F466}\u200D\u{1F466}|\u{1F467}\u200D[\u{1F466}\u{1F467}])|\u{1F469}(?:\u200D(?:\u2764\uFE0F\u200D(?:\u{1F48B}\u200D[\u{1F468}\u{1F469}]|[\u{1F468}\u{1F469}])|[\u{1F33E}\u{1F373}\u{1F37C}\u{1F393}\u{1F3A4}\u{1F3A8}\u{1F3EB}\u{1F3ED}\u{1F4BB}\u{1F4BC}\u{1F527}\u{1F52C}\u{1F680}\u{1F692}\u{1F9AF}-\u{1F9B3}\u{1F9BC}\u{1F9BD}])|\u{1F3FF}\u200D[\u{1F33E}\u{1F373}\u{1F37C}\u{1F393}\u{1F3A4}\u{1F3A8}\u{1F3EB}\u{1F3ED}\u{1F4BB}\u{1F4BC}\u{1F527}\u{1F52C}\u{1F680}\u{1F692}\u{1F9AF}-\u{1F9B3}\u{1F9BC}\u{1F9BD}]|\u{1F3FE}\u200D[\u{1F33E}\u{1F373}\u{1F37C}\u{1F393}\u{1F3A4}\u{1F3A8}\u{1F3EB}\u{1F3ED}\u{1F4BB}\u{1F4BC}\u{1F527}\u{1F52C}\u{1F680}\u{1F692}\u{1F9AF}-\u{1F9B3}\u{1F9BC}\u{1F9BD}]|\u{1F3FD}\u200D[\u{1F33E}\u{1F373}\u{1F37C}\u{1F393}\u{1F3A4}\u{1F3A8}\u{1F3EB}\u{1F3ED}\u{1F4BB}\u{1F4BC}\u{1F527}\u{1F52C}\u{1F680}\u{1F692}\u{1F9AF}-\u{1F9B3}\u{1F9BC}\u{1F9BD}]|\u{1F3FC}\u200D[\u{1F33E}\u{1F373}\u{1F37C}\u{1F393}\u{1F3A4}\u{1F3A8}\u{1F3EB}\u{1F3ED}\u{1F4BB}\u{1F4BC}\u{1F527}\u{1F52C}\u{1F680}\u{1F692}\u{1F9AF}-\u{1F9B3}\u{1F9BC}\u{1F9BD}]|\u{1F3FB}\u200D[\u{1F33E}\u{1F373}\u{1F37C}\u{1F393}\u{1F3A4}\u{1F3A8}\u{1F3EB}\u{1F3ED}\u{1F4BB}\u{1F4BC}\u{1F527}\u{1F52C}\u{1F680}\u{1F692}\u{1F9AF}-\u{1F9B3}\u{1F9BC}\u{1F9BD}])|\u{1F9D1}(?:\u200D(?:\u{1F91D}\u200D\u{1F9D1}|[\u{1F33E}\u{1F373}\u{1F37C}\u{1F384}\u{1F393}\u{1F3A4}\u{1F3A8}\u{1F3EB}\u{1F3ED}\u{1F4BB}\u{1F4BC}\u{1F527}\u{1F52C}\u{1F680}\u{1F692}\u{1F9AF}-\u{1F9B3}\u{1F9BC}\u{1F9BD}])|\u{1F3FF}\u200D[\u{1F33E}\u{1F373}\u{1F37C}\u{1F384}\u{1F393}\u{1F3A4}\u{1F3A8}\u{1F3EB}\u{1F3ED}\u{1F4BB}\u{1F4BC}\u{1F527}\u{1F52C}\u{1F680}\u{1F692}\u{1F9AF}-\u{1F9B3}\u{1F9BC}\u{1F9BD}]|\u{1F3FE}\u200D[\u{1F33E}\u{1F373}\u{1F37C}\u{1F384}\u{1F393}\u{1F3A4}\u{1F3A8}\u{1F3EB}\u{1F3ED}\u{1F4BB}\u{1F4BC}\u{1F527}\u{1F52C}\u{1F680}\u{1F692}\u{1F9AF}-\u{1F9B3}\u{1F9BC}\u{1F9BD}]|\u{1F3FD}\u200D[\u{1F33E}\u{1F373}\u{1F37C}\u{1F384}\u{1F393}\u{1F3A4}\u{1F3A8}\u{1F3EB}\u{1F3ED}\u{1F4BB}\u{1F4BC}\u{1F527}\u{1F52C}\u{1F680}\u{1F692}\u{1F9AF}-\u{1F9B3}\u{1F9BC}\u{1F9BD}]|\u{1F3FC}\u200D[\u{1F33E}\u{1F373}\u{1F37C}\u{1F384}\u{1F393}\u{1F3A4}\u{1F3A8}\u{1F3EB}\u{1F3ED}\u{1F4BB}\u{1F4BC}\u{1F527}\u{1F52C}\u{1F680}\u{1F692}\u{1F9AF}-\u{1F9B3}\u{1F9BC}\u{1F9BD}]|\u{1F3FB}\u200D[\u{1F33E}\u{1F373}\u{1F37C}\u{1F384}\u{1F393}\u{1F3A4}\u{1F3A8}\u{1F3EB}\u{1F3ED}\u{1F4BB}\u{1F4BC}\u{1F527}\u{1F52C}\u{1F680}\u{1F692}\u{1F9AF}-\u{1F9B3}\u{1F9BC}\u{1F9BD}])|\u{1F469}\u200D\u{1F466}\u200D\u{1F466}|\u{1F469}\u200D\u{1F469}\u200D[\u{1F466}\u{1F467}]|\u{1F469}\u200D\u{1F467}\u200D[\u{1F466}\u{1F467}]|(?:\u{1F441}\uFE0F\u200D\u{1F5E8}|\u{1F9D1}(?:\u{1F3FF}\u200D[\u2695\u2696\u2708]|\u{1F3FE}\u200D[\u2695\u2696\u2708]|\u{1F3FD}\u200D[\u2695\u2696\u2708]|\u{1F3FC}\u200D[\u2695\u2696\u2708]|\u{1F3FB}\u200D[\u2695\u2696\u2708]|\u200D[\u2695\u2696\u2708])|\u{1F469}(?:\u{1F3FF}\u200D[\u2695\u2696\u2708]|\u{1F3FE}\u200D[\u2695\u2696\u2708]|\u{1F3FD}\u200D[\u2695\u2696\u2708]|\u{1F3FC}\u200D[\u2695\u2696\u2708]|\u{1F3FB}\u200D[\u2695\u2696\u2708]|\u200D[\u2695\u2696\u2708])|\u{1F636}\u200D\u{1F32B}|\u{1F3F3}\uFE0F\u200D\u26A7|\u{1F43B}\u200D\u2744|(?:[\u{1F3C3}\u{1F3C4}\u{1F3CA}\u{1F46E}\u{1F470}\u{1F471}\u{1F473}\u{1F477}\u{1F481}\u{1F482}\u{1F486}\u{1F487}\u{1F645}-\u{1F647}\u{1F64B}\u{1F64D}\u{1F64E}\u{1F6A3}\u{1F6B4}-\u{1F6B6}\u{1F926}\u{1F935}\u{1F937}-\u{1F939}\u{1F93D}\u{1F93E}\u{1F9B8}\u{1F9B9}\u{1F9CD}-\u{1F9CF}\u{1F9D4}\u{1F9D6}-\u{1F9DD}][\u{1F3FB}-\u{1F3FF}]|[\u{1F46F}\u{1F93C}\u{1F9DE}\u{1F9DF}])\u200D[\u2640\u2642]|[\u26F9\u{1F3CB}\u{1F3CC}\u{1F575}][\uFE0F\u{1F3FB}-\u{1F3FF}]\u200D[\u2640\u2642]|\u{1F3F4}\u200D\u2620|[\u{1F3C3}\u{1F3C4}\u{1F3CA}\u{1F46E}\u{1F470}\u{1F471}\u{1F473}\u{1F477}\u{1F481}\u{1F482}\u{1F486}\u{1F487}\u{1F645}-\u{1F647}\u{1F64B}\u{1F64D}\u{1F64E}\u{1F6A3}\u{1F6B4}-\u{1F6B6}\u{1F926}\u{1F935}\u{1F937}-\u{1F939}\u{1F93D}\u{1F93E}\u{1F9B8}\u{1F9B9}\u{1F9CD}-\u{1F9CF}\u{1F9D4}\u{1F9D6}-\u{1F9DD}]\u200D[\u2640\u2642]|[\xA9\xAE\u203C\u2049\u2122\u2139\u2194-\u2199\u21A9\u21AA\u2328\u23CF\u23ED-\u23EF\u23F1\u23F2\u23F8-\u23FA\u24C2\u25AA\u25AB\u25B6\u25C0\u25FB\u25FC\u2600-\u2604\u260E\u2611\u2618\u2620\u2622\u2623\u2626\u262A\u262E\u262F\u2638-\u263A\u2640\u2642\u265F\u2660\u2663\u2665\u2666\u2668\u267B\u267E\u2692\u2694-\u2697\u2699\u269B\u269C\u26A0\u26A7\u26B0\u26B1\u26C8\u26CF\u26D1\u26D3\u26E9\u26F0\u26F1\u26F4\u26F7\u26F8\u2702\u2708\u2709\u270F\u2712\u2714\u2716\u271D\u2721\u2733\u2734\u2744\u2747\u2763\u27A1\u2934\u2935\u2B05-\u2B07\u3030\u303D\u3297\u3299\u{1F170}\u{1F171}\u{1F17E}\u{1F17F}\u{1F202}\u{1F237}\u{1F321}\u{1F324}-\u{1F32C}\u{1F336}\u{1F37D}\u{1F396}\u{1F397}\u{1F399}-\u{1F39B}\u{1F39E}\u{1F39F}\u{1F3CD}\u{1F3CE}\u{1F3D4}-\u{1F3DF}\u{1F3F5}\u{1F3F7}\u{1F43F}\u{1F4FD}\u{1F549}\u{1F54A}\u{1F56F}\u{1F570}\u{1F573}\u{1F576}-\u{1F579}\u{1F587}\u{1F58A}-\u{1F58D}\u{1F5A5}\u{1F5A8}\u{1F5B1}\u{1F5B2}\u{1F5BC}\u{1F5C2}-\u{1F5C4}\u{1F5D1}-\u{1F5D3}\u{1F5DC}-\u{1F5DE}\u{1F5E1}\u{1F5E3}\u{1F5E8}\u{1F5EF}\u{1F5F3}\u{1F5FA}\u{1F6CB}\u{1F6CD}-\u{1F6CF}\u{1F6E0}-\u{1F6E5}\u{1F6E9}\u{1F6F0}\u{1F6F3}])\uFE0F|\u{1F3F3}\uFE0F\u200D\u{1F308}|\u{1F469}\u200D\u{1F467}|\u{1F469}\u200D\u{1F466}|\u{1F635}\u200D\u{1F4AB}|\u{1F62E}\u200D\u{1F4A8}|\u{1F415}\u200D\u{1F9BA}|\u{1F9D1}(?:\u{1F3FF}|\u{1F3FE}|\u{1F3FD}|\u{1F3FC}|\u{1F3FB})?|\u{1F469}(?:\u{1F3FF}|\u{1F3FE}|\u{1F3FD}|\u{1F3FC}|\u{1F3FB})?|\u{1F1FD}\u{1F1F0}|\u{1F1F6}\u{1F1E6}|\u{1F1F4}\u{1F1F2}|\u{1F408}\u200D\u2B1B|\u2764\uFE0F\u200D[\u{1F525}\u{1FA79}]|\u{1F441}\uFE0F|\u{1F3F3}\uFE0F|\u{1F1FF}[\u{1F1E6}\u{1F1F2}\u{1F1FC}]|\u{1F1FE}[\u{1F1EA}\u{1F1F9}]|\u{1F1FC}[\u{1F1EB}\u{1F1F8}]|\u{1F1FB}[\u{1F1E6}\u{1F1E8}\u{1F1EA}\u{1F1EC}\u{1F1EE}\u{1F1F3}\u{1F1FA}]|\u{1F1FA}[\u{1F1E6}\u{1F1EC}\u{1F1F2}\u{1F1F3}\u{1F1F8}\u{1F1FE}\u{1F1FF}]|\u{1F1F9}[\u{1F1E6}\u{1F1E8}\u{1F1E9}\u{1F1EB}-\u{1F1ED}\u{1F1EF}-\u{1F1F4}\u{1F1F7}\u{1F1F9}\u{1F1FB}\u{1F1FC}\u{1F1FF}]|\u{1F1F8}[\u{1F1E6}-\u{1F1EA}\u{1F1EC}-\u{1F1F4}\u{1F1F7}-\u{1F1F9}\u{1F1FB}\u{1F1FD}-\u{1F1FF}]|\u{1F1F7}[\u{1F1EA}\u{1F1F4}\u{1F1F8}\u{1F1FA}\u{1F1FC}]|\u{1F1F5}[\u{1F1E6}\u{1F1EA}-\u{1F1ED}\u{1F1F0}-\u{1F1F3}\u{1F1F7}-\u{1F1F9}\u{1F1FC}\u{1F1FE}]|\u{1F1F3}[\u{1F1E6}\u{1F1E8}\u{1F1EA}-\u{1F1EC}\u{1F1EE}\u{1F1F1}\u{1F1F4}\u{1F1F5}\u{1F1F7}\u{1F1FA}\u{1F1FF}]|\u{1F1F2}[\u{1F1E6}\u{1F1E8}-\u{1F1ED}\u{1F1F0}-\u{1F1FF}]|\u{1F1F1}[\u{1F1E6}-\u{1F1E8}\u{1F1EE}\u{1F1F0}\u{1F1F7}-\u{1F1FB}\u{1F1FE}]|\u{1F1F0}[\u{1F1EA}\u{1F1EC}-\u{1F1EE}\u{1F1F2}\u{1F1F3}\u{1F1F5}\u{1F1F7}\u{1F1FC}\u{1F1FE}\u{1F1FF}]|\u{1F1EF}[\u{1F1EA}\u{1F1F2}\u{1F1F4}\u{1F1F5}]|\u{1F1EE}[\u{1F1E8}-\u{1F1EA}\u{1F1F1}-\u{1F1F4}\u{1F1F6}-\u{1F1F9}]|\u{1F1ED}[\u{1F1F0}\u{1F1F2}\u{1F1F3}\u{1F1F7}\u{1F1F9}\u{1F1FA}]|\u{1F1EC}[\u{1F1E6}\u{1F1E7}\u{1F1E9}-\u{1F1EE}\u{1F1F1}-\u{1F1F3}\u{1F1F5}-\u{1F1FA}\u{1F1FC}\u{1F1FE}]|\u{1F1EB}[\u{1F1EE}-\u{1F1F0}\u{1F1F2}\u{1F1F4}\u{1F1F7}]|\u{1F1EA}[\u{1F1E6}\u{1F1E8}\u{1F1EA}\u{1F1EC}\u{1F1ED}\u{1F1F7}-\u{1F1FA}]|\u{1F1E9}[\u{1F1EA}\u{1F1EC}\u{1F1EF}\u{1F1F0}\u{1F1F2}\u{1F1F4}\u{1F1FF}]|\u{1F1E8}[\u{1F1E6}\u{1F1E8}\u{1F1E9}\u{1F1EB}-\u{1F1EE}\u{1F1F0}-\u{1F1F5}\u{1F1F7}\u{1F1FA}-\u{1F1FF}]|\u{1F1E7}[\u{1F1E6}\u{1F1E7}\u{1F1E9}-\u{1F1EF}\u{1F1F1}-\u{1F1F4}\u{1F1F6}-\u{1F1F9}\u{1F1FB}\u{1F1FC}\u{1F1FE}\u{1F1FF}]|\u{1F1E6}[\u{1F1E8}-\u{1F1EC}\u{1F1EE}\u{1F1F1}\u{1F1F2}\u{1F1F4}\u{1F1F6}-\u{1F1FA}\u{1F1FC}\u{1F1FD}\u{1F1FF}]|[#\*0-9]\uFE0F\u20E3|\u2764\uFE0F|[\u{1F3C3}\u{1F3C4}\u{1F3CA}\u{1F46E}\u{1F470}\u{1F471}\u{1F473}\u{1F477}\u{1F481}\u{1F482}\u{1F486}\u{1F487}\u{1F645}-\u{1F647}\u{1F64B}\u{1F64D}\u{1F64E}\u{1F6A3}\u{1F6B4}-\u{1F6B6}\u{1F926}\u{1F935}\u{1F937}-\u{1F939}\u{1F93D}\u{1F93E}\u{1F9B8}\u{1F9B9}\u{1F9CD}-\u{1F9CF}\u{1F9D4}\u{1F9D6}-\u{1F9DD}][\u{1F3FB}-\u{1F3FF}]|[\u26F9\u{1F3CB}\u{1F3CC}\u{1F575}][\uFE0F\u{1F3FB}-\u{1F3FF}]|\u{1F3F4}|[\u270A\u270B\u{1F385}\u{1F3C2}\u{1F3C7}\u{1F442}\u{1F443}\u{1F446}-\u{1F450}\u{1F466}\u{1F467}\u{1F46B}-\u{1F46D}\u{1F472}\u{1F474}-\u{1F476}\u{1F478}\u{1F47C}\u{1F483}\u{1F485}\u{1F48F}\u{1F491}\u{1F4AA}\u{1F57A}\u{1F595}\u{1F596}\u{1F64C}\u{1F64F}\u{1F6C0}\u{1F6CC}\u{1F90C}\u{1F90F}\u{1F918}-\u{1F91C}\u{1F91E}\u{1F91F}\u{1F930}-\u{1F934}\u{1F936}\u{1F977}\u{1F9B5}\u{1F9B6}\u{1F9BB}\u{1F9D2}\u{1F9D3}\u{1F9D5}][\u{1F3FB}-\u{1F3FF}]|[\u261D\u270C\u270D\u{1F574}\u{1F590}][\uFE0F\u{1F3FB}-\u{1F3FF}]|[\u270A\u270B\u{1F385}\u{1F3C2}\u{1F3C7}\u{1F408}\u{1F415}\u{1F43B}\u{1F442}\u{1F443}\u{1F446}-\u{1F450}\u{1F466}\u{1F467}\u{1F46B}-\u{1F46D}\u{1F472}\u{1F474}-\u{1F476}\u{1F478}\u{1F47C}\u{1F483}\u{1F485}\u{1F48F}\u{1F491}\u{1F4AA}\u{1F57A}\u{1F595}\u{1F596}\u{1F62E}\u{1F635}\u{1F636}\u{1F64C}\u{1F64F}\u{1F6C0}\u{1F6CC}\u{1F90C}\u{1F90F}\u{1F918}-\u{1F91C}\u{1F91E}\u{1F91F}\u{1F930}-\u{1F934}\u{1F936}\u{1F977}\u{1F9B5}\u{1F9B6}\u{1F9BB}\u{1F9D2}\u{1F9D3}\u{1F9D5}]|[\u{1F3C3}\u{1F3C4}\u{1F3CA}\u{1F46E}\u{1F470}\u{1F471}\u{1F473}\u{1F477}\u{1F481}\u{1F482}\u{1F486}\u{1F487}\u{1F645}-\u{1F647}\u{1F64B}\u{1F64D}\u{1F64E}\u{1F6A3}\u{1F6B4}-\u{1F6B6}\u{1F926}\u{1F935}\u{1F937}-\u{1F939}\u{1F93D}\u{1F93E}\u{1F9B8}\u{1F9B9}\u{1F9CD}-\u{1F9CF}\u{1F9D4}\u{1F9D6}-\u{1F9DD}]|[\u{1F46F}\u{1F93C}\u{1F9DE}\u{1F9DF}]|[\u231A\u231B\u23E9-\u23EC\u23F0\u23F3\u25FD\u25FE\u2614\u2615\u2648-\u2653\u267F\u2693\u26A1\u26AA\u26AB\u26BD\u26BE\u26C4\u26C5\u26CE\u26D4\u26EA\u26F2\u26F3\u26F5\u26FA\u26FD\u2705\u2728\u274C\u274E\u2753-\u2755\u2757\u2795-\u2797\u27B0\u27BF\u2B1B\u2B1C\u2B50\u2B55\u{1F004}\u{1F0CF}\u{1F18E}\u{1F191}-\u{1F19A}\u{1F201}\u{1F21A}\u{1F22F}\u{1F232}-\u{1F236}\u{1F238}-\u{1F23A}\u{1F250}\u{1F251}\u{1F300}-\u{1F320}\u{1F32D}-\u{1F335}\u{1F337}-\u{1F37C}\u{1F37E}-\u{1F384}\u{1F386}-\u{1F393}\u{1F3A0}-\u{1F3C1}\u{1F3C5}\u{1F3C6}\u{1F3C8}\u{1F3C9}\u{1F3CF}-\u{1F3D3}\u{1F3E0}-\u{1F3F0}\u{1F3F8}-\u{1F407}\u{1F409}-\u{1F414}\u{1F416}-\u{1F43A}\u{1F43C}-\u{1F43E}\u{1F440}\u{1F444}\u{1F445}\u{1F451}-\u{1F465}\u{1F46A}\u{1F479}-\u{1F47B}\u{1F47D}-\u{1F480}\u{1F484}\u{1F488}-\u{1F48E}\u{1F490}\u{1F492}-\u{1F4A9}\u{1F4AB}-\u{1F4FC}\u{1F4FF}-\u{1F53D}\u{1F54B}-\u{1F54E}\u{1F550}-\u{1F567}\u{1F5A4}\u{1F5FB}-\u{1F62D}\u{1F62F}-\u{1F634}\u{1F637}-\u{1F644}\u{1F648}-\u{1F64A}\u{1F680}-\u{1F6A2}\u{1F6A4}-\u{1F6B3}\u{1F6B7}-\u{1F6BF}\u{1F6C1}-\u{1F6C5}\u{1F6D0}-\u{1F6D2}\u{1F6D5}-\u{1F6D7}\u{1F6EB}\u{1F6EC}\u{1F6F4}-\u{1F6FC}\u{1F7E0}-\u{1F7EB}\u{1F90D}\u{1F90E}\u{1F910}-\u{1F917}\u{1F91D}\u{1F920}-\u{1F925}\u{1F927}-\u{1F92F}\u{1F93A}\u{1F93F}-\u{1F945}\u{1F947}-\u{1F976}\u{1F978}\u{1F97A}-\u{1F9B4}\u{1F9B7}\u{1F9BA}\u{1F9BC}-\u{1F9CB}\u{1F9D0}\u{1F9E0}-\u{1F9FF}\u{1FA70}-\u{1FA74}\u{1FA78}-\u{1FA7A}\u{1FA80}-\u{1FA86}\u{1FA90}-\u{1FAA8}\u{1FAB0}-\u{1FAB6}\u{1FAC0}-\u{1FAC2}\u{1FAD0}-\u{1FAD6}]|[#\*0-9\xA9\xAE\u203C\u2049\u2122\u2139\u2194-\u2199\u21A9\u21AA\u231A\u231B\u2328\u23CF\u23E9-\u23F3\u23F8-\u23FA\u24C2\u25AA\u25AB\u25B6\u25C0\u25FB-\u25FE\u2600-\u2604\u260E\u2611\u2614\u2615\u2618\u261D\u2620\u2622\u2623\u2626\u262A\u262E\u262F\u2638-\u263A\u2640\u2642\u2648-\u2653\u265F\u2660\u2663\u2665\u2666\u2668\u267B\u267E\u267F\u2692-\u2697\u2699\u269B\u269C\u26A0\u26A1\u26A7\u26AA\u26AB\u26B0\u26B1\u26BD\u26BE\u26C4\u26C5\u26C8\u26CE\u26CF\u26D1\u26D3\u26D4\u26E9\u26EA\u26F0-\u26F5\u26F7-\u26FA\u26FD\u2702\u2705\u2708-\u270D\u270F\u2712\u2714\u2716\u271D\u2721\u2728\u2733\u2734\u2744\u2747\u274C\u274E\u2753-\u2755\u2757\u2763\u2764\u2795-\u2797\u27A1\u27B0\u27BF\u2934\u2935\u2B05-\u2B07\u2B1B\u2B1C\u2B50\u2B55\u3030\u303D\u3297\u3299\u{1F004}\u{1F0CF}\u{1F170}\u{1F171}\u{1F17E}\u{1F17F}\u{1F18E}\u{1F191}-\u{1F19A}\u{1F1E6}-\u{1F1FF}\u{1F201}\u{1F202}\u{1F21A}\u{1F22F}\u{1F232}-\u{1F23A}\u{1F250}\u{1F251}\u{1F300}-\u{1F321}\u{1F324}-\u{1F393}\u{1F396}\u{1F397}\u{1F399}-\u{1F39B}\u{1F39E}-\u{1F3F0}\u{1F3F3}-\u{1F3F5}\u{1F3F7}-\u{1F4FD}\u{1F4FF}-\u{1F53D}\u{1F549}-\u{1F54E}\u{1F550}-\u{1F567}\u{1F56F}\u{1F570}\u{1F573}-\u{1F57A}\u{1F587}\u{1F58A}-\u{1F58D}\u{1F590}\u{1F595}\u{1F596}\u{1F5A4}\u{1F5A5}\u{1F5A8}\u{1F5B1}\u{1F5B2}\u{1F5BC}\u{1F5C2}-\u{1F5C4}\u{1F5D1}-\u{1F5D3}\u{1F5DC}-\u{1F5DE}\u{1F5E1}\u{1F5E3}\u{1F5E8}\u{1F5EF}\u{1F5F3}\u{1F5FA}-\u{1F64F}\u{1F680}-\u{1F6C5}\u{1F6CB}-\u{1F6D2}\u{1F6D5}-\u{1F6D7}\u{1F6E0}-\u{1F6E5}\u{1F6E9}\u{1F6EB}\u{1F6EC}\u{1F6F0}\u{1F6F3}-\u{1F6FC}\u{1F7E0}-\u{1F7EB}\u{1F90C}-\u{1F93A}\u{1F93C}-\u{1F945}\u{1F947}-\u{1F978}\u{1F97A}-\u{1F9CB}\u{1F9CD}-\u{1F9FF}\u{1FA70}-\u{1FA74}\u{1FA78}-\u{1FA7A}\u{1FA80}-\u{1FA86}\u{1FA90}-\u{1FAA8}\u{1FAB0}-\u{1FAB6}\u{1FAC0}-\u{1FAC2}\u{1FAD0}-\u{1FAD6}]\uFE0F?/gu;
+};
diff --git a/app/node_modules/emoji-regex/index.d.ts b/app/node_modules/emoji-regex/index.d.ts
new file mode 100644
index 0000000..8f235c9
--- /dev/null
+++ b/app/node_modules/emoji-regex/index.d.ts
@@ -0,0 +1,5 @@
+declare module 'emoji-regex' {
+ function emojiRegex(): RegExp;
+
+ export = emojiRegex;
+}
diff --git a/app/node_modules/emoji-regex/index.js b/app/node_modules/emoji-regex/index.js
new file mode 100644
index 0000000..c0490d4
--- /dev/null
+++ b/app/node_modules/emoji-regex/index.js
@@ -0,0 +1,6 @@
+"use strict";
+
+module.exports = function () {
+ // https://mths.be/emoji
+ return /\uD83C\uDFF4\uDB40\uDC67\uDB40\uDC62(?:\uDB40\uDC77\uDB40\uDC6C\uDB40\uDC73|\uDB40\uDC73\uDB40\uDC63\uDB40\uDC74|\uDB40\uDC65\uDB40\uDC6E\uDB40\uDC67)\uDB40\uDC7F|(?:\uD83E\uDDD1\uD83C\uDFFF\u200D\u2764\uFE0F\u200D(?:\uD83D\uDC8B\u200D)?\uD83E\uDDD1|\uD83D\uDC69\uD83C\uDFFF\u200D\uD83E\uDD1D\u200D(?:\uD83D[\uDC68\uDC69]))(?:\uD83C[\uDFFB-\uDFFE])|(?:\uD83E\uDDD1\uD83C\uDFFE\u200D\u2764\uFE0F\u200D(?:\uD83D\uDC8B\u200D)?\uD83E\uDDD1|\uD83D\uDC69\uD83C\uDFFE\u200D\uD83E\uDD1D\u200D(?:\uD83D[\uDC68\uDC69]))(?:\uD83C[\uDFFB-\uDFFD\uDFFF])|(?:\uD83E\uDDD1\uD83C\uDFFD\u200D\u2764\uFE0F\u200D(?:\uD83D\uDC8B\u200D)?\uD83E\uDDD1|\uD83D\uDC69\uD83C\uDFFD\u200D\uD83E\uDD1D\u200D(?:\uD83D[\uDC68\uDC69]))(?:\uD83C[\uDFFB\uDFFC\uDFFE\uDFFF])|(?:\uD83E\uDDD1\uD83C\uDFFC\u200D\u2764\uFE0F\u200D(?:\uD83D\uDC8B\u200D)?\uD83E\uDDD1|\uD83D\uDC69\uD83C\uDFFC\u200D\uD83E\uDD1D\u200D(?:\uD83D[\uDC68\uDC69]))(?:\uD83C[\uDFFB\uDFFD-\uDFFF])|(?:\uD83E\uDDD1\uD83C\uDFFB\u200D\u2764\uFE0F\u200D(?:\uD83D\uDC8B\u200D)?\uD83E\uDDD1|\uD83D\uDC69\uD83C\uDFFB\u200D\uD83E\uDD1D\u200D(?:\uD83D[\uDC68\uDC69]))(?:\uD83C[\uDFFC-\uDFFF])|\uD83D\uDC68(?:\uD83C\uDFFB(?:\u200D(?:\u2764\uFE0F\u200D(?:\uD83D\uDC8B\u200D\uD83D\uDC68(?:\uD83C[\uDFFB-\uDFFF])|\uD83D\uDC68(?:\uD83C[\uDFFB-\uDFFF]))|\uD83E\uDD1D\u200D\uD83D\uDC68(?:\uD83C[\uDFFC-\uDFFF])|[\u2695\u2696\u2708]\uFE0F|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD]))?|(?:\uD83C[\uDFFC-\uDFFF])\u200D\u2764\uFE0F\u200D(?:\uD83D\uDC8B\u200D\uD83D\uDC68(?:\uD83C[\uDFFB-\uDFFF])|\uD83D\uDC68(?:\uD83C[\uDFFB-\uDFFF]))|\u200D(?:\u2764\uFE0F\u200D(?:\uD83D\uDC8B\u200D)?\uD83D\uDC68|(?:\uD83D[\uDC68\uDC69])\u200D(?:\uD83D\uDC66\u200D\uD83D\uDC66|\uD83D\uDC67\u200D(?:\uD83D[\uDC66\uDC67]))|\uD83D\uDC66\u200D\uD83D\uDC66|\uD83D\uDC67\u200D(?:\uD83D[\uDC66\uDC67])|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFF\u200D(?:\uD83E\uDD1D\u200D\uD83D\uDC68(?:\uD83C[\uDFFB-\uDFFE])|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFE\u200D(?:\uD83E\uDD1D\u200D\uD83D\uDC68(?:\uD83C[\uDFFB-\uDFFD\uDFFF])|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFD\u200D(?:\uD83E\uDD1D\u200D\uD83D\uDC68(?:\uD83C[\uDFFB\uDFFC\uDFFE\uDFFF])|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFC\u200D(?:\uD83E\uDD1D\u200D\uD83D\uDC68(?:\uD83C[\uDFFB\uDFFD-\uDFFF])|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|(?:\uD83C\uDFFF\u200D[\u2695\u2696\u2708]|\uD83C\uDFFE\u200D[\u2695\u2696\u2708]|\uD83C\uDFFD\u200D[\u2695\u2696\u2708]|\uD83C\uDFFC\u200D[\u2695\u2696\u2708]|\u200D[\u2695\u2696\u2708])\uFE0F|\u200D(?:(?:\uD83D[\uDC68\uDC69])\u200D(?:\uD83D[\uDC66\uDC67])|\uD83D[\uDC66\uDC67])|\uD83C\uDFFF|\uD83C\uDFFE|\uD83C\uDFFD|\uD83C\uDFFC)?|(?:\uD83D\uDC69(?:\uD83C\uDFFB\u200D\u2764\uFE0F\u200D(?:\uD83D\uDC8B\u200D(?:\uD83D[\uDC68\uDC69])|\uD83D[\uDC68\uDC69])|(?:\uD83C[\uDFFC-\uDFFF])\u200D\u2764\uFE0F\u200D(?:\uD83D\uDC8B\u200D(?:\uD83D[\uDC68\uDC69])|\uD83D[\uDC68\uDC69]))|\uD83E\uDDD1(?:\uD83C[\uDFFB-\uDFFF])\u200D\uD83E\uDD1D\u200D\uD83E\uDDD1)(?:\uD83C[\uDFFB-\uDFFF])|\uD83D\uDC69\u200D\uD83D\uDC69\u200D(?:\uD83D\uDC66\u200D\uD83D\uDC66|\uD83D\uDC67\u200D(?:\uD83D[\uDC66\uDC67]))|\uD83D\uDC69(?:\u200D(?:\u2764\uFE0F\u200D(?:\uD83D\uDC8B\u200D(?:\uD83D[\uDC68\uDC69])|\uD83D[\uDC68\uDC69])|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFF\u200D(?:\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFE\u200D(?:\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFD\u200D(?:\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFC\u200D(?:\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFB\u200D(?:\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD]))|\uD83E\uDDD1(?:\u200D(?:\uD83E\uDD1D\u200D\uD83E\uDDD1|\uD83C[\uDF3E\uDF73\uDF7C\uDF84\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFF\u200D(?:\uD83C[\uDF3E\uDF73\uDF7C\uDF84\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFE\u200D(?:\uD83C[\uDF3E\uDF73\uDF7C\uDF84\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFD\u200D(?:\uD83C[\uDF3E\uDF73\uDF7C\uDF84\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFC\u200D(?:\uD83C[\uDF3E\uDF73\uDF7C\uDF84\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFB\u200D(?:\uD83C[\uDF3E\uDF73\uDF7C\uDF84\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD]))|\uD83D\uDC69\u200D\uD83D\uDC66\u200D\uD83D\uDC66|\uD83D\uDC69\u200D\uD83D\uDC69\u200D(?:\uD83D[\uDC66\uDC67])|\uD83D\uDC69\u200D\uD83D\uDC67\u200D(?:\uD83D[\uDC66\uDC67])|(?:\uD83D\uDC41\uFE0F\u200D\uD83D\uDDE8|\uD83E\uDDD1(?:\uD83C\uDFFF\u200D[\u2695\u2696\u2708]|\uD83C\uDFFE\u200D[\u2695\u2696\u2708]|\uD83C\uDFFD\u200D[\u2695\u2696\u2708]|\uD83C\uDFFC\u200D[\u2695\u2696\u2708]|\uD83C\uDFFB\u200D[\u2695\u2696\u2708]|\u200D[\u2695\u2696\u2708])|\uD83D\uDC69(?:\uD83C\uDFFF\u200D[\u2695\u2696\u2708]|\uD83C\uDFFE\u200D[\u2695\u2696\u2708]|\uD83C\uDFFD\u200D[\u2695\u2696\u2708]|\uD83C\uDFFC\u200D[\u2695\u2696\u2708]|\uD83C\uDFFB\u200D[\u2695\u2696\u2708]|\u200D[\u2695\u2696\u2708])|\uD83D\uDE36\u200D\uD83C\uDF2B|\uD83C\uDFF3\uFE0F\u200D\u26A7|\uD83D\uDC3B\u200D\u2744|(?:(?:\uD83C[\uDFC3\uDFC4\uDFCA]|\uD83D[\uDC6E\uDC70\uDC71\uDC73\uDC77\uDC81\uDC82\uDC86\uDC87\uDE45-\uDE47\uDE4B\uDE4D\uDE4E\uDEA3\uDEB4-\uDEB6]|\uD83E[\uDD26\uDD35\uDD37-\uDD39\uDD3D\uDD3E\uDDB8\uDDB9\uDDCD-\uDDCF\uDDD4\uDDD6-\uDDDD])(?:\uD83C[\uDFFB-\uDFFF])|\uD83D\uDC6F|\uD83E[\uDD3C\uDDDE\uDDDF])\u200D[\u2640\u2642]|(?:\u26F9|\uD83C[\uDFCB\uDFCC]|\uD83D\uDD75)(?:\uFE0F|\uD83C[\uDFFB-\uDFFF])\u200D[\u2640\u2642]|\uD83C\uDFF4\u200D\u2620|(?:\uD83C[\uDFC3\uDFC4\uDFCA]|\uD83D[\uDC6E\uDC70\uDC71\uDC73\uDC77\uDC81\uDC82\uDC86\uDC87\uDE45-\uDE47\uDE4B\uDE4D\uDE4E\uDEA3\uDEB4-\uDEB6]|\uD83E[\uDD26\uDD35\uDD37-\uDD39\uDD3D\uDD3E\uDDB8\uDDB9\uDDCD-\uDDCF\uDDD4\uDDD6-\uDDDD])\u200D[\u2640\u2642]|[\xA9\xAE\u203C\u2049\u2122\u2139\u2194-\u2199\u21A9\u21AA\u2328\u23CF\u23ED-\u23EF\u23F1\u23F2\u23F8-\u23FA\u24C2\u25AA\u25AB\u25B6\u25C0\u25FB\u25FC\u2600-\u2604\u260E\u2611\u2618\u2620\u2622\u2623\u2626\u262A\u262E\u262F\u2638-\u263A\u2640\u2642\u265F\u2660\u2663\u2665\u2666\u2668\u267B\u267E\u2692\u2694-\u2697\u2699\u269B\u269C\u26A0\u26A7\u26B0\u26B1\u26C8\u26CF\u26D1\u26D3\u26E9\u26F0\u26F1\u26F4\u26F7\u26F8\u2702\u2708\u2709\u270F\u2712\u2714\u2716\u271D\u2721\u2733\u2734\u2744\u2747\u2763\u27A1\u2934\u2935\u2B05-\u2B07\u3030\u303D\u3297\u3299]|\uD83C[\uDD70\uDD71\uDD7E\uDD7F\uDE02\uDE37\uDF21\uDF24-\uDF2C\uDF36\uDF7D\uDF96\uDF97\uDF99-\uDF9B\uDF9E\uDF9F\uDFCD\uDFCE\uDFD4-\uDFDF\uDFF5\uDFF7]|\uD83D[\uDC3F\uDCFD\uDD49\uDD4A\uDD6F\uDD70\uDD73\uDD76-\uDD79\uDD87\uDD8A-\uDD8D\uDDA5\uDDA8\uDDB1\uDDB2\uDDBC\uDDC2-\uDDC4\uDDD1-\uDDD3\uDDDC-\uDDDE\uDDE1\uDDE3\uDDE8\uDDEF\uDDF3\uDDFA\uDECB\uDECD-\uDECF\uDEE0-\uDEE5\uDEE9\uDEF0\uDEF3])\uFE0F|\uD83C\uDFF3\uFE0F\u200D\uD83C\uDF08|\uD83D\uDC69\u200D\uD83D\uDC67|\uD83D\uDC69\u200D\uD83D\uDC66|\uD83D\uDE35\u200D\uD83D\uDCAB|\uD83D\uDE2E\u200D\uD83D\uDCA8|\uD83D\uDC15\u200D\uD83E\uDDBA|\uD83E\uDDD1(?:\uD83C\uDFFF|\uD83C\uDFFE|\uD83C\uDFFD|\uD83C\uDFFC|\uD83C\uDFFB)?|\uD83D\uDC69(?:\uD83C\uDFFF|\uD83C\uDFFE|\uD83C\uDFFD|\uD83C\uDFFC|\uD83C\uDFFB)?|\uD83C\uDDFD\uD83C\uDDF0|\uD83C\uDDF6\uD83C\uDDE6|\uD83C\uDDF4\uD83C\uDDF2|\uD83D\uDC08\u200D\u2B1B|\u2764\uFE0F\u200D(?:\uD83D\uDD25|\uD83E\uDE79)|\uD83D\uDC41\uFE0F|\uD83C\uDFF3\uFE0F|\uD83C\uDDFF(?:\uD83C[\uDDE6\uDDF2\uDDFC])|\uD83C\uDDFE(?:\uD83C[\uDDEA\uDDF9])|\uD83C\uDDFC(?:\uD83C[\uDDEB\uDDF8])|\uD83C\uDDFB(?:\uD83C[\uDDE6\uDDE8\uDDEA\uDDEC\uDDEE\uDDF3\uDDFA])|\uD83C\uDDFA(?:\uD83C[\uDDE6\uDDEC\uDDF2\uDDF3\uDDF8\uDDFE\uDDFF])|\uD83C\uDDF9(?:\uD83C[\uDDE6\uDDE8\uDDE9\uDDEB-\uDDED\uDDEF-\uDDF4\uDDF7\uDDF9\uDDFB\uDDFC\uDDFF])|\uD83C\uDDF8(?:\uD83C[\uDDE6-\uDDEA\uDDEC-\uDDF4\uDDF7-\uDDF9\uDDFB\uDDFD-\uDDFF])|\uD83C\uDDF7(?:\uD83C[\uDDEA\uDDF4\uDDF8\uDDFA\uDDFC])|\uD83C\uDDF5(?:\uD83C[\uDDE6\uDDEA-\uDDED\uDDF0-\uDDF3\uDDF7-\uDDF9\uDDFC\uDDFE])|\uD83C\uDDF3(?:\uD83C[\uDDE6\uDDE8\uDDEA-\uDDEC\uDDEE\uDDF1\uDDF4\uDDF5\uDDF7\uDDFA\uDDFF])|\uD83C\uDDF2(?:\uD83C[\uDDE6\uDDE8-\uDDED\uDDF0-\uDDFF])|\uD83C\uDDF1(?:\uD83C[\uDDE6-\uDDE8\uDDEE\uDDF0\uDDF7-\uDDFB\uDDFE])|\uD83C\uDDF0(?:\uD83C[\uDDEA\uDDEC-\uDDEE\uDDF2\uDDF3\uDDF5\uDDF7\uDDFC\uDDFE\uDDFF])|\uD83C\uDDEF(?:\uD83C[\uDDEA\uDDF2\uDDF4\uDDF5])|\uD83C\uDDEE(?:\uD83C[\uDDE8-\uDDEA\uDDF1-\uDDF4\uDDF6-\uDDF9])|\uD83C\uDDED(?:\uD83C[\uDDF0\uDDF2\uDDF3\uDDF7\uDDF9\uDDFA])|\uD83C\uDDEC(?:\uD83C[\uDDE6\uDDE7\uDDE9-\uDDEE\uDDF1-\uDDF3\uDDF5-\uDDFA\uDDFC\uDDFE])|\uD83C\uDDEB(?:\uD83C[\uDDEE-\uDDF0\uDDF2\uDDF4\uDDF7])|\uD83C\uDDEA(?:\uD83C[\uDDE6\uDDE8\uDDEA\uDDEC\uDDED\uDDF7-\uDDFA])|\uD83C\uDDE9(?:\uD83C[\uDDEA\uDDEC\uDDEF\uDDF0\uDDF2\uDDF4\uDDFF])|\uD83C\uDDE8(?:\uD83C[\uDDE6\uDDE8\uDDE9\uDDEB-\uDDEE\uDDF0-\uDDF5\uDDF7\uDDFA-\uDDFF])|\uD83C\uDDE7(?:\uD83C[\uDDE6\uDDE7\uDDE9-\uDDEF\uDDF1-\uDDF4\uDDF6-\uDDF9\uDDFB\uDDFC\uDDFE\uDDFF])|\uD83C\uDDE6(?:\uD83C[\uDDE8-\uDDEC\uDDEE\uDDF1\uDDF2\uDDF4\uDDF6-\uDDFA\uDDFC\uDDFD\uDDFF])|[#\*0-9]\uFE0F\u20E3|\u2764\uFE0F|(?:\uD83C[\uDFC3\uDFC4\uDFCA]|\uD83D[\uDC6E\uDC70\uDC71\uDC73\uDC77\uDC81\uDC82\uDC86\uDC87\uDE45-\uDE47\uDE4B\uDE4D\uDE4E\uDEA3\uDEB4-\uDEB6]|\uD83E[\uDD26\uDD35\uDD37-\uDD39\uDD3D\uDD3E\uDDB8\uDDB9\uDDCD-\uDDCF\uDDD4\uDDD6-\uDDDD])(?:\uD83C[\uDFFB-\uDFFF])|(?:\u26F9|\uD83C[\uDFCB\uDFCC]|\uD83D\uDD75)(?:\uFE0F|\uD83C[\uDFFB-\uDFFF])|\uD83C\uDFF4|(?:[\u270A\u270B]|\uD83C[\uDF85\uDFC2\uDFC7]|\uD83D[\uDC42\uDC43\uDC46-\uDC50\uDC66\uDC67\uDC6B-\uDC6D\uDC72\uDC74-\uDC76\uDC78\uDC7C\uDC83\uDC85\uDC8F\uDC91\uDCAA\uDD7A\uDD95\uDD96\uDE4C\uDE4F\uDEC0\uDECC]|\uD83E[\uDD0C\uDD0F\uDD18-\uDD1C\uDD1E\uDD1F\uDD30-\uDD34\uDD36\uDD77\uDDB5\uDDB6\uDDBB\uDDD2\uDDD3\uDDD5])(?:\uD83C[\uDFFB-\uDFFF])|(?:[\u261D\u270C\u270D]|\uD83D[\uDD74\uDD90])(?:\uFE0F|\uD83C[\uDFFB-\uDFFF])|[\u270A\u270B]|\uD83C[\uDF85\uDFC2\uDFC7]|\uD83D[\uDC08\uDC15\uDC3B\uDC42\uDC43\uDC46-\uDC50\uDC66\uDC67\uDC6B-\uDC6D\uDC72\uDC74-\uDC76\uDC78\uDC7C\uDC83\uDC85\uDC8F\uDC91\uDCAA\uDD7A\uDD95\uDD96\uDE2E\uDE35\uDE36\uDE4C\uDE4F\uDEC0\uDECC]|\uD83E[\uDD0C\uDD0F\uDD18-\uDD1C\uDD1E\uDD1F\uDD30-\uDD34\uDD36\uDD77\uDDB5\uDDB6\uDDBB\uDDD2\uDDD3\uDDD5]|\uD83C[\uDFC3\uDFC4\uDFCA]|\uD83D[\uDC6E\uDC70\uDC71\uDC73\uDC77\uDC81\uDC82\uDC86\uDC87\uDE45-\uDE47\uDE4B\uDE4D\uDE4E\uDEA3\uDEB4-\uDEB6]|\uD83E[\uDD26\uDD35\uDD37-\uDD39\uDD3D\uDD3E\uDDB8\uDDB9\uDDCD-\uDDCF\uDDD4\uDDD6-\uDDDD]|\uD83D\uDC6F|\uD83E[\uDD3C\uDDDE\uDDDF]|[\u231A\u231B\u23E9-\u23EC\u23F0\u23F3\u25FD\u25FE\u2614\u2615\u2648-\u2653\u267F\u2693\u26A1\u26AA\u26AB\u26BD\u26BE\u26C4\u26C5\u26CE\u26D4\u26EA\u26F2\u26F3\u26F5\u26FA\u26FD\u2705\u2728\u274C\u274E\u2753-\u2755\u2757\u2795-\u2797\u27B0\u27BF\u2B1B\u2B1C\u2B50\u2B55]|\uD83C[\uDC04\uDCCF\uDD8E\uDD91-\uDD9A\uDE01\uDE1A\uDE2F\uDE32-\uDE36\uDE38-\uDE3A\uDE50\uDE51\uDF00-\uDF20\uDF2D-\uDF35\uDF37-\uDF7C\uDF7E-\uDF84\uDF86-\uDF93\uDFA0-\uDFC1\uDFC5\uDFC6\uDFC8\uDFC9\uDFCF-\uDFD3\uDFE0-\uDFF0\uDFF8-\uDFFF]|\uD83D[\uDC00-\uDC07\uDC09-\uDC14\uDC16-\uDC3A\uDC3C-\uDC3E\uDC40\uDC44\uDC45\uDC51-\uDC65\uDC6A\uDC79-\uDC7B\uDC7D-\uDC80\uDC84\uDC88-\uDC8E\uDC90\uDC92-\uDCA9\uDCAB-\uDCFC\uDCFF-\uDD3D\uDD4B-\uDD4E\uDD50-\uDD67\uDDA4\uDDFB-\uDE2D\uDE2F-\uDE34\uDE37-\uDE44\uDE48-\uDE4A\uDE80-\uDEA2\uDEA4-\uDEB3\uDEB7-\uDEBF\uDEC1-\uDEC5\uDED0-\uDED2\uDED5-\uDED7\uDEEB\uDEEC\uDEF4-\uDEFC\uDFE0-\uDFEB]|\uD83E[\uDD0D\uDD0E\uDD10-\uDD17\uDD1D\uDD20-\uDD25\uDD27-\uDD2F\uDD3A\uDD3F-\uDD45\uDD47-\uDD76\uDD78\uDD7A-\uDDB4\uDDB7\uDDBA\uDDBC-\uDDCB\uDDD0\uDDE0-\uDDFF\uDE70-\uDE74\uDE78-\uDE7A\uDE80-\uDE86\uDE90-\uDEA8\uDEB0-\uDEB6\uDEC0-\uDEC2\uDED0-\uDED6]|(?:[\u231A\u231B\u23E9-\u23EC\u23F0\u23F3\u25FD\u25FE\u2614\u2615\u2648-\u2653\u267F\u2693\u26A1\u26AA\u26AB\u26BD\u26BE\u26C4\u26C5\u26CE\u26D4\u26EA\u26F2\u26F3\u26F5\u26FA\u26FD\u2705\u270A\u270B\u2728\u274C\u274E\u2753-\u2755\u2757\u2795-\u2797\u27B0\u27BF\u2B1B\u2B1C\u2B50\u2B55]|\uD83C[\uDC04\uDCCF\uDD8E\uDD91-\uDD9A\uDDE6-\uDDFF\uDE01\uDE1A\uDE2F\uDE32-\uDE36\uDE38-\uDE3A\uDE50\uDE51\uDF00-\uDF20\uDF2D-\uDF35\uDF37-\uDF7C\uDF7E-\uDF93\uDFA0-\uDFCA\uDFCF-\uDFD3\uDFE0-\uDFF0\uDFF4\uDFF8-\uDFFF]|\uD83D[\uDC00-\uDC3E\uDC40\uDC42-\uDCFC\uDCFF-\uDD3D\uDD4B-\uDD4E\uDD50-\uDD67\uDD7A\uDD95\uDD96\uDDA4\uDDFB-\uDE4F\uDE80-\uDEC5\uDECC\uDED0-\uDED2\uDED5-\uDED7\uDEEB\uDEEC\uDEF4-\uDEFC\uDFE0-\uDFEB]|\uD83E[\uDD0C-\uDD3A\uDD3C-\uDD45\uDD47-\uDD78\uDD7A-\uDDCB\uDDCD-\uDDFF\uDE70-\uDE74\uDE78-\uDE7A\uDE80-\uDE86\uDE90-\uDEA8\uDEB0-\uDEB6\uDEC0-\uDEC2\uDED0-\uDED6])|(?:[#\*0-9\xA9\xAE\u203C\u2049\u2122\u2139\u2194-\u2199\u21A9\u21AA\u231A\u231B\u2328\u23CF\u23E9-\u23F3\u23F8-\u23FA\u24C2\u25AA\u25AB\u25B6\u25C0\u25FB-\u25FE\u2600-\u2604\u260E\u2611\u2614\u2615\u2618\u261D\u2620\u2622\u2623\u2626\u262A\u262E\u262F\u2638-\u263A\u2640\u2642\u2648-\u2653\u265F\u2660\u2663\u2665\u2666\u2668\u267B\u267E\u267F\u2692-\u2697\u2699\u269B\u269C\u26A0\u26A1\u26A7\u26AA\u26AB\u26B0\u26B1\u26BD\u26BE\u26C4\u26C5\u26C8\u26CE\u26CF\u26D1\u26D3\u26D4\u26E9\u26EA\u26F0-\u26F5\u26F7-\u26FA\u26FD\u2702\u2705\u2708-\u270D\u270F\u2712\u2714\u2716\u271D\u2721\u2728\u2733\u2734\u2744\u2747\u274C\u274E\u2753-\u2755\u2757\u2763\u2764\u2795-\u2797\u27A1\u27B0\u27BF\u2934\u2935\u2B05-\u2B07\u2B1B\u2B1C\u2B50\u2B55\u3030\u303D\u3297\u3299]|\uD83C[\uDC04\uDCCF\uDD70\uDD71\uDD7E\uDD7F\uDD8E\uDD91-\uDD9A\uDDE6-\uDDFF\uDE01\uDE02\uDE1A\uDE2F\uDE32-\uDE3A\uDE50\uDE51\uDF00-\uDF21\uDF24-\uDF93\uDF96\uDF97\uDF99-\uDF9B\uDF9E-\uDFF0\uDFF3-\uDFF5\uDFF7-\uDFFF]|\uD83D[\uDC00-\uDCFD\uDCFF-\uDD3D\uDD49-\uDD4E\uDD50-\uDD67\uDD6F\uDD70\uDD73-\uDD7A\uDD87\uDD8A-\uDD8D\uDD90\uDD95\uDD96\uDDA4\uDDA5\uDDA8\uDDB1\uDDB2\uDDBC\uDDC2-\uDDC4\uDDD1-\uDDD3\uDDDC-\uDDDE\uDDE1\uDDE3\uDDE8\uDDEF\uDDF3\uDDFA-\uDE4F\uDE80-\uDEC5\uDECB-\uDED2\uDED5-\uDED7\uDEE0-\uDEE5\uDEE9\uDEEB\uDEEC\uDEF0\uDEF3-\uDEFC\uDFE0-\uDFEB]|\uD83E[\uDD0C-\uDD3A\uDD3C-\uDD45\uDD47-\uDD78\uDD7A-\uDDCB\uDDCD-\uDDFF\uDE70-\uDE74\uDE78-\uDE7A\uDE80-\uDE86\uDE90-\uDEA8\uDEB0-\uDEB6\uDEC0-\uDEC2\uDED0-\uDED6])\uFE0F|(?:[\u261D\u26F9\u270A-\u270D]|\uD83C[\uDF85\uDFC2-\uDFC4\uDFC7\uDFCA-\uDFCC]|\uD83D[\uDC42\uDC43\uDC46-\uDC50\uDC66-\uDC78\uDC7C\uDC81-\uDC83\uDC85-\uDC87\uDC8F\uDC91\uDCAA\uDD74\uDD75\uDD7A\uDD90\uDD95\uDD96\uDE45-\uDE47\uDE4B-\uDE4F\uDEA3\uDEB4-\uDEB6\uDEC0\uDECC]|\uD83E[\uDD0C\uDD0F\uDD18-\uDD1F\uDD26\uDD30-\uDD39\uDD3C-\uDD3E\uDD77\uDDB5\uDDB6\uDDB8\uDDB9\uDDBB\uDDCD-\uDDCF\uDDD1-\uDDDD])/g;
+};
diff --git a/app/node_modules/emoji-regex/package.json b/app/node_modules/emoji-regex/package.json
new file mode 100644
index 0000000..eac892a
--- /dev/null
+++ b/app/node_modules/emoji-regex/package.json
@@ -0,0 +1,52 @@
+{
+ "name": "emoji-regex",
+ "version": "9.2.2",
+ "description": "A regular expression to match all Emoji-only symbols as per the Unicode Standard.",
+ "homepage": "https://mths.be/emoji-regex",
+ "main": "index.js",
+ "types": "index.d.ts",
+ "keywords": [
+ "unicode",
+ "regex",
+ "regexp",
+ "regular expressions",
+ "code points",
+ "symbols",
+ "characters",
+ "emoji"
+ ],
+ "license": "MIT",
+ "author": {
+ "name": "Mathias Bynens",
+ "url": "https://mathiasbynens.be/"
+ },
+ "repository": {
+ "type": "git",
+ "url": "https://github.com/mathiasbynens/emoji-regex.git"
+ },
+ "bugs": "https://github.com/mathiasbynens/emoji-regex/issues",
+ "files": [
+ "LICENSE-MIT.txt",
+ "index.js",
+ "index.d.ts",
+ "RGI_Emoji.js",
+ "RGI_Emoji.d.ts",
+ "text.js",
+ "text.d.ts",
+ "es2015"
+ ],
+ "scripts": {
+ "build": "rm -rf -- es2015; babel src -d .; NODE_ENV=es2015 babel src es2015_types -D -d ./es2015; node script/inject-sequences.js",
+ "test": "mocha",
+ "test:watch": "npm run test -- --watch"
+ },
+ "devDependencies": {
+ "@babel/cli": "^7.4.4",
+ "@babel/core": "^7.4.4",
+ "@babel/plugin-proposal-unicode-property-regex": "^7.4.4",
+ "@babel/preset-env": "^7.4.4",
+ "@unicode/unicode-13.0.0": "^1.0.3",
+ "mocha": "^6.1.4",
+ "regexgen": "^1.3.0"
+ }
+}
diff --git a/app/node_modules/emoji-regex/text.d.ts b/app/node_modules/emoji-regex/text.d.ts
new file mode 100644
index 0000000..c3a0125
--- /dev/null
+++ b/app/node_modules/emoji-regex/text.d.ts
@@ -0,0 +1,5 @@
+declare module 'emoji-regex/text' {
+ function emojiRegex(): RegExp;
+
+ export = emojiRegex;
+}
diff --git a/app/node_modules/emoji-regex/text.js b/app/node_modules/emoji-regex/text.js
new file mode 100644
index 0000000..9bc63ce
--- /dev/null
+++ b/app/node_modules/emoji-regex/text.js
@@ -0,0 +1,6 @@
+"use strict";
+
+module.exports = function () {
+ // https://mths.be/emoji
+ return /\uD83C\uDFF4\uDB40\uDC67\uDB40\uDC62(?:\uDB40\uDC77\uDB40\uDC6C\uDB40\uDC73|\uDB40\uDC73\uDB40\uDC63\uDB40\uDC74|\uDB40\uDC65\uDB40\uDC6E\uDB40\uDC67)\uDB40\uDC7F|(?:\uD83E\uDDD1\uD83C\uDFFF\u200D\u2764\uFE0F\u200D(?:\uD83D\uDC8B\u200D)?\uD83E\uDDD1|\uD83D\uDC69\uD83C\uDFFF\u200D\uD83E\uDD1D\u200D(?:\uD83D[\uDC68\uDC69]))(?:\uD83C[\uDFFB-\uDFFE])|(?:\uD83E\uDDD1\uD83C\uDFFE\u200D\u2764\uFE0F\u200D(?:\uD83D\uDC8B\u200D)?\uD83E\uDDD1|\uD83D\uDC69\uD83C\uDFFE\u200D\uD83E\uDD1D\u200D(?:\uD83D[\uDC68\uDC69]))(?:\uD83C[\uDFFB-\uDFFD\uDFFF])|(?:\uD83E\uDDD1\uD83C\uDFFD\u200D\u2764\uFE0F\u200D(?:\uD83D\uDC8B\u200D)?\uD83E\uDDD1|\uD83D\uDC69\uD83C\uDFFD\u200D\uD83E\uDD1D\u200D(?:\uD83D[\uDC68\uDC69]))(?:\uD83C[\uDFFB\uDFFC\uDFFE\uDFFF])|(?:\uD83E\uDDD1\uD83C\uDFFC\u200D\u2764\uFE0F\u200D(?:\uD83D\uDC8B\u200D)?\uD83E\uDDD1|\uD83D\uDC69\uD83C\uDFFC\u200D\uD83E\uDD1D\u200D(?:\uD83D[\uDC68\uDC69]))(?:\uD83C[\uDFFB\uDFFD-\uDFFF])|(?:\uD83E\uDDD1\uD83C\uDFFB\u200D\u2764\uFE0F\u200D(?:\uD83D\uDC8B\u200D)?\uD83E\uDDD1|\uD83D\uDC69\uD83C\uDFFB\u200D\uD83E\uDD1D\u200D(?:\uD83D[\uDC68\uDC69]))(?:\uD83C[\uDFFC-\uDFFF])|\uD83D\uDC68(?:\uD83C\uDFFB(?:\u200D(?:\u2764\uFE0F\u200D(?:\uD83D\uDC8B\u200D\uD83D\uDC68(?:\uD83C[\uDFFB-\uDFFF])|\uD83D\uDC68(?:\uD83C[\uDFFB-\uDFFF]))|\uD83E\uDD1D\u200D\uD83D\uDC68(?:\uD83C[\uDFFC-\uDFFF])|[\u2695\u2696\u2708]\uFE0F|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD]))?|(?:\uD83C[\uDFFC-\uDFFF])\u200D\u2764\uFE0F\u200D(?:\uD83D\uDC8B\u200D\uD83D\uDC68(?:\uD83C[\uDFFB-\uDFFF])|\uD83D\uDC68(?:\uD83C[\uDFFB-\uDFFF]))|\u200D(?:\u2764\uFE0F\u200D(?:\uD83D\uDC8B\u200D)?\uD83D\uDC68|(?:\uD83D[\uDC68\uDC69])\u200D(?:\uD83D\uDC66\u200D\uD83D\uDC66|\uD83D\uDC67\u200D(?:\uD83D[\uDC66\uDC67]))|\uD83D\uDC66\u200D\uD83D\uDC66|\uD83D\uDC67\u200D(?:\uD83D[\uDC66\uDC67])|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFF\u200D(?:\uD83E\uDD1D\u200D\uD83D\uDC68(?:\uD83C[\uDFFB-\uDFFE])|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFE\u200D(?:\uD83E\uDD1D\u200D\uD83D\uDC68(?:\uD83C[\uDFFB-\uDFFD\uDFFF])|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFD\u200D(?:\uD83E\uDD1D\u200D\uD83D\uDC68(?:\uD83C[\uDFFB\uDFFC\uDFFE\uDFFF])|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFC\u200D(?:\uD83E\uDD1D\u200D\uD83D\uDC68(?:\uD83C[\uDFFB\uDFFD-\uDFFF])|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|(?:\uD83C\uDFFF\u200D[\u2695\u2696\u2708]|\uD83C\uDFFE\u200D[\u2695\u2696\u2708]|\uD83C\uDFFD\u200D[\u2695\u2696\u2708]|\uD83C\uDFFC\u200D[\u2695\u2696\u2708]|\u200D[\u2695\u2696\u2708])\uFE0F|\u200D(?:(?:\uD83D[\uDC68\uDC69])\u200D(?:\uD83D[\uDC66\uDC67])|\uD83D[\uDC66\uDC67])|\uD83C\uDFFF|\uD83C\uDFFE|\uD83C\uDFFD|\uD83C\uDFFC)?|(?:\uD83D\uDC69(?:\uD83C\uDFFB\u200D\u2764\uFE0F\u200D(?:\uD83D\uDC8B\u200D(?:\uD83D[\uDC68\uDC69])|\uD83D[\uDC68\uDC69])|(?:\uD83C[\uDFFC-\uDFFF])\u200D\u2764\uFE0F\u200D(?:\uD83D\uDC8B\u200D(?:\uD83D[\uDC68\uDC69])|\uD83D[\uDC68\uDC69]))|\uD83E\uDDD1(?:\uD83C[\uDFFB-\uDFFF])\u200D\uD83E\uDD1D\u200D\uD83E\uDDD1)(?:\uD83C[\uDFFB-\uDFFF])|\uD83D\uDC69\u200D\uD83D\uDC69\u200D(?:\uD83D\uDC66\u200D\uD83D\uDC66|\uD83D\uDC67\u200D(?:\uD83D[\uDC66\uDC67]))|\uD83D\uDC69(?:\u200D(?:\u2764\uFE0F\u200D(?:\uD83D\uDC8B\u200D(?:\uD83D[\uDC68\uDC69])|\uD83D[\uDC68\uDC69])|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFF\u200D(?:\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFE\u200D(?:\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFD\u200D(?:\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFC\u200D(?:\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFB\u200D(?:\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD]))|\uD83E\uDDD1(?:\u200D(?:\uD83E\uDD1D\u200D\uD83E\uDDD1|\uD83C[\uDF3E\uDF73\uDF7C\uDF84\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFF\u200D(?:\uD83C[\uDF3E\uDF73\uDF7C\uDF84\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFE\u200D(?:\uD83C[\uDF3E\uDF73\uDF7C\uDF84\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFD\u200D(?:\uD83C[\uDF3E\uDF73\uDF7C\uDF84\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFC\u200D(?:\uD83C[\uDF3E\uDF73\uDF7C\uDF84\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFB\u200D(?:\uD83C[\uDF3E\uDF73\uDF7C\uDF84\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD]))|\uD83D\uDC69\u200D\uD83D\uDC66\u200D\uD83D\uDC66|\uD83D\uDC69\u200D\uD83D\uDC69\u200D(?:\uD83D[\uDC66\uDC67])|\uD83D\uDC69\u200D\uD83D\uDC67\u200D(?:\uD83D[\uDC66\uDC67])|(?:\uD83D\uDC41\uFE0F\u200D\uD83D\uDDE8|\uD83E\uDDD1(?:\uD83C\uDFFF\u200D[\u2695\u2696\u2708]|\uD83C\uDFFE\u200D[\u2695\u2696\u2708]|\uD83C\uDFFD\u200D[\u2695\u2696\u2708]|\uD83C\uDFFC\u200D[\u2695\u2696\u2708]|\uD83C\uDFFB\u200D[\u2695\u2696\u2708]|\u200D[\u2695\u2696\u2708])|\uD83D\uDC69(?:\uD83C\uDFFF\u200D[\u2695\u2696\u2708]|\uD83C\uDFFE\u200D[\u2695\u2696\u2708]|\uD83C\uDFFD\u200D[\u2695\u2696\u2708]|\uD83C\uDFFC\u200D[\u2695\u2696\u2708]|\uD83C\uDFFB\u200D[\u2695\u2696\u2708]|\u200D[\u2695\u2696\u2708])|\uD83D\uDE36\u200D\uD83C\uDF2B|\uD83C\uDFF3\uFE0F\u200D\u26A7|\uD83D\uDC3B\u200D\u2744|(?:(?:\uD83C[\uDFC3\uDFC4\uDFCA]|\uD83D[\uDC6E\uDC70\uDC71\uDC73\uDC77\uDC81\uDC82\uDC86\uDC87\uDE45-\uDE47\uDE4B\uDE4D\uDE4E\uDEA3\uDEB4-\uDEB6]|\uD83E[\uDD26\uDD35\uDD37-\uDD39\uDD3D\uDD3E\uDDB8\uDDB9\uDDCD-\uDDCF\uDDD4\uDDD6-\uDDDD])(?:\uD83C[\uDFFB-\uDFFF])|\uD83D\uDC6F|\uD83E[\uDD3C\uDDDE\uDDDF])\u200D[\u2640\u2642]|(?:\u26F9|\uD83C[\uDFCB\uDFCC]|\uD83D\uDD75)(?:\uFE0F|\uD83C[\uDFFB-\uDFFF])\u200D[\u2640\u2642]|\uD83C\uDFF4\u200D\u2620|(?:\uD83C[\uDFC3\uDFC4\uDFCA]|\uD83D[\uDC6E\uDC70\uDC71\uDC73\uDC77\uDC81\uDC82\uDC86\uDC87\uDE45-\uDE47\uDE4B\uDE4D\uDE4E\uDEA3\uDEB4-\uDEB6]|\uD83E[\uDD26\uDD35\uDD37-\uDD39\uDD3D\uDD3E\uDDB8\uDDB9\uDDCD-\uDDCF\uDDD4\uDDD6-\uDDDD])\u200D[\u2640\u2642]|[\xA9\xAE\u203C\u2049\u2122\u2139\u2194-\u2199\u21A9\u21AA\u2328\u23CF\u23ED-\u23EF\u23F1\u23F2\u23F8-\u23FA\u24C2\u25AA\u25AB\u25B6\u25C0\u25FB\u25FC\u2600-\u2604\u260E\u2611\u2618\u2620\u2622\u2623\u2626\u262A\u262E\u262F\u2638-\u263A\u2640\u2642\u265F\u2660\u2663\u2665\u2666\u2668\u267B\u267E\u2692\u2694-\u2697\u2699\u269B\u269C\u26A0\u26A7\u26B0\u26B1\u26C8\u26CF\u26D1\u26D3\u26E9\u26F0\u26F1\u26F4\u26F7\u26F8\u2702\u2708\u2709\u270F\u2712\u2714\u2716\u271D\u2721\u2733\u2734\u2744\u2747\u2763\u27A1\u2934\u2935\u2B05-\u2B07\u3030\u303D\u3297\u3299]|\uD83C[\uDD70\uDD71\uDD7E\uDD7F\uDE02\uDE37\uDF21\uDF24-\uDF2C\uDF36\uDF7D\uDF96\uDF97\uDF99-\uDF9B\uDF9E\uDF9F\uDFCD\uDFCE\uDFD4-\uDFDF\uDFF5\uDFF7]|\uD83D[\uDC3F\uDCFD\uDD49\uDD4A\uDD6F\uDD70\uDD73\uDD76-\uDD79\uDD87\uDD8A-\uDD8D\uDDA5\uDDA8\uDDB1\uDDB2\uDDBC\uDDC2-\uDDC4\uDDD1-\uDDD3\uDDDC-\uDDDE\uDDE1\uDDE3\uDDE8\uDDEF\uDDF3\uDDFA\uDECB\uDECD-\uDECF\uDEE0-\uDEE5\uDEE9\uDEF0\uDEF3])\uFE0F|\uD83C\uDFF3\uFE0F\u200D\uD83C\uDF08|\uD83D\uDC69\u200D\uD83D\uDC67|\uD83D\uDC69\u200D\uD83D\uDC66|\uD83D\uDE35\u200D\uD83D\uDCAB|\uD83D\uDE2E\u200D\uD83D\uDCA8|\uD83D\uDC15\u200D\uD83E\uDDBA|\uD83E\uDDD1(?:\uD83C\uDFFF|\uD83C\uDFFE|\uD83C\uDFFD|\uD83C\uDFFC|\uD83C\uDFFB)?|\uD83D\uDC69(?:\uD83C\uDFFF|\uD83C\uDFFE|\uD83C\uDFFD|\uD83C\uDFFC|\uD83C\uDFFB)?|\uD83C\uDDFD\uD83C\uDDF0|\uD83C\uDDF6\uD83C\uDDE6|\uD83C\uDDF4\uD83C\uDDF2|\uD83D\uDC08\u200D\u2B1B|\u2764\uFE0F\u200D(?:\uD83D\uDD25|\uD83E\uDE79)|\uD83D\uDC41\uFE0F|\uD83C\uDFF3\uFE0F|\uD83C\uDDFF(?:\uD83C[\uDDE6\uDDF2\uDDFC])|\uD83C\uDDFE(?:\uD83C[\uDDEA\uDDF9])|\uD83C\uDDFC(?:\uD83C[\uDDEB\uDDF8])|\uD83C\uDDFB(?:\uD83C[\uDDE6\uDDE8\uDDEA\uDDEC\uDDEE\uDDF3\uDDFA])|\uD83C\uDDFA(?:\uD83C[\uDDE6\uDDEC\uDDF2\uDDF3\uDDF8\uDDFE\uDDFF])|\uD83C\uDDF9(?:\uD83C[\uDDE6\uDDE8\uDDE9\uDDEB-\uDDED\uDDEF-\uDDF4\uDDF7\uDDF9\uDDFB\uDDFC\uDDFF])|\uD83C\uDDF8(?:\uD83C[\uDDE6-\uDDEA\uDDEC-\uDDF4\uDDF7-\uDDF9\uDDFB\uDDFD-\uDDFF])|\uD83C\uDDF7(?:\uD83C[\uDDEA\uDDF4\uDDF8\uDDFA\uDDFC])|\uD83C\uDDF5(?:\uD83C[\uDDE6\uDDEA-\uDDED\uDDF0-\uDDF3\uDDF7-\uDDF9\uDDFC\uDDFE])|\uD83C\uDDF3(?:\uD83C[\uDDE6\uDDE8\uDDEA-\uDDEC\uDDEE\uDDF1\uDDF4\uDDF5\uDDF7\uDDFA\uDDFF])|\uD83C\uDDF2(?:\uD83C[\uDDE6\uDDE8-\uDDED\uDDF0-\uDDFF])|\uD83C\uDDF1(?:\uD83C[\uDDE6-\uDDE8\uDDEE\uDDF0\uDDF7-\uDDFB\uDDFE])|\uD83C\uDDF0(?:\uD83C[\uDDEA\uDDEC-\uDDEE\uDDF2\uDDF3\uDDF5\uDDF7\uDDFC\uDDFE\uDDFF])|\uD83C\uDDEF(?:\uD83C[\uDDEA\uDDF2\uDDF4\uDDF5])|\uD83C\uDDEE(?:\uD83C[\uDDE8-\uDDEA\uDDF1-\uDDF4\uDDF6-\uDDF9])|\uD83C\uDDED(?:\uD83C[\uDDF0\uDDF2\uDDF3\uDDF7\uDDF9\uDDFA])|\uD83C\uDDEC(?:\uD83C[\uDDE6\uDDE7\uDDE9-\uDDEE\uDDF1-\uDDF3\uDDF5-\uDDFA\uDDFC\uDDFE])|\uD83C\uDDEB(?:\uD83C[\uDDEE-\uDDF0\uDDF2\uDDF4\uDDF7])|\uD83C\uDDEA(?:\uD83C[\uDDE6\uDDE8\uDDEA\uDDEC\uDDED\uDDF7-\uDDFA])|\uD83C\uDDE9(?:\uD83C[\uDDEA\uDDEC\uDDEF\uDDF0\uDDF2\uDDF4\uDDFF])|\uD83C\uDDE8(?:\uD83C[\uDDE6\uDDE8\uDDE9\uDDEB-\uDDEE\uDDF0-\uDDF5\uDDF7\uDDFA-\uDDFF])|\uD83C\uDDE7(?:\uD83C[\uDDE6\uDDE7\uDDE9-\uDDEF\uDDF1-\uDDF4\uDDF6-\uDDF9\uDDFB\uDDFC\uDDFE\uDDFF])|\uD83C\uDDE6(?:\uD83C[\uDDE8-\uDDEC\uDDEE\uDDF1\uDDF2\uDDF4\uDDF6-\uDDFA\uDDFC\uDDFD\uDDFF])|[#\*0-9]\uFE0F\u20E3|\u2764\uFE0F|(?:\uD83C[\uDFC3\uDFC4\uDFCA]|\uD83D[\uDC6E\uDC70\uDC71\uDC73\uDC77\uDC81\uDC82\uDC86\uDC87\uDE45-\uDE47\uDE4B\uDE4D\uDE4E\uDEA3\uDEB4-\uDEB6]|\uD83E[\uDD26\uDD35\uDD37-\uDD39\uDD3D\uDD3E\uDDB8\uDDB9\uDDCD-\uDDCF\uDDD4\uDDD6-\uDDDD])(?:\uD83C[\uDFFB-\uDFFF])|(?:\u26F9|\uD83C[\uDFCB\uDFCC]|\uD83D\uDD75)(?:\uFE0F|\uD83C[\uDFFB-\uDFFF])|\uD83C\uDFF4|(?:[\u270A\u270B]|\uD83C[\uDF85\uDFC2\uDFC7]|\uD83D[\uDC42\uDC43\uDC46-\uDC50\uDC66\uDC67\uDC6B-\uDC6D\uDC72\uDC74-\uDC76\uDC78\uDC7C\uDC83\uDC85\uDC8F\uDC91\uDCAA\uDD7A\uDD95\uDD96\uDE4C\uDE4F\uDEC0\uDECC]|\uD83E[\uDD0C\uDD0F\uDD18-\uDD1C\uDD1E\uDD1F\uDD30-\uDD34\uDD36\uDD77\uDDB5\uDDB6\uDDBB\uDDD2\uDDD3\uDDD5])(?:\uD83C[\uDFFB-\uDFFF])|(?:[\u261D\u270C\u270D]|\uD83D[\uDD74\uDD90])(?:\uFE0F|\uD83C[\uDFFB-\uDFFF])|[\u270A\u270B]|\uD83C[\uDF85\uDFC2\uDFC7]|\uD83D[\uDC08\uDC15\uDC3B\uDC42\uDC43\uDC46-\uDC50\uDC66\uDC67\uDC6B-\uDC6D\uDC72\uDC74-\uDC76\uDC78\uDC7C\uDC83\uDC85\uDC8F\uDC91\uDCAA\uDD7A\uDD95\uDD96\uDE2E\uDE35\uDE36\uDE4C\uDE4F\uDEC0\uDECC]|\uD83E[\uDD0C\uDD0F\uDD18-\uDD1C\uDD1E\uDD1F\uDD30-\uDD34\uDD36\uDD77\uDDB5\uDDB6\uDDBB\uDDD2\uDDD3\uDDD5]|\uD83C[\uDFC3\uDFC4\uDFCA]|\uD83D[\uDC6E\uDC70\uDC71\uDC73\uDC77\uDC81\uDC82\uDC86\uDC87\uDE45-\uDE47\uDE4B\uDE4D\uDE4E\uDEA3\uDEB4-\uDEB6]|\uD83E[\uDD26\uDD35\uDD37-\uDD39\uDD3D\uDD3E\uDDB8\uDDB9\uDDCD-\uDDCF\uDDD4\uDDD6-\uDDDD]|\uD83D\uDC6F|\uD83E[\uDD3C\uDDDE\uDDDF]|[\u231A\u231B\u23E9-\u23EC\u23F0\u23F3\u25FD\u25FE\u2614\u2615\u2648-\u2653\u267F\u2693\u26A1\u26AA\u26AB\u26BD\u26BE\u26C4\u26C5\u26CE\u26D4\u26EA\u26F2\u26F3\u26F5\u26FA\u26FD\u2705\u2728\u274C\u274E\u2753-\u2755\u2757\u2795-\u2797\u27B0\u27BF\u2B1B\u2B1C\u2B50\u2B55]|\uD83C[\uDC04\uDCCF\uDD8E\uDD91-\uDD9A\uDE01\uDE1A\uDE2F\uDE32-\uDE36\uDE38-\uDE3A\uDE50\uDE51\uDF00-\uDF20\uDF2D-\uDF35\uDF37-\uDF7C\uDF7E-\uDF84\uDF86-\uDF93\uDFA0-\uDFC1\uDFC5\uDFC6\uDFC8\uDFC9\uDFCF-\uDFD3\uDFE0-\uDFF0\uDFF8-\uDFFF]|\uD83D[\uDC00-\uDC07\uDC09-\uDC14\uDC16-\uDC3A\uDC3C-\uDC3E\uDC40\uDC44\uDC45\uDC51-\uDC65\uDC6A\uDC79-\uDC7B\uDC7D-\uDC80\uDC84\uDC88-\uDC8E\uDC90\uDC92-\uDCA9\uDCAB-\uDCFC\uDCFF-\uDD3D\uDD4B-\uDD4E\uDD50-\uDD67\uDDA4\uDDFB-\uDE2D\uDE2F-\uDE34\uDE37-\uDE44\uDE48-\uDE4A\uDE80-\uDEA2\uDEA4-\uDEB3\uDEB7-\uDEBF\uDEC1-\uDEC5\uDED0-\uDED2\uDED5-\uDED7\uDEEB\uDEEC\uDEF4-\uDEFC\uDFE0-\uDFEB]|\uD83E[\uDD0D\uDD0E\uDD10-\uDD17\uDD1D\uDD20-\uDD25\uDD27-\uDD2F\uDD3A\uDD3F-\uDD45\uDD47-\uDD76\uDD78\uDD7A-\uDDB4\uDDB7\uDDBA\uDDBC-\uDDCB\uDDD0\uDDE0-\uDDFF\uDE70-\uDE74\uDE78-\uDE7A\uDE80-\uDE86\uDE90-\uDEA8\uDEB0-\uDEB6\uDEC0-\uDEC2\uDED0-\uDED6]|(?:[#\*0-9\xA9\xAE\u203C\u2049\u2122\u2139\u2194-\u2199\u21A9\u21AA\u231A\u231B\u2328\u23CF\u23E9-\u23F3\u23F8-\u23FA\u24C2\u25AA\u25AB\u25B6\u25C0\u25FB-\u25FE\u2600-\u2604\u260E\u2611\u2614\u2615\u2618\u261D\u2620\u2622\u2623\u2626\u262A\u262E\u262F\u2638-\u263A\u2640\u2642\u2648-\u2653\u265F\u2660\u2663\u2665\u2666\u2668\u267B\u267E\u267F\u2692-\u2697\u2699\u269B\u269C\u26A0\u26A1\u26A7\u26AA\u26AB\u26B0\u26B1\u26BD\u26BE\u26C4\u26C5\u26C8\u26CE\u26CF\u26D1\u26D3\u26D4\u26E9\u26EA\u26F0-\u26F5\u26F7-\u26FA\u26FD\u2702\u2705\u2708-\u270D\u270F\u2712\u2714\u2716\u271D\u2721\u2728\u2733\u2734\u2744\u2747\u274C\u274E\u2753-\u2755\u2757\u2763\u2764\u2795-\u2797\u27A1\u27B0\u27BF\u2934\u2935\u2B05-\u2B07\u2B1B\u2B1C\u2B50\u2B55\u3030\u303D\u3297\u3299]|\uD83C[\uDC04\uDCCF\uDD70\uDD71\uDD7E\uDD7F\uDD8E\uDD91-\uDD9A\uDDE6-\uDDFF\uDE01\uDE02\uDE1A\uDE2F\uDE32-\uDE3A\uDE50\uDE51\uDF00-\uDF21\uDF24-\uDF93\uDF96\uDF97\uDF99-\uDF9B\uDF9E-\uDFF0\uDFF3-\uDFF5\uDFF7-\uDFFF]|\uD83D[\uDC00-\uDCFD\uDCFF-\uDD3D\uDD49-\uDD4E\uDD50-\uDD67\uDD6F\uDD70\uDD73-\uDD7A\uDD87\uDD8A-\uDD8D\uDD90\uDD95\uDD96\uDDA4\uDDA5\uDDA8\uDDB1\uDDB2\uDDBC\uDDC2-\uDDC4\uDDD1-\uDDD3\uDDDC-\uDDDE\uDDE1\uDDE3\uDDE8\uDDEF\uDDF3\uDDFA-\uDE4F\uDE80-\uDEC5\uDECB-\uDED2\uDED5-\uDED7\uDEE0-\uDEE5\uDEE9\uDEEB\uDEEC\uDEF0\uDEF3-\uDEFC\uDFE0-\uDFEB]|\uD83E[\uDD0C-\uDD3A\uDD3C-\uDD45\uDD47-\uDD78\uDD7A-\uDDCB\uDDCD-\uDDFF\uDE70-\uDE74\uDE78-\uDE7A\uDE80-\uDE86\uDE90-\uDEA8\uDEB0-\uDEB6\uDEC0-\uDEC2\uDED0-\uDED6])\uFE0F?/g;
+};
diff --git a/app/node_modules/encodeurl/HISTORY.md b/app/node_modules/encodeurl/HISTORY.md
new file mode 100644
index 0000000..41313b2
--- /dev/null
+++ b/app/node_modules/encodeurl/HISTORY.md
@@ -0,0 +1,14 @@
+1.0.2 / 2018-01-21
+==================
+
+ * Fix encoding `%` as last character
+
+1.0.1 / 2016-06-09
+==================
+
+ * Fix encoding unpaired surrogates at start/end of string
+
+1.0.0 / 2016-06-08
+==================
+
+ * Initial release
diff --git a/app/node_modules/encodeurl/LICENSE b/app/node_modules/encodeurl/LICENSE
new file mode 100644
index 0000000..8812229
--- /dev/null
+++ b/app/node_modules/encodeurl/LICENSE
@@ -0,0 +1,22 @@
+(The MIT License)
+
+Copyright (c) 2016 Douglas Christopher Wilson
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+'Software'), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
diff --git a/app/node_modules/encodeurl/README.md b/app/node_modules/encodeurl/README.md
new file mode 100644
index 0000000..127c5a0
--- /dev/null
+++ b/app/node_modules/encodeurl/README.md
@@ -0,0 +1,128 @@
+# encodeurl
+
+[![NPM Version][npm-image]][npm-url]
+[![NPM Downloads][downloads-image]][downloads-url]
+[![Node.js Version][node-version-image]][node-version-url]
+[![Build Status][travis-image]][travis-url]
+[![Test Coverage][coveralls-image]][coveralls-url]
+
+Encode a URL to a percent-encoded form, excluding already-encoded sequences
+
+## Installation
+
+This is a [Node.js](https://nodejs.org/en/) module available through the
+[npm registry](https://www.npmjs.com/). Installation is done using the
+[`npm install` command](https://docs.npmjs.com/getting-started/installing-npm-packages-locally):
+
+```sh
+$ npm install encodeurl
+```
+
+## API
+
+```js
+var encodeUrl = require('encodeurl')
+```
+
+### encodeUrl(url)
+
+Encode a URL to a percent-encoded form, excluding already-encoded sequences.
+
+This function will take an already-encoded URL and encode all the non-URL
+code points (as UTF-8 byte sequences). This function will not encode the
+"%" character unless it is not part of a valid sequence (`%20` will be
+left as-is, but `%foo` will be encoded as `%25foo`).
+
+This encode is meant to be "safe" and does not throw errors. It will try as
+hard as it can to properly encode the given URL, including replacing any raw,
+unpaired surrogate pairs with the Unicode replacement character prior to
+encoding.
+
+This function is _similar_ to the intrinsic function `encodeURI`, except it
+will not encode the `%` character if that is part of a valid sequence, will
+not encode `[` and `]` (for IPv6 hostnames) and will replace raw, unpaired
+surrogate pairs with the Unicode replacement character (instead of throwing).
+
+## Examples
+
+### Encode a URL containing user-controled data
+
+```js
+var encodeUrl = require('encodeurl')
+var escapeHtml = require('escape-html')
+
+http.createServer(function onRequest (req, res) {
+ // get encoded form of inbound url
+ var url = encodeUrl(req.url)
+
+ // create html message
+ var body = 'Location ' + escapeHtml(url) + ' not found
'
+
+ // send a 404
+ res.statusCode = 404
+ res.setHeader('Content-Type', 'text/html; charset=UTF-8')
+ res.setHeader('Content-Length', String(Buffer.byteLength(body, 'utf-8')))
+ res.end(body, 'utf-8')
+})
+```
+
+### Encode a URL for use in a header field
+
+```js
+var encodeUrl = require('encodeurl')
+var escapeHtml = require('escape-html')
+var url = require('url')
+
+http.createServer(function onRequest (req, res) {
+ // parse inbound url
+ var href = url.parse(req)
+
+ // set new host for redirect
+ href.host = 'localhost'
+ href.protocol = 'https:'
+ href.slashes = true
+
+ // create location header
+ var location = encodeUrl(url.format(href))
+
+ // create html message
+ var body = 'Redirecting to new site: ' + escapeHtml(location) + '
'
+
+ // send a 301
+ res.statusCode = 301
+ res.setHeader('Content-Type', 'text/html; charset=UTF-8')
+ res.setHeader('Content-Length', String(Buffer.byteLength(body, 'utf-8')))
+ res.setHeader('Location', location)
+ res.end(body, 'utf-8')
+})
+```
+
+## Testing
+
+```sh
+$ npm test
+$ npm run lint
+```
+
+## References
+
+- [RFC 3986: Uniform Resource Identifier (URI): Generic Syntax][rfc-3986]
+- [WHATWG URL Living Standard][whatwg-url]
+
+[rfc-3986]: https://tools.ietf.org/html/rfc3986
+[whatwg-url]: https://url.spec.whatwg.org/
+
+## License
+
+[MIT](LICENSE)
+
+[npm-image]: https://img.shields.io/npm/v/encodeurl.svg
+[npm-url]: https://npmjs.org/package/encodeurl
+[node-version-image]: https://img.shields.io/node/v/encodeurl.svg
+[node-version-url]: https://nodejs.org/en/download
+[travis-image]: https://img.shields.io/travis/pillarjs/encodeurl.svg
+[travis-url]: https://travis-ci.org/pillarjs/encodeurl
+[coveralls-image]: https://img.shields.io/coveralls/pillarjs/encodeurl.svg
+[coveralls-url]: https://coveralls.io/r/pillarjs/encodeurl?branch=master
+[downloads-image]: https://img.shields.io/npm/dm/encodeurl.svg
+[downloads-url]: https://npmjs.org/package/encodeurl
diff --git a/app/node_modules/encodeurl/index.js b/app/node_modules/encodeurl/index.js
new file mode 100644
index 0000000..fc4906c
--- /dev/null
+++ b/app/node_modules/encodeurl/index.js
@@ -0,0 +1,60 @@
+/*!
+ * encodeurl
+ * Copyright(c) 2016 Douglas Christopher Wilson
+ * MIT Licensed
+ */
+
+'use strict'
+
+/**
+ * Module exports.
+ * @public
+ */
+
+module.exports = encodeUrl
+
+/**
+ * RegExp to match non-URL code points, *after* encoding (i.e. not including "%")
+ * and including invalid escape sequences.
+ * @private
+ */
+
+var ENCODE_CHARS_REGEXP = /(?:[^\x21\x25\x26-\x3B\x3D\x3F-\x5B\x5D\x5F\x61-\x7A\x7E]|%(?:[^0-9A-Fa-f]|[0-9A-Fa-f][^0-9A-Fa-f]|$))+/g
+
+/**
+ * RegExp to match unmatched surrogate pair.
+ * @private
+ */
+
+var UNMATCHED_SURROGATE_PAIR_REGEXP = /(^|[^\uD800-\uDBFF])[\uDC00-\uDFFF]|[\uD800-\uDBFF]([^\uDC00-\uDFFF]|$)/g
+
+/**
+ * String to replace unmatched surrogate pair with.
+ * @private
+ */
+
+var UNMATCHED_SURROGATE_PAIR_REPLACE = '$1\uFFFD$2'
+
+/**
+ * Encode a URL to a percent-encoded form, excluding already-encoded sequences.
+ *
+ * This function will take an already-encoded URL and encode all the non-URL
+ * code points. This function will not encode the "%" character unless it is
+ * not part of a valid sequence (`%20` will be left as-is, but `%foo` will
+ * be encoded as `%25foo`).
+ *
+ * This encode is meant to be "safe" and does not throw errors. It will try as
+ * hard as it can to properly encode the given URL, including replacing any raw,
+ * unpaired surrogate pairs with the Unicode replacement character prior to
+ * encoding.
+ *
+ * @param {string} url
+ * @return {string}
+ * @public
+ */
+
+function encodeUrl (url) {
+ return String(url)
+ .replace(UNMATCHED_SURROGATE_PAIR_REGEXP, UNMATCHED_SURROGATE_PAIR_REPLACE)
+ .replace(ENCODE_CHARS_REGEXP, encodeURI)
+}
diff --git a/app/node_modules/encodeurl/package.json b/app/node_modules/encodeurl/package.json
new file mode 100644
index 0000000..b9f25ef
--- /dev/null
+++ b/app/node_modules/encodeurl/package.json
@@ -0,0 +1,40 @@
+{
+ "name": "encodeurl",
+ "description": "Encode a URL to a percent-encoded form, excluding already-encoded sequences",
+ "version": "1.0.2",
+ "contributors": [
+ "Douglas Christopher Wilson "
+ ],
+ "license": "MIT",
+ "keywords": [
+ "encode",
+ "encodeurl",
+ "url"
+ ],
+ "repository": "pillarjs/encodeurl",
+ "devDependencies": {
+ "eslint": "3.19.0",
+ "eslint-config-standard": "10.2.1",
+ "eslint-plugin-import": "2.8.0",
+ "eslint-plugin-node": "5.2.1",
+ "eslint-plugin-promise": "3.6.0",
+ "eslint-plugin-standard": "3.0.1",
+ "istanbul": "0.4.5",
+ "mocha": "2.5.3"
+ },
+ "files": [
+ "LICENSE",
+ "HISTORY.md",
+ "README.md",
+ "index.js"
+ ],
+ "engines": {
+ "node": ">= 0.8"
+ },
+ "scripts": {
+ "lint": "eslint .",
+ "test": "mocha --reporter spec --bail --check-leaks test/",
+ "test-cov": "istanbul cover node_modules/mocha/bin/_mocha -- --reporter dot --check-leaks test/",
+ "test-travis": "istanbul cover node_modules/mocha/bin/_mocha --report lcovonly -- --reporter spec --check-leaks test/"
+ }
+}
diff --git a/app/node_modules/es-define-property/.eslintrc b/app/node_modules/es-define-property/.eslintrc
new file mode 100644
index 0000000..46f3b12
--- /dev/null
+++ b/app/node_modules/es-define-property/.eslintrc
@@ -0,0 +1,13 @@
+{
+ "root": true,
+
+ "extends": "@ljharb",
+
+ "rules": {
+ "new-cap": ["error", {
+ "capIsNewExceptions": [
+ "GetIntrinsic",
+ ],
+ }],
+ },
+}
diff --git a/app/node_modules/es-define-property/.github/FUNDING.yml b/app/node_modules/es-define-property/.github/FUNDING.yml
new file mode 100644
index 0000000..4445451
--- /dev/null
+++ b/app/node_modules/es-define-property/.github/FUNDING.yml
@@ -0,0 +1,12 @@
+# These are supported funding model platforms
+
+github: [ljharb]
+patreon: # Replace with a single Patreon username
+open_collective: # Replace with a single Open Collective username
+ko_fi: # Replace with a single Ko-fi username
+tidelift: npm/es-define-property
+community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry
+liberapay: # Replace with a single Liberapay username
+issuehunt: # Replace with a single IssueHunt username
+otechie: # Replace with a single Otechie username
+custom: # Replace with a single custom sponsorship URL
diff --git a/app/node_modules/es-define-property/.nycrc b/app/node_modules/es-define-property/.nycrc
new file mode 100644
index 0000000..bdd626c
--- /dev/null
+++ b/app/node_modules/es-define-property/.nycrc
@@ -0,0 +1,9 @@
+{
+ "all": true,
+ "check-coverage": false,
+ "reporter": ["text-summary", "text", "html", "json"],
+ "exclude": [
+ "coverage",
+ "test"
+ ]
+}
diff --git a/app/node_modules/es-define-property/CHANGELOG.md b/app/node_modules/es-define-property/CHANGELOG.md
new file mode 100644
index 0000000..4dce2ec
--- /dev/null
+++ b/app/node_modules/es-define-property/CHANGELOG.md
@@ -0,0 +1,15 @@
+# Changelog
+
+All notable changes to this project will be documented in this file.
+
+The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/)
+and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
+
+## v1.0.0 - 2024-02-12
+
+### Commits
+
+- Initial implementation, tests, readme, types [`3e154e1`](https://github.com/ljharb/es-define-property/commit/3e154e11a2fee09127220f5e503bf2c0a31dd480)
+- Initial commit [`07d98de`](https://github.com/ljharb/es-define-property/commit/07d98de34a4dc31ff5e83a37c0c3f49e0d85cd50)
+- npm init [`c4eb634`](https://github.com/ljharb/es-define-property/commit/c4eb6348b0d3886aac36cef34ad2ee0665ea6f3e)
+- Only apps should have lockfiles [`7af86ec`](https://github.com/ljharb/es-define-property/commit/7af86ec1d311ec0b17fdfe616a25f64276903856)
diff --git a/app/node_modules/es-define-property/LICENSE b/app/node_modules/es-define-property/LICENSE
new file mode 100644
index 0000000..f82f389
--- /dev/null
+++ b/app/node_modules/es-define-property/LICENSE
@@ -0,0 +1,21 @@
+MIT License
+
+Copyright (c) 2024 Jordan Harband
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
diff --git a/app/node_modules/es-define-property/README.md b/app/node_modules/es-define-property/README.md
new file mode 100644
index 0000000..9b291bd
--- /dev/null
+++ b/app/node_modules/es-define-property/README.md
@@ -0,0 +1,49 @@
+# es-define-property [![Version Badge][npm-version-svg]][package-url]
+
+[![github actions][actions-image]][actions-url]
+[![coverage][codecov-image]][codecov-url]
+[![License][license-image]][license-url]
+[![Downloads][downloads-image]][downloads-url]
+
+[![npm badge][npm-badge-png]][package-url]
+
+`Object.defineProperty`, but not IE 8's broken one.
+
+## Example
+
+```js
+const assert = require('assert');
+
+const $defineProperty = require('es-define-property');
+
+if ($defineProperty) {
+ assert.equal($defineProperty, Object.defineProperty);
+} else if (Object.defineProperty) {
+ assert.equal($defineProperty, false, 'this is IE 8');
+} else {
+ assert.equal($defineProperty, false, 'this is an ES3 engine');
+}
+```
+
+## Tests
+Simply clone the repo, `npm install`, and run `npm test`
+
+## Security
+
+Please email [@ljharb](https://github.com/ljharb) or see https://tidelift.com/security if you have a potential security vulnerability to report.
+
+[package-url]: https://npmjs.org/package/es-define-property
+[npm-version-svg]: https://versionbadg.es/ljharb/es-define-property.svg
+[deps-svg]: https://david-dm.org/ljharb/es-define-property.svg
+[deps-url]: https://david-dm.org/ljharb/es-define-property
+[dev-deps-svg]: https://david-dm.org/ljharb/es-define-property/dev-status.svg
+[dev-deps-url]: https://david-dm.org/ljharb/es-define-property#info=devDependencies
+[npm-badge-png]: https://nodei.co/npm/es-define-property.png?downloads=true&stars=true
+[license-image]: https://img.shields.io/npm/l/es-define-property.svg
+[license-url]: LICENSE
+[downloads-image]: https://img.shields.io/npm/dm/es-define-property.svg
+[downloads-url]: https://npm-stat.com/charts.html?package=es-define-property
+[codecov-image]: https://codecov.io/gh/ljharb/es-define-property/branch/main/graphs/badge.svg
+[codecov-url]: https://app.codecov.io/gh/ljharb/es-define-property/
+[actions-image]: https://img.shields.io/endpoint?url=https://github-actions-badge-u3jn4tfpocch.runkit.sh/ljharb/es-define-property
+[actions-url]: https://github.com/ljharb/es-define-property/actions
diff --git a/app/node_modules/es-define-property/index.d.ts b/app/node_modules/es-define-property/index.d.ts
new file mode 100644
index 0000000..6012247
--- /dev/null
+++ b/app/node_modules/es-define-property/index.d.ts
@@ -0,0 +1,3 @@
+declare const defineProperty: false | typeof Object.defineProperty;
+
+export = defineProperty;
\ No newline at end of file
diff --git a/app/node_modules/es-define-property/index.js b/app/node_modules/es-define-property/index.js
new file mode 100644
index 0000000..f32737d
--- /dev/null
+++ b/app/node_modules/es-define-property/index.js
@@ -0,0 +1,16 @@
+'use strict';
+
+var GetIntrinsic = require('get-intrinsic');
+
+/** @type {import('.')} */
+var $defineProperty = GetIntrinsic('%Object.defineProperty%', true) || false;
+if ($defineProperty) {
+ try {
+ $defineProperty({}, 'a', { value: 1 });
+ } catch (e) {
+ // IE 8 has a broken defineProperty
+ $defineProperty = false;
+ }
+}
+
+module.exports = $defineProperty;
diff --git a/app/node_modules/es-define-property/package.json b/app/node_modules/es-define-property/package.json
new file mode 100644
index 0000000..45bc90f
--- /dev/null
+++ b/app/node_modules/es-define-property/package.json
@@ -0,0 +1,81 @@
+{
+ "name": "es-define-property",
+ "version": "1.0.0",
+ "description": "`Object.defineProperty`, but not IE 8's broken one.",
+ "main": "index.js",
+ "types": "./index.d.ts",
+ "exports": {
+ ".": "./index.js",
+ "./package.json": "./package.json"
+ },
+ "sideEffects": false,
+ "scripts": {
+ "prepack": "npmignore --auto --commentLines=autogenerated",
+ "prepublish": "not-in-publish || npm run prepublishOnly",
+ "prepublishOnly": "safe-publish-latest",
+ "prelint": "evalmd README.md",
+ "lint": "eslint --ext=js,mjs .",
+ "postlint": "tsc -p .",
+ "pretest": "npm run lint",
+ "tests-only": "nyc tape 'test/**/*.js'",
+ "test": "npm run tests-only",
+ "posttest": "aud --production",
+ "version": "auto-changelog && git add CHANGELOG.md",
+ "postversion": "auto-changelog && git add CHANGELOG.md && git commit --no-edit --amend && git tag -f \"v$(node -e \"console.log(require('./package.json').version)\")\""
+ },
+ "repository": {
+ "type": "git",
+ "url": "git+https://github.com/ljharb/es-define-property.git"
+ },
+ "keywords": [
+ "javascript",
+ "ecmascript",
+ "object",
+ "define",
+ "property",
+ "defineProperty",
+ "Object.defineProperty"
+ ],
+ "author": "Jordan Harband ",
+ "license": "MIT",
+ "bugs": {
+ "url": "https://github.com/ljharb/es-define-property/issues"
+ },
+ "homepage": "https://github.com/ljharb/es-define-property#readme",
+ "dependencies": {
+ "get-intrinsic": "^1.2.4"
+ },
+ "devDependencies": {
+ "@ljharb/eslint-config": "^21.1.0",
+ "@types/get-intrinsic": "^1.2.2",
+ "@types/gopd": "^1.0.3",
+ "@types/tape": "^5.6.4",
+ "aud": "^2.0.4",
+ "auto-changelog": "^2.4.0",
+ "eslint": "^8.8.0",
+ "evalmd": "^0.0.19",
+ "gopd": "^1.0.1",
+ "in-publish": "^2.0.1",
+ "npmignore": "^0.3.1",
+ "nyc": "^10.3.2",
+ "safe-publish-latest": "^2.0.0",
+ "tape": "^5.7.4",
+ "typescript": "next"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "auto-changelog": {
+ "output": "CHANGELOG.md",
+ "template": "keepachangelog",
+ "unreleased": false,
+ "commitLimit": false,
+ "backfillLimit": false,
+ "hideCredit": true
+ },
+ "publishConfig": {
+ "ignore": [
+ ".github/workflows"
+ ]
+ }
+}
diff --git a/app/node_modules/es-define-property/test/index.js b/app/node_modules/es-define-property/test/index.js
new file mode 100644
index 0000000..dbc054e
--- /dev/null
+++ b/app/node_modules/es-define-property/test/index.js
@@ -0,0 +1,55 @@
+'use strict';
+
+var $defineProperty = require('../');
+
+var test = require('tape');
+var gOPD = require('gopd');
+
+test('defineProperty: supported', { skip: !$defineProperty }, function (t) {
+ t.plan(4);
+
+ t.equal(typeof $defineProperty, 'function', 'defineProperty is supported');
+ if ($defineProperty && gOPD) { // this `if` check is just to shut TS up
+ var o = { a: 1 };
+
+ $defineProperty(o, 'b', { enumerable: true, value: 2 });
+ t.deepEqual(
+ gOPD(o, 'b'),
+ {
+ configurable: false,
+ enumerable: true,
+ value: 2,
+ writable: false
+ },
+ 'property descriptor is as expected'
+ );
+
+ $defineProperty(o, 'c', { enumerable: false, value: 3, writable: true });
+ t.deepEqual(
+ gOPD(o, 'c'),
+ {
+ configurable: false,
+ enumerable: false,
+ value: 3,
+ writable: true
+ },
+ 'property descriptor is as expected'
+ );
+ }
+
+ t.equal($defineProperty, Object.defineProperty, 'defineProperty is Object.defineProperty');
+
+ t.end();
+});
+
+test('defineProperty: not supported', { skip: !!$defineProperty }, function (t) {
+ t.notOk($defineProperty, 'defineProperty is not supported');
+
+ t.match(
+ typeof $defineProperty,
+ /^(?:undefined|boolean)$/,
+ '`typeof defineProperty` is `undefined` or `boolean`'
+ );
+
+ t.end();
+});
diff --git a/app/node_modules/es-define-property/tsconfig.json b/app/node_modules/es-define-property/tsconfig.json
new file mode 100644
index 0000000..fdfa155
--- /dev/null
+++ b/app/node_modules/es-define-property/tsconfig.json
@@ -0,0 +1,50 @@
+{
+ "compilerOptions": {
+ /* Visit https://aka.ms/tsconfig.json to read more about this file */
+
+ /* Projects */
+
+ /* Language and Environment */
+ "target": "es2022", /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */
+ // "lib": [], /* Specify a set of bundled library declaration files that describe the target runtime environment. */
+ // "noLib": true, /* Disable including any library files, including the default lib.d.ts. */
+ "useDefineForClassFields": true, /* Emit ECMAScript-standard-compliant class fields. */
+ // "moduleDetection": "auto", /* Control what method is used to detect module-format JS files. */
+
+ /* Modules */
+ "module": "commonjs", /* Specify what module code is generated. */
+ // "rootDir": "./", /* Specify the root folder within your source files. */
+ // "moduleResolution": "node", /* Specify how TypeScript looks up a file from a given module specifier. */
+ // "baseUrl": "./", /* Specify the base directory to resolve non-relative module names. */
+ // "paths": {}, /* Specify a set of entries that re-map imports to additional lookup locations. */
+ // "rootDirs": [], /* Allow multiple folders to be treated as one when resolving modules. */
+ // "typeRoots": ["types"], /* Specify multiple folders that act like `./node_modules/@types`. */
+ "resolveJsonModule": true, /* Enable importing .json files. */
+ // "allowArbitraryExtensions": true, /* Enable importing files with any extension, provided a declaration file is present. */
+
+ /* JavaScript Support */
+ "allowJs": true, /* Allow JavaScript files to be a part of your program. Use the `checkJS` option to get errors from these files. */
+ "checkJs": true, /* Enable error reporting in type-checked JavaScript files. */
+ "maxNodeModuleJsDepth": 1, /* Specify the maximum folder depth used for checking JavaScript files from `node_modules`. Only applicable with `allowJs`. */
+
+ /* Emit */
+ "declaration": true, /* Generate .d.ts files from TypeScript and JavaScript files in your project. */
+ "declarationMap": true, /* Create sourcemaps for d.ts files. */
+ "noEmit": true, /* Disable emitting files from a compilation. */
+
+ /* Interop Constraints */
+ "allowSyntheticDefaultImports": true, /* Allow `import x from y` when a module doesn't have a default export. */
+ "esModuleInterop": true, /* Emit additional JavaScript to ease support for importing CommonJS modules. This enables `allowSyntheticDefaultImports` for type compatibility. */
+ "forceConsistentCasingInFileNames": true, /* Ensure that casing is correct in imports. */
+
+ /* Type Checking */
+ "strict": true, /* Enable all strict type-checking options. */
+
+ /* Completeness */
+ // "skipLibCheck": true /* Skip type checking all .d.ts files. */
+ },
+ "exclude": [
+ "coverage",
+ "test/list-exports"
+ ],
+}
diff --git a/app/node_modules/es-errors/.eslintrc b/app/node_modules/es-errors/.eslintrc
new file mode 100644
index 0000000..3b5d9e9
--- /dev/null
+++ b/app/node_modules/es-errors/.eslintrc
@@ -0,0 +1,5 @@
+{
+ "root": true,
+
+ "extends": "@ljharb",
+}
diff --git a/app/node_modules/es-errors/.github/FUNDING.yml b/app/node_modules/es-errors/.github/FUNDING.yml
new file mode 100644
index 0000000..f1b8805
--- /dev/null
+++ b/app/node_modules/es-errors/.github/FUNDING.yml
@@ -0,0 +1,12 @@
+# These are supported funding model platforms
+
+github: [ljharb]
+patreon: # Replace with a single Patreon username
+open_collective: # Replace with a single Open Collective username
+ko_fi: # Replace with a single Ko-fi username
+tidelift: npm/es-errors
+community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry
+liberapay: # Replace with a single Liberapay username
+issuehunt: # Replace with a single IssueHunt username
+otechie: # Replace with a single Otechie username
+custom: # Replace with a single custom sponsorship URL
diff --git a/app/node_modules/es-errors/CHANGELOG.md b/app/node_modules/es-errors/CHANGELOG.md
new file mode 100644
index 0000000..204a9e9
--- /dev/null
+++ b/app/node_modules/es-errors/CHANGELOG.md
@@ -0,0 +1,40 @@
+# Changelog
+
+All notable changes to this project will be documented in this file.
+
+The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/)
+and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
+
+## [v1.3.0](https://github.com/ljharb/es-errors/compare/v1.2.1...v1.3.0) - 2024-02-05
+
+### Commits
+
+- [New] add `EvalError` and `URIError` [`1927627`](https://github.com/ljharb/es-errors/commit/1927627ba68cb6c829d307231376c967db53acdf)
+
+## [v1.2.1](https://github.com/ljharb/es-errors/compare/v1.2.0...v1.2.1) - 2024-02-04
+
+### Commits
+
+- [Fix] add missing `exports` entry [`5bb5f28`](https://github.com/ljharb/es-errors/commit/5bb5f280f98922701109d6ebb82eea2257cecc7e)
+
+## [v1.2.0](https://github.com/ljharb/es-errors/compare/v1.1.0...v1.2.0) - 2024-02-04
+
+### Commits
+
+- [New] add `ReferenceError` [`6d8cf5b`](https://github.com/ljharb/es-errors/commit/6d8cf5bbb6f3f598d02cf6f30e468ba2caa8e143)
+
+## [v1.1.0](https://github.com/ljharb/es-errors/compare/v1.0.0...v1.1.0) - 2024-02-04
+
+### Commits
+
+- [New] add base Error [`2983ab6`](https://github.com/ljharb/es-errors/commit/2983ab65f7bc5441276cb021dc3aa03c78881698)
+
+## v1.0.0 - 2024-02-03
+
+### Commits
+
+- Initial implementation, tests, readme, type [`8f47631`](https://github.com/ljharb/es-errors/commit/8f476317e9ad76f40ad648081829b1a1a3a1288b)
+- Initial commit [`ea5d099`](https://github.com/ljharb/es-errors/commit/ea5d099ef18e550509ab9e2be000526afd81c385)
+- npm init [`6f5ebf9`](https://github.com/ljharb/es-errors/commit/6f5ebf9cead474dadd72b9e63dad315820a089ae)
+- Only apps should have lockfiles [`e1a0aeb`](https://github.com/ljharb/es-errors/commit/e1a0aeb7b80f5cfc56be54d6b2100e915d47def8)
+- [meta] add `sideEffects` flag [`a9c7d46`](https://github.com/ljharb/es-errors/commit/a9c7d460a492f1d8a241c836bc25a322a19cc043)
diff --git a/app/node_modules/es-errors/LICENSE b/app/node_modules/es-errors/LICENSE
new file mode 100644
index 0000000..f82f389
--- /dev/null
+++ b/app/node_modules/es-errors/LICENSE
@@ -0,0 +1,21 @@
+MIT License
+
+Copyright (c) 2024 Jordan Harband
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
diff --git a/app/node_modules/es-errors/README.md b/app/node_modules/es-errors/README.md
new file mode 100644
index 0000000..8dbfacf
--- /dev/null
+++ b/app/node_modules/es-errors/README.md
@@ -0,0 +1,55 @@
+# es-errors [![Version Badge][npm-version-svg]][package-url]
+
+[![github actions][actions-image]][actions-url]
+[![coverage][codecov-image]][codecov-url]
+[![License][license-image]][license-url]
+[![Downloads][downloads-image]][downloads-url]
+
+[![npm badge][npm-badge-png]][package-url]
+
+A simple cache for a few of the JS Error constructors.
+
+## Example
+
+```js
+const assert = require('assert');
+
+const Base = require('es-errors');
+const Eval = require('es-errors/eval');
+const Range = require('es-errors/range');
+const Ref = require('es-errors/ref');
+const Syntax = require('es-errors/syntax');
+const Type = require('es-errors/type');
+const URI = require('es-errors/uri');
+
+assert.equal(Base, Error);
+assert.equal(Eval, EvalError);
+assert.equal(Range, RangeError);
+assert.equal(Ref, ReferenceError);
+assert.equal(Syntax, SyntaxError);
+assert.equal(Type, TypeError);
+assert.equal(URI, URIError);
+```
+
+## Tests
+Simply clone the repo, `npm install`, and run `npm test`
+
+## Security
+
+Please email [@ljharb](https://github.com/ljharb) or see https://tidelift.com/security if you have a potential security vulnerability to report.
+
+[package-url]: https://npmjs.org/package/es-errors
+[npm-version-svg]: https://versionbadg.es/ljharb/es-errors.svg
+[deps-svg]: https://david-dm.org/ljharb/es-errors.svg
+[deps-url]: https://david-dm.org/ljharb/es-errors
+[dev-deps-svg]: https://david-dm.org/ljharb/es-errors/dev-status.svg
+[dev-deps-url]: https://david-dm.org/ljharb/es-errors#info=devDependencies
+[npm-badge-png]: https://nodei.co/npm/es-errors.png?downloads=true&stars=true
+[license-image]: https://img.shields.io/npm/l/es-errors.svg
+[license-url]: LICENSE
+[downloads-image]: https://img.shields.io/npm/dm/es-errors.svg
+[downloads-url]: https://npm-stat.com/charts.html?package=es-errors
+[codecov-image]: https://codecov.io/gh/ljharb/es-errors/branch/main/graphs/badge.svg
+[codecov-url]: https://app.codecov.io/gh/ljharb/es-errors/
+[actions-image]: https://img.shields.io/endpoint?url=https://github-actions-badge-u3jn4tfpocch.runkit.sh/ljharb/es-errors
+[actions-url]: https://github.com/ljharb/es-errors/actions
diff --git a/app/node_modules/es-errors/eval.d.ts b/app/node_modules/es-errors/eval.d.ts
new file mode 100644
index 0000000..e4210e0
--- /dev/null
+++ b/app/node_modules/es-errors/eval.d.ts
@@ -0,0 +1,3 @@
+declare const EvalError: EvalErrorConstructor;
+
+export = EvalError;
diff --git a/app/node_modules/es-errors/eval.js b/app/node_modules/es-errors/eval.js
new file mode 100644
index 0000000..725ccb6
--- /dev/null
+++ b/app/node_modules/es-errors/eval.js
@@ -0,0 +1,4 @@
+'use strict';
+
+/** @type {import('./eval')} */
+module.exports = EvalError;
diff --git a/app/node_modules/es-errors/index.d.ts b/app/node_modules/es-errors/index.d.ts
new file mode 100644
index 0000000..69bdbc9
--- /dev/null
+++ b/app/node_modules/es-errors/index.d.ts
@@ -0,0 +1,3 @@
+declare const Error: ErrorConstructor;
+
+export = Error;
diff --git a/app/node_modules/es-errors/index.js b/app/node_modules/es-errors/index.js
new file mode 100644
index 0000000..cc0c521
--- /dev/null
+++ b/app/node_modules/es-errors/index.js
@@ -0,0 +1,4 @@
+'use strict';
+
+/** @type {import('.')} */
+module.exports = Error;
diff --git a/app/node_modules/es-errors/package.json b/app/node_modules/es-errors/package.json
new file mode 100644
index 0000000..ff8c2a5
--- /dev/null
+++ b/app/node_modules/es-errors/package.json
@@ -0,0 +1,80 @@
+{
+ "name": "es-errors",
+ "version": "1.3.0",
+ "description": "A simple cache for a few of the JS Error constructors.",
+ "main": "index.js",
+ "exports": {
+ ".": "./index.js",
+ "./eval": "./eval.js",
+ "./range": "./range.js",
+ "./ref": "./ref.js",
+ "./syntax": "./syntax.js",
+ "./type": "./type.js",
+ "./uri": "./uri.js",
+ "./package.json": "./package.json"
+ },
+ "sideEffects": false,
+ "scripts": {
+ "prepack": "npmignore --auto --commentLines=autogenerated",
+ "prepublishOnly": "safe-publish-latest",
+ "prepublish": "not-in-publish || npm run prepublishOnly",
+ "pretest": "npm run lint",
+ "test": "npm run tests-only",
+ "tests-only": "nyc tape 'test/**/*.js'",
+ "posttest": "aud --production",
+ "prelint": "evalmd README.md",
+ "lint": "eslint --ext=js,mjs .",
+ "postlint": "tsc -p . && eclint check $(git ls-files | xargs find 2> /dev/null | grep -vE 'node_modules|\\.git' | grep -v dist/)",
+ "version": "auto-changelog && git add CHANGELOG.md",
+ "postversion": "auto-changelog && git add CHANGELOG.md && git commit --no-edit --amend && git tag -f \"v$(node -e \"console.log(require('./package.json').version)\")\""
+ },
+ "repository": {
+ "type": "git",
+ "url": "git+https://github.com/ljharb/es-errors.git"
+ },
+ "keywords": [
+ "javascript",
+ "ecmascript",
+ "error",
+ "typeerror",
+ "syntaxerror",
+ "rangeerror"
+ ],
+ "author": "Jordan Harband ",
+ "license": "MIT",
+ "bugs": {
+ "url": "https://github.com/ljharb/es-errors/issues"
+ },
+ "homepage": "https://github.com/ljharb/es-errors#readme",
+ "devDependencies": {
+ "@ljharb/eslint-config": "^21.1.0",
+ "@types/tape": "^5.6.4",
+ "aud": "^2.0.4",
+ "auto-changelog": "^2.4.0",
+ "eclint": "^2.8.1",
+ "eslint": "^8.8.0",
+ "evalmd": "^0.0.19",
+ "in-publish": "^2.0.1",
+ "npmignore": "^0.3.1",
+ "nyc": "^10.3.2",
+ "safe-publish-latest": "^2.0.0",
+ "tape": "^5.7.4",
+ "typescript": "next"
+ },
+ "auto-changelog": {
+ "output": "CHANGELOG.md",
+ "template": "keepachangelog",
+ "unreleased": false,
+ "commitLimit": false,
+ "backfillLimit": false,
+ "hideCredit": true
+ },
+ "publishConfig": {
+ "ignore": [
+ ".github/workflows"
+ ]
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+}
diff --git a/app/node_modules/es-errors/range.d.ts b/app/node_modules/es-errors/range.d.ts
new file mode 100644
index 0000000..3a12e86
--- /dev/null
+++ b/app/node_modules/es-errors/range.d.ts
@@ -0,0 +1,3 @@
+declare const RangeError: RangeErrorConstructor;
+
+export = RangeError;
diff --git a/app/node_modules/es-errors/range.js b/app/node_modules/es-errors/range.js
new file mode 100644
index 0000000..2044fe0
--- /dev/null
+++ b/app/node_modules/es-errors/range.js
@@ -0,0 +1,4 @@
+'use strict';
+
+/** @type {import('./range')} */
+module.exports = RangeError;
diff --git a/app/node_modules/es-errors/ref.d.ts b/app/node_modules/es-errors/ref.d.ts
new file mode 100644
index 0000000..a13107e
--- /dev/null
+++ b/app/node_modules/es-errors/ref.d.ts
@@ -0,0 +1,3 @@
+declare const ReferenceError: ReferenceErrorConstructor;
+
+export = ReferenceError;
diff --git a/app/node_modules/es-errors/ref.js b/app/node_modules/es-errors/ref.js
new file mode 100644
index 0000000..d7c430f
--- /dev/null
+++ b/app/node_modules/es-errors/ref.js
@@ -0,0 +1,4 @@
+'use strict';
+
+/** @type {import('./ref')} */
+module.exports = ReferenceError;
diff --git a/app/node_modules/es-errors/syntax.d.ts b/app/node_modules/es-errors/syntax.d.ts
new file mode 100644
index 0000000..6a0c53c
--- /dev/null
+++ b/app/node_modules/es-errors/syntax.d.ts
@@ -0,0 +1,3 @@
+declare const SyntaxError: SyntaxErrorConstructor;
+
+export = SyntaxError;
diff --git a/app/node_modules/es-errors/syntax.js b/app/node_modules/es-errors/syntax.js
new file mode 100644
index 0000000..5f5fdde
--- /dev/null
+++ b/app/node_modules/es-errors/syntax.js
@@ -0,0 +1,4 @@
+'use strict';
+
+/** @type {import('./syntax')} */
+module.exports = SyntaxError;
diff --git a/app/node_modules/es-errors/test/index.js b/app/node_modules/es-errors/test/index.js
new file mode 100644
index 0000000..1ff0277
--- /dev/null
+++ b/app/node_modules/es-errors/test/index.js
@@ -0,0 +1,19 @@
+'use strict';
+
+var test = require('tape');
+
+var E = require('../');
+var R = require('../range');
+var Ref = require('../ref');
+var S = require('../syntax');
+var T = require('../type');
+
+test('errors', function (t) {
+ t.equal(E, Error);
+ t.equal(R, RangeError);
+ t.equal(Ref, ReferenceError);
+ t.equal(S, SyntaxError);
+ t.equal(T, TypeError);
+
+ t.end();
+});
diff --git a/app/node_modules/es-errors/tsconfig.json b/app/node_modules/es-errors/tsconfig.json
new file mode 100644
index 0000000..99dfeb6
--- /dev/null
+++ b/app/node_modules/es-errors/tsconfig.json
@@ -0,0 +1,49 @@
+{
+ "compilerOptions": {
+ /* Visit https://aka.ms/tsconfig.json to read more about this file */
+
+ /* Projects */
+
+ /* Language and Environment */
+ "target": "es5", /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */
+ // "lib": [], /* Specify a set of bundled library declaration files that describe the target runtime environment. */
+ // "noLib": true, /* Disable including any library files, including the default lib.d.ts. */
+ "useDefineForClassFields": true, /* Emit ECMAScript-standard-compliant class fields. */
+ // "moduleDetection": "auto", /* Control what method is used to detect module-format JS files. */
+
+ /* Modules */
+ "module": "commonjs", /* Specify what module code is generated. */
+ // "rootDir": "./", /* Specify the root folder within your source files. */
+ // "moduleResolution": "node", /* Specify how TypeScript looks up a file from a given module specifier. */
+ // "baseUrl": "./", /* Specify the base directory to resolve non-relative module names. */
+ // "paths": {}, /* Specify a set of entries that re-map imports to additional lookup locations. */
+ // "rootDirs": [], /* Allow multiple folders to be treated as one when resolving modules. */
+ // "typeRoots": ["types"], /* Specify multiple folders that act like `./node_modules/@types`. */
+ "resolveJsonModule": true, /* Enable importing .json files. */
+ // "allowArbitraryExtensions": true, /* Enable importing files with any extension, provided a declaration file is present. */
+
+ /* JavaScript Support */
+ "allowJs": true, /* Allow JavaScript files to be a part of your program. Use the `checkJS` option to get errors from these files. */
+ "checkJs": true, /* Enable error reporting in type-checked JavaScript files. */
+ "maxNodeModuleJsDepth": 1, /* Specify the maximum folder depth used for checking JavaScript files from `node_modules`. Only applicable with `allowJs`. */
+
+ /* Emit */
+ "declaration": true, /* Generate .d.ts files from TypeScript and JavaScript files in your project. */
+ "declarationMap": true, /* Create sourcemaps for d.ts files. */
+ "noEmit": true, /* Disable emitting files from a compilation. */
+
+ /* Interop Constraints */
+ "allowSyntheticDefaultImports": true, /* Allow `import x from y` when a module doesn't have a default export. */
+ "esModuleInterop": true, /* Emit additional JavaScript to ease support for importing CommonJS modules. This enables `allowSyntheticDefaultImports` for type compatibility. */
+ "forceConsistentCasingInFileNames": true, /* Ensure that casing is correct in imports. */
+
+ /* Type Checking */
+ "strict": true, /* Enable all strict type-checking options. */
+
+ /* Completeness */
+ // "skipLibCheck": true /* Skip type checking all .d.ts files. */
+ },
+ "exclude": [
+ "coverage",
+ ],
+}
diff --git a/app/node_modules/es-errors/type.d.ts b/app/node_modules/es-errors/type.d.ts
new file mode 100644
index 0000000..576fb51
--- /dev/null
+++ b/app/node_modules/es-errors/type.d.ts
@@ -0,0 +1,3 @@
+declare const TypeError: TypeErrorConstructor
+
+export = TypeError;
diff --git a/app/node_modules/es-errors/type.js b/app/node_modules/es-errors/type.js
new file mode 100644
index 0000000..9769e44
--- /dev/null
+++ b/app/node_modules/es-errors/type.js
@@ -0,0 +1,4 @@
+'use strict';
+
+/** @type {import('./type')} */
+module.exports = TypeError;
diff --git a/app/node_modules/es-errors/uri.d.ts b/app/node_modules/es-errors/uri.d.ts
new file mode 100644
index 0000000..c3261c9
--- /dev/null
+++ b/app/node_modules/es-errors/uri.d.ts
@@ -0,0 +1,3 @@
+declare const URIError: URIErrorConstructor;
+
+export = URIError;
diff --git a/app/node_modules/es-errors/uri.js b/app/node_modules/es-errors/uri.js
new file mode 100644
index 0000000..e9cd1c7
--- /dev/null
+++ b/app/node_modules/es-errors/uri.js
@@ -0,0 +1,4 @@
+'use strict';
+
+/** @type {import('./uri')} */
+module.exports = URIError;
diff --git a/app/node_modules/escape-html/LICENSE b/app/node_modules/escape-html/LICENSE
new file mode 100644
index 0000000..2e70de9
--- /dev/null
+++ b/app/node_modules/escape-html/LICENSE
@@ -0,0 +1,24 @@
+(The MIT License)
+
+Copyright (c) 2012-2013 TJ Holowaychuk
+Copyright (c) 2015 Andreas Lubbe
+Copyright (c) 2015 Tiancheng "Timothy" Gu
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+'Software'), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
diff --git a/app/node_modules/escape-html/Readme.md b/app/node_modules/escape-html/Readme.md
new file mode 100644
index 0000000..653d9ea
--- /dev/null
+++ b/app/node_modules/escape-html/Readme.md
@@ -0,0 +1,43 @@
+
+# escape-html
+
+ Escape string for use in HTML
+
+## Example
+
+```js
+var escape = require('escape-html');
+var html = escape('foo & bar');
+// -> foo & bar
+```
+
+## Benchmark
+
+```
+$ npm run-script bench
+
+> escape-html@1.0.3 bench nodejs-escape-html
+> node benchmark/index.js
+
+
+ http_parser@1.0
+ node@0.10.33
+ v8@3.14.5.9
+ ares@1.9.0-DEV
+ uv@0.10.29
+ zlib@1.2.3
+ modules@11
+ openssl@1.0.1j
+
+ 1 test completed.
+ 2 tests completed.
+ 3 tests completed.
+
+ no special characters x 19,435,271 ops/sec ±0.85% (187 runs sampled)
+ single special character x 6,132,421 ops/sec ±0.67% (194 runs sampled)
+ many special characters x 3,175,826 ops/sec ±0.65% (193 runs sampled)
+```
+
+## License
+
+ MIT
\ No newline at end of file
diff --git a/app/node_modules/escape-html/index.js b/app/node_modules/escape-html/index.js
new file mode 100644
index 0000000..bf9e226
--- /dev/null
+++ b/app/node_modules/escape-html/index.js
@@ -0,0 +1,78 @@
+/*!
+ * escape-html
+ * Copyright(c) 2012-2013 TJ Holowaychuk
+ * Copyright(c) 2015 Andreas Lubbe
+ * Copyright(c) 2015 Tiancheng "Timothy" Gu
+ * MIT Licensed
+ */
+
+'use strict';
+
+/**
+ * Module variables.
+ * @private
+ */
+
+var matchHtmlRegExp = /["'&<>]/;
+
+/**
+ * Module exports.
+ * @public
+ */
+
+module.exports = escapeHtml;
+
+/**
+ * Escape special characters in the given string of html.
+ *
+ * @param {string} string The string to escape for inserting into HTML
+ * @return {string}
+ * @public
+ */
+
+function escapeHtml(string) {
+ var str = '' + string;
+ var match = matchHtmlRegExp.exec(str);
+
+ if (!match) {
+ return str;
+ }
+
+ var escape;
+ var html = '';
+ var index = 0;
+ var lastIndex = 0;
+
+ for (index = match.index; index < str.length; index++) {
+ switch (str.charCodeAt(index)) {
+ case 34: // "
+ escape = '"';
+ break;
+ case 38: // &
+ escape = '&';
+ break;
+ case 39: // '
+ escape = ''';
+ break;
+ case 60: // <
+ escape = '<';
+ break;
+ case 62: // >
+ escape = '>';
+ break;
+ default:
+ continue;
+ }
+
+ if (lastIndex !== index) {
+ html += str.substring(lastIndex, index);
+ }
+
+ lastIndex = index + 1;
+ html += escape;
+ }
+
+ return lastIndex !== index
+ ? html + str.substring(lastIndex, index)
+ : html;
+}
diff --git a/app/node_modules/escape-html/package.json b/app/node_modules/escape-html/package.json
new file mode 100644
index 0000000..57ec7bd
--- /dev/null
+++ b/app/node_modules/escape-html/package.json
@@ -0,0 +1,24 @@
+{
+ "name": "escape-html",
+ "description": "Escape string for use in HTML",
+ "version": "1.0.3",
+ "license": "MIT",
+ "keywords": [
+ "escape",
+ "html",
+ "utility"
+ ],
+ "repository": "component/escape-html",
+ "devDependencies": {
+ "benchmark": "1.0.0",
+ "beautify-benchmark": "0.2.4"
+ },
+ "files": [
+ "LICENSE",
+ "Readme.md",
+ "index.js"
+ ],
+ "scripts": {
+ "bench": "node benchmark/index.js"
+ }
+}
diff --git a/app/node_modules/etag/HISTORY.md b/app/node_modules/etag/HISTORY.md
new file mode 100644
index 0000000..222b293
--- /dev/null
+++ b/app/node_modules/etag/HISTORY.md
@@ -0,0 +1,83 @@
+1.8.1 / 2017-09-12
+==================
+
+ * perf: replace regular expression with substring
+
+1.8.0 / 2017-02-18
+==================
+
+ * Use SHA1 instead of MD5 for ETag hashing
+ - Improves performance for larger entities
+ - Works with FIPS 140-2 OpenSSL configuration
+
+1.7.0 / 2015-06-08
+==================
+
+ * Always include entity length in ETags for hash length extensions
+ * Generate non-Stats ETags using MD5 only (no longer CRC32)
+ * Improve stat performance by removing hashing
+ * Remove base64 padding in ETags to shorten
+ * Use MD5 instead of MD4 in weak ETags over 1KB
+
+1.6.0 / 2015-05-10
+==================
+
+ * Improve support for JXcore
+ * Remove requirement of `atime` in the stats object
+ * Support "fake" stats objects in environments without `fs`
+
+1.5.1 / 2014-11-19
+==================
+
+ * deps: crc@3.2.1
+ - Minor fixes
+
+1.5.0 / 2014-10-14
+==================
+
+ * Improve string performance
+ * Slightly improve speed for weak ETags over 1KB
+
+1.4.0 / 2014-09-21
+==================
+
+ * Support "fake" stats objects
+ * Support Node.js 0.6
+
+1.3.1 / 2014-09-14
+==================
+
+ * Use the (new and improved) `crc` for crc32
+
+1.3.0 / 2014-08-29
+==================
+
+ * Default strings to strong ETags
+ * Improve speed for weak ETags over 1KB
+
+1.2.1 / 2014-08-29
+==================
+
+ * Use the (much faster) `buffer-crc32` for crc32
+
+1.2.0 / 2014-08-24
+==================
+
+ * Add support for file stat objects
+
+1.1.0 / 2014-08-24
+==================
+
+ * Add fast-path for empty entity
+ * Add weak ETag generation
+ * Shrink size of generated ETags
+
+1.0.1 / 2014-08-24
+==================
+
+ * Fix behavior of string containing Unicode
+
+1.0.0 / 2014-05-18
+==================
+
+ * Initial release
diff --git a/app/node_modules/etag/LICENSE b/app/node_modules/etag/LICENSE
new file mode 100644
index 0000000..cab251c
--- /dev/null
+++ b/app/node_modules/etag/LICENSE
@@ -0,0 +1,22 @@
+(The MIT License)
+
+Copyright (c) 2014-2016 Douglas Christopher Wilson
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+'Software'), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
diff --git a/app/node_modules/etag/README.md b/app/node_modules/etag/README.md
new file mode 100644
index 0000000..09c2169
--- /dev/null
+++ b/app/node_modules/etag/README.md
@@ -0,0 +1,159 @@
+# etag
+
+[![NPM Version][npm-image]][npm-url]
+[![NPM Downloads][downloads-image]][downloads-url]
+[![Node.js Version][node-version-image]][node-version-url]
+[![Build Status][travis-image]][travis-url]
+[![Test Coverage][coveralls-image]][coveralls-url]
+
+Create simple HTTP ETags
+
+This module generates HTTP ETags (as defined in RFC 7232) for use in
+HTTP responses.
+
+## Installation
+
+This is a [Node.js](https://nodejs.org/en/) module available through the
+[npm registry](https://www.npmjs.com/). Installation is done using the
+[`npm install` command](https://docs.npmjs.com/getting-started/installing-npm-packages-locally):
+
+```sh
+$ npm install etag
+```
+
+## API
+
+
+
+```js
+var etag = require('etag')
+```
+
+### etag(entity, [options])
+
+Generate a strong ETag for the given entity. This should be the complete
+body of the entity. Strings, `Buffer`s, and `fs.Stats` are accepted. By
+default, a strong ETag is generated except for `fs.Stats`, which will
+generate a weak ETag (this can be overwritten by `options.weak`).
+
+
+
+```js
+res.setHeader('ETag', etag(body))
+```
+
+#### Options
+
+`etag` accepts these properties in the options object.
+
+##### weak
+
+Specifies if the generated ETag will include the weak validator mark (that
+is, the leading `W/`). The actual entity tag is the same. The default value
+is `false`, unless the `entity` is `fs.Stats`, in which case it is `true`.
+
+## Testing
+
+```sh
+$ npm test
+```
+
+## Benchmark
+
+```bash
+$ npm run-script bench
+
+> etag@1.8.1 bench nodejs-etag
+> node benchmark/index.js
+
+ http_parser@2.7.0
+ node@6.11.1
+ v8@5.1.281.103
+ uv@1.11.0
+ zlib@1.2.11
+ ares@1.10.1-DEV
+ icu@58.2
+ modules@48
+ openssl@1.0.2k
+
+> node benchmark/body0-100b.js
+
+ 100B body
+
+ 4 tests completed.
+
+ buffer - strong x 258,647 ops/sec ±1.07% (180 runs sampled)
+ buffer - weak x 263,812 ops/sec ±0.61% (184 runs sampled)
+ string - strong x 259,955 ops/sec ±1.19% (185 runs sampled)
+ string - weak x 264,356 ops/sec ±1.09% (184 runs sampled)
+
+> node benchmark/body1-1kb.js
+
+ 1KB body
+
+ 4 tests completed.
+
+ buffer - strong x 189,018 ops/sec ±1.12% (182 runs sampled)
+ buffer - weak x 190,586 ops/sec ±0.81% (186 runs sampled)
+ string - strong x 144,272 ops/sec ±0.96% (188 runs sampled)
+ string - weak x 145,380 ops/sec ±1.43% (187 runs sampled)
+
+> node benchmark/body2-5kb.js
+
+ 5KB body
+
+ 4 tests completed.
+
+ buffer - strong x 92,435 ops/sec ±0.42% (188 runs sampled)
+ buffer - weak x 92,373 ops/sec ±0.58% (189 runs sampled)
+ string - strong x 48,850 ops/sec ±0.56% (186 runs sampled)
+ string - weak x 49,380 ops/sec ±0.56% (190 runs sampled)
+
+> node benchmark/body3-10kb.js
+
+ 10KB body
+
+ 4 tests completed.
+
+ buffer - strong x 55,989 ops/sec ±0.93% (188 runs sampled)
+ buffer - weak x 56,148 ops/sec ±0.55% (190 runs sampled)
+ string - strong x 27,345 ops/sec ±0.43% (188 runs sampled)
+ string - weak x 27,496 ops/sec ±0.45% (190 runs sampled)
+
+> node benchmark/body4-100kb.js
+
+ 100KB body
+
+ 4 tests completed.
+
+ buffer - strong x 7,083 ops/sec ±0.22% (190 runs sampled)
+ buffer - weak x 7,115 ops/sec ±0.26% (191 runs sampled)
+ string - strong x 3,068 ops/sec ±0.34% (190 runs sampled)
+ string - weak x 3,096 ops/sec ±0.35% (190 runs sampled)
+
+> node benchmark/stats.js
+
+ stat
+
+ 4 tests completed.
+
+ real - strong x 871,642 ops/sec ±0.34% (189 runs sampled)
+ real - weak x 867,613 ops/sec ±0.39% (190 runs sampled)
+ fake - strong x 401,051 ops/sec ±0.40% (189 runs sampled)
+ fake - weak x 400,100 ops/sec ±0.47% (188 runs sampled)
+```
+
+## License
+
+[MIT](LICENSE)
+
+[npm-image]: https://img.shields.io/npm/v/etag.svg
+[npm-url]: https://npmjs.org/package/etag
+[node-version-image]: https://img.shields.io/node/v/etag.svg
+[node-version-url]: https://nodejs.org/en/download/
+[travis-image]: https://img.shields.io/travis/jshttp/etag/master.svg
+[travis-url]: https://travis-ci.org/jshttp/etag
+[coveralls-image]: https://img.shields.io/coveralls/jshttp/etag/master.svg
+[coveralls-url]: https://coveralls.io/r/jshttp/etag?branch=master
+[downloads-image]: https://img.shields.io/npm/dm/etag.svg
+[downloads-url]: https://npmjs.org/package/etag
diff --git a/app/node_modules/etag/index.js b/app/node_modules/etag/index.js
new file mode 100644
index 0000000..2a585c9
--- /dev/null
+++ b/app/node_modules/etag/index.js
@@ -0,0 +1,131 @@
+/*!
+ * etag
+ * Copyright(c) 2014-2016 Douglas Christopher Wilson
+ * MIT Licensed
+ */
+
+'use strict'
+
+/**
+ * Module exports.
+ * @public
+ */
+
+module.exports = etag
+
+/**
+ * Module dependencies.
+ * @private
+ */
+
+var crypto = require('crypto')
+var Stats = require('fs').Stats
+
+/**
+ * Module variables.
+ * @private
+ */
+
+var toString = Object.prototype.toString
+
+/**
+ * Generate an entity tag.
+ *
+ * @param {Buffer|string} entity
+ * @return {string}
+ * @private
+ */
+
+function entitytag (entity) {
+ if (entity.length === 0) {
+ // fast-path empty
+ return '"0-2jmj7l5rSw0yVb/vlWAYkK/YBwk"'
+ }
+
+ // compute hash of entity
+ var hash = crypto
+ .createHash('sha1')
+ .update(entity, 'utf8')
+ .digest('base64')
+ .substring(0, 27)
+
+ // compute length of entity
+ var len = typeof entity === 'string'
+ ? Buffer.byteLength(entity, 'utf8')
+ : entity.length
+
+ return '"' + len.toString(16) + '-' + hash + '"'
+}
+
+/**
+ * Create a simple ETag.
+ *
+ * @param {string|Buffer|Stats} entity
+ * @param {object} [options]
+ * @param {boolean} [options.weak]
+ * @return {String}
+ * @public
+ */
+
+function etag (entity, options) {
+ if (entity == null) {
+ throw new TypeError('argument entity is required')
+ }
+
+ // support fs.Stats object
+ var isStats = isstats(entity)
+ var weak = options && typeof options.weak === 'boolean'
+ ? options.weak
+ : isStats
+
+ // validate argument
+ if (!isStats && typeof entity !== 'string' && !Buffer.isBuffer(entity)) {
+ throw new TypeError('argument entity must be string, Buffer, or fs.Stats')
+ }
+
+ // generate entity tag
+ var tag = isStats
+ ? stattag(entity)
+ : entitytag(entity)
+
+ return weak
+ ? 'W/' + tag
+ : tag
+}
+
+/**
+ * Determine if object is a Stats object.
+ *
+ * @param {object} obj
+ * @return {boolean}
+ * @api private
+ */
+
+function isstats (obj) {
+ // genuine fs.Stats
+ if (typeof Stats === 'function' && obj instanceof Stats) {
+ return true
+ }
+
+ // quack quack
+ return obj && typeof obj === 'object' &&
+ 'ctime' in obj && toString.call(obj.ctime) === '[object Date]' &&
+ 'mtime' in obj && toString.call(obj.mtime) === '[object Date]' &&
+ 'ino' in obj && typeof obj.ino === 'number' &&
+ 'size' in obj && typeof obj.size === 'number'
+}
+
+/**
+ * Generate a tag for a stat.
+ *
+ * @param {object} stat
+ * @return {string}
+ * @private
+ */
+
+function stattag (stat) {
+ var mtime = stat.mtime.getTime().toString(16)
+ var size = stat.size.toString(16)
+
+ return '"' + size + '-' + mtime + '"'
+}
diff --git a/app/node_modules/etag/package.json b/app/node_modules/etag/package.json
new file mode 100644
index 0000000..b06ab80
--- /dev/null
+++ b/app/node_modules/etag/package.json
@@ -0,0 +1,47 @@
+{
+ "name": "etag",
+ "description": "Create simple HTTP ETags",
+ "version": "1.8.1",
+ "contributors": [
+ "Douglas Christopher Wilson ",
+ "David Björklund "
+ ],
+ "license": "MIT",
+ "keywords": [
+ "etag",
+ "http",
+ "res"
+ ],
+ "repository": "jshttp/etag",
+ "devDependencies": {
+ "beautify-benchmark": "0.2.4",
+ "benchmark": "2.1.4",
+ "eslint": "3.19.0",
+ "eslint-config-standard": "10.2.1",
+ "eslint-plugin-import": "2.7.0",
+ "eslint-plugin-markdown": "1.0.0-beta.6",
+ "eslint-plugin-node": "5.1.1",
+ "eslint-plugin-promise": "3.5.0",
+ "eslint-plugin-standard": "3.0.1",
+ "istanbul": "0.4.5",
+ "mocha": "1.21.5",
+ "safe-buffer": "5.1.1",
+ "seedrandom": "2.4.3"
+ },
+ "files": [
+ "LICENSE",
+ "HISTORY.md",
+ "README.md",
+ "index.js"
+ ],
+ "engines": {
+ "node": ">= 0.6"
+ },
+ "scripts": {
+ "bench": "node benchmark/index.js",
+ "lint": "eslint --plugin markdown --ext js,md .",
+ "test": "mocha --reporter spec --bail --check-leaks test/",
+ "test-cov": "istanbul cover node_modules/mocha/bin/_mocha -- --reporter dot --check-leaks test/",
+ "test-travis": "istanbul cover node_modules/mocha/bin/_mocha --report lcovonly -- --reporter spec --check-leaks test/"
+ }
+}
diff --git a/app/node_modules/express-handlebars/.eslintignore b/app/node_modules/express-handlebars/.eslintignore
new file mode 100644
index 0000000..e7dda6c
--- /dev/null
+++ b/app/node_modules/express-handlebars/.eslintignore
@@ -0,0 +1,4 @@
+node_modules/
+npm-debug.log
+coverage/
+dist/
diff --git a/app/node_modules/express-handlebars/.eslintrc.js b/app/node_modules/express-handlebars/.eslintrc.js
new file mode 100644
index 0000000..7a6e2f4
--- /dev/null
+++ b/app/node_modules/express-handlebars/.eslintrc.js
@@ -0,0 +1,42 @@
+module.exports = {
+ root: true,
+ env: {
+ node: true,
+ jest: true,
+ },
+ extends: [
+ "standard",
+ "plugin:@typescript-eslint/recommended",
+ ],
+ plugins: [
+ "@typescript-eslint",
+ ],
+ parser: "@typescript-eslint/parser",
+ parserOptions: {
+ ecmaVersion: 2018,
+ },
+ rules: {
+ quotes: ["error", "double"],
+ semi: ["error", "always"],
+ "no-warning-comments": "warn",
+ "comma-dangle": ["error", "always-multiline"],
+ indent: ["error", "tab", { SwitchCase: 1 }],
+ "no-tabs": "off",
+ "no-var": "error",
+ "prefer-const": "error",
+ "object-shorthand": "error",
+ "no-restricted-globals": [
+ "error",
+ {
+ name: "fit",
+ message: "Do not commit focused tests.",
+ },
+ {
+ name: "fdescribe",
+ message: "Do not commit focused tests.",
+ },
+ ],
+ "@typescript-eslint/ban-ts-comment": "warn",
+ "@typescript-eslint/no-var-requires": "warn",
+ },
+};
diff --git a/app/node_modules/express-handlebars/.github/workflows/codeql-analysis.yml b/app/node_modules/express-handlebars/.github/workflows/codeql-analysis.yml
new file mode 100644
index 0000000..e4cb080
--- /dev/null
+++ b/app/node_modules/express-handlebars/.github/workflows/codeql-analysis.yml
@@ -0,0 +1,71 @@
+# For most projects, this workflow file will not need changing; you simply need
+# to commit it to your repository.
+#
+# You may wish to alter this file to override the set of languages analyzed,
+# or to provide custom queries or build logic.
+name: "CodeQL"
+
+on:
+ push:
+ branches: [master]
+ pull_request:
+ # The branches below must be a subset of the branches above
+ branches: [master]
+ schedule:
+ - cron: '0 15 * * 4'
+
+jobs:
+ analyze:
+ name: Analyze
+ runs-on: ubuntu-latest
+
+ strategy:
+ fail-fast: false
+ matrix:
+ # Override automatic language detection by changing the below list
+ # Supported options are ['csharp', 'cpp', 'go', 'java', 'javascript', 'python']
+ language: ['javascript']
+ # Learn more...
+ # https://docs.github.com/en/github/finding-security-vulnerabilities-and-errors-in-your-code/configuring-code-scanning#overriding-automatic-language-detection
+
+ steps:
+ - name: Checkout repository
+ uses: actions/checkout@v3
+ with:
+ # We must fetch at least the immediate parents so that if this is
+ # a pull request then we can checkout the head.
+ fetch-depth: 2
+
+ # If this run was triggered by a pull request event, then checkout
+ # the head of the pull request instead of the merge commit.
+ - run: git checkout HEAD^2
+ if: ${{ github.event_name == 'pull_request' }}
+
+ # Initializes the CodeQL tools for scanning.
+ - name: Initialize CodeQL
+ uses: github/codeql-action/init@v2
+ with:
+ languages: ${{ matrix.language }}
+ # If you wish to specify custom queries, you can do so here or in a config file.
+ # By default, queries listed here will override any specified in a config file.
+ # Prefix the list here with "+" to use these queries and those in the config file.
+ # queries: ./path/to/local/query, your-org/your-repo/queries@main
+
+ # Autobuild attempts to build any compiled languages (C/C++, C#, or Java).
+ # If this step fails, then you should remove it and run the build manually (see below)
+ - name: Autobuild
+ uses: github/codeql-action/autobuild@v2
+
+ # â„¹ï¸ Command-line programs to run using the OS shell.
+ # 📚 https://git.io/JvXDl
+
+ # âœï¸ If the Autobuild fails above, remove it and uncomment the following three lines
+ # and modify them (or add more) to build your code if your project
+ # uses a compiled language
+
+ #- run: |
+ # make bootstrap
+ # make release
+
+ - name: Perform CodeQL Analysis
+ uses: github/codeql-action/analyze@v2
diff --git a/app/node_modules/express-handlebars/.github/workflows/main.yml b/app/node_modules/express-handlebars/.github/workflows/main.yml
new file mode 100644
index 0000000..8f322f5
--- /dev/null
+++ b/app/node_modules/express-handlebars/.github/workflows/main.yml
@@ -0,0 +1,115 @@
+name: "Tests"
+on:
+ pull_request:
+ push:
+ branches:
+ - master
+
+env:
+ CI: true
+
+jobs:
+ TestOS:
+ name: Test
+ strategy:
+ matrix:
+ os: [macos-latest, windows-latest]
+ node_version: ['lts/*']
+ runs-on: ${{ matrix.os }}
+ steps:
+ - name: Checkout Code
+ uses: actions/checkout@v3
+ - name: Install Node
+ uses: actions/setup-node@v3
+ with:
+ node-version: ${{ matrix.node_version }}
+ check-latest: true
+ - name: Install dependencies
+ run: npm ci
+ - name: Run tests 👩ðŸ¾â€ðŸ’»
+ run: npm run test
+ TestNode:
+ name: Test
+ strategy:
+ matrix:
+ os: [ubuntu-latest]
+ node_version: ['lts/*', '*']
+ runs-on: ${{ matrix.os }}
+ steps:
+ - name: Checkout Code
+ uses: actions/checkout@v3
+ - name: Install Node
+ uses: actions/setup-node@v3
+ with:
+ node-version: ${{ matrix.node_version }}
+ check-latest: true
+ - name: Install dependencies
+ run: npm ci
+ - name: Run tests 👩ðŸ¾â€ðŸ’»
+ run: npm run test
+ Coverage:
+ runs-on: ubuntu-latest
+ steps:
+ - name: Checkout Code
+ uses: actions/checkout@v3
+ - name: Install Node
+ uses: actions/setup-node@v3
+ with:
+ node-version: 'lts/*'
+ check-latest: true
+ - name: Install dependencies
+ run: npm ci
+ - name: Run tests 👩ðŸ¾â€ðŸ’»
+ run: npm run test:cover
+ Lint:
+ runs-on: ubuntu-latest
+ steps:
+ - name: Checkout Code
+ uses: actions/checkout@v3
+ - name: Install Node
+ uses: actions/setup-node@v3
+ with:
+ node-version: 'lts/*'
+ check-latest: true
+ - name: NPM install
+ run: npm ci
+ - name: Lint ✨
+ run: npm run lint
+ Build:
+ runs-on: ubuntu-latest
+ steps:
+ - name: Checkout Code
+ uses: actions/checkout@v3
+ - name: Install Node
+ uses: actions/setup-node@v3
+ with:
+ node-version: 'lts/*'
+ check-latest: true
+ - name: NPM install
+ run: npm ci
+ - name: Build 🧱
+ run: npm run build
+
+ Release:
+ needs: [TestOS, TestNode, Coverage, Lint, Build]
+ if: |
+ github.ref == 'refs/heads/master' &&
+ github.event.repository.fork == false
+ runs-on: ubuntu-latest
+ steps:
+ - name: Checkout Code
+ uses: actions/checkout@v3
+ - name: Install Node
+ uses: actions/setup-node@v3
+ with:
+ node-version: 'lts/*'
+ check-latest: true
+ - name: NPM install
+ run: npm ci
+ - name: NPM build
+ run: npm run build
+ - name: Release 🎉
+ env:
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+ NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
+ run: npx semantic-release
diff --git a/app/node_modules/express-handlebars/CHANGELOG.md b/app/node_modules/express-handlebars/CHANGELOG.md
new file mode 100644
index 0000000..67fddfc
--- /dev/null
+++ b/app/node_modules/express-handlebars/CHANGELOG.md
@@ -0,0 +1,259 @@
+## [7.1.2](https://github.com/express-handlebars/express-handlebars/compare/v7.1.1...v7.1.2) (2023-08-08)
+
+
+### Bug Fixes
+
+* use types from handlebars for helpers ([#617](https://github.com/express-handlebars/express-handlebars/issues/617)) ([bc38da4](https://github.com/express-handlebars/express-handlebars/commit/bc38da4199cdc450dd84537c0515da475ef0d6ad))
+
+## [7.1.1](https://github.com/express-handlebars/express-handlebars/compare/v7.1.0...v7.1.1) (2023-08-02)
+
+
+### Bug Fixes
+
+* **deps:** update dependency handlebars to ^4.7.8 ([#616](https://github.com/express-handlebars/express-handlebars/issues/616)) ([54ef900](https://github.com/express-handlebars/express-handlebars/commit/54ef9006ad1dd425a166bd4f1fdd08aa0911dc19))
+
+# [7.1.0](https://github.com/express-handlebars/express-handlebars/compare/v7.0.7...v7.1.0) (2023-07-20)
+
+
+### Features
+
+* add resetCache ([#554](https://github.com/express-handlebars/express-handlebars/issues/554)) ([868e9b4](https://github.com/express-handlebars/express-handlebars/commit/868e9b4ac9690de5000385c1fecdef858cf8d504))
+
+## [7.0.7](https://github.com/express-handlebars/express-handlebars/compare/v7.0.6...v7.0.7) (2023-04-15)
+
+
+### Bug Fixes
+
+* **deps:** update dependency glob to ^10.1.0 ([#555](https://github.com/express-handlebars/express-handlebars/issues/555)) ([196c925](https://github.com/express-handlebars/express-handlebars/commit/196c9255716856ae741a9c6672821ff8e2aeb2a9))
+
+## [7.0.6](https://github.com/express-handlebars/express-handlebars/compare/v7.0.5...v7.0.6) (2023-04-12)
+
+
+### Bug Fixes
+
+* replace backslash in partials with forward slash ([#553](https://github.com/express-handlebars/express-handlebars/issues/553)) ([2ecd784](https://github.com/express-handlebars/express-handlebars/commit/2ecd7840cb16d0e5013469b84183211e02212053))
+
+## [7.0.5](https://github.com/express-handlebars/express-handlebars/compare/v7.0.4...v7.0.5) (2023-04-11)
+
+
+### Bug Fixes
+
+* **deps:** update dependency glob to v10 ([#551](https://github.com/express-handlebars/express-handlebars/issues/551)) ([7817150](https://github.com/express-handlebars/express-handlebars/commit/7817150a1c06b9cb50826574a2e2127d5730c268))
+
+## [7.0.4](https://github.com/express-handlebars/express-handlebars/compare/v7.0.3...v7.0.4) (2023-03-23)
+
+
+### Bug Fixes
+
+* **deps:** update dependency graceful-fs to ^4.2.11 ([#531](https://github.com/express-handlebars/express-handlebars/issues/531)) ([570e73d](https://github.com/express-handlebars/express-handlebars/commit/570e73da862694ee3b760c3616eb23ace7b0d4af))
+
+## [7.0.3](https://github.com/express-handlebars/express-handlebars/compare/v7.0.2...v7.0.3) (2023-03-23)
+
+
+### Bug Fixes
+
+* **deps:** update dependency glob to ^9.3.2 ([#526](https://github.com/express-handlebars/express-handlebars/issues/526)) ([2aa9c4a](https://github.com/express-handlebars/express-handlebars/commit/2aa9c4aa58cf43d25ae7dd4b21110523451ebaac))
+
+## [7.0.2](https://github.com/express-handlebars/express-handlebars/compare/v7.0.1...v7.0.2) (2023-03-09)
+
+
+### Bug Fixes
+
+* **deps:** update dependency glob to ^9.2.1 ([#520](https://github.com/express-handlebars/express-handlebars/issues/520)) ([16a9bc3](https://github.com/express-handlebars/express-handlebars/commit/16a9bc356ba333586bb1626d2402d9aa7df948fd))
+
+## [7.0.1](https://github.com/express-handlebars/express-handlebars/compare/v7.0.0...v7.0.1) (2023-03-01)
+
+
+### Bug Fixes
+
+* **deps:** update dependency glob to ^9.1.0 ([#518](https://github.com/express-handlebars/express-handlebars/issues/518)) ([635922c](https://github.com/express-handlebars/express-handlebars/commit/635922c746c76b0f36fe7061fcecc7c9f64d3b1b))
+* fix cannot use import ([0f45477](https://github.com/express-handlebars/express-handlebars/commit/0f45477b822a9d7814e1d05c493e4b827279717c))
+
+# [7.0.0](https://github.com/express-handlebars/express-handlebars/compare/v6.0.7...v7.0.0) (2023-03-01)
+
+
+### Bug Fixes
+
+* **deps:** update dependency glob to v9 ([#514](https://github.com/express-handlebars/express-handlebars/issues/514)) ([3b08bbb](https://github.com/express-handlebars/express-handlebars/commit/3b08bbb05fe195a855a090fadc11fc183f5c2292))
+* minimum Node v16 ([#516](https://github.com/express-handlebars/express-handlebars/issues/516)) ([86da3b2](https://github.com/express-handlebars/express-handlebars/commit/86da3b229b9c3bdf1c0e5924a796199a861ec260))
+
+
+### BREAKING CHANGES
+
+* minimum node version is v16
+
+## [6.0.7](https://github.com/express-handlebars/express-handlebars/compare/v6.0.6...v6.0.7) (2023-01-25)
+
+
+### Bug Fixes
+
+* **deps:** update dependency glob to ^8.1.0 ([#489](https://github.com/express-handlebars/express-handlebars/issues/489)) ([1bb2a2f](https://github.com/express-handlebars/express-handlebars/commit/1bb2a2f3dae7148afc5468bc916f6abe08381937))
+
+## [6.0.6](https://github.com/express-handlebars/express-handlebars/compare/v6.0.5...v6.0.6) (2022-05-13)
+
+
+### Bug Fixes
+
+* **deps:** update dependency glob to ^8.0.2 ([8202ea1](https://github.com/express-handlebars/express-handlebars/commit/8202ea19fb6e4354edd05dc457d2f3a14a5c29d9))
+
+## [6.0.5](https://github.com/express-handlebars/express-handlebars/compare/v6.0.4...v6.0.5) (2022-04-11)
+
+
+### Bug Fixes
+
+* **deps:** update dependency glob to v8 ([4025b58](https://github.com/express-handlebars/express-handlebars/commit/4025b58534b794863b2f51dcdc779d347a46c4a6))
+
+## [6.0.4](https://github.com/express-handlebars/express-handlebars/compare/v6.0.3...v6.0.4) (2022-04-06)
+
+
+### Bug Fixes
+
+* **deps:** update dependency graceful-fs to ^4.2.10 ([2d6e89c](https://github.com/express-handlebars/express-handlebars/commit/2d6e89c219b11000125f7bc2630f6ddaf241987d))
+
+## [6.0.3](https://github.com/express-handlebars/express-handlebars/compare/v6.0.2...v6.0.3) (2022-03-03)
+
+
+### Bug Fixes
+
+* allow false for defaultLayout ([#303](https://github.com/express-handlebars/express-handlebars/issues/303)) ([d6180fe](https://github.com/express-handlebars/express-handlebars/commit/d6180fe7ad8ab74e60f58b4ced1b6d6af2d68c42))
+* **deps:** update dependency graceful-fs to ^4.2.9 ([#271](https://github.com/express-handlebars/express-handlebars/issues/271)) ([ea0f1f5](https://github.com/express-handlebars/express-handlebars/commit/ea0f1f563488d67202d7d6067116a4fe67eddf18))
+
+## [6.0.2](https://github.com/express-handlebars/express-handlebars/compare/v6.0.1...v6.0.2) (2021-11-25)
+
+
+### Bug Fixes
+
+* fix typescript in strict mode ([6833d8d](https://github.com/express-handlebars/express-handlebars/commit/6833d8dd4532e45790e04940b646e33f5fd07429))
+
+## [6.0.1](https://github.com/express-handlebars/express-handlebars/compare/v6.0.0...v6.0.1) (2021-11-13)
+
+
+### Bug Fixes
+
+* fix types ([f4de857](https://github.com/express-handlebars/express-handlebars/commit/f4de8577d5ad4510f4c5286cdee300dd27c6abfc))
+* remove default export ([a7f38a1](https://github.com/express-handlebars/express-handlebars/commit/a7f38a1d3127d63450b10b3f3539e3ce8131b677))
+* update examples ([1b1f5f7](https://github.com/express-handlebars/express-handlebars/commit/1b1f5f7b818985d433f6dc0398f7866c62b6cdea))
+
+# [6.0.0](https://github.com/express-handlebars/express-handlebars/compare/v5.3.5...v6.0.0) (2021-11-13)
+
+
+### Features
+
+* rewrite in typescript ([188d3c4](https://github.com/express-handlebars/express-handlebars/commit/188d3c48526499143b7e1787accd230150a200d3))
+
+
+### BREAKING CHANGES
+
+* Change minimum node version to 12
+
+## [5.3.5](https://github.com/express-handlebars/express-handlebars/compare/v5.3.4...v5.3.5) (2021-11-13)
+
+
+### Bug Fixes
+
+* update deps ([b516cff](https://github.com/express-handlebars/express-handlebars/commit/b516cff30ba3de90db02b3a3682c9ffbcfb10091))
+
+## [5.3.4](https://github.com/express-handlebars/express-handlebars/compare/v5.3.3...v5.3.4) (2021-09-23)
+
+
+### Bug Fixes
+
+* **deps:** update dependency glob to ^7.2.0 ([15c77f5](https://github.com/express-handlebars/express-handlebars/commit/15c77f5e7cf31168942adaee8d021870719d9cd8))
+
+## [5.3.3](https://github.com/express-handlebars/express-handlebars/compare/v5.3.2...v5.3.3) (2021-08-05)
+
+
+### Bug Fixes
+
+* **deps:** update dependency graceful-fs to ^4.2.7 ([94a4073](https://github.com/express-handlebars/express-handlebars/commit/94a4073bbea4591b57ea5e3cdae03c8fd861d50e))
+
+## [5.3.2](https://github.com/express-handlebars/express-handlebars/compare/v5.3.1...v5.3.2) (2021-05-06)
+
+
+### Bug Fixes
+
+* **deps:** update dependency glob to ^7.1.7 ([8222f00](https://github.com/express-handlebars/express-handlebars/commit/8222f0015805b1287f62a1c66747a7f831a976db))
+
+## [5.3.1](https://github.com/express-handlebars/express-handlebars/compare/v5.3.0...v5.3.1) (2021-05-04)
+
+
+### Bug Fixes
+
+* add note about security ([78c47a2](https://github.com/express-handlebars/express-handlebars/commit/78c47a235c4ad7bc2674bddd8ec2721567ed8c72))
+
+# [5.3.0](https://github.com/express-handlebars/express-handlebars/compare/v5.2.1...v5.3.0) (2021-03-30)
+
+
+### Features
+
+* Add partialsDir.rename option ([#151](https://github.com/express-handlebars/express-handlebars/issues/151)) ([1a6771b](https://github.com/express-handlebars/express-handlebars/commit/1a6771b0f9a3db1cbd516faf79cb5e20a779e456))
+
+## [5.2.1](https://github.com/express-handlebars/express-handlebars/compare/v5.2.0...v5.2.1) (2021-02-16)
+
+
+### Bug Fixes
+
+* **deps:** update dependency handlebars to ^4.7.7 ([1930523](https://github.com/express-handlebars/express-handlebars/commit/1930523103e6c97a3f3e41d6e7b5d6dc329c66f9))
+
+# [5.2.0](https://github.com/express-handlebars/express-handlebars/compare/v5.1.0...v5.2.0) (2020-10-23)
+
+
+### Features
+
+* allow views to be an array ([a9f4aaa](https://github.com/express-handlebars/express-handlebars/commit/a9f4aaabd657221236b7321a4f87df7c9eb9a1bd))
+
+# [5.1.0](https://github.com/express-handlebars/express-handlebars/compare/v5.0.0...v5.1.0) (2020-07-16)
+
+
+### Features
+
+* add encoding option ([9e516c3](https://github.com/express-handlebars/express-handlebars/commit/9e516c382269b3ab586a6ab0dbd586b3c23110c4))
+
+# [5.0.0](https://github.com/express-handlebars/express-handlebars/compare/v4.0.6...v5.0.0) (2020-07-06)
+
+
+### Bug Fixes
+
+* update code to es2015+ ([e5a08ee](https://github.com/express-handlebars/express-handlebars/commit/e5a08eed844f177b0f365f882a20c7b229715bdd))
+* update node support ([ea30d53](https://github.com/express-handlebars/express-handlebars/commit/ea30d531b2f458c37f65b50bddc504180e774f8f))
+
+
+### BREAKING CHANGES
+
+* Drop support for node versions below v10
+
+## [4.0.6](https://github.com/express-handlebars/express-handlebars/compare/v4.0.5...v4.0.6) (2020-07-06)
+
+
+### Bug Fixes
+
+* add runtimeOptions ([b64284f](https://github.com/express-handlebars/express-handlebars/commit/b64284f6f6eab2d184671736c33fc45df5b26246))
+
+## [4.0.5](https://github.com/express-handlebars/express-handlebars/compare/v4.0.4...v4.0.5) (2020-07-03)
+
+
+### Bug Fixes
+
+* overwrite past settings.views ([c27f1b0](https://github.com/express-handlebars/express-handlebars/commit/c27f1b0e8dcf2be974584861433cfb01a10ce1f6))
+* renderView returns promise when no callback given ([c39ed87](https://github.com/express-handlebars/express-handlebars/commit/c39ed87f2478ed64211821a6ffe1dca7212fb21b))
+
+## [4.0.4](https://github.com/express-handlebars/express-handlebars/compare/v4.0.3...v4.0.4) (2020-04-29)
+
+
+### Bug Fixes
+
+* **deps:** update dependency graceful-fs to ^4.2.4 ([c01661b](https://github.com/express-handlebars/express-handlebars/commit/c01661be5193ea77d9914b71aedcb71d6ad4ab92))
+
+## [4.0.3](https://github.com/express-handlebars/express-handlebars/compare/v4.0.2...v4.0.3) (2020-04-05)
+
+
+### Bug Fixes
+
+* **deps:** update dependency handlebars to ^4.7.6 ([2aa29ab](https://github.com/express-handlebars/express-handlebars/commit/2aa29ab29d5db9becccb5690a6fdef4a46055906))
+
+## [4.0.2](https://github.com/express-handlebars/express-handlebars/compare/v4.0.1...v4.0.2) (2020-04-03)
+
+
+### Bug Fixes
+
+* **deps:** update dependency handlebars to ^4.7.5 ([#6](https://github.com/express-handlebars/express-handlebars/issues/6)) ([e597254](https://github.com/express-handlebars/express-handlebars/commit/e59725426cd6c6ab261127fd96065f30009ea1e1))
diff --git a/app/node_modules/express-handlebars/HISTORY.md b/app/node_modules/express-handlebars/HISTORY.md
new file mode 100644
index 0000000..24a663d
--- /dev/null
+++ b/app/node_modules/express-handlebars/HISTORY.md
@@ -0,0 +1,402 @@
+Express Handlebars Change History
+=================================
+
+4.0.1 (2020-04-01)
+------------------
+
+* Update handlebars to fix mimist vulnerability.
+
+4.0.0 (2020-03-25)
+------------------
+
+* Move to repo https://github.com/express-handlebars/express-handlebars/
+* Update all deps.
+
+3.1.0 (2019-05-14)
+------------------
+
+* `defaultLayout` defaults to main ([#249][])
+* Upgrade Handlebars to v4.1.2 ([#250][])
+
+[#249]: https://github.com/ericf/express-handlebars/issues/249
+[#250]: https://github.com/ericf/express-handlebars/issues/250
+
+3.0.2 (2019-02-24)
+------------------
+
+* Fix configuration `layoutsDir` & `partialsDir`. ([#244][])
+
+[#244]: https://github.com/ericf/express-handlebars/issues/244
+
+3.0.1 (2019-02-20)
+------------------
+
+* Updated dependencies that are long over due
+
+3.0.0 (2016-01-26)
+------------------
+
+* Upgraded to Handlebars 4.0. ([#142][])
+
+[#142]: https://github.com/ericf/express-handlebars/issues/142
+
+2.0.1 (2015-04-23)
+------------------
+
+* Guarded against unexpected Handlebars API change that was released in a patch.
+ ([#125][])
+
+
+[#125]: https://github.com/ericf/express-handlebars/issues/125
+
+
+2.0.0 (2015-03-22)
+------------------
+
+* __[!]__ Upgraded to Handlebars 3.0 by default, but still works with Handlebars
+ 2.x by using the `handlebars` config option. ([#105][])
+
+* __[!]__ Removed using prototype properties for default config values. The
+ default values are now embedded in the constructor. ([#105][])
+
+* __[!]__ Removed `handlebarsVersion` instance property and
+ `getHandlebarsSemver()` static function on the `ExpressHandlebars`
+ constructor. ([#105][])
+
+* __[!]__ Replaced undocumented `compileTemplate()` hook with the protected but
+ supported `_compileTemplate()` and `_precompileTemplate()` hooks. ([#95][])
+
+* Fixed layout path resolution on Windows. ([#113][] @Tineler)
+
+* Added `compilerOptions` config property which is passed along to
+ `Handlebars.compile()` and `Handlebars.precompile()`. ([#95][])
+
+* Exposed Express Handlebars metadata to the data channel during render. This
+ metadata is accessible via `{{@exphbs.*}}` ([#89][], [#101][])
+
+* Added new "protected" hooks for AOP-ing template compilation and rendering,
+ all of which can optionally return a Promise: ([#105][])
+
+ * `_compileTemplate()`
+ * `_precompileTemplate()`
+ * `_renderTemplate()`
+
+
+[#89]: https://github.com/ericf/express-handlebars/issues/89
+[#95]: https://github.com/ericf/express-handlebars/issues/95
+[#101]: https://github.com/ericf/express-handlebars/issues/101
+[#105]: https://github.com/ericf/express-handlebars/issues/105
+[#113]: https://github.com/ericf/express-handlebars/issues/113
+
+
+1.2.2 (2015-03-06)
+------------------
+
+* Upgraded `glob` dependency to v5 which now officially supports symlinks via
+ the new `follow` option. ([#98][])
+
+
+1.2.1 (2015-02-17)
+------------------
+
+* Locked down `glob` dependency to a v4 version range that is known to work with
+ this package _and_ support symlinks. The `glob` version can be updated when
+ [isaacs/node-glob#139](https://github.com/isaacs/node-glob/issues/139) is
+ resolved. ([#98][] @adgad)
+
+
+[#98]: https://github.com/ericf/express-handlebars/issues/98
+
+
+1.2.0 (2015-02-17)
+------------------
+
+* Added support for render-level `partials` to be specified when calling
+ `renderView()` (which is the method Express calls). The `options.partials`
+ value matches what Handlebars accepts during template rendering: it should
+ have the shape `{partialName: fn}` or be a Promise for such an object.
+ ([#82][])
+
+
+[#82]: https://github.com/ericf/express-handlebars/issues/82
+
+
+1.1.0 (2014-09-14)
+------------------
+
+* __[!]__ Upgraded Handlebars to 2.0.0 final, it was beta before.
+
+* Added support for `partialsDir` to be configured with a collection (or promise
+ for a collection) of templates, via the new `templates` prop in `partialDir`
+ config objects. This allows developers to hand Express Handlebars the compiled
+ partials templates to use for a specific partials dir.
+ ([#81][] @joanniclaborde)
+
+* Upgraded Promise dependency.
+
+
+[#81]: https://github.com/ericf/express-handlebars/issues/81
+
+
+1.0.3 (2014-09-05)
+------------------
+
+* Fixed issue with namespaced partials dirs not actually being namespaces.
+ ([#76][] @inerte)
+
+
+[#76]: https://github.com/ericf/express-handlebars/issues/76
+
+
+1.0.2 (2014-09-05)
+------------------
+
+* Fixed `engines` entry in `package.json` to Node `>=0.10` to reflect this
+ package's requirements. ([#78][])
+
+
+[#78]: https://github.com/ericf/express-handlebars/issues/78
+
+
+1.0.1 (2014-08-08)
+------------------
+
+* Fixed bug where rendered content was only be returned if a layout template was
+ being used. Now a layout-less render will actually return content. ([#73][])
+
+
+[#73]: https://github.com/ericf/express-handlebars/issues/73
+
+
+1.0.0 (2014-08-07)
+------------------
+
+* __[!]__ Renamed to: `express-handlebars`. ([#65][])
+
+* __[!]__ Rewritten to use Promises instead of `async` for asynchronous code.
+ ([#68][]) This resulted in the following public API changes:
+
+ * `loadPartials()` --> `getPartials()`, returns a Promise.
+ * `loadTemplate()` --> `getTemplate()`, returns a Promise.
+ * `loadTemplates()` --> `getTemplates()`, returns a Promise.
+ * `render(file, context, [options])`, returns a Promise.
+
+
+* `partialsDir` can now be set with an array of objects in the following form to
+ support namespaced partials: ([#70][] @joanniclaborde)
+
+ { dir: 'foo/bar/', namespace: 'bar' }
+
+* Added support for Handlebars' `data` channel via `options.data`. ([#62][])
+
+* Added `compileTemplate()` hook for the pre/post compile process, this also
+ supports returning a Promise. ([#39][], [#41][])
+
+* Added `_renderTemplate()` hook that supports returning a Promise.
+ ([#39][], [#41][])
+
+* Upgraded all dependencies, including Handlebars to 2.x. ([#59][])
+
+* Added `graceful-fs` dependency to support large numbers of files to avoid
+ EMFILE errors.
+
+* Reduced complexity of cache code.
+
+* Updated examples to each be self-contained and have `package.json` files.
+
+
+[#39]: https://github.com/ericf/express-handlebars/issues/39
+[#41]: https://github.com/ericf/express-handlebars/issues/41
+[#59]: https://github.com/ericf/express-handlebars/issues/59
+[#62]: https://github.com/ericf/express-handlebars/issues/62
+[#65]: https://github.com/ericf/express-handlebars/issues/65
+[#68]: https://github.com/ericf/express-handlebars/issues/68
+[#70]: https://github.com/ericf/express-handlebars/issues/70
+
+
+0.5.1 (2014-08-05)
+------------------
+
+* __[!]__ Last release before `v1.0` which will have breaking changes.
+
+* Improved `extname` docs in README and added example. ([#30][] @Crashthatch)
+
+* `extname` can now be specified _without_ the leading `"."`.
+ ([#51][] @calvinmetcalf)
+
+
+[#30]: https://github.com/ericf/express-handlebars/issues/30
+[#51]: https://github.com/ericf/express-handlebars/issues/51
+
+
+0.5.0 (2013-07-25)
+------------------
+
+* Added `loadTemplates()` method which will load all the templates in a
+ specified directory. ([#21][])
+
+* Added support for multiple partials directories. This enables the
+ `partialsDir` configuration property to be specified as an *array* of
+ directories, and loads all of the templates in each one.
+
+ This feature allows an app's partials to be split up in multiple directories,
+ which is common if an app has some shared partials which will also be exposed
+ to the client, and some server-side-only partials. ([#20][])
+
+* Added runnable code examples in this package's "examples/" directory.
+ ([#22][])
+
+* Improved optional argument handling in public methods to treat Express
+ `locals` function objects as `options` and not `callback` params to the method
+ being invoked. ([#27][])
+
+
+[#20]: https://github.com/ericf/express-handlebars/issues/20
+[#21]: https://github.com/ericf/express-handlebars/issues/21
+[#22]: https://github.com/ericf/express-handlebars/issues/22
+[#27]: https://github.com/ericf/express-handlebars/issues/27
+
+
+0.4.1 (2013-04-06)
+------------------
+
+* Updated `async` dependency to the latest stable minor version: "~0.2".
+
+
+0.4.0 (2013-03-24)
+------------------
+
+* __[!]__ Removed the following "get" -> "load" aliases which kept in v0.2.0 for
+ back-compat:
+
+ * `getPartials()` -> `loadPartials()`
+ * `getTemplate()` -> `loadTemplate()`
+
+ This is the future version where these aliases have been removed.
+
+* __[!]__ Renamed `lib/express3-handlebars.js` -> `lib/express-handlebars.js`.
+
+* Exposed `getHandlebarsSemver()` function as a static property on the
+ `ExpressHandlebars` constructor.
+
+* Rearranged module exports by moving the engine factory function to `index.js`,
+ making the `lib/express3-handlebars.js` module only responsible for exporting
+ the `ExpressHandlebars` constructor.
+
+
+0.3.3 (2013-03-22)
+------------------
+
+* Updated internal `_resolveLayoutPath()` method to take the full
+ `options`/locals objects which the view is rendered with. This makes it easier
+ to override. ([#14][])
+
+
+[#14]: https://github.com/ericf/express-handlebars/issues/14
+
+
+0.3.2 (2013-02-20)
+------------------
+
+* Transfered ownership and copyright to Yahoo! Inc. This software is still free
+ to use, and is now licensed under the Yahoo! Inc. BSD license.
+
+
+0.3.1 (2013-02-18)
+------------------
+
+* Updated README with info about `options.helpers` for `render()` and
+ `renderView()` docs. ([#7][])
+
+
+[#7]: https://github.com/ericf/express-handlebars/issues/7
+
+
+0.3.0 (2013-02-18)
+------------------
+
+* Added support for render-level helpers, via `options.helpers`, to the
+ `render()` and `renderView()` methods. Handlebars' `registerHelper()` function
+ now works as expected and does not have to be called before the
+ `ExpressHandlebars` instance is created. Helpers are now merged from:
+ `handlebars.helpers` (global), `helpers` (instance), and `options.helpers`
+ (render-level) before a template is rendered; this provides flexibility at
+ all levels. ([#3][], [#11][])
+
+* Added `handlebarsVersion` property which is the version number of `handlebars`
+ as a semver. This is used internally to branch on certain operations which
+ differ between Handlebars releases.
+
+
+[#3]: https://github.com/ericf/express-handlebars/issues/3
+[#11]: https://github.com/ericf/express-handlebars/issues/11
+
+
+0.2.3 (2013-02-13)
+------------------
+
+* Fixed issue with naming nested partials when using the latest version of
+ Handlebars (1.0.rc.2). Previous versions require a hack to replace "/"s with
+ "."s in partial names, and the latest version of Handlebars fixes that bug.
+ This hack will only be applied to old versions of Handlebars. ([#9][])
+
+
+[#9]: https://github.com/ericf/express-handlebars/issues/9
+
+
+0.2.2 (2013-02-04)
+------------------
+
+* Updated README with the public method renames which happened v0.2.0.
+
+
+0.2.1 (2013-02-04)
+------------------
+
+* `extname`, `layoutsDir`, and `partialsDir` property values will now reference
+ the values on the prototype unless an `ExpressHandlebars` instance is
+ constructed with config values for these properties.
+
+* Improved clarity of method implementations, and exposed more override "hooks"
+ via new private methods: `_getPartialName()`, `_renderTemplate()`, and
+ `_resolveLayoutPath()`.
+
+
+0.2.0 (2013-02-01)
+------------------
+
+* __[!]__ Renamed methods prefixed with "get" to "load" for clarity:
+
+ * `getPartials()` -> `loadPartials()`
+ * `getTemplate()` -> `loadTemplate()`
+
+ Aliases for these methods have been created to maintain back-compat, but the
+ old method names are now deprecated will be removed in the future. ([#5][])
+
+* All paths are resolved before checking in or adding to caches. ([#1][])
+
+* Force `{precompiled: false}` option within `render()` and `renderView()`
+ methods to prevent trying to render with precompiled templates. ([#2][])
+
+
+[#1]: https://github.com/ericf/express-handlebars/issues/1
+[#2]: https://github.com/ericf/express-handlebars/issues/2
+[#5]: https://github.com/ericf/express-handlebars/issues/5
+
+
+0.1.2 (2013-01-10)
+------------------
+
+* Tweaked formatting of README documentation.
+
+
+0.1.1 (2013-01-10)
+------------------
+
+* Added README documentation.
+
+
+0.1.0 (2013-01-07)
+------------------
+
+* Initial release.
diff --git a/app/node_modules/express-handlebars/LICENSE b/app/node_modules/express-handlebars/LICENSE
new file mode 100644
index 0000000..58708e7
--- /dev/null
+++ b/app/node_modules/express-handlebars/LICENSE
@@ -0,0 +1,31 @@
+Copyright (c) 2014, Yahoo Inc. All rights reserved.
+
+Redistribution and use of this software in source and binary forms,
+with or without modification, are permitted provided that the following
+conditions are met:
+
+* Redistributions of source code must retain the above
+ copyright notice, this list of conditions and the
+ following disclaimer.
+
+* Redistributions in binary form must reproduce the above
+ copyright notice, this list of conditions and the
+ following disclaimer in the documentation and/or other
+ materials provided with the distribution.
+
+* Neither the name of Yahoo Inc. nor the names of its
+ contributors may be used to endorse or promote products
+ derived from this software without specific prior
+ written permission of Yahoo Inc.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
\ No newline at end of file
diff --git a/app/node_modules/express-handlebars/README.md b/app/node_modules/express-handlebars/README.md
new file mode 100644
index 0000000..2c27be7
--- /dev/null
+++ b/app/node_modules/express-handlebars/README.md
@@ -0,0 +1,611 @@
+Express Handlebars
+==================
+
+A [Handlebars][] view engine for [Express][] which doesn't suck.
+
+[![npm version][npm-badge]][npm]
+
+**This package used to be named `express3-handlebars`. The previous `express-handlebars` package by @jneen can be found [here][jneen-exphbs].**
+
+
+[Express]: https://github.com/expressjs/express
+[Handlebars]: https://github.com/handlebars-lang/handlebars.js
+[npm]: https://www.npmjs.org/package/express-handlebars
+[npm-badge]: https://img.shields.io/npm/v/express-handlebars.svg?style=flat-square
+[jneen-exphbs]: https://github.com/jneen/express-handlebars
+
+
+## Goals & Design
+
+I created this project out of frustration with the existing Handlebars view engines for Express. As of version 3.x, Express got out of the business of being a generic view engine — this was a great decision — leaving developers to implement the concepts of layouts, partials, and doing file I/O for their template engines of choice.
+
+### Goals and Features
+
+After building a half-dozen Express apps, I developed requirements and opinions about what a Handlebars view engine should provide and how it should be implemented. The following is that list:
+
+* Add back the concept of "layout", which was removed in Express 3.x.
+
+* Add back the concept of "partials" via Handlebars' partials mechanism.
+
+* Support a directory of partials; e.g., `{{> foo/bar}}` which exists on the file system at `views/partials/foo/bar.handlebars`, by default.
+
+* Smart file system I/O and template caching. When in development, templates are always loaded from disk. In production, raw files and compiled templates are cached, including partials.
+
+* All async and non-blocking. File system I/O is slow and servers should not be blocked from handling requests while reading from disk. I/O queuing is used to avoid doing unnecessary work.
+
+* Ability to easily precompile templates and partials for use on the client, enabling template sharing and reuse.
+
+* Ability to use a different Handlebars module/implementation other than the Handlebars npm package.
+
+### Package Design
+
+This package was designed to work great for both the simple and complex use cases. I _intentionally_ made sure the full implementation is exposed and is easily overridable.
+
+The package exports a function which can be invoked with no arguments or with a `config` object and it will return a function (closed over sensible defaults) which can be registered with an Express app. It's an engine factory function.
+
+This exported engine factory has two properties which expose the underlying implementation:
+
+* `ExpressHandlebars()`: The constructor function which holds the internal implementation on its `prototype`. This produces instance objects which store their configuration, `compiled` and `precompiled` templates, and expose an `engine()` function which can be registered with an Express app.
+
+* `create()`: A convenience factory function for creating `ExpressHandlebars` instances.
+
+An instance-based approach is used so that multiple `ExpressHandlebars` instances can be created with their own configuration, templates, partials, and helpers.
+
+
+## Installation
+
+Install using npm:
+
+```shell
+$ npm install express-handlebars
+```
+
+## Danger 🔥
+
+Never put objects on the `req` object straight in as the data, this can allow hackers to run XSS attacks. Always make sure you are destructuring the values on objects like `req.query` and `req.params`. See https://blog.shoebpatel.com/2021/01/23/The-Secret-Parameter-LFR-and-Potential-RCE-in-NodeJS-Apps/ for more details.
+
+## Usage
+
+This view engine uses sensible defaults that leverage the "Express-way" of structuring an app's views. This makes it trivial to use in basic apps:
+
+### Basic Usage
+
+**Directory Structure:**
+
+```
+.
+├── app.js
+└── views
+ ├── home.handlebars
+ └── layouts
+ └── main.handlebars
+
+2 directories, 3 files
+```
+
+**app.js:**
+
+Creates a super simple Express app which shows the basic way to register a Handlebars view engine using this package.
+
+```javascript
+import express from 'express';
+import { engine } from 'express-handlebars';
+
+const app = express();
+
+app.engine('handlebars', engine());
+app.set('view engine', 'handlebars');
+app.set('views', './views');
+
+app.get('/', (req, res) => {
+ res.render('home');
+});
+
+app.listen(3000);
+```
+
+**views/layouts/main.handlebars:**
+
+The main layout is the HTML page wrapper which can be reused for the different views of the app. `{{{body}}}` is used as a placeholder for where the main content should be rendered.
+
+```handlebars
+
+
+
+
+ Example App
+
+
+
+ {{{body}}}
+
+
+
+```
+
+**views/home.handlebars:**
+
+The content for the app's home view which will be rendered into the layout's `{{{body}}}`.
+
+```handlebars
+Example App: Home
+```
+
+#### Running the Example
+
+The above example is bundled in this package's [examples directory][], where it can be run by:
+
+```shell
+$ cd examples/basic/
+$ npm install
+$ npm start
+```
+
+### Using Instances
+
+Another way to use this view engine is to create an instance(s) of `ExpressHandlebars`, allowing access to the full API:
+
+```javascript
+import express from 'express';
+import { create } from 'express-handlebars';
+
+const app = express();
+const hbs = create({ /* config */ });
+
+// Register `hbs.engine` with the Express app.
+app.engine('handlebars', hbs.engine);
+app.set('view engine', 'handlebars');
+app.set('views', './views');
+
+// ...still have a reference to `hbs`, on which methods like `getPartials()`
+// can be called.
+```
+
+**Note:** The [Advanced Usage][] example demonstrates how `ExpressHandlebars` instances can be leveraged.
+
+### Template Caching
+
+This view engine uses a smart template caching strategy. In development, templates will always be loaded from disk, i.e., no caching. In production, raw files and compiled Handlebars templates are aggressively cached.
+
+The easiest way to control template/view caching is through Express' [view cache setting][]:
+
+```javascript
+app.enable('view cache');
+```
+
+Express enables this setting by default when in production mode, i.e.:
+
+```
+process.env.NODE_ENV === "production"
+```
+
+**Note:** All of the public API methods accept `options.cache`, which gives control over caching when calling these methods directly.
+
+### Layouts
+
+A layout is simply a Handlebars template with a `{{{body}}}` placeholder. Usually it will be an HTML page wrapper into which views will be rendered.
+
+This view engine adds back the concept of "layout", which was removed in Express 3.x. It can be configured with a path to the layouts directory, by default it's set to relative to `express settings.view` + `layouts/`
+
+There are two ways to set a default layout: configuring the view engine's `defaultLayout` property, or setting [Express locals][] `app.locals.layout`.
+
+The layout into which a view should be rendered can be overridden per-request by assigning a different value to the `layout` request local. The following will render the "home" view with no layout:
+
+```javascript
+app.get('/', (req, res, next) => {
+ res.render('home', {layout: false});
+});
+```
+
+### Helpers
+
+Helper functions, or "helpers" are functions that can be [registered with Handlebars][] and can be called within a template. Helpers can be used for transforming output, iterating over data, etc. To keep with the spirit of *logic-less* templates, helpers are the place where logic should be defined.
+
+Handlebars ships with some [built-in helpers][], such as: `with`, `if`, `each`, etc. Most applications will need to extend this set of helpers to include app-specific logic and transformations. Beyond defining global helpers on `Handlebars`, this view engine supports `ExpressHandlebars` instance-level helpers via the `helpers` configuration property, and render-level helpers via `options.helpers` when calling the `render()` and `renderView()` methods.
+
+The following example shows helpers being specified at each level:
+
+**app.js:**
+
+Creates a super simple Express app which shows the basic way to register `ExpressHandlebars` instance-level helpers, and override one at the render-level.
+
+```javascript
+import express from 'express';
+import { create } from 'express-handlebars';
+
+const app = express();
+
+const hbs = create({
+ // Specify helpers which are only registered on this instance.
+ helpers: {
+ foo() { return 'FOO!'; },
+ bar() { return 'BAR!'; }
+ }
+});
+
+app.engine('handlebars', hbs.engine);
+app.set('view engine', 'handlebars');
+app.set('views', './views');
+
+app.get('/', (req, res, next) => {
+ res.render('home', {
+ showTitle: true,
+
+ // Override `foo` helper only for this rendering.
+ helpers: {
+ foo() { return 'foo.'; }
+ }
+ });
+});
+
+app.listen(3000);
+```
+
+**views/home.handlebars:**
+
+The app's home view which uses helper functions to help render the contents.
+
+```handlebars
+
+
+
+
+ Example App - Home
+
+
+
+
+ {{#if showTitle}}
+ Home
+ {{/if}}
+
+
+ {{foo}}
+
+
+ {{bar}}
+
+
+
+```
+
+#### More on Helpers
+
+Refer to the [Handlebars website][] for more information on defining helpers:
+
+* [Expression Helpers][]
+* [Block Helpers][]
+
+### Metadata
+
+Handlebars has a data channel feature that propagates data through all scopes, including helpers and partials. Values in the data channel can be accessed via the `{{@variable}}` syntax. Express Handlebars provides metadata about a template it renders on a `{{@exphbs}}` object allowing access to things like the view name passed to `res.render()` via `{{@exphbs.view}}`.
+
+The following is the list of metadata that's accessible on the `{{@exphbs}}` data object:
+
+* `cache`: Boolean whether or not the template is cached.
+* `encoding`: String name of encoding for files.
+* `view`: String name of the view passed to `res.render()`.
+* `layout`: String name of the layout view.
+* `data`: Original data object passed when rendering the template.
+* `helpers`: Collection of helpers used when rendering the template.
+* `partials`: Collection of partials used when rendering the template.
+* `runtimeOptions`: Runtime Options used to render the template.
+
+
+[examples directory]: https://github.com/express-handlebars/express-handlebars/tree/master/examples
+[view cache setting]: https://expressjs.com/en/api.html#app.settings.table
+[Express locals]: https://expressjs.com/en/api.html#app.locals
+[registered with Handlebars]: https://github.com/wycats/handlebars.js/#registering-helpers
+[built-in helpers]: https://handlebarsjs.com/guide/builtin-helpers.html
+[Handlebars website]: https://handlebarsjs.com/
+[Expression Helpers]: https://handlebarsjs.com/guide/#custom-helpers
+[Block Helpers]: https://handlebarsjs.com/guide/#block-helpers
+
+
+## API
+
+### Configuration and Defaults
+
+There are two main ways to use this package: via its engine factory function, or creating `ExpressHandlebars` instances; both use the same configuration properties and defaults.
+
+```javascript
+import { engine, create, ExpressHandlebars } from 'express-handlebars';
+
+// Using the engine factory:
+engine({ /* config */ });
+
+// Create an instance:
+create({ /* config */ });
+
+// Using the class:
+new ExpressHandlebars({ /* config */})
+```
+
+The following is the list of configuration properties and their default values (if any):
+
+#### `handlebars=require('handlebars')`
+The Handlebars module/implementation. This allows for the `ExpressHandlebars` instance to use a different Handlebars module/implementation than that provided by the Handlebars npm package.
+
+#### `extname=".handlebars"`
+The string name of the file extension used by the templates. This value should correspond with the `extname` under which this view engine is registered with Express when calling `app.engine()`.
+
+The following example sets up an Express app to use `.hbs` as the file extension for views:
+
+```javascript
+import express from 'express';
+import { engine } from 'express-handlebars';
+
+const app = express();
+
+app.engine('.hbs', engine({extname: '.hbs'}));
+app.set('view engine', '.hbs');
+app.set('views', './views');
+```
+
+**Note:** Setting the app's `"view engine"` setting will make that value the default file extension used for looking up views.
+
+#### `encoding="utf8"`
+Default encoding when reading files.
+
+#### `layoutsDir`
+Default layouts directory is relative to `express settings.view` + `layouts/`
+The string path to the directory where the layout templates reside.
+
+**Note:** If you configure Express to look for views in a custom location (e.g., `app.set('views', 'some/path/')`), and if your `layoutsDir` is not relative to `express settings.view` + `layouts/`, you will need to reflect that by passing an updated path as the `layoutsDir` property in your configuration.
+
+#### `partialsDir`
+Default partials directory is relative to `express settings.view` + `partials/`
+The string path to the directory where the partials templates reside or object with the following properties:
+
+* `dir`: The string path to the directory where the partials templates reside.
+* `namespace`: Optional string namespace to prefix the partial names.
+* `templates`: Optional collection (or promise of a collection) of templates in the form: `{filename: template}`.
+* `rename(filePath, namespace)`: Optional function to rename the partials. Takes two arguments: `filePath`, e.g., `partials/some/path/template.handlebars` and `namespace`.
+
+**Note:** If you configure Express to look for views in a custom location (e.g., `app.set('views', 'some/path/')`), and if your `partialsDir` is not relative to `express settings.view` + `partials/`, you will need to reflect that by passing an updated path as the `partialsDir` property in your configuration.
+
+**Note:** Multiple partials dirs can be used by making `partialsDir` an array of strings, and/or config objects as described above. The namespacing feature is useful if multiple partials dirs are used and their file paths might clash.
+
+#### `defaultLayout`
+The string name or path of a template in the `layoutsDir` to use as the default layout. `main` is used as the default. This is overridden by a `layout` specified in the app or response `locals`. **Note:** A falsy value will render without a layout; e.g., `res.render('home', {layout: false});`. You can also use a falsy value when creating the engine to make using no layout a default e.g. `app.engine('.hbs', exphbs({defaultLayout: false}));`.
+
+#### `helpers`
+An object which holds the helper functions used when rendering templates with this `ExpressHandlebars` instance. When rendering a template, a collection of helpers will be generated by merging: `handlebars.helpers` (global), `helpers` (instance), and `options.helpers` (render-level). This allows Handlebars' `registerHelper()` function to operate as expected, will providing two extra levels over helper overrides.
+
+#### `compilerOptions`
+An object which holds options that will be passed along to the Handlebars compiler functions: `Handlebars.compile()` and `Handlebars.precompile()`.
+
+#### `runtimeOptions`
+An object which holds options that will be passed along to the template function in addition to the `data`, `helpers`, and `partials` options. See [Runtime Options][] for a list of available options.
+
+### Properties
+
+The public API properties are provided via `ExpressHandlebars` instances. In additional to the properties listed in the **Configuration and Defaults** section, the following are additional public properties:
+
+#### `engine`
+A function reference to the `renderView()` method which is bound to `this` `ExpressHandlebars` instance. This bound function should be used when registering this view engine with an Express app.
+
+#### `extname`
+The normalized `extname` which will _always_ start with `.` and defaults to `.handlebars`.
+
+#### `compiled`
+An object cache which holds compiled Handlebars template functions in the format: `{"path/to/template": [Function]}`.
+
+#### `precompiled`
+An object cache which holds precompiled Handlebars template strings in the format: `{"path/to/template": [String]}`.
+
+### Methods
+
+The following is the list of public API methods provided via `ExpressHandlebars` instances:
+
+**Note:** All of the public methods return a [`Promise`][promise] (with the exception of `renderView()` which is the interface with Express.)
+
+#### `getPartials([options])`
+Retrieves the partials in the `partialsDir` and returns a Promise for an object mapping the partials in the form `{name: partial}`.
+
+By default each partial will be a compiled Handlebars template function. Use `options.precompiled` to receive the partials as precompiled templates — this is useful for sharing templates with client code.
+
+**Parameters:**
+
+* `[options]`: Optional object containing any of the following properties:
+
+ * `[cache]`: Whether cached templates can be used if they have already been requested. This is recommended for production to avoid unnecessary file I/O.
+
+ * `[encoding]`: File encoding.
+
+ * `[precompiled=false]`: Whether precompiled templates should be provided, instead of compiled Handlebars template functions.
+
+The name of each partial corresponds to its location in `partialsDir`. For example, consider the following directory structure:
+
+```
+views
+└── partials
+ ├── foo
+ │  └── bar.handlebars
+ └── title.handlebars
+
+2 directories, 2 files
+```
+
+`getPartials()` would produce the following result:
+
+```javascript
+import { create } from 'express-handlebars';
+
+const hbs = create();
+hbs.getPartials().then(function (partials) {
+ console.log(partials);
+ // => { 'foo/bar': [Function],
+ // => title: [Function] }
+});
+```
+
+#### `getTemplate(filePath, [options])`
+Retrieves the template at the specified `filePath` and returns a Promise for the compiled Handlebars template function.
+
+Use `options.precompiled` to receive a precompiled Handlebars template.
+
+**Parameters:**
+
+* `filePath`: String path to the Handlebars template file.
+
+* `[options]`: Optional object containing any of the following properties:
+
+ * `[cache]`: Whether a cached template can be used if it have already been requested. This is recommended for production to avoid necessary file I/O.
+
+ * `[encoding]`: File encoding.
+
+ * `[precompiled=false]`: Whether a precompiled template should be provided, instead of a compiled Handlebars template function.
+
+#### `getTemplates(dirPath, [options])`
+Retrieves all the templates in the specified `dirPath` and returns a Promise for an object mapping the compiled templates in the form `{filename: template}`.
+
+Use `options.precompiled` to receive precompiled Handlebars templates — this is useful for sharing templates with client code.
+
+**Parameters:**
+
+* `dirPath`: String path to the directory containing Handlebars template files.
+
+* `[options]`: Optional object containing any of the following properties:
+
+ * `[cache]`: Whether cached templates can be used if it have already been requested. This is recommended for production to avoid necessary file I/O.
+
+ * `[encoding]`: File encoding.
+
+ * `[precompiled=false]`: Whether precompiled templates should be provided, instead of a compiled Handlebars template function.
+
+#### `resetCache([filePathsOrFilter])`
+Reset template cache. The cache can be partially reset by providing a filter argument. If no argument is given the whole cache will be reset.
+
+**Parameters:**
+
+* `[filePathsOrFilter]`: Optional filter to reset part of the cache. This can be a file path, an array of file paths, or a filter function based on file path.
+
+#### `render(filePath, context, [options])`
+Renders the template at the specified `filePath` with the `context`, using this instance's `helpers` and partials by default, and returns a Promise for the resulting string.
+
+**Parameters:**
+
+* `filePath`: String path to the Handlebars template file.
+
+* `context`: Object in which the template will be executed. This contains all of the values to fill into the template.
+
+* `[options]`: Optional object which can contain any of the following properties which affect this view engine's behavior:
+
+ * `[cache]`: Whether a cached template can be used if it have already been requested. This is recommended for production to avoid unnecessary file I/O.
+
+ * `[encoding]`: File encoding.
+
+ * `[data]`: Optional object which can contain any data that Handlebars will pipe through the template, all helpers, and all partials. This is a side data channel.
+
+ * `[helpers]`: Render-level helpers that will be used instead of any instance-level helpers; these will be merged with (and will override) any global Handlebars helper functions.
+
+ * `[partials]`: Render-level partials that will be used instead of any instance-level partials. This is used internally as an optimization to avoid re-loading all the partials.
+
+ * `[runtimeOptions]`: Optional object which can contain options passed to the template function.
+
+#### `renderView(viewPath, options|callback, [callback])`
+Renders the template at the specified `viewPath` as the `{{{body}}}` within the layout specified by the `defaultLayout` or `options.layout`. Rendering will use this instance's `helpers` and partials, and passes the resulting string to the `callback`.
+
+This method is called by Express and is the main entry point into this Express view engine implementation. It adds the concept of a "layout" and delegates rendering to the `render()` method.
+
+The `options` will be used both as the context in which the Handlebars templates are rendered, and to signal this view engine on how it should behave, e.g., `options.cache=false` will _always_ load the templates from disk.
+
+**Parameters:**
+
+* `viewPath`: String path to the Handlebars template file which should serve as the `{{{body}}}` when using a layout.
+
+* `[options]`: Optional object which will serve as the context in which the Handlebars templates are rendered. It may also contain any of the following properties which affect this view engine's behavior:
+
+ * `[cache]`: Whether cached templates can be used if they have already been requested. This is recommended for production to avoid unnecessary file I/O.
+
+ * `[encoding]`: File encoding.
+
+ * `[data]`: Optional object which can contain any data that Handlebars will pipe through the template, all helpers, and all partials. This is a side data channel.
+
+ * `[helpers]`: Render-level helpers that will be merged with (and will override) instance and global helper functions.
+
+ * `[partials]`: Render-level partials will be merged with (and will override) instance and global partials. This should be a `{partialName: fn}` hash or a Promise of an object with this shape.
+
+ * `[layout]`: Optional string path to the Handlebars template file to be used as the "layout". This overrides any `defaultLayout` value. Passing a falsy value will render with no layout (even if a `defaultLayout` is defined).
+
+ * `[runtimeOptions]`: Optional object which can contain options passed to the template function.
+
+* `callback`: Function to call once the template is retrieved.
+
+### Hooks
+
+The following is the list of protected methods that are called internally and serve as _hooks_ to override functionality of `ExpressHandlebars` instances. A value or a promise can be returned from these methods which allows them to perform async operations.
+
+#### `_compileTemplate(template, options)`
+This hook will be called when a Handlebars template needs to be compiled. This function needs to return a compiled Handlebars template function, or a promise for one.
+
+By default this hook calls `Handlebars.compile()`, but it can be overridden to preform operations before and/or after Handlebars compiles the template. This is useful if you wanted to first process Markdown within a Handlebars template.
+
+**Parameters:**
+
+* `template`: String Handlebars template that needs to be compiled.
+
+* `options`: Object `compilerOptions` that were specified when the `ExpressHandlebars` instance as created. This object should be passed along to the `Handlebars.compile()` function.
+
+#### `_precompileTemplate(template, options)`
+This hook will be called when a Handlebars template needs to be precompiled. This function needs to return a serialized Handlebars template spec. string, or a promise for one.
+
+By default this hook calls `Handlebars.precompile()`, but it can be overridden to preform operations before and/or after Handlebars precompiles the template. This is useful if you wanted to first process Markdown within a Handlebars template.
+
+**Parameters:**
+
+* `template`: String Handlebars template that needs to be precompiled.
+
+* `options`: Object `compilerOptions` that were specified when the `ExpressHandlebars` instance as created. This object should be passed along to the `Handlebars.compile()` function.
+
+#### `_renderTemplate(template, context, options)`
+This hook will be called when a compiled Handlebars template needs to be rendered. This function needs to returned the rendered output string, or a promise for one.
+
+By default this hook simply calls the passed-in `template` with the `context` and `options` arguments, but it can be overridden to perform operations before and/or after rendering the template.
+
+**Parameters:**
+
+* `template`: Compiled Handlebars template function to call.
+
+* `context`: The context object in which to render the `template`.
+
+* `options`: Object that contains options and metadata for rendering the template:
+
+ * `data`: Object to define custom `@variable` private variables.
+
+ * `helpers`: Object to provide custom helpers in addition to the globally defined helpers.
+
+ * `partials`: Object to provide custom partials in addition to the globally defined partials.
+
+ * `...runtimeOptions`: Other options specified by the `runtimeOptions` value.
+
+
+[promise]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise
+[Runtime Options]: https://handlebarsjs.com/api-reference/runtime-options.html
+
+
+## Examples
+
+### [Basic Usage][]
+
+This example shows the most basic way to use this view engine.
+
+### [Advanced Usage][]
+
+This example is more comprehensive and shows how to use many of the features of this view engine, including helpers, partials, multiple layouts, etc.
+
+As noted in the **Package Design** section, this view engine's implementation is instance-based, and more advanced usages can take advantage of this. The Advanced Usage example demonstrates how to use an `ExpressHandlebars` instance to share templates with the client, among other features.
+
+
+[Basic Usage]: https://github.com/express-handlebars/express-handlebars/tree/master/examples/basic
+[Advanced Usage]: https://github.com/express-handlebars/express-handlebars/tree/master/examples/advanced
+
+
+License
+-------
+
+This software is free to use under the Yahoo! Inc. BSD license. See the [LICENSE file][] for license text and copyright information.
+
+
+[LICENSE file]: https://github.com/express-handlebars/express-handlebars/blob/master/LICENSE
diff --git a/app/node_modules/express-handlebars/dist/express-handlebars.d.ts b/app/node_modules/express-handlebars/dist/express-handlebars.d.ts
new file mode 100644
index 0000000..cf831a9
--- /dev/null
+++ b/app/node_modules/express-handlebars/dist/express-handlebars.d.ts
@@ -0,0 +1,37 @@
+///
+///
+import type { UnknownObject, HelperDelegateObject, ConfigOptions, Engine, TemplateSpecificationObject, TemplateDelegateObject, FsCache, PartialTemplateOptions, PartialsDirObject, RenderOptions, RenderViewOptions, RenderCallback, HandlebarsImport, CompiledCache, PrecompiledCache } from "../types";
+export default class ExpressHandlebars {
+ config: ConfigOptions;
+ engine: Engine;
+ encoding: BufferEncoding;
+ layoutsDir: string;
+ extname: string;
+ compiled: CompiledCache;
+ precompiled: PrecompiledCache;
+ _fsCache: FsCache;
+ partialsDir: string | PartialsDirObject | (string | PartialsDirObject)[];
+ compilerOptions: CompileOptions;
+ runtimeOptions: RuntimeOptions;
+ helpers: HelperDelegateObject;
+ defaultLayout: string;
+ handlebars: HandlebarsImport;
+ constructor(config?: ConfigOptions);
+ getPartials(options?: PartialTemplateOptions): Promise;
+ getTemplate(filePath: string, options?: PartialTemplateOptions): Promise;
+ getTemplates(dirPath: string, options?: PartialTemplateOptions): Promise;
+ render(filePath: string, context?: UnknownObject, options?: RenderOptions): Promise;
+ renderView(viewPath: string): Promise;
+ renderView(viewPath: string, options: RenderViewOptions): Promise;
+ renderView(viewPath: string, callback: RenderCallback): Promise;
+ renderView(viewPath: string, options: RenderViewOptions, callback: RenderCallback): Promise;
+ resetCache(filePathsOrFilter?: string | string[] | ((template: string) => boolean)): void;
+ protected _compileTemplate(template: string, options?: RuntimeOptions): HandlebarsTemplateDelegate;
+ protected _precompileTemplate(template: string, options?: RuntimeOptions): TemplateSpecification;
+ protected _renderTemplate(template: HandlebarsTemplateDelegate, context?: UnknownObject, options?: RuntimeOptions): string;
+ private _getDir;
+ private _getFile;
+ private _getTemplateName;
+ private _resolveViewsPath;
+ private _resolveLayoutPath;
+}
diff --git a/app/node_modules/express-handlebars/dist/express-handlebars.js b/app/node_modules/express-handlebars/dist/express-handlebars.js
new file mode 100644
index 0000000..dfb9c54
--- /dev/null
+++ b/app/node_modules/express-handlebars/dist/express-handlebars.js
@@ -0,0 +1,337 @@
+"use strict";
+/*
+ * Copyright (c) 2015, Yahoo Inc. All rights reserved.
+ * Copyrights licensed under the New BSD License.
+ * See the accompanying LICENSE file for terms.
+ */
+var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
+ return new (P || (P = Promise))(function (resolve, reject) {
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
+ });
+};
+Object.defineProperty(exports, "__esModule", { value: true });
+const Handlebars = require("handlebars");
+const fs = require("graceful-fs");
+const path = require("node:path");
+const node_util_1 = require("node:util");
+const glob_1 = require("glob");
+const readFile = (0, node_util_1.promisify)(fs.readFile);
+// -----------------------------------------------------------------------------
+const defaultConfig = {
+ handlebars: Handlebars,
+ extname: ".handlebars",
+ encoding: "utf8",
+ layoutsDir: undefined,
+ partialsDir: undefined,
+ defaultLayout: "main",
+ helpers: undefined,
+ compilerOptions: undefined,
+ runtimeOptions: undefined,
+};
+class ExpressHandlebars {
+ constructor(config = {}) {
+ // Config properties with defaults.
+ Object.assign(this, defaultConfig, config);
+ // save given config to override other settings.
+ this.config = config;
+ // Express view engine integration point.
+ this.engine = this.renderView.bind(this);
+ // Normalize `extname`.
+ if (this.extname.charAt(0) !== ".") {
+ this.extname = "." + this.extname;
+ }
+ // Internal caches of compiled and precompiled templates.
+ this.compiled = {};
+ this.precompiled = {};
+ // Private internal file system cache.
+ this._fsCache = {};
+ }
+ getPartials(options = {}) {
+ return __awaiter(this, void 0, void 0, function* () {
+ if (typeof this.partialsDir === "undefined") {
+ return {};
+ }
+ const partialsDirs = Array.isArray(this.partialsDir) ? this.partialsDir : [this.partialsDir];
+ const dirs = yield Promise.all(partialsDirs.map((dir) => __awaiter(this, void 0, void 0, function* () {
+ let dirPath;
+ let dirTemplates;
+ let dirNamespace;
+ let dirRename;
+ // Support `partialsDir` collection with object entries that contain a
+ // templates promise and a namespace.
+ if (typeof dir === "string") {
+ dirPath = dir;
+ }
+ else if (typeof dir === "object") {
+ dirTemplates = dir.templates;
+ dirNamespace = dir.namespace;
+ dirRename = dir.rename;
+ dirPath = dir.dir;
+ }
+ // We must have some path to templates, or templates themselves.
+ if (!dirPath && !dirTemplates) {
+ throw new Error("A partials dir must be a string or config object");
+ }
+ const templates = dirTemplates || (yield this.getTemplates(dirPath, options));
+ return {
+ templates: templates,
+ namespace: dirNamespace,
+ rename: dirRename,
+ };
+ })));
+ const partials = {};
+ for (const dir of dirs) {
+ const { templates, namespace, rename } = dir;
+ const filePaths = Object.keys(templates);
+ const getTemplateNameFn = typeof rename === "function"
+ ? rename
+ : this._getTemplateName.bind(this);
+ for (const filePath of filePaths) {
+ const partialName = getTemplateNameFn(filePath, namespace);
+ partials[partialName] = templates[filePath];
+ }
+ }
+ return partials;
+ });
+ }
+ getTemplate(filePath, options = {}) {
+ return __awaiter(this, void 0, void 0, function* () {
+ filePath = path.resolve(filePath);
+ const encoding = options.encoding || this.encoding;
+ const cache = options.precompiled ? this.precompiled : this.compiled;
+ const template = options.cache && cache[filePath];
+ if (template) {
+ return template;
+ }
+ // Optimistically cache template promise to reduce file system I/O, but
+ // remove from cache if there was a problem.
+ try {
+ cache[filePath] = this._getFile(filePath, { cache: options.cache, encoding })
+ .then((file) => {
+ const compileTemplate = (options.precompiled ? this._precompileTemplate : this._compileTemplate).bind(this);
+ return compileTemplate(file, this.compilerOptions);
+ });
+ return yield cache[filePath];
+ }
+ catch (err) {
+ delete cache[filePath];
+ throw err;
+ }
+ });
+ }
+ getTemplates(dirPath, options = {}) {
+ return __awaiter(this, void 0, void 0, function* () {
+ const cache = options.cache;
+ const filePaths = yield this._getDir(dirPath, { cache });
+ const templates = yield Promise.all(filePaths.map(filePath => {
+ return this.getTemplate(path.join(dirPath, filePath), options);
+ }));
+ const hash = {};
+ for (let i = 0; i < filePaths.length; i++) {
+ hash[filePaths[i]] = templates[i];
+ }
+ return hash;
+ });
+ }
+ render(filePath, context = {}, options = {}) {
+ return __awaiter(this, void 0, void 0, function* () {
+ const encoding = options.encoding || this.encoding;
+ const [template, partials] = yield Promise.all([
+ this.getTemplate(filePath, { cache: options.cache, encoding }),
+ (options.partials || this.getPartials({ cache: options.cache, encoding })),
+ ]);
+ const helpers = Object.assign(Object.assign({}, this.helpers), options.helpers);
+ const runtimeOptions = Object.assign(Object.assign({}, this.runtimeOptions), options.runtimeOptions);
+ // Add ExpressHandlebars metadata to the data channel so that it's
+ // accessible within the templates and helpers, namespaced under:
+ // `@exphbs.*`
+ const data = Object.assign(Object.assign({}, options.data), { exphbs: Object.assign(Object.assign({}, options), { filePath,
+ helpers,
+ partials,
+ runtimeOptions }) });
+ const html = this._renderTemplate(template, context, Object.assign(Object.assign({}, runtimeOptions), { data,
+ helpers,
+ partials }));
+ return html;
+ });
+ }
+ renderView(viewPath, options = {}, callback = null) {
+ return __awaiter(this, void 0, void 0, function* () {
+ if (typeof options === "function") {
+ callback = options;
+ options = {};
+ }
+ const context = options;
+ let promise = null;
+ if (!callback) {
+ promise = new Promise((resolve, reject) => {
+ callback = (err, value) => { err !== null ? reject(err) : resolve(value); };
+ });
+ }
+ // Express provides `settings.views` which is the path to the views dir that
+ // the developer set on the Express app. When this value exists, it's used
+ // to compute the view's name. Layouts and Partials directories are relative
+ // to `settings.view` path
+ let view;
+ const views = options.settings && options.settings.views;
+ const viewsPath = this._resolveViewsPath(views, viewPath);
+ if (viewsPath) {
+ view = this._getTemplateName(path.relative(viewsPath, viewPath));
+ this.partialsDir = this.config.partialsDir || path.join(viewsPath, "partials/");
+ this.layoutsDir = this.config.layoutsDir || path.join(viewsPath, "layouts/");
+ }
+ const encoding = options.encoding || this.encoding;
+ // Merge render-level and instance-level helpers together.
+ const helpers = Object.assign(Object.assign({}, this.helpers), options.helpers);
+ // Merge render-level and instance-level partials together.
+ const partials = Object.assign(Object.assign({}, yield this.getPartials({ cache: options.cache, encoding })), (options.partials || {}));
+ // Pluck-out ExpressHandlebars-specific options and Handlebars-specific
+ // rendering options.
+ const renderOptions = {
+ cache: options.cache,
+ encoding,
+ view,
+ layout: "layout" in options ? options.layout : this.defaultLayout,
+ data: options.data,
+ helpers,
+ partials,
+ runtimeOptions: options.runtimeOptions,
+ };
+ try {
+ let html = yield this.render(viewPath, context, renderOptions);
+ const layoutPath = this._resolveLayoutPath(renderOptions.layout);
+ if (layoutPath) {
+ html = yield this.render(layoutPath, Object.assign(Object.assign({}, context), { body: html }), Object.assign(Object.assign({}, renderOptions), { layout: undefined }));
+ }
+ callback(null, html);
+ }
+ catch (err) {
+ callback(err);
+ }
+ return promise;
+ });
+ }
+ resetCache(filePathsOrFilter) {
+ let filePaths = [];
+ if (typeof filePathsOrFilter === "undefined") {
+ filePaths = Object.keys(this._fsCache);
+ }
+ else if (typeof filePathsOrFilter === "string") {
+ filePaths = [filePathsOrFilter];
+ }
+ else if (typeof filePathsOrFilter === "function") {
+ filePaths = Object.keys(this._fsCache).filter(filePathsOrFilter);
+ }
+ else if (Array.isArray(filePathsOrFilter)) {
+ filePaths = filePathsOrFilter;
+ }
+ for (const filePath of filePaths) {
+ delete this._fsCache[filePath];
+ }
+ }
+ // -- Protected Hooks ----------------------------------------------------------
+ _compileTemplate(template, options = {}) {
+ return this.handlebars.compile(template.trim(), options);
+ }
+ _precompileTemplate(template, options = {}) {
+ return this.handlebars.precompile(template.trim(), options);
+ }
+ _renderTemplate(template, context = {}, options = {}) {
+ return template(context, options).trim();
+ }
+ // -- Private ------------------------------------------------------------------
+ _getDir(dirPath, options = {}) {
+ return __awaiter(this, void 0, void 0, function* () {
+ dirPath = path.resolve(dirPath);
+ const cache = this._fsCache;
+ let dir = options.cache && cache[dirPath];
+ if (dir) {
+ return [...yield dir];
+ }
+ const pattern = "**/*" + this.extname;
+ // Optimistically cache dir promise to reduce file system I/O, but remove
+ // from cache if there was a problem.
+ try {
+ dir = cache[dirPath] = (0, glob_1.glob)(pattern, {
+ cwd: dirPath,
+ follow: true,
+ posix: true,
+ });
+ // @ts-expect-error FIXME: not sure how to throw error in glob for test coverage
+ if (options._throwTestError) {
+ throw new Error("test");
+ }
+ return [...yield dir];
+ }
+ catch (err) {
+ delete cache[dirPath];
+ throw err;
+ }
+ });
+ }
+ _getFile(filePath, options = {}) {
+ return __awaiter(this, void 0, void 0, function* () {
+ filePath = path.resolve(filePath);
+ const cache = this._fsCache;
+ const encoding = options.encoding || this.encoding;
+ const file = options.cache && cache[filePath];
+ if (file) {
+ return file;
+ }
+ // Optimistically cache file promise to reduce file system I/O, but remove
+ // from cache if there was a problem.
+ try {
+ cache[filePath] = readFile(filePath, { encoding: encoding || "utf8" });
+ return yield cache[filePath];
+ }
+ catch (err) {
+ delete cache[filePath];
+ throw err;
+ }
+ });
+ }
+ _getTemplateName(filePath, namespace = null) {
+ let name = filePath;
+ if (name.endsWith(this.extname)) {
+ name = name.substring(0, name.length - this.extname.length);
+ }
+ if (namespace) {
+ name = namespace + "/" + name;
+ }
+ return name;
+ }
+ _resolveViewsPath(views, file) {
+ if (!Array.isArray(views)) {
+ return views;
+ }
+ let lastDir = path.resolve(file);
+ let dir = path.dirname(lastDir);
+ const absoluteViews = views.map(v => path.resolve(v));
+ // find the closest parent
+ while (dir !== lastDir) {
+ const index = absoluteViews.indexOf(dir);
+ if (index >= 0) {
+ return views[index];
+ }
+ lastDir = dir;
+ dir = path.dirname(lastDir);
+ }
+ // cannot resolve view
+ return null;
+ }
+ _resolveLayoutPath(layoutPath) {
+ if (!layoutPath) {
+ return null;
+ }
+ if (!path.extname(layoutPath)) {
+ layoutPath += this.extname;
+ }
+ return path.resolve(this.layoutsDir || "", layoutPath);
+ }
+}
+exports.default = ExpressHandlebars;
+//# sourceMappingURL=express-handlebars.js.map
\ No newline at end of file
diff --git a/app/node_modules/express-handlebars/dist/express-handlebars.js.map b/app/node_modules/express-handlebars/dist/express-handlebars.js.map
new file mode 100644
index 0000000..82b8bdc
--- /dev/null
+++ b/app/node_modules/express-handlebars/dist/express-handlebars.js.map
@@ -0,0 +1 @@
+{"version":3,"file":"express-handlebars.js","sourceRoot":"","sources":["../lib/express-handlebars.ts"],"names":[],"mappings":";AAAA;;;;GAIG;;;;;;;;;;;AAEH,yCAAyC;AACzC,kCAAkC;AAClC,kCAAkC;AAClC,yCAAsC;AACtC,+BAA4B;AAoB5B,MAAM,QAAQ,GAAG,IAAA,qBAAS,EAAC,EAAE,CAAC,QAAQ,CAAC,CAAC;AAExC,gFAAgF;AAEhF,MAAM,aAAa,GAAkB;IACpC,UAAU,EAAE,UAAU;IACtB,OAAO,EAAE,aAAa;IACtB,QAAQ,EAAE,MAAM;IAChB,UAAU,EAAE,SAAS;IACrB,WAAW,EAAE,SAAS;IACtB,aAAa,EAAE,MAAM;IACrB,OAAO,EAAE,SAAS;IAClB,eAAe,EAAE,SAAS;IAC1B,cAAc,EAAE,SAAS;CACzB,CAAC;AAEF,MAAqB,iBAAiB;IAgBrC,YAAa,SAAwB,EAAE;QACtC,mCAAmC;QACnC,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,aAAa,EAAE,MAAM,CAAC,CAAC;QAE3C,gDAAgD;QAChD,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;QAErB,yCAAyC;QACzC,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAEzC,uBAAuB;QACvB,IAAI,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,GAAG,EAAE;YACnC,IAAI,CAAC,OAAO,GAAG,GAAG,GAAG,IAAI,CAAC,OAAO,CAAC;SAClC;QAED,yDAAyD;QACzD,IAAI,CAAC,QAAQ,GAAG,EAAE,CAAC;QACnB,IAAI,CAAC,WAAW,GAAG,EAAE,CAAC;QAEtB,sCAAsC;QACtC,IAAI,CAAC,QAAQ,GAAG,EAAE,CAAC;IACpB,CAAC;IAEK,WAAW,CAAE,UAAkC,EAAE;;YACtD,IAAI,OAAO,IAAI,CAAC,WAAW,KAAK,WAAW,EAAE;gBAC5C,OAAO,EAAE,CAAC;aACV;YACD,MAAM,YAAY,GAAG,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;YAE7F,MAAM,IAAI,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC,YAAY,CAAC,GAAG,CAAC,CAAM,GAAG,EAAC,EAAE;gBAC3D,IAAI,OAAe,CAAC;gBACpB,IAAI,YAAoC,CAAC;gBACzC,IAAI,YAAoB,CAAC;gBACzB,IAAI,SAAyB,CAAC;gBAE9B,sEAAsE;gBACtE,qCAAqC;gBACrC,IAAI,OAAO,GAAG,KAAK,QAAQ,EAAE;oBAC5B,OAAO,GAAG,GAAG,CAAC;iBACd;qBAAM,IAAI,OAAO,GAAG,KAAK,QAAQ,EAAE;oBACnC,YAAY,GAAG,GAAG,CAAC,SAAS,CAAC;oBAC7B,YAAY,GAAG,GAAG,CAAC,SAAS,CAAC;oBAC7B,SAAS,GAAG,GAAG,CAAC,MAAM,CAAC;oBACvB,OAAO,GAAG,GAAG,CAAC,GAAG,CAAC;iBAClB;gBAED,gEAAgE;gBAChE,IAAI,CAAC,OAAO,IAAI,CAAC,YAAY,EAAE;oBAC9B,MAAM,IAAI,KAAK,CAAC,kDAAkD,CAAC,CAAC;iBACpE;gBAED,MAAM,SAAS,GAAqD,YAAY,KAAI,MAAM,IAAI,CAAC,YAAY,CAAC,OAAO,EAAE,OAAO,CAAC,CAAA,CAAC;gBAE9H,OAAO;oBACN,SAAS,EAAE,SAA6D;oBACxE,SAAS,EAAE,YAAY;oBACvB,MAAM,EAAE,SAAS;iBACjB,CAAC;YACH,CAAC,CAAA,CAAC,CAAC,CAAC;YAEJ,MAAM,QAAQ,GAAuD,EAAE,CAAC;YAExE,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE;gBACvB,MAAM,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,EAAE,GAAG,GAAG,CAAC;gBAC7C,MAAM,SAAS,GAAG,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;gBAEzC,MAAM,iBAAiB,GAAG,OAAO,MAAM,KAAK,UAAU;oBACrD,CAAC,CAAC,MAAM;oBACR,CAAC,CAAC,IAAI,CAAC,gBAAgB,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;gBAEpC,KAAK,MAAM,QAAQ,IAAI,SAAS,EAAE;oBACjC,MAAM,WAAW,GAAG,iBAAiB,CAAC,QAAQ,EAAE,SAAS,CAAC,CAAC;oBAC3D,QAAQ,CAAC,WAAW,CAAC,GAAG,SAAS,CAAC,QAAQ,CAAC,CAAC;iBAC5C;aACD;YAED,OAAO,QAAQ,CAAC;QACjB,CAAC;KAAA;IAEK,WAAW,CAAE,QAAgB,EAAE,UAAkC,EAAE;;YACxE,QAAQ,GAAG,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;YAElC,MAAM,QAAQ,GAAG,OAAO,CAAC,QAAQ,IAAI,IAAI,CAAC,QAAQ,CAAC;YACnD,MAAM,KAAK,GAAmC,OAAO,CAAC,WAAW,CAAC,CAAC,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC;YACrG,MAAM,QAAQ,GAA8D,OAAO,CAAC,KAAK,IAAI,KAAK,CAAC,QAAQ,CAAC,CAAC;YAE7G,IAAI,QAAQ,EAAE;gBACb,OAAO,QAAQ,CAAC;aAChB;YAED,uEAAuE;YACvE,4CAA4C;YAC5C,IAAI;gBACH,KAAK,CAAC,QAAQ,CAAC,GAAG,IAAI,CAAC,QAAQ,CAAC,QAAQ,EAAE,EAAE,KAAK,EAAE,OAAO,CAAC,KAAK,EAAE,QAAQ,EAAE,CAAC;qBAC3E,IAAI,CAAC,CAAC,IAAY,EAAE,EAAE;oBACtB,MAAM,eAAe,GAAgG,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC,CAAC,IAAI,CAAC,mBAAmB,CAAC,CAAC,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;oBACzM,OAAO,eAAe,CAAC,IAAI,EAAE,IAAI,CAAC,eAAe,CAAC,CAAC;gBACpD,CAAC,CAAC,CAAC;gBACJ,OAAO,MAAM,KAAK,CAAC,QAAQ,CAAC,CAAC;aAC7B;YAAC,OAAO,GAAG,EAAE;gBACb,OAAO,KAAK,CAAC,QAAQ,CAAC,CAAC;gBACvB,MAAM,GAAG,CAAC;aACV;QACF,CAAC;KAAA;IAEK,YAAY,CAAE,OAAe,EAAE,UAAkC,EAAE;;YACxE,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC;YAE5B,MAAM,SAAS,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE,EAAE,KAAK,EAAE,CAAC,CAAC;YACzD,MAAM,SAAS,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC,SAAS,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE;gBAC5D,OAAO,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,QAAQ,CAAC,EAAE,OAAO,CAAC,CAAC;YAChE,CAAC,CAAC,CAAC,CAAC;YAEJ,MAAM,IAAI,GAAG,EAAE,CAAC;YAChB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,SAAS,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;gBAC1C,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,GAAG,SAAS,CAAC,CAAC,CAAC,CAAC;aAClC;YACD,OAAO,IAAI,CAAC;QACb,CAAC;KAAA;IAEK,MAAM,CAAE,QAAgB,EAAE,UAAyB,EAAE,EAAE,UAAyB,EAAE;;YACvF,MAAM,QAAQ,GAAG,OAAO,CAAC,QAAQ,IAAI,IAAI,CAAC,QAAQ,CAAC;YACnD,MAAM,CAAC,QAAQ,EAAE,QAAQ,CAAC,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC;gBAC9C,IAAI,CAAC,WAAW,CAAC,QAAQ,EAAE,EAAE,KAAK,EAAE,OAAO,CAAC,KAAK,EAAE,QAAQ,EAAE,CAAwC;gBACrG,CAAC,OAAO,CAAC,QAAQ,IAAI,IAAI,CAAC,WAAW,CAAC,EAAE,KAAK,EAAE,OAAO,CAAC,KAAK,EAAE,QAAQ,EAAE,CAAC,CAAoC;aAC7G,CAAC,CAAC;YACH,MAAM,OAAO,mCAA8B,IAAI,CAAC,OAAO,GAAK,OAAO,CAAC,OAAO,CAAE,CAAC;YAC9E,MAAM,cAAc,mCAAQ,IAAI,CAAC,cAAc,GAAK,OAAO,CAAC,cAAc,CAAE,CAAC;YAE7E,kEAAkE;YAClE,iEAAiE;YACjE,cAAc;YACd,MAAM,IAAI,mCACN,OAAO,CAAC,IAAI,KACf,MAAM,kCACF,OAAO,KACV,QAAQ;oBACR,OAAO;oBACP,QAAQ;oBACR,cAAc,MAEf,CAAC;YAEF,MAAM,IAAI,GAAG,IAAI,CAAC,eAAe,CAAC,QAAQ,EAAE,OAAO,kCAC/C,cAAc,KACjB,IAAI;gBACJ,OAAO;gBACP,QAAQ,IACP,CAAC;YAEH,OAAO,IAAI,CAAC;QACb,CAAC;KAAA;IAMK,UAAU,CAAE,QAAgB,EAAE,UAA4C,EAAE,EAAE,WAAgC,IAAI;;YACvH,IAAI,OAAO,OAAO,KAAK,UAAU,EAAE;gBAClC,QAAQ,GAAG,OAAO,CAAC;gBACnB,OAAO,GAAG,EAAE,CAAC;aACb;YAED,MAAM,OAAO,GAAG,OAAwB,CAAC;YAEzC,IAAI,OAAO,GAAyB,IAAI,CAAC;YACzC,IAAI,CAAC,QAAQ,EAAE;gBACd,OAAO,GAAG,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;oBACzC,QAAQ,GAAG,CAAC,GAAG,EAAE,KAAK,EAAE,EAAE,GAAG,GAAG,KAAK,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;gBAC7E,CAAC,CAAC,CAAC;aACH;YAED,4EAA4E;YAC5E,0EAA0E;YAC1E,4EAA4E;YAC5E,0BAA0B;YAC1B,IAAI,IAAY,CAAC;YACjB,MAAM,KAAK,GAAG,OAAO,CAAC,QAAQ,IAAI,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAC;YACzD,MAAM,SAAS,GAAG,IAAI,CAAC,iBAAiB,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAC;YAC1D,IAAI,SAAS,EAAE;gBACd,IAAI,GAAG,IAAI,CAAC,gBAAgB,CAAC,IAAI,CAAC,QAAQ,CAAC,SAAS,EAAE,QAAQ,CAAC,CAAC,CAAC;gBACjE,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC,MAAM,CAAC,WAAW,IAAI,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,WAAW,CAAC,CAAC;gBAChF,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC,MAAM,CAAC,UAAU,IAAI,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,UAAU,CAAC,CAAC;aAC7E;YAED,MAAM,QAAQ,GAAG,OAAO,CAAC,QAAQ,IAAI,IAAI,CAAC,QAAQ,CAAC;YAEnD,0DAA0D;YAC1D,MAAM,OAAO,mCAAQ,IAAI,CAAC,OAAO,GAAK,OAAO,CAAC,OAAO,CAAE,CAAC;YAExD,2DAA2D;YAC3D,MAAM,QAAQ,mCACV,MAAM,IAAI,CAAC,WAAW,CAAC,EAAE,KAAK,EAAE,OAAO,CAAC,KAAK,EAAE,QAAQ,EAAE,CAA2B,GACpF,CAAC,OAAO,CAAC,QAAQ,IAAI,EAAE,CAAC,CAC3B,CAAC;YAEF,uEAAuE;YACvE,qBAAqB;YACrB,MAAM,aAAa,GAAG;gBACrB,KAAK,EAAE,OAAO,CAAC,KAAK;gBACpB,QAAQ;gBACR,IAAI;gBACJ,MAAM,EAAE,QAAQ,IAAI,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,aAAa;gBACjE,IAAI,EAAE,OAAO,CAAC,IAAI;gBAClB,OAAO;gBACP,QAAQ;gBACR,cAAc,EAAE,OAAO,CAAC,cAAc;aACtC,CAAC;YAEF,IAAI;gBACH,IAAI,IAAI,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,QAAQ,EAAE,OAAO,EAAE,aAAa,CAAC,CAAC;gBAC/D,MAAM,UAAU,GAAG,IAAI,CAAC,kBAAkB,CAAC,aAAa,CAAC,MAAM,CAAC,CAAC;gBAEjE,IAAI,UAAU,EAAE;oBACf,IAAI,GAAG,MAAM,IAAI,CAAC,MAAM,CACvB,UAAU,kCACL,OAAO,KAAE,IAAI,EAAE,IAAI,qCACnB,aAAa,KAAE,MAAM,EAAE,SAAS,IACrC,CAAC;iBACF;gBACD,QAAQ,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;aACrB;YAAC,OAAO,GAAG,EAAE;gBACb,QAAQ,CAAC,GAAG,CAAC,CAAC;aACd;YAED,OAAO,OAAO,CAAC;QAChB,CAAC;KAAA;IAED,UAAU,CAAE,iBAAuE;QAClF,IAAI,SAAS,GAAa,EAAE,CAAC;QAE7B,IAAI,OAAO,iBAAiB,KAAK,WAAW,EAAE;YAC7C,SAAS,GAAG,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;SACvC;aAAM,IAAI,OAAO,iBAAiB,KAAK,QAAQ,EAAE;YACjD,SAAS,GAAG,CAAC,iBAAiB,CAAC,CAAC;SAChC;aAAM,IAAI,OAAO,iBAAiB,KAAK,UAAU,EAAE;YACnD,SAAS,GAAG,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,iBAAiB,CAAC,CAAC;SACjE;aAAM,IAAI,KAAK,CAAC,OAAO,CAAC,iBAAiB,CAAC,EAAE;YAC5C,SAAS,GAAG,iBAAiB,CAAC;SAC9B;QAED,KAAK,MAAM,QAAQ,IAAI,SAAS,EAAE;YACjC,OAAO,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;SAC/B;IACF,CAAC;IAED,gFAAgF;IAEtE,gBAAgB,CAAE,QAAgB,EAAE,UAA0B,EAAE;QACzE,OAAO,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,QAAQ,CAAC,IAAI,EAAE,EAAE,OAAO,CAAC,CAAC;IAC1D,CAAC;IAES,mBAAmB,CAAE,QAAgB,EAAE,UAA0B,EAAE;QAC5E,OAAO,IAAI,CAAC,UAAU,CAAC,UAAU,CAAC,QAAQ,CAAC,IAAI,EAAE,EAAE,OAAO,CAAC,CAAC;IAC7D,CAAC;IAES,eAAe,CAAE,QAAoC,EAAE,UAAyB,EAAE,EAAE,UAA0B,EAAE;QACzH,OAAO,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC,IAAI,EAAE,CAAC;IAC1C,CAAC;IAED,gFAAgF;IAElE,OAAO,CAAE,OAAe,EAAE,UAAkC,EAAE;;YAC3E,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;YAEhC,MAAM,KAAK,GAAG,IAAI,CAAC,QAAQ,CAAC;YAC5B,IAAI,GAAG,GAAG,OAAO,CAAC,KAAK,IAAK,KAAK,CAAC,OAAO,CAAuB,CAAC;YAEjE,IAAI,GAAG,EAAE;gBACR,OAAO,CAAC,GAAG,MAAM,GAAG,CAAC,CAAC;aACtB;YAED,MAAM,OAAO,GAAG,MAAM,GAAG,IAAI,CAAC,OAAO,CAAC;YAEtC,yEAAyE;YACzE,qCAAqC;YAErC,IAAI;gBACH,GAAG,GAAG,KAAK,CAAC,OAAO,CAAC,GAAG,IAAA,WAAI,EAAC,OAAO,EAAE;oBACpC,GAAG,EAAE,OAAO;oBACZ,MAAM,EAAE,IAAI;oBACZ,KAAK,EAAE,IAAI;iBACX,CAAC,CAAC;gBACH,gFAAgF;gBAChF,IAAI,OAAO,CAAC,eAAe,EAAE;oBAC5B,MAAM,IAAI,KAAK,CAAC,MAAM,CAAC,CAAC;iBACxB;gBAED,OAAO,CAAC,GAAG,MAAM,GAAG,CAAC,CAAC;aACtB;YAAC,OAAO,GAAG,EAAE;gBACb,OAAO,KAAK,CAAC,OAAO,CAAC,CAAC;gBACtB,MAAM,GAAG,CAAC;aACV;QACF,CAAC;KAAA;IAEa,QAAQ,CAAE,QAAgB,EAAE,UAAkC,EAAE;;YAC7E,QAAQ,GAAG,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;YAElC,MAAM,KAAK,GAAG,IAAI,CAAC,QAAQ,CAAC;YAC5B,MAAM,QAAQ,GAAG,OAAO,CAAC,QAAQ,IAAI,IAAI,CAAC,QAAQ,CAAC;YACnD,MAAM,IAAI,GAAG,OAAO,CAAC,KAAK,IAAK,KAAK,CAAC,QAAQ,CAAqB,CAAC;YAEnE,IAAI,IAAI,EAAE;gBACT,OAAO,IAAI,CAAC;aACZ;YAED,0EAA0E;YAC1E,qCAAqC;YACrC,IAAI;gBACH,KAAK,CAAC,QAAQ,CAAC,GAAG,QAAQ,CAAC,QAAQ,EAAE,EAAE,QAAQ,EAAE,QAAQ,IAAI,MAAM,EAAE,CAAC,CAAC;gBACvE,OAAO,MAAM,KAAK,CAAC,QAAQ,CAAW,CAAC;aACvC;YAAC,OAAO,GAAG,EAAE;gBACb,OAAO,KAAK,CAAC,QAAQ,CAAC,CAAC;gBACvB,MAAM,GAAG,CAAC;aACV;QACF,CAAC;KAAA;IAEO,gBAAgB,CAAE,QAAgB,EAAE,YAAoB,IAAI;QACnE,IAAI,IAAI,GAAG,QAAQ,CAAC;QAEpB,IAAI,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE;YAChC,IAAI,GAAG,IAAI,CAAC,SAAS,CAAC,CAAC,EAAE,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;SAC5D;QAED,IAAI,SAAS,EAAE;YACd,IAAI,GAAG,SAAS,GAAG,GAAG,GAAG,IAAI,CAAC;SAC9B;QAED,OAAO,IAAI,CAAC;IACb,CAAC;IAEO,iBAAiB,CAAE,KAAsB,EAAE,IAAY;QAC9D,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE;YAC1B,OAAO,KAAK,CAAC;SACb;QAED,IAAI,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;QACjC,IAAI,GAAG,GAAG,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;QAChC,MAAM,aAAa,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC;QAEtD,0BAA0B;QAC1B,OAAO,GAAG,KAAK,OAAO,EAAE;YACvB,MAAM,KAAK,GAAG,aAAa,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;YACzC,IAAI,KAAK,IAAI,CAAC,EAAE;gBACf,OAAO,KAAK,CAAC,KAAK,CAAC,CAAC;aACpB;YACD,OAAO,GAAG,GAAG,CAAC;YACd,GAAG,GAAG,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;SAC5B;QAED,sBAAsB;QACtB,OAAO,IAAI,CAAC;IACb,CAAC;IAEO,kBAAkB,CAAE,UAAkB;QAC7C,IAAI,CAAC,UAAU,EAAE;YAChB,OAAO,IAAI,CAAC;SACZ;QAED,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,EAAE;YAC9B,UAAU,IAAI,IAAI,CAAC,OAAO,CAAC;SAC3B;QAED,OAAO,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,UAAU,IAAI,EAAE,EAAE,UAAU,CAAC,CAAC;IACxD,CAAC;CACD;AA7XD,oCA6XC"}
\ No newline at end of file
diff --git a/app/node_modules/express-handlebars/dist/index.d.ts b/app/node_modules/express-handlebars/dist/index.d.ts
new file mode 100644
index 0000000..6466f3a
--- /dev/null
+++ b/app/node_modules/express-handlebars/dist/index.d.ts
@@ -0,0 +1,5 @@
+import ExpressHandlebars from "./express-handlebars";
+import type { ConfigOptions, Engine } from "../types";
+export { ExpressHandlebars };
+export declare function create(config?: ConfigOptions): ExpressHandlebars;
+export declare function engine(config?: ConfigOptions): Engine;
diff --git a/app/node_modules/express-handlebars/dist/index.js b/app/node_modules/express-handlebars/dist/index.js
new file mode 100644
index 0000000..cc0bd6e
--- /dev/null
+++ b/app/node_modules/express-handlebars/dist/index.js
@@ -0,0 +1,19 @@
+"use strict";
+/*
+ * Copyright (c) 2014, Yahoo Inc. All rights reserved.
+ * Copyrights licensed under the New BSD License.
+ * See the accompanying LICENSE file for terms.
+ */
+Object.defineProperty(exports, "__esModule", { value: true });
+exports.engine = exports.create = exports.ExpressHandlebars = void 0;
+const express_handlebars_1 = require("./express-handlebars");
+exports.ExpressHandlebars = express_handlebars_1.default;
+function create(config = {}) {
+ return new express_handlebars_1.default(config);
+}
+exports.create = create;
+function engine(config = {}) {
+ return create(config).engine;
+}
+exports.engine = engine;
+//# sourceMappingURL=index.js.map
\ No newline at end of file
diff --git a/app/node_modules/express-handlebars/dist/index.js.map b/app/node_modules/express-handlebars/dist/index.js.map
new file mode 100644
index 0000000..fae7619
--- /dev/null
+++ b/app/node_modules/express-handlebars/dist/index.js.map
@@ -0,0 +1 @@
+{"version":3,"file":"index.js","sourceRoot":"","sources":["../lib/index.ts"],"names":[],"mappings":";AAAA;;;;GAIG;;;AAEH,6DAAqD;AAM5C,4BANF,4BAAiB,CAME;AAE1B,SAAgB,MAAM,CAAE,SAAwB,EAAE;IACjD,OAAO,IAAI,4BAAiB,CAAC,MAAM,CAAC,CAAC;AACtC,CAAC;AAFD,wBAEC;AAED,SAAgB,MAAM,CAAE,SAAwB,EAAE;IACjD,OAAO,MAAM,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC;AAC9B,CAAC;AAFD,wBAEC"}
\ No newline at end of file
diff --git a/app/node_modules/express-handlebars/jest.config.js b/app/node_modules/express-handlebars/jest.config.js
new file mode 100644
index 0000000..f70e68f
--- /dev/null
+++ b/app/node_modules/express-handlebars/jest.config.js
@@ -0,0 +1,27 @@
+module.exports = {
+ preset: "ts-jest",
+ testEnvironment: "node",
+ restoreMocks: true,
+ clearMocks: true,
+ collectCoverageFrom: [
+ "lib/**/*.ts",
+ ],
+ coverageDirectory: "coverage",
+ coverageThreshold: {
+ global: {
+ branches: 100,
+ functions: 100,
+ lines: 100,
+ statements: 100,
+ },
+ },
+ testRegex: /\.test\.tsx?/.source,
+ transform: {
+ [/\.test\.tsx?/.source]: [
+ "ts-jest", {
+ diagnostics: false,
+ },
+ ],
+ },
+ moduleFileExtensions: ["js", "json", "jsx", "d.ts", "ts", "tsx", "node"],
+};
diff --git a/app/node_modules/express-handlebars/lib/express-handlebars.ts b/app/node_modules/express-handlebars/lib/express-handlebars.ts
new file mode 100644
index 0000000..0aa9467
--- /dev/null
+++ b/app/node_modules/express-handlebars/lib/express-handlebars.ts
@@ -0,0 +1,428 @@
+/*
+ * Copyright (c) 2015, Yahoo Inc. All rights reserved.
+ * Copyrights licensed under the New BSD License.
+ * See the accompanying LICENSE file for terms.
+ */
+
+import * as Handlebars from "handlebars";
+import * as fs from "graceful-fs";
+import * as path from "node:path";
+import { promisify } from "node:util";
+import { glob } from "glob";
+import type {
+ UnknownObject,
+ HelperDelegateObject,
+ ConfigOptions,
+ Engine,
+ TemplateSpecificationObject,
+ TemplateDelegateObject,
+ FsCache,
+ PartialTemplateOptions,
+ PartialsDirObject,
+ RenderOptions,
+ RenderViewOptions,
+ RenderCallback,
+ HandlebarsImport,
+ CompiledCache,
+ PrecompiledCache,
+ RenameFunction,
+} from "../types";
+
+const readFile = promisify(fs.readFile);
+
+// -----------------------------------------------------------------------------
+
+const defaultConfig: ConfigOptions = {
+ handlebars: Handlebars,
+ extname: ".handlebars",
+ encoding: "utf8",
+ layoutsDir: undefined, // Default layouts directory is relative to `express settings.view` + `layouts/`
+ partialsDir: undefined, // Default partials directory is relative to `express settings.view` + `partials/`
+ defaultLayout: "main",
+ helpers: undefined,
+ compilerOptions: undefined,
+ runtimeOptions: undefined,
+};
+
+export default class ExpressHandlebars {
+ config: ConfigOptions;
+ engine: Engine;
+ encoding: BufferEncoding;
+ layoutsDir: string;
+ extname: string;
+ compiled: CompiledCache;
+ precompiled: PrecompiledCache;
+ _fsCache: FsCache;
+ partialsDir: string|PartialsDirObject|(string|PartialsDirObject)[];
+ compilerOptions: CompileOptions;
+ runtimeOptions: RuntimeOptions;
+ helpers: HelperDelegateObject;
+ defaultLayout: string;
+ handlebars: HandlebarsImport;
+
+ constructor (config: ConfigOptions = {}) {
+ // Config properties with defaults.
+ Object.assign(this, defaultConfig, config);
+
+ // save given config to override other settings.
+ this.config = config;
+
+ // Express view engine integration point.
+ this.engine = this.renderView.bind(this);
+
+ // Normalize `extname`.
+ if (this.extname.charAt(0) !== ".") {
+ this.extname = "." + this.extname;
+ }
+
+ // Internal caches of compiled and precompiled templates.
+ this.compiled = {};
+ this.precompiled = {};
+
+ // Private internal file system cache.
+ this._fsCache = {};
+ }
+
+ async getPartials (options: PartialTemplateOptions = {}): Promise {
+ if (typeof this.partialsDir === "undefined") {
+ return {};
+ }
+ const partialsDirs = Array.isArray(this.partialsDir) ? this.partialsDir : [this.partialsDir];
+
+ const dirs = await Promise.all(partialsDirs.map(async dir => {
+ let dirPath: string;
+ let dirTemplates: TemplateDelegateObject;
+ let dirNamespace: string;
+ let dirRename: RenameFunction;
+
+ // Support `partialsDir` collection with object entries that contain a
+ // templates promise and a namespace.
+ if (typeof dir === "string") {
+ dirPath = dir;
+ } else if (typeof dir === "object") {
+ dirTemplates = dir.templates;
+ dirNamespace = dir.namespace;
+ dirRename = dir.rename;
+ dirPath = dir.dir;
+ }
+
+ // We must have some path to templates, or templates themselves.
+ if (!dirPath && !dirTemplates) {
+ throw new Error("A partials dir must be a string or config object");
+ }
+
+ const templates: HandlebarsTemplateDelegate|TemplateSpecification = dirTemplates || await this.getTemplates(dirPath, options);
+
+ return {
+ templates: templates as HandlebarsTemplateDelegate|TemplateSpecification,
+ namespace: dirNamespace,
+ rename: dirRename,
+ };
+ }));
+
+ const partials: TemplateDelegateObject|TemplateSpecificationObject = {};
+
+ for (const dir of dirs) {
+ const { templates, namespace, rename } = dir;
+ const filePaths = Object.keys(templates);
+
+ const getTemplateNameFn = typeof rename === "function"
+ ? rename
+ : this._getTemplateName.bind(this);
+
+ for (const filePath of filePaths) {
+ const partialName = getTemplateNameFn(filePath, namespace);
+ partials[partialName] = templates[filePath];
+ }
+ }
+
+ return partials;
+ }
+
+ async getTemplate (filePath: string, options: PartialTemplateOptions = {}): Promise {
+ filePath = path.resolve(filePath);
+
+ const encoding = options.encoding || this.encoding;
+ const cache: PrecompiledCache|CompiledCache = options.precompiled ? this.precompiled : this.compiled;
+ const template: Promise = options.cache && cache[filePath];
+
+ if (template) {
+ return template;
+ }
+
+ // Optimistically cache template promise to reduce file system I/O, but
+ // remove from cache if there was a problem.
+ try {
+ cache[filePath] = this._getFile(filePath, { cache: options.cache, encoding })
+ .then((file: string) => {
+ const compileTemplate: (file: string, options: RuntimeOptions) => TemplateSpecification|HandlebarsTemplateDelegate = (options.precompiled ? this._precompileTemplate : this._compileTemplate).bind(this);
+ return compileTemplate(file, this.compilerOptions);
+ });
+ return await cache[filePath];
+ } catch (err) {
+ delete cache[filePath];
+ throw err;
+ }
+ }
+
+ async getTemplates (dirPath: string, options: PartialTemplateOptions = {}): Promise {
+ const cache = options.cache;
+
+ const filePaths = await this._getDir(dirPath, { cache });
+ const templates = await Promise.all(filePaths.map(filePath => {
+ return this.getTemplate(path.join(dirPath, filePath), options);
+ }));
+
+ const hash = {};
+ for (let i = 0; i < filePaths.length; i++) {
+ hash[filePaths[i]] = templates[i];
+ }
+ return hash;
+ }
+
+ async render (filePath: string, context: UnknownObject = {}, options: RenderOptions = {}): Promise {
+ const encoding = options.encoding || this.encoding;
+ const [template, partials] = await Promise.all([
+ this.getTemplate(filePath, { cache: options.cache, encoding }) as Promise,
+ (options.partials || this.getPartials({ cache: options.cache, encoding })) as Promise,
+ ]);
+ const helpers: HelperDelegateObject = { ...this.helpers, ...options.helpers };
+ const runtimeOptions = { ...this.runtimeOptions, ...options.runtimeOptions };
+
+ // Add ExpressHandlebars metadata to the data channel so that it's
+ // accessible within the templates and helpers, namespaced under:
+ // `@exphbs.*`
+ const data = {
+ ...options.data,
+ exphbs: {
+ ...options,
+ filePath,
+ helpers,
+ partials,
+ runtimeOptions,
+ },
+ };
+
+ const html = this._renderTemplate(template, context, {
+ ...runtimeOptions,
+ data,
+ helpers,
+ partials,
+ });
+
+ return html;
+ }
+
+ async renderView (viewPath: string): Promise;
+ async renderView (viewPath: string, options: RenderViewOptions): Promise;
+ async renderView (viewPath: string, callback: RenderCallback): Promise;
+ async renderView (viewPath: string, options: RenderViewOptions, callback: RenderCallback): Promise;
+ async renderView (viewPath: string, options: RenderViewOptions|RenderCallback = {}, callback: RenderCallback|null = null): Promise {
+ if (typeof options === "function") {
+ callback = options;
+ options = {};
+ }
+
+ const context = options as UnknownObject;
+
+ let promise: Promise|null = null;
+ if (!callback) {
+ promise = new Promise((resolve, reject) => {
+ callback = (err, value) => { err !== null ? reject(err) : resolve(value); };
+ });
+ }
+
+ // Express provides `settings.views` which is the path to the views dir that
+ // the developer set on the Express app. When this value exists, it's used
+ // to compute the view's name. Layouts and Partials directories are relative
+ // to `settings.view` path
+ let view: string;
+ const views = options.settings && options.settings.views;
+ const viewsPath = this._resolveViewsPath(views, viewPath);
+ if (viewsPath) {
+ view = this._getTemplateName(path.relative(viewsPath, viewPath));
+ this.partialsDir = this.config.partialsDir || path.join(viewsPath, "partials/");
+ this.layoutsDir = this.config.layoutsDir || path.join(viewsPath, "layouts/");
+ }
+
+ const encoding = options.encoding || this.encoding;
+
+ // Merge render-level and instance-level helpers together.
+ const helpers = { ...this.helpers, ...options.helpers };
+
+ // Merge render-level and instance-level partials together.
+ const partials: TemplateDelegateObject = {
+ ...await this.getPartials({ cache: options.cache, encoding }) as TemplateDelegateObject,
+ ...(options.partials || {}),
+ };
+
+ // Pluck-out ExpressHandlebars-specific options and Handlebars-specific
+ // rendering options.
+ const renderOptions = {
+ cache: options.cache,
+ encoding,
+ view,
+ layout: "layout" in options ? options.layout : this.defaultLayout,
+ data: options.data,
+ helpers,
+ partials,
+ runtimeOptions: options.runtimeOptions,
+ };
+
+ try {
+ let html = await this.render(viewPath, context, renderOptions);
+ const layoutPath = this._resolveLayoutPath(renderOptions.layout);
+
+ if (layoutPath) {
+ html = await this.render(
+ layoutPath,
+ { ...context, body: html },
+ { ...renderOptions, layout: undefined },
+ );
+ }
+ callback(null, html);
+ } catch (err) {
+ callback(err);
+ }
+
+ return promise;
+ }
+
+ resetCache (filePathsOrFilter?: string | string[] | ((template: string) => boolean)) {
+ let filePaths: string[] = [];
+
+ if (typeof filePathsOrFilter === "undefined") {
+ filePaths = Object.keys(this._fsCache);
+ } else if (typeof filePathsOrFilter === "string") {
+ filePaths = [filePathsOrFilter];
+ } else if (typeof filePathsOrFilter === "function") {
+ filePaths = Object.keys(this._fsCache).filter(filePathsOrFilter);
+ } else if (Array.isArray(filePathsOrFilter)) {
+ filePaths = filePathsOrFilter;
+ }
+
+ for (const filePath of filePaths) {
+ delete this._fsCache[filePath];
+ }
+ }
+
+ // -- Protected Hooks ----------------------------------------------------------
+
+ protected _compileTemplate (template: string, options: RuntimeOptions = {}): HandlebarsTemplateDelegate {
+ return this.handlebars.compile(template.trim(), options);
+ }
+
+ protected _precompileTemplate (template: string, options: RuntimeOptions = {}): TemplateSpecification {
+ return this.handlebars.precompile(template.trim(), options);
+ }
+
+ protected _renderTemplate (template: HandlebarsTemplateDelegate, context: UnknownObject = {}, options: RuntimeOptions = {}): string {
+ return template(context, options).trim();
+ }
+
+ // -- Private ------------------------------------------------------------------
+
+ private async _getDir (dirPath: string, options: PartialTemplateOptions = {}): Promise {
+ dirPath = path.resolve(dirPath);
+
+ const cache = this._fsCache;
+ let dir = options.cache && (cache[dirPath] as Promise);
+
+ if (dir) {
+ return [...await dir];
+ }
+
+ const pattern = "**/*" + this.extname;
+
+ // Optimistically cache dir promise to reduce file system I/O, but remove
+ // from cache if there was a problem.
+
+ try {
+ dir = cache[dirPath] = glob(pattern, {
+ cwd: dirPath,
+ follow: true,
+ posix: true,
+ });
+ // @ts-expect-error FIXME: not sure how to throw error in glob for test coverage
+ if (options._throwTestError) {
+ throw new Error("test");
+ }
+
+ return [...await dir];
+ } catch (err) {
+ delete cache[dirPath];
+ throw err;
+ }
+ }
+
+ private async _getFile (filePath: string, options: PartialTemplateOptions = {}): Promise {
+ filePath = path.resolve(filePath);
+
+ const cache = this._fsCache;
+ const encoding = options.encoding || this.encoding;
+ const file = options.cache && (cache[filePath] as Promise);
+
+ if (file) {
+ return file;
+ }
+
+ // Optimistically cache file promise to reduce file system I/O, but remove
+ // from cache if there was a problem.
+ try {
+ cache[filePath] = readFile(filePath, { encoding: encoding || "utf8" });
+ return await cache[filePath] as string;
+ } catch (err) {
+ delete cache[filePath];
+ throw err;
+ }
+ }
+
+ private _getTemplateName (filePath: string, namespace: string = null): string {
+ let name = filePath;
+
+ if (name.endsWith(this.extname)) {
+ name = name.substring(0, name.length - this.extname.length);
+ }
+
+ if (namespace) {
+ name = namespace + "/" + name;
+ }
+
+ return name;
+ }
+
+ private _resolveViewsPath (views: string|string[], file: string): string|null {
+ if (!Array.isArray(views)) {
+ return views;
+ }
+
+ let lastDir = path.resolve(file);
+ let dir = path.dirname(lastDir);
+ const absoluteViews = views.map(v => path.resolve(v));
+
+ // find the closest parent
+ while (dir !== lastDir) {
+ const index = absoluteViews.indexOf(dir);
+ if (index >= 0) {
+ return views[index];
+ }
+ lastDir = dir;
+ dir = path.dirname(lastDir);
+ }
+
+ // cannot resolve view
+ return null;
+ }
+
+ private _resolveLayoutPath (layoutPath: string): string|null {
+ if (!layoutPath) {
+ return null;
+ }
+
+ if (!path.extname(layoutPath)) {
+ layoutPath += this.extname;
+ }
+
+ return path.resolve(this.layoutsDir || "", layoutPath);
+ }
+}
diff --git a/app/node_modules/express-handlebars/lib/index.ts b/app/node_modules/express-handlebars/lib/index.ts
new file mode 100644
index 0000000..10726b2
--- /dev/null
+++ b/app/node_modules/express-handlebars/lib/index.ts
@@ -0,0 +1,21 @@
+/*
+ * Copyright (c) 2014, Yahoo Inc. All rights reserved.
+ * Copyrights licensed under the New BSD License.
+ * See the accompanying LICENSE file for terms.
+ */
+
+import ExpressHandlebars from "./express-handlebars";
+import type {
+ ConfigOptions,
+ Engine,
+} from "../types";
+
+export { ExpressHandlebars };
+
+export function create (config: ConfigOptions = {}): ExpressHandlebars {
+ return new ExpressHandlebars(config);
+}
+
+export function engine (config: ConfigOptions = {}): Engine {
+ return create(config).engine;
+}
diff --git a/app/node_modules/express-handlebars/package.json b/app/node_modules/express-handlebars/package.json
new file mode 100644
index 0000000..9fa61ca
--- /dev/null
+++ b/app/node_modules/express-handlebars/package.json
@@ -0,0 +1,74 @@
+{
+ "name": "express-handlebars",
+ "description": "A Handlebars view engine for Express which doesn't suck.",
+ "version": "7.1.2",
+ "homepage": "https://github.com/express-handlebars/express-handlebars",
+ "keywords": [
+ "express",
+ "express3",
+ "handlebars",
+ "view",
+ "layout",
+ "partials",
+ "templates"
+ ],
+ "author": "Eric Ferraiuolo (http://ericf.me/)",
+ "repository": {
+ "type": "git",
+ "url": "git://github.com/express-handlebars/express-handlebars.git"
+ },
+ "bugs": {
+ "url": "https://github.com/express-handlebars/express-handlebars/issues"
+ },
+ "engines": {
+ "node": ">=v16"
+ },
+ "dependencies": {
+ "glob": "^10.3.3",
+ "graceful-fs": "^4.2.11",
+ "handlebars": "^4.7.8"
+ },
+ "main": "dist/index.js",
+ "directories": {
+ "example": "examples"
+ },
+ "devDependencies": {
+ "@semantic-release/changelog": "^6.0.3",
+ "@semantic-release/commit-analyzer": "^10.0.1",
+ "@semantic-release/git": "^10.0.1",
+ "@semantic-release/github": "^9.0.4",
+ "@semantic-release/npm": "^10.0.4",
+ "@semantic-release/release-notes-generator": "^11.0.4",
+ "@types/glob": "^8.1.0",
+ "@types/jest": "^29.5.3",
+ "@types/node": "^18.17.3",
+ "@typescript-eslint/eslint-plugin": "^6.3.0",
+ "@typescript-eslint/parser": "^6.3.0",
+ "eslint": "^8.46.0",
+ "eslint-config-standard": "^17.1.0",
+ "eslint-plugin-import": "^2.28.0",
+ "eslint-plugin-n": "^16.0.1",
+ "eslint-plugin-promise": "^6.1.1",
+ "jest-cli": "^29.6.2",
+ "semantic-release": "^21.0.7",
+ "ts-jest": "^29.1.1",
+ "typescript": "^5.1.6"
+ },
+ "release": {
+ "plugins": [
+ "@semantic-release/commit-analyzer",
+ "@semantic-release/release-notes-generator",
+ "@semantic-release/changelog",
+ "@semantic-release/npm",
+ "@semantic-release/github",
+ "@semantic-release/git"
+ ]
+ },
+ "scripts": {
+ "test": "jest --verbose",
+ "test:cover": "jest --coverage",
+ "lint": "eslint .",
+ "build": "tsc"
+ },
+ "license": "BSD-3-Clause"
+}
diff --git a/app/node_modules/express-handlebars/renovate.json b/app/node_modules/express-handlebars/renovate.json
new file mode 100644
index 0000000..cefdcbc
--- /dev/null
+++ b/app/node_modules/express-handlebars/renovate.json
@@ -0,0 +1,10 @@
+{
+ "extends": [
+ "config:base"
+ ],
+ "devDependencies": {
+ "automerge": true,
+ "commitMessageTopic": "devDependency {{depName}}"
+ },
+ "rangeStrategy": "bump"
+}
diff --git a/app/node_modules/express-handlebars/spec/express-handlebars.test.ts b/app/node_modules/express-handlebars/spec/express-handlebars.test.ts
new file mode 100644
index 0000000..8fa4813
--- /dev/null
+++ b/app/node_modules/express-handlebars/spec/express-handlebars.test.ts
@@ -0,0 +1,880 @@
+import * as path from "node:path";
+import * as expressHandlebars from "../lib/index";
+import type {
+ TemplateDelegateObject,
+ EngineOptions,
+} from "../types";
+
+function fixturePath (filePath = "") {
+ return path.resolve(__dirname, "./fixtures", filePath);
+}
+
+// allow access to private functions for testing
+// https://github.com/microsoft/TypeScript/issues/19335
+/* eslint-disable dot-notation, @typescript-eslint/no-empty-function */
+
+describe("express-handlebars", () => {
+ test("ExpressHandlebars instance", () => {
+ const exphbs = new expressHandlebars.ExpressHandlebars();
+ expect(exphbs).toBeDefined();
+ });
+
+ test("should nomalize extname", () => {
+ const exphbs1 = expressHandlebars.create({ extname: "ext" });
+ const exphbs2 = expressHandlebars.create({ extname: ".ext" });
+ expect(exphbs1.extname).toBe(".ext");
+ expect(exphbs2.extname).toBe(".ext");
+ });
+
+ describe("getPartials", () => {
+ test("should throw if partialsDir is not correct type", async () => {
+ // @ts-expect-error partialsDir is invalid
+ const exphbs = expressHandlebars.create({ partialsDir: 1 });
+ let error: Error | undefined;
+ try {
+ await exphbs.getPartials();
+ } catch (e) {
+ error = e;
+ }
+ expect(error).toEqual(expect.any(Error));
+ expect(error?.message).toBe("A partials dir must be a string or config object");
+ });
+
+ test("should return empty object if no partialsDir is defined", async () => {
+ const exphbs = expressHandlebars.create();
+ const partials = await exphbs.getPartials();
+ expect(partials).toEqual({});
+ });
+
+ test("should return empty object partialsDir does not exist", async () => {
+ const exphbs = expressHandlebars.create({ partialsDir: "does-not-exist" });
+ const partials = await exphbs.getPartials();
+ expect(partials).toEqual({});
+ });
+
+ test("should return partials on string", async () => {
+ const exphbs = expressHandlebars.create({ partialsDir: fixturePath("partials") });
+ const partials = await exphbs.getPartials();
+ expect(partials).toEqual({
+ partial: expect.any(Function),
+ "partial-latin1": expect.any(Function),
+ "subdir/partial-subdir": expect.any(Function),
+ });
+ });
+
+ test("should return partials on array", async () => {
+ const exphbs = expressHandlebars.create({ partialsDir: [fixturePath("partials")] });
+ const partials = await exphbs.getPartials();
+ expect(partials).toEqual({
+ partial: expect.any(Function),
+ "partial-latin1": expect.any(Function),
+ "subdir/partial-subdir": expect.any(Function),
+ });
+ });
+
+ test("should return partials on object", async () => {
+ const fn = jest.fn();
+ const exphbs = expressHandlebars.create({
+ partialsDir: {
+ templates: { "partial template": fn },
+ namespace: "partial namespace",
+ dir: fixturePath("partials"),
+ },
+ });
+ const partials = await exphbs.getPartials();
+ expect(partials).toEqual({
+ "partial namespace/partial template": fn,
+ });
+ });
+
+ test("should return renamed partials with rename function", async () => {
+ const fn = jest.fn();
+ const exphbs = expressHandlebars.create({
+ partialsDir: {
+ templates: { "partial/template": fn },
+ namespace: "partial namespace",
+ dir: fixturePath("partials"),
+ rename: (filePath, namespace) => {
+ return `${namespace}/${filePath.split("/")[0]}`;
+ },
+ },
+ });
+ const partials = await exphbs.getPartials();
+ expect(partials).toEqual({
+ "partial namespace/partial": fn,
+ });
+ });
+
+ test("should return partials on path relative to cwd", async () => {
+ const exphbs = expressHandlebars.create({ partialsDir: "spec/fixtures/partials" });
+ const partials = await exphbs.getPartials();
+ expect(partials).toEqual({
+ partial: expect.any(Function),
+ "partial-latin1": expect.any(Function),
+ "subdir/partial-subdir": expect.any(Function),
+ });
+ });
+
+ test("should return template function", async () => {
+ const exphbs = expressHandlebars.create({ partialsDir: "spec/fixtures/partials" });
+ const partials = await exphbs.getPartials() as TemplateDelegateObject;
+ const html = partials.partial({ text: "test text" });
+ expect(html).toBe("partial test text");
+ });
+
+ test("should return a template with encoding", async () => {
+ const exphbs = expressHandlebars.create({ partialsDir: "spec/fixtures/partials" });
+ const partials = await exphbs.getPartials({ encoding: "latin1" }) as TemplateDelegateObject;
+ const html = partials["partial-latin1"]({});
+ expect(html).toContain("ñáéÃóú");
+ });
+
+ test("should return a template with default encoding", async () => {
+ const exphbs = expressHandlebars.create({
+ encoding: "latin1",
+ partialsDir: "spec/fixtures/partials",
+ });
+ const partials = await exphbs.getPartials() as TemplateDelegateObject;
+ const html = partials["partial-latin1"]({});
+ expect(html).toContain("ñáéÃóú");
+ });
+ });
+
+ describe("getTemplate", () => {
+ test("should return cached template", async () => {
+ const exphbs = expressHandlebars.create();
+ const filePath = fixturePath("templates/template.handlebars");
+ const compiledCachedFunction = (() => "compiled") as Handlebars.TemplateDelegate;
+ exphbs.compiled[filePath] = Promise.resolve(compiledCachedFunction);
+ const precompiledCachedFunction = (() => "precompiled") as TemplateSpecification;
+ exphbs.precompiled[filePath] = Promise.resolve(precompiledCachedFunction);
+ const template = await exphbs.getTemplate(filePath, { cache: true });
+ expect(template).toBe(compiledCachedFunction);
+ });
+
+ test("should return precompiled cached template", async () => {
+ const exphbs = expressHandlebars.create();
+ const filePath = fixturePath("templates/template.handlebars");
+ const compiledCachedFunction = (() => "compiled") as Handlebars.TemplateDelegate;
+ exphbs.compiled[filePath] = Promise.resolve(compiledCachedFunction);
+ const precompiledCachedFunction = (() => "precompiled") as TemplateSpecification;
+ exphbs.precompiled[filePath] = Promise.resolve(precompiledCachedFunction);
+ const template = await exphbs.getTemplate(filePath, { precompiled: true, cache: true });
+ expect(template).toBe(precompiledCachedFunction);
+ });
+
+ test("should store in precompiled cache", async () => {
+ const exphbs = expressHandlebars.create();
+ const filePath = fixturePath("templates/template.handlebars");
+ expect(exphbs.compiled[filePath]).toBeUndefined();
+ expect(exphbs.precompiled[filePath]).toBeUndefined();
+ await exphbs.getTemplate(filePath, { precompiled: true });
+ expect(exphbs.compiled[filePath]).toBeUndefined();
+ expect(exphbs.precompiled[filePath]).toBeDefined();
+ });
+
+ test("should store in compiled cache", async () => {
+ const exphbs = expressHandlebars.create();
+ const filePath = fixturePath("templates/template.handlebars");
+ expect(exphbs.compiled[filePath]).toBeUndefined();
+ expect(exphbs.precompiled[filePath]).toBeUndefined();
+ await exphbs.getTemplate(filePath);
+ expect(exphbs.compiled[filePath]).toBeDefined();
+ expect(exphbs.precompiled[filePath]).toBeUndefined();
+ });
+
+ test("should return a template", async () => {
+ const exphbs = expressHandlebars.create();
+ const filePath = fixturePath("templates/template.handlebars");
+ const template = await exphbs.getTemplate(filePath) as HandlebarsTemplateDelegate;
+ const html = template({ text: "test text" });
+ expect(html).toBe("test text
");
+ });
+
+ test("should return a template with encoding", async () => {
+ const exphbs = expressHandlebars.create();
+ const filePath = fixturePath("templates/template-latin1.handlebars");
+ const template = await exphbs.getTemplate(filePath, { encoding: "latin1" }) as HandlebarsTemplateDelegate;
+ const html = template({});
+ expect(html).toContain("ñáéÃóú");
+ });
+
+ test("should return a template with default encoding", async () => {
+ const exphbs = expressHandlebars.create({ encoding: "latin1" });
+ const filePath = fixturePath("templates/template-latin1.handlebars");
+ const template = await exphbs.getTemplate(filePath) as HandlebarsTemplateDelegate;
+ const html = template({});
+ expect(html).toContain("ñáéÃóú");
+ });
+
+ test("should not store in cache on error", async () => {
+ const exphbs = expressHandlebars.create();
+ const filePath = "does-not-exist";
+ expect(exphbs.compiled[filePath]).toBeUndefined();
+ let error: Error | undefined;
+ try {
+ await exphbs.getTemplate(filePath);
+ } catch (e) {
+ error = e;
+ }
+ expect(error?.message).toEqual(expect.stringContaining("no such file or directory"));
+ expect(exphbs.compiled[filePath]).toBeUndefined();
+ });
+ });
+
+ describe("getTemplates", () => {
+ test("should return cached templates", async () => {
+ const exphbs = expressHandlebars.create();
+ const dirPath = fixturePath("templates");
+ const fsCache = Promise.resolve([]);
+ exphbs._fsCache[dirPath] = fsCache;
+ const templates = await exphbs.getTemplates(dirPath, { cache: true });
+ expect(templates).toEqual({});
+ });
+
+ test("should return templates", async () => {
+ const exphbs = expressHandlebars.create();
+ const dirPath = fixturePath("templates");
+ const templates = await exphbs.getTemplates(dirPath);
+ const html = templates["template.handlebars"]({ text: "test text" });
+ expect(html).toBe("test text
");
+ });
+
+ test("should get templates in sub directories", async () => {
+ const exphbs = expressHandlebars.create();
+ const dirPath = fixturePath("templates");
+ const templates = await exphbs.getTemplates(dirPath);
+ const paths = Object.keys(templates);
+ expect(paths).toEqual([
+ "template.handlebars",
+ "template-latin1.handlebars",
+ "subdir/template.handlebars",
+ ]);
+ });
+ });
+
+ describe("render", () => {
+ test("should return cached templates", async () => {
+ const exphbs = expressHandlebars.create();
+ const filePath = fixturePath("render-cached.handlebars");
+ exphbs.compiled[filePath] = Promise.resolve(() => "cached");
+ const html = await exphbs.render(filePath, undefined, { cache: true });
+ expect(html).toBe("cached");
+ });
+
+ test("should use helpers", async () => {
+ const exphbs = expressHandlebars.create({
+ helpers: {
+ help: () => "help",
+ },
+ });
+ const filePath = fixturePath("render-helper.handlebars");
+ const html = await exphbs.render(filePath, { text: "test text" });
+ expect(html).toBe("help
");
+ });
+
+ test("should override helpers", async () => {
+ const exphbs = expressHandlebars.create({
+ helpers: {
+ help: () => "help",
+ },
+ });
+ const filePath = fixturePath("render-helper.handlebars");
+ const html = await exphbs.render(filePath, { text: "test text" }, {
+ helpers: {
+ help: (text: string) => text,
+ },
+ });
+ expect(html).toBe("test text
");
+ });
+
+ test("should return html", async () => {
+ const exphbs = expressHandlebars.create();
+ const filePath = fixturePath("render-text.handlebars");
+ const html = await exphbs.render(filePath, { text: "test text" });
+ expect(html).toBe("test text
");
+ });
+
+ test("should return html with encoding", async () => {
+ const exphbs = expressHandlebars.create({
+ partialsDir: fixturePath("partials"),
+ });
+ const filePath = fixturePath("render-latin1.handlebars");
+ const html = await exphbs.render(filePath, undefined, { encoding: "latin1" });
+ expect(html).toContain("partial ñáéÃóú");
+ expect(html).toContain("render ñáéÃóú");
+ });
+
+ test("should return html with default encoding", async () => {
+ const exphbs = expressHandlebars.create({
+ encoding: "latin1",
+ partialsDir: fixturePath("partials"),
+ });
+ const filePath = fixturePath("render-latin1.handlebars");
+ const html = await exphbs.render(filePath);
+ expect(html).toContain("partial ñáéÃóú");
+ expect(html).toContain("render ñáéÃóú");
+ });
+
+ test("should render with partial", async () => {
+ const exphbs = expressHandlebars.create({
+ partialsDir: fixturePath("partials"),
+ });
+ const filePath = fixturePath("render-partial.handlebars");
+ const html = await exphbs.render(filePath, { text: "test text" });
+ expect(html.replace(/\r/g, "")).toBe("partial test text
\ntest text
");
+ });
+
+ test("should render with subdir/partial", async () => {
+ const exphbs = expressHandlebars.create({
+ partialsDir: fixturePath("partials"),
+ });
+ const filePath = fixturePath("render-subdir-partial.handlebars");
+ const html = await exphbs.render(filePath, { text: "test text" });
+ expect(html.replace(/\r/g, "")).toBe("subdir partial test text
\ntest text
");
+ });
+
+ test("should render with runtimeOptions", async () => {
+ const exphbs = expressHandlebars.create({
+ runtimeOptions: { allowProtoPropertiesByDefault: true },
+ });
+ const filePath = fixturePath("test");
+ const spy = jest.fn(() => { return "test"; }) as Handlebars.TemplateDelegate;
+ exphbs.compiled[filePath] = Promise.resolve(spy);
+ await exphbs.render(filePath, undefined, { cache: true });
+ expect(spy).toHaveBeenCalledWith(expect.any(Object), expect.objectContaining({ allowProtoPropertiesByDefault: true }));
+ });
+
+ test("should override runtimeOptions", async () => {
+ const exphbs = expressHandlebars.create({
+ runtimeOptions: { allowProtoPropertiesByDefault: true },
+ });
+ const filePath = fixturePath("test");
+ const spy = jest.fn(() => { return "test"; }) as Handlebars.TemplateDelegate;
+ exphbs.compiled[filePath] = Promise.resolve(spy);
+ await exphbs.render(filePath, undefined, {
+ cache: true,
+ runtimeOptions: { allowProtoPropertiesByDefault: false },
+ });
+ expect(spy).toHaveBeenCalledWith(expect.any(Object), expect.objectContaining({ allowProtoPropertiesByDefault: false }));
+ });
+ });
+
+ describe("engine", () => {
+ test("should call renderView", async () => {
+ jest.spyOn(expressHandlebars.ExpressHandlebars.prototype, "renderView").mockImplementation(() => Promise.resolve(null));
+ const exphbs = expressHandlebars.create();
+ const cb = () => { /* empty */ };
+ exphbs.engine("view", {}, cb);
+ expect(expressHandlebars.ExpressHandlebars.prototype.renderView).toHaveBeenCalledWith("view", {}, cb);
+ });
+
+ test("should call engine", async () => {
+ jest.spyOn(expressHandlebars.ExpressHandlebars.prototype, "renderView").mockImplementation(() => Promise.resolve(null));
+ const cb = () => { /* empty */ };
+ expressHandlebars.engine()("view", {}, cb);
+ expect(expressHandlebars.ExpressHandlebars.prototype.renderView).toHaveBeenCalledWith("view", {}, cb);
+ });
+
+ test("should render html", async () => {
+ const renderView = expressHandlebars.engine({ defaultLayout: undefined });
+ const viewPath = fixturePath("render-text.handlebars");
+ const html = await renderView(viewPath, { text: "test text" } as EngineOptions);
+ expect(html).toBe("test text
");
+ });
+ });
+
+ describe("renderView", () => {
+ test("should use settings.views", async () => {
+ const exphbs = expressHandlebars.create();
+ const viewPath = fixturePath("render-partial.handlebars");
+ const viewsPath = fixturePath();
+ const html = await exphbs.renderView(viewPath, {
+ text: "test text",
+ settings: { views: viewsPath },
+ });
+ expect(html.replace(/\r/g, "")).toBe("\npartial test text
\ntest text
\n");
+ });
+
+ test("should use settings.views array", async () => {
+ const exphbs = expressHandlebars.create();
+ const viewPath = fixturePath("render-partial.handlebars");
+ const viewsPath = fixturePath();
+ const html = await exphbs.renderView(viewPath, {
+ text: "test text",
+ settings: { views: [viewsPath] },
+ });
+ expect(html.replace(/\r/g, "")).toBe("\npartial test text
\ntest text
\n");
+ });
+
+ test("should not use settings.views array when no parent found", async () => {
+ const exphbs = expressHandlebars.create({ defaultLayout: undefined });
+ const viewPath = fixturePath("render-text.handlebars");
+ const viewsPath = "does-not-exist";
+ const html = await exphbs.renderView(viewPath, {
+ text: "test text",
+ settings: { views: [viewsPath] },
+ });
+ expect(html).toBe("test text
");
+ });
+
+ test("should use settings.views when it changes", async () => {
+ const exphbs = expressHandlebars.create();
+ const viewPath = fixturePath("render-partial.handlebars");
+ const viewsPath = fixturePath();
+ const html = await exphbs.renderView(viewPath, {
+ text: "test text",
+ settings: { views: viewsPath },
+ });
+ expect(html.replace(/\r/g, "")).toBe("\npartial test text
\ntest text
\n");
+ const otherViewsPath = fixturePath("other-views");
+ const otherhtml = await exphbs.renderView(viewPath, {
+ text: "test text",
+ settings: { views: otherViewsPath },
+ });
+ expect(otherhtml.replace(/\r/g, "")).toBe("\nother layout\nother partial test text
\ntest text
\n");
+ });
+
+ test("should not overwrite config with settings.views", async () => {
+ const exphbs = expressHandlebars.create({
+ layoutsDir: fixturePath("layouts"),
+ partialsDir: fixturePath("partials"),
+ });
+ const viewPath = fixturePath("render-partial.handlebars");
+ const viewsPath = fixturePath("other-views");
+ const html = await exphbs.renderView(viewPath, {
+ text: "test text",
+ settings: { views: viewsPath },
+ });
+ expect(html.replace(/\r/g, "")).toBe("\npartial test text
\ntest text
\n");
+ });
+
+ test("should merge helpers", async () => {
+ const exphbs = expressHandlebars.create({
+ defaultLayout: undefined,
+ helpers: {
+ help: () => "help",
+ },
+ });
+ const viewPath = fixturePath("render-helper.handlebars");
+ const html = await exphbs.renderView(viewPath, {
+ text: "test text",
+ helpers: {
+ help: (text: string) => text,
+ },
+ });
+ expect(html).toBe("test text
");
+ });
+
+ test("should use layout option", async () => {
+ const exphbs = expressHandlebars.create({ defaultLayout: undefined });
+ const layoutPath = fixturePath("layouts/main.handlebars");
+ const viewPath = fixturePath("render-text.handlebars");
+ const html = await exphbs.renderView(viewPath, {
+ text: "test text",
+ layout: layoutPath,
+ });
+ expect(html.replace(/\r/g, "")).toBe("\ntest text
\n");
+ });
+
+ test("should render html", async () => {
+ const exphbs = expressHandlebars.create({ defaultLayout: undefined });
+ const viewPath = fixturePath("render-text.handlebars");
+ const html = await exphbs.renderView(viewPath, { text: "test text" });
+ expect(html).toBe("test text
");
+ });
+
+ test("should render html with encoding", async () => {
+ const exphbs = expressHandlebars.create({
+ defaultLayout: "main-latin1",
+ partialsDir: fixturePath("partials"),
+ layoutsDir: fixturePath("layouts"),
+ });
+ const viewPath = fixturePath("render-latin1.handlebars");
+ const html = await exphbs.renderView(viewPath, { encoding: "latin1" });
+ expect(html).toContain("layout ñáéÃóú");
+ expect(html).toContain("partial ñáéÃóú");
+ expect(html).toContain("render ñáéÃóú");
+ });
+
+ test("should render html with default encoding", async () => {
+ const exphbs = expressHandlebars.create({
+ encoding: "latin1",
+ defaultLayout: "main-latin1",
+ partialsDir: fixturePath("partials"),
+ layoutsDir: fixturePath("layouts"),
+ });
+ const viewPath = fixturePath("render-latin1.handlebars");
+ const html = await exphbs.renderView(viewPath);
+ expect(html).toContain("layout ñáéÃóú");
+ expect(html).toContain("partial ñáéÃóú");
+ expect(html).toContain("render ñáéÃóú");
+ });
+
+ test("should call callback with html", (done) => {
+ const exphbs = expressHandlebars.create({ defaultLayout: undefined });
+ const viewPath = fixturePath("render-text.handlebars");
+ exphbs.renderView(viewPath, { text: "test text" }, (err: Error|null, html: string|undefined) => {
+ expect(err).toBe(null);
+ expect(html).toBe("test text
");
+ done();
+ });
+ });
+
+ test("should call callback as second parameter", (done) => {
+ const exphbs = expressHandlebars.create({ defaultLayout: undefined });
+ const viewPath = fixturePath("render-text.handlebars");
+ exphbs.renderView(viewPath, (err: Error|null, html: string|undefined) => {
+ expect(err).toBe(null);
+ expect(html).toBe("");
+ done();
+ });
+ });
+
+ test("should call callback with error", (done) => {
+ const exphbs = expressHandlebars.create({ defaultLayout: undefined });
+ const viewPath = "does-not-exist";
+ exphbs.renderView(viewPath, {}, (err: Error|null, html: string | undefined) => {
+ expect(err?.message).toEqual(expect.stringContaining("no such file or directory"));
+ expect(html).toBeUndefined();
+ done();
+ });
+ });
+
+ test("should reject with error", async () => {
+ const exphbs = expressHandlebars.create({ defaultLayout: undefined });
+ const viewPath = "does-not-exist";
+ let error: Error | undefined;
+ try {
+ await exphbs.renderView(viewPath);
+ } catch (e) {
+ error = e;
+ }
+ expect(error?.message).toEqual(expect.stringContaining("no such file or directory"));
+ });
+
+ test("should use runtimeOptions", async () => {
+ const exphbs = expressHandlebars.create({ defaultLayout: undefined });
+ const filePath = fixturePath("test");
+ const spy = jest.fn(() => { return "test"; }) as Handlebars.TemplateDelegate;
+ exphbs.compiled[filePath] = Promise.resolve(spy);
+ await exphbs.renderView(filePath, {
+ cache: true,
+ runtimeOptions: { allowProtoPropertiesByDefault: true },
+ });
+ expect(spy).toHaveBeenCalledWith(expect.any(Object), expect.objectContaining({ allowProtoPropertiesByDefault: true }));
+ });
+ });
+
+ describe("resetCache", () => {
+ test("should reset all cache", async () => {
+ const exphbs = expressHandlebars.create();
+ const dirPath = fixturePath("templates");
+ const template = fixturePath("templates/template.handlebars");
+ await exphbs.getTemplates(dirPath);
+ expect(exphbs._fsCache[template]).toBeDefined();
+ exphbs.resetCache();
+ expect(exphbs._fsCache).toEqual({});
+ });
+
+ test("should reset all cache with undefined", async () => {
+ const exphbs = expressHandlebars.create();
+ const dirPath = fixturePath("templates");
+ const template = fixturePath("templates/template.handlebars");
+ await exphbs.getTemplates(dirPath);
+ expect(exphbs._fsCache[template]).toBeDefined();
+ let undef: undefined;
+ exphbs.resetCache(undef);
+ expect(exphbs._fsCache).toEqual({});
+ });
+
+ test("should reset cached file path", async () => {
+ const exphbs = expressHandlebars.create();
+ const dirPath = fixturePath("templates");
+ const template = fixturePath("templates/template.handlebars");
+ await exphbs.getTemplates(dirPath);
+ expect(Object.keys(exphbs._fsCache).length).toEqual(4);
+ expect(exphbs._fsCache[template]).toBeDefined();
+ exphbs.resetCache(template);
+ expect(Object.keys(exphbs._fsCache).length).toEqual(3);
+ expect(exphbs._fsCache[template]).toBeUndefined();
+ });
+
+ test("should reset cached file paths", async () => {
+ const exphbs = expressHandlebars.create();
+ const dirPath = fixturePath("templates");
+ const template = fixturePath("templates/template.handlebars");
+ const templateLatin1 = fixturePath("templates/template-latin1.handlebars");
+ await exphbs.getTemplates(dirPath);
+ expect(Object.keys(exphbs._fsCache).length).toEqual(4);
+ expect(exphbs._fsCache[template]).toBeDefined();
+ expect(exphbs._fsCache[templateLatin1]).toBeDefined();
+ exphbs.resetCache([template, templateLatin1]);
+ expect(Object.keys(exphbs._fsCache).length).toEqual(2);
+ expect(exphbs._fsCache[template]).toBeUndefined();
+ expect(exphbs._fsCache[templateLatin1]).toBeUndefined();
+ });
+
+ test("should reset cached file based on filter", async () => {
+ const exphbs = expressHandlebars.create();
+ const dirPath = fixturePath("templates");
+ const templateLatin1 = fixturePath("templates/template-latin1.handlebars");
+ await exphbs.getTemplates(dirPath);
+ expect(Object.keys(exphbs._fsCache).length).toEqual(4);
+ expect(exphbs._fsCache[templateLatin1]).toBeDefined();
+ exphbs.resetCache((f) => f.includes("latin1"));
+ expect(Object.keys(exphbs._fsCache).length).toEqual(3);
+ expect(exphbs._fsCache[templateLatin1]).toBeUndefined();
+ });
+
+ test("should not error on invalid file path", async () => {
+ const exphbs = expressHandlebars.create();
+ const dirPath = fixturePath("templates");
+ const template = fixturePath("templates/invalid.handlebars");
+ await exphbs.getTemplates(dirPath);
+ expect(Object.keys(exphbs._fsCache).length).toEqual(4);
+ expect(exphbs._fsCache[template]).toBeUndefined();
+ exphbs.resetCache(template);
+ expect(Object.keys(exphbs._fsCache).length).toEqual(4);
+ expect(exphbs._fsCache[template]).toBeUndefined();
+ });
+ });
+
+ describe("hooks", () => {
+ describe("_compileTemplate", () => {
+ test("should call template with context and options", () => {
+ const exphbs = expressHandlebars.create();
+ // @ts-expect-error empty function
+ jest.spyOn(exphbs.handlebars, "compile").mockImplementation(() => {});
+ const template = "template";
+ const options = {};
+ exphbs["_compileTemplate"](template, options);
+ expect(exphbs.handlebars.compile).toHaveBeenCalledWith(template, options);
+ });
+
+ test("should trim template", () => {
+ const exphbs = expressHandlebars.create();
+ // @ts-expect-error empty function
+ jest.spyOn(exphbs.handlebars, "compile").mockImplementation(() => {});
+ const template = " template\n";
+ const options = {};
+ exphbs["_compileTemplate"](template, options);
+ expect(exphbs.handlebars.compile).toHaveBeenCalledWith("template", options);
+ });
+ });
+
+ describe("_precompileTemplate", () => {
+ test("should call template with context and options", () => {
+ const exphbs = expressHandlebars.create();
+ // @ts-expect-error empty function
+ jest.spyOn(exphbs.handlebars, "precompile").mockImplementation(() => {});
+ const template = "template";
+ const options = {};
+ exphbs["_precompileTemplate"](template, options);
+ expect(exphbs.handlebars.precompile).toHaveBeenCalledWith(template, options);
+ });
+
+ test("should trim template", () => {
+ const exphbs = expressHandlebars.create();
+ // @ts-expect-error empty function
+ jest.spyOn(exphbs.handlebars, "precompile").mockImplementation(() => {});
+ const template = " template\n";
+ const options = {};
+ exphbs["_precompileTemplate"](template, options);
+ expect(exphbs.handlebars.precompile).toHaveBeenCalledWith("template", options);
+ });
+ });
+
+ describe("_renderTemplate", () => {
+ test("should call template with context and options", () => {
+ const exphbs = expressHandlebars.create();
+ const template = jest.fn(() => "");
+ const context = {};
+ const options = {};
+ exphbs["_renderTemplate"](template, context, options);
+ expect(template).toHaveBeenCalledWith(context, options);
+ });
+
+ test("should trim html", () => {
+ const exphbs = expressHandlebars.create();
+ const template = () => " \n";
+ const html = exphbs["_renderTemplate"](template);
+ expect(html).toBe("");
+ });
+ });
+
+ describe("_getDir", () => {
+ test("should get from cache", async () => {
+ const exphbs = expressHandlebars.create();
+ const filePath = fixturePath("test");
+ exphbs._fsCache[filePath] = Promise.resolve(["test"]);
+ const file = await exphbs["_getDir"](filePath, { cache: true });
+ expect(file).toEqual(["test"]);
+ });
+
+ test("should store in cache", async () => {
+ const exphbs = expressHandlebars.create();
+ const filePath = fixturePath("templates");
+ expect(exphbs._fsCache[filePath]).toBeUndefined();
+ const expected = await exphbs["_getDir"](filePath);
+ expect(exphbs._fsCache[filePath]).toBeInstanceOf(Promise);
+ expect(await exphbs._fsCache[filePath]).toEqual(expected);
+ });
+
+ test("should not store in cache on error", async () => {
+ const exphbs = expressHandlebars.create();
+ const filePath = "test";
+ expect(exphbs._fsCache[filePath]).toBeUndefined();
+ let error: Error | undefined;
+ try {
+ await exphbs["_getDir"](filePath, {
+ // @ts-expect-error Add this just for testing
+ _throwTestError: true,
+ });
+ } catch (e) {
+ error = e;
+ }
+ expect(error).toBeTruthy();
+ expect(exphbs._fsCache[filePath]).toBeUndefined();
+ });
+ });
+
+ describe("_getFile", () => {
+ test("should get from cache", async () => {
+ const exphbs = expressHandlebars.create();
+ const filePath = fixturePath("test");
+ exphbs._fsCache[filePath] = "test";
+ const file = await exphbs["_getFile"](filePath, { cache: true });
+ expect(file).toBe("test");
+ });
+
+ test("should store in cache", async () => {
+ const exphbs = expressHandlebars.create();
+ const filePath = fixturePath("render-text.handlebars");
+ expect(exphbs._fsCache[filePath]).toBeUndefined();
+ await exphbs["_getFile"](filePath);
+ expect(exphbs._fsCache[filePath]).toBeDefined();
+ });
+
+ test("should not store in cache on error", async () => {
+ const exphbs = expressHandlebars.create();
+ const filePath = "does-not-exist";
+ expect(exphbs._fsCache[filePath]).toBeUndefined();
+ let error: Error | undefined;
+ try {
+ await exphbs["_getFile"](filePath);
+ } catch (e) {
+ error = e;
+ }
+ expect(error?.message).toEqual(expect.stringContaining("no such file or directory"));
+ expect(exphbs._fsCache[filePath]).toBeUndefined();
+ });
+
+ test("should read as utf8", async () => {
+ const exphbs = expressHandlebars.create();
+ const filePath = fixturePath("render-text.handlebars");
+ const text = await exphbs["_getFile"](filePath);
+ expect(text.trim()).toBe("{{text}}
");
+ });
+
+ test("should read as utf8 by default", async () => {
+ const exphbs = expressHandlebars.create({ encoding: undefined });
+ const filePath = fixturePath("render-text.handlebars");
+ const text = await exphbs["_getFile"](filePath);
+ expect(text.trim()).toBe("{{text}}
");
+ });
+
+ test("should read as latin1", async () => {
+ const exphbs = expressHandlebars.create();
+ const filePath = fixturePath("render-latin1.handlebars");
+ const text = await exphbs["_getFile"](filePath, { encoding: "latin1" });
+ expect(text).toContain("ñáéÃóú");
+ });
+
+ test("should read as default encoding", async () => {
+ const exphbs = expressHandlebars.create({ encoding: "latin1" });
+ const filePath = fixturePath("render-latin1.handlebars");
+ const text = await exphbs["_getFile"](filePath);
+ expect(text).toContain("ñáéÃóú");
+ });
+ });
+
+ describe("_getTemplateName", () => {
+ test("should remove extension", () => {
+ const exphbs = expressHandlebars.create();
+ const name = exphbs["_getTemplateName"]("filePath.handlebars");
+ expect(name).toBe("filePath");
+ });
+
+ test("should leave if no extension", () => {
+ const exphbs = expressHandlebars.create();
+ const name = exphbs["_getTemplateName"]("filePath");
+ expect(name).toBe("filePath");
+ });
+
+ test("should add namespace", () => {
+ const exphbs = expressHandlebars.create();
+ const name = exphbs["_getTemplateName"]("filePath.handlebars", "namespace");
+ expect(name).toBe("namespace/filePath");
+ });
+ });
+
+ describe("_resolveViewsPath", () => {
+ test("should return closest parent", () => {
+ const file = "/root/views/file.hbs";
+ const exphbs = expressHandlebars.create();
+ const viewsPath = exphbs["_resolveViewsPath"]([
+ "/root",
+ "/root/views",
+ "/root/views/file",
+ ], file);
+ expect(viewsPath).toBe("/root/views");
+ });
+
+ test("should return string views", () => {
+ const exphbs = expressHandlebars.create();
+ const viewsPath = exphbs["_resolveViewsPath"]("./views", "filePath.hbs");
+ expect(viewsPath).toBe("./views");
+ });
+
+ test("should return null views", () => {
+ const exphbs = expressHandlebars.create();
+ // @ts-expect-error shouldn't expect null parameter
+ const viewsPath = exphbs["_resolveViewsPath"](null, "filePath.hbs");
+ expect(viewsPath).toBe(null);
+ });
+
+ test("should return null if not found", () => {
+ const file = "/file.hbs";
+ const exphbs = expressHandlebars.create();
+ const viewsPath = exphbs["_resolveViewsPath"]([
+ "/views",
+ ], file);
+ expect(viewsPath).toBe(null);
+ });
+ });
+
+ describe("_resolveLayoutPath", () => {
+ test("should add extension", () => {
+ const exphbs = expressHandlebars.create();
+ const layoutPath = exphbs["_resolveLayoutPath"]("filePath");
+ expect(layoutPath).toEqual(expect.stringMatching(/filePath\.handlebars$/));
+ });
+
+ test("should use layoutsDir", () => {
+ const layoutsDir = fixturePath("layouts");
+ const filePath = "filePath.handlebars";
+ const exphbs = expressHandlebars.create({ layoutsDir });
+ const layoutPath = exphbs["_resolveLayoutPath"](filePath);
+ expect(layoutPath).toBe(path.resolve(layoutsDir, filePath));
+ });
+
+ test("should return null", () => {
+ const exphbs = expressHandlebars.create();
+ // @ts-expect-error shouldn't expect null parameter
+ const layoutPath = exphbs["_resolveLayoutPath"](null);
+ expect(layoutPath).toBe(null);
+ });
+ });
+ });
+});
diff --git a/app/node_modules/express-handlebars/spec/fixtures/layouts/main-latin1.handlebars b/app/node_modules/express-handlebars/spec/fixtures/layouts/main-latin1.handlebars
new file mode 100644
index 0000000..203e4cb
--- /dev/null
+++ b/app/node_modules/express-handlebars/spec/fixtures/layouts/main-latin1.handlebars
@@ -0,0 +1,3 @@
+file encoding: Windows 1252 (latin1)
+layout ñáéíóú
+{{{body}}}
diff --git a/app/node_modules/express-handlebars/spec/fixtures/layouts/main.handlebars b/app/node_modules/express-handlebars/spec/fixtures/layouts/main.handlebars
new file mode 100644
index 0000000..1818b8b
--- /dev/null
+++ b/app/node_modules/express-handlebars/spec/fixtures/layouts/main.handlebars
@@ -0,0 +1,3 @@
+
+{{{body}}}
+
diff --git a/app/node_modules/express-handlebars/spec/fixtures/other-views/layouts/main.handlebars b/app/node_modules/express-handlebars/spec/fixtures/other-views/layouts/main.handlebars
new file mode 100644
index 0000000..3d8db1e
--- /dev/null
+++ b/app/node_modules/express-handlebars/spec/fixtures/other-views/layouts/main.handlebars
@@ -0,0 +1,4 @@
+
+other layout
+{{{body}}}
+
diff --git a/app/node_modules/express-handlebars/spec/fixtures/other-views/partials/partial.handlebars b/app/node_modules/express-handlebars/spec/fixtures/other-views/partials/partial.handlebars
new file mode 100644
index 0000000..a1853ca
--- /dev/null
+++ b/app/node_modules/express-handlebars/spec/fixtures/other-views/partials/partial.handlebars
@@ -0,0 +1 @@
+other partial {{text}}
diff --git a/app/node_modules/express-handlebars/spec/fixtures/partials/partial-latin1.handlebars b/app/node_modules/express-handlebars/spec/fixtures/partials/partial-latin1.handlebars
new file mode 100644
index 0000000..14af5a8
--- /dev/null
+++ b/app/node_modules/express-handlebars/spec/fixtures/partials/partial-latin1.handlebars
@@ -0,0 +1,2 @@
+file encoding: Windows 1252 (latin1)
+partial ñáéíóú
diff --git a/app/node_modules/express-handlebars/spec/fixtures/partials/partial.handlebars b/app/node_modules/express-handlebars/spec/fixtures/partials/partial.handlebars
new file mode 100644
index 0000000..27919f9
--- /dev/null
+++ b/app/node_modules/express-handlebars/spec/fixtures/partials/partial.handlebars
@@ -0,0 +1 @@
+partial {{text}}
diff --git a/app/node_modules/express-handlebars/spec/fixtures/partials/subdir/partial-subdir.handlebars b/app/node_modules/express-handlebars/spec/fixtures/partials/subdir/partial-subdir.handlebars
new file mode 100644
index 0000000..b411a23
--- /dev/null
+++ b/app/node_modules/express-handlebars/spec/fixtures/partials/subdir/partial-subdir.handlebars
@@ -0,0 +1 @@
+subdir partial {{text}}
diff --git a/app/node_modules/express-handlebars/spec/fixtures/render-cached.handlebars b/app/node_modules/express-handlebars/spec/fixtures/render-cached.handlebars
new file mode 100644
index 0000000..8b51bcc
--- /dev/null
+++ b/app/node_modules/express-handlebars/spec/fixtures/render-cached.handlebars
@@ -0,0 +1 @@
+not cached
diff --git a/app/node_modules/express-handlebars/spec/fixtures/render-helper.handlebars b/app/node_modules/express-handlebars/spec/fixtures/render-helper.handlebars
new file mode 100644
index 0000000..b3102cc
--- /dev/null
+++ b/app/node_modules/express-handlebars/spec/fixtures/render-helper.handlebars
@@ -0,0 +1 @@
+{{help text}}
diff --git a/app/node_modules/express-handlebars/spec/fixtures/render-latin1.handlebars b/app/node_modules/express-handlebars/spec/fixtures/render-latin1.handlebars
new file mode 100644
index 0000000..40447df
--- /dev/null
+++ b/app/node_modules/express-handlebars/spec/fixtures/render-latin1.handlebars
@@ -0,0 +1,3 @@
+{{> partial-latin1}}
+file encoding: Windows 1252 (latin1)
+render ñáéíóú
diff --git a/app/node_modules/express-handlebars/spec/fixtures/render-partial.handlebars b/app/node_modules/express-handlebars/spec/fixtures/render-partial.handlebars
new file mode 100644
index 0000000..d6d8a0c
--- /dev/null
+++ b/app/node_modules/express-handlebars/spec/fixtures/render-partial.handlebars
@@ -0,0 +1,2 @@
+{{> partial}}
+{{text}}
diff --git a/app/node_modules/express-handlebars/spec/fixtures/render-subdir-partial.handlebars b/app/node_modules/express-handlebars/spec/fixtures/render-subdir-partial.handlebars
new file mode 100644
index 0000000..0fab341
--- /dev/null
+++ b/app/node_modules/express-handlebars/spec/fixtures/render-subdir-partial.handlebars
@@ -0,0 +1,2 @@
+{{> subdir/partial-subdir}}
+{{text}}
diff --git a/app/node_modules/express-handlebars/spec/fixtures/render-text.handlebars b/app/node_modules/express-handlebars/spec/fixtures/render-text.handlebars
new file mode 100644
index 0000000..f73bbab
--- /dev/null
+++ b/app/node_modules/express-handlebars/spec/fixtures/render-text.handlebars
@@ -0,0 +1 @@
+{{text}}
diff --git a/app/node_modules/express-handlebars/spec/fixtures/templates/subdir/template.handlebars b/app/node_modules/express-handlebars/spec/fixtures/templates/subdir/template.handlebars
new file mode 100644
index 0000000..f73bbab
--- /dev/null
+++ b/app/node_modules/express-handlebars/spec/fixtures/templates/subdir/template.handlebars
@@ -0,0 +1 @@
+{{text}}
diff --git a/app/node_modules/express-handlebars/spec/fixtures/templates/template-latin1.handlebars b/app/node_modules/express-handlebars/spec/fixtures/templates/template-latin1.handlebars
new file mode 100644
index 0000000..4d3a055
--- /dev/null
+++ b/app/node_modules/express-handlebars/spec/fixtures/templates/template-latin1.handlebars
@@ -0,0 +1,2 @@
+file encoding: Windows 1252 (latin1)
+ñáéíóú
diff --git a/app/node_modules/express-handlebars/spec/fixtures/templates/template.handlebars b/app/node_modules/express-handlebars/spec/fixtures/templates/template.handlebars
new file mode 100644
index 0000000..f73bbab
--- /dev/null
+++ b/app/node_modules/express-handlebars/spec/fixtures/templates/template.handlebars
@@ -0,0 +1 @@
+{{text}}
diff --git a/app/node_modules/express-handlebars/tsconfig.json b/app/node_modules/express-handlebars/tsconfig.json
new file mode 100644
index 0000000..d2d4fd8
--- /dev/null
+++ b/app/node_modules/express-handlebars/tsconfig.json
@@ -0,0 +1,12 @@
+{
+ "compilerOptions": {
+ "outDir": "./dist",
+ "target": "ES2015",
+ "declaration": true,
+ "sourceMap": true,
+ "module": "commonjs",
+ "moduleResolution": "node",
+ "allowSyntheticDefaultImports": true
+ },
+ "include": ["./lib/**/*"]
+}
diff --git a/app/node_modules/express-handlebars/types/index.d.ts b/app/node_modules/express-handlebars/types/index.d.ts
new file mode 100644
index 0000000..1d3acba
--- /dev/null
+++ b/app/node_modules/express-handlebars/types/index.d.ts
@@ -0,0 +1,92 @@
+///
+
+export interface UnknownObject {
+ [index: string]: unknown
+}
+
+export interface HelperDelegateObject {
+ [index: string]: Handlebars.HelperDelegate;
+}
+
+export interface TemplateDelegateObject {
+ [index: string]: Handlebars.TemplateDelegate;
+}
+
+export interface TemplateSpecificationObject {
+ [index: string]: TemplateSpecification;
+}
+
+export interface CompiledCache {
+ [index: string]: Promise;
+}
+
+export interface PrecompiledCache {
+ [index: string]: Promise;
+}
+
+export interface FsCache {
+ [index: string]: string|string[]|Promise;
+}
+
+export type RenameFunction = (filePath: string, namespace?: string) => string
+
+export interface PartialsDirObject {
+ templates: TemplateDelegateObject;
+ namespace: string;
+ dir: string;
+ rename?: RenameFunction | undefined;
+}
+
+export interface PartialTemplateOptions {
+ encoding?: BufferEncoding;
+ cache?: boolean;
+ precompiled?: boolean;
+}
+
+export interface RenderOptions {
+ cache?: boolean;
+ data?: UnknownObject;
+ encoding?: BufferEncoding;
+ helpers?: HelperDelegateObject;
+ layout?: string;
+ partials?: TemplateDelegateObject;
+ runtimeOptions?: Handlebars.RuntimeOptions;
+}
+
+export interface RenderViewOptions extends RenderOptions {
+ [index: string]: unknown;
+ settings?: {
+ views: string|string[]
+ }
+}
+
+export type HandlebarsCompile = (input: unknown, options: CompileOptions) => Handlebars.TemplateDelegate;
+export type HandlebarsPrecompile = (input: unknown, options: PrecompileOptions) => TemplateSpecification;
+
+export interface HandlebarsImport {
+ [index: string]: unknown;
+ compile: HandlebarsCompile;
+ precompile: HandlebarsPrecompile;
+}
+
+export interface ConfigOptions {
+ handlebars?: HandlebarsImport;
+ extname?: string;
+ encoding?: BufferEncoding;
+ layoutsDir?: string;
+ partialsDir?: string|string[]|PartialsDirObject|PartialsDirObject[];
+ defaultLayout?: string|false;
+ helpers?: UnknownObject;
+ compilerOptions?: CompileOptions;
+ runtimeOptions?: Handlebars.RuntimeOptions;
+}
+
+export interface EngineOptions extends ConfigOptions {
+ [index: string]: unknown;
+}
+
+export interface RenderCallback {
+ (err: Error|null, content?: string): void;
+}
+
+export type Engine = (viewPath: string, options: ConfigOptions, callback?: RenderCallback) => Promise
diff --git a/app/node_modules/express/History.md b/app/node_modules/express/History.md
new file mode 100644
index 0000000..ac2e7cf
--- /dev/null
+++ b/app/node_modules/express/History.md
@@ -0,0 +1,3615 @@
+4.19.2 / 2024-03-25
+==========
+
+ * Improved fix for open redirect allow list bypass
+
+4.19.1 / 2024-03-20
+==========
+
+ * Allow passing non-strings to res.location with new encoding handling checks
+
+4.19.0 / 2024-03-20
+==========
+
+ * Prevent open redirect allow list bypass due to encodeurl
+ * deps: cookie@0.6.0
+
+4.18.3 / 2024-02-29
+==========
+
+ * Fix routing requests without method
+ * deps: body-parser@1.20.2
+ - Fix strict json error message on Node.js 19+
+ - deps: content-type@~1.0.5
+ - deps: raw-body@2.5.2
+ * deps: cookie@0.6.0
+ - Add `partitioned` option
+
+4.18.2 / 2022-10-08
+===================
+
+ * Fix regression routing a large stack in a single route
+ * deps: body-parser@1.20.1
+ - deps: qs@6.11.0
+ - perf: remove unnecessary object clone
+ * deps: qs@6.11.0
+
+4.18.1 / 2022-04-29
+===================
+
+ * Fix hanging on large stack of sync routes
+
+4.18.0 / 2022-04-25
+===================
+
+ * Add "root" option to `res.download`
+ * Allow `options` without `filename` in `res.download`
+ * Deprecate string and non-integer arguments to `res.status`
+ * Fix behavior of `null`/`undefined` as `maxAge` in `res.cookie`
+ * Fix handling very large stacks of sync middleware
+ * Ignore `Object.prototype` values in settings through `app.set`/`app.get`
+ * Invoke `default` with same arguments as types in `res.format`
+ * Support proper 205 responses using `res.send`
+ * Use `http-errors` for `res.format` error
+ * deps: body-parser@1.20.0
+ - Fix error message for json parse whitespace in `strict`
+ - Fix internal error when inflated body exceeds limit
+ - Prevent loss of async hooks context
+ - Prevent hanging when request already read
+ - deps: depd@2.0.0
+ - deps: http-errors@2.0.0
+ - deps: on-finished@2.4.1
+ - deps: qs@6.10.3
+ - deps: raw-body@2.5.1
+ * deps: cookie@0.5.0
+ - Add `priority` option
+ - Fix `expires` option to reject invalid dates
+ * deps: depd@2.0.0
+ - Replace internal `eval` usage with `Function` constructor
+ - Use instance methods on `process` to check for listeners
+ * deps: finalhandler@1.2.0
+ - Remove set content headers that break response
+ - deps: on-finished@2.4.1
+ - deps: statuses@2.0.1
+ * deps: on-finished@2.4.1
+ - Prevent loss of async hooks context
+ * deps: qs@6.10.3
+ * deps: send@0.18.0
+ - Fix emitted 416 error missing headers property
+ - Limit the headers removed for 304 response
+ - deps: depd@2.0.0
+ - deps: destroy@1.2.0
+ - deps: http-errors@2.0.0
+ - deps: on-finished@2.4.1
+ - deps: statuses@2.0.1
+ * deps: serve-static@1.15.0
+ - deps: send@0.18.0
+ * deps: statuses@2.0.1
+ - Remove code 306
+ - Rename `425 Unordered Collection` to standard `425 Too Early`
+
+4.17.3 / 2022-02-16
+===================
+
+ * deps: accepts@~1.3.8
+ - deps: mime-types@~2.1.34
+ - deps: negotiator@0.6.3
+ * deps: body-parser@1.19.2
+ - deps: bytes@3.1.2
+ - deps: qs@6.9.7
+ - deps: raw-body@2.4.3
+ * deps: cookie@0.4.2
+ * deps: qs@6.9.7
+ * Fix handling of `__proto__` keys
+ * pref: remove unnecessary regexp for trust proxy
+
+4.17.2 / 2021-12-16
+===================
+
+ * Fix handling of `undefined` in `res.jsonp`
+ * Fix handling of `undefined` when `"json escape"` is enabled
+ * Fix incorrect middleware execution with unanchored `RegExp`s
+ * Fix `res.jsonp(obj, status)` deprecation message
+ * Fix typo in `res.is` JSDoc
+ * deps: body-parser@1.19.1
+ - deps: bytes@3.1.1
+ - deps: http-errors@1.8.1
+ - deps: qs@6.9.6
+ - deps: raw-body@2.4.2
+ - deps: safe-buffer@5.2.1
+ - deps: type-is@~1.6.18
+ * deps: content-disposition@0.5.4
+ - deps: safe-buffer@5.2.1
+ * deps: cookie@0.4.1
+ - Fix `maxAge` option to reject invalid values
+ * deps: proxy-addr@~2.0.7
+ - Use `req.socket` over deprecated `req.connection`
+ - deps: forwarded@0.2.0
+ - deps: ipaddr.js@1.9.1
+ * deps: qs@6.9.6
+ * deps: safe-buffer@5.2.1
+ * deps: send@0.17.2
+ - deps: http-errors@1.8.1
+ - deps: ms@2.1.3
+ - pref: ignore empty http tokens
+ * deps: serve-static@1.14.2
+ - deps: send@0.17.2
+ * deps: setprototypeof@1.2.0
+
+4.17.1 / 2019-05-25
+===================
+
+ * Revert "Improve error message for `null`/`undefined` to `res.status`"
+
+4.17.0 / 2019-05-16
+===================
+
+ * Add `express.raw` to parse bodies into `Buffer`
+ * Add `express.text` to parse bodies into string
+ * Improve error message for non-strings to `res.sendFile`
+ * Improve error message for `null`/`undefined` to `res.status`
+ * Support multiple hosts in `X-Forwarded-Host`
+ * deps: accepts@~1.3.7
+ * deps: body-parser@1.19.0
+ - Add encoding MIK
+ - Add petabyte (`pb`) support
+ - Fix parsing array brackets after index
+ - deps: bytes@3.1.0
+ - deps: http-errors@1.7.2
+ - deps: iconv-lite@0.4.24
+ - deps: qs@6.7.0
+ - deps: raw-body@2.4.0
+ - deps: type-is@~1.6.17
+ * deps: content-disposition@0.5.3
+ * deps: cookie@0.4.0
+ - Add `SameSite=None` support
+ * deps: finalhandler@~1.1.2
+ - Set stricter `Content-Security-Policy` header
+ - deps: parseurl@~1.3.3
+ - deps: statuses@~1.5.0
+ * deps: parseurl@~1.3.3
+ * deps: proxy-addr@~2.0.5
+ - deps: ipaddr.js@1.9.0
+ * deps: qs@6.7.0
+ - Fix parsing array brackets after index
+ * deps: range-parser@~1.2.1
+ * deps: send@0.17.1
+ - Set stricter CSP header in redirect & error responses
+ - deps: http-errors@~1.7.2
+ - deps: mime@1.6.0
+ - deps: ms@2.1.1
+ - deps: range-parser@~1.2.1
+ - deps: statuses@~1.5.0
+ - perf: remove redundant `path.normalize` call
+ * deps: serve-static@1.14.1
+ - Set stricter CSP header in redirect response
+ - deps: parseurl@~1.3.3
+ - deps: send@0.17.1
+ * deps: setprototypeof@1.1.1
+ * deps: statuses@~1.5.0
+ - Add `103 Early Hints`
+ * deps: type-is@~1.6.18
+ - deps: mime-types@~2.1.24
+ - perf: prevent internal `throw` on invalid type
+
+4.16.4 / 2018-10-10
+===================
+
+ * Fix issue where `"Request aborted"` may be logged in `res.sendfile`
+ * Fix JSDoc for `Router` constructor
+ * deps: body-parser@1.18.3
+ - Fix deprecation warnings on Node.js 10+
+ - Fix stack trace for strict json parse error
+ - deps: depd@~1.1.2
+ - deps: http-errors@~1.6.3
+ - deps: iconv-lite@0.4.23
+ - deps: qs@6.5.2
+ - deps: raw-body@2.3.3
+ - deps: type-is@~1.6.16
+ * deps: proxy-addr@~2.0.4
+ - deps: ipaddr.js@1.8.0
+ * deps: qs@6.5.2
+ * deps: safe-buffer@5.1.2
+
+4.16.3 / 2018-03-12
+===================
+
+ * deps: accepts@~1.3.5
+ - deps: mime-types@~2.1.18
+ * deps: depd@~1.1.2
+ - perf: remove argument reassignment
+ * deps: encodeurl@~1.0.2
+ - Fix encoding `%` as last character
+ * deps: finalhandler@1.1.1
+ - Fix 404 output for bad / missing pathnames
+ - deps: encodeurl@~1.0.2
+ - deps: statuses@~1.4.0
+ * deps: proxy-addr@~2.0.3
+ - deps: ipaddr.js@1.6.0
+ * deps: send@0.16.2
+ - Fix incorrect end tag in default error & redirects
+ - deps: depd@~1.1.2
+ - deps: encodeurl@~1.0.2
+ - deps: statuses@~1.4.0
+ * deps: serve-static@1.13.2
+ - Fix incorrect end tag in redirects
+ - deps: encodeurl@~1.0.2
+ - deps: send@0.16.2
+ * deps: statuses@~1.4.0
+ * deps: type-is@~1.6.16
+ - deps: mime-types@~2.1.18
+
+4.16.2 / 2017-10-09
+===================
+
+ * Fix `TypeError` in `res.send` when given `Buffer` and `ETag` header set
+ * perf: skip parsing of entire `X-Forwarded-Proto` header
+
+4.16.1 / 2017-09-29
+===================
+
+ * deps: send@0.16.1
+ * deps: serve-static@1.13.1
+ - Fix regression when `root` is incorrectly set to a file
+ - deps: send@0.16.1
+
+4.16.0 / 2017-09-28
+===================
+
+ * Add `"json escape"` setting for `res.json` and `res.jsonp`
+ * Add `express.json` and `express.urlencoded` to parse bodies
+ * Add `options` argument to `res.download`
+ * Improve error message when autoloading invalid view engine
+ * Improve error messages when non-function provided as middleware
+ * Skip `Buffer` encoding when not generating ETag for small response
+ * Use `safe-buffer` for improved Buffer API
+ * deps: accepts@~1.3.4
+ - deps: mime-types@~2.1.16
+ * deps: content-type@~1.0.4
+ - perf: remove argument reassignment
+ - perf: skip parameter parsing when no parameters
+ * deps: etag@~1.8.1
+ - perf: replace regular expression with substring
+ * deps: finalhandler@1.1.0
+ - Use `res.headersSent` when available
+ * deps: parseurl@~1.3.2
+ - perf: reduce overhead for full URLs
+ - perf: unroll the "fast-path" `RegExp`
+ * deps: proxy-addr@~2.0.2
+ - Fix trimming leading / trailing OWS in `X-Forwarded-For`
+ - deps: forwarded@~0.1.2
+ - deps: ipaddr.js@1.5.2
+ - perf: reduce overhead when no `X-Forwarded-For` header
+ * deps: qs@6.5.1
+ - Fix parsing & compacting very deep objects
+ * deps: send@0.16.0
+ - Add 70 new types for file extensions
+ - Add `immutable` option
+ - Fix missing `