diff --git a/.editorconfig b/.editorconfig
new file mode 100644
index 00000000..4e882bc7
--- /dev/null
+++ b/.editorconfig
@@ -0,0 +1,7 @@
+[*]
+end_of_line = lf
+trim_trailing_whitespace = true
+
+[*.js]
+indent_style = space
+indent_size = 4
diff --git a/.github/contributing.md b/.github/contributing.md
new file mode 100644
index 00000000..313059cf
--- /dev/null
+++ b/.github/contributing.md
@@ -0,0 +1,27 @@
+# Contributing
+
+There are a few steps to take to get twig.js building in your environment.
+
+
+## Requirements
+
+In order work on twig.js you will need node installed to run the tests and create the minified version of twig.js
+
+## Building
+
+1. Fork and clone the twig.js git repository.
+2. Run `npm ci` to install the development dependencies.
+3. Make your changes to the source files in `src/`.
+4. Add/update tests in `test/`.
+5. Run `npm run test` to make sure your tests pass.
+6. Run `npm run build` to build the source.
+
+
+## Contributing
+
+1. If possible, create tests (in the `test/` directory) which test your changes. E.g. if you found and fixed a bug, create a test which fails in the buggy version.
+2. Please commit only changes in the source code, not in the built files like `twig.js`, `twig.min.js`, etc. as they blow up the repository and create conflicts when merging pull requests. We build a final file when releasing a new version.
+3. If possible, rebase your changes to the current master.
+4. Tidy up your commit history. It's important to have distinct commits so that you can follow development process.
+5. Push a branch to your fork on Github and create a pull request.
+
diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml
new file mode 100644
index 00000000..49ef2f73
--- /dev/null
+++ b/.github/workflows/deploy.yml
@@ -0,0 +1,69 @@
+# Sample workflow for building and deploying a VitePress site to GitHub Pages
+#
+name: Deploy VitePress site to Pages
+
+on:
+ # Runs on pushes targeting the `main` branch. Change this to `master` if you're
+ # using the `master` branch as the default branch.
+ push:
+ branches: [write-docs-using-vitepress]
+
+ # Allows you to run this workflow manually from the Actions tab
+ workflow_dispatch:
+
+# Sets permissions of the GITHUB_TOKEN to allow deployment to GitHub Pages
+permissions:
+ contents: read
+ pages: write
+ id-token: write
+
+# Allow only one concurrent deployment, skipping runs queued between the run in-progress and latest queued.
+# However, do NOT cancel in-progress runs as we want to allow these production deployments to complete.
+concurrency:
+ group: pages
+ cancel-in-progress: false
+
+jobs:
+ # Build job
+ build:
+ runs-on: ubuntu-latest
+ steps:
+ - name: Checkout
+ uses: actions/checkout@v4
+ with:
+ fetch-depth: 0
+
+ - name: Setup Node
+ uses: actions/setup-node@v4
+ with:
+ node-version: 20
+ cache: npm
+
+ - name: Setup Pages
+ uses: actions/configure-pages@v4
+
+ - name: Install dependencies
+ run: npm ci
+ working-directory: docs
+
+ - name: Build with VitePress
+ run: npm run docs:build
+ working-directory: docs
+
+ - name: Upload artifact
+ uses: actions/upload-pages-artifact@v3
+ with:
+ path: docs/.vitepress/dist
+
+ # Deployment job
+ deploy:
+ environment:
+ name: github-pages
+ url: ${{ steps.deployment.outputs.page_url }}
+ needs: build
+ runs-on: ubuntu-latest
+ name: Deploy
+ steps:
+ - name: Deploy to GitHub Pages
+ id: deployment
+ uses: actions/deploy-pages@v4
diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml
new file mode 100644
index 00000000..03662771
--- /dev/null
+++ b/.github/workflows/tests.yml
@@ -0,0 +1,41 @@
+name: "tests"
+
+on:
+ push:
+ pull_request:
+
+jobs:
+ tests:
+ name: "Node v${{ matrix.node_js }}"
+
+ runs-on: "ubuntu-latest"
+
+ strategy:
+ fail-fast: true
+ matrix:
+ node_js:
+ - 10
+ - 11
+ - 12
+ - 13
+ - 14
+ - 15
+ - 16
+ - 17
+ - 18
+
+ steps:
+ - name: "Checkout code"
+ uses: "actions/checkout@v3"
+
+ - name: "Setup Node and npm"
+ uses: "actions/setup-node@v3"
+ with:
+ cache: "npm"
+ node-version: "${{ matrix.node_js }}"
+
+ - name: "Install Node dependencies"
+ run: "npm ci"
+
+ - name: "Run tests"
+ run: "npm run test"
diff --git a/.gitignore b/.gitignore
index 94b06b78..28b2bd6a 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,3 +1,10 @@
-node_modules
-.c9revisions
-twig.php
+.idea/
+node_modules/
+twig.js
+twig.min.js
+twig.min.js.map
+twig.min.js.LICENSE.txt
+
+# docs
+docs/.vitepress/cache/
+docs/.vitepress/dist/
diff --git a/.gitmodules b/.gitmodules
index 17a914cc..fbdf6eb8 100644
--- a/.gitmodules
+++ b/.gitmodules
@@ -1,3 +1,3 @@
[submodule "docs/wiki"]
path = docs/wiki
- url = git://github.com/justjohn/twig.js.wiki.git
+ url = https://github.com/twigjs/twig.js.wiki.git
diff --git a/.npmignore b/.npmignore
index d479aa1e..8b8a027b 100644
--- a/.npmignore
+++ b/.npmignore
@@ -1,7 +1,14 @@
demos
tools
test
+test-ext
+docs
qtest
-src
.hg
.git
+.gitignore
+.gitmodules
+.travis.yml
+.idea
+webpack.config.js
+bower.json
diff --git a/.travis.yml b/.travis.yml
index 8e3af8fb..75c38d3b 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -1,6 +1,15 @@
language: node_js
node_js:
- - 0.6
- - 0.8
- - 0.10
- - 0.11
+ - 10
+ - 11
+ - 12
+ - 13
+
+cache:
+ directories:
+ - node_modules
+ - $HOME/.npm
+
+notifications:
+ on_success: false
+ email: false
diff --git a/ASYNC.md b/ASYNC.md
new file mode 100644
index 00000000..989b8686
--- /dev/null
+++ b/ASYNC.md
@@ -0,0 +1,218 @@
+# Twig Asynchronous Rendering
+
+## Synchronous promises
+
+The asynchronous behaviour of Twig.js relies on promises, in order to support both the synchronous and asynchronous behaviour there is an internal promise implementation that runs fully synchronous.
+
+The internal implementation of promises does not use `setTimeout` to run through the promise chain, but instead synchronously runs through the promise chain.
+
+The different promise implementations can be mixed, synchronous behaviour however is no longer guaranteed as soon as the regular promise implementation is run.
+
+### Examples
+
+**Internal (synchronous) implementation**
+
+[Internal implementation](https://github.com/JorgenEvens/twig.js/tree/master/src/twig.async.js#L40)
+
+```javascript
+console.log('start');
+Twig.Promise.resolve('1')
+.then(function(v) {
+ console.log(v);
+ return '2';
+})
+.then(function(v) {
+ console.log(v);
+});
+console.log('stop');
+
+/**
+ * Prints to the console:
+ * start
+ * 1
+ * 2
+ * stop
+ */
+```
+
+**Regular / native promises**
+
+Implementations such as the native promises or [bluebird](http://bluebirdjs.com/docs/getting-started.html) promises.
+
+```javascript
+console.log('start');
+Promise.resolve('1')
+.then(function(v) {
+ console.log(v);
+ return '2';
+})
+.then(function(v) {
+ console.log(v);
+});
+console.log('stop');
+
+/**
+ * Prints to the console:
+ * start
+ * stop
+ * 1
+ * 2
+ */
+```
+
+**Mixing promises**
+
+```javascript
+console.log('start');
+Twig.Promise.resolve('1')
+.then(function(v) {
+ console.log(v);
+ return Promise.resolve('2');
+})
+.then(function(v) {
+ console.log(v);
+});
+console.log('stop');
+
+/**
+ * Prints to the console:
+ * start
+ * 1
+ * stop
+ * 2
+ */
+```
+
+
+## Async helpers
+
+To preserve the correct order of execution there is an implemenation of `Twig.forEach()` that waits any promises returned from the callback before executing the next iteration of the loop. If no promise is returned the next iteration is invoked immediately.
+
+```javascript
+var arr = new Array(5);
+
+Twig.async.forEach(arr, function(value, index) {
+ console.log(index);
+
+ if (index % 2 == 0)
+ return index;
+
+ return Promise.resolve(index);
+})
+.then(function() {
+ console.log('finished');
+});
+
+/**
+ * Prints to the console:
+ * 0
+ * 1
+ * 2
+ * 3
+ * 4
+ * finished
+ */
+```
+
+## Switching render mode
+
+The rendering mode of Twig.js internally is determined by the `allowAsync` argument that can be passed into `Twig.expression.parse`, `Twig.logic.parse`, `Twig.parse` and `Twig.Template.render`. Detecting if at any point code runs asynchronously is explained in [detecting asynchronous behaviour](#detecting-asynchronous-behaviour).
+
+For the end user switching between synchronous and asynchronous is as simple as using a different method on the template instance.
+
+**Render template synchronously**
+
+```javascript
+var output = twig({
+ data: 'a {{value}}'
+}).render({
+ value: 'test'
+});
+
+/**
+ * Prints to the console:
+ * a test
+ */
+```
+
+**Render template asynchronously**
+
+```javascript
+var template = twig({
+ data: 'a {{value}}'
+}).renderAsync({
+ value: 'test'
+})
+.then(function(output) {
+ console.log(output);
+});
+
+/**
+ * Prints to the console:
+ * a test
+ */
+```
+
+## Detecting asynchronous behaviour
+
+The pattern used to detect asynchronous behaviour is the same everywhere it is used and follows a simple pattern.
+
+1. Set a variable `isAsync = true`
+2. Run the promise chain that might contain some asynchronous behaviour.
+3. As the last method in the promise chain set `isAsync = false`
+4. Underneath the promise chain test whether `isAsync` is `true`
+
+This pattern works because the last method in the chain will be executed in the next run of the eventloop (`setTimeout`/`setImmediate`).
+
+### Examples
+
+**Synchronous promises only**
+
+```javascript
+var isAsync = true;
+
+Twig.Promise.resolve()
+.then(function() {
+ // We run our work in here such to allow for asynchronous work
+ // This example is fully synchronous
+ return 'hello world';
+})
+.then(function() {
+ isAsync = false;
+});
+
+if (isAsync)
+ console.log('method ran asynchronous');
+
+console.log('method ran synchronous');
+
+/**
+ * Prints to the console:
+ * method ran synchronous
+ */
+```
+
+**Mixed promises**
+
+```javascript
+var isAsync = true;
+
+Twig.Promise.resolve()
+.then(function() {
+ // We run our work in here such to allow for asynchronous work
+ return Promise.resolve('hello world');
+})
+.then(function() {
+ isAsync = false;
+});
+
+if (isAsync)
+ console.log('method ran asynchronous');
+
+console.log('method ran synchronous');
+
+/**
+ * Prints to the console:
+ * method ran asynchronous
+ */
+```
diff --git a/CHANGELOG.md b/CHANGELOG.md
new file mode 100644
index 00000000..1dd062c2
--- /dev/null
+++ b/CHANGELOG.md
@@ -0,0 +1,352 @@
+Version 1.17.0, release 2023-11-16
+----------------------------------
+Major improvements:
+* Add string position of tokens in token trees by @synga-nl in https://github.com/twigjs/twig.js/pull/859
+* Allow multiple spaces after elseif statement. by @antoineveldhoven in https://github.com/twigjs/twig.js/pull/870
+* Make is empty return false for boolean true. by @antoineveldhoven in https://github.com/twigjs/twig.js/pull/869
+* Add support for spaceship operator by @antoineveldhoven in https://github.com/twigjs/twig.js/pull/873
+* Allow colon inside Twig.expression.type.key.brackets. by @antoineveldhoven in https://github.com/twigjs/twig.js/pull/879
+* Support variables in slice filter shorthand by @antoineveldhoven in https://github.com/twigjs/twig.js/pull/881
+
+Minor improvements:
+* Bump @babel/traverse from 7.12.5 to 7.23.2 by @dependabot in https://github.com/twigjs/twig.js/pull/877
+
+Version 1.16.0, release 2023-02-27
+----------------------------------
+Major improvements:
+* Fix passing context around by @willrowe in https://github.com/twigjs/twig.js/pull/850
+* Add namespace support to `source` function by @willrowe in https://github.com/twigjs/twig.js/pull/823
+* Use src/twig.js as package's main script instead of the compiled twig.js by @RobLoach in https://github.com/twigjs/twig.js/pull/829
+
+Minor improvements:
+* Fix macro changing context in loop by @mihkeleidast in https://github.com/twigjs/twig.js/pull/773
+* Imported function PATHS.strip_slash() missing by @murageyun in https://github.com/twigjs/twig.js/pull/770
+* Convert non-string values to string before replacing by @kmonahan in https://github.com/twigjs/twig.js/pull/797
+* Add GitHub actions test workflow by @willrowe in https://github.com/twigjs/twig.js/pull/817
+* Fix date parsing with timezones by @plepe in https://github.com/twigjs/twig.js/pull/765
+* Fixed Twig official's URL on README.md by @Geolim4 in https://github.com/twigjs/twig.js/pull/822
+* Add tests for whitespace in paths by @willrowe in https://github.com/twigjs/twig.js/pull/824
+* Fix multiple includes with embeds by @willrowe in https://github.com/twigjs/twig.js/pull/828
+* Update to Mocha 9.x by @RobLoach in https://github.com/twigjs/twig.js/pull/831
+* Add test for issue #767 by @willrowe in https://github.com/twigjs/twig.js/pull/837
+* Add support for `divisible by` test by @willrowe in https://github.com/twigjs/twig.js/pull/838
+* Add support for `with` tag without context or `only` keyword by @willrowe in https://github.com/twigjs/twig.js/pull/839
+* Use v3 of `actions/checkout` by @willrowe in https://github.com/twigjs/twig.js/pull/846
+* Test on more node versions by @willrowe in https://github.com/twigjs/twig.js/pull/847
+* Fix webpack 5 compatibility by @willrowe in https://github.com/twigjs/twig.js/pull/849
+* Add test to confirm `renderFile` error handling by @willrowe in https://github.com/twigjs/twig.js/pull/851
+* Fix casing of variables in docs by @willrowe in https://github.com/twigjs/twig.js/pull/852
+* Bumped dependencies by @dependabot
+
+Version 1.15.4, released 2020-11-27
+-----------------------------------
+Minor improvements:
+* Fix lost context when calling a macro multiple times ([#727](https://github.com/twigjs/twig.js/pull/727)) by [mihkeleidast ](https://github.com/mihkeleidast)
+
+Version 1.15.3, released 2020-11-05
+-----------------------------------
+Minor improvements:
+* Fix documentation of browser usage ([#755](https://github.com/twigjs/twig.js/pull/755)) by [odebparla](https://github.com/obedparla)
+* Add support for template arrays when using extends ([#754](https://github.com/twigjs/twig.js/pull/754)) by [justafish](https://github.com/justafish)
+
+Version 1.15.2, released 2020-08-19
+-----------------------------------
+Minor improvements:
+* Specify MimeType to always use for AJAX templates ([#742](https://github.com/twigjs/twig.js/pull/742)) by [MasterOdin](https://github.com/MasterOdin)
+* Added token count validation ([#745](https://github.com/twigjs/twig.js/pull/742)) by [HakS](https://github.com/haks)
+* Async renderFile error callback ([#748](https://github.com/twigjs/twig.js/pull/748)) by [ArnauMrJeff](https://github.com/ArnauMrJeff)
+* Ternary operator overrides context fix ([#737](https://github.com/twigjs/twig.js/issues/737)) by [oleg-andreyev](https://github.com/oleg-andreyev)
+* Update lodash to `4.17.19`
+* Update elliptic to `6.5.3`
+
+Version 1.15.1, released 2020-04-16
+-----------------------------------
+Major improvements:
+* Make "js" escaped strings embeddable in JSON ([#724](https://github.com/twigjs/twig.js/pull/724) by [@dorian-marchal])
+
+Minor improvements:
+* Fix parsing expression when value is `null` ([#735](https://github.com/twigjs/twig.js/pull/735) by [@RobLoach])
+
+Version 1.15.0, released 2020-02-20
+-----------------------------------
+Major improvements:
+* Add support for arrays with `include` ([#681](https://github.com/twigjs/twig.js/pull/681) by [@justafish](https://github.com/justafish))
+* Add babel preset on serverBuild ([#707](https://github.com/twigjs/twig.js/pull/707) by [@stephane-r](https://github.com/stephane-r))
+* Support for "do" tag ([#703](https://github.com/twigjs/twig.js/pull/703) by [@drzraf](https://github.com/drzraf))
+* Update [`xo`](https://www.npmjs.com/package/xo) and code syntax by [@RobLoach](https://github.com/robloach)
+* Deprecate Node.js 8 from testing by [@RobLoach](https://github.com/robloach)
+* Support for Source Maps ([#700](https://github.com/twigjs/twig.js/pull/700) by [@drzraf](https://github.com/drzraf))
+* Search for block within all ascendants instead of parent only ([#698](https://github.com/twigjs/twig.js/pull/698) by [@drzraf](https://github.com/drzraf))
+
+Minor improvements:
+* Fix autoescape for empty includes ([#687](https://github.com/twigjs/twig.js/pull/687) by [@tgabi333](https://github.com/tgabi333))
+* Fix filters with empty string input ([#690](https://github.com/twigjs/twig.js/pull/690) by [@tbence94](https://github.com/tbence94))
+
+Version 1.14.0, released 2019-11-13
+-----------------------------------
+Major improvements:
+* Add [Babel](https://babeljs.io) to the webpack build
+
+Minor improvements:
+* Add `apply` tag ([#656](https://github.com/twigjs/twig.js/pull/656) by [@maxhelias](https://github.com/maxhelias))
+* Add `spaceless` filter ([#655](https://github.com/twigjs/twig.js/pull/655) by [@maxhelias](https://github.com/maxhelias))
+* Add `deprecated` tag ([#675](https://github.com/twigjs/twig.js/pull/675) by [@josephineb](https://github.com/josephineb))
+* Fix `starts with` and `ends with` expressions ([#661](https://github.com/twigjs/twig.js/pull/661) by [@ilkkave](https://github.com/ilkkave))
+* Add `package.json` license field to fix npm warning ([#672](https://github.com/twigjs/twig.js/pull/672) by [@WietseWind](https://github.com/WietseWind))
+* Update `strict_variables` option to match Twig's strict messages ([#674](https://github.com/twigjs/twig.js/pull/674) by [@toptalo](https://github.com/toptalo))
+* Fix `??` operator when used with arrays to return the array rather than its length ([#653](https://github.com/twigjs/twig.js/pull/653) by [@diegorales](https://github.com/diegomorales))
+
+Version 1.13.3, released 2019-05-03
+-----------------------------------
+Minor improvements:
+* Allow project development on Windows ([#611](https://github.com/twigjs/twig.js/pull/611))
+* Add possibility to define namespace without slash at the end of the path ([#609](https://github.com/twigjs/twig.js/pull/609))
+* Update `verbatim` tag ([#584](https://github.com/twigjs/twig.js/pull/584))
+
+Version 1.13.2, released 2019-01-22
+-----------------------------------
+Minor improvements:
+* fix for not autoescaping includes having a parent ([#606](https://github.com/twigjs/twig.js/pull/606))
+
+Version 1.13.1, released 2019-01-19
+-----------------------------------
+Minor improvements:
+* Fix for not autoescaping includes ([#604](https://github.com/twigjs/twig.js/pull/604))
+
+Version 1.13.0, released 2019-01-09
+-----------------------------------
+
+Major improvements:
+* Unminified sources in the npm package ([#598](https://github.com/twigjs/twig.js/pull/598))
+
+Minor improvements:
+* Multiple namespace performance improvement ([#580](https://github.com/twigjs/twig.js/pull/580))
+* `|url_encode` can now extend parameters ([#588](https://github.com/twigjs/twig.js/pull/588))
+* Fix `.startsWith` and `.endsWith` with `.indexOf` for IE ([#587](https://github.com/twigjs/twig.js/pull/587))
+* Autoescaping improvement ([#577](https://github.com/twigjs/twig.js/pull/577))
+* Support null-coalescing operator `??` ([#575](https://github.com/twigjs/twig.js/pull/575))
+* Add `verbatim` tag ([#574](https://github.com/twigjs/twig.js/pull/574))
+* Fix bug in `for` loop ([#573](https://github.com/twigjs/twig.js/pull/573))
+* Fix twig `{% if(x) %}` and `{% elseif(x) %}` blocks parsing error ([#570](https://github.com/twigjs/twig.js/pull/570))
+
+Version 1.12.0, released 2018-06-11
+-----------------------------------
+
+Major improvements:
+* Fix array declaration on multiple lines (#546)
+* Fix extend when add is null (#559)
+
+Minor improvements:
+* Improve namespaces support (#556)
+* Allow express to render async (#558)
+
+Version 1.11.1, released 2018-05-22
+-----------------------------------
+
+Major improvements:
+* Upgrade to Webpack 4 (#542)
+* Fix embed blocks logic (#537)
+
+Minor improvements:
+* Improve detection of when a block is in a loop (#541)
+* Add possibility to set default value for a macro parameter (#544)
+
+Version 1.11.0, released 2018-04-10
+-----------------------------------
+
+Major improvements:
+* Add support for 'with' tag (#497)
+* Add date support for json_encode filter (#515)
+* Fix 'embed' tag options (#534)
+* Performance improvements when including templates (#492)
+
+Minor improvements:
+* Fix incorrect 'and' and 'or' behaviour when comparing variables (#481)
+* Remove 'trim' filter autoescape (#488)
+* Fix empty output from loop with async call (#538)
+* Add allowable tags to strip tags filter (#524)
+
+
+Version 1.10.5, released 2017-05-24
+-----------------------------------
+
+Minor improvements:
+* Template id is now returned as part of the error when an exception is thrown (#464)
+* Test result no longer dependent on the name of the test file (#465)
+* Fix unexpected 'const' (#471)
+
+Version 1.10.4, released 2017-03-02
+-----------------------------------
+
+Minor improvements:
+* Fixed missing changelog updates
+
+Version 1.10.3, released 2017-03-02
+-----------------------------------
+
+Major improvements:
+* Async rendering and filters (#457)
+* From aliases (#438)
+* Bitwise operators (#443)
+* Fix object method context (#455)
+
+Minor improvements:
+* Readme updates (#454)
+* 'not' unary can be more widely used (#444)
+* Fix `importFile` relative path handling (#449)
+
+Version 0.10.3, released 2016-12-09
+-----------------------------------
+Minor improvements:
+* Spaceless tag no longer escapes Static values (#435)
+* Inline includes now load (#433)
+* Errors during async fs loading use error callback (#431)
+
+Version 0.10.2, released 2016-11-23
+-----------------------------------
+Minor improvements:
+* Support 'same as' (#429)
+* Fix windows colon colon namespace (#430)
+
+Version 0.10.1, released 2016-11-18
+-----------------------------------
+
+Minor improvements:
+* Fixed missing changelog updates
+* Fixed incorrect versions in source
+* Rethrow errors when option to do so is set (#422)
+
+Version 0.10.0, released 2016-10-28
+-----------------------------------
+Bower is no longer supported
+
+Major improvements:
+* Updated to locutus which replaces phpjs
+* elseif now accepts truthy values (#370)
+* Use PHP style falsy matching (#383)
+* Fix 'not' after binary expressions (#385)
+* Use current context when parsing an include (#395)
+* Correct handling of 'ignore missing' in embed and include (#424)
+
+Minor improvements:
+* Documentation updates
+* Refreshed dependencies
+
+Version 0.9.5, released 2016-05-14
+-----------------------------------
+
+Minor improvements:
+* Templates that are included via "extends" now populate the parent template context
+
+Version 0.9.4, released 2016-05-13
+-----------------------------------
+Parentheses parsing has undergone quite a large refactoring, but nothing should have explicitly broken.
+
+Major improvements:
+* Subexpressions are now supported and parsed differently from function parameters
+
+Version 0.9.3, released 2016-05-12
+-----------------------------------
+Fix missing changelog updates
+
+Version 0.9.2, released 2016-05-12
+-----------------------------------
+Minor improvements:
+* Empty strings can now be passed to the date filter
+* Twig.expression.resolve keeps the correct context for `this`
+
+Version 0.9.1, released 2016-05-10
+-----------------------------------
+Fixed changelog versioning
+
+Version 0.9.0, released 2016-05-10
+-----------------------------------
+Theoretically no breaking changes, but lots of things have changed so it is possible something has slipped through.
+
+Dependencies have been updated. You should run `npm install` to update these.
+
+Major improvements:
+* Webpack is now used for builds
+* phpjs is now a dependency and replaces our reimplementation of PHP functions (#343)
+* Arrays are now cast to booleans unless accessing their contents
+* in/not in operator precedence changed (#344)
+* Expressions can now be keys (#350)
+* The extended ternary operator is now supported (#354)
+* Expressions can now appear after period accessor (#356)
+* The slice shorthand is now supported (#362)
+
+Minor improvements:
+* Twig.exports.renderFile now returns a string rather than a String (#348)
+* The value of context is now cloned when setting a variable to context (#345)
+* Negative numbers are now correctly parsed (#353)
+* The // operator now works correctly (#353)
+
+
+Version 0.8.9, released 2016-03-18
+-----------------------------
+Dependencies have been updated to current versions. You should run `npm install` to update these. (#313)
+
+Major improvements:
+* Twig's `source` function is now supported (#309)
+* It is possible to add additional parsers using Twig.Templates.registerParser() (currently available: twig, source). If you are using a custom loader, please investigate src/twig.loader.fs.js how to call the requested parser. (#309)
+* `undefined` and `null` values now supported in the `in` operator (#311)
+* Namespaces can now be defined using the '@' symbol (#328)
+
+Minor improvements:
+* Undefined object properties now have the value of `undefined` rather than `null` (#311)
+* Improved browser tests (#325, #310)
+* IE8 fix (#324)
+* Path resolution has been refactored to its own module (#323)
+
+Version 0.8.8, released 2016-02-13
+----------------------------------
+Major improvements:
+* Support for [block shortcuts](http://twig.sensiolabs.org/doc/tags/extends.html#block-shortcuts): `{% block title page_title|title %}` (#304)
+* Define custom template loaders, by registering them via `Twig.Templates.registerLoader()` (#301)
+
+Minor improvements:
+* Some mocha tests didn't work in browsers (#281)
+* Fix Twig.renderFile (#303)
+
+[All issues of this milestone](https://github.com/justjohn/twig.js/issues?q=milestone%3A0.8.8)
+
+Version 0.8.7, released 2016-01-20
+----------------------------------
+Major improvements:
+* The `autoescape` option now supports all strategies which are supported by the `escape` filter (#299)
+
+Minor improvements:
+* The `date` filter now recognises unix timestamps as input, when they are passed as string (#296)
+* The `default` filter now allows to be called without parameters (it will return an empty string in that case) (#295)
+* Normalize provided template paths (this generated problems when using nodejs under Windows) (#252, #300)
+
+Version 0.8.6, released 2016-01-05
+----------------------------------
+Major improvements:
+* The `escape` filter now supports the strategy parameter: `{{ var|escape('css') }}` with the following available strategies: html (default), js, css, url, html_attr. (#289)
+
+Minor improvements:
+* The filter `url_encode` now also encodes apostrophe (as in Twig.php) (#288)
+* Minor bugfixes (#290, #291)
+
+Version 0.8.5, released 2015-12-24
+----------------------------------
+From 0.8.5 on, a summary of changes between each version will be included in the CHANGELOG.md file.
+
+There were some changes to the [Contribution guidelines](https://github.com/justjohn/twig.js/wiki/Contributing): please commit only changes to source files, the files `twig.js` and `twig.min.js` will be rebuilt when a new version gets released. Therefore you need to run `make` after cloning resp. pulling (if you want to use the development version).
+
+Major improvements:
+* Implement `min` and `max` functions (#164)
+* Support for the whitespace control modifier: `{{- -}}` (#266)
+* `sort` filter: try to cast values to match type (numeric values to number, string otherwise) (#278)
+* Support for twig namespaces (#195, #251)
+* Support for expressions as object keys: `{% set foo = { (1 + 1): 'bar' } %}` (#284)
+
+Minor improvements:
+* Allow integer 0 as key in objects: `{ 0: "value" }` (#186)
+* `json_encode` filter: always return objects in order of keys, also ignore the internal key `_keys` for nested objects (#279)
+* `date` filter: update to current strtotime() function from phpjs: now support ISO8601 dates as input on Mozilla Firefox. (#276)
+* Validate template IDs only when caching is enabled (#233, #259)
+* Support xmlhttp.status==0 when using cordova (#240)
+* Improved sub template file loading (#264)
+* Ignore quotes between `{% raw %}` and `{% endraw %}` (#286)
diff --git a/LICENSE b/LICENSE
index e4e6ec0b..f2911cd3 100644
--- a/LICENSE
+++ b/LICENSE
@@ -1,4 +1,4 @@
-Copyright (c) 2011-2013, John Roepke
+Copyright (c) 2011-2015, John Roepke and the Twig.js Contributors
All rights reserved.
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
@@ -6,4 +6,5 @@ Redistribution and use in source and binary forms, with or without modification,
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.
-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 HOLDER 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
+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 HOLDER 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.
+
diff --git a/Makefile b/Makefile
deleted file mode 100644
index 11159e5f..00000000
--- a/Makefile
+++ /dev/null
@@ -1,59 +0,0 @@
-SRC = src/twig.header.js src/twig.core.js src/twig.fills.js src/twig.lib.js src/twig.logic.js src/twig.expression.js src/twig.expression.operator.js src/twig.filters.js src/twig.functions.js src/twig.tests.js src/twig.exports.js src/twig.compiler.js src/twig.module.js
-
-TESTS = test/*.js
-TESTSEXT = test-ext/*.js
-REPORTER = spec
-
-UGLIFY = ./node_modules/uglify-js/bin/uglifyjs
-DOCCO = ./node_modules/docco/bin/docco
-MOCHA = ./node_modules/mocha/bin/mocha
-
-all: twig.js twig.min.js
-
-test:
- @NODE_ENV=test $(MOCHA) \
- --require should \
- --reporter $(REPORTER) \
- --timeout 100 \
- --growl \
- $(TESTS)
-
-twig.php:
- ./test-ext/checkout.sh
-
-testphp: twig.php
- @NODE_ENV=test $(MOCHA) \
- --require should \
- --reporter $(REPORTER) \
- --timeout 100 \
- --growl \
- $(TESTSEXT)
-
-twig.js: $(SRC)
- cat $^ > $@
- cp $@ demos/node_express/public/vendor/
- cp $@ demos/twitter_backbone/vendor/
-
-twig.min.js: twig.js
- $(UGLIFY) \
- --source-map $@.map \
- --comments "@license" \
- $< > $@
-
-docs: test-docs annotated-docs
-
-test-docs:
- @NODE_ENV=test $(MOCHA) \
- --require should \
- --reporter markdown \
- --timeout 100 \
- --growl \
- $(TESTS) > docs/tests.md
-
-annotated-docs: $(SRC)
- $(DOCCO) twig.js
-
-clean:
- rm -f twig.min.js twig.js
-
-.PHONY: test text-ext docs test-docs clean
diff --git a/README.md b/README.md
index 3c88b66a..12b3fffb 100644
--- a/README.md
+++ b/README.md
@@ -1,10 +1,16 @@
-[](http://travis-ci.org/#!/justjohn/twig.js)
-[](http://badge.fury.io/js/twig)
+[](https://snyk.io/test/github/twigjs/twig.js)
+[](http://travis-ci.org/twigjs/twig.js)
+[](http://badge.fury.io/js/twig)
+[](https://gitter.im/twigjs/twig.js?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge)
# About
+
+
Twig.js is a pure JavaScript implementation of the Twig PHP templating language
-( )
+( )
The goal is to provide a library that is compatible with both browsers and server side JavaScript environments such as node.js.
@@ -12,28 +18,30 @@ Twig.js is currently a work in progress and supports a limited subset of the Twi
### Docs
-Documentation is available in the [twig.js wiki](https://github.com/justjohn/twig.js/wiki) on Github.
+Documentation is available in the [twig.js wiki](https://github.com/twigjs/twig.js/wiki) on Github.
### Feature Support
-For a list of supported tags/filters/functions/tests see the [Implementation Notes](https://github.com/justjohn/twig.js/wiki/Implementation-Notes) page on the wiki.
+For a list of supported tags/filters/functions/tests see the [Implementation Notes](https://github.com/twigjs/twig.js/wiki/Implementation-Notes) page on the wiki.
-### Contributing
+# Install
-If you have a change you want to make to twig.js, feel free to fork this repository and submit a pull request on Github. The source files are located in src/*.js. twig.js is built by running `make`
+Download the latest twig.js release from github: https://github.com/twigjs/twig.js/releases or via NPM:
-For more details on getting setup, see the [contributing page](https://github.com/justjohn/twig.js/wiki/Contributing) on the wiki.
+```bash
+npm install twig --save
+```
-# Browser Usage
+# Bower
-Twig.js can be installed as a bower package with:
+A bower package is available from [philsbury](https://github.com/philsbury/twigjs-bower). Please direct any Bower support issues to that repo.
- bower install twig.js
+## Browser Usage
Include twig.js or twig.min.js in your page, then:
```js
-var template = twig({
+var template = Twig.twig({
data: 'The {{ baked_good }} is a lie.'
});
@@ -43,20 +51,37 @@ console.log(
// outputs: "The cupcake is a lie."
```
-# Node Usage
+## Webpack
+
+A loader is available from [zimmo.be](https://github.com/zimmo-be/twig-loader).
-Twig.js can be installed with NPM
+## Node Usage (npm)
- npm install twig
+Tested on node >=6.0.
You can use twig in your app with
- var Twig = require('twig'), // Twig module
- twig = Twig.twig; // Render function
+```js
+var Twig = require('twig'), // Twig module
+ twig = Twig.twig; // Render function
+```
+
+### Usage without Express
+
+If you don't want to use Express, you can render a template with the following method:
-Twig is compatable with express 2 and 3. You can create an express app using the twig.js templating language by setting the view engine to twig.
+```js
+import Twig from 'twig';
+Twig.renderFile('./path/to/someFile.twig', {foo:'bar'}, (err, html) => {
+ html; // compiled string
+});
+```
-## app.js
+### Usage with Express
+
+Twig is compatible with express 2 and 3. You can create an express app using the twig.js templating language by setting the view engine to twig.
+
+### app.js
**Express 3**
@@ -67,6 +92,7 @@ var Twig = require("twig"),
// This section is optional and used to configure twig.
app.set("twig options", {
+ allowAsync: true, // Allow asynchronous compiling
strict_variables: false
});
@@ -85,17 +111,32 @@ app.listen(9999);
Message of the moment: {{ message }}
```
-An [Express 2 Example](https://github.com/justjohn/twig.js/wiki/Express-2) is available on the wiki.
+An [Express 2 Example](https://github.com/twigjs/twig.js/wiki/Express-2) is available on the wiki.
+
+# Alternatives
+
+- [Twing](https://github.com/ericmorand/twing)
+
+# Contributing
+
+If you have a change you want to make to twig.js, feel free to fork this repository and submit a pull request on Github. The source files are located in `src/*.js`.
+
+twig.js is built by running `npm run build`
+
+For more details on getting setup, see the [contributing page](https://github.com/twigjs/twig.js/wiki/Contributing) on the wiki.
+
+## Environment Requirements
+When developing on Windows, the repository must be checked out **without** automatic conversion of LF to CRLF. Failure to do so will cause tests that would otherwise pass on Linux or Mac to fail instead.
-# Tests
+## Tests
-The twig.js tests are written in [Mocha][mocha] and can be invoked with `make test`.
+The twig.js tests are written in [Mocha][mocha] and can be invoked with `npm test`.
-# License
+## License
Twig.js is available under a [BSD 2-Clause License][bsd-2], see the LICENSE file for more information.
-# Acknowledgments
+## Acknowledgments
See the LICENSES.md file for copies of the referenced licenses.
@@ -116,5 +157,5 @@ See the LICENSES.md file for copies of the referenced licenses.
[bsd-3]: http://www.opensource.org/licenses/BSD-3-Clause
[cc-by-sa-2.5]: http://creativecommons.org/licenses/by-sa/2.5/ "Creative Commons Attribution-ShareAlike 2.5 License"
-[mocha]: http://visionmedia.github.com/mocha/
+[mocha]: http://mochajs.org/
[qunit]: http://docs.jquery.com/QUnit
diff --git a/bin/twigjs b/bin/twigjs
index cfacb852..291f5f71 100755
--- a/bin/twigjs
+++ b/bin/twigjs
@@ -24,7 +24,7 @@ while (args.length > 0) {
return;
case "--output":
case "-o":
- options.output = PATHS.strip_slash(args.shift());
+ options.output = PATHS.stripSlash(args.shift());
break;
case "--pattern":
case "-p":
diff --git a/bower.json b/bower.json
deleted file mode 100644
index 11393a3b..00000000
--- a/bower.json
+++ /dev/null
@@ -1,28 +0,0 @@
-{
- "name": "twig.js",
- "version": "0.7.2",
- "main": "twig.min.js",
- "ignore": [
- "Makefile",
- "src",
- "demos",
- "bin",
- "lib",
- "**/.*",
- "node_modules",
- "bower_components",
- "test",
- "test-ext"
- ],
- "homepage": "https://github.com/justjohn/twig.js",
- "authors": [
- "John Roepke "
- ],
- "description": "JS implementation of the Twig templating language.",
- "keywords": [
- "template",
- "engine",
- "twig"
- ],
- "license": "BSD 2-Clause"
-}
diff --git a/demos/node_express/.gitignore b/demos/node_express/.gitignore
new file mode 100644
index 00000000..483a9c42
--- /dev/null
+++ b/demos/node_express/.gitignore
@@ -0,0 +1 @@
+package-lock.json
\ No newline at end of file
diff --git a/demos/node_express/app.js b/demos/node_express/app.js
index a5ea3929..30934cd4 100644
--- a/demos/node_express/app.js
+++ b/demos/node_express/app.js
@@ -1,143 +1,139 @@
-var twig = require("../../twig")
- , _ = require("underscore")._
- , markdown = require("markdown")
- , express = require('express')
- , app = express.createServer();
+const twig = require('twig');
+const {_} = require('underscore');
+ const markdown = require('markdown');
+const express = require('express');
+const bodyParser = require('body-parser');
+const app = express();
// Generate some
function error_json(id, message) {
- return {
- error: true
- , id: id
- , message: message
- , json: true
- }
+ return {
+ error: true,
+ id,
+ message,
+ json: true
+ };
}
function update_note(body) {
- var title = body.title;
- var text = body.text;
- var id = body.id;
+ const {title} = body;
+ const {text} = body;
+ let {id} = body;
if (title) {
- if (id == "") {
+ if (id == '') {
// Get new ID and increment ID counter
id = id_ctr;
id_ctr++;
}
notes[id] = {
- title: title
- , text: text
- , id: id
+ title,
+ text,
+ id
};
- console.log("Adding/Updating note");
+ console.log('Adding/Updating note');
console.log(notes[id]);
}
-
}
// Some test data to pre-populate the notebook with
var id_ctr = 4;
var notes = {
1: {
- title: "Note"
- , text: "These could be your **notes**.\n\nBut you would have to turn this demo program into something beautiful."
- , id: 1
- }
- , 2: {
- title: "Templates"
- , text: "Templates are a way of enhancing content with markup. Or really anything that requires the merging of data and display."
- , id: 2
- }
- , 3: {
- title: "Tasks"
- , text: "* Wake Up\n* Drive to Work\n* Work\n* Drive Home\n* Sleep"
- , id: 3
+ title: 'Note',
+ text: 'These could be your **notes**.\n\nBut you would have to turn this demo program into something beautiful.',
+ id: 1
+ },
+ 2: {
+ title: 'Templates',
+ text: 'Templates are a way of enhancing content with markup. Or really anything that requires the merging of data and display.',
+ id: 2
+ },
+ 3: {
+ title: 'Tasks',
+ text: '* Wake Up\n* Drive to Work\n* Work\n* Drive Home\n* Sleep',
+ id: 3
}
};
-app.configure(function () {
- app.use(express.static(__dirname + '/public'));
- app.use(express.bodyParser());
- app.set('views', __dirname + '/public/views');
- app.set('view engine', 'twig');
- // We don't need express to use a parent "page" layout
- // Twig.js has support for this using the {% extends parent %} tag
- app.set("view options", { layout: false });
-});
-
-app.register('twig', twig);
+app.use(express.static(__dirname + '/public'));
+app.use(bodyParser());
+app.set('views', __dirname + '/public/views');
+app.set('view engine', 'twig');
+// We don't need express to use a parent "page" layout
+// Twig.js has support for this using the {% extends parent %} tag
+app.set('view options', {layout: false});
// Routing for the notebook
-app.get('/', function(req, res){
- res.render('pages/index', {
- message : "Hello World"
- });
+app.get('/', (req, res) => {
+ res.render('pages/index', {
+ message: 'Hello World'
+ });
});
-app.get('/add', function(req, res) {
- res.render('pages/note_form', {});
+app.get('/add', (req, res) => {
+ res.render('pages/note_form', {});
});
-app.get('/edit/:id', function(req, res) {
- var id = parseInt(req.params.id);
- var note = notes[id];
+app.get('/edit/:id', (req, res) => {
+ const id = parseInt(req.params.id);
+ const note = notes[id];
- res.render('pages/note_form', note);
+ res.render('pages/note_form', note);
});
-app.all('/notes', function(req, res) {
- update_note(req.body);
+app.all('/notes', (req, res) => {
+ update_note(req.body);
- res.render('pages/notes', {
- notes : notes
- });
+ res.render('pages/notes', {
+ notes
+ });
});
-app.all('/notes/:id', function(req, res) {
- update_note(req.body);
+app.all('/notes/:id', (req, res) => {
+ update_note(req.body);
- var id = parseInt(req.params.id);
- var note = notes[id];
+ const id = parseInt(req.params.id);
+ const note = notes[id];
- if (note) {
- note.markdown = markdown.markdown.toHTML( note.text );
+ if (note) {
+ note.markdown = markdown.markdown.toHTML(note.text);
res.render('pages/note', note);
- } else {
- res.render('pages/note_404');
- }
+ } else {
+ res.render('pages/note_404');
+ }
});
// RESTFUL endpoint for notes
-app.get('/api/notes', function(req, res) {
- res.json({
- notes : notes
- , json: true
- });
+app.get('/api/notes', (req, res) => {
+ res.json({
+ notes,
+ json: true
+ });
});
-app.get('/api/notes/:id', function(req, res) {
- var id = parseInt(req.params.id);
- var note = notes[id];
+app.get('/api/notes/:id', (req, res) => {
+ const id = parseInt(req.params.id);
+ const note = notes[id];
- if (note) {
- note.markdown = markdown.markdown.toHTML( note.text );
+ if (note) {
+ note.markdown = markdown.markdown.toHTML(note.text);
res.json(_.extend({
json: true
}, note));
- } else {
- res.json(error_json(41, "Unable to find note with id " + id))
- }
+ } else {
+ res.json(error_json(41, 'Unable to find note with id ' + id));
+ }
});
-var port = process.env.PORT || 9999,
- host = process.env.IP || "0.0.0.0";
+const port = process.env.PORT || 9999;
+const host = process.env.IP || '0.0.0.0';
app.listen(port, host);
-console.log("Express Twig.js Demo is running on " + host + ":" + port);
+console.log('Express Twig.js Demo is running on ' + host + ':' + port);
diff --git a/demos/node_express/package.json b/demos/node_express/package.json
index 9870a334..532b9510 100644
--- a/demos/node_express/package.json
+++ b/demos/node_express/package.json
@@ -1,25 +1,34 @@
{
"author": "John Roepke (http://johnroepke.com/)",
"name": "twig-demo-node",
+ "private": true,
"description": "Demo using node and twig.",
"version": "0.3.0",
- "homepage": "https://github.com/justjohn/twig.js",
+ "homepage": "https://github.com/twigjs/twig.js",
"licenses": [
- { "type": "BSD-2-Clause",
- "url": "https://raw.github.com/justjohn/twig.js/master/LICENSE" }
+ {
+ "type": "BSD-2-Clause",
+ "url": "https://raw.github.com/twigjs/twig.js/master/LICENSE"
+ }
],
+ "scripts": {
+ "install": "cd ../.. && npm it",
+ "start": "node app.js"
+ },
"repository": {
"type": "git",
- "url": "git://github.com/justjohn/twig.js.git"
+ "url": "git://github.com/twigjs/twig.js.git"
},
"main": "app.js",
"engines": {
"node": "*"
},
"dependencies": {
- "express": "2.5.x",
- "markdown": "0.3.x",
- "underscore": "1.3.x"
+ "body-parser": "^1.19.0",
+ "express": "4.17.x",
+ "markdown": "0.5.x",
+ "underscore": "1.9.x",
+ "twig": "file:../.."
},
"devDependencies": {}
}
diff --git a/demos/node_express/public/js/app.js b/demos/node_express/public/js/app.js
index 25dab8dd..81ae7d2a 100644
--- a/demos/node_express/public/js/app.js
+++ b/demos/node_express/public/js/app.js
@@ -1,123 +1,126 @@
// Notebook client code
Twig.cache = true;
-(function(window,undefined){
- var base = "/views/"
- api_base = "/api";
-
- crossroads.addRoute('/', function(){
+(function (window, undefined) {
+ const base = '/views/';
+ api_base = '/api';
+
+ crossroads.addRoute('/', () => {
// Load notes page
- var template = twig({ref: "index"})
- , output = template.render({json:true});
-
- $("#noteApp").html(output);
+ const template = twig({ref: 'index'});
+ const output = template.render({json: true});
+
+ $('#noteApp').html(output);
});
-
- crossroads.addRoute('/notes', function(){
+
+ crossroads.addRoute('/notes', () => {
// Load notes page
- var template = twig({ref: "notes"})
- , url = api_base + "/notes";
-
- $.getJSON(url, function(data) {
- var output = template.render(data);
- $("#noteApp").html(output);
+ const template = twig({ref: 'notes'});
+ const url = api_base + '/notes';
+
+ $.getJSON(url, data => {
+ const output = template.render(data);
+ $('#noteApp').html(output);
});
});
-
- crossroads.addRoute('/notes/{id}', function(id) {
+
+ crossroads.addRoute('/notes/{id}', id => {
// Load notes page
- var template = twig({ref: "note"})
- , error_template = twig({ref: "404"})
- , url = api_base + "/notes/" + id;
-
- $.getJSON(url, function(data) {
- var output;
+ const template = twig({ref: 'note'});
+ const error_template = twig({ref: '404'});
+ const url = api_base + '/notes/' + id;
+
+ $.getJSON(url, data => {
+ let output;
if (data.error) {
output = error_template.render(data);
} else {
output = template.render(data);
}
- $("#noteApp").html(output);
+
+ $('#noteApp').html(output);
});
});
-
- crossroads.addRoute('/add', function(){
+
+ crossroads.addRoute('/add', () => {
// Load notes page
- var template = twig({ref: "form"})
- , output = template.render({json:true});
-
- $("#noteApp").html(output);
+ const template = twig({ref: 'form'});
+ const output = template.render({json: true});
+
+ $('#noteApp').html(output);
});
-
- crossroads.addRoute('/edit/{id}', function(id) {
+
+ crossroads.addRoute('/edit/{id}', id => {
// Load notes page
- var template = twig({ref: "form"})
- , error_template = twig({ref: "404"})
- , url = api_base + "/notes/" + id;
-
- $.getJSON(url, function(data) {
- var output;
+ const template = twig({ref: 'form'});
+ const error_template = twig({ref: '404'});
+ const url = api_base + '/notes/' + id;
+
+ $.getJSON(url, data => {
+ let output;
if (data.error) {
output = error_template.render(data);
} else {
output = template.render(data);
}
- $("#noteApp").html(output);
+
+ $('#noteApp').html(output);
});
});
-
+
// Preload templates
- (function() {
- var loaded = 0
- , count = 5
- , inc_loaded = function() {
- loaded++;
- if (loaded == count) {
- // Flag as loaded, signal any waiting events
- }
+ (function () {
+ let loaded = 0;
+ const count = 5;
+ const inc_loaded = function () {
+ loaded++;
+ if (loaded == count) {
+ // Flag as loaded, signal any waiting events
}
- , pages = {
- "note": "pages/note.twig"
- , "notes": "pages/notes.twig"
- , "index": "pages/index.twig"
- , "form": "pages/note_form.twig"
- , "404": "pages/note_404.twig"
- };
-
+ };
+
+ const pages = {
+ note: 'pages/note.twig',
+ notes: 'pages/notes.twig',
+ index: 'pages/index.twig',
+ form: 'pages/note_form.twig',
+ 404: 'pages/note_404.twig'
+ };
+
for (id in pages) {
if (pages.hasOwnProperty(id)) {
twig({
- id: id
- , href: base + pages[id]
- , load: function() {
+ id,
+ href: base + pages[id],
+ load() {
inc_loaded();
}
- });
- };
+ });
+ }
}
})();
-
- var History = window.History;
+
+ const {History} = window;
// Don't bind AJAX events without history support
- if ( !History.enabled ) {
+ if (!History.enabled) {
return false;
}
- $(function() {
+ $(() => {
// Bind to StateChange Event
- History.Adapter.bind(window,'statechange',function(){ // Note: We are using statechange instead of popstate
- var State = History.getState()
- , hash = State.hash;
-
+ History.Adapter.bind(window, 'statechange', () => { // Note: We are using statechange instead of popstate
+ const State = History.getState();
+ const {hash} = State;
+
console.log(hash);
// Trigger router
crossroads.parse(hash);
});
// Bind to links
- $("a.ajax_link").live("click", function(event) {
+ $('a.ajax_link').live('click', function (event) {
event.preventDefault();
- var href = $(this).attr("href");
+ const href = $(this).attr('href');
History.pushState(null, null, href);
});
});
diff --git a/demos/node_express/public/vendor/jquery.history.js b/demos/node_express/public/vendor/jquery.history.js
index 8d4edcd2..dedbc20f 100644
--- a/demos/node_express/public/vendor/jquery.history.js
+++ b/demos/node_express/public/vendor/jquery.history.js
@@ -1 +1,480 @@
-window.JSON||(window.JSON={}),function(){function f(a){return a<10?"0"+a:a}function quote(a){return escapable.lastIndex=0,escapable.test(a)?'"'+a.replace(escapable,function(a){var b=meta[a];return typeof b=="string"?b:"\\u"+("0000"+a.charCodeAt(0).toString(16)).slice(-4)})+'"':'"'+a+'"'}function str(a,b){var c,d,e,f,g=gap,h,i=b[a];i&&typeof i=="object"&&typeof i.toJSON=="function"&&(i=i.toJSON(a)),typeof rep=="function"&&(i=rep.call(b,a,i));switch(typeof i){case"string":return quote(i);case"number":return isFinite(i)?String(i):"null";case"boolean":case"null":return String(i);case"object":if(!i)return"null";gap+=indent,h=[];if(Object.prototype.toString.apply(i)==="[object Array]"){f=i.length;for(c=0;c ")&&c[0]);return a>4?a:!1}();return a},m.isInternetExplorer=function(){var a=m.isInternetExplorer.cached=typeof m.isInternetExplorer.cached!="undefined"?m.isInternetExplorer.cached:Boolean(m.getInternetExplorerMajorVersion());return a},m.emulated={pushState:!Boolean(a.history&&a.history.pushState&&a.history.replaceState&&!/ Mobile\/([1-7][a-z]|(8([abcde]|f(1[0-8]))))/i.test(e.userAgent)&&!/AppleWebKit\/5([0-2]|3[0-2])/i.test(e.userAgent)),hashChange:Boolean(!("onhashchange"in a||"onhashchange"in d)||m.isInternetExplorer()&&m.getInternetExplorerMajorVersion()<8)},m.enabled=!m.emulated.pushState,m.bugs={setHash:Boolean(!m.emulated.pushState&&e.vendor==="Apple Computer, Inc."&&/AppleWebKit\/5([0-2]|3[0-3])/.test(e.userAgent)),safariPoll:Boolean(!m.emulated.pushState&&e.vendor==="Apple Computer, Inc."&&/AppleWebKit\/5([0-2]|3[0-3])/.test(e.userAgent)),ieDoubleCheck:Boolean(m.isInternetExplorer()&&m.getInternetExplorerMajorVersion()<8),hashEscape:Boolean(m.isInternetExplorer()&&m.getInternetExplorerMajorVersion()<7)},m.isEmptyObject=function(a){for(var b in a)return!1;return!0},m.cloneObject=function(a){var b,c;return a?(b=k.stringify(a),c=k.parse(b)):c={},c},m.getRootUrl=function(){var a=d.location.protocol+"//"+(d.location.hostname||d.location.host);if(d.location.port||!1)a+=":"+d.location.port;return a+="/",a},m.getBaseHref=function(){var a=d.getElementsByTagName("base"),b=null,c="";return a.length===1&&(b=a[0],c=b.href.replace(/[^\/]+$/,"")),c=c.replace(/\/+$/,""),c&&(c+="/"),c},m.getBaseUrl=function(){var a=m.getBaseHref()||m.getBasePageUrl()||m.getRootUrl();return a},m.getPageUrl=function(){var a=m.getState(!1,!1),b=(a||{}).url||d.location.href,c;return c=b.replace(/\/+$/,"").replace(/[^\/]+$/,function(a,b,c){return/\./.test(a)?a:a+"/"}),c},m.getBasePageUrl=function(){var a=d.location.href.replace(/[#\?].*/,"").replace(/[^\/]+$/,function(a,b,c){return/[^\/]$/.test(a)?"":a}).replace(/\/+$/,"")+"/";return a},m.getFullUrl=function(a,b){var c=a,d=a.substring(0,1);return b=typeof b=="undefined"?!0:b,/[a-z]+\:\/\//.test(a)||(d==="/"?c=m.getRootUrl()+a.replace(/^\/+/,""):d==="#"?c=m.getPageUrl().replace(/#.*/,"")+a:d==="?"?c=m.getPageUrl().replace(/[\?#].*/,"")+a:b?c=m.getBaseUrl()+a.replace(/^(\.\/)+/,""):c=m.getBasePageUrl()+a.replace(/^(\.\/)+/,"")),c.replace(/\#$/,"")},m.getShortUrl=function(a){var b=a,c=m.getBaseUrl(),d=m.getRootUrl();return m.emulated.pushState&&(b=b.replace(c,"")),b=b.replace(d,"/"),m.isTraditionalAnchor(b)&&(b="./"+b),b=b.replace(/^(\.\/)+/g,"./").replace(/\#$/,""),b},m.store={},m.idToState=m.idToState||{},m.stateToId=m.stateToId||{},m.urlToId=m.urlToId||{},m.storedStates=m.storedStates||[],m.savedStates=m.savedStates||[],m.normalizeStore=function(){m.store.idToState=m.store.idToState||{},m.store.urlToId=m.store.urlToId||{},m.store.stateToId=m.store.stateToId||{}},m.getState=function(a,b){typeof a=="undefined"&&(a=!0),typeof b=="undefined"&&(b=!0);var c=m.getLastSavedState();return!c&&b&&(c=m.createStateObject()),a&&(c=m.cloneObject(c),c.url=c.cleanUrl||c.url),c},m.getIdByState=function(a){var b=m.extractId(a.url),c;if(!b){c=m.getStateString(a);if(typeof m.stateToId[c]!="undefined")b=m.stateToId[c];else if(typeof m.store.stateToId[c]!="undefined")b=m.store.stateToId[c];else{for(;;){b=(new Date).getTime()+String(Math.random()).replace(/\D/g,"");if(typeof m.idToState[b]=="undefined"&&typeof m.store.idToState[b]=="undefined")break}m.stateToId[c]=b,m.idToState[b]=a}}return b},m.normalizeState=function(a){var b,c;if(!a||typeof a!="object")a={};if(typeof a.normalized!="undefined")return a;if(!a.data||typeof a.data!="object")a.data={};b={},b.normalized=!0,b.title=a.title||"",b.url=m.getFullUrl(m.unescapeString(a.url||d.location.href)),b.hash=m.getShortUrl(b.url),b.data=m.cloneObject(a.data),b.id=m.getIdByState(b),b.cleanUrl=b.url.replace(/\??\&_suid.*/,""),b.url=b.cleanUrl,c=!m.isEmptyObject(b.data);if(b.title||c)b.hash=m.getShortUrl(b.url).replace(/\??\&_suid.*/,""),/\?/.test(b.hash)||(b.hash+="?"),b.hash+="&_suid="+b.id;return b.hashedUrl=m.getFullUrl(b.hash),(m.emulated.pushState||m.bugs.safariPoll)&&m.hasUrlDuplicate(b)&&(b.url=b.hashedUrl),b},m.createStateObject=function(a,b,c){var d={data:a,title:b,url:c};return d=m.normalizeState(d),d},m.getStateById=function(a){a=String(a);var c=m.idToState[a]||m.store.idToState[a]||b;return c},m.getStateString=function(a){var b,c,d;return b=m.normalizeState(a),c={data:b.data,title:a.title,url:a.url},d=k.stringify(c),d},m.getStateId=function(a){var b,c;return b=m.normalizeState(a),c=b.id,c},m.getHashByState=function(a){var b,c;return b=m.normalizeState(a),c=b.hash,c},m.extractId=function(a){var b,c,d;return c=/(.*)\&_suid=([0-9]+)$/.exec(a),d=c?c[1]||a:a,b=c?String(c[2]||""):"",b||!1},m.isTraditionalAnchor=function(a){var b=!/[\/\?\.]/.test(a);return b},m.extractState=function(a,b){var c=null,d,e;return b=b||!1,d=m.extractId(a),d&&(c=m.getStateById(d)),c||(e=m.getFullUrl(a),d=m.getIdByUrl(e)||!1,d&&(c=m.getStateById(d)),!c&&b&&!m.isTraditionalAnchor(a)&&(c=m.createStateObject(null,null,e))),c},m.getIdByUrl=function(a){var c=m.urlToId[a]||m.store.urlToId[a]||b;return c},m.getLastSavedState=function(){return m.savedStates[m.savedStates.length-1]||b},m.getLastStoredState=function(){return m.storedStates[m.storedStates.length-1]||b},m.hasUrlDuplicate=function(a){var b=!1,c;return c=m.extractState(a.url),b=c&&c.id!==a.id,b},m.storeState=function(a){return m.urlToId[a.url]=a.id,m.storedStates.push(m.cloneObject(a)),a},m.isLastSavedState=function(a){var b=!1,c,d,e;return m.savedStates.length&&(c=a.id,d=m.getLastSavedState(),e=d.id,b=c===e),b},m.saveState=function(a){return m.isLastSavedState(a)?!1:(m.savedStates.push(m.cloneObject(a)),!0)},m.getStateByIndex=function(a){var b=null;return typeof a=="undefined"?b=m.savedStates[m.savedStates.length-1]:a<0?b=m.savedStates[m.savedStates.length+a]:b=m.savedStates[a],b},m.getHash=function(){var a=m.unescapeHash(d.location.hash);return a},m.unescapeString=function(b){var c=b,d;for(;;){d=a.unescape(c);if(d===c)break;c=d}return c},m.unescapeHash=function(a){var b=m.normalizeHash(a);return b=m.unescapeString(b),b},m.normalizeHash=function(a){var b=a.replace(/[^#]*#/,"").replace(/#.*/,"");return b},m.setHash=function(a,b){var c,e,f;return b!==!1&&m.busy()?(m.pushQueue({scope:m,callback:m.setHash,args:arguments,queue:b}),!1):(c=m.escapeHash(a),m.busy(!0),e=m.extractState(a,!0),e&&!m.emulated.pushState?m.pushState(e.data,e.title,e.url,!1):d.location.hash!==c&&(m.bugs.setHash?(f=m.getPageUrl(),m.pushState(null,null,f+"#"+c,!1)):d.location.hash=c),m)},m.escapeHash=function(b){var c=m.normalizeHash(b);return c=a.escape(c),m.bugs.hashEscape||(c=c.replace(/\%21/g,"!").replace(/\%26/g,"&").replace(/\%3D/g,"=").replace(/\%3F/g,"?")),c},m.getHashByUrl=function(a){var b=String(a).replace(/([^#]*)#?([^#]*)#?(.*)/,"$2");return b=m.unescapeHash(b),b},m.setTitle=function(a){var b=a.title,c;b||(c=m.getStateByIndex(0),c&&c.url===a.url&&(b=c.title||m.options.initialTitle));try{d.getElementsByTagName("title")[0].innerHTML=b.replace("<","<").replace(">",">").replace(" & "," & ")}catch(e){}return d.title=b,m},m.queues=[],m.busy=function(a){typeof a!="undefined"?m.busy.flag=a:typeof m.busy.flag=="undefined"&&(m.busy.flag=!1);if(!m.busy.flag){h(m.busy.timeout);var b=function(){var a,c,d;if(m.busy.flag)return;for(a=m.queues.length-1;a>=0;--a){c=m.queues[a];if(c.length===0)continue;d=c.shift(),m.fireQueueItem(d),m.busy.timeout=g(b,m.options.busyDelay)}};m.busy.timeout=g(b,m.options.busyDelay)}return m.busy.flag},m.busy.flag=!1,m.fireQueueItem=function(a){return a.callback.apply(a.scope||m,a.args||[])},m.pushQueue=function(a){return m.queues[a.queue||0]=m.queues[a.queue||0]||[],m.queues[a.queue||0].push(a),m},m.queue=function(a,b){return typeof a=="function"&&(a={callback:a}),typeof b!="undefined"&&(a.queue=b),m.busy()?m.pushQueue(a):m.fireQueueItem(a),m},m.clearQueue=function(){return m.busy.flag=!1,m.queues=[],m},m.stateChanged=!1,m.doubleChecker=!1,m.doubleCheckComplete=function(){return m.stateChanged=!0,m.doubleCheckClear(),m},m.doubleCheckClear=function(){return m.doubleChecker&&(h(m.doubleChecker),m.doubleChecker=!1),m},m.doubleCheck=function(a){return m.stateChanged=!1,m.doubleCheckClear(),m.bugs.ieDoubleCheck&&(m.doubleChecker=g(function(){return m.doubleCheckClear(),m.stateChanged||a(),!0},m.options.doubleCheckInterval)),m},m.safariStatePoll=function(){var b=m.extractState(d.location.href),c;if(!m.isLastSavedState(b))c=b;else return;return c||(c=m.createStateObject()),m.Adapter.trigger(a,"popstate"),m},m.back=function(a){return a!==!1&&m.busy()?(m.pushQueue({scope:m,callback:m.back,args:arguments,queue:a}),!1):(m.busy(!0),m.doubleCheck(function(){m.back(!1)}),n.go(-1),!0)},m.forward=function(a){return a!==!1&&m.busy()?(m.pushQueue({scope:m,callback:m.forward,args:arguments,queue:a}),!1):(m.busy(!0),m.doubleCheck(function(){m.forward(!1)}),n.go(1),!0)},m.go=function(a,b){var c;if(a>0)for(c=1;c<=a;++c)m.forward(b);else{if(!(a<0))throw new Error("History.go: History.go requires a positive or negative integer passed.");for(c=-1;c>=a;--c)m.back(b)}return m};if(m.emulated.pushState){var o=function(){};m.pushState=m.pushState||o,m.replaceState=m.replaceState||o}else m.onPopState=function(b,c){var e=!1,f=!1,g,h;return m.doubleCheckComplete(),g=m.getHash(),g?(h=m.extractState(g||d.location.href,!0),h?m.replaceState(h.data,h.title,h.url,!1):(m.Adapter.trigger(a,"anchorchange"),m.busy(!1)),m.expectedStateId=!1,!1):(e=m.Adapter.extractEventData("state",b,c)||!1,e?f=m.getStateById(e):m.expectedStateId?f=m.getStateById(m.expectedStateId):f=m.extractState(d.location.href),f||(f=m.createStateObject(null,null,d.location.href)),m.expectedStateId=!1,m.isLastSavedState(f)?(m.busy(!1),!1):(m.storeState(f),m.saveState(f),m.setTitle(f),m.Adapter.trigger(a,"statechange"),m.busy(!1),!0))},m.Adapter.bind(a,"popstate",m.onPopState),m.pushState=function(b,c,d,e){if(m.getHashByUrl(d)&&m.emulated.pushState)throw new Error("History.js does not support states with fragement-identifiers (hashes/anchors).");if(e!==!1&&m.busy())return m.pushQueue({scope:m,callback:m.pushState,args:arguments,queue:e}),!1;m.busy(!0);var f=m.createStateObject(b,c,d);return m.isLastSavedState(f)?m.busy(!1):(m.storeState(f),m.expectedStateId=f.id,n.pushState(f.id,f.title,f.url),m.Adapter.trigger(a,"popstate")),!0},m.replaceState=function(b,c,d,e){if(m.getHashByUrl(d)&&m.emulated.pushState)throw new Error("History.js does not support states with fragement-identifiers (hashes/anchors).");if(e!==!1&&m.busy())return m.pushQueue({scope:m,callback:m.replaceState,args:arguments,queue:e}),!1;m.busy(!0);var f=m.createStateObject(b,c,d);return m.isLastSavedState(f)?m.busy(!1):(m.storeState(f),m.expectedStateId=f.id,n.replaceState(f.id,f.title,f.url),m.Adapter.trigger(a,"popstate")),!0};if(f){try{m.store=k.parse(f.getItem("History.store"))||{}}catch(p){m.store={}}m.normalizeStore()}else m.store={},m.normalizeStore();m.Adapter.bind(a,"beforeunload",m.clearAllIntervals),m.Adapter.bind(a,"unload",m.clearAllIntervals),m.saveState(m.storeState(m.extractState(d.location.href,!0))),f&&(m.onUnload=function(){var a,b;try{a=k.parse(f.getItem("History.store"))||{}}catch(c){a={}}a.idToState=a.idToState||{},a.urlToId=a.urlToId||{},a.stateToId=a.stateToId||{};for(b in m.idToState){if(!m.idToState.hasOwnProperty(b))continue;a.idToState[b]=m.idToState[b]}for(b in m.urlToId){if(!m.urlToId.hasOwnProperty(b))continue;a.urlToId[b]=m.urlToId[b]}for(b in m.stateToId){if(!m.stateToId.hasOwnProperty(b))continue;a.stateToId[b]=m.stateToId[b]}m.store=a,m.normalizeStore(),f.setItem("History.store",k.stringify(a))},m.intervalList.push(i(m.onUnload,m.options.storeInterval)),m.Adapter.bind(a,"beforeunload",m.onUnload),m.Adapter.bind(a,"unload",m.onUnload));if(!m.emulated.pushState){m.bugs.safariPoll&&m.intervalList.push(i(m.safariStatePoll,m.options.safariPollInterval));if(e.vendor==="Apple Computer, Inc."||(e.appCodeName||"")==="Mozilla")m.Adapter.bind(a,"hashchange",function(){m.Adapter.trigger(a,"popstate")}),m.getHash()&&m.Adapter.onDomLoad(function(){m.Adapter.trigger(a,"hashchange")})}},m.init()}(window)
\ No newline at end of file
+window.JSON || (window.JSON = {}), (function () {
+ function f(a) {
+ return a < 10 ? '0' + a : a;
+ }
+
+ function quote(a) {
+ return escapable.lastIndex = 0, escapable.test(a) ? '"' + a.replace(escapable, a => {
+ const b = meta[a]; return typeof b === 'string' ? b : '\\u' + ('0000' + a.charCodeAt(0).toString(16)).slice(-4);
+ }) + '"' : '"' + a + '"';
+ }
+
+ function str(a, b) {
+ let c; let d; let e; let f; const g = gap; let h; let i = b[a]; i && typeof i === 'object' && typeof i.toJSON === 'function' && (i = i.toJSON(a)), typeof rep === 'function' && (i = rep.call(b, a, i)); switch (typeof i) {
+ case 'string': return quote(i); case 'number': return isFinite(i) ? String(i) : 'null'; case 'boolean': case 'null': return String(i); case 'object': if (!i) {
+ return 'null';
+ }
+
+ gap += indent, h = []; if (Object.prototype.toString.apply(i) === '[object Array]') {
+ f = i.length; for (c = 0; c < f; c += 1) {
+ h[c] = str(c, i) || 'null';
+ }
+
+ return e = h.length === 0 ? '[]' : (gap ? '[\n' + gap + h.join(',\n' + gap) + '\n' + g + ']' : '[' + h.join(',') + ']'), gap = g, e;
+ }
+
+ if (rep && typeof rep === 'object') {
+ f = rep.length; for (c = 0; c < f; c += 1) {
+ d = rep[c], typeof d === 'string' && (e = str(d, i), e && h.push(quote(d) + (gap ? ': ' : ':') + e));
+ }
+ } else {
+ for (d in i) {
+ Object.hasOwnProperty.call(i, d) && (e = str(d, i), e && h.push(quote(d) + (gap ? ': ' : ':') + e));
+ }
+ }
+
+ return e = h.length === 0 ? '{}' : (gap ? '{\n' + gap + h.join(',\n' + gap) + '\n' + g + '}' : '{' + h.join(',') + '}'), gap = g, e;
+ }
+ }
+
+ 'use strict', typeof Date.prototype.toJSON !== 'function' && (Date.prototype.toJSON = function (a) {
+ return isFinite(this.valueOf()) ? this.getUTCFullYear() + '-' + f(this.getUTCMonth() + 1) + '-' + f(this.getUTCDate()) + 'T' + f(this.getUTCHours()) + ':' + f(this.getUTCMinutes()) + ':' + f(this.getUTCSeconds()) + 'Z' : null;
+ }, String.prototype.toJSON = Number.prototype.toJSON = Boolean.prototype.toJSON = function (a) {
+ return this.valueOf();
+ }); const {JSON} = window; const cx = /[\u0000\u00AD\u0600-\u0604\u070F\u17B4\u17B5\u200C-\u200F\u2028-\u202F\u2060-\u206f\ufeff\ufff0-\uffff]/g; var escapable = /[\\\"\u0000-\u001F\u007F-\u009F\u00AD\u0600-\u0604\u070F\u17B4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g; let gap; let indent; var meta = {'\b': '\\b', '\t': '\\t', '\n': '\\n', '\f': '\\f', '\r': '\\r', '"': '\\"', '\\': '\\\\'}; let
+ rep; typeof JSON.stringify !== 'function' && (JSON.stringify = function (a, b, c) {
+ let d; gap = '', indent = ''; if (typeof c === 'number') {
+ for (d = 0; d < c; d += 1) {
+ indent += ' ';
+ }
+ } else {
+ typeof c === 'string' && (indent = c);
+ }
+
+ rep = b; if (!b || typeof b === 'function' || typeof b === 'object' && typeof b.length === 'number') {
+ return str('', {'': a});
+ }
+
+ throw new Error('JSON.stringify');
+ }), typeof JSON.parse !== 'function' && (JSON.parse = function (text, reviver) {
+ function walk(a, b) {
+ let c; let d; const e = a[b]; if (e && typeof e === 'object') {
+ for (c in e) {
+ Object.hasOwnProperty.call(e, c) && (d = walk(e, c), d !== undefined ? e[c] = d : delete e[c]);
+ }
+ }
+
+ return reviver.call(a, b, e);
+ }
+
+ let j; text = String(text), cx.lastIndex = 0, cx.test(text) && (text = text.replace(cx, a => {
+ return '\\u' + ('0000' + a.charCodeAt(0).toString(16)).slice(-4);
+ })); if (/^[\],:{}\s]*$/.test(text.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g, '@').replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g, ']').replace(/(?:^|:|,)(?:\s*\[)+/g, ''))) {
+ return j = eval('(' + text + ')'), typeof reviver === 'function' ? walk({'': j}, '') : j;
+ }
+
+ throw new SyntaxError('JSON.parse');
+ });
+})(), (function (a, b) {
+ 'use strict'; const c = a.History = a.History || {}; const d = a.jQuery; if (typeof c.Adapter !== 'undefined') {
+ throw new TypeError('History.js Adapter has already been loaded...');
+ }
+
+ c.Adapter = {bind(a, b, c) {
+ d(a).bind(b, c);
+ }, trigger(a, b, c) {
+ d(a).trigger(b, c);
+ }, extractEventData(a, c, d) {
+ const e = c && c.originalEvent && c.originalEvent[a] || d && d[a] || b; return e;
+ }, onDomLoad(a) {
+ d(a);
+ }}, typeof c.init !== 'undefined' && c.init();
+})(window), (function (a, b) {
+ 'use strict'; const c = a.document; var d = a.setTimeout || d; var e = a.clearTimeout || e; var f = a.setInterval || f; const g = a.History = a.History || {}; if (typeof g.initHtml4 !== 'undefined') {
+ throw new TypeError('History.js HTML4 Support has already been loaded...');
+ }
+
+ g.initHtml4 = function () {
+ if (typeof g.initHtml4.initialized !== 'undefined') {
+ return !1;
+ }
+
+ g.initHtml4.initialized = !0, g.enabled = !0, g.savedHashes = [], g.isLastHash = function (a) {
+ const b = g.getHashByIndex(); let c; return c = a === b, c;
+ }, g.saveHash = function (a) {
+ return g.isLastHash(a) ? !1 : (g.savedHashes.push(a), !0);
+ }, g.getHashByIndex = function (a) {
+ let b = null; return typeof a === 'undefined' ? b = g.savedHashes[g.savedHashes.length - 1] : (a < 0 ? b = g.savedHashes[g.savedHashes.length + a] : b = g.savedHashes[a]), b;
+ }, g.discardedHashes = {}, g.discardedStates = {}, g.discardState = function (a, b, c) {
+ const d = g.getHashByState(a); let e; return e = {discardedState: a, backState: c, forwardState: b}, g.discardedStates[d] = e, !0;
+ }, g.discardHash = function (a, b, c) {
+ const d = {discardedHash: a, backState: c, forwardState: b}; return g.discardedHashes[a] = d, !0;
+ }, g.discardedState = function (a) {
+ const b = g.getHashByState(a); let c; return c = g.discardedStates[b] || !1, c;
+ }, g.discardedHash = function (a) {
+ const b = g.discardedHashes[a] || !1; return b;
+ }, g.recycleState = function (a) {
+ const b = g.getHashByState(a); return g.discardedState(a) && delete g.discardedStates[b], !0;
+ }, g.emulated.hashChange && (g.hashChangeInit = function () {
+ g.checkerFunction = null; let b = ''; let d; let e; let h; let i; return g.isInternetExplorer() ? (d = 'historyjs-iframe', e = c.createElement('iframe'), e.setAttribute('id', d), e.style.display = 'none', c.body.appendChild(e), e.contentWindow.document.open(), e.contentWindow.document.close(), h = '', i = !1, g.checkerFunction = function () {
+ if (i) {
+ return !1;
+ }
+
+ i = !0; const c = g.getHash() || ''; let d = g.unescapeHash(e.contentWindow.document.location.hash) || ''; return c !== b ? (b = c, d !== c && (h = d = c, e.contentWindow.document.open(), e.contentWindow.document.close(), e.contentWindow.document.location.hash = g.escapeHash(c)), g.Adapter.trigger(a, 'hashchange')) : d !== h && (h = d, g.setHash(d, !1)), i = !1, !0;
+ }) : g.checkerFunction = function () {
+ const c = g.getHash(); return c !== b && (b = c, g.Adapter.trigger(a, 'hashchange')), !0;
+ }, g.intervalList.push(f(g.checkerFunction, g.options.hashChangeInterval)), !0;
+ }, g.Adapter.onDomLoad(g.hashChangeInit)), g.emulated.pushState && (g.onHashChange = function (b) {
+ const d = b && b.newURL || c.location.href; const e = g.getHashByUrl(d); let f = null; let h = null; const i = null; let j; return g.isLastHash(e) ? (g.busy(!1), !1) : (g.doubleCheckComplete(), g.saveHash(e), e && g.isTraditionalAnchor(e) ? (g.Adapter.trigger(a, 'anchorchange'), g.busy(!1), !1) : (f = g.extractState(g.getFullUrl(e || c.location.href, !1), !0), g.isLastSavedState(f) ? (g.busy(!1), !1) : (h = g.getHashByState(f), j = g.discardedState(f), j ? (g.getHashByIndex(-2) === g.getHashByState(j.forwardState) ? g.back(!1) : g.forward(!1), !1) : (g.pushState(f.data, f.title, f.url, !1), !0))));
+ }, g.Adapter.bind(a, 'hashchange', g.onHashChange), g.pushState = function (b, d, e, f) {
+ if (g.getHashByUrl(e)) {
+ throw new Error('History.js does not support states with fragement-identifiers (hashes/anchors).');
+ }
+
+ if (f !== !1 && g.busy()) {
+ return g.pushQueue({scope: g, callback: g.pushState, args: arguments, queue: f}), !1;
+ }
+
+ g.busy(!0); const h = g.createStateObject(b, d, e); const i = g.getHashByState(h); const j = g.getState(!1); const k = g.getHashByState(j); const l = g.getHash(); return g.storeState(h), g.expectedStateId = h.id, g.recycleState(h), g.setTitle(h), i === k ? (g.busy(!1), !1) : (i !== l && i !== g.getShortUrl(c.location.href) ? (g.setHash(i, !1), !1) : (g.saveState(h), g.Adapter.trigger(a, 'statechange'), g.busy(!1), !0));
+ }, g.replaceState = function (a, b, c, d) {
+ if (g.getHashByUrl(c)) {
+ throw new Error('History.js does not support states with fragement-identifiers (hashes/anchors).');
+ }
+
+ if (d !== !1 && g.busy()) {
+ return g.pushQueue({scope: g, callback: g.replaceState, args: arguments, queue: d}), !1;
+ }
+
+ g.busy(!0); const e = g.createStateObject(a, b, c); const f = g.getState(!1); const h = g.getStateByIndex(-2); return g.discardState(f, e, h), g.pushState(e.data, e.title, e.url, !1), !0;
+ }), g.emulated.pushState && g.getHash() && !g.emulated.hashChange && g.Adapter.onDomLoad(() => {
+ g.Adapter.trigger(a, 'hashchange');
+ });
+ }, typeof g.init !== 'undefined' && g.init();
+})(window), (function (a, b) {
+ 'use strict'; const c = a.console || b; const d = a.document; const e = a.navigator; const f = a.sessionStorage || !1; const g = a.setTimeout; const h = a.clearTimeout; const i = a.setInterval; const j = a.clearInterval; const k = a.JSON; const l = a.alert; const m = a.History = a.History || {}; const n = a.history; k.stringify = k.stringify || k.encode, k.parse = k.parse || k.decode; if (typeof m.init !== 'undefined') {
+ throw new TypeError('History.js Core has already been loaded...');
+ }
+
+ m.init = function () {
+ return typeof m.Adapter === 'undefined' ? !1 : (typeof m.initCore !== 'undefined' && m.initCore(), typeof m.initHtml4 !== 'undefined' && m.initHtml4(), !0);
+ }, m.initCore = function () {
+ if (typeof m.initCore.initialized !== 'undefined') {
+ return !1;
+ }
+
+ m.initCore.initialized = !0, m.options = m.options || {}, m.options.hashChangeInterval = m.options.hashChangeInterval || 100, m.options.safariPollInterval = m.options.safariPollInterval || 500, m.options.doubleCheckInterval = m.options.doubleCheckInterval || 500, m.options.storeInterval = m.options.storeInterval || 1e3, m.options.busyDelay = m.options.busyDelay || 250, m.options.debug = m.options.debug || !1, m.options.initialTitle = m.options.initialTitle || d.title, m.intervalList = [], m.clearAllIntervals = function () {
+ let a; const b = m.intervalList; if (typeof b !== 'undefined' && b !== null) {
+ for (a = 0; a < b.length; a++) {
+ j(b[a]);
+ }
+
+ m.intervalList = null;
+ }
+ }, m.debug = function () {
+ (m.options.debug || !1) && m.log.apply(m, arguments);
+ }, m.log = function () {
+ const a = typeof c !== 'undefined' && typeof c.log !== 'undefined' && typeof c.log.apply !== 'undefined'; const b = d.querySelector('#log'); let e; let f; let g; let h; let i; a ? (h = Array.prototype.slice.call(arguments), e = h.shift(), typeof c.debug !== 'undefined' ? c.debug.apply(c, [e, h]) : c.log.apply(c, [e, h])) : e = '\n' + arguments[0] + '\n'; for (f = 1, g = arguments.length; f < g; ++f) {
+ i = arguments[f]; if (typeof i === 'object' && typeof k !== 'undefined') {
+ try {
+ i = k.stringify(i);
+ } catch (error) {}
+ }
+
+ e += '\n' + i + '\n';
+ }
+
+ return b ? (b.value += e + '\n-----\n', b.scrollTop = b.scrollHeight - b.clientHeight) : a || l(e), !0;
+ }, m.getInternetExplorerMajorVersion = function () {
+ const a = m.getInternetExplorerMajorVersion.cached = typeof m.getInternetExplorerMajorVersion.cached !== 'undefined' ? m.getInternetExplorerMajorVersion.cached : (function () {
+ let a = 3; const b = d.createElement('div'); const c = b.querySelectorAll('i'); while ((b.innerHTML = '') && c[0]) {
+
+ }
+
+ return a > 4 ? a : !1;
+ })(); return a;
+ }, m.isInternetExplorer = function () {
+ const a = m.isInternetExplorer.cached = typeof m.isInternetExplorer.cached !== 'undefined' ? m.isInternetExplorer.cached : Boolean(m.getInternetExplorerMajorVersion()); return a;
+ }, m.emulated = {pushState: !(a.history && a.history.pushState && a.history.replaceState && !/ Mobile\/([1-7][a-z]|(8([abcde]|f(1[0-8]))))/i.test(e.userAgent) && !/AppleWebKit\/5([0-2]|3[0-2])/i.test(e.userAgent)), hashChange: Boolean(!('onhashchange' in a || 'onhashchange' in d) || m.isInternetExplorer() && m.getInternetExplorerMajorVersion() < 8)}, m.enabled = !m.emulated.pushState, m.bugs = {setHash: Boolean(!m.emulated.pushState && e.vendor === 'Apple Computer, Inc.' && /AppleWebKit\/5([0-2]|3[0-3])/.test(e.userAgent)), safariPoll: Boolean(!m.emulated.pushState && e.vendor === 'Apple Computer, Inc.' && /AppleWebKit\/5([0-2]|3[0-3])/.test(e.userAgent)), ieDoubleCheck: Boolean(m.isInternetExplorer() && m.getInternetExplorerMajorVersion() < 8), hashEscape: Boolean(m.isInternetExplorer() && m.getInternetExplorerMajorVersion() < 7)}, m.isEmptyObject = function (a) {
+ for (const b in a) {
+ return !1;
+ }
+
+ return !0;
+ }, m.cloneObject = function (a) {
+ let b; let c; return a ? (b = k.stringify(a), c = k.parse(b)) : c = {}, c;
+ }, m.getRootUrl = function () {
+ let a = d.location.protocol + '//' + (d.location.hostname || d.location.host); if (d.location.port || !1) {
+ a += ':' + d.location.port;
+ }
+
+ return a += '/', a;
+ }, m.getBaseHref = function () {
+ const a = d.querySelectorAll('base'); let b = null; let c = ''; return a.length === 1 && (b = a[0], c = b.href.replace(/[^\/]+$/, '')), c = c.replace(/\/+$/, ''), c && (c += '/'), c;
+ }, m.getBaseUrl = function () {
+ const a = m.getBaseHref() || m.getBasePageUrl() || m.getRootUrl(); return a;
+ }, m.getPageUrl = function () {
+ const a = m.getState(!1, !1); const b = (a || {}).url || d.location.href; let c; return c = b.replace(/\/+$/, '').replace(/[^\/]+$/, (a, b, c) => {
+ return /\./.test(a) ? a : a + '/';
+ }), c;
+ }, m.getBasePageUrl = function () {
+ const a = d.location.href.replace(/[#\?].*/, '').replace(/[^\/]+$/, (a, b, c) => {
+ return /[^\/]$/.test(a) ? '' : a;
+ }).replace(/\/+$/, '') + '/'; return a;
+ }, m.getFullUrl = function (a, b) {
+ let c = a; const d = a.slice(0, 1); return b = typeof b === 'undefined' ? !0 : b, /[a-z]+\:\/\//.test(a) || (d === '/' ? c = m.getRootUrl() + a.replace(/^\/+/, '') : d === '#' ? c = m.getPageUrl().replace(/#.*/, '') + a : d === '?' ? c = m.getPageUrl().replace(/[\?#].*/, '') + a : (b ? c = m.getBaseUrl() + a.replace(/^(\.\/)+/, '') : c = m.getBasePageUrl() + a.replace(/^(\.\/)+/, ''))), c.replace(/\#$/, '');
+ }, m.getShortUrl = function (a) {
+ let b = a; const c = m.getBaseUrl(); const d = m.getRootUrl(); return m.emulated.pushState && (b = b.replace(c, '')), b = b.replace(d, '/'), m.isTraditionalAnchor(b) && (b = './' + b), b = b.replace(/^(\.\/)+/g, './').replace(/\#$/, ''), b;
+ }, m.store = {}, m.idToState = m.idToState || {}, m.stateToId = m.stateToId || {}, m.urlToId = m.urlToId || {}, m.storedStates = m.storedStates || [], m.savedStates = m.savedStates || [], m.normalizeStore = function () {
+ m.store.idToState = m.store.idToState || {}, m.store.urlToId = m.store.urlToId || {}, m.store.stateToId = m.store.stateToId || {};
+ }, m.getState = function (a, b) {
+ typeof a === 'undefined' && (a = !0), typeof b === 'undefined' && (b = !0); let c = m.getLastSavedState(); return !c && b && (c = m.createStateObject()), a && (c = m.cloneObject(c), c.url = c.cleanUrl || c.url), c;
+ }, m.getIdByState = function (a) {
+ let b = m.extractId(a.url); let c; if (!b) {
+ c = m.getStateString(a); if (typeof m.stateToId[c] !== 'undefined') {
+ b = m.stateToId[c];
+ } else if (typeof m.store.stateToId[c] !== 'undefined') {
+ b = m.store.stateToId[c];
+ } else {
+ for (;;) {
+ b = (new Date()).getTime() + String(Math.random()).replace(/\D/g, ''); if (typeof m.idToState[b] === 'undefined' && typeof m.store.idToState[b] === 'undefined') {
+ break;
+ }
+ }
+
+ m.stateToId[c] = b, m.idToState[b] = a;
+ }
+ }
+
+ return b;
+ }, m.normalizeState = function (a) {
+ let b; let c; if (!a || typeof a !== 'object') {
+ a = {};
+ }
+
+ if (typeof a.normalized !== 'undefined') {
+ return a;
+ }
+
+ if (!a.data || typeof a.data !== 'object') {
+ a.data = {};
+ }
+
+ b = {}, b.normalized = !0, b.title = a.title || '', b.url = m.getFullUrl(m.unescapeString(a.url || d.location.href)), b.hash = m.getShortUrl(b.url), b.data = m.cloneObject(a.data), b.id = m.getIdByState(b), b.cleanUrl = b.url.replace(/\??\&_suid.*/, ''), b.url = b.cleanUrl, c = !m.isEmptyObject(b.data); if (b.title || c) {
+ b.hash = m.getShortUrl(b.url).replace(/\??\&_suid.*/, ''), /\?/.test(b.hash) || (b.hash += '?'), b.hash += '&_suid=' + b.id;
+ }
+
+ return b.hashedUrl = m.getFullUrl(b.hash), (m.emulated.pushState || m.bugs.safariPoll) && m.hasUrlDuplicate(b) && (b.url = b.hashedUrl), b;
+ }, m.createStateObject = function (a, b, c) {
+ let d = {data: a, title: b, url: c}; return d = m.normalizeState(d), d;
+ }, m.getStateById = function (a) {
+ a = String(a); const c = m.idToState[a] || m.store.idToState[a] || b; return c;
+ }, m.getStateString = function (a) {
+ let b; let c; let d; return b = m.normalizeState(a), c = {data: b.data, title: a.title, url: a.url}, d = k.stringify(c), d;
+ }, m.getStateId = function (a) {
+ let b; let c; return b = m.normalizeState(a), c = b.id, c;
+ }, m.getHashByState = function (a) {
+ let b; let c; return b = m.normalizeState(a), c = b.hash, c;
+ }, m.extractId = function (a) {
+ let b; let c; let d; return c = /(.*)\&_suid=([0-9]+)$/.exec(a), d = c ? c[1] || a : a, b = c ? String(c[2] || '') : '', b || !1;
+ }, m.isTraditionalAnchor = function (a) {
+ const b = !/[\/\?\.]/.test(a); return b;
+ }, m.extractState = function (a, b) {
+ let c = null; let d; let e; return b = b || !1, d = m.extractId(a), d && (c = m.getStateById(d)), c || (e = m.getFullUrl(a), d = m.getIdByUrl(e) || !1, d && (c = m.getStateById(d)), !c && b && !m.isTraditionalAnchor(a) && (c = m.createStateObject(null, null, e))), c;
+ }, m.getIdByUrl = function (a) {
+ const c = m.urlToId[a] || m.store.urlToId[a] || b; return c;
+ }, m.getLastSavedState = function () {
+ return m.savedStates[m.savedStates.length - 1] || b;
+ }, m.getLastStoredState = function () {
+ return m.storedStates[m.storedStates.length - 1] || b;
+ }, m.hasUrlDuplicate = function (a) {
+ let b = !1; let c; return c = m.extractState(a.url), b = c && c.id !== a.id, b;
+ }, m.storeState = function (a) {
+ return m.urlToId[a.url] = a.id, m.storedStates.push(m.cloneObject(a)), a;
+ }, m.isLastSavedState = function (a) {
+ let b = !1; let c; let d; let e; return m.savedStates.length && (c = a.id, d = m.getLastSavedState(), e = d.id, b = c === e), b;
+ }, m.saveState = function (a) {
+ return m.isLastSavedState(a) ? !1 : (m.savedStates.push(m.cloneObject(a)), !0);
+ }, m.getStateByIndex = function (a) {
+ let b = null; return typeof a === 'undefined' ? b = m.savedStates[m.savedStates.length - 1] : (a < 0 ? b = m.savedStates[m.savedStates.length + a] : b = m.savedStates[a]), b;
+ }, m.getHash = function () {
+ const a = m.unescapeHash(d.location.hash); return a;
+ }, m.unescapeString = function (b) {
+ let c = b; let d; for (;;) {
+ d = a.unescape(c); if (d === c) {
+ break;
+ }
+
+ c = d;
+ }
+
+ return c;
+ }, m.unescapeHash = function (a) {
+ let b = m.normalizeHash(a); return b = m.unescapeString(b), b;
+ }, m.normalizeHash = function (a) {
+ const b = a.replace(/[^#]*#/, '').replace(/#.*/, ''); return b;
+ }, m.setHash = function (a, b) {
+ let c; let e; let f; return b !== !1 && m.busy() ? (m.pushQueue({scope: m, callback: m.setHash, args: arguments, queue: b}), !1) : (c = m.escapeHash(a), m.busy(!0), e = m.extractState(a, !0), e && !m.emulated.pushState ? m.pushState(e.data, e.title, e.url, !1) : d.location.hash !== c && (m.bugs.setHash ? (f = m.getPageUrl(), m.pushState(null, null, f + '#' + c, !1)) : d.location.hash = c), m);
+ }, m.escapeHash = function (b) {
+ let c = m.normalizeHash(b); return c = a.escape(c), m.bugs.hashEscape || (c = c.replace(/\%21/g, '!').replace(/\%26/g, '&').replace(/\%3D/g, '=').replace(/\%3F/g, '?')), c;
+ }, m.getHashByUrl = function (a) {
+ let b = String(a).replace(/([^#]*)#?([^#]*)#?(.*)/, '$2'); return b = m.unescapeHash(b), b;
+ }, m.setTitle = function (a) {
+ let b = a.title; let c; b || (c = m.getStateByIndex(0), c && c.url === a.url && (b = c.title || m.options.initialTitle)); try {
+ d.querySelectorAll('title')[0].innerHTML = b.replace('<', '<').replace('>', '>').replace(' & ', ' & ');
+ } catch (error) {}
+
+ return d.title = b, m;
+ }, m.queues = [], m.busy = function (a) {
+ typeof a !== 'undefined' ? m.busy.flag = a : typeof m.busy.flag === 'undefined' && (m.busy.flag = !1); if (!m.busy.flag) {
+ h(m.busy.timeout); var b = function () {
+ let a; let c; let d; if (m.busy.flag) {
+ return;
+ }
+
+ for (a = m.queues.length - 1; a >= 0; --a) {
+ c = m.queues[a]; if (c.length === 0) {
+ continue;
+ }
+
+ d = c.shift(), m.fireQueueItem(d), m.busy.timeout = g(b, m.options.busyDelay);
+ }
+ };
+
+ m.busy.timeout = g(b, m.options.busyDelay);
+ }
+
+ return m.busy.flag;
+ }, m.busy.flag = !1, m.fireQueueItem = function (a) {
+ return a.callback.apply(a.scope || m, a.args || []);
+ }, m.pushQueue = function (a) {
+ return m.queues[a.queue || 0] = m.queues[a.queue || 0] || [], m.queues[a.queue || 0].push(a), m;
+ }, m.queue = function (a, b) {
+ return typeof a === 'function' && (a = {callback: a}), typeof b !== 'undefined' && (a.queue = b), m.busy() ? m.pushQueue(a) : m.fireQueueItem(a), m;
+ }, m.clearQueue = function () {
+ return m.busy.flag = !1, m.queues = [], m;
+ }, m.stateChanged = !1, m.doubleChecker = !1, m.doubleCheckComplete = function () {
+ return m.stateChanged = !0, m.doubleCheckClear(), m;
+ }, m.doubleCheckClear = function () {
+ return m.doubleChecker && (h(m.doubleChecker), m.doubleChecker = !1), m;
+ }, m.doubleCheck = function (a) {
+ return m.stateChanged = !1, m.doubleCheckClear(), m.bugs.ieDoubleCheck && (m.doubleChecker = g(() => {
+ return m.doubleCheckClear(), m.stateChanged || a(), !0;
+ }, m.options.doubleCheckInterval)), m;
+ }, m.safariStatePoll = function () {
+ const b = m.extractState(d.location.href); let c; if (!m.isLastSavedState(b)) {
+ c = b;
+ } else {
+ return;
+ }
+
+ return c || (c = m.createStateObject()), m.Adapter.trigger(a, 'popstate'), m;
+ }, m.back = function (a) {
+ return a !== !1 && m.busy() ? (m.pushQueue({scope: m, callback: m.back, args: arguments, queue: a}), !1) : (m.busy(!0), m.doubleCheck(() => {
+ m.back(!1);
+ }), n.go(-1), !0);
+ }, m.forward = function (a) {
+ return a !== !1 && m.busy() ? (m.pushQueue({scope: m, callback: m.forward, args: arguments, queue: a}), !1) : (m.busy(!0), m.doubleCheck(() => {
+ m.forward(!1);
+ }), n.go(1), !0);
+ }, m.go = function (a, b) {
+ let c; if (a > 0) {
+ for (c = 1; c <= a; ++c) {
+ m.forward(b);
+ }
+ } else {
+ if (!(a < 0)) {
+ throw new Error('History.go: History.go requires a positive or negative integer passed.');
+ }
+
+ for (c = -1; c >= a; --c) {
+ m.back(b);
+ }
+ }
+
+ return m;
+ };
+
+ if (m.emulated.pushState) {
+ const o = function () {}; m.pushState = m.pushState || o, m.replaceState = m.replaceState || o;
+ } else {
+ m.onPopState = function (b, c) {
+ let e = !1; let f = !1; let g; let h; return m.doubleCheckComplete(), g = m.getHash(), g ? (h = m.extractState(g || d.location.href, !0), h ? m.replaceState(h.data, h.title, h.url, !1) : (m.Adapter.trigger(a, 'anchorchange'), m.busy(!1)), m.expectedStateId = !1, !1) : (e = m.Adapter.extractEventData('state', b, c) || !1, e ? f = m.getStateById(e) : (m.expectedStateId ? f = m.getStateById(m.expectedStateId) : f = m.extractState(d.location.href)), f || (f = m.createStateObject(null, null, d.location.href)), m.expectedStateId = !1, m.isLastSavedState(f) ? (m.busy(!1), !1) : (m.storeState(f), m.saveState(f), m.setTitle(f), m.Adapter.trigger(a, 'statechange'), m.busy(!1), !0));
+ }, m.Adapter.bind(a, 'popstate', m.onPopState), m.pushState = function (b, c, d, e) {
+ if (m.getHashByUrl(d) && m.emulated.pushState) {
+ throw new Error('History.js does not support states with fragement-identifiers (hashes/anchors).');
+ }
+
+ if (e !== !1 && m.busy()) {
+ return m.pushQueue({scope: m, callback: m.pushState, args: arguments, queue: e}), !1;
+ }
+
+ m.busy(!0); const f = m.createStateObject(b, c, d); return m.isLastSavedState(f) ? m.busy(!1) : (m.storeState(f), m.expectedStateId = f.id, n.pushState(f.id, f.title, f.url), m.Adapter.trigger(a, 'popstate')), !0;
+ }, m.replaceState = function (b, c, d, e) {
+ if (m.getHashByUrl(d) && m.emulated.pushState) {
+ throw new Error('History.js does not support states with fragement-identifiers (hashes/anchors).');
+ }
+
+ if (e !== !1 && m.busy()) {
+ return m.pushQueue({scope: m, callback: m.replaceState, args: arguments, queue: e}), !1;
+ }
+
+ m.busy(!0); const f = m.createStateObject(b, c, d); return m.isLastSavedState(f) ? m.busy(!1) : (m.storeState(f), m.expectedStateId = f.id, n.replaceState(f.id, f.title, f.url), m.Adapter.trigger(a, 'popstate')), !0;
+ };
+ }
+
+ if (f) {
+ try {
+ m.store = k.parse(f.getItem('History.store')) || {};
+ } catch (error) {
+ m.store = {};
+ }
+
+ m.normalizeStore();
+ } else {
+ m.store = {}, m.normalizeStore();
+ }
+
+ m.Adapter.bind(a, 'beforeunload', m.clearAllIntervals), m.Adapter.bind(a, 'unload', m.clearAllIntervals), m.saveState(m.storeState(m.extractState(d.location.href, !0))), f && (m.onUnload = function () {
+ let a; let b; try {
+ a = k.parse(f.getItem('History.store')) || {};
+ } catch (error) {
+ a = {};
+ }
+
+ a.idToState = a.idToState || {}, a.urlToId = a.urlToId || {}, a.stateToId = a.stateToId || {}; for (b in m.idToState) {
+ if (!m.idToState.hasOwnProperty(b)) {
+ continue;
+ }
+
+ a.idToState[b] = m.idToState[b];
+ }
+
+ for (b in m.urlToId) {
+ if (!m.urlToId.hasOwnProperty(b)) {
+ continue;
+ }
+
+ a.urlToId[b] = m.urlToId[b];
+ }
+
+ for (b in m.stateToId) {
+ if (!m.stateToId.hasOwnProperty(b)) {
+ continue;
+ }
+
+ a.stateToId[b] = m.stateToId[b];
+ }
+
+ m.store = a, m.normalizeStore(), f.setItem('History.store', k.stringify(a));
+ }, m.intervalList.push(i(m.onUnload, m.options.storeInterval)), m.Adapter.bind(a, 'beforeunload', m.onUnload), m.Adapter.bind(a, 'unload', m.onUnload)); if (!m.emulated.pushState) {
+ m.bugs.safariPoll && m.intervalList.push(i(m.safariStatePoll, m.options.safariPollInterval)); if (e.vendor === 'Apple Computer, Inc.' || (e.appCodeName || '') === 'Mozilla') {
+ m.Adapter.bind(a, 'hashchange', () => {
+ m.Adapter.trigger(a, 'popstate');
+ }), m.getHash() && m.Adapter.onDomLoad(() => {
+ m.Adapter.trigger(a, 'hashchange');
+ });
+ }
+ }
+ }, m.init();
+})(window);
diff --git a/demos/node_express/public/vendor/twig.js b/demos/node_express/public/vendor/twig.js
index 2eebc11d..00914b98 100644
--- a/demos/node_express/public/vendor/twig.js
+++ b/demos/node_express/public/vendor/twig.js
@@ -1,19 +1,18 @@
/**
- * Twig.js 0.7.2
+ * Twig.js 0.8.9
*
- * @copyright 2011-2013 John Roepke
+ * @copyright 2011-2015 John Roepke and the Twig.js Contributors
* @license Available under the BSD 2-Clause License
* @link https://github.com/justjohn/twig.js
*/
var Twig = (function (Twig) {
- Twig.VERSION = "0.7.2";
+ Twig.VERSION = "0.8.9";
return Twig;
})(Twig || {});
// Twig.js
-// Copyright (c) 2011-2013 John Roepke
// Available under the BSD 2-Clause License
// https://github.com/justjohn/twig.js
@@ -132,6 +131,18 @@ var Twig = (function (Twig) {
// 8. return undefined
};
+ Twig.merge = function(target, source, onlyChanged) {
+ Twig.forEach(Object.keys(source), function (key) {
+ if (onlyChanged && !(key in target)) {
+ return;
+ }
+
+ target[key] = source[key]
+ });
+
+ return target;
+ };
+
/**
* Exception thrown by twig.js.
*/
@@ -155,18 +166,35 @@ var Twig = (function (Twig) {
*/
Twig.log = {
trace: function() {if (Twig.trace && console) {console.log(Array.prototype.slice.call(arguments));}},
- debug: function() {if (Twig.debug && console) {console.log(Array.prototype.slice.call(arguments));}},
+ debug: function() {if (Twig.debug && console) {console.log(Array.prototype.slice.call(arguments));}}
};
- if (typeof console !== "undefined" &&
- typeof console.log !== "undefined") {
- Twig.log.error = function() {
- console.log.apply(console, arguments);
+
+ if (typeof console !== "undefined") {
+ if (typeof console.error !== "undefined") {
+ Twig.log.error = function() {
+ console.error.apply(console, arguments);
+ }
+ } else if (typeof console.log !== "undefined") {
+ Twig.log.error = function() {
+ console.log.apply(console, arguments);
+ }
}
} else {
Twig.log.error = function(){};
}
+ /**
+ * Wrapper for child context objects in Twig.
+ *
+ * @param {Object} context Values to initialize the context with.
+ */
+ Twig.ChildContext = function(context) {
+ var ChildContext = function ChildContext() {};
+ ChildContext.prototype = context;
+ return new ChildContext();
+ };
+
/**
* Container for methods related to handling high level template tokens
* (for example: {{ expression }}, {% logic %}, {# comment #}, raw data)
@@ -177,10 +205,16 @@ var Twig = (function (Twig) {
* Token types.
*/
Twig.token.type = {
- output: 'output',
- logic: 'logic',
- comment: 'comment',
- raw: 'raw'
+ output: 'output',
+ logic: 'logic',
+ comment: 'comment',
+ raw: 'raw',
+ output_whitespace_pre: 'output_whitespace_pre',
+ output_whitespace_post: 'output_whitespace_post',
+ output_whitespace_both: 'output_whitespace_both',
+ logic_whitespace_pre: 'logic_whitespace_pre',
+ logic_whitespace_post: 'logic_whitespace_post',
+ logic_whitespace_both: 'logic_whitespace_both'
};
/**
@@ -192,6 +226,44 @@ var Twig = (function (Twig) {
open: '{% raw %}',
close: '{% endraw %}'
},
+ {
+ type: Twig.token.type.raw,
+ open: '{% verbatim %}',
+ close: '{% endverbatim %}'
+ },
+ // *Whitespace type tokens*
+ //
+ // These typically take the form `{{- expression -}}` or `{{- expression }}` or `{{ expression -}}`.
+ {
+ type: Twig.token.type.output_whitespace_pre,
+ open: '{{-',
+ close: '}}'
+ },
+ {
+ type: Twig.token.type.output_whitespace_post,
+ open: '{{',
+ close: '-}}'
+ },
+ {
+ type: Twig.token.type.output_whitespace_both,
+ open: '{{-',
+ close: '-}}'
+ },
+ {
+ type: Twig.token.type.logic_whitespace_pre,
+ open: '{%-',
+ close: '%}'
+ },
+ {
+ type: Twig.token.type.logic_whitespace_post,
+ open: '{%',
+ close: '-%}'
+ },
+ {
+ type: Twig.token.type.logic_whitespace_both,
+ open: '{%-',
+ close: '-%}'
+ },
// *Output type tokens*
//
// These typically take the form `{{ expression }}`.
@@ -228,25 +300,69 @@ var Twig = (function (Twig) {
Twig.token.findStart = function (template) {
var output = {
position: null,
+ close_position: null,
def: null
},
i,
token_template,
- first_key_position;
+ first_key_position,
+ close_key_position;
for (i=0;i= 0) {
+ //This token matches the template
+ if (token_template.open.length !== token_template.close.length) {
+ //This token has mismatched closing and opening tags
+ if (close_key_position < 0) {
+ //This token's closing tag does not match the template
+ continue;
+ }
+ }
+ }
// Does this token occur before any other types?
if (first_key_position >= 0 && (output.position === null || first_key_position < output.position)) {
output.position = first_key_position;
output.def = token_template;
+ output.close_position = close_key_position;
+ } else if (first_key_position >= 0 && output.position !== null && first_key_position === output.position) {
+ /*This token exactly matches another token,
+ greedily match to check if this token has a greater specificity*/
+ if (token_template.open.length > output.def.open.length) {
+ //This token's opening tag is more specific than the previous match
+ output.position = first_key_position;
+ output.def = token_template;
+ output.close_position = close_key_position;
+ } else if (token_template.open.length === output.def.open.length) {
+ if (token_template.close.length > output.def.close.length) {
+ //This token's opening tag is as specific as the previous match,
+ //but the closing tag has greater specificity
+ if (close_key_position >= 0 && close_key_position < output.close_position) {
+ //This token's closing tag exists in the template,
+ //and it occurs sooner than the previous match
+ output.position = first_key_position;
+ output.def = token_template;
+ output.close_position = close_key_position;
+ }
+ } else if (close_key_position >= 0 && close_key_position < output.close_position) {
+ //This token's closing tag is not more specific than the previous match,
+ //but it occurs sooner than the previous match
+ output.position = first_key_position;
+ output.def = token_template;
+ output.close_position = close_key_position;
+ }
+ }
}
}
+ delete output['close_position'];
+
return output;
};
@@ -286,6 +402,11 @@ var Twig = (function (Twig) {
if (token_def.type === Twig.token.type.comment) {
break;
}
+ // Ignore quotes within raw tag
+ // Fixes #283
+ if (token_def.type === Twig.token.type.raw) {
+ break;
+ }
l = Twig.token.strings.length;
for (i = 0; i < l; i += 1) {
@@ -361,9 +482,16 @@ var Twig = (function (Twig) {
value: template.substring(0, end).trim()
});
- if ( found_token.def.type === "logic" && template.substr( end + found_token.def.close.length, 1 ) === "\n" ) {
- // Newlines directly after logic tokens are ignored
- end += 1;
+ if (template.substr( end + found_token.def.close.length, 1 ) === "\n") {
+ switch (found_token.def.type) {
+ case "logic_whitespace_pre":
+ case "logic_whitespace_post":
+ case "logic_whitespace_both":
+ case "logic":
+ // Newlines directly after logic tokens are ignored
+ end += 1;
+ break;
+ }
}
template = template.substr(end + found_token.def.close.length);
@@ -399,8 +527,14 @@ var Twig = (function (Twig) {
unclosed_token = null,
// Temporary previous token.
prev_token = null,
+ // Temporary previous output.
+ prev_output = null,
+ // Temporary previous intermediate output.
+ prev_intermediate_output = null,
// The previous token's template
prev_template = null,
+ // Token lookahead
+ next_token = null,
// The output token
tok_output = null,
@@ -409,8 +543,87 @@ var Twig = (function (Twig) {
open = null,
next = null;
+ var compile_output = function(token) {
+ Twig.expression.compile.apply(this, [token]);
+ if (stack.length > 0) {
+ intermediate_output.push(token);
+ } else {
+ output.push(token);
+ }
+ };
+
+ var compile_logic = function(token) {
+ // Compile the logic token
+ logic_token = Twig.logic.compile.apply(this, [token]);
+
+ type = logic_token.type;
+ open = Twig.logic.handler[type].open;
+ next = Twig.logic.handler[type].next;
+
+ Twig.log.trace("Twig.compile: ", "Compiled logic token to ", logic_token,
+ " next is: ", next, " open is : ", open);
+
+ // Not a standalone token, check logic stack to see if this is expected
+ if (open !== undefined && !open) {
+ prev_token = stack.pop();
+ prev_template = Twig.logic.handler[prev_token.type];
+
+ if (Twig.indexOf(prev_template.next, type) < 0) {
+ throw new Error(type + " not expected after a " + prev_token.type);
+ }
+
+ prev_token.output = prev_token.output || [];
+
+ prev_token.output = prev_token.output.concat(intermediate_output);
+ intermediate_output = [];
+
+ tok_output = {
+ type: Twig.token.type.logic,
+ token: prev_token
+ };
+ if (stack.length > 0) {
+ intermediate_output.push(tok_output);
+ } else {
+ output.push(tok_output);
+ }
+ }
+
+ // This token requires additional tokens to complete the logic structure.
+ if (next !== undefined && next.length > 0) {
+ Twig.log.trace("Twig.compile: ", "Pushing ", logic_token, " to logic stack.");
+
+ if (stack.length > 0) {
+ // Put any currently held output into the output list of the logic operator
+ // currently at the head of the stack before we push a new one on.
+ prev_token = stack.pop();
+ prev_token.output = prev_token.output || [];
+ prev_token.output = prev_token.output.concat(intermediate_output);
+ stack.push(prev_token);
+ intermediate_output = [];
+ }
+
+ // Push the new logic token onto the logic stack
+ stack.push(logic_token);
+
+ } else if (open !== undefined && open) {
+ tok_output = {
+ type: Twig.token.type.logic,
+ token: logic_token
+ };
+ // Standalone token (like {% set ... %}
+ if (stack.length > 0) {
+ intermediate_output.push(tok_output);
+ } else {
+ output.push(tok_output);
+ }
+ }
+ };
+
while (tokens.length > 0) {
token = tokens.shift();
+ prev_output = output[output.length - 1];
+ prev_intermediate_output = intermediate_output[intermediate_output.length - 1];
+ next_token = tokens[0];
Twig.log.trace("Compiling token ", token);
switch (token.type) {
case Twig.token.type.raw:
@@ -422,83 +635,84 @@ var Twig = (function (Twig) {
break;
case Twig.token.type.logic:
- // Compile the logic token
- logic_token = Twig.logic.compile.apply(this, [token]);
-
- type = logic_token.type;
- open = Twig.logic.handler[type].open;
- next = Twig.logic.handler[type].next;
+ compile_logic.call(this, token);
+ break;
- Twig.log.trace("Twig.compile: ", "Compiled logic token to ", logic_token,
- " next is: ", next, " open is : ", open);
+ // Do nothing, comments should be ignored
+ case Twig.token.type.comment:
+ break;
- // Not a standalone token, check logic stack to see if this is expected
- if (open !== undefined && !open) {
- prev_token = stack.pop();
- prev_template = Twig.logic.handler[prev_token.type];
+ case Twig.token.type.output:
+ compile_output.call(this, token);
+ break;
- if (Twig.indexOf(prev_template.next, type) < 0) {
- throw new Error(type + " not expected after a " + prev_token.type);
+ //Kill whitespace ahead and behind this token
+ case Twig.token.type.logic_whitespace_pre:
+ case Twig.token.type.logic_whitespace_post:
+ case Twig.token.type.logic_whitespace_both:
+ case Twig.token.type.output_whitespace_pre:
+ case Twig.token.type.output_whitespace_post:
+ case Twig.token.type.output_whitespace_both:
+ if (token.type !== Twig.token.type.output_whitespace_post && token.type !== Twig.token.type.logic_whitespace_post) {
+ if (prev_output) {
+ //If the previous output is raw, pop it off
+ if (prev_output.type === Twig.token.type.raw) {
+ output.pop();
+
+ //If the previous output is not just whitespace, trim it
+ if (prev_output.value.match(/^\s*$/) === null) {
+ prev_output.value = prev_output.value.trim();
+ //Repush the previous output
+ output.push(prev_output);
+ }
+ }
}
- prev_token.output = prev_token.output || [];
+ if (prev_intermediate_output) {
+ //If the previous intermediate output is raw, pop it off
+ if (prev_intermediate_output.type === Twig.token.type.raw) {
+ intermediate_output.pop();
- prev_token.output = prev_token.output.concat(intermediate_output);
- intermediate_output = [];
-
- tok_output = {
- type: Twig.token.type.logic,
- token: prev_token
- };
- if (stack.length > 0) {
- intermediate_output.push(tok_output);
- } else {
- output.push(tok_output);
+ //If the previous output is not just whitespace, trim it
+ if (prev_intermediate_output.value.match(/^\s*$/) === null) {
+ prev_intermediate_output.value = prev_intermediate_output.value.trim();
+ //Repush the previous intermediate output
+ intermediate_output.push(prev_intermediate_output);
+ }
+ }
}
}
- // This token requires additional tokens to complete the logic structure.
- if (next !== undefined && next.length > 0) {
- Twig.log.trace("Twig.compile: ", "Pushing ", logic_token, " to logic stack.");
-
- if (stack.length > 0) {
- // Put any currently held output into the output list of the logic operator
- // currently at the head of the stack before we push a new one on.
- prev_token = stack.pop();
- prev_token.output = prev_token.output || [];
- prev_token.output = prev_token.output.concat(intermediate_output);
- stack.push(prev_token);
- intermediate_output = [];
- }
+ //Compile this token
+ switch (token.type) {
+ case Twig.token.type.output_whitespace_pre:
+ case Twig.token.type.output_whitespace_post:
+ case Twig.token.type.output_whitespace_both:
+ compile_output.call(this, token);
+ break;
+ case Twig.token.type.logic_whitespace_pre:
+ case Twig.token.type.logic_whitespace_post:
+ case Twig.token.type.logic_whitespace_both:
+ compile_logic.call(this, token);
+ break;
+ }
- // Push the new logic token onto the logic stack
- stack.push(logic_token);
-
- } else if (open !== undefined && open) {
- tok_output = {
- type: Twig.token.type.logic,
- token: logic_token
- };
- // Standalone token (like {% set ... %}
- if (stack.length > 0) {
- intermediate_output.push(tok_output);
- } else {
- output.push(tok_output);
+ if (token.type !== Twig.token.type.output_whitespace_pre && token.type !== Twig.token.type.logic_whitespace_pre) {
+ if (next_token) {
+ //If the next token is raw, shift it out
+ if (next_token.type === Twig.token.type.raw) {
+ tokens.shift();
+
+ //If the next token is not just whitespace, trim it
+ if (next_token.value.match(/^\s*$/) === null) {
+ next_token.value = next_token.value.trim();
+ //Unshift the next token
+ tokens.unshift(next_token);
+ }
+ }
}
}
- break;
-
- // Do nothing, comments should be ignored
- case Twig.token.type.comment:
- break;
- case Twig.token.type.output:
- Twig.expression.compile.apply(this, [token]);
- if (stack.length > 0) {
- intermediate_output.push(token);
- } else {
- output.push(token);
- }
break;
}
@@ -541,16 +755,12 @@ var Twig = (function (Twig) {
chain = true,
that = this;
- // Default to an empty object if none provided
- context = context || { };
-
-
Twig.forEach(tokens, function parseToken(token) {
Twig.log.debug("Twig.parse: ", "Parsing token: ", token);
switch (token.type) {
case Twig.token.type.raw:
- output.push(token.value);
+ output.push(Twig.filters.raw(token.value));
break;
case Twig.token.type.logic:
@@ -572,6 +782,10 @@ var Twig = (function (Twig) {
// Do nothing, comments should be ignored
break;
+ //Fall through whitespace to output
+ case Twig.token.type.output_whitespace_pre:
+ case Twig.token.type.output_whitespace_post:
+ case Twig.token.type.output_whitespace_both:
case Twig.token.type.output:
Twig.log.debug("Twig.parse: ", "Output token: ", token.stack);
// Parse the given expression in the given context
@@ -579,7 +793,7 @@ var Twig = (function (Twig) {
break;
}
});
- return output.join("");
+ return Twig.output.apply(this, [output]);
} catch (ex) {
Twig.log.error("Error parsing twig template " + this.id + ": ");
if (ex.stack) {
@@ -619,8 +833,51 @@ var Twig = (function (Twig) {
return tokens;
};
+ /**
+ * Join the output token's stack and escape it if needed
+ *
+ * @param {Array} Output token's stack
+ *
+ * @return {string|String} Autoescaped output
+ */
+ Twig.output = function(output) {
+ if (!this.options.autoescape) {
+ return output.join("");
+ }
+
+ var strategy = 'html';
+ if(typeof this.options.autoescape == 'string')
+ strategy = this.options.autoescape;
+
+ // [].map would be better but it's not supported by IE8-
+ var escaped_output = [];
+ Twig.forEach(output, function (str) {
+ if (str && (str.twig_markup !== true && str.twig_markup != strategy)) {
+ str = Twig.filters.escape(str, [ strategy ]);
+ }
+ escaped_output.push(str);
+ });
+ return Twig.Markup(escaped_output.join(""));
+ }
+
// Namespace for template storage and retrieval
Twig.Templates = {
+ /**
+ * Registered template loaders - use Twig.Templates.registerLoader to add supported loaders
+ * @type {Object}
+ */
+ loaders: {},
+
+ /**
+ * Registered template parsers - use Twig.Templates.registerParser to add supported parsers
+ * @type {Object}
+ */
+ parsers: {},
+
+ /**
+ * Cached / loaded templates
+ * @type {Object}
+ */
registry: {}
};
@@ -635,12 +892,131 @@ var Twig = (function (Twig) {
Twig.validateId = function(id) {
if (id === "prototype") {
throw new Twig.Error(id + " is not a valid twig identifier");
- } else if (Twig.Templates.registry.hasOwnProperty(id)) {
+ } else if (Twig.cache && Twig.Templates.registry.hasOwnProperty(id)) {
throw new Twig.Error("There is already a template with the ID " + id);
}
return true;
}
+ /**
+ * Register a template loader
+ *
+ * @example
+ * Twig.extend(function(Twig) {
+ * Twig.Templates.registerLoader('custom_loader', function(location, params, callback, error_callback) {
+ * // ... load the template ...
+ * params.data = loadedTemplateData;
+ * // create and return the template
+ * var template = new Twig.Template(params);
+ * if (typeof callback === 'function') {
+ * callback(template);
+ * }
+ * return template;
+ * });
+ * });
+ *
+ * @param {String} method_name The method this loader is intended for (ajax, fs)
+ * @param {Function} func The function to execute when loading the template
+ * @param {Object|undefined} scope Optional scope parameter to bind func to
+ *
+ * @throws Twig.Error
+ *
+ * @return {void}
+ */
+ Twig.Templates.registerLoader = function(method_name, func, scope) {
+ if (typeof func !== 'function') {
+ throw new Twig.Error('Unable to add loader for ' + method_name + ': Invalid function reference given.');
+ }
+ if (scope) {
+ func = func.bind(scope);
+ }
+ this.loaders[method_name] = func;
+ };
+
+ /**
+ * Remove a registered loader
+ *
+ * @param {String} method_name The method name for the loader you wish to remove
+ *
+ * @return {void}
+ */
+ Twig.Templates.unRegisterLoader = function(method_name) {
+ if (this.isRegisteredLoader(method_name)) {
+ delete this.loaders[method_name];
+ }
+ };
+
+ /**
+ * See if a loader is registered by its method name
+ *
+ * @param {String} method_name The name of the loader you are looking for
+ *
+ * @return {boolean}
+ */
+ Twig.Templates.isRegisteredLoader = function(method_name) {
+ return this.loaders.hasOwnProperty(method_name);
+ };
+
+ /**
+ * Register a template parser
+ *
+ * @example
+ * Twig.extend(function(Twig) {
+ * Twig.Templates.registerParser('custom_parser', function(params) {
+ * // this template source can be accessed in params.data
+ * var template = params.data
+ *
+ * // ... custom process that modifies the template
+ *
+ * // return the parsed template
+ * return template;
+ * });
+ * });
+ *
+ * @param {String} method_name The method this parser is intended for (twig, source)
+ * @param {Function} func The function to execute when parsing the template
+ * @param {Object|undefined} scope Optional scope parameter to bind func to
+ *
+ * @throws Twig.Error
+ *
+ * @return {void}
+ */
+ Twig.Templates.registerParser = function(method_name, func, scope) {
+ if (typeof func !== 'function') {
+ throw new Twig.Error('Unable to add parser for ' + method_name + ': Invalid function regerence given.');
+ }
+
+ if (scope) {
+ func = func.bind(scope);
+ }
+
+ this.parsers[method_name] = func;
+ };
+
+ /**
+ * Remove a registered parser
+ *
+ * @param {String} method_name The method name for the parser you wish to remove
+ *
+ * @return {void}
+ */
+ Twig.Templates.unRegisterParser = function(method_name) {
+ if (this.isRegisteredParser(method_name)) {
+ delete this.parsers[method_name];
+ }
+ };
+
+ /**
+ * See if a parser is registered by its method name
+ *
+ * @param {String} method_name The name of the parser you are looking for
+ *
+ * @return {boolean}
+ */
+ Twig.Templates.isRegisteredParser = function(method_name) {
+ return this.parsers.hasOwnProperty(method_name);
+ };
+
/**
* Save a template object to the store.
*
@@ -676,6 +1052,8 @@ var Twig = (function (Twig) {
* Defaults to true.
* method: What method should be used to load the template
* (fs or ajax)
+ * parser: What method should be used to parse the template
+ * (twig or source)
* precompiled: Has the template already been compiled.
*
* @param {string} location The remote URL to load as a template.
@@ -686,119 +1064,34 @@ var Twig = (function (Twig) {
*
*/
Twig.Templates.loadRemote = function(location, params, callback, error_callback) {
- var id = params.id,
- method = params.method,
- async = params.async,
- precompiled = params.precompiled,
- template = null;
+ var loader;
// Default to async
- if (async === undefined) async = true;
+ if (params.async === undefined) {
+ params.async = true;
+ }
// Default to the URL so the template is cached.
- if (id === undefined) {
- id = location;
+ if (params.id === undefined) {
+ params.id = location;
}
- params.id = id;
// Check for existing template
- if (Twig.cache && Twig.Templates.registry.hasOwnProperty(id)) {
+ if (Twig.cache && Twig.Templates.registry.hasOwnProperty(params.id)) {
// A template is already saved with the given id.
- if (callback) {
- callback(Twig.Templates.registry[id]);
+ if (typeof callback === 'function') {
+ callback(Twig.Templates.registry[params.id]);
}
- return Twig.Templates.registry[id];
+ // TODO: if async, return deferred promise
+ return Twig.Templates.registry[params.id];
}
- if (method == 'ajax') {
- if (typeof XMLHttpRequest == "undefined") {
- throw new Twig.Error("Unsupported platform: Unable to do remote requests " +
- "because there is no XMLHTTPRequest implementation");
- }
-
- var xmlhttp = new XMLHttpRequest();
- xmlhttp.onreadystatechange = function() {
- var data = null;
-
- if(xmlhttp.readyState == 4) {
- if (xmlhttp.status == 200) {
- Twig.log.debug("Got template ", xmlhttp.responseText);
-
- if (precompiled === true) {
- data = JSON.parse(xmlhttp.responseText);
- } else {
- data = xmlhttp.responseText;
- }
-
- params.url = location;
- params.data = data;
-
- template = new Twig.Template(params);
-
- if (callback) {
- callback(template);
- }
- } else {
- if (error_callback) {
- error_callback(xmlhttp);
- }
- }
- }
- };
- xmlhttp.open("GET", location, async);
- xmlhttp.send();
-
- } else { // if method = 'fs'
- // Create local scope
- (function() {
- var fs = require('fs'),
- path = require('path'),
- data = null,
- loadTemplateFn = function(err, data) {
- if (err) {
- if (error_callback) {
- error_callback(err);
- }
- return;
- }
-
- if (precompiled === true) {
- data = JSON.parse(data);
- }
-
- params.data = data;
- params.path = location;
+ //if the parser name hasn't been set, default it to twig
+ params.parser = params.parser || 'twig';
- // template is in data
- template = new Twig.Template(params);
-
- if (callback) {
- callback(template);
- }
- };
-
- if (async === true) {
- fs.stat(location, function (err, stats) {
- if (err || !stats.isFile())
- throw new Twig.Error("Unable to find template file " + location);
-
- fs.readFile(location, 'utf8', loadTemplateFn);
- });
- } else {
- if (!fs.statSync(location).isFile())
- throw new Twig.Error("Unable to find template file " + location);
-
- data = fs.readFileSync(location, 'utf8');
- loadTemplateFn(undefined, data);
- }
- })();
- }
- if (async === false) {
- return template;
- } else {
- // placeholder for now, should eventually return a deferred object.
- return true;
- }
+ // Assume 'fs' if the loader is not defined
+ loader = this.loaders[params.method] || this.loaders.fs;
+ return loader.apply(this, arguments);
};
// Determine object type
@@ -826,6 +1119,8 @@ var Twig = (function (Twig) {
base = params.base,
path = params.path,
url = params.url,
+ name = params.name,
+ method = params.method,
// parser options
options = params.options;
@@ -841,16 +1136,18 @@ var Twig = (function (Twig) {
// options: {
// Compiler/parser options
//
- // strict_variables: true/false
+ // strictVariables: true/false
// Should missing variable/keys emit an error message. If false, they default to null.
// }
// }
//
this.id = id;
+ this.method = method;
this.base = base;
this.path = path;
this.url = url;
+ this.name = name;
this.macros = macros;
this.options = options;
@@ -870,6 +1167,8 @@ var Twig = (function (Twig) {
Twig.Template.prototype.reset = function(blocks) {
Twig.log.debug("Twig.Template.reset", "Reseting template " + this.id);
this.blocks = {};
+ this.importedBlocks = [];
+ this.originalBlockTokens = {};
this.child = {
blocks: blocks || {}
};
@@ -909,10 +1208,10 @@ var Twig = (function (Twig) {
// check for the template file via include
if (!ext_template) {
- url = relativePath(this, this.extend);
+ url = Twig.path.parsePath(this, this.extend);
ext_template = Twig.Templates.loadRemote(url, {
- method: this.url?'ajax':'fs',
+ method: this.getLoaderMethod(),
base: this.base,
async: false,
id: url,
@@ -938,21 +1237,33 @@ var Twig = (function (Twig) {
Twig.Template.prototype.importFile = function(file) {
var url, sub_template;
- if ( !this.url && !this.path && this.options.allowInlineIncludes ) {
+ if (!this.url && this.options.allowInlineIncludes) {
+ file = this.path ? this.path + '/' + file : file;
sub_template = Twig.Templates.load(file);
- sub_template.options = this.options;
- if ( sub_template ) {
- return sub_template;
+
+ if (!sub_template) {
+ sub_template = Twig.Templates.loadRemote(url, {
+ id: file,
+ method: this.getLoaderMethod(),
+ async: false,
+ options: this.options
+ });
+
+ if (!sub_template) {
+ throw new Twig.Error("Unable to find the template " + file);
+ }
}
- throw new Twig.Error("Didn't find the inline template by id");
+ sub_template.options = this.options;
+
+ return sub_template;
}
- url = relativePath(this, file);
+ url = Twig.path.parsePath(this, file);
// Load blocks from an external file
sub_template = Twig.Templates.loadRemote(url, {
- method: this.url?'ajax':'fs',
+ method: this.getLoaderMethod(),
base: this.base,
async: false,
options: this.options,
@@ -976,16 +1287,17 @@ var Twig = (function (Twig) {
Twig.forEach(Object.keys(sub_template.blocks), function(key) {
if (override || that.blocks[key] === undefined) {
that.blocks[key] = sub_template.blocks[key];
+ that.importedBlocks.push(key);
}
});
};
Twig.Template.prototype.importMacros = function(file) {
- var url = relativePath(this, file);
+ var url = Twig.path.parsePath(this, file);
// load remote template
var remoteTemplate = Twig.Templates.loadRemote(url, {
- method: this.url?'ajax':'fs',
+ method: this.getLoaderMethod(),
async: false,
id: url
});
@@ -993,76 +1305,181 @@ var Twig = (function (Twig) {
return remoteTemplate;
};
+ Twig.Template.prototype.getLoaderMethod = function() {
+ if (this.path) {
+ return 'fs';
+ }
+ if (this.url) {
+ return 'ajax';
+ }
+ return this.method || 'fs';
+ };
+
Twig.Template.prototype.compile = function(options) {
// compile the template into raw JS
return Twig.compiler.compile(this, options);
};
/**
- * Generate the relative canonical version of a url based on the given base path and file path.
+ * Create safe output
*
- * @param {string} template The Twig.Template.
- * @param {string} file The file path, relative to the base path.
+ * @param {string} Content safe to output
*
- * @return {string} The canonical version of the path.
+ * @return {String} Content wrapped into a String
*/
- function relativePath(template, file) {
- var base,
- base_path,
- sep_chr = "/",
- new_path = [],
- val;
- if (template.url) {
- if (typeof template.base !== 'undefined') {
- base = template.base + ((template.base.charAt(template.base.length-1) === '/') ? '' : '/');
- } else {
- base = template.url;
- }
- } else if (template.path) {
- // Get the system-specific path separator
- var path = require("path"),
- sep = path.sep || sep_chr,
- relative = new RegExp("^\\.{1,2}" + sep.replace("\\", "\\\\"));
- file = file.replace(/\//g, sep);
+ Twig.Markup = function(content, strategy) {
+ if(typeof strategy == 'undefined') {
+ strategy = true;
+ }
- if (template.base !== undefined && file.match(relative) == null) {
- file = file.replace(template.base, '');
- base = template.base + sep;
- } else {
- base = template.path;
- }
+ if (typeof content === 'string' && content.length > 0) {
+ content = new String(content);
+ content.twig_markup = strategy;
+ }
+ return content;
+ };
- base = base.replace(sep+sep, sep);
- sep_chr = sep;
- } else {
- throw new Twig.Error("Cannot extend an inline template.");
+ return Twig;
+
+}) (Twig || { });
+
+(function(Twig) {
+
+ 'use strict';
+
+ Twig.Templates.registerLoader('ajax', function(location, params, callback, error_callback) {
+ var template,
+ xmlhttp,
+ precompiled = params.precompiled,
+ parser = this.parsers[params.parser] || this.parser.twig;
+
+ if (typeof XMLHttpRequest === "undefined") {
+ throw new Twig.Error('Unsupported platform: Unable to do ajax requests ' +
+ 'because there is no "XMLHTTPRequest" implementation');
}
- base_path = base.split(sep_chr);
+ xmlhttp = new XMLHttpRequest();
+ xmlhttp.onreadystatechange = function() {
+ var data = null;
- // Remove file from url
- base_path.pop();
- base_path = base_path.concat(file.split(sep_chr));
+ if(xmlhttp.readyState === 4) {
+ if (xmlhttp.status === 200 || (window.cordova && xmlhttp.status == 0)) {
+ Twig.log.debug("Got template ", xmlhttp.responseText);
- while (base_path.length > 0) {
- val = base_path.shift();
- if (val == ".") {
- // Ignore
- } else if (val == ".." && new_path.length > 0 && new_path[new_path.length-1] != "..") {
- new_path.pop();
- } else {
- new_path.push(val);
+ if (precompiled === true) {
+ data = JSON.parse(xmlhttp.responseText);
+ } else {
+ data = xmlhttp.responseText;
+ }
+
+ params.url = location;
+ params.data = data;
+
+ template = parser.call(this, params);
+
+ if (typeof callback === 'function') {
+ callback(template);
+ }
+ } else {
+ if (typeof error_callback === 'function') {
+ error_callback(xmlhttp);
+ }
+ }
}
+ };
+ xmlhttp.open("GET", location, !!params.async);
+ xmlhttp.send();
+
+ if (params.async) {
+ // TODO: return deferred promise
+ return true;
+ } else {
+ return template;
}
+ });
- return new_path.join(sep_chr);
+}(Twig));(function(Twig) {
+ 'use strict';
+
+ var fs, path;
+
+ try {
+ // require lib dependencies at runtime
+ fs = require('fs');
+ path = require('path');
+ } catch (e) {
+ // NOTE: this is in a try/catch to avoid errors cross platform
}
- return Twig;
+ Twig.Templates.registerLoader('fs', function(location, params, callback, error_callback) {
+ var template,
+ data = null,
+ precompiled = params.precompiled,
+ parser = this.parsers[params.parser] || this.parser.twig;
-}) (Twig || { });
+ if (!fs || !path) {
+ throw new Twig.Error('Unsupported platform: Unable to load from file ' +
+ 'because there is no "fs" or "path" implementation');
+ }
+
+ var loadTemplateFn = function(err, data) {
+ if (err) {
+ if (typeof error_callback === 'function') {
+ error_callback(err);
+ }
+ return;
+ }
+
+ if (precompiled === true) {
+ data = JSON.parse(data);
+ }
+
+ params.data = data;
+ params.path = params.path || location;
+ // template is in data
+ template = parser.call(this, params);
+
+ if (typeof callback === 'function') {
+ callback(template);
+ }
+ };
+ params.path = params.path || location;
+
+ if (params.async) {
+ fs.stat(params.path, function (err, stats) {
+ if (err || !stats.isFile()) {
+ throw new Twig.Error('Unable to find template file ' + location);
+ }
+ fs.readFile(params.path, 'utf8', loadTemplateFn);
+ });
+ // TODO: return deferred promise
+ return true;
+ } else {
+ if (!fs.statSync(params.path).isFile()) {
+ throw new Twig.Error('Unable to find template file ' + location);
+ }
+ data = fs.readFileSync(params.path, 'utf8');
+ loadTemplateFn(undefined, data);
+ return template
+ }
+ });
+
+}(Twig));(function(Twig){
+ 'use strict';
+
+ Twig.Templates.registerParser('source', function(params) {
+ return params.data || '';
+ });
+})(Twig);
+(function(Twig){
+ 'use strict';
+
+ Twig.Templates.registerParser('twig', function(params) {
+ return new Twig.Template(params);
+ });
+})(Twig);
// The following methods are from MDN and are available under a
// [MIT License](http://www.opensource.org/licenses/mit-license.php) or are
// [Public Domain](https://developer.mozilla.org/Project:Copyrights).
@@ -1107,132 +1524,207 @@ var Twig = (function(Twig) {
Twig.lib = { };
/**
- sprintf() for JavaScript 0.7-beta1
- http://www.diveintojavascript.com/projects/javascript-sprintf
+ sprintf() for JavaScript 1.0.3
+ https://github.com/alexei/sprintf.js
**/
- var sprintf = (function() {
- function get_type(variable) {
- return Object.prototype.toString.call(variable).slice(8, -1).toLowerCase();
- }
- function str_repeat(input, multiplier) {
- for (var output = []; multiplier > 0; output[--multiplier] = input) {/* do nothing */}
- return output.join('');
+ var sprintfLib = (function() {
+ var re = {
+ not_string: /[^s]/,
+ number: /[diefg]/,
+ json: /[j]/,
+ not_json: /[^j]/,
+ text: /^[^\x25]+/,
+ modulo: /^\x25{2}/,
+ placeholder: /^\x25(?:([1-9]\d*)\$|\(([^\)]+)\))?(\+)?(0|'[^$])?(-)?(\d+)?(?:\.(\d+))?([b-gijosuxX])/,
+ key: /^([a-z_][a-z_\d]*)/i,
+ key_access: /^\.([a-z_][a-z_\d]*)/i,
+ index_access: /^\[(\d+)\]/,
+ sign: /^[\+\-]/
+ }
+
+ function sprintf() {
+ var key = arguments[0], cache = sprintf.cache
+ if (!(cache[key] && cache.hasOwnProperty(key))) {
+ cache[key] = sprintf.parse(key)
}
+ return sprintf.format.call(null, cache[key], arguments)
+ }
+
+ sprintf.format = function(parse_tree, argv) {
+ var cursor = 1, tree_length = parse_tree.length, node_type = "", arg, output = [], i, k, match, pad, pad_character, pad_length, is_positive = true, sign = ""
+ for (i = 0; i < tree_length; i++) {
+ node_type = get_type(parse_tree[i])
+ if (node_type === "string") {
+ output[output.length] = parse_tree[i]
+ }
+ else if (node_type === "array") {
+ match = parse_tree[i] // convenience purposes only
+ if (match[2]) { // keyword argument
+ arg = argv[cursor]
+ for (k = 0; k < match[2].length; k++) {
+ if (!arg.hasOwnProperty(match[2][k])) {
+ throw new Error(sprintf("[sprintf] property '%s' does not exist", match[2][k]))
+ }
+ arg = arg[match[2][k]]
+ }
+ }
+ else if (match[1]) { // positional argument (explicit)
+ arg = argv[match[1]]
+ }
+ else { // positional argument (implicit)
+ arg = argv[cursor++]
+ }
- var str_format = function() {
- if (!str_format.cache.hasOwnProperty(arguments[0])) {
- str_format.cache[arguments[0]] = str_format.parse(arguments[0]);
+ if (get_type(arg) == "function") {
+ arg = arg()
}
- return str_format.format.call(null, str_format.cache[arguments[0]], arguments);
- };
- str_format.format = function(parse_tree, argv) {
- var cursor = 1, tree_length = parse_tree.length, node_type = '', arg, output = [], i, k, match, pad, pad_character, pad_length;
- for (i = 0; i < tree_length; i++) {
- node_type = get_type(parse_tree[i]);
- if (node_type === 'string') {
- output.push(parse_tree[i]);
- }
- else if (node_type === 'array') {
- match = parse_tree[i]; // convenience purposes only
- if (match[2]) { // keyword argument
- arg = argv[cursor];
- for (k = 0; k < match[2].length; k++) {
- if (!arg.hasOwnProperty(match[2][k])) {
- throw(sprintf('[sprintf] property "%s" does not exist', match[2][k]));
- }
- arg = arg[match[2][k]];
- }
- }
- else if (match[1]) { // positional argument (explicit)
- arg = argv[match[1]];
- }
- else { // positional argument (implicit)
- arg = argv[cursor++];
- }
+ if (re.not_string.test(match[8]) && re.not_json.test(match[8]) && (get_type(arg) != "number" && isNaN(arg))) {
+ throw new TypeError(sprintf("[sprintf] expecting number but found %s", get_type(arg)))
+ }
+
+ if (re.number.test(match[8])) {
+ is_positive = arg >= 0
+ }
+
+ switch (match[8]) {
+ case "b":
+ arg = arg.toString(2)
+ break
+ case "c":
+ arg = String.fromCharCode(arg)
+ break
+ case "d":
+ case "i":
+ arg = parseInt(arg, 10)
+ break
+ case "j":
+ arg = JSON.stringify(arg, null, match[6] ? parseInt(match[6]) : 0)
+ break
+ case "e":
+ arg = match[7] ? arg.toExponential(match[7]) : arg.toExponential()
+ break
+ case "f":
+ arg = match[7] ? parseFloat(arg).toFixed(match[7]) : parseFloat(arg)
+ break
+ case "g":
+ arg = match[7] ? parseFloat(arg).toPrecision(match[7]) : parseFloat(arg)
+ break
+ case "o":
+ arg = arg.toString(8)
+ break
+ case "s":
+ arg = ((arg = String(arg)) && match[7] ? arg.substring(0, match[7]) : arg)
+ break
+ case "u":
+ arg = arg >>> 0
+ break
+ case "x":
+ arg = arg.toString(16)
+ break
+ case "X":
+ arg = arg.toString(16).toUpperCase()
+ break
+ }
+ if (re.json.test(match[8])) {
+ output[output.length] = arg
+ }
+ else {
+ if (re.number.test(match[8]) && (!is_positive || match[3])) {
+ sign = is_positive ? "+" : "-"
+ arg = arg.toString().replace(re.sign, "")
+ }
+ else {
+ sign = ""
+ }
+ pad_character = match[4] ? match[4] === "0" ? "0" : match[4].charAt(1) : " "
+ pad_length = match[6] - (sign + arg).length
+ pad = match[6] ? (pad_length > 0 ? str_repeat(pad_character, pad_length) : "") : ""
+ output[output.length] = match[5] ? sign + arg + pad : (pad_character === "0" ? sign + pad + arg : pad + sign + arg)
+ }
+ }
+ }
+ return output.join("")
+ }
+
+ sprintf.cache = {}
- if (/[^s]/.test(match[8]) && (get_type(arg) != 'number')) {
- throw(sprintf('[sprintf] expecting number but found %s', get_type(arg)));
- }
- switch (match[8]) {
- case 'b': arg = arg.toString(2); break;
- case 'c': arg = String.fromCharCode(arg); break;
- case 'd': arg = parseInt(arg, 10); break;
- case 'e': arg = match[7] ? arg.toExponential(match[7]) : arg.toExponential(); break;
- case 'f': arg = match[7] ? parseFloat(arg).toFixed(match[7]) : parseFloat(arg); break;
- case 'o': arg = arg.toString(8); break;
- case 's': arg = ((arg = String(arg)) && match[7] ? arg.substring(0, match[7]) : arg); break;
- case 'u': arg = Math.abs(arg); break;
- case 'x': arg = arg.toString(16); break;
- case 'X': arg = arg.toString(16).toUpperCase(); break;
- }
- arg = (/[def]/.test(match[8]) && match[3] && arg >= 0 ? '+'+ arg : arg);
- pad_character = match[4] ? match[4] == '0' ? '0' : match[4].charAt(1) : ' ';
- pad_length = match[6] - String(arg).length;
- pad = match[6] ? str_repeat(pad_character, pad_length) : '';
- output.push(match[5] ? arg + pad : pad + arg);
+ sprintf.parse = function(fmt) {
+ var _fmt = fmt, match = [], parse_tree = [], arg_names = 0
+ while (_fmt) {
+ if ((match = re.text.exec(_fmt)) !== null) {
+ parse_tree[parse_tree.length] = match[0]
+ }
+ else if ((match = re.modulo.exec(_fmt)) !== null) {
+ parse_tree[parse_tree.length] = "%"
+ }
+ else if ((match = re.placeholder.exec(_fmt)) !== null) {
+ if (match[2]) {
+ arg_names |= 1
+ var field_list = [], replacement_field = match[2], field_match = []
+ if ((field_match = re.key.exec(replacement_field)) !== null) {
+ field_list[field_list.length] = field_match[1]
+ while ((replacement_field = replacement_field.substring(field_match[0].length)) !== "") {
+ if ((field_match = re.key_access.exec(replacement_field)) !== null) {
+ field_list[field_list.length] = field_match[1]
+ }
+ else if ((field_match = re.index_access.exec(replacement_field)) !== null) {
+ field_list[field_list.length] = field_match[1]
+ }
+ else {
+ throw new SyntaxError("[sprintf] failed to parse named argument key")
+ }
}
+ }
+ else {
+ throw new SyntaxError("[sprintf] failed to parse named argument key")
+ }
+ match[2] = field_list
}
- return output.join('');
- };
+ else {
+ arg_names |= 2
+ }
+ if (arg_names === 3) {
+ throw new Error("[sprintf] mixing positional and named placeholders is not (yet) supported")
+ }
+ parse_tree[parse_tree.length] = match
+ }
+ else {
+ throw new SyntaxError("[sprintf] unexpected placeholder")
+ }
+ _fmt = _fmt.substring(match[0].length)
+ }
+ return parse_tree
+ }
- str_format.cache = {};
+ var vsprintf = function(fmt, argv, _argv) {
+ _argv = (argv || []).slice(0)
+ _argv.splice(0, 0, fmt)
+ return sprintf.apply(null, _argv)
+ }
- str_format.parse = function(fmt) {
- var _fmt = fmt, match = [], parse_tree = [], arg_names = 0;
- while (_fmt) {
- if ((match = /^[^\x25]+/.exec(_fmt)) !== null) {
- parse_tree.push(match[0]);
- }
- else if ((match = /^\x25{2}/.exec(_fmt)) !== null) {
- parse_tree.push('%');
- }
- else if ((match = /^\x25(?:([1-9]\d*)\$|\(([^\)]+)\))?(\+)?(0|'[^$])?(-)?(\d+)?(?:\.(\d+))?([b-fosuxX])/.exec(_fmt)) !== null) {
- if (match[2]) {
- arg_names |= 1;
- var field_list = [], replacement_field = match[2], field_match = [];
- if ((field_match = /^([a-z_][a-z_\d]*)/i.exec(replacement_field)) !== null) {
- field_list.push(field_match[1]);
- while ((replacement_field = replacement_field.substring(field_match[0].length)) !== '') {
- if ((field_match = /^\.([a-z_][a-z_\d]*)/i.exec(replacement_field)) !== null) {
- field_list.push(field_match[1]);
- }
- else if ((field_match = /^\[(\d+)\]/.exec(replacement_field)) !== null) {
- field_list.push(field_match[1]);
- }
- else {
- throw('[sprintf] huh?');
- }
- }
- }
- else {
- throw('[sprintf] huh?');
- }
- match[2] = field_list;
- }
- else {
- arg_names |= 2;
- }
- if (arg_names === 3) {
- throw('[sprintf] mixing positional and named placeholders is not (yet) supported');
- }
- parse_tree.push(match);
- }
- else {
- throw('[sprintf] huh?');
- }
- _fmt = _fmt.substring(match[0].length);
- }
- return parse_tree;
- };
+ /**
+ * helpers
+ */
+ function get_type(variable) {
+ return Object.prototype.toString.call(variable).slice(8, -1).toLowerCase()
+ }
- return str_format;
+ function str_repeat(input, multiplier) {
+ return Array(multiplier + 1).join(input)
+ }
+
+ /**
+ * export
+ */
+ return {
+ sprintf: sprintf,
+ vsprintf: vsprintf
+ }
})();
- var vsprintf = function(fmt, argv) {
- argv.unshift(fmt);
- return sprintf.apply(null, argv);
- };
+ var sprintf = sprintfLib.sprintf;
+ var vsprintf = sprintfLib.vsprintf;
// Expose to Twig
Twig.lib.sprintf = sprintf;
@@ -1443,8 +1935,8 @@ var Twig = (function(Twig) {
Twig.lib.parseISO8601Date = function (s){
// Taken from http://n8v.enteuxis.org/2010/12/parsing-iso-8601-dates-in-javascript/
// parenthese matches:
- // year month day hours minutes seconds
- // dotmilliseconds
+ // year month day hours minutes seconds
+ // dotmilliseconds
// tzstring plusminus hours minutes
var re = /(\d{4})-(\d\d)-(\d\d)T(\d\d):(\d\d):(\d\d)(\.\d+)?(Z|([+-])(\d\d):(\d\d))/;
@@ -1455,7 +1947,7 @@ var Twig = (function(Twig) {
// ["2010-12-07T11:00:00.000-09:00", "2010", "12", "07", "11",
// "00", "00", ".000", "-09:00", "-", "09", "00"]
// "2010-12-07T11:00:00.000Z" parses to:
- // ["2010-12-07T11:00:00.000Z", "2010", "12", "07", "11",
+ // ["2010-12-07T11:00:00.000Z", "2010", "12", "07", "11",
// "00", "00", ".000", "Z", undefined, undefined, undefined]
if (! d) {
@@ -1475,7 +1967,7 @@ var Twig = (function(Twig) {
var ms = Date.UTC(d[1], d[2] - 1, d[3], d[4], d[5], d[6]);
// if there are milliseconds, add them
- if (d[7] > 0) {
+ if (d[7] > 0) {
ms += Math.round(d[7] * 1000);
}
@@ -1496,196 +1988,300 @@ var Twig = (function(Twig) {
return new Date(ms);
};
- Twig.lib.strtotime = function (str, now) {
- // http://kevin.vanzonneveld.net
- // + original by: Caio Ariede (http://caioariede.com)
- // + improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
- // + input by: David
- // + improved by: Caio Ariede (http://caioariede.com)
- // + improved by: Brett Zamir (http://brett-zamir.me)
- // + bugfixed by: Wagner B. Soares
- // + bugfixed by: Artur Tchernychev
- // % note 1: Examples all have a fixed timestamp to prevent tests to fail because of variable time(zones)
- // * example 1: strtotime('+1 day', 1129633200);
- // * returns 1: 1129719600
- // * example 2: strtotime('+1 week 2 days 4 hours 2 seconds', 1129633200);
- // * returns 2: 1130425202
- // * example 3: strtotime('last month', 1129633200);
- // * returns 3: 1127041200
- // * example 4: strtotime('2009-05-04 08:30:00');
- // * returns 4: 1241418600
- var i, l, match, s, parse = '';
-
- str = str.replace(/\s{2,}|^\s|\s$/g, ' '); // unecessary spaces
- str = str.replace(/[\t\r\n]/g, ''); // unecessary chars
- if (str === 'now') {
- return now === null || isNaN(now) ? new Date().getTime() / 1000 | 0 : now | 0;
- } else if (!isNaN(parse = Date.parse(str))) {
- return parse / 1000 | 0;
- } else if (now) {
- now = new Date(now * 1000); // Accept PHP-style seconds
- } else {
- now = new Date();
- }
-
- var upperCaseStr = str;
-
- str = str.toLowerCase();
-
- var __is = {
- day: {
- 'sun': 0,
- 'mon': 1,
- 'tue': 2,
- 'wed': 3,
- 'thu': 4,
- 'fri': 5,
- 'sat': 6
- },
- mon: [
- 'jan',
- 'feb',
- 'mar',
- 'apr',
- 'may',
- 'jun',
- 'jul',
- 'aug',
- 'sep',
- 'oct',
- 'nov',
- 'dec'
- ]
- };
-
- var process = function (m) {
- var ago = (m[2] && m[2] === 'ago');
- var num = (num = m[0] === 'last' ? -1 : 1) * (ago ? -1 : 1);
-
- switch (m[0]) {
- case 'last':
- case 'next':
- switch (m[1].substring(0, 3)) {
- case 'yea':
- now.setFullYear(now.getFullYear() + num);
- break;
- case 'wee':
- now.setDate(now.getDate() + (num * 7));
- break;
- case 'day':
- now.setDate(now.getDate() + num);
- break;
- case 'hou':
- now.setHours(now.getHours() + num);
- break;
- case 'min':
- now.setMinutes(now.getMinutes() + num);
- break;
- case 'sec':
- now.setSeconds(now.getSeconds() + num);
- break;
- case 'mon':
- if (m[1] === "month") {
- now.setMonth(now.getMonth() + num);
- break;
- }
- // fall through
- default:
- var day = __is.day[m[1].substring(0, 3)];
- if (typeof day !== 'undefined') {
- var diff = day - now.getDay();
- if (diff === 0) {
- diff = 7 * num;
- } else if (diff > 0) {
- if (m[0] === 'last') {
- diff -= 7;
- }
- } else {
- if (m[0] === 'next') {
- diff += 7;
- }
- }
- now.setDate(now.getDate() + diff);
- now.setHours(0, 0, 0, 0); // when jumping to a specific last/previous day of week, PHP sets the time to 00:00:00
- }
- }
- break;
-
- default:
- if (/\d+/.test(m[0])) {
- num *= parseInt(m[0], 10);
-
- switch (m[1].substring(0, 3)) {
- case 'yea':
- now.setFullYear(now.getFullYear() + num);
- break;
- case 'mon':
- now.setMonth(now.getMonth() + num);
- break;
- case 'wee':
- now.setDate(now.getDate() + (num * 7));
- break;
- case 'day':
- now.setDate(now.getDate() + num);
- break;
- case 'hou':
- now.setHours(now.getHours() + num);
- break;
- case 'min':
- now.setMinutes(now.getMinutes() + num);
- break;
- case 'sec':
- now.setSeconds(now.getSeconds() + num);
- break;
- }
- } else {
- return false;
- }
- break;
- }
- return true;
- };
-
- match = str.match(/^(\d{2,4}-\d{2}-\d{2})(?:\s(\d{1,2}:\d{2}(:\d{2})?)?(?:\.(\d+))?)?$/);
- if (match !== null) {
- if (!match[2]) {
- match[2] = '00:00:00';
- } else if (!match[3]) {
- match[2] += ':00';
- }
-
- s = match[1].split(/-/g);
-
- s[1] = __is.mon[s[1] - 1] || s[1];
- s[0] = +s[0];
-
- s[0] = (s[0] >= 0 && s[0] <= 69) ? '20' + (s[0] < 10 ? '0' + s[0] : s[0] + '') : (s[0] >= 70 && s[0] <= 99) ? '19' + s[0] : s[0] + '';
- return parseInt(this.strtotime(s[2] + ' ' + s[1] + ' ' + s[0] + ' ' + match[2]) + (match[4] ? match[4] / 1000 : ''), 10);
- }
-
- var regex = '([+-]?\\d+\\s' + '(years?|months?|weeks?|days?|hours?|min|minutes?|sec|seconds?' + '|sun\\.?|sunday|mon\\.?|monday|tue\\.?|tuesday|wed\\.?|wednesday' + '|thu\\.?|thursday|fri\\.?|friday|sat\\.?|saturday)' + '|(last|next)\\s' + '(years?|months?|weeks?|days?|hours?|min|minutes?|sec|seconds?' + '|sun\\.?|sunday|mon\\.?|monday|tue\\.?|tuesday|wed\\.?|wednesday' + '|thu\\.?|thursday|fri\\.?|friday|sat\\.?|saturday))' + '(\\sago)?';
-
- match = str.match(new RegExp(regex, 'gi')); // Brett: seems should be case insensitive per docs, so added 'i'
- if (match === null) {
- // Try to parse ISO8601 in IE8
- try {
- num = Twig.lib.parseISO8601Date(upperCaseStr);
- if (num) {
- return num / 1000 | 0;
- }
- } catch (err) {
- return false;
- }
- return false;
- }
-
- for (i = 0, l = match.length; i < l; i++) {
- if (!process(match[i].split(' '))) {
- return false;
- }
- }
-
- return now.getTime() / 1000 | 0;
+ Twig.lib.strtotime = function (text, now) {
+ // discuss at: http://phpjs.org/functions/strtotime/
+ // version: 1109.2016
+ // original by: Caio Ariede (http://caioariede.com)
+ // improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
+ // improved by: Caio Ariede (http://caioariede.com)
+ // improved by: A. Matías Quezada (http://amatiasq.com)
+ // improved by: preuter
+ // improved by: Brett Zamir (http://brett-zamir.me)
+ // improved by: Mirko Faber
+ // input by: David
+ // bugfixed by: Wagner B. Soares
+ // bugfixed by: Artur Tchernychev
+ // bugfixed by: Stephan Bösch-Plepelits (http://github.com/plepe)
+ // note: Examples all have a fixed timestamp to prevent tests to fail because of variable time(zones)
+ // example 1: strtotime('+1 day', 1129633200);
+ // returns 1: 1129719600
+ // example 2: strtotime('+1 week 2 days 4 hours 2 seconds', 1129633200);
+ // returns 2: 1130425202
+ // example 3: strtotime('last month', 1129633200);
+ // returns 3: 1127041200
+ // example 4: strtotime('2009-05-04 08:30:00 GMT');
+ // returns 4: 1241425800
+ // example 5: strtotime('2009-05-04 08:30:00+00');
+ // returns 5: 1241425800
+ // example 6: strtotime('2009-05-04 08:30:00+02:00');
+ // returns 6: 1241418600
+ // example 7: strtotime('2009-05-04T08:30:00Z');
+ // returns 7: 1241425800
+
+ var parsed, match, today, year, date, days, ranges, len, times, regex, i, fail = false;
+
+ if (!text) {
+ return fail;
+ }
+
+ // Unecessary spaces
+ text = text.replace(/^\s+|\s+$/g, '')
+ .replace(/\s{2,}/g, ' ')
+ .replace(/[\t\r\n]/g, '')
+ .toLowerCase();
+
+ // in contrast to php, js Date.parse function interprets:
+ // dates given as yyyy-mm-dd as in timezone: UTC,
+ // dates with "." or "-" as MDY instead of DMY
+ // dates with two-digit years differently
+ // etc...etc...
+ // ...therefore we manually parse lots of common date formats
+ match = text.match(
+ /^(\d{1,4})([\-\.\/\:])(\d{1,2})([\-\.\/\:])(\d{1,4})(?:\s(\d{1,2}):(\d{2})?:?(\d{2})?)?(?:\s([A-Z]+)?)?$/);
+
+ if (match && match[2] === match[4]) {
+ if (match[1] > 1901) {
+ switch (match[2]) {
+ case '-':
+ {
+ // YYYY-M-D
+ if (match[3] > 12 || match[5] > 31) {
+ return fail;
+ }
+
+ return new Date(match[1], parseInt(match[3], 10) - 1, match[5],
+ match[6] || 0, match[7] || 0, match[8] || 0, match[9] || 0) / 1000;
+ }
+ case '.':
+ {
+ // YYYY.M.D is not parsed by strtotime()
+ return fail;
+ }
+ case '/':
+ {
+ // YYYY/M/D
+ if (match[3] > 12 || match[5] > 31) {
+ return fail;
+ }
+
+ return new Date(match[1], parseInt(match[3], 10) - 1, match[5],
+ match[6] || 0, match[7] || 0, match[8] || 0, match[9] || 0) / 1000;
+ }
+ }
+ } else if (match[5] > 1901) {
+ switch (match[2]) {
+ case '-':
+ {
+ // D-M-YYYY
+ if (match[3] > 12 || match[1] > 31) {
+ return fail;
+ }
+
+ return new Date(match[5], parseInt(match[3], 10) - 1, match[1],
+ match[6] || 0, match[7] || 0, match[8] || 0, match[9] || 0) / 1000;
+ }
+ case '.':
+ {
+ // D.M.YYYY
+ if (match[3] > 12 || match[1] > 31) {
+ return fail;
+ }
+
+ return new Date(match[5], parseInt(match[3], 10) - 1, match[1],
+ match[6] || 0, match[7] || 0, match[8] || 0, match[9] || 0) / 1000;
+ }
+ case '/':
+ {
+ // M/D/YYYY
+ if (match[1] > 12 || match[3] > 31) {
+ return fail;
+ }
+
+ return new Date(match[5], parseInt(match[1], 10) - 1, match[3],
+ match[6] || 0, match[7] || 0, match[8] || 0, match[9] || 0) / 1000;
+ }
+ }
+ } else {
+ switch (match[2]) {
+ case '-':
+ {
+ // YY-M-D
+ if (match[3] > 12 || match[5] > 31 || (match[1] < 70 && match[1] > 38)) {
+ return fail;
+ }
+
+ year = match[1] >= 0 && match[1] <= 38 ? +match[1] + 2000 : match[1];
+ return new Date(year, parseInt(match[3], 10) - 1, match[5],
+ match[6] || 0, match[7] || 0, match[8] || 0, match[9] || 0) / 1000;
+ }
+ case '.':
+ {
+ // D.M.YY or H.MM.SS
+ if (match[5] >= 70) {
+ // D.M.YY
+ if (match[3] > 12 || match[1] > 31) {
+ return fail;
+ }
+
+ return new Date(match[5], parseInt(match[3], 10) - 1, match[1],
+ match[6] || 0, match[7] || 0, match[8] || 0, match[9] || 0) / 1000;
+ }
+ if (match[5] < 60 && !match[6]) {
+ // H.MM.SS
+ if (match[1] > 23 || match[3] > 59) {
+ return fail;
+ }
+
+ today = new Date();
+ return new Date(today.getFullYear(), today.getMonth(), today.getDate(),
+ match[1] || 0, match[3] || 0, match[5] || 0, match[9] || 0) / 1000;
+ }
+
+ // invalid format, cannot be parsed
+ return fail;
+ }
+ case '/':
+ {
+ // M/D/YY
+ if (match[1] > 12 || match[3] > 31 || (match[5] < 70 && match[5] > 38)) {
+ return fail;
+ }
+
+ year = match[5] >= 0 && match[5] <= 38 ? +match[5] + 2000 : match[5];
+ return new Date(year, parseInt(match[1], 10) - 1, match[3],
+ match[6] || 0, match[7] || 0, match[8] || 0, match[9] || 0) / 1000;
+ }
+ case ':':
+ {
+ // HH:MM:SS
+ if (match[1] > 23 || match[3] > 59 || match[5] > 59) {
+ return fail;
+ }
+
+ today = new Date();
+ return new Date(today.getFullYear(), today.getMonth(), today.getDate(),
+ match[1] || 0, match[3] || 0, match[5] || 0) / 1000;
+ }
+ }
+ }
+ }
+
+ // other formats and "now" should be parsed by Date.parse()
+ if (text === 'now') {
+ return now === null || isNaN(now) ? new Date()
+ .getTime() / 1000 | 0 : now | 0;
+ }
+ if (!isNaN(parsed = Date.parse(text))) {
+ return parsed / 1000 | 0;
+ }
+ // Browsers != Chrome have problems parsing ISO 8601 date strings, as they do
+ // not accept lower case characters, space, or shortened time zones.
+ // Therefore, fix these problems and try again.
+ // Examples:
+ // 2015-04-15 20:33:59+02
+ // 2015-04-15 20:33:59z
+ // 2015-04-15t20:33:59+02:00
+ if (match = text.match(/^([0-9]{4}-[0-9]{2}-[0-9]{2})[ t]([0-9]{2}:[0-9]{2}:[0-9]{2}(\.[0-9]+)?)([\+-][0-9]{2}(:[0-9]{2})?|z)/)) {
+ // fix time zone information
+ if (match[4] == 'z') {
+ match[4] = 'Z';
+ }
+ else if (match[4].match(/^([\+-][0-9]{2})$/)) {
+ match[4] = match[4] + ':00';
+ }
+
+ if (!isNaN(parsed = Date.parse(match[1] + 'T' + match[2] + match[4]))) {
+ return parsed / 1000 | 0;
+ }
+ }
+
+ date = now ? new Date(now * 1000) : new Date();
+ days = {
+ 'sun': 0,
+ 'mon': 1,
+ 'tue': 2,
+ 'wed': 3,
+ 'thu': 4,
+ 'fri': 5,
+ 'sat': 6
+ };
+ ranges = {
+ 'yea': 'FullYear',
+ 'mon': 'Month',
+ 'day': 'Date',
+ 'hou': 'Hours',
+ 'min': 'Minutes',
+ 'sec': 'Seconds'
+ };
+
+ function lastNext(type, range, modifier) {
+ var diff, day = days[range];
+
+ if (typeof day !== 'undefined') {
+ diff = day - date.getDay();
+
+ if (diff === 0) {
+ diff = 7 * modifier;
+ } else if (diff > 0 && type === 'last') {
+ diff -= 7;
+ } else if (diff < 0 && type === 'next') {
+ diff += 7;
+ }
+
+ date.setDate(date.getDate() + diff);
+ }
+ }
+
+ function process(val) {
+ var splt = val.split(' '), // Todo: Reconcile this with regex using \s, taking into account browser issues with split and regexes
+ type = splt[0],
+ range = splt[1].substring(0, 3),
+ typeIsNumber = /\d+/.test(type),
+ ago = splt[2] === 'ago',
+ num = (type === 'last' ? -1 : 1) * (ago ? -1 : 1);
+
+ if (typeIsNumber) {
+ num *= parseInt(type, 10);
+ }
+
+ if (ranges.hasOwnProperty(range) && !splt[1].match(/^mon(day|\.)?$/i)) {
+ return date['set' + ranges[range]](date['get' + ranges[range]]() + num);
+ }
+
+ if (range === 'wee') {
+ return date.setDate(date.getDate() + (num * 7));
+ }
+
+ if (type === 'next' || type === 'last') {
+ lastNext(type, range, num);
+ } else if (!typeIsNumber) {
+ return false;
+ }
+
+ return true;
+ }
+
+ times = '(years?|months?|weeks?|days?|hours?|minutes?|min|seconds?|sec' +
+ '|sunday|sun\\.?|monday|mon\\.?|tuesday|tue\\.?|wednesday|wed\\.?' +
+ '|thursday|thu\\.?|friday|fri\\.?|saturday|sat\\.?)';
+ regex = '([+-]?\\d+\\s' + times + '|' + '(last|next)\\s' + times + ')(\\sago)?';
+
+ match = text.match(new RegExp(regex, 'gi'));
+ if (!match) {
+ return fail;
+ }
+
+ for (i = 0, len = match.length; i < len; i++) {
+ if (!process(match[i])) {
+ return fail;
+ }
+ }
+
+ // ECMAScript 5 only
+ // if (!match.every(process))
+ // return false;
+
+ return (date.getTime() / 1000);
};
Twig.lib.is = function(type, obj) {
@@ -1776,13 +2372,236 @@ var Twig = (function(Twig) {
}
return (isHalf ? value : Math.round(value)) / m;
- }
+ };
+
+ Twig.lib.max = function max() {
+ // discuss at: http://phpjs.org/functions/max/
+ // original by: Onno Marsman
+ // revised by: Onno Marsman
+ // improved by: Jack
+ // note: Long code cause we're aiming for maximum PHP compatibility
+ // example 1: max(1, 3, 5, 6, 7);
+ // returns 1: 7
+ // example 2: max([2, 4, 5]);
+ // returns 2: 5
+ // example 3: max(0, 'hello');
+ // returns 3: 0
+ // example 4: max('hello', 0);
+ // returns 4: 'hello'
+ // example 5: max(-1, 'hello');
+ // returns 5: 'hello'
+ // example 6: max([2, 4, 8], [2, 5, 7]);
+ // returns 6: [2, 5, 7]
+
+ var ar, retVal, i = 0,
+ n = 0,
+ argv = arguments,
+ argc = argv.length,
+ _obj2Array = function(obj) {
+ if (Object.prototype.toString.call(obj) === '[object Array]') {
+ return obj;
+ } else {
+ var ar = [];
+ for (var i in obj) {
+ if (obj.hasOwnProperty(i)) {
+ ar.push(obj[i]);
+ }
+ }
+ return ar;
+ }
+ }, //function _obj2Array
+ _compare = function(current, next) {
+ var i = 0,
+ n = 0,
+ tmp = 0,
+ nl = 0,
+ cl = 0;
+
+ if (current === next) {
+ return 0;
+ } else if (typeof current === 'object') {
+ if (typeof next === 'object') {
+ current = _obj2Array(current);
+ next = _obj2Array(next);
+ cl = current.length;
+ nl = next.length;
+ if (nl > cl) {
+ return 1;
+ } else if (nl < cl) {
+ return -1;
+ }
+ for (i = 0, n = cl; i < n; ++i) {
+ tmp = _compare(current[i], next[i]);
+ if (tmp == 1) {
+ return 1;
+ } else if (tmp == -1) {
+ return -1;
+ }
+ }
+ return 0;
+ }
+ return -1;
+ } else if (typeof next === 'object') {
+ return 1;
+ } else if (isNaN(next) && !isNaN(current)) {
+ if (current == 0) {
+ return 0;
+ }
+ return (current < 0 ? 1 : -1);
+ } else if (isNaN(current) && !isNaN(next)) {
+ if (next == 0) {
+ return 0;
+ }
+ return (next > 0 ? 1 : -1);
+ }
+
+ if (next == current) {
+ return 0;
+ }
+ return (next > current ? 1 : -1);
+ }; //function _compare
+ if (argc === 0) {
+ throw new Error('At least one value should be passed to max()');
+ } else if (argc === 1) {
+ if (typeof argv[0] === 'object') {
+ ar = _obj2Array(argv[0]);
+ } else {
+ throw new Error('Wrong parameter count for max()');
+ }
+ if (ar.length === 0) {
+ throw new Error('Array must contain at least one element for max()');
+ }
+ } else {
+ ar = argv;
+ }
+
+ retVal = ar[0];
+ for (i = 1, n = ar.length; i < n; ++i) {
+ if (_compare(retVal, ar[i]) == 1) {
+ retVal = ar[i];
+ }
+ }
+
+ return retVal;
+ };
+
+ Twig.lib.min = function min() {
+ // discuss at: http://phpjs.org/functions/min/
+ // original by: Onno Marsman
+ // revised by: Onno Marsman
+ // improved by: Jack
+ // note: Long code cause we're aiming for maximum PHP compatibility
+ // example 1: min(1, 3, 5, 6, 7);
+ // returns 1: 1
+ // example 2: min([2, 4, 5]);
+ // returns 2: 2
+ // example 3: min(0, 'hello');
+ // returns 3: 0
+ // example 4: min('hello', 0);
+ // returns 4: 'hello'
+ // example 5: min(-1, 'hello');
+ // returns 5: -1
+ // example 6: min([2, 4, 8], [2, 5, 7]);
+ // returns 6: [2, 4, 8]
+
+ var ar, retVal, i = 0,
+ n = 0,
+ argv = arguments,
+ argc = argv.length,
+ _obj2Array = function(obj) {
+ if (Object.prototype.toString.call(obj) === '[object Array]') {
+ return obj;
+ }
+ var ar = [];
+ for (var i in obj) {
+ if (obj.hasOwnProperty(i)) {
+ ar.push(obj[i]);
+ }
+ }
+ return ar;
+ }, //function _obj2Array
+ _compare = function(current, next) {
+ var i = 0,
+ n = 0,
+ tmp = 0,
+ nl = 0,
+ cl = 0;
+
+ if (current === next) {
+ return 0;
+ } else if (typeof current === 'object') {
+ if (typeof next === 'object') {
+ current = _obj2Array(current);
+ next = _obj2Array(next);
+ cl = current.length;
+ nl = next.length;
+ if (nl > cl) {
+ return 1;
+ } else if (nl < cl) {
+ return -1;
+ }
+ for (i = 0, n = cl; i < n; ++i) {
+ tmp = _compare(current[i], next[i]);
+ if (tmp == 1) {
+ return 1;
+ } else if (tmp == -1) {
+ return -1;
+ }
+ }
+ return 0;
+ }
+ return -1;
+ } else if (typeof next === 'object') {
+ return 1;
+ } else if (isNaN(next) && !isNaN(current)) {
+ if (current == 0) {
+ return 0;
+ }
+ return (current < 0 ? 1 : -1);
+ } else if (isNaN(current) && !isNaN(next)) {
+ if (next == 0) {
+ return 0;
+ }
+ return (next > 0 ? 1 : -1);
+ }
+
+ if (next == current) {
+ return 0;
+ }
+ return (next > current ? 1 : -1);
+ }; //function _compare
+
+ if (argc === 0) {
+ throw new Error('At least one value should be passed to min()');
+ } else if (argc === 1) {
+ if (typeof argv[0] === 'object') {
+ ar = _obj2Array(argv[0]);
+ } else {
+ throw new Error('Wrong parameter count for min()');
+ }
+
+ if (ar.length === 0) {
+ throw new Error('Array must contain at least one element for min()');
+ }
+ } else {
+ ar = argv;
+ }
+
+ retVal = ar[0];
+
+ for (i = 1, n = ar.length; i < n; ++i) {
+ if (_compare(retVal, ar[i]) == -1) {
+ retVal = ar[i];
+ }
+ }
+
+ return retVal;
+ };
return Twig;
})(Twig || { });
// Twig.js
-// Copyright (c) 2011-2013 John Roepke
// Available under the BSD 2-Clause License
// https://github.com/justjohn/twig.js
@@ -1812,6 +2631,7 @@ var Twig = (function (Twig) {
endset: 'Twig.logic.type.endset',
filter: 'Twig.logic.type.filter',
endfilter: 'Twig.logic.type.endfilter',
+ shortblock: 'Twig.logic.type.shortblock',
block: 'Twig.logic.type.block',
endblock: 'Twig.logic.type.endblock',
extends_: 'Twig.logic.type.extends',
@@ -1822,7 +2642,9 @@ var Twig = (function (Twig) {
macro: 'Twig.logic.type.macro',
endmacro: 'Twig.logic.type.endmacro',
import_: 'Twig.logic.type.import',
- from: 'Twig.logic.type.from'
+ from: 'Twig.logic.type.from',
+ embed: 'Twig.logic.type.embed',
+ endembed: 'Twig.logic.type.endembed'
};
@@ -1855,7 +2677,7 @@ var Twig = (function (Twig) {
* Format: {% if expression %}
*/
type: Twig.logic.type.if_,
- regex: /^if\s+([^\s].+)$/,
+ regex: /^if\s+([\s\S]+)$/,
next: [
Twig.logic.type.else_,
Twig.logic.type.elseif,
@@ -2024,8 +2846,8 @@ var Twig = (function (Twig) {
// Parse expression
var result = Twig.expression.parse.apply(this, [token.expression, context]),
output = [],
- len,
- index = 0,
+ len,
+ index = 0,
keyset,
that = this,
conditional = token.conditional,
@@ -2042,10 +2864,12 @@ var Twig = (function (Twig) {
parent: context
};
},
+ // run once for each iteration of the loop
loop = function(key, value) {
- var inner_context = Twig.lib.copy(context);
+ var inner_context = Twig.ChildContext(context);
inner_context[token.value_var] = value;
+
if (token.key_var) {
inner_context[token.key_var] = key;
}
@@ -2059,22 +2883,32 @@ var Twig = (function (Twig) {
output.push(Twig.parse.apply(that, [token.output, inner_context]));
index += 1;
}
+
+ // Delete loop-related variables from the context
+ delete inner_context['loop'];
+ delete inner_context[token.value_var];
+ delete inner_context[token.key_var];
+
+ // Merge in values that exist in context but have changed
+ // in inner_context.
+ Twig.merge(context, inner_context, true);
};
- if (result instanceof Array) {
+
+ if (Twig.lib.is('Array', result)) {
len = result.length;
Twig.forEach(result, function (value) {
var key = index;
loop(key, value);
});
- } else if (result instanceof Object) {
+ } else if (Twig.lib.is('Object', result)) {
if (result._keys !== undefined) {
keyset = result._keys;
} else {
keyset = Object.keys(result);
}
- len = keyset.length;
+ len = keyset.length;
Twig.forEach(keyset, function(key) {
// Ignore the _keys property, it's internal to twig.js
if (key === "_keys") return;
@@ -2088,7 +2922,7 @@ var Twig = (function (Twig) {
return {
chain: continue_chain,
- output: output.join("")
+ output: Twig.output.apply(this, [output])
};
}
},
@@ -2110,7 +2944,7 @@ var Twig = (function (Twig) {
* Format: {% set key = expression %}
*/
type: Twig.logic.type.set,
- regex: /^set\s+([a-zA-Z0-9_,\s]+)\s*=\s*(.+)$/,
+ regex: /^set\s+([a-zA-Z0-9_,\s]+)\s*=\s*([\s\S]+)$/,
next: [ ],
open: true,
compile: function (token) {
@@ -2132,8 +2966,6 @@ var Twig = (function (Twig) {
var value = Twig.expression.parse.apply(this, [token.expression, context]),
key = token.key;
- // set on both the global and local context
- this.context[key] = value;
context[key] = value;
return {
@@ -2254,23 +3086,44 @@ var Twig = (function (Twig) {
return token;
},
parse: function (token, context, chain) {
- var block_output = "",
- output = "",
- hasParent = this.blocks[token.block] && this.blocks[token.block].indexOf(Twig.placeholders.parent) > -1;
+ var block_output,
+ output,
+ isImported = Twig.indexOf(this.importedBlocks, token.block) > -1,
+ hasParent = this.blocks[token.block] && Twig.indexOf(this.blocks[token.block], Twig.placeholders.parent) > -1;
- // Don't override previous blocks
+ // Don't override previous blocks unless they're imported with "use"
// Loops should be exempted as well.
- if (this.blocks[token.block] === undefined || hasParent || context.loop) {
- block_output = Twig.expression.parse.apply(this, [{
- type: Twig.expression.type.string,
- value: Twig.parse.apply(this, [token.output, context])
- }, context]);
+ if (this.blocks[token.block] === undefined || isImported || hasParent || context.loop || token.overwrite) {
+ if (token.expression) {
+ // Short blocks have output as an expression on the open tag (no body)
+ block_output = Twig.expression.parse.apply(this, [{
+ type: Twig.expression.type.string,
+ value: Twig.expression.parse.apply(this, [token.output, context])
+ }, context]);
+ } else {
+ block_output = Twig.expression.parse.apply(this, [{
+ type: Twig.expression.type.string,
+ value: Twig.parse.apply(this, [token.output, context])
+ }, context]);
+ }
+
+ if (isImported) {
+ // once the block is overridden, remove it from the list of imported blocks
+ this.importedBlocks.splice(this.importedBlocks.indexOf(token.block), 1);
+ }
if (hasParent) {
- this.blocks[token.block] = this.blocks[token.block].replace(Twig.placeholders.parent, block_output);
+ this.blocks[token.block] = Twig.Markup(this.blocks[token.block].replace(Twig.placeholders.parent, block_output));
} else {
this.blocks[token.block] = block_output;
}
+
+ this.originalBlockTokens[token.block] = {
+ type: token.type,
+ block: token.block,
+ output: token.output,
+ overwrite: true
+ };
}
// Check if a child block has been set from a template extending this one.
@@ -2286,6 +3139,32 @@ var Twig = (function (Twig) {
};
}
},
+ {
+ /**
+ * Block shorthand logic tokens.
+ *
+ * Format: {% block title expression %}
+ */
+ type: Twig.logic.type.shortblock,
+ regex: /^block\s+([a-zA-Z0-9_]+)\s+(.+)$/,
+ next: [ ],
+ open: true,
+ compile: function (token) {
+ token.expression = token.match[2].trim();
+
+ token.output = Twig.expression.compile({
+ type: Twig.expression.type.expression,
+ value: token.expression
+ }).stack;
+
+ token.block = token.match[1].trim();
+ delete token.match;
+ return token;
+ },
+ parse: function (token, context, chain) {
+ return Twig.logic.handler[Twig.logic.type.block].parse.apply(this, arguments);
+ }
+ },
{
/**
* End block logic tokens.
@@ -2335,7 +3214,7 @@ var Twig = (function (Twig) {
/**
* Block logic tokens.
*
- * Format: {% extends "template.twig" %}
+ * Format: {% use "template.twig" %}
*/
type: Twig.logic.type.use,
regex: /^use\s+(.+)$/,
@@ -2372,7 +3251,7 @@ var Twig = (function (Twig) {
* Format: {% includes "template.twig" [with {some: 'values'} only] %}
*/
type: Twig.logic.type.include,
- regex: /^include\s+(ignore missing\s+)?(.+?)\s*(?:with\s+(.+?))?\s*(only)?$/,
+ regex: /^include\s+(ignore missing\s+)?(.+?)\s*(?:with\s+([\S\s]+?))?\s*(only)?$/,
next: [ ],
open: true,
compile: function (token) {
@@ -2409,10 +3288,7 @@ var Twig = (function (Twig) {
template;
if (!token.only) {
- for (i in context) {
- if (context.hasOwnProperty(i))
- innerContext[i] = context[i];
- }
+ innerContext = Twig.ChildContext(context);
}
if (token.withStack !== undefined) {
@@ -2426,8 +3302,12 @@ var Twig = (function (Twig) {
var file = Twig.expression.parse.apply(this, [token.stack, innerContext]);
- // Import file
- template = this.importFile(file);
+ if (file instanceof Twig.Template) {
+ template = file;
+ } else {
+ // Import file
+ template = this.importFile(file);
+ }
return {
chain: chain,
@@ -2474,14 +3354,14 @@ var Twig = (function (Twig) {
*
*/
type: Twig.logic.type.macro,
- regex: /^macro\s+([a-zA-Z0-9_]+)\s?\((([a-zA-Z0-9_]+(,\s?)?)*)\)$/,
+ regex: /^macro\s+([a-zA-Z0-9_]+)\s*\(\s*((?:[a-zA-Z0-9_]+(?:,\s*)?)*)\s*\)$/,
next: [
Twig.logic.type.endmacro
],
open: true,
compile: function (token) {
var macroName = token.match[1],
- parameters = token.match[2].split(/[ ,]+/);
+ parameters = token.match[2].split(/[\s,]+/);
//TODO: Clean up duplicate check
for (var i=0; i -1;
-
} else {
var el;
for (el in b) {
@@ -4089,7 +5066,6 @@ var Twig = (function (Twig) {
})( Twig || { } );
// Twig.js
-// Copyright (c) 2011-2013 John Roepke
// Available under the BSD 2-Clause License
// https://github.com/justjohn/twig.js
@@ -4156,7 +5132,7 @@ var Twig = (function (Twig) {
return value.reverse();
} else if (is("String", value)) {
return value.split("").reverse().join("");
- } else if (value instanceof Object) {
+ } else if (is("Object", value)) {
var keys = value._keys || Object.keys(value).reverse();
value._keys = keys;
return value;
@@ -4165,16 +5141,48 @@ var Twig = (function (Twig) {
sort: function(value) {
if (is("Array", value)) {
return value.sort();
- } else if (value instanceof Object) {
+ } else if (is('Object', value)) {
// Sorting objects isn't obvious since the order of
- // returned keys isn't guaranteedin JavaScript.
+ // returned keys isn't guaranteed in JavaScript.
// Because of this we use a "hidden" key called _keys to
// store the keys in the order we want to return them.
delete value._keys;
var keys = Object.keys(value),
sorted_keys = keys.sort(function(a, b) {
- return value[a] > value[b];
+ var a1, a2;
+
+ // if a and b are comparable, we're fine :-)
+ if((value[a] > value[b]) == !(value[a] <= value[b])) {
+ return value[a] > value[b] ? 1 :
+ value[a] < value[b] ? -1 :
+ 0;
+ }
+ // if a and b can be parsed as numbers, we can compare
+ // their numeric value
+ else if(!isNaN(a1 = parseFloat(value[a])) &&
+ !isNaN(b1 = parseFloat(value[b]))) {
+ return a1 > b1 ? 1 :
+ a1 < b1 ? -1 :
+ 0;
+ }
+ // if one of the values is a string, we convert the
+ // other value to string as well
+ else if(typeof value[a] == 'string') {
+ return value[a] > value[b].toString() ? 1 :
+ value[a] < value[b].toString() ? -1 :
+ 0;
+ }
+ else if(typeof value[b] == 'string') {
+ return value[a].toString() > value[b] ? 1 :
+ value[a].toString() < value[b] ? -1 :
+ 0;
+ }
+ // everything failed - return 'null' as sign, that
+ // the values are not comparable
+ else {
+ return null;
+ }
});
value._keys = sorted_keys;
return value;
@@ -4201,7 +5209,9 @@ var Twig = (function (Twig) {
return;
}
- return encodeURIComponent(value);
+ var result = encodeURIComponent(value);
+ result = result.replace("'", "%27");
+ return result;
},
join: function(value, params) {
if (value === undefined || value === null){
@@ -4215,7 +5225,7 @@ var Twig = (function (Twig) {
if (params && params[0]) {
join_str = params[0];
}
- if (value instanceof Array) {
+ if (is("Array", value)) {
output = value;
} else {
keyset = value._keys || Object.keys(value);
@@ -4229,23 +5239,45 @@ var Twig = (function (Twig) {
return output.join(join_str);
},
"default": function(value, params) {
- if (params === undefined || params.length !== 1) {
+ if (params !== undefined && params.length > 1) {
throw new Twig.Error("default filter expects one argument");
}
if (value === undefined || value === null || value === '' ) {
+ if (params === undefined) {
+ return '';
+ }
+
return params[0];
} else {
return value;
}
},
json_encode: function(value) {
- if (value && value.hasOwnProperty( "_keys" ) ) {
- delete value._keys;
- }
if(value === undefined || value === null) {
return "null";
}
- return JSON.stringify(value);
+ else if ((typeof value == 'object') && (is("Array", value))) {
+ output = [];
+
+ Twig.forEach(value, function(v) {
+ output.push(Twig.filters.json_encode(v));
+ });
+
+ return "[" + output.join(",") + "]";
+ }
+ else if (typeof value == 'object') {
+ var keyset = value._keys || Object.keys(value),
+ output = [];
+
+ Twig.forEach(keyset, function(key) {
+ output.push(JSON.stringify(key) + ":" + Twig.filters.json_encode(value[key]));
+ });
+
+ return "{" + output.join(",") + "}";
+ }
+ else {
+ return JSON.stringify(value);
+ }
},
merge: function(value, params) {
var obj = [],
@@ -4253,21 +5285,21 @@ var Twig = (function (Twig) {
keyset = [];
// Check to see if all the objects being merged are arrays
- if (!(value instanceof Array)) {
+ if (!is("Array", value)) {
// Create obj as an Object
obj = { };
} else {
Twig.forEach(params, function(param) {
- if (!(param instanceof Array)) {
+ if (!is("Array", param)) {
obj = { };
}
});
}
- if (!(obj instanceof Array)) {
+ if (!is("Array", obj)) {
obj._keys = [];
}
- if (value instanceof Array) {
+ if (is("Array", value)) {
Twig.forEach(value, function(val) {
if (obj._keys) obj._keys.push(arr_index);
obj[arr_index] = val;
@@ -4295,7 +5327,7 @@ var Twig = (function (Twig) {
// mixin the merge arrays
Twig.forEach(params, function(param) {
- if (param instanceof Array) {
+ if (is("Array", param)) {
Twig.forEach(param, function(val) {
if (obj._keys) obj._keys.push(arr_index);
obj[arr_index] = val;
@@ -4321,12 +5353,9 @@ var Twig = (function (Twig) {
return obj;
},
date: function(value, params) {
- if (value === undefined||value === null){
- return;
- }
-
var date = Twig.functions.date(value);
- return Twig.lib.formatDate(date, params[0]);
+ var format = params && params.length ? params[0] : 'F j, Y H:i';
+ return Twig.lib.formatDate(date, format);
},
date_modify: function(value, params) {
@@ -4383,20 +5412,92 @@ var Twig = (function (Twig) {
return Twig.lib.strip_tags(value);
},
- escape: function(value) {
+ escape: function(value, params) {
if (value === undefined|| value === null){
return;
}
- return value.toString().replace(/&/g, "&")
- .replace(//g, ">")
- .replace(/"/g, """)
- .replace(/'/g, "'");
+
+ var strategy = "html";
+ if(params && params.length && params[0] !== true)
+ strategy = params[0];
+
+ if(strategy == "html") {
+ var raw_value = value.toString().replace(/&/g, "&")
+ .replace(//g, ">")
+ .replace(/"/g, """)
+ .replace(/'/g, "'");
+ return Twig.Markup(raw_value, 'html');
+ } else if(strategy == "js") {
+ var raw_value = value.toString();
+ var result = "";
+
+ for(var i = 0; i < raw_value.length; i++) {
+ if(raw_value[i].match(/^[a-zA-Z0-9,\._]$/))
+ result += raw_value[i];
+ else {
+ var char_code = raw_value.charCodeAt(i);
+
+ if(char_code < 0x80)
+ result += "\\x" + char_code.toString(16).toUpperCase();
+ else
+ result += Twig.lib.sprintf("\\u%04s", char_code.toString(16).toUpperCase());
+ }
+ }
+
+ return Twig.Markup(result, 'js');
+ } else if(strategy == "css") {
+ var raw_value = value.toString();
+ var result = "";
+
+ for(var i = 0; i < raw_value.length; i++) {
+ if(raw_value[i].match(/^[a-zA-Z0-9]$/))
+ result += raw_value[i];
+ else {
+ var char_code = raw_value.charCodeAt(i);
+ result += "\\" + char_code.toString(16).toUpperCase() + " ";
+ }
+ }
+
+ return Twig.Markup(result, 'css');
+ } else if(strategy == "url") {
+ var result = Twig.filters.url_encode(value);
+ return Twig.Markup(result, 'url');
+ } else if(strategy == "html_attr") {
+ var raw_value = value.toString();
+ var result = "";
+
+ for(var i = 0; i < raw_value.length; i++) {
+ if(raw_value[i].match(/^[a-zA-Z0-9,\.\-_]$/))
+ result += raw_value[i];
+ else if(raw_value[i].match(/^[&<>"]$/))
+ result += raw_value[i].replace(/&/g, "&")
+ .replace(//g, ">")
+ .replace(/"/g, """);
+ else {
+ var char_code = raw_value.charCodeAt(i);
+
+ // The following replaces characters undefined in HTML with
+ // the hex entity for the Unicode replacement character.
+ if(char_code <= 0x1f && char_code != 0x09 && char_code != 0x0a && char_code != 0x0d)
+ result += "�";
+ else if(char_code < 0x80)
+ result += Twig.lib.sprintf("%02s;", char_code.toString(16).toUpperCase());
+ else
+ result += Twig.lib.sprintf("%04s;", char_code.toString(16).toUpperCase());
+ }
+ }
+
+ return Twig.Markup(result, 'html_attr');
+ } else {
+ throw new Twig.Error("escape strategy unsupported");
+ }
},
/* Alias of escape */
- "e": function(value) {
- return Twig.filters.escape(value);
+ "e": function(value, params) {
+ return Twig.filters.escape(value, params);
},
nl2br: function(value) {
@@ -4411,7 +5512,9 @@ var Twig = (function (Twig) {
.replace(/\r/g, br)
.replace(/\n/g, br);
- return Twig.lib.replaceAll(value, linebreak_tag, "\n");
+ value = Twig.lib.replaceAll(value, linebreak_tag, "\n");
+
+ return Twig.Markup(value);
},
/**
@@ -4470,6 +5573,39 @@ var Twig = (function (Twig) {
return whitespace.indexOf(str.charAt(0)) === -1 ? str : '';
},
+ truncate: function (value, params) {
+ var length = 30,
+ preserve = false,
+ separator = '...';
+
+ value = value + '';
+ if (params) {
+ if (params[0]) {
+ length = params[0];
+ }
+ if (params[1]) {
+ preserve = params[1];
+ }
+ if (params[2]) {
+ separator = params[2];
+ }
+ }
+
+ if (value.length > length) {
+
+ if (preserve) {
+ length = value.indexOf(' ', length);
+ if (length === -1) {
+ return value;
+ }
+ }
+
+ value = value.substr(0, length) + separator;
+ }
+
+ return value;
+ },
+
slice: function(value, params) {
if (value === undefined || value === null) {
return;
@@ -4507,9 +5643,9 @@ var Twig = (function (Twig) {
},
first: function(value) {
- if (value instanceof Array) {
+ if (is("Array", value)) {
return value[0];
- } else if (value instanceof Object) {
+ } else if (is("Object", value)) {
if ('_keys' in value) {
return value[value._keys[0]];
}
@@ -4595,8 +5731,7 @@ var Twig = (function (Twig) {
return value[value.length - 1];
},
raw: function(value) {
- //Raw filter shim
- return value;
+ return Twig.Markup(value);
},
batch: function(items, params) {
var size = params.shift(),
@@ -4669,7 +5804,6 @@ var Twig = (function (Twig) {
})(Twig || { });
// Twig.js
-// Copyright (c) 2011-2013 John Roepke
// 2012 Hadrien Lanneau
// Available under the BSD 2-Clause License
// https://github.com/justjohn/twig.js
@@ -4678,6 +5812,11 @@ var Twig = (function (Twig) {
//
// This file handles parsing filters.
var Twig = (function (Twig) {
+ /**
+ * @constant
+ * @type {string}
+ */
+ var TEMPLATE_NOT_FOUND_MESSAGE = 'Template "{name}" is not defined.';
// Determine object type
function is(type, obj) {
@@ -4739,19 +5878,19 @@ var Twig = (function (Twig) {
},
dump: function() {
var EOL = '\n',
- indentChar = ' ',
- indentTimes = 0,
- out = '',
- args = Array.prototype.slice.call(arguments),
- indent = function(times) {
- var ind = '';
+ indentChar = ' ',
+ indentTimes = 0,
+ out = '',
+ args = Array.prototype.slice.call(arguments),
+ indent = function(times) {
+ var ind = '';
while (times > 0) {
times--;
ind += indentChar;
}
return ind;
},
- displayVar = function(variable) {
+ displayVar = function(variable) {
out += indent(indentTimes);
if (typeof(variable) === 'object') {
dumpVar(variable);
@@ -4765,41 +5904,41 @@ var Twig = (function (Twig) {
out += 'bool(' + variable + ')' + EOL;
}
},
- dumpVar = function(variable) {
- var i;
- if (variable === null) {
- out += 'NULL' + EOL;
- } else if (variable === undefined) {
- out += 'undefined' + EOL;
- } else if (typeof variable === 'object') {
- out += indent(indentTimes) + typeof(variable);
- indentTimes++;
- out += '(' + (function(obj) {
- var size = 0, key;
- for (key in obj) {
- if (obj.hasOwnProperty(key)) {
- size++;
- }
- }
- return size;
- })(variable) + ') {' + EOL;
- for (i in variable) {
- out += indent(indentTimes) + '[' + i + ']=> ' + EOL;
- displayVar(variable[i]);
- }
- indentTimes--;
- out += indent(indentTimes) + '}' + EOL;
- } else {
- displayVar(variable);
- }
- };
-
- // handle no argument case by dumping the entire render context
- if (args.length == 0) args.push(this.context);
-
- Twig.forEach(args, function(variable) {
- dumpVar(variable);
- });
+ dumpVar = function(variable) {
+ var i;
+ if (variable === null) {
+ out += 'NULL' + EOL;
+ } else if (variable === undefined) {
+ out += 'undefined' + EOL;
+ } else if (typeof variable === 'object') {
+ out += indent(indentTimes) + typeof(variable);
+ indentTimes++;
+ out += '(' + (function(obj) {
+ var size = 0, key;
+ for (key in obj) {
+ if (obj.hasOwnProperty(key)) {
+ size++;
+ }
+ }
+ return size;
+ })(variable) + ') {' + EOL;
+ for (i in variable) {
+ out += indent(indentTimes) + '[' + i + ']=> ' + EOL;
+ displayVar(variable[i]);
+ }
+ indentTimes--;
+ out += indent(indentTimes) + '}' + EOL;
+ } else {
+ displayVar(variable);
+ }
+ };
+
+ // handle no argument case by dumping the entire render context
+ if (args.length == 0) args.push(this.context);
+
+ Twig.forEach(args, function(variable) {
+ dumpVar(variable);
+ });
return out;
},
@@ -4810,7 +5949,12 @@ var Twig = (function (Twig) {
} else if (Twig.lib.is("Date", date)) {
dateObj = date;
} else if (Twig.lib.is("String", date)) {
- dateObj = new Date(Twig.lib.strtotime(date) * 1000);
+ if (date.match(/^[0-9]+$/)) {
+ dateObj = new Date(date * 1000);
+ }
+ else {
+ dateObj = new Date(Twig.lib.strtotime(date) * 1000);
+ }
} else if (Twig.lib.is("Number", date)) {
// timestamp
dateObj = new Date(date * 1000);
@@ -4820,14 +5964,18 @@ var Twig = (function (Twig) {
return dateObj;
},
block: function(block) {
- return this.blocks[block];
+ if (this.originalBlockTokens[block]) {
+ return Twig.logic.parse.apply(this, [this.originalBlockTokens[block], this.context]).output;
+ } else {
+ return this.blocks[block];
+ }
},
parent: function() {
// Add a placeholder
return Twig.placeholders.parent;
},
attribute: function(object, method, params) {
- if (object instanceof Object) {
+ if (Twig.lib.is('Object', object)) {
if (object.hasOwnProperty(method)) {
if (typeof object[method] === "function") {
return object[method].apply(undefined, params);
@@ -4839,6 +5987,130 @@ var Twig = (function (Twig) {
}
// Array will return element 0-index
return object[method] || undefined;
+ },
+ max: function(values) {
+ if(Twig.lib.is("Object", values)) {
+ delete values["_keys"];
+ return Twig.lib.max(values);
+ }
+
+ return Twig.lib.max.apply(null, arguments);
+ },
+ min: function(values) {
+ if(Twig.lib.is("Object", values)) {
+ delete values["_keys"];
+ return Twig.lib.min(values);
+ }
+
+ return Twig.lib.min.apply(null, arguments);
+ },
+ template_from_string: function(template) {
+ if (template === undefined) {
+ template = '';
+ }
+ return Twig.Templates.parsers.twig({
+ options: this.options,
+ data: template
+ });
+ },
+ random: function(value) {
+ var LIMIT_INT31 = 0x80000000;
+
+ function getRandomNumber(n) {
+ var random = Math.floor(Math.random() * LIMIT_INT31);
+ var limits = [0, n];
+ var min = Math.min.apply(null, limits),
+ max = Math.max.apply(null, limits);
+ return min + Math.floor((max - min + 1) * random / LIMIT_INT31);
+ }
+
+ if(Twig.lib.is("Number", value)) {
+ return getRandomNumber(value);
+ }
+
+ if(Twig.lib.is("String", value)) {
+ return value.charAt(getRandomNumber(value.length-1));
+ }
+
+ if(Twig.lib.is("Array", value)) {
+ return value[getRandomNumber(value.length-1)];
+ }
+
+ if(Twig.lib.is("Object", value)) {
+ var keys = Object.keys(value);
+ return value[keys[getRandomNumber(keys.length-1)]];
+ }
+
+ return getRandomNumber(LIMIT_INT31-1);
+ },
+
+ /**
+ * Returns the content of a template without rendering it
+ * @param {string} name
+ * @param {boolean} [ignore_missing=false]
+ * @returns {string}
+ */
+ source: function(name, ignore_missing) {
+ var templateSource;
+ var templateFound = false;
+ var isNodeEnvironment = typeof module !== 'undefined' && typeof module.exports !== 'undefined' && typeof window === 'undefined';
+ var loader;
+ var path;
+
+ //if we are running in a node.js environment, set the loader to 'fs' and ensure the
+ // path is relative to the CWD of the running script
+ //else, set the loader to 'ajax' and set the path to the value of name
+ if (isNodeEnvironment) {
+ loader = 'fs';
+ path = __dirname + '/' + name;
+ } else {
+ loader = 'ajax';
+ path = name;
+ }
+
+ //build the params object
+ var params = {
+ id: name,
+ path: path,
+ method: loader,
+ parser: 'source',
+ async: false,
+ fetchTemplateSource: true
+ };
+
+ //default ignore_missing to false
+ if (typeof ignore_missing === 'undefined') {
+ ignore_missing = false;
+ }
+
+ //try to load the remote template
+ //
+ //on exception, log it
+ try {
+ templateSource = Twig.Templates.loadRemote(name, params);
+
+ //if the template is undefined or null, set the template to an empty string and do NOT flip the
+ // boolean indicating we found the template
+ //
+ //else, all is good! flip the boolean indicating we found the template
+ if (typeof templateSource === 'undefined' || templateSource === null) {
+ templateSource = '';
+ } else {
+ templateFound = true;
+ }
+ } catch (e) {
+ Twig.log.debug('Twig.functions.source: ', 'Problem loading template ', e);
+ }
+
+ //if the template was NOT found AND we are not ignoring missing templates, return the same message
+ // that is returned by the PHP implementation of the twig source() function
+ //
+ //else, return the template source
+ if (!templateFound && !ignore_missing) {
+ return TEMPLATE_NOT_FOUND_MESSAGE.replace('{name}', name);
+ } else {
+ return templateSource;
+ }
}
};
@@ -4857,7 +6129,119 @@ var Twig = (function (Twig) {
})(Twig || { });
// Twig.js
-// Copyright (c) 2011-2013 John Roepke
+// Available under the BSD 2-Clause License
+// https://github.com/justjohn/twig.js
+
+// ## twig.path.js
+//
+// This file handles path parsing
+var Twig = (function (Twig) {
+ "use strict";
+
+ /**
+ * Namespace for path handling.
+ */
+ Twig.path = {};
+
+ /**
+ * Generate the canonical version of a url based on the given base path and file path and in
+ * the previously registered namespaces.
+ *
+ * @param {string} template The Twig Template
+ * @param {string} file The file path, may be relative and may contain namespaces.
+ *
+ * @return {string} The canonical version of the path
+ */
+ Twig.path.parsePath = function(template, file) {
+ var namespaces = null,
+ file = file || "";
+
+ if (typeof template === 'object' && typeof template.options === 'object') {
+ namespaces = template.options.namespaces;
+ }
+
+ if (typeof namespaces === 'object' && (file.indexOf('::') > 0) || file.indexOf('@') >= 0){
+ for (var k in namespaces){
+ if (namespaces.hasOwnProperty(k)) {
+ file = file.replace(k + '::', namespaces[k]);
+ file = file.replace('@' + k, namespaces[k]);
+ }
+ }
+
+ return file;
+ }
+
+ return Twig.path.relativePath(template, file);
+ };
+
+ /**
+ * Generate the relative canonical version of a url based on the given base path and file path.
+ *
+ * @param {Twig.Template} template The Twig.Template.
+ * @param {string} file The file path, relative to the base path.
+ *
+ * @return {string} The canonical version of the path.
+ */
+ Twig.path.relativePath = function(template, file) {
+ var base,
+ base_path,
+ sep_chr = "/",
+ new_path = [],
+ file = file || "",
+ val;
+
+ if (template.url) {
+ if (typeof template.base !== 'undefined') {
+ base = template.base + ((template.base.charAt(template.base.length-1) === '/') ? '' : '/');
+ } else {
+ base = template.url;
+ }
+ } else if (template.path) {
+ // Get the system-specific path separator
+ var path = require("path"),
+ sep = path.sep || sep_chr,
+ relative = new RegExp("^\\.{1,2}" + sep.replace("\\", "\\\\"));
+ file = file.replace(/\//g, sep);
+
+ if (template.base !== undefined && file.match(relative) == null) {
+ file = file.replace(template.base, '');
+ base = template.base + sep;
+ } else {
+ base = path.normalize(template.path);
+ }
+
+ base = base.replace(sep+sep, sep);
+ sep_chr = sep;
+ } else if ((template.name || template.id) && template.method && template.method !== 'fs' && template.method !== 'ajax') {
+ // Custom registered loader
+ base = template.base || template.name || template.id;
+ } else {
+ throw new Twig.Error("Cannot extend an inline template.");
+ }
+
+ base_path = base.split(sep_chr);
+
+ // Remove file from url
+ base_path.pop();
+ base_path = base_path.concat(file.split(sep_chr));
+
+ while (base_path.length > 0) {
+ val = base_path.shift();
+ if (val == ".") {
+ // Ignore
+ } else if (val == ".." && new_path.length > 0 && new_path[new_path.length-1] != "..") {
+ new_path.pop();
+ } else {
+ new_path.push(val);
+ }
+ }
+
+ return new_path.join(sep_chr);
+ };
+
+ return Twig;
+}) (Twig || { });
+// Twig.js
// Available under the BSD 2-Clause License
// https://github.com/justjohn/twig.js
@@ -4899,6 +6283,9 @@ var Twig = (function (Twig) {
},
sameas: function(value, params) {
return value === params[0];
+ },
+ iterable: function(value) {
+ return value && (Twig.lib.is("Array", value) || Twig.lib.is("Object", value));
}
/*
constant ?
@@ -4919,7 +6306,6 @@ var Twig = (function (Twig) {
return Twig;
})( Twig || { } );
// Twig.js
-// Copyright (c) 2011-2013 John Roepke
// Available under the BSD 2-Clause License
// https://github.com/justjohn/twig.js
@@ -4944,12 +6330,15 @@ var Twig = (function (Twig) {
'use strict';
var id = params.id,
options = {
- strict_variables: params.strict_variables || false,
+ strictVariables: params.strictVariables || false,
+ // TODO: turn autoscape on in the next major version
+ autoescape: params.autoescape != null && params.autoescape || false,
allowInlineIncludes: params.allowInlineIncludes || false,
- rethrow: params.rethrow || false
+ rethrow: params.rethrow || false,
+ namespaces: params.namespaces
};
- if (id) {
+ if (Twig.cache && id) {
Twig.validateId(id);
}
@@ -4961,8 +6350,9 @@ var Twig = (function (Twig) {
}
if (params.data !== undefined) {
- return new Twig.Template({
+ return Twig.Templates.parsers.twig({
data: params.data,
+ path: params.hasOwnProperty('path') ? params.path : undefined,
module: params.module,
id: id,
options: options
@@ -4974,10 +6364,27 @@ var Twig = (function (Twig) {
}
return Twig.Templates.load(params.ref);
+ } else if (params.method !== undefined) {
+ if (!Twig.Templates.isRegisteredLoader(params.method)) {
+ throw new Twig.Error('Loader for "' + params.method + '" is not defined.');
+ }
+ return Twig.Templates.loadRemote(params.name || params.href || params.path || id || undefined, {
+ id: id,
+ method: params.method,
+ parser: params.parser || 'twig',
+ base: params.base,
+ module: params.module,
+ precompiled: params.precompiled,
+ async: params.async,
+ options: options
+
+ }, params.load, params.error);
+
} else if (params.href !== undefined) {
return Twig.Templates.loadRemote(params.href, {
id: id,
method: 'ajax',
+ parser: params.parser || 'twig',
base: params.base,
module: params.module,
precompiled: params.precompiled,
@@ -4990,6 +6397,7 @@ var Twig = (function (Twig) {
return Twig.Templates.loadRemote(params.path, {
id: id,
method: 'fs',
+ parser: params.parser || 'twig',
base: params.base,
module: params.module,
precompiled: params.precompiled,
@@ -5059,32 +6467,37 @@ var Twig = (function (Twig) {
* @param {string} path The location of the template file on disk.
* @param {Object|Function} The options or callback.
* @param {Function} fn callback.
+ *
+ * @throws Twig.Error
*/
-
Twig.exports.renderFile = function(path, options, fn) {
// handle callback in options
- if ('function' == typeof options) {
+ if (typeof options === 'function') {
fn = options;
options = {};
}
options = options || {};
+ var settings = options.settings || {};
+
var params = {
- path: path,
- base: options.settings['views'],
- load: function(template) {
- // render and return template
- fn(null, template.render(options));
- }
- };
+ path: path,
+ base: settings.views,
+ load: function(template) {
+ // render and return template
+ fn(null, template.render(options));
+ }
+ };
// mixin any options provided to the express app.
- var view_options = options.settings['twig options'];
+ var view_options = settings['twig options'];
if (view_options) {
- for (var option in view_options) if (view_options.hasOwnProperty(option)) {
- params[option] = view_options[option];
+ for (var option in view_options) {
+ if (view_options.hasOwnProperty(option)) {
+ params[option] = view_options[option];
+ }
}
}
@@ -5103,13 +6516,15 @@ var Twig = (function (Twig) {
*/
Twig.exports.cache = function(cache) {
Twig.cache = cache;
- }
+ };
+
+ //We need to export the path module so we can effectively test it
+ Twig.exports.path = Twig.path;
return Twig;
}) (Twig || { });
// Twig.js
-// Copyright (c) 2011-2013 John Roepke
// Available under the BSD 2-Clause License
// https://github.com/justjohn/twig.js
@@ -5165,7 +6580,6 @@ var Twig = (function (Twig) {
return Twig;
})(Twig || {});
// Twig.js
-// Copyright (c) 2011-2013 John Roepke
// Available under the BSD 2-Clause License
// https://github.com/justjohn/twig.js
diff --git a/demos/node_express/public/vendor/zepto.history.js b/demos/node_express/public/vendor/zepto.history.js
index c1e0baf9..1f416039 100644
--- a/demos/node_express/public/vendor/zepto.history.js
+++ b/demos/node_express/public/vendor/zepto.history.js
@@ -1 +1,480 @@
-window.JSON||(window.JSON={}),function(){function f(a){return a<10?"0"+a:a}function quote(a){return escapable.lastIndex=0,escapable.test(a)?'"'+a.replace(escapable,function(a){var b=meta[a];return typeof b=="string"?b:"\\u"+("0000"+a.charCodeAt(0).toString(16)).slice(-4)})+'"':'"'+a+'"'}function str(a,b){var c,d,e,f,g=gap,h,i=b[a];i&&typeof i=="object"&&typeof i.toJSON=="function"&&(i=i.toJSON(a)),typeof rep=="function"&&(i=rep.call(b,a,i));switch(typeof i){case"string":return quote(i);case"number":return isFinite(i)?String(i):"null";case"boolean":case"null":return String(i);case"object":if(!i)return"null";gap+=indent,h=[];if(Object.prototype.toString.apply(i)==="[object Array]"){f=i.length;for(c=0;c ")&&c[0]);return a>4?a:!1}();return a},m.isInternetExplorer=function(){var a=m.isInternetExplorer.cached=typeof m.isInternetExplorer.cached!="undefined"?m.isInternetExplorer.cached:Boolean(m.getInternetExplorerMajorVersion());return a},m.emulated={pushState:!Boolean(a.history&&a.history.pushState&&a.history.replaceState&&!/ Mobile\/([1-7][a-z]|(8([abcde]|f(1[0-8]))))/i.test(e.userAgent)&&!/AppleWebKit\/5([0-2]|3[0-2])/i.test(e.userAgent)),hashChange:Boolean(!("onhashchange"in a||"onhashchange"in d)||m.isInternetExplorer()&&m.getInternetExplorerMajorVersion()<8)},m.enabled=!m.emulated.pushState,m.bugs={setHash:Boolean(!m.emulated.pushState&&e.vendor==="Apple Computer, Inc."&&/AppleWebKit\/5([0-2]|3[0-3])/.test(e.userAgent)),safariPoll:Boolean(!m.emulated.pushState&&e.vendor==="Apple Computer, Inc."&&/AppleWebKit\/5([0-2]|3[0-3])/.test(e.userAgent)),ieDoubleCheck:Boolean(m.isInternetExplorer()&&m.getInternetExplorerMajorVersion()<8),hashEscape:Boolean(m.isInternetExplorer()&&m.getInternetExplorerMajorVersion()<7)},m.isEmptyObject=function(a){for(var b in a)return!1;return!0},m.cloneObject=function(a){var b,c;return a?(b=k.stringify(a),c=k.parse(b)):c={},c},m.getRootUrl=function(){var a=d.location.protocol+"//"+(d.location.hostname||d.location.host);if(d.location.port||!1)a+=":"+d.location.port;return a+="/",a},m.getBaseHref=function(){var a=d.getElementsByTagName("base"),b=null,c="";return a.length===1&&(b=a[0],c=b.href.replace(/[^\/]+$/,"")),c=c.replace(/\/+$/,""),c&&(c+="/"),c},m.getBaseUrl=function(){var a=m.getBaseHref()||m.getBasePageUrl()||m.getRootUrl();return a},m.getPageUrl=function(){var a=m.getState(!1,!1),b=(a||{}).url||d.location.href,c;return c=b.replace(/\/+$/,"").replace(/[^\/]+$/,function(a,b,c){return/\./.test(a)?a:a+"/"}),c},m.getBasePageUrl=function(){var a=d.location.href.replace(/[#\?].*/,"").replace(/[^\/]+$/,function(a,b,c){return/[^\/]$/.test(a)?"":a}).replace(/\/+$/,"")+"/";return a},m.getFullUrl=function(a,b){var c=a,d=a.substring(0,1);return b=typeof b=="undefined"?!0:b,/[a-z]+\:\/\//.test(a)||(d==="/"?c=m.getRootUrl()+a.replace(/^\/+/,""):d==="#"?c=m.getPageUrl().replace(/#.*/,"")+a:d==="?"?c=m.getPageUrl().replace(/[\?#].*/,"")+a:b?c=m.getBaseUrl()+a.replace(/^(\.\/)+/,""):c=m.getBasePageUrl()+a.replace(/^(\.\/)+/,"")),c.replace(/\#$/,"")},m.getShortUrl=function(a){var b=a,c=m.getBaseUrl(),d=m.getRootUrl();return m.emulated.pushState&&(b=b.replace(c,"")),b=b.replace(d,"/"),m.isTraditionalAnchor(b)&&(b="./"+b),b=b.replace(/^(\.\/)+/g,"./").replace(/\#$/,""),b},m.store={},m.idToState=m.idToState||{},m.stateToId=m.stateToId||{},m.urlToId=m.urlToId||{},m.storedStates=m.storedStates||[],m.savedStates=m.savedStates||[],m.normalizeStore=function(){m.store.idToState=m.store.idToState||{},m.store.urlToId=m.store.urlToId||{},m.store.stateToId=m.store.stateToId||{}},m.getState=function(a,b){typeof a=="undefined"&&(a=!0),typeof b=="undefined"&&(b=!0);var c=m.getLastSavedState();return!c&&b&&(c=m.createStateObject()),a&&(c=m.cloneObject(c),c.url=c.cleanUrl||c.url),c},m.getIdByState=function(a){var b=m.extractId(a.url),c;if(!b){c=m.getStateString(a);if(typeof m.stateToId[c]!="undefined")b=m.stateToId[c];else if(typeof m.store.stateToId[c]!="undefined")b=m.store.stateToId[c];else{for(;;){b=(new Date).getTime()+String(Math.random()).replace(/\D/g,"");if(typeof m.idToState[b]=="undefined"&&typeof m.store.idToState[b]=="undefined")break}m.stateToId[c]=b,m.idToState[b]=a}}return b},m.normalizeState=function(a){var b,c;if(!a||typeof a!="object")a={};if(typeof a.normalized!="undefined")return a;if(!a.data||typeof a.data!="object")a.data={};b={},b.normalized=!0,b.title=a.title||"",b.url=m.getFullUrl(m.unescapeString(a.url||d.location.href)),b.hash=m.getShortUrl(b.url),b.data=m.cloneObject(a.data),b.id=m.getIdByState(b),b.cleanUrl=b.url.replace(/\??\&_suid.*/,""),b.url=b.cleanUrl,c=!m.isEmptyObject(b.data);if(b.title||c)b.hash=m.getShortUrl(b.url).replace(/\??\&_suid.*/,""),/\?/.test(b.hash)||(b.hash+="?"),b.hash+="&_suid="+b.id;return b.hashedUrl=m.getFullUrl(b.hash),(m.emulated.pushState||m.bugs.safariPoll)&&m.hasUrlDuplicate(b)&&(b.url=b.hashedUrl),b},m.createStateObject=function(a,b,c){var d={data:a,title:b,url:c};return d=m.normalizeState(d),d},m.getStateById=function(a){a=String(a);var c=m.idToState[a]||m.store.idToState[a]||b;return c},m.getStateString=function(a){var b,c,d;return b=m.normalizeState(a),c={data:b.data,title:a.title,url:a.url},d=k.stringify(c),d},m.getStateId=function(a){var b,c;return b=m.normalizeState(a),c=b.id,c},m.getHashByState=function(a){var b,c;return b=m.normalizeState(a),c=b.hash,c},m.extractId=function(a){var b,c,d;return c=/(.*)\&_suid=([0-9]+)$/.exec(a),d=c?c[1]||a:a,b=c?String(c[2]||""):"",b||!1},m.isTraditionalAnchor=function(a){var b=!/[\/\?\.]/.test(a);return b},m.extractState=function(a,b){var c=null,d,e;return b=b||!1,d=m.extractId(a),d&&(c=m.getStateById(d)),c||(e=m.getFullUrl(a),d=m.getIdByUrl(e)||!1,d&&(c=m.getStateById(d)),!c&&b&&!m.isTraditionalAnchor(a)&&(c=m.createStateObject(null,null,e))),c},m.getIdByUrl=function(a){var c=m.urlToId[a]||m.store.urlToId[a]||b;return c},m.getLastSavedState=function(){return m.savedStates[m.savedStates.length-1]||b},m.getLastStoredState=function(){return m.storedStates[m.storedStates.length-1]||b},m.hasUrlDuplicate=function(a){var b=!1,c;return c=m.extractState(a.url),b=c&&c.id!==a.id,b},m.storeState=function(a){return m.urlToId[a.url]=a.id,m.storedStates.push(m.cloneObject(a)),a},m.isLastSavedState=function(a){var b=!1,c,d,e;return m.savedStates.length&&(c=a.id,d=m.getLastSavedState(),e=d.id,b=c===e),b},m.saveState=function(a){return m.isLastSavedState(a)?!1:(m.savedStates.push(m.cloneObject(a)),!0)},m.getStateByIndex=function(a){var b=null;return typeof a=="undefined"?b=m.savedStates[m.savedStates.length-1]:a<0?b=m.savedStates[m.savedStates.length+a]:b=m.savedStates[a],b},m.getHash=function(){var a=m.unescapeHash(d.location.hash);return a},m.unescapeString=function(b){var c=b,d;for(;;){d=a.unescape(c);if(d===c)break;c=d}return c},m.unescapeHash=function(a){var b=m.normalizeHash(a);return b=m.unescapeString(b),b},m.normalizeHash=function(a){var b=a.replace(/[^#]*#/,"").replace(/#.*/,"");return b},m.setHash=function(a,b){var c,e,f;return b!==!1&&m.busy()?(m.pushQueue({scope:m,callback:m.setHash,args:arguments,queue:b}),!1):(c=m.escapeHash(a),m.busy(!0),e=m.extractState(a,!0),e&&!m.emulated.pushState?m.pushState(e.data,e.title,e.url,!1):d.location.hash!==c&&(m.bugs.setHash?(f=m.getPageUrl(),m.pushState(null,null,f+"#"+c,!1)):d.location.hash=c),m)},m.escapeHash=function(b){var c=m.normalizeHash(b);return c=a.escape(c),m.bugs.hashEscape||(c=c.replace(/\%21/g,"!").replace(/\%26/g,"&").replace(/\%3D/g,"=").replace(/\%3F/g,"?")),c},m.getHashByUrl=function(a){var b=String(a).replace(/([^#]*)#?([^#]*)#?(.*)/,"$2");return b=m.unescapeHash(b),b},m.setTitle=function(a){var b=a.title,c;b||(c=m.getStateByIndex(0),c&&c.url===a.url&&(b=c.title||m.options.initialTitle));try{d.getElementsByTagName("title")[0].innerHTML=b.replace("<","<").replace(">",">").replace(" & "," & ")}catch(e){}return d.title=b,m},m.queues=[],m.busy=function(a){typeof a!="undefined"?m.busy.flag=a:typeof m.busy.flag=="undefined"&&(m.busy.flag=!1);if(!m.busy.flag){h(m.busy.timeout);var b=function(){var a,c,d;if(m.busy.flag)return;for(a=m.queues.length-1;a>=0;--a){c=m.queues[a];if(c.length===0)continue;d=c.shift(),m.fireQueueItem(d),m.busy.timeout=g(b,m.options.busyDelay)}};m.busy.timeout=g(b,m.options.busyDelay)}return m.busy.flag},m.busy.flag=!1,m.fireQueueItem=function(a){return a.callback.apply(a.scope||m,a.args||[])},m.pushQueue=function(a){return m.queues[a.queue||0]=m.queues[a.queue||0]||[],m.queues[a.queue||0].push(a),m},m.queue=function(a,b){return typeof a=="function"&&(a={callback:a}),typeof b!="undefined"&&(a.queue=b),m.busy()?m.pushQueue(a):m.fireQueueItem(a),m},m.clearQueue=function(){return m.busy.flag=!1,m.queues=[],m},m.stateChanged=!1,m.doubleChecker=!1,m.doubleCheckComplete=function(){return m.stateChanged=!0,m.doubleCheckClear(),m},m.doubleCheckClear=function(){return m.doubleChecker&&(h(m.doubleChecker),m.doubleChecker=!1),m},m.doubleCheck=function(a){return m.stateChanged=!1,m.doubleCheckClear(),m.bugs.ieDoubleCheck&&(m.doubleChecker=g(function(){return m.doubleCheckClear(),m.stateChanged||a(),!0},m.options.doubleCheckInterval)),m},m.safariStatePoll=function(){var b=m.extractState(d.location.href),c;if(!m.isLastSavedState(b))c=b;else return;return c||(c=m.createStateObject()),m.Adapter.trigger(a,"popstate"),m},m.back=function(a){return a!==!1&&m.busy()?(m.pushQueue({scope:m,callback:m.back,args:arguments,queue:a}),!1):(m.busy(!0),m.doubleCheck(function(){m.back(!1)}),n.go(-1),!0)},m.forward=function(a){return a!==!1&&m.busy()?(m.pushQueue({scope:m,callback:m.forward,args:arguments,queue:a}),!1):(m.busy(!0),m.doubleCheck(function(){m.forward(!1)}),n.go(1),!0)},m.go=function(a,b){var c;if(a>0)for(c=1;c<=a;++c)m.forward(b);else{if(!(a<0))throw new Error("History.go: History.go requires a positive or negative integer passed.");for(c=-1;c>=a;--c)m.back(b)}return m};if(m.emulated.pushState){var o=function(){};m.pushState=m.pushState||o,m.replaceState=m.replaceState||o}else m.onPopState=function(b,c){var e=!1,f=!1,g,h;return m.doubleCheckComplete(),g=m.getHash(),g?(h=m.extractState(g||d.location.href,!0),h?m.replaceState(h.data,h.title,h.url,!1):(m.Adapter.trigger(a,"anchorchange"),m.busy(!1)),m.expectedStateId=!1,!1):(e=m.Adapter.extractEventData("state",b,c)||!1,e?f=m.getStateById(e):m.expectedStateId?f=m.getStateById(m.expectedStateId):f=m.extractState(d.location.href),f||(f=m.createStateObject(null,null,d.location.href)),m.expectedStateId=!1,m.isLastSavedState(f)?(m.busy(!1),!1):(m.storeState(f),m.saveState(f),m.setTitle(f),m.Adapter.trigger(a,"statechange"),m.busy(!1),!0))},m.Adapter.bind(a,"popstate",m.onPopState),m.pushState=function(b,c,d,e){if(m.getHashByUrl(d)&&m.emulated.pushState)throw new Error("History.js does not support states with fragement-identifiers (hashes/anchors).");if(e!==!1&&m.busy())return m.pushQueue({scope:m,callback:m.pushState,args:arguments,queue:e}),!1;m.busy(!0);var f=m.createStateObject(b,c,d);return m.isLastSavedState(f)?m.busy(!1):(m.storeState(f),m.expectedStateId=f.id,n.pushState(f.id,f.title,f.url),m.Adapter.trigger(a,"popstate")),!0},m.replaceState=function(b,c,d,e){if(m.getHashByUrl(d)&&m.emulated.pushState)throw new Error("History.js does not support states with fragement-identifiers (hashes/anchors).");if(e!==!1&&m.busy())return m.pushQueue({scope:m,callback:m.replaceState,args:arguments,queue:e}),!1;m.busy(!0);var f=m.createStateObject(b,c,d);return m.isLastSavedState(f)?m.busy(!1):(m.storeState(f),m.expectedStateId=f.id,n.replaceState(f.id,f.title,f.url),m.Adapter.trigger(a,"popstate")),!0};if(f){try{m.store=k.parse(f.getItem("History.store"))||{}}catch(p){m.store={}}m.normalizeStore()}else m.store={},m.normalizeStore();m.Adapter.bind(a,"beforeunload",m.clearAllIntervals),m.Adapter.bind(a,"unload",m.clearAllIntervals),m.saveState(m.storeState(m.extractState(d.location.href,!0))),f&&(m.onUnload=function(){var a,b;try{a=k.parse(f.getItem("History.store"))||{}}catch(c){a={}}a.idToState=a.idToState||{},a.urlToId=a.urlToId||{},a.stateToId=a.stateToId||{};for(b in m.idToState){if(!m.idToState.hasOwnProperty(b))continue;a.idToState[b]=m.idToState[b]}for(b in m.urlToId){if(!m.urlToId.hasOwnProperty(b))continue;a.urlToId[b]=m.urlToId[b]}for(b in m.stateToId){if(!m.stateToId.hasOwnProperty(b))continue;a.stateToId[b]=m.stateToId[b]}m.store=a,m.normalizeStore(),f.setItem("History.store",k.stringify(a))},m.intervalList.push(i(m.onUnload,m.options.storeInterval)),m.Adapter.bind(a,"beforeunload",m.onUnload),m.Adapter.bind(a,"unload",m.onUnload));if(!m.emulated.pushState){m.bugs.safariPoll&&m.intervalList.push(i(m.safariStatePoll,m.options.safariPollInterval));if(e.vendor==="Apple Computer, Inc."||(e.appCodeName||"")==="Mozilla")m.Adapter.bind(a,"hashchange",function(){m.Adapter.trigger(a,"popstate")}),m.getHash()&&m.Adapter.onDomLoad(function(){m.Adapter.trigger(a,"hashchange")})}},m.init()}(window)
\ No newline at end of file
+window.JSON || (window.JSON = {}), (function () {
+ function f(a) {
+ return a < 10 ? '0' + a : a;
+ }
+
+ function quote(a) {
+ return escapable.lastIndex = 0, escapable.test(a) ? '"' + a.replace(escapable, a => {
+ const b = meta[a]; return typeof b === 'string' ? b : '\\u' + ('0000' + a.charCodeAt(0).toString(16)).slice(-4);
+ }) + '"' : '"' + a + '"';
+ }
+
+ function str(a, b) {
+ let c; let d; let e; let f; const g = gap; let h; let i = b[a]; i && typeof i === 'object' && typeof i.toJSON === 'function' && (i = i.toJSON(a)), typeof rep === 'function' && (i = rep.call(b, a, i)); switch (typeof i) {
+ case 'string': return quote(i); case 'number': return isFinite(i) ? String(i) : 'null'; case 'boolean': case 'null': return String(i); case 'object': if (!i) {
+ return 'null';
+ }
+
+ gap += indent, h = []; if (Object.prototype.toString.apply(i) === '[object Array]') {
+ f = i.length; for (c = 0; c < f; c += 1) {
+ h[c] = str(c, i) || 'null';
+ }
+
+ return e = h.length === 0 ? '[]' : (gap ? '[\n' + gap + h.join(',\n' + gap) + '\n' + g + ']' : '[' + h.join(',') + ']'), gap = g, e;
+ }
+
+ if (rep && typeof rep === 'object') {
+ f = rep.length; for (c = 0; c < f; c += 1) {
+ d = rep[c], typeof d === 'string' && (e = str(d, i), e && h.push(quote(d) + (gap ? ': ' : ':') + e));
+ }
+ } else {
+ for (d in i) {
+ Object.hasOwnProperty.call(i, d) && (e = str(d, i), e && h.push(quote(d) + (gap ? ': ' : ':') + e));
+ }
+ }
+
+ return e = h.length === 0 ? '{}' : (gap ? '{\n' + gap + h.join(',\n' + gap) + '\n' + g + '}' : '{' + h.join(',') + '}'), gap = g, e;
+ }
+ }
+
+ 'use strict', typeof Date.prototype.toJSON !== 'function' && (Date.prototype.toJSON = function (a) {
+ return isFinite(this.valueOf()) ? this.getUTCFullYear() + '-' + f(this.getUTCMonth() + 1) + '-' + f(this.getUTCDate()) + 'T' + f(this.getUTCHours()) + ':' + f(this.getUTCMinutes()) + ':' + f(this.getUTCSeconds()) + 'Z' : null;
+ }, String.prototype.toJSON = Number.prototype.toJSON = Boolean.prototype.toJSON = function (a) {
+ return this.valueOf();
+ }); const {JSON} = window; const cx = /[\u0000\u00AD\u0600-\u0604\u070F\u17B4\u17B5\u200C-\u200F\u2028-\u202F\u2060-\u206f\ufeff\ufff0-\uffff]/g; var escapable = /[\\\"\u0000-\u001F\u007F-\u009F\u00AD\u0600-\u0604\u070F\u17B4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g; let gap; let indent; var meta = {'\b': '\\b', '\t': '\\t', '\n': '\\n', '\f': '\\f', '\r': '\\r', '"': '\\"', '\\': '\\\\'}; let
+ rep; typeof JSON.stringify !== 'function' && (JSON.stringify = function (a, b, c) {
+ let d; gap = '', indent = ''; if (typeof c === 'number') {
+ for (d = 0; d < c; d += 1) {
+ indent += ' ';
+ }
+ } else {
+ typeof c === 'string' && (indent = c);
+ }
+
+ rep = b; if (!b || typeof b === 'function' || typeof b === 'object' && typeof b.length === 'number') {
+ return str('', {'': a});
+ }
+
+ throw new Error('JSON.stringify');
+ }), typeof JSON.parse !== 'function' && (JSON.parse = function (text, reviver) {
+ function walk(a, b) {
+ let c; let d; const e = a[b]; if (e && typeof e === 'object') {
+ for (c in e) {
+ Object.hasOwnProperty.call(e, c) && (d = walk(e, c), d !== undefined ? e[c] = d : delete e[c]);
+ }
+ }
+
+ return reviver.call(a, b, e);
+ }
+
+ let j; text = String(text), cx.lastIndex = 0, cx.test(text) && (text = text.replace(cx, a => {
+ return '\\u' + ('0000' + a.charCodeAt(0).toString(16)).slice(-4);
+ })); if (/^[\],:{}\s]*$/.test(text.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g, '@').replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g, ']').replace(/(?:^|:|,)(?:\s*\[)+/g, ''))) {
+ return j = eval('(' + text + ')'), typeof reviver === 'function' ? walk({'': j}, '') : j;
+ }
+
+ throw new SyntaxError('JSON.parse');
+ });
+})(), (function (a, b) {
+ 'use strict'; const c = a.History = a.History || {}; const d = a.Zepto; if (typeof c.Adapter !== 'undefined') {
+ throw new TypeError('History.js Adapter has already been loaded...');
+ }
+
+ c.Adapter = {bind(a, b, c) {
+ (new d(a)).bind(b, c);
+ }, trigger(a, b) {
+ (new d(a)).trigger(b);
+ }, extractEventData(a, c) {
+ const d = c && c[a] || b; return d;
+ }, onDomLoad(a) {
+ new d(a);
+ }}, typeof c.init !== 'undefined' && c.init();
+})(window), (function (a, b) {
+ 'use strict'; const c = a.document; var d = a.setTimeout || d; var e = a.clearTimeout || e; var f = a.setInterval || f; const g = a.History = a.History || {}; if (typeof g.initHtml4 !== 'undefined') {
+ throw new TypeError('History.js HTML4 Support has already been loaded...');
+ }
+
+ g.initHtml4 = function () {
+ if (typeof g.initHtml4.initialized !== 'undefined') {
+ return !1;
+ }
+
+ g.initHtml4.initialized = !0, g.enabled = !0, g.savedHashes = [], g.isLastHash = function (a) {
+ const b = g.getHashByIndex(); let c; return c = a === b, c;
+ }, g.saveHash = function (a) {
+ return g.isLastHash(a) ? !1 : (g.savedHashes.push(a), !0);
+ }, g.getHashByIndex = function (a) {
+ let b = null; return typeof a === 'undefined' ? b = g.savedHashes[g.savedHashes.length - 1] : (a < 0 ? b = g.savedHashes[g.savedHashes.length + a] : b = g.savedHashes[a]), b;
+ }, g.discardedHashes = {}, g.discardedStates = {}, g.discardState = function (a, b, c) {
+ const d = g.getHashByState(a); let e; return e = {discardedState: a, backState: c, forwardState: b}, g.discardedStates[d] = e, !0;
+ }, g.discardHash = function (a, b, c) {
+ const d = {discardedHash: a, backState: c, forwardState: b}; return g.discardedHashes[a] = d, !0;
+ }, g.discardedState = function (a) {
+ const b = g.getHashByState(a); let c; return c = g.discardedStates[b] || !1, c;
+ }, g.discardedHash = function (a) {
+ const b = g.discardedHashes[a] || !1; return b;
+ }, g.recycleState = function (a) {
+ const b = g.getHashByState(a); return g.discardedState(a) && delete g.discardedStates[b], !0;
+ }, g.emulated.hashChange && (g.hashChangeInit = function () {
+ g.checkerFunction = null; let b = ''; let d; let e; let h; let i; return g.isInternetExplorer() ? (d = 'historyjs-iframe', e = c.createElement('iframe'), e.setAttribute('id', d), e.style.display = 'none', c.body.appendChild(e), e.contentWindow.document.open(), e.contentWindow.document.close(), h = '', i = !1, g.checkerFunction = function () {
+ if (i) {
+ return !1;
+ }
+
+ i = !0; const c = g.getHash() || ''; let d = g.unescapeHash(e.contentWindow.document.location.hash) || ''; return c !== b ? (b = c, d !== c && (h = d = c, e.contentWindow.document.open(), e.contentWindow.document.close(), e.contentWindow.document.location.hash = g.escapeHash(c)), g.Adapter.trigger(a, 'hashchange')) : d !== h && (h = d, g.setHash(d, !1)), i = !1, !0;
+ }) : g.checkerFunction = function () {
+ const c = g.getHash(); return c !== b && (b = c, g.Adapter.trigger(a, 'hashchange')), !0;
+ }, g.intervalList.push(f(g.checkerFunction, g.options.hashChangeInterval)), !0;
+ }, g.Adapter.onDomLoad(g.hashChangeInit)), g.emulated.pushState && (g.onHashChange = function (b) {
+ const d = b && b.newURL || c.location.href; const e = g.getHashByUrl(d); let f = null; let h = null; const i = null; let j; return g.isLastHash(e) ? (g.busy(!1), !1) : (g.doubleCheckComplete(), g.saveHash(e), e && g.isTraditionalAnchor(e) ? (g.Adapter.trigger(a, 'anchorchange'), g.busy(!1), !1) : (f = g.extractState(g.getFullUrl(e || c.location.href, !1), !0), g.isLastSavedState(f) ? (g.busy(!1), !1) : (h = g.getHashByState(f), j = g.discardedState(f), j ? (g.getHashByIndex(-2) === g.getHashByState(j.forwardState) ? g.back(!1) : g.forward(!1), !1) : (g.pushState(f.data, f.title, f.url, !1), !0))));
+ }, g.Adapter.bind(a, 'hashchange', g.onHashChange), g.pushState = function (b, d, e, f) {
+ if (g.getHashByUrl(e)) {
+ throw new Error('History.js does not support states with fragement-identifiers (hashes/anchors).');
+ }
+
+ if (f !== !1 && g.busy()) {
+ return g.pushQueue({scope: g, callback: g.pushState, args: arguments, queue: f}), !1;
+ }
+
+ g.busy(!0); const h = g.createStateObject(b, d, e); const i = g.getHashByState(h); const j = g.getState(!1); const k = g.getHashByState(j); const l = g.getHash(); return g.storeState(h), g.expectedStateId = h.id, g.recycleState(h), g.setTitle(h), i === k ? (g.busy(!1), !1) : (i !== l && i !== g.getShortUrl(c.location.href) ? (g.setHash(i, !1), !1) : (g.saveState(h), g.Adapter.trigger(a, 'statechange'), g.busy(!1), !0));
+ }, g.replaceState = function (a, b, c, d) {
+ if (g.getHashByUrl(c)) {
+ throw new Error('History.js does not support states with fragement-identifiers (hashes/anchors).');
+ }
+
+ if (d !== !1 && g.busy()) {
+ return g.pushQueue({scope: g, callback: g.replaceState, args: arguments, queue: d}), !1;
+ }
+
+ g.busy(!0); const e = g.createStateObject(a, b, c); const f = g.getState(!1); const h = g.getStateByIndex(-2); return g.discardState(f, e, h), g.pushState(e.data, e.title, e.url, !1), !0;
+ }), g.emulated.pushState && g.getHash() && !g.emulated.hashChange && g.Adapter.onDomLoad(() => {
+ g.Adapter.trigger(a, 'hashchange');
+ });
+ }, typeof g.init !== 'undefined' && g.init();
+})(window), (function (a, b) {
+ 'use strict'; const c = a.console || b; const d = a.document; const e = a.navigator; const f = a.sessionStorage || !1; const g = a.setTimeout; const h = a.clearTimeout; const i = a.setInterval; const j = a.clearInterval; const k = a.JSON; const l = a.alert; const m = a.History = a.History || {}; const n = a.history; k.stringify = k.stringify || k.encode, k.parse = k.parse || k.decode; if (typeof m.init !== 'undefined') {
+ throw new TypeError('History.js Core has already been loaded...');
+ }
+
+ m.init = function () {
+ return typeof m.Adapter === 'undefined' ? !1 : (typeof m.initCore !== 'undefined' && m.initCore(), typeof m.initHtml4 !== 'undefined' && m.initHtml4(), !0);
+ }, m.initCore = function () {
+ if (typeof m.initCore.initialized !== 'undefined') {
+ return !1;
+ }
+
+ m.initCore.initialized = !0, m.options = m.options || {}, m.options.hashChangeInterval = m.options.hashChangeInterval || 100, m.options.safariPollInterval = m.options.safariPollInterval || 500, m.options.doubleCheckInterval = m.options.doubleCheckInterval || 500, m.options.storeInterval = m.options.storeInterval || 1e3, m.options.busyDelay = m.options.busyDelay || 250, m.options.debug = m.options.debug || !1, m.options.initialTitle = m.options.initialTitle || d.title, m.intervalList = [], m.clearAllIntervals = function () {
+ let a; const b = m.intervalList; if (typeof b !== 'undefined' && b !== null) {
+ for (a = 0; a < b.length; a++) {
+ j(b[a]);
+ }
+
+ m.intervalList = null;
+ }
+ }, m.debug = function () {
+ (m.options.debug || !1) && m.log.apply(m, arguments);
+ }, m.log = function () {
+ const a = typeof c !== 'undefined' && typeof c.log !== 'undefined' && typeof c.log.apply !== 'undefined'; const b = d.querySelector('#log'); let e; let f; let g; let h; let i; a ? (h = Array.prototype.slice.call(arguments), e = h.shift(), typeof c.debug !== 'undefined' ? c.debug.apply(c, [e, h]) : c.log.apply(c, [e, h])) : e = '\n' + arguments[0] + '\n'; for (f = 1, g = arguments.length; f < g; ++f) {
+ i = arguments[f]; if (typeof i === 'object' && typeof k !== 'undefined') {
+ try {
+ i = k.stringify(i);
+ } catch (error) {}
+ }
+
+ e += '\n' + i + '\n';
+ }
+
+ return b ? (b.value += e + '\n-----\n', b.scrollTop = b.scrollHeight - b.clientHeight) : a || l(e), !0;
+ }, m.getInternetExplorerMajorVersion = function () {
+ const a = m.getInternetExplorerMajorVersion.cached = typeof m.getInternetExplorerMajorVersion.cached !== 'undefined' ? m.getInternetExplorerMajorVersion.cached : (function () {
+ let a = 3; const b = d.createElement('div'); const c = b.querySelectorAll('i'); while ((b.innerHTML = '') && c[0]) {
+
+ }
+
+ return a > 4 ? a : !1;
+ })(); return a;
+ }, m.isInternetExplorer = function () {
+ const a = m.isInternetExplorer.cached = typeof m.isInternetExplorer.cached !== 'undefined' ? m.isInternetExplorer.cached : Boolean(m.getInternetExplorerMajorVersion()); return a;
+ }, m.emulated = {pushState: !(a.history && a.history.pushState && a.history.replaceState && !/ Mobile\/([1-7][a-z]|(8([abcde]|f(1[0-8]))))/i.test(e.userAgent) && !/AppleWebKit\/5([0-2]|3[0-2])/i.test(e.userAgent)), hashChange: Boolean(!('onhashchange' in a || 'onhashchange' in d) || m.isInternetExplorer() && m.getInternetExplorerMajorVersion() < 8)}, m.enabled = !m.emulated.pushState, m.bugs = {setHash: Boolean(!m.emulated.pushState && e.vendor === 'Apple Computer, Inc.' && /AppleWebKit\/5([0-2]|3[0-3])/.test(e.userAgent)), safariPoll: Boolean(!m.emulated.pushState && e.vendor === 'Apple Computer, Inc.' && /AppleWebKit\/5([0-2]|3[0-3])/.test(e.userAgent)), ieDoubleCheck: Boolean(m.isInternetExplorer() && m.getInternetExplorerMajorVersion() < 8), hashEscape: Boolean(m.isInternetExplorer() && m.getInternetExplorerMajorVersion() < 7)}, m.isEmptyObject = function (a) {
+ for (const b in a) {
+ return !1;
+ }
+
+ return !0;
+ }, m.cloneObject = function (a) {
+ let b; let c; return a ? (b = k.stringify(a), c = k.parse(b)) : c = {}, c;
+ }, m.getRootUrl = function () {
+ let a = d.location.protocol + '//' + (d.location.hostname || d.location.host); if (d.location.port || !1) {
+ a += ':' + d.location.port;
+ }
+
+ return a += '/', a;
+ }, m.getBaseHref = function () {
+ const a = d.querySelectorAll('base'); let b = null; let c = ''; return a.length === 1 && (b = a[0], c = b.href.replace(/[^\/]+$/, '')), c = c.replace(/\/+$/, ''), c && (c += '/'), c;
+ }, m.getBaseUrl = function () {
+ const a = m.getBaseHref() || m.getBasePageUrl() || m.getRootUrl(); return a;
+ }, m.getPageUrl = function () {
+ const a = m.getState(!1, !1); const b = (a || {}).url || d.location.href; let c; return c = b.replace(/\/+$/, '').replace(/[^\/]+$/, (a, b, c) => {
+ return /\./.test(a) ? a : a + '/';
+ }), c;
+ }, m.getBasePageUrl = function () {
+ const a = d.location.href.replace(/[#\?].*/, '').replace(/[^\/]+$/, (a, b, c) => {
+ return /[^\/]$/.test(a) ? '' : a;
+ }).replace(/\/+$/, '') + '/'; return a;
+ }, m.getFullUrl = function (a, b) {
+ let c = a; const d = a.slice(0, 1); return b = typeof b === 'undefined' ? !0 : b, /[a-z]+\:\/\//.test(a) || (d === '/' ? c = m.getRootUrl() + a.replace(/^\/+/, '') : d === '#' ? c = m.getPageUrl().replace(/#.*/, '') + a : d === '?' ? c = m.getPageUrl().replace(/[\?#].*/, '') + a : (b ? c = m.getBaseUrl() + a.replace(/^(\.\/)+/, '') : c = m.getBasePageUrl() + a.replace(/^(\.\/)+/, ''))), c.replace(/\#$/, '');
+ }, m.getShortUrl = function (a) {
+ let b = a; const c = m.getBaseUrl(); const d = m.getRootUrl(); return m.emulated.pushState && (b = b.replace(c, '')), b = b.replace(d, '/'), m.isTraditionalAnchor(b) && (b = './' + b), b = b.replace(/^(\.\/)+/g, './').replace(/\#$/, ''), b;
+ }, m.store = {}, m.idToState = m.idToState || {}, m.stateToId = m.stateToId || {}, m.urlToId = m.urlToId || {}, m.storedStates = m.storedStates || [], m.savedStates = m.savedStates || [], m.normalizeStore = function () {
+ m.store.idToState = m.store.idToState || {}, m.store.urlToId = m.store.urlToId || {}, m.store.stateToId = m.store.stateToId || {};
+ }, m.getState = function (a, b) {
+ typeof a === 'undefined' && (a = !0), typeof b === 'undefined' && (b = !0); let c = m.getLastSavedState(); return !c && b && (c = m.createStateObject()), a && (c = m.cloneObject(c), c.url = c.cleanUrl || c.url), c;
+ }, m.getIdByState = function (a) {
+ let b = m.extractId(a.url); let c; if (!b) {
+ c = m.getStateString(a); if (typeof m.stateToId[c] !== 'undefined') {
+ b = m.stateToId[c];
+ } else if (typeof m.store.stateToId[c] !== 'undefined') {
+ b = m.store.stateToId[c];
+ } else {
+ for (;;) {
+ b = (new Date()).getTime() + String(Math.random()).replace(/\D/g, ''); if (typeof m.idToState[b] === 'undefined' && typeof m.store.idToState[b] === 'undefined') {
+ break;
+ }
+ }
+
+ m.stateToId[c] = b, m.idToState[b] = a;
+ }
+ }
+
+ return b;
+ }, m.normalizeState = function (a) {
+ let b; let c; if (!a || typeof a !== 'object') {
+ a = {};
+ }
+
+ if (typeof a.normalized !== 'undefined') {
+ return a;
+ }
+
+ if (!a.data || typeof a.data !== 'object') {
+ a.data = {};
+ }
+
+ b = {}, b.normalized = !0, b.title = a.title || '', b.url = m.getFullUrl(m.unescapeString(a.url || d.location.href)), b.hash = m.getShortUrl(b.url), b.data = m.cloneObject(a.data), b.id = m.getIdByState(b), b.cleanUrl = b.url.replace(/\??\&_suid.*/, ''), b.url = b.cleanUrl, c = !m.isEmptyObject(b.data); if (b.title || c) {
+ b.hash = m.getShortUrl(b.url).replace(/\??\&_suid.*/, ''), /\?/.test(b.hash) || (b.hash += '?'), b.hash += '&_suid=' + b.id;
+ }
+
+ return b.hashedUrl = m.getFullUrl(b.hash), (m.emulated.pushState || m.bugs.safariPoll) && m.hasUrlDuplicate(b) && (b.url = b.hashedUrl), b;
+ }, m.createStateObject = function (a, b, c) {
+ let d = {data: a, title: b, url: c}; return d = m.normalizeState(d), d;
+ }, m.getStateById = function (a) {
+ a = String(a); const c = m.idToState[a] || m.store.idToState[a] || b; return c;
+ }, m.getStateString = function (a) {
+ let b; let c; let d; return b = m.normalizeState(a), c = {data: b.data, title: a.title, url: a.url}, d = k.stringify(c), d;
+ }, m.getStateId = function (a) {
+ let b; let c; return b = m.normalizeState(a), c = b.id, c;
+ }, m.getHashByState = function (a) {
+ let b; let c; return b = m.normalizeState(a), c = b.hash, c;
+ }, m.extractId = function (a) {
+ let b; let c; let d; return c = /(.*)\&_suid=([0-9]+)$/.exec(a), d = c ? c[1] || a : a, b = c ? String(c[2] || '') : '', b || !1;
+ }, m.isTraditionalAnchor = function (a) {
+ const b = !/[\/\?\.]/.test(a); return b;
+ }, m.extractState = function (a, b) {
+ let c = null; let d; let e; return b = b || !1, d = m.extractId(a), d && (c = m.getStateById(d)), c || (e = m.getFullUrl(a), d = m.getIdByUrl(e) || !1, d && (c = m.getStateById(d)), !c && b && !m.isTraditionalAnchor(a) && (c = m.createStateObject(null, null, e))), c;
+ }, m.getIdByUrl = function (a) {
+ const c = m.urlToId[a] || m.store.urlToId[a] || b; return c;
+ }, m.getLastSavedState = function () {
+ return m.savedStates[m.savedStates.length - 1] || b;
+ }, m.getLastStoredState = function () {
+ return m.storedStates[m.storedStates.length - 1] || b;
+ }, m.hasUrlDuplicate = function (a) {
+ let b = !1; let c; return c = m.extractState(a.url), b = c && c.id !== a.id, b;
+ }, m.storeState = function (a) {
+ return m.urlToId[a.url] = a.id, m.storedStates.push(m.cloneObject(a)), a;
+ }, m.isLastSavedState = function (a) {
+ let b = !1; let c; let d; let e; return m.savedStates.length && (c = a.id, d = m.getLastSavedState(), e = d.id, b = c === e), b;
+ }, m.saveState = function (a) {
+ return m.isLastSavedState(a) ? !1 : (m.savedStates.push(m.cloneObject(a)), !0);
+ }, m.getStateByIndex = function (a) {
+ let b = null; return typeof a === 'undefined' ? b = m.savedStates[m.savedStates.length - 1] : (a < 0 ? b = m.savedStates[m.savedStates.length + a] : b = m.savedStates[a]), b;
+ }, m.getHash = function () {
+ const a = m.unescapeHash(d.location.hash); return a;
+ }, m.unescapeString = function (b) {
+ let c = b; let d; for (;;) {
+ d = a.unescape(c); if (d === c) {
+ break;
+ }
+
+ c = d;
+ }
+
+ return c;
+ }, m.unescapeHash = function (a) {
+ let b = m.normalizeHash(a); return b = m.unescapeString(b), b;
+ }, m.normalizeHash = function (a) {
+ const b = a.replace(/[^#]*#/, '').replace(/#.*/, ''); return b;
+ }, m.setHash = function (a, b) {
+ let c; let e; let f; return b !== !1 && m.busy() ? (m.pushQueue({scope: m, callback: m.setHash, args: arguments, queue: b}), !1) : (c = m.escapeHash(a), m.busy(!0), e = m.extractState(a, !0), e && !m.emulated.pushState ? m.pushState(e.data, e.title, e.url, !1) : d.location.hash !== c && (m.bugs.setHash ? (f = m.getPageUrl(), m.pushState(null, null, f + '#' + c, !1)) : d.location.hash = c), m);
+ }, m.escapeHash = function (b) {
+ let c = m.normalizeHash(b); return c = a.escape(c), m.bugs.hashEscape || (c = c.replace(/\%21/g, '!').replace(/\%26/g, '&').replace(/\%3D/g, '=').replace(/\%3F/g, '?')), c;
+ }, m.getHashByUrl = function (a) {
+ let b = String(a).replace(/([^#]*)#?([^#]*)#?(.*)/, '$2'); return b = m.unescapeHash(b), b;
+ }, m.setTitle = function (a) {
+ let b = a.title; let c; b || (c = m.getStateByIndex(0), c && c.url === a.url && (b = c.title || m.options.initialTitle)); try {
+ d.querySelectorAll('title')[0].innerHTML = b.replace('<', '<').replace('>', '>').replace(' & ', ' & ');
+ } catch (error) {}
+
+ return d.title = b, m;
+ }, m.queues = [], m.busy = function (a) {
+ typeof a !== 'undefined' ? m.busy.flag = a : typeof m.busy.flag === 'undefined' && (m.busy.flag = !1); if (!m.busy.flag) {
+ h(m.busy.timeout); var b = function () {
+ let a; let c; let d; if (m.busy.flag) {
+ return;
+ }
+
+ for (a = m.queues.length - 1; a >= 0; --a) {
+ c = m.queues[a]; if (c.length === 0) {
+ continue;
+ }
+
+ d = c.shift(), m.fireQueueItem(d), m.busy.timeout = g(b, m.options.busyDelay);
+ }
+ };
+
+ m.busy.timeout = g(b, m.options.busyDelay);
+ }
+
+ return m.busy.flag;
+ }, m.busy.flag = !1, m.fireQueueItem = function (a) {
+ return a.callback.apply(a.scope || m, a.args || []);
+ }, m.pushQueue = function (a) {
+ return m.queues[a.queue || 0] = m.queues[a.queue || 0] || [], m.queues[a.queue || 0].push(a), m;
+ }, m.queue = function (a, b) {
+ return typeof a === 'function' && (a = {callback: a}), typeof b !== 'undefined' && (a.queue = b), m.busy() ? m.pushQueue(a) : m.fireQueueItem(a), m;
+ }, m.clearQueue = function () {
+ return m.busy.flag = !1, m.queues = [], m;
+ }, m.stateChanged = !1, m.doubleChecker = !1, m.doubleCheckComplete = function () {
+ return m.stateChanged = !0, m.doubleCheckClear(), m;
+ }, m.doubleCheckClear = function () {
+ return m.doubleChecker && (h(m.doubleChecker), m.doubleChecker = !1), m;
+ }, m.doubleCheck = function (a) {
+ return m.stateChanged = !1, m.doubleCheckClear(), m.bugs.ieDoubleCheck && (m.doubleChecker = g(() => {
+ return m.doubleCheckClear(), m.stateChanged || a(), !0;
+ }, m.options.doubleCheckInterval)), m;
+ }, m.safariStatePoll = function () {
+ const b = m.extractState(d.location.href); let c; if (!m.isLastSavedState(b)) {
+ c = b;
+ } else {
+ return;
+ }
+
+ return c || (c = m.createStateObject()), m.Adapter.trigger(a, 'popstate'), m;
+ }, m.back = function (a) {
+ return a !== !1 && m.busy() ? (m.pushQueue({scope: m, callback: m.back, args: arguments, queue: a}), !1) : (m.busy(!0), m.doubleCheck(() => {
+ m.back(!1);
+ }), n.go(-1), !0);
+ }, m.forward = function (a) {
+ return a !== !1 && m.busy() ? (m.pushQueue({scope: m, callback: m.forward, args: arguments, queue: a}), !1) : (m.busy(!0), m.doubleCheck(() => {
+ m.forward(!1);
+ }), n.go(1), !0);
+ }, m.go = function (a, b) {
+ let c; if (a > 0) {
+ for (c = 1; c <= a; ++c) {
+ m.forward(b);
+ }
+ } else {
+ if (!(a < 0)) {
+ throw new Error('History.go: History.go requires a positive or negative integer passed.');
+ }
+
+ for (c = -1; c >= a; --c) {
+ m.back(b);
+ }
+ }
+
+ return m;
+ };
+
+ if (m.emulated.pushState) {
+ const o = function () {}; m.pushState = m.pushState || o, m.replaceState = m.replaceState || o;
+ } else {
+ m.onPopState = function (b, c) {
+ let e = !1; let f = !1; let g; let h; return m.doubleCheckComplete(), g = m.getHash(), g ? (h = m.extractState(g || d.location.href, !0), h ? m.replaceState(h.data, h.title, h.url, !1) : (m.Adapter.trigger(a, 'anchorchange'), m.busy(!1)), m.expectedStateId = !1, !1) : (e = m.Adapter.extractEventData('state', b, c) || !1, e ? f = m.getStateById(e) : (m.expectedStateId ? f = m.getStateById(m.expectedStateId) : f = m.extractState(d.location.href)), f || (f = m.createStateObject(null, null, d.location.href)), m.expectedStateId = !1, m.isLastSavedState(f) ? (m.busy(!1), !1) : (m.storeState(f), m.saveState(f), m.setTitle(f), m.Adapter.trigger(a, 'statechange'), m.busy(!1), !0));
+ }, m.Adapter.bind(a, 'popstate', m.onPopState), m.pushState = function (b, c, d, e) {
+ if (m.getHashByUrl(d) && m.emulated.pushState) {
+ throw new Error('History.js does not support states with fragement-identifiers (hashes/anchors).');
+ }
+
+ if (e !== !1 && m.busy()) {
+ return m.pushQueue({scope: m, callback: m.pushState, args: arguments, queue: e}), !1;
+ }
+
+ m.busy(!0); const f = m.createStateObject(b, c, d); return m.isLastSavedState(f) ? m.busy(!1) : (m.storeState(f), m.expectedStateId = f.id, n.pushState(f.id, f.title, f.url), m.Adapter.trigger(a, 'popstate')), !0;
+ }, m.replaceState = function (b, c, d, e) {
+ if (m.getHashByUrl(d) && m.emulated.pushState) {
+ throw new Error('History.js does not support states with fragement-identifiers (hashes/anchors).');
+ }
+
+ if (e !== !1 && m.busy()) {
+ return m.pushQueue({scope: m, callback: m.replaceState, args: arguments, queue: e}), !1;
+ }
+
+ m.busy(!0); const f = m.createStateObject(b, c, d); return m.isLastSavedState(f) ? m.busy(!1) : (m.storeState(f), m.expectedStateId = f.id, n.replaceState(f.id, f.title, f.url), m.Adapter.trigger(a, 'popstate')), !0;
+ };
+ }
+
+ if (f) {
+ try {
+ m.store = k.parse(f.getItem('History.store')) || {};
+ } catch (error) {
+ m.store = {};
+ }
+
+ m.normalizeStore();
+ } else {
+ m.store = {}, m.normalizeStore();
+ }
+
+ m.Adapter.bind(a, 'beforeunload', m.clearAllIntervals), m.Adapter.bind(a, 'unload', m.clearAllIntervals), m.saveState(m.storeState(m.extractState(d.location.href, !0))), f && (m.onUnload = function () {
+ let a; let b; try {
+ a = k.parse(f.getItem('History.store')) || {};
+ } catch (error) {
+ a = {};
+ }
+
+ a.idToState = a.idToState || {}, a.urlToId = a.urlToId || {}, a.stateToId = a.stateToId || {}; for (b in m.idToState) {
+ if (!m.idToState.hasOwnProperty(b)) {
+ continue;
+ }
+
+ a.idToState[b] = m.idToState[b];
+ }
+
+ for (b in m.urlToId) {
+ if (!m.urlToId.hasOwnProperty(b)) {
+ continue;
+ }
+
+ a.urlToId[b] = m.urlToId[b];
+ }
+
+ for (b in m.stateToId) {
+ if (!m.stateToId.hasOwnProperty(b)) {
+ continue;
+ }
+
+ a.stateToId[b] = m.stateToId[b];
+ }
+
+ m.store = a, m.normalizeStore(), f.setItem('History.store', k.stringify(a));
+ }, m.intervalList.push(i(m.onUnload, m.options.storeInterval)), m.Adapter.bind(a, 'beforeunload', m.onUnload), m.Adapter.bind(a, 'unload', m.onUnload)); if (!m.emulated.pushState) {
+ m.bugs.safariPoll && m.intervalList.push(i(m.safariStatePoll, m.options.safariPollInterval)); if (e.vendor === 'Apple Computer, Inc.' || (e.appCodeName || '') === 'Mozilla') {
+ m.Adapter.bind(a, 'hashchange', () => {
+ m.Adapter.trigger(a, 'popstate');
+ }), m.getHash() && m.Adapter.onDomLoad(() => {
+ m.Adapter.trigger(a, 'hashchange');
+ });
+ }
+ }
+ }, m.init();
+})(window);
diff --git a/demos/twitter_backbone/app.js b/demos/twitter_backbone/app.js
index 747af372..f96e1473 100644
--- a/demos/twitter_backbone/app.js
+++ b/demos/twitter_backbone/app.js
@@ -1,39 +1,40 @@
-var http = require("http"),
- url = require("url"),
- path = require("path"),
- fs = require("fs")
- port = process.argv[2] || process.env.PORT || 8888,
- host = process.argv[3] || process.env.IP || "0.0.0.0";
-
-http.createServer(function(request, response) {
-
- var uri = url.parse(request.url).pathname
- , filename = path.join(__dirname, uri);
-
- path.exists(filename, function(exists) {
- if(!exists) {
- response.writeHead(404, {"Content-Type": "text/plain"});
- response.write("404 Not Found\n");
- response.end();
- return;
- }
-
-if (fs.statSync(filename).isDirectory()) filename += '/index.html';
-
- fs.readFile(filename, "binary", function(err, file) {
- if(err) {
- response.writeHead(500, {"Content-Type": "text/plain"});
- response.write(err + "\n");
- response.end();
- return;
- }
-
- response.writeHead(200);
- response.write(file, "binary");
- response.end();
+const http = require('http');
+const url = require('url');
+const path = require('path');
+const fs = require('fs');
+port = process.argv[2] || process.env.PORT || 8888,
+host = process.argv[3] || process.env.IP || '0.0.0.0';
+
+http.createServer((request, response) => {
+ const uri = url.parse(request.url).pathname;
+ let filename = path.join(__dirname, uri);
+
+ path.exists(filename, exists => {
+ if (!exists) {
+ response.writeHead(404, {'Content-Type': 'text/plain'});
+ response.write('404 Not Found\n');
+ response.end();
+ return;
+ }
+
+ if (fs.statSync(filename).isDirectory()) {
+ filename += '/index.html';
+ }
+
+ fs.readFile(filename, 'binary', (err, file) => {
+ if (err) {
+ response.writeHead(500, {'Content-Type': 'text/plain'});
+ response.write(err + '\n');
+ response.end();
+ return;
+ }
+
+ response.writeHead(200);
+ response.write(file, 'binary');
+ response.end();
+ });
});
- });
}).listen(parseInt(port, 10), host);
-console.log("Twig.Twitter demo running at\n => " + host + ":" + port + "/\nCTRL + C to shutdown");
+console.log('Twig.Twitter demo running at\n => ' + host + ':' + port + '/\nCTRL + C to shutdown');
diff --git a/demos/twitter_backbone/js/app.js b/demos/twitter_backbone/js/app.js
index c7429095..96eea7e6 100644
--- a/demos/twitter_backbone/js/app.js
+++ b/demos/twitter_backbone/js/app.js
@@ -5,39 +5,39 @@
module.declare(
[
- { settings: "js/model/settings" }
- , { appView: "js/view/appView" }
+ {settings: 'js/model/settings'},
+ {appView: 'js/view/appView'}
]
- , function (require, exports, module) {
- var Settings = require("settings").Settings
- , AppView = require("appView").AppView
+ , (require, exports, module) => {
+ const {Settings} = require('settings');
+ const {AppView} = require('appView')
// Models
- , settingId = 0
- , settings = new Settings;
+ ; const settingId = 0;
+ const settings = new Settings();
// Load from local storage
settings.fetch();
-
- var setting = settings.get(settingId),
- username = null;
+
+ let setting = settings.get(settingId);
+ let username = null;
// Initialize the settings model with a username
- if (!setting || !setting.get("username")) {
- username = prompt("Please enter a twitter username:");
+ if (!setting || !setting.get('username')) {
+ username = prompt('Please enter a twitter username:');
setting = settings.create({
- "id": settingId
- , "username": username
+ id: settingId,
+ username
});
setting.save();
}
// Create the view and kick off the application
- var appView = new AppView({
+ const appView = new AppView({
model: setting
});
- $("body").append(appView.el);
+ $('body').append(appView.el);
}
);
diff --git a/demos/twitter_backbone/js/model/account.js b/demos/twitter_backbone/js/model/account.js
index 34d6ac53..b56c19e2 100644
--- a/demos/twitter_backbone/js/model/account.js
+++ b/demos/twitter_backbone/js/model/account.js
@@ -1,10 +1,10 @@
module.declare(
[
- { backbone: 'vendor/backbone' }
+ {backbone: 'vendor/backbone'}
]
- , function(require, exports, module) {
- var Backbone = require('backbone')
- , Account = Backbone.Model.extend({ });
+ , (require, exports, module) => {
+ const Backbone = require('backbone');
+ const Account = Backbone.Model.extend({ });
return Account;
}
diff --git a/demos/twitter_backbone/js/model/feed.js b/demos/twitter_backbone/js/model/feed.js
index 3ce67bb1..b851e557 100644
--- a/demos/twitter_backbone/js/model/feed.js
+++ b/demos/twitter_backbone/js/model/feed.js
@@ -1,46 +1,47 @@
module.declare(
[
- { backbone: 'vendor/backbone' }
- , { underscore: 'vendor/underscore' }
- , { tweet: "js/model/tweet" }
+ {backbone: 'vendor/backbone'},
+ {underscore: 'vendor/underscore'},
+ {tweet: 'js/model/tweet'}
],
- function(require, exports, module) {
- var Backbone = require("backbone")
- , _ = require("underscore")._
- , Tweet = require("tweet").Tweet
- , Feed = Backbone.Collection.extend({
- localStorage: new Backbone.Store("tweets")
- , model: Tweet
+ (require, exports, module) => {
+ const Backbone = require('backbone');
+ const {_} = require('underscore');
+ const {Tweet} = require('tweet');
+ const Feed = Backbone.Collection.extend({
+ localStorage: new Backbone.Store('tweets'),
+ model: Tweet,
- , loadUser: function(username) {
- var that = this
- , request;
- while(this.length > 0) {
- this.each(function(tweet){
- tweet.destroy();
- });
- }
- request = $.ajax({
- url: 'https://api.twitter.com/1/statuses/user_timeline.json?callback=?'
- , dataType: 'json'
- , data: {
- include_entities: "true"
- , include_rts: "true"
- , screen_name: username
- }
+ loadUser(username) {
+ const that = this;
+ let request;
+ while (this.length > 0) {
+ this.each(tweet => {
+ tweet.destroy();
});
+ }
- request.done(function(data) {
- _.each(data, function(tweet) {
- var newTweet = that.create(tweet);
- });
- });
+ request = $.ajax({
+ url: 'https://api.twitter.com/1/statuses/user_timeline.json?callback=?',
+ dataType: 'json',
+ data: {
+ include_entities: 'true',
+ include_rts: 'true',
+ screen_name: username
+ }
+ });
- request.error(function(jqXHR, status) {
- alert("Unable to load tweets, error:\n" + status);
+ request.done(data => {
+ _.each(data, tweet => {
+ const newTweet = that.create(tweet);
});
- }
- });
- exports.feed = new Feed;
+ });
+
+ request.error((jqXHR, status) => {
+ alert('Unable to load tweets, error:\n' + status);
+ });
+ }
+ });
+ exports.feed = new Feed();
}
);
diff --git a/demos/twitter_backbone/js/model/settings.js b/demos/twitter_backbone/js/model/settings.js
index 3f8803d3..eabf4b91 100644
--- a/demos/twitter_backbone/js/model/settings.js
+++ b/demos/twitter_backbone/js/model/settings.js
@@ -1,15 +1,15 @@
// Settings model and collection
module.declare(
[
- { backbone: 'vendor/backbone' }
+ {backbone: 'vendor/backbone'}
]
- , function(require, exports, module) {
- var Backbone = require("backbone")
- , Setting = Backbone.Model.extend({ })
- , Settings = Backbone.Collection.extend({
- model: Setting
- , localStorage: new Backbone.Store("settings")
- });
+ , (require, exports, module) => {
+ const Backbone = require('backbone');
+ const Setting = Backbone.Model.extend({ });
+ const Settings = Backbone.Collection.extend({
+ model: Setting,
+ localStorage: new Backbone.Store('settings')
+ });
exports.Setting = Setting;
exports.Settings = Settings;
diff --git a/demos/twitter_backbone/js/model/tweet.js b/demos/twitter_backbone/js/model/tweet.js
index b4f7d159..6bcb6c20 100644
--- a/demos/twitter_backbone/js/model/tweet.js
+++ b/demos/twitter_backbone/js/model/tweet.js
@@ -1,11 +1,11 @@
// Tweet Model
module.declare(
[
- { backbone: 'vendor/backbone' }
+ {backbone: 'vendor/backbone'}
]
- , function(require, exports, module) {
- var Backbone = require("backbone")
- , Tweet = Backbone.Model.extend({ });
+ , (require, exports, module) => {
+ const Backbone = require('backbone');
+ const Tweet = Backbone.Model.extend({ });
exports.Tweet = Tweet;
}
diff --git a/demos/twitter_backbone/js/view/appView.js b/demos/twitter_backbone/js/view/appView.js
index a1ff85dc..197333d5 100644
--- a/demos/twitter_backbone/js/view/appView.js
+++ b/demos/twitter_backbone/js/view/appView.js
@@ -8,86 +8,85 @@
module.declare(
[
- { backbone: 'vendor/backbone' }
- , { twig: "vendor/twig" }
- , { feed: "js/model/feed" }
- , { feedView: "js/view/feedView" }
+ {backbone: 'vendor/backbone'},
+ {twig: 'vendor/twig'},
+ {feed: 'js/model/feed'},
+ {feedView: 'js/view/feedView'}
]
- , function (require, exports, module) {
- var twig = require("twig").twig
- , Backbone = require("backbone")
- , feed = require("feed").feed
+ , (require, exports, module) => {
+ const {twig} = require('twig');
+ const Backbone = require('backbone');
+ const {feed} = require('feed')
// The application template
- , template = twig({
- href: 'templates/app.twig'
- , async: false
- })
-
- , FeedView = require("feedView").FeedView
- , feedView = new FeedView
+ ; const template = twig({
+ href: 'templates/app.twig',
+ async: false
+ });
+ const {FeedView} = require('feedView');
+ const feedView = new FeedView();
+ const AppView = Backbone.View.extend({
+ tagName: 'div',
+ className: 'app',
- , AppView = Backbone.View.extend({
- tagName: "div"
- , className: "app"
+ // Bind to the buttons in the template
+ events: {
+ 'click .reloadTweets': 'reload',
+ 'click .changeUser': 'changeUser',
+ 'click .twitter_user': 'twitterLink'
+ },
- // Bind to the buttons in the template
- , events: {
- "click .reloadTweets": "reload"
- , "click .changeUser": "changeUser"
- , "click .twitter_user": "twitterLink"
- }
+ // Initialize the Application
+ initialize() {
+ this.model.bind('change', this.changeSettings, this);
+ this.feedView = feedView;
+ this.changeSettings();
+ },
- // Initialize the Application
- , initialize: function() {
- this.model.bind("change", this.changeSettings, this);
- this.feedView = feedView;
- this.changeSettings();
- }
+ // Render the template with the contents of the Setting model
+ render() {
+ $(this.el).html(template.render(this.model.toJSON()));
- // Render the template with the contents of the Setting model
- , render: function() {
- $(this.el).html(template.render(this.model.toJSON()));
+ this.$('.feedContainer').html(this.feedView.el);
+ },
- this.$(".feedContainer").html(this.feedView.el);
- }
+ // Trigger the feed Collection to refresh the twitter feed
+ reload() {
+ const username = this.model.get('username');
+ feed.loadUser(username);
+ },
- // Trigger the feed Collection to refresh the twitter feed
- , reload: function() {
- var username = this.model.get("username");
- feed.loadUser(username);
- }
+ // Update the Setting model associated with this AppView
+ // The change event will trigger a redraw
+ changeUser() {
+ const username = prompt('Please enter a twitter username:');
+ this.model.set({
+ username
+ });
+ this.model.save();
+ },
- // Update the Setting model associated with this AppView
- // The change event will trigger a redraw
- , changeUser: function() {
- var username = prompt("Please enter a twitter username:");
+ twitterLink(e) {
+ const username = $(e.target).attr('user');
+ if (username) {
this.model.set({
- username: username
+ username
});
this.model.save();
}
-
- , twitterLink: function(e) {
- var username = $(e.target).attr("user");
- if (username) {
- this.model.set({
- username: username
- });
- this.model.save();
- }
- e.preventDefault();
- e.stopPropagation();
- }
- // Handle change events from the Setting model
- // Renders the view and triggers a reload of the feed
- , changeSettings: function() {
- this.render();
- this.reload();
- }
- });
-
+ e.preventDefault();
+ e.stopPropagation();
+ },
+
+ // Handle change events from the Setting model
+ // Renders the view and triggers a reload of the feed
+ changeSettings() {
+ this.render();
+ this.reload();
+ }
+ });
+
exports.AppView = AppView;
}
);
diff --git a/demos/twitter_backbone/js/view/feedView.js b/demos/twitter_backbone/js/view/feedView.js
index e6ce910e..42b036af 100644
--- a/demos/twitter_backbone/js/view/feedView.js
+++ b/demos/twitter_backbone/js/view/feedView.js
@@ -5,52 +5,54 @@
module.declare(
[
- { backbone: 'vendor/backbone' }
- , { feed: "js/model/feed" }
- , { tweetView: "js/view/tweetView" }
+ {backbone: 'vendor/backbone'},
+ {feed: 'js/model/feed'},
+ {tweetView: 'js/view/tweetView'}
]
- , function (require, exports, module) {
- var feed = require("feed").feed
- , Backbone = require("backbone")
- , TweetView = require("tweetView").TweetView
+ , (require, exports, module) => {
+ const {feed} = require('feed');
+ const Backbone = require('backbone');
+ const {TweetView} = require('tweetView')
// The FeedView is a simple container of TweetViews and therefore
// doesn't need a template. The ul element provided by the Backbone
// View is sufficient.
- , FeedView = Backbone.View.extend({
- tagName: "ul"
- , className: "feed"
-
- , initialize: function() {
- // Bind to model changes
- feed.bind('add', this.addTweet, this);
- feed.bind('reset', this.addAll, this);
-
- // Load stored tweets from local storage
- feed.fetch();
- }
-
- // Add a tweet to the view
- // Creates a new TweetView for the tweet model
- // and adds it to the FeedView
- , addTweet: function(tweet) {
- var tweetView = new TweetView({
- model: tweet
- });
- var el = tweetView.render().el;
- $(this.el).append(el);
-
- return this;
- }
-
- // Handle resets to the model by adding all new elements to the view
- // Existing tweet views will have been removed when their models are
- // destroyed.
- , addAll: function() {
- var that = this;
- feed.each(function(tweet){that.addTweet(tweet)});
- }
- });
+ ; const FeedView = Backbone.View.extend({
+ tagName: 'ul',
+ className: 'feed',
+
+ initialize() {
+ // Bind to model changes
+ feed.bind('add', this.addTweet, this);
+ feed.bind('reset', this.addAll, this);
+
+ // Load stored tweets from local storage
+ feed.fetch();
+ },
+
+ // Add a tweet to the view
+ // Creates a new TweetView for the tweet model
+ // and adds it to the FeedView
+ addTweet(tweet) {
+ const tweetView = new TweetView({
+ model: tweet
+ });
+ const {el} = tweetView.render();
+ $(this.el).append(el);
+
+ return this;
+ },
+
+ // Handle resets to the model by adding all new elements to the view
+ // Existing tweet views will have been removed when their models are
+ // destroyed.
+ addAll() {
+ const that = this;
+ feed.each(tweet => {
+ that.addTweet(tweet);
+ });
+ }
+ });
exports.FeedView = FeedView;
}
diff --git a/demos/twitter_backbone/js/view/tweetView.js b/demos/twitter_backbone/js/view/tweetView.js
index 2f7b4a1e..e92f8471 100644
--- a/demos/twitter_backbone/js/view/tweetView.js
+++ b/demos/twitter_backbone/js/view/tweetView.js
@@ -5,63 +5,63 @@
module.declare(
[
- { backbone: 'vendor/backbone' }
- , { twig: "vendor/twig" }
- , { tweet: "js/model/tweet" }
+ {backbone: 'vendor/backbone'},
+ {twig: 'vendor/twig'},
+ {tweet: 'js/model/tweet'}
]
- , function (require, exports, module) {
- var Backbone = require("backbone")
- , twig = require("twig").twig
-
- // Load the template for a "Tweet"
- // This template only needs to be loaded once. It will be compiled at
- // load time and can be rendered separately for each Tweet.
- , template = twig({
- href: 'templates/tweet.twig'
- , async: false
- })
-
- , TweetView = Backbone.View.extend({
- tagName: "li"
- , className: "tweet"
+ , (require, exports, module) => {
+ const Backbone = require('backbone');
+ const {twig} = require('twig');
- // Create the Tweet view
- , initialize: function() {
- // Re-render the tweet if the backing model changes
- this.model.bind('change', this.render, this);
+ // Load the template for a "Tweet"
+ // This template only needs to be loaded once. It will be compiled at
+ // load time and can be rendered separately for each Tweet.
+ const template = twig({
+ href: 'templates/tweet.twig',
+ async: false
+ });
- // Remove the Tweet if the backing model is removed.
- this.model.bind('destroy', this.remove, this);
- }
+ const TweetView = Backbone.View.extend({
+ tagName: 'li',
+ className: 'tweet',
- // Render the tweet Twig template with the contents of the model
- , render: function() {
- // Pass in an object representing the Tweet to serve as the
- // render context for the template and inject it into the View.
- $(this.el).html(template.render(
- this.enhanceModel(this.model.toJSON())
- ));
- return this;
- }
-
- // Regex's for matching twitter usernames and web links
- , userRegEx: /\@([a-zA-Z0-9_\-\.]+)/g
- , hashRegex: /#([a-zA-Z0-9_\-\.]+)/g
- , linkRegEx: /\b((?:https?:\/\/|www\d{0,3}[.]|[a-z0-9.\-]+[.][a-z]{2,4}\/)(?:[^\s()<>]+|\(([^\s()<>]+|(\([^\s()<>]+\)))*\))+(?:\(([^\s()<>]+|(\([^\s()<>]+\)))*\)|[^\s`!()\[\]{};:'".,<>?«»“”‘’]))/g
-
- // Enhance the model passed to the template with links
- , enhanceModel: function(model) {
- model.text = model.text.replace(this.linkRegEx, '$1 ');
- model.text = model.text.replace(this.hashRegex, '#$1 ');
- model.text = model.text.replace(this.userRegEx, '');
- return model;
- }
+ // Create the Tweet view
+ initialize() {
+ // Re-render the tweet if the backing model changes
+ this.model.bind('change', this.render, this);
- // Remove the tweet view from it's container (a FeedView)
- , remove: function() {
- $(this.el).remove();
- }
- });
+ // Remove the Tweet if the backing model is removed.
+ this.model.bind('destroy', this.remove, this);
+ },
+
+ // Render the tweet Twig template with the contents of the model
+ render() {
+ // Pass in an object representing the Tweet to serve as the
+ // render context for the template and inject it into the View.
+ $(this.el).html(template.render(
+ this.enhanceModel(this.model.toJSON())
+ ));
+ return this;
+ },
+
+ // Regex's for matching twitter usernames and web links
+ userRegEx: /\@([a-zA-Z0-9_\-\.]+)/g,
+ hashRegex: /#([a-zA-Z0-9_\-\.]+)/g,
+ linkRegEx: /\b((?:https?:\/\/|www\d{0,3}[.]|[a-z0-9.\-]+[.][a-z]{2,4}\/)(?:[^\s()<>]+|\(([^\s()<>]+|(\([^\s()<>]+\)))*\))+(?:\(([^\s()<>]+|(\([^\s()<>]+\)))*\)|[^\s`!()\[\]{};:'".,<>?«»“”‘’]))/g,
+
+ // Enhance the model passed to the template with links
+ enhanceModel(model) {
+ model.text = model.text.replace(this.linkRegEx, '$1 ');
+ model.text = model.text.replace(this.hashRegex, '#$1 ');
+ model.text = model.text.replace(this.userRegEx, '');
+ return model;
+ },
+
+ // Remove the tweet view from it's container (a FeedView)
+ remove() {
+ $(this.el).remove();
+ }
+ });
exports.TweetView = TweetView;
}
diff --git a/demos/twitter_backbone/vendor/backbone.js b/demos/twitter_backbone/vendor/backbone.js
index c020cfdf..d620915f 100644
--- a/demos/twitter_backbone/vendor/backbone.js
+++ b/demos/twitter_backbone/vendor/backbone.js
@@ -1,56 +1,626 @@
module.declare(
[
- { underscore: "vendor/underscore" }
+ {underscore: 'vendor/underscore'}
]
, function (require, exports, module) {
+ // Backbone.js 0.5.3
+ // (c) 2010 Jeremy Ashkenas, DocumentCloud Inc.
+ // Backbone may be freely distributed under the MIT license.
+ // For all details and documentation:
+ // http://documentcloud.github.com/backbone
+ (function () {
+ const h = this; const p = h.Backbone; let e; e = typeof exports !== 'undefined' ? exports : h.Backbone = {}; e.VERSION = '0.5.3'; let f = h._; if (!f && typeof require !== 'undefined') {
+ f = require('underscore')._;
+ }
-// Backbone.js 0.5.3
-// (c) 2010 Jeremy Ashkenas, DocumentCloud Inc.
-// Backbone may be freely distributed under the MIT license.
-// For all details and documentation:
-// http://documentcloud.github.com/backbone
-(function(){var h=this,p=h.Backbone,e;e=typeof exports!=="undefined"?exports:h.Backbone={};e.VERSION="0.5.3";var f=h._;if(!f&&typeof require!=="undefined")f=require("underscore")._;var g=h.jQuery||h.Zepto;e.noConflict=function(){h.Backbone=p;return this};e.emulateHTTP=!1;e.emulateJSON=!1;e.Events={bind:function(a,b,c){var d=this._callbacks||(this._callbacks={});(d[a]||(d[a]=[])).push([b,c]);return this},unbind:function(a,b){var c;if(a){if(c=this._callbacks)if(b){c=c[a];if(!c)return this;for(var d=
-0,e=c.length;d /g,">").replace(/"/g,""").replace(/'/g,"'").replace(/\//g,"/")},has:function(a){return this.attributes[a]!=null},set:function(a,b){b||(b={});if(!a)return this;if(a.attributes)a=a.attributes;var c=this.attributes,d=this._escapedAttributes;if(!b.silent&&this.validate&&!this._performValidation(a,b))return!1;if(this.idAttribute in a)this.id=a[this.idAttribute];
-var e=this._changing;this._changing=!0;for(var g in a){var h=a[g];if(!f.isEqual(c[g],h))c[g]=h,delete d[g],this._changed=!0,b.silent||this.trigger("change:"+g,this,h,b)}!e&&!b.silent&&this._changed&&this.change(b);this._changing=!1;return this},unset:function(a,b){if(!(a in this.attributes))return this;b||(b={});var c={};c[a]=void 0;if(!b.silent&&this.validate&&!this._performValidation(c,b))return!1;delete this.attributes[a];delete this._escapedAttributes[a];a==this.idAttribute&&delete this.id;this._changed=
-!0;b.silent||(this.trigger("change:"+a,this,void 0,b),this.change(b));return this},clear:function(a){a||(a={});var b,c=this.attributes,d={};for(b in c)d[b]=void 0;if(!a.silent&&this.validate&&!this._performValidation(d,a))return!1;this.attributes={};this._escapedAttributes={};this._changed=!0;if(!a.silent){for(b in c)this.trigger("change:"+b,this,void 0,a);this.change(a)}return this},fetch:function(a){a||(a={});var b=this,c=a.success;a.success=function(d,e,f){if(!b.set(b.parse(d,f),a))return!1;c&&
-c(b,d)};a.error=i(a.error,b,a);return(this.sync||e.sync).call(this,"read",this,a)},save:function(a,b){b||(b={});if(a&&!this.set(a,b))return!1;var c=this,d=b.success;b.success=function(a,e,f){if(!c.set(c.parse(a,f),b))return!1;d&&d(c,a,f)};b.error=i(b.error,c,b);var f=this.isNew()?"create":"update";return(this.sync||e.sync).call(this,f,this,b)},destroy:function(a){a||(a={});if(this.isNew())return this.trigger("destroy",this,this.collection,a);var b=this,c=a.success;a.success=function(d){b.trigger("destroy",
-b,b.collection,a);c&&c(b,d)};a.error=i(a.error,b,a);return(this.sync||e.sync).call(this,"delete",this,a)},url:function(){var a=k(this.collection)||this.urlRoot||l();if(this.isNew())return a;return a+(a.charAt(a.length-1)=="/"?"":"/")+encodeURIComponent(this.id)},parse:function(a){return a},clone:function(){return new this.constructor(this)},isNew:function(){return this.id==null},change:function(a){this.trigger("change",this,a);this._previousAttributes=f.clone(this.attributes);this._changed=!1},hasChanged:function(a){if(a)return this._previousAttributes[a]!=
-this.attributes[a];return this._changed},changedAttributes:function(a){a||(a=this.attributes);var b=this._previousAttributes,c=!1,d;for(d in a)f.isEqual(b[d],a[d])||(c=c||{},c[d]=a[d]);return c},previous:function(a){if(!a||!this._previousAttributes)return null;return this._previousAttributes[a]},previousAttributes:function(){return f.clone(this._previousAttributes)},_performValidation:function(a,b){var c=this.validate(a);if(c)return b.error?b.error(this,c,b):this.trigger("error",this,c,b),!1;return!0}});
-e.Collection=function(a,b){b||(b={});if(b.comparator)this.comparator=b.comparator;f.bindAll(this,"_onModelEvent","_removeReference");this._reset();a&&this.reset(a,{silent:!0});this.initialize.apply(this,arguments)};f.extend(e.Collection.prototype,e.Events,{model:e.Model,initialize:function(){},toJSON:function(){return this.map(function(a){return a.toJSON()})},add:function(a,b){if(f.isArray(a))for(var c=0,d=a.length;c ').hide().appendTo("body")[0].contentWindow,this.navigate(a);
-this._hasPushState?g(window).bind("popstate",this.checkUrl):"onhashchange"in window&&!b?g(window).bind("hashchange",this.checkUrl):setInterval(this.checkUrl,this.interval);this.fragment=a;m=!0;a=window.location;b=a.pathname==this.options.root;if(this._wantsPushState&&!this._hasPushState&&!b)return this.fragment=this.getFragment(null,!0),window.location.replace(this.options.root+"#"+this.fragment),!0;else if(this._wantsPushState&&this._hasPushState&&b&&a.hash)this.fragment=a.hash.replace(j,""),window.history.replaceState({},
-document.title,a.protocol+"//"+a.host+this.options.root+this.fragment);if(!this.options.silent)return this.loadUrl()},route:function(a,b){this.handlers.unshift({route:a,callback:b})},checkUrl:function(){var a=this.getFragment();a==this.fragment&&this.iframe&&(a=this.getFragment(this.iframe.location.hash));if(a==this.fragment||a==decodeURIComponent(this.fragment))return!1;this.iframe&&this.navigate(a);this.loadUrl()||this.loadUrl(window.location.hash)},loadUrl:function(a){var b=this.fragment=this.getFragment(a);
-return f.any(this.handlers,function(a){if(a.route.test(b))return a.callback(b),!0})},navigate:function(a,b){var c=(a||"").replace(j,"");if(!(this.fragment==c||this.fragment==decodeURIComponent(c))){if(this._hasPushState){var d=window.location;c.indexOf(this.options.root)!=0&&(c=this.options.root+c);this.fragment=c;window.history.pushState({},document.title,d.protocol+"//"+d.host+c)}else if(window.location.hash=this.fragment=c,this.iframe&&c!=this.getFragment(this.iframe.location.hash))this.iframe.document.open().close(),
-this.iframe.location.hash=c;b&&this.loadUrl(a)}}});e.View=function(a){this.cid=f.uniqueId("view");this._configure(a||{});this._ensureElement();this.delegateEvents();this.initialize.apply(this,arguments)};var u=/^(\S+)\s*(.*)$/,n=["model","collection","el","id","attributes","className","tagName"];f.extend(e.View.prototype,e.Events,{tagName:"div",$:function(a){return g(a,this.el)},initialize:function(){},render:function(){return this},remove:function(){g(this.el).remove();return this},make:function(a,
-b,c){a=document.createElement(a);b&&g(a).attr(b);c&&g(a).html(c);return a},delegateEvents:function(a){if(a||(a=this.events))for(var b in f.isFunction(a)&&(a=a.call(this)),g(this.el).unbind(".delegateEvents"+this.cid),a){var c=this[a[b]];if(!c)throw Error('Event "'+a[b]+'" does not exist');var d=b.match(u),e=d[1];d=d[2];c=f.bind(c,this);e+=".delegateEvents"+this.cid;d===""?g(this.el).bind(e,c):g(this.el).delegate(d,e,c)}},_configure:function(a){this.options&&(a=f.extend({},this.options,a));for(var b=
-0,c=n.length;b /g, '>').replace(/"/g, '"').replace(/'/g, ''').replace(/\//g, '/');
+ }, has(a) {
+ return this.attributes[a] != null;
+ }, set(a, b) {
+ b || (b = {}); if (!a) {
+ return this;
+ }
+
+ if (a.attributes) {
+ a = a.attributes;
+ }
+
+ const c = this.attributes; const d = this._escapedAttributes; if (!b.silent && this.validate && !this._performValidation(a, b)) {
+ return !1;
+ }
+
+ if (this.idAttribute in a) {
+ this.id = a[this.idAttribute];
+ }
+
+ const e = this._changing; this._changing = !0; for (const g in a) {
+ const h = a[g]; if (!f.isEqual(c[g], h)) {
+ c[g] = h, delete d[g], this._changed = !0, b.silent || this.trigger('change:' + g, this, h, b);
+ }
+ }
+
+ !e && !b.silent && this._changed && this.change(b); this._changing = !1; return this;
+ }, unset(a, b) {
+ if (!(a in this.attributes)) {
+ return this;
+ }
+
+ b || (b = {}); const c = {}; c[a] = void 0; if (!b.silent && this.validate && !this._performValidation(c, b)) {
+ return !1;
+ }
+
+ delete this.attributes[a]; delete this._escapedAttributes[a]; a == this.idAttribute && delete this.id; this._changed =
+!0; b.silent || (this.trigger('change:' + a, this, void 0, b), this.change(b)); return this;
+ }, clear(a) {
+ a || (a = {}); let b; const c = this.attributes; const d = {}; for (b in c) {
+ d[b] = void 0;
+ }
+
+ if (!a.silent && this.validate && !this._performValidation(d, a)) {
+ return !1;
+ }
+
+ this.attributes = {}; this._escapedAttributes = {}; this._changed = !0; if (!a.silent) {
+ for (b in c) {
+ this.trigger('change:' + b, this, void 0, a);
+ }
+
+ this.change(a);
+ }
+
+ return this;
+ }, fetch(a) {
+ a || (a = {}); const b = this; const c = a.success; a.success = function (d, e, f) {
+ if (!b.set(b.parse(d, f), a)) {
+ return !1;
+ }
+
+ c &&
+c(b, d);
+ };
+
+ a.error = i(a.error, b, a); return (this.sync || e.sync).call(this, 'read', this, a);
+ }, save(a, b) {
+ b || (b = {}); if (a && !this.set(a, b)) {
+ return !1;
+ }
+
+ const c = this; const d = b.success; b.success = function (a, e, f) {
+ if (!c.set(c.parse(a, f), b)) {
+ return !1;
+ }
+
+ d && d(c, a, f);
+ };
+
+ b.error = i(b.error, c, b); const f = this.isNew() ? 'create' : 'update'; return (this.sync || e.sync).call(this, f, this, b);
+ }, destroy(a) {
+ a || (a = {}); if (this.isNew()) {
+ return this.trigger('destroy', this, this.collection, a);
+ }
+
+ const b = this; const c = a.success; a.success = function (d) {
+ b.trigger('destroy',
+ b, b.collection, a); c && c(b, d);
+ };
+
+ a.error = i(a.error, b, a); return (this.sync || e.sync).call(this, 'delete', this, a);
+ }, url() {
+ const a = k(this.collection) || this.urlRoot || l(); if (this.isNew()) {
+ return a;
+ }
+
+ return a + (a.charAt(a.length - 1) == '/' ? '' : '/') + encodeURIComponent(this.id);
+ }, parse(a) {
+ return a;
+ }, clone() {
+ return new this.constructor(this);
+ }, isNew() {
+ return this.id == null;
+ }, change(a) {
+ this.trigger('change', this, a); this._previousAttributes = f.clone(this.attributes); this._changed = !1;
+ }, hasChanged(a) {
+ if (a) {
+ return this._previousAttributes[a] !=
+this.attributes[a];
+ }
+
+ return this._changed;
+ }, changedAttributes(a) {
+ a || (a = this.attributes); const b = this._previousAttributes; let c = !1; let d; for (d in a) {
+ f.isEqual(b[d], a[d]) || (c = c || {}, c[d] = a[d]);
+ }
+
+ return c;
+ }, previous(a) {
+ if (!a || !this._previousAttributes) {
+ return null;
+ }
+
+ return this._previousAttributes[a];
+ }, previousAttributes() {
+ return f.clone(this._previousAttributes);
+ }, _performValidation(a, b) {
+ const c = this.validate(a); if (c) {
+ return b.error ? b.error(this, c, b) : this.trigger('error', this, c, b), !1;
+ }
+
+ return !0;
+ }});
+ e.Collection = function (a, b) {
+ b || (b = {}); if (b.comparator) {
+ this.comparator = b.comparator;
+ }
+
+ f.bindAll(this, '_onModelEvent', '_removeReference'); this._reset(); a && this.reset(a, {silent: !0}); Reflect.apply(this.initialize, this, arguments);
+ };
+
+ f.extend(e.Collection.prototype, e.Events, {model: e.Model, initialize() {}, toJSON() {
+ return this.map(a => {
+ return a.toJSON();
+ });
+ }, add(a, b) {
+ if (f.isArray(a)) {
+ for (let c = 0, d = a.length; c < d; c++) {
+ this._add(a[c], b);
+ }
+ } else {
+ this._add(a, b);
+ }
+
+ return this;
+ }, remove(a, b) {
+ if (f.isArray(a)) {
+ for (let c =
+0, d = a.length; c < d; c++) {
+ this._remove(a[c], b);
+ }
+ } else {
+ this._remove(a, b);
+ }
+
+ return this;
+ }, get(a) {
+ if (a == null) {
+ return null;
+ }
+
+ return this._byId[a.id != null ? a.id : a];
+ }, getByCid(a) {
+ return a && this._byCid[a.cid || a];
+ }, at(a) {
+ return this.models[a];
+ }, sort(a) {
+ a || (a = {}); if (!this.comparator) {
+ throw new Error('Cannot sort a set without a comparator');
+ }
+
+ this.models = this.sortBy(this.comparator); a.silent || this.trigger('reset', this, a); return this;
+ }, pluck(a) {
+ return f.map(this.models, b => {
+ return b.get(a);
+ });
+ },
+ reset(a, b) {
+ a || (a = []); b || (b = {}); this.each(this._removeReference); this._reset(); this.add(a, {silent: !0}); b.silent || this.trigger('reset', this, b); return this;
+ }, fetch(a) {
+ a || (a = {}); const b = this; const c = a.success; a.success = function (d, f, e) {
+ b[a.add ? 'add' : 'reset'](b.parse(d, e), a); c && c(b, d);
+ };
+
+ a.error = i(a.error, b, a); return (this.sync || e.sync).call(this, 'read', this, a);
+ }, create(a, b) {
+ const c = this; b || (b = {}); a = this._prepareModel(a, b); if (!a) {
+ return !1;
+ }
+
+ const d = b.success; b.success = function (a, e, f) {
+ c.add(a, b);
+ d && d(a, e, f);
+ };
+
+ a.save(null, b); return a;
+ }, parse(a) {
+ return a;
+ }, chain() {
+ return f(this.models).chain();
+ }, _reset() {
+ this.length = 0; this.models = []; this._byId = {}; this._byCid = {};
+ }, _prepareModel(a, b) {
+ if (a instanceof e.Model) {
+ if (!a.collection) {
+ a.collection = this;
+ }
+ } else {
+ const c = a; a = new this.model(c, {collection: this}); a.validate && !a._performValidation(c, b) && (a = !1);
+ }
+
+ return a;
+ }, _add(a, b) {
+ b || (b = {}); a = this._prepareModel(a, b); if (!a) {
+ return !1;
+ }
+
+ const c = this.getByCid(a); if (c) {
+ throw new Error(['Can\'t add the same model to a set twice',
+ c.id]);
+ }
+
+ this._byId[a.id] = a; this._byCid[a.cid] = a; this.models.splice(b.at != null ? b.at : (this.comparator ? this.sortedIndex(a, this.comparator) : this.length), 0, a); a.bind('all', this._onModelEvent); this.length++; b.silent || a.trigger('add', a, this, b); return a;
+ }, _remove(a, b) {
+ b || (b = {}); a = this.getByCid(a) || this.get(a); if (!a) {
+ return null;
+ }
+
+ delete this._byId[a.id]; delete this._byCid[a.cid]; this.models.splice(this.indexOf(a), 1); this.length--; b.silent || a.trigger('remove', a, this, b); this._removeReference(a); return a;
+ },
+ _removeReference(a) {
+ this == a.collection && delete a.collection; a.unbind('all', this._onModelEvent);
+ }, _onModelEvent(a, b, c, d) {
+ (a == 'add' || a == 'remove') && c != this || (a == 'destroy' && this._remove(b, d), b && a === 'change:' + b.idAttribute && (delete this._byId[b.previous(b.idAttribute)], this._byId[b.id] = b), Reflect.apply(this.trigger, this, arguments));
+ }}); f.each(['forEach',
+ 'each',
+ 'map',
+ 'reduce',
+ 'reduceRight',
+ 'find',
+ 'detect',
+ 'filter',
+ 'select',
+ 'reject',
+ 'every',
+ 'all',
+ 'some',
+ 'any',
+ 'include',
+ 'contains',
+ 'invoke',
+ 'max',
+ 'min',
+ 'sortBy',
+ 'sortedIndex',
+ 'toArray',
+ 'size',
+ 'first',
+ 'rest',
+ 'last',
+ 'without',
+ 'indexOf',
+ 'lastIndexOf',
+ 'isEmpty',
+ 'groupBy'], a => {
+ e.Collection.prototype[a] = function () {
+ return f[a].apply(f, [this.models].concat(f.toArray(arguments)));
+ };
+ }); e.Router = function (a) {
+ a || (a = {}); if (a.routes) {
+ this.routes = a.routes;
+ }
+
+ this._bindRoutes(); Reflect.apply(this.initialize, this, arguments);
+ };
+
+ const q = /:([\w\d]+)/g; const r = /\*([\w\d]+)/g; const s = /[-[\]{}()+?.,\\^$|#\s]/g; f.extend(e.Router.prototype, e.Events, {initialize() {}, route(a,
+ b, c) {
+ e.history || (e.history = new e.History()); f.isRegExp(a) || (a = this._routeToRegExp(a)); e.history.route(a, f.bind(function (d) {
+ d = this._extractParameters(a, d); c.apply(this, d); this.trigger.apply(this, ['route:' + b].concat(d));
+ }, this));
+ }, navigate(a, b) {
+ e.history.navigate(a, b);
+ }, _bindRoutes() {
+ if (this.routes) {
+ const a = []; let b; for (b in this.routes) {
+ a.unshift([b, this.routes[b]]);
+ }
+
+ b = 0; for (let c = a.length; b < c; b++) {
+ this.route(a[b][0], a[b][1], this[a[b][1]]);
+ }
+ }
+ }, _routeToRegExp(a) {
+ a = a.replace(s, '\\$&').replace(q,
+ '([^/]*)').replace(r, '(.*?)'); return new RegExp('^' + a + '$');
+ }, _extractParameters(a, b) {
+ return a.exec(b).slice(1);
+ }}); e.History = function () {
+ this.handlers = []; f.bindAll(this, 'checkUrl');
+ };
+
+ const j = /^#*/; const t = /msie [\w.]+/; let m = !1; f.extend(e.History.prototype, {interval: 50, getFragment(a, b) {
+ if (a == null) {
+ if (this._hasPushState || b) {
+ a = window.location.pathname; const c = window.location.search; c && (a += c); a.indexOf(this.options.root) == 0 && (a = a.slice(this.options.root.length));
+ } else {
+ a = window.location.hash;
+ }
+ }
+
+ return decodeURIComponent(a.replace(j,
+ ''));
+ }, start(a) {
+ if (m) {
+ throw new Error('Backbone.history has already been started');
+ }
+
+ this.options = f.extend({}, {root: '/'}, this.options, a); this._wantsPushState = Boolean(this.options.pushState); this._hasPushState = !(!this.options.pushState || !window.history || !window.history.pushState); a = this.getFragment(); let b = document.documentMode; if (b = t.exec(navigator.userAgent.toLowerCase()) && (!b || b <= 7)) {
+ this.iframe = g('').hide().appendTo('body')[0].contentWindow, this.navigate(a);
+ }
+
+ this._hasPushState ? g(window).bind('popstate', this.checkUrl) : ('onhashchange' in window && !b ? g(window).bind('hashchange', this.checkUrl) : setInterval(this.checkUrl, this.interval)); this.fragment = a; m = !0; a = window.location; b = a.pathname == this.options.root; if (this._wantsPushState && !this._hasPushState && !b) {
+ return this.fragment = this.getFragment(null, !0), window.location.replace(this.options.root + '#' + this.fragment), !0;
+ }
+
+ if (this._wantsPushState && this._hasPushState && b && a.hash) {
+ this.fragment = a.hash.replace(j, ''), window.history.replaceState({},
+ document.title, a.protocol + '//' + a.host + this.options.root + this.fragment);
+ }
+
+ if (!this.options.silent) {
+ return this.loadUrl();
+ }
+ }, route(a, b) {
+ this.handlers.unshift({route: a, callback: b});
+ }, checkUrl() {
+ let a = this.getFragment(); a == this.fragment && this.iframe && (a = this.getFragment(this.iframe.location.hash)); if (a == this.fragment || a == decodeURIComponent(this.fragment)) {
+ return !1;
+ }
+
+ this.iframe && this.navigate(a); this.loadUrl() || this.loadUrl(window.location.hash);
+ }, loadUrl(a) {
+ const b = this.fragment = this.getFragment(a);
+ return f.any(this.handlers, a => {
+ if (a.route.test(b)) {
+ return a.callback(b), !0;
+ }
+ });
+ }, navigate(a, b) {
+ let c = (a || '').replace(j, ''); if (!(this.fragment == c || this.fragment == decodeURIComponent(c))) {
+ if (this._hasPushState) {
+ const d = window.location; c.indexOf(this.options.root) != 0 && (c = this.options.root + c); this.fragment = c; window.history.pushState({}, document.title, d.protocol + '//' + d.host + c);
+ } else if (window.location.hash = this.fragment = c, this.iframe && c != this.getFragment(this.iframe.location.hash)) {
+ this.iframe.document.open().close(),
+ this.iframe.location.hash = c;
+ }
+
+ b && this.loadUrl(a);
+ }
+ }}); e.View = function (a) {
+ this.cid = f.uniqueId('view'); this._configure(a || {}); this._ensureElement(); this.delegateEvents(); Reflect.apply(this.initialize, this, arguments);
+ };
+
+ const u = /^(\S+)\s*(.*)$/; const n = ['model', 'collection', 'el', 'id', 'attributes', 'className', 'tagName']; f.extend(e.View.prototype, e.Events, {tagName: 'div', $(a) {
+ return g(a, this.el);
+ }, initialize() {}, render() {
+ return this;
+ }, remove() {
+ g(this.el).remove(); return this;
+ }, make(a,
+ b, c) {
+ a = document.createElement(a); b && g(a).attr(b); c && g(a).html(c); return a;
+ }, delegateEvents(a) {
+ if (a || (a = this.events)) {
+ for (const b in f.isFunction(a) && (a = a.call(this)), g(this.el).unbind('.delegateEvents' + this.cid), a) {
+ let c = this[a[b]]; if (!c) {
+ throw new Error('Event "' + a[b] + '" does not exist');
+ }
+
+ let d = b.match(u); let e = d[1]; d = d[2]; c = f.bind(c, this); e += '.delegateEvents' + this.cid; d === '' ? g(this.el).bind(e, c) : g(this.el).delegate(d, e, c);
+ }
+ }
+ }, _configure(a) {
+ this.options && (a = f.extend({}, this.options, a)); for (let b =
+0, c = n.length; b < c; b++) {
+ const d = n[b]; a[d] && (this[d] = a[d]);
+ }
+
+ this.options = a;
+ }, _ensureElement() {
+ if (this.el) {
+ if (f.isString(this.el)) {
+ this.el = g(this.el).get(0);
+ }
+ } else {
+ const a = this.attributes || {}; if (this.id) {
+ a.id = this.id;
+ }
+
+ if (this.className) {
+ a.class = this.className;
+ }
+
+ this.el = this.make(this.tagName, a);
+ }
+ }}); e.Model.extend = e.Collection.extend = e.Router.extend = e.View.extend = function (a, b) {
+ const c = v(this, a, b); c.extend = this.extend; return c;
+ };
+
+ const w = {create: 'POST', update: 'PUT', delete: 'DELETE', read: 'GET'}; e.sync = function (a,
+ b, c) {
+ const d = w[a]; c = f.extend({type: d, dataType: 'json'}, c); if (!c.url) {
+ c.url = k(b) || l();
+ }
+
+ if (!c.data && b && (a == 'create' || a == 'update')) {
+ c.contentType = 'application/json', c.data = JSON.stringify(b.toJSON());
+ }
+
+ if (e.emulateJSON) {
+ c.contentType = 'application/x-www-form-urlencoded', c.data = c.data ? {model: c.data} : {};
+ }
+
+ if (e.emulateHTTP && (d === 'PUT' || d === 'DELETE')) {
+ if (e.emulateJSON) {
+ c.data._method = d;
+ }
+
+ c.type = 'POST'; c.beforeSend = function (a) {
+ a.setRequestHeader('X-HTTP-Method-Override', d);
+ };
+ }
+
+ if (c.type !== 'GET' && !e.emulateJSON) {
+ c.processData =
+!1;
+ }
+
+ return g.ajax(c);
+ };
+
+ const o = function () {}; var v = function (a, b, c) {
+ let d; d = b && b.hasOwnProperty('constructor') ? b.constructor : function () {
+ return Reflect.apply(a, this, arguments);
+ };
+
+ f.extend(d, a); o.prototype = a.prototype; d.prototype = new o(); b && f.extend(d.prototype, b); c && f.extend(d, c); d.prototype.constructor = d; d.__super__ = a.prototype; return d;
+ };
+
+ var k = function (a) {
+ if (!a || !a.url) {
+ return null;
+ }
+
+ return f.isFunction(a.url) ? a.url() : a.url;
+ };
+
+ var l = function () {
+ throw new Error('A "url" property or function must be specified');
+ };
+
+ var i = function (a, b, c) {
+ return function (d) {
+ a ?
+ a(b, d, c) : b.trigger('error', b, d, c);
+ };
+ };
+ }).call(this);
+
+ /**
* Backbone localStorage Adapter v1.0
* https://github.com/jeromegn/Backbone.localStorage
*
* Date: Sun Aug 14 2011 09:53:55 -0400
*/
-; (function() {
- var _ = require("underscore")._;
- var Backbone = exports;
- function S4(){return(((1+Math.random())*65536)|0).toString(16).substring(1)}
- function guid(){return(S4()+S4()+"-"+S4()+"-"+S4()+"-"+S4()+"-"+S4()+S4()+S4())}
- var Store=function(b){this.name=b;var a=localStorage.getItem(this.name);this.records=(a&&a.split(","))||[]};_.extend(Store.prototype,{save:function(){localStorage.setItem(this.name,this.records.join(","))},create:function(a){if(!a.id){a.id=a.attributes.id=guid()}localStorage.setItem(this.name+"-"+a.id,JSON.stringify(a));this.records.push(a.id.toString());this.save();return a},update:function(a){localStorage.setItem(this.name+"-"+a.id,JSON.stringify(a));if(!_.include(this.records,a.id.toString())){this.records.push(a.id.toString())}this.save();return a},find:function(a){return JSON.parse(localStorage.getItem(this.name+"-"+a.id))},findAll:function(){return _.map(this.records,function(a){return JSON.parse(localStorage.getItem(this.name+"-"+a))},this)},destroy:function(a){localStorage.removeItem(this.name+"-"+a.id);this.records=_.reject(this.records,function(b){return b==a.id.toString()});this.save();return a}});Backbone.sync=function(f,d,c,b){if(typeof c=="function"){c={success:c,error:b}}var e;var a=d.localStorage||d.collection.localStorage;switch(f){case"read":e=d.id?a.find(d):a.findAll();break;case"create":e=a.create(d);break;case"update":e=a.update(d);break;case"delete":e=a.destroy(d);break}if(e){c.success(e)}else{c.error("Record not found")}};
- exports.Store = Store;
-})();
-
-});
+ (function () {
+ const {_} = require('underscore');
+ const Backbone = exports;
+ function S4() {
+ return (((1 + Math.random()) * 65536) | 0).toString(16).slice(1);
+ }
+
+ function guid() {
+ return (S4() + S4() + '-' + S4() + '-' + S4() + '-' + S4() + '-' + S4() + S4() + S4());
+ }
+
+ const Store = function (b) {
+ this.name = b; const a = localStorage.getItem(this.name); this.records = (a && a.split(',')) || [];
+ };
+
+ _.extend(Store.prototype, {save() {
+ localStorage.setItem(this.name, this.records.join(','));
+ }, create(a) {
+ if (!a.id) {
+ a.id = a.attributes.id = guid();
+ }
+
+ localStorage.setItem(this.name + '-' + a.id, JSON.stringify(a)); this.records.push(a.id.toString()); this.save(); return a;
+ }, update(a) {
+ localStorage.setItem(this.name + '-' + a.id, JSON.stringify(a)); if (!_.include(this.records, a.id.toString())) {
+ this.records.push(a.id.toString());
+ }
+
+ this.save(); return a;
+ }, find(a) {
+ return JSON.parse(localStorage.getItem(this.name + '-' + a.id));
+ }, findAll() {
+ return _.map(this.records, function (a) {
+ return JSON.parse(localStorage.getItem(this.name + '-' + a));
+ }, this);
+ }, destroy(a) {
+ localStorage.removeItem(this.name + '-' + a.id); this.records = _.reject(this.records, b => {
+ return b == a.id.toString();
+ }); this.save(); return a;
+ }}); Backbone.sync = function (f, d, c, b) {
+ if (typeof c === 'function') {
+ c = {success: c, error: b};
+ }
+
+ let e; const a = d.localStorage || d.collection.localStorage; switch (f) {
+ case 'read': e = d.id ? a.find(d) : a.findAll(); break; case 'create': e = a.create(d); break; case 'update': e = a.update(d); break; case 'delete': e = a.destroy(d); break;
+ }
+
+ if (e) {
+ c.success(e);
+ } else {
+ c.error('Record not found');
+ }
+ };
+
+ exports.Store = Store;
+ })();
+ });
diff --git a/demos/twitter_backbone/vendor/bravo.js b/demos/twitter_backbone/vendor/bravo.js
index 20ae4cbb..b725a624 100644
--- a/demos/twitter_backbone/vendor/bravo.js
+++ b/demos/twitter_backbone/vendor/bravo.js
@@ -5,260 +5,258 @@
* Wes Garland, wes@page.ca
* MIT License
*/
-var bravojs; /**< Namespace object for this implementation */
+let bravojs; /** < Namespace object for this implementation */
-if (typeof bravojs === "undefined")
- bravojs = {};
-
-try {
-
-if (!bravojs.hasOwnProperty("errorReporter"))
-{
- bravojs.errorReporter = function bravojs_defaultDrrorReporter(e)
- {
- alert(" * BravoJS: " + e + "\n" + e.stack);
- throw(e);
- }
-}
-
-/** Reset the environment so that a new main module can be loaded */
-bravojs.reset = function bravojs_reset(mainModuleDir)
-{
- if (!mainModuleDir)
- {
- if (bravojs.mainModuleDir)
- mainModuleDir = bravojs.mainModuleDir;
- else
- mainModuleDir = bravojs.dirname(bravojs.URL_toId(window.location.href + ".js", true));
- }
-
- bravojs.requireMemo = {}; /**< Module exports, indexed by canonical name */
- bravojs.pendingModuleDeclarations = {}; /**< Module.declare arguments, indexed by canonical name */
- bravojs.mainModuleDir = mainModuleDir;
-
- delete bravojs.Module.prototype.main;
- delete bravojs.scriptTagMemo;
- delete bravojs.scriptTagMemoIE;
-
- /** Extra-module environment */
- window.require = bravojs.requireFactory(bravojs.mainModuleDir);
- window.module = new bravojs.Module('', []);
+if (typeof bravojs === 'undefined') {
+ bravojs = {};
}
-/** Print to text to stdout */
-bravojs.print = function bravojs_print()
-{
- var output="";
- var i;
- var stdout;
-
- for (i=0; i < arguments.length; i++)
- output += arguments[i] + (i===arguments.length - 1 ? "" : " ");
- output.replace(/\t/, " ");
-
- if ((stdout = document.getElementById('stdout')))
- {
- output += "\n";
-
- if (typeof stdout.value !== "undefined")
- {
- stdout.value += output;
- if (stdout.focus)
- stdout.focus();
-
- if (stdout.tagName === "TEXTAREA")
- stdout.scrollTop = stdout.scrollHeight;
- }
- else
- {
- if (typeof stdout.innerText !== "undefined")
- {
- stdout.innerText = stdout.innerText.slice(0,-1) + output + " "; /* IE normalizes trailing newlines away */
- }
- else
- stdout.textContent += output;
+try {
+ if (!bravojs.hasOwnProperty('errorReporter')) {
+ bravojs.errorReporter = function bravojs_defaultDrrorReporter(e) {
+ alert(' * BravoJS: ' + e + '\n' + e.stack);
+ throw (e);
+ };
}
- }
- else if (typeof console === "object" && console.print)
- {
- console.print(output);
- }
- else if (typeof console === "object" && console.log)
- {
- console.log(output);
- }
- else
- alert(" * BravoJS stdout: " + output);
-}
-/** Canonicalize path, compacting slashes and dots per basic UNIX rules.
+ /** Reset the environment so that a new main module can be loaded */
+ bravojs.reset = function bravojs_reset(mainModuleDir) {
+ if (!mainModuleDir) {
+ if (bravojs.mainModuleDir) {
+ mainModuleDir = bravojs.mainModuleDir;
+ } else {
+ mainModuleDir = bravojs.dirname(bravojs.URL_toId(window.location.href + '.js', true));
+ }
+ }
+
+ bravojs.requireMemo = {}; /** < Module exports, indexed by canonical name */
+ bravojs.pendingModuleDeclarations = {}; /** < Module.declare arguments, indexed by canonical name */
+ bravojs.mainModuleDir = mainModuleDir;
+
+ delete bravojs.Module.prototype.main;
+ delete bravojs.scriptTagMemo;
+ delete bravojs.scriptTagMemoIE;
+
+ /** Extra-module environment */
+ window.require = bravojs.requireFactory(bravojs.mainModuleDir);
+ window.module = new bravojs.Module('', []);
+ };
+
+ /** Print to text to stdout */
+ bravojs.print = function bravojs_print() {
+ let output = '';
+ let i;
+ let stdout;
+
+ for (i = 0; i < arguments.length; i++) {
+ output += arguments[i] + (i === arguments.length - 1 ? '' : ' ');
+ }
+
+ output.replace(/\t/, ' ');
+
+ if ((stdout = document.querySelector('#stdout'))) {
+ output += '\n';
+
+ if (typeof stdout.value !== 'undefined') {
+ stdout.value += output;
+ if (stdout.focus) {
+ stdout.focus();
+ }
+
+ if (stdout.tagName === 'TEXTAREA') {
+ stdout.scrollTop = stdout.scrollHeight;
+ }
+ } else if (typeof stdout.textContent !== 'undefined') {
+ stdout.textContent = stdout.textContent.slice(0, -1) + output + ' '; /* IE normalizes trailing newlines away */
+ } else {
+ stdout.textContent += output;
+ }
+ } else if (typeof console === 'object' && console.print) {
+ console.print(output);
+ } else if (typeof console === 'object' && console.log) {
+ console.log(output);
+ } else {
+ alert(' * BravoJS stdout: ' + output);
+ }
+ };
+
+ /** Canonicalize path, compacting slashes and dots per basic UNIX rules.
* Treats paths with trailing slashes as though they end with INDEX instead.
* Not rigorous.
*/
-bravojs.realpath = function bravojs_realpath(path)
-{
- if (typeof path !== "string")
- path = path.toString();
-
- var oldPath = path.split('/');
- var newPath = [];
- var i;
-
- if (path.charAt(path.length - 1) === '/')
- oldPath.push("INDEX");
-
- for (i = 0; i < oldPath.length; i++)
- {
- if (oldPath[i] == '.' || !oldPath[i].length)
- continue;
- if (oldPath[i] == '..')
- {
- if (!newPath.length)
- throw new Error("Invalid module path: " + path);
- newPath.pop();
- continue;
- }
- newPath.push(oldPath[i]);
- }
-
- newPath.unshift('');
- return newPath.join('/');
-}
+ bravojs.realpath = function bravojs_realpath(path) {
+ if (typeof path !== 'string') {
+ path = path.toString();
+ }
+
+ const oldPath = path.split('/');
+ const newPath = [];
+ let i;
+
+ if (path.charAt(path.length - 1) === '/') {
+ oldPath.push('INDEX');
+ }
+
+ for (i = 0; i < oldPath.length; i++) {
+ if (oldPath[i] == '.' || !oldPath[i].length) {
+ continue;
+ }
+
+ if (oldPath[i] == '..') {
+ if (!newPath.length) {
+ throw new Error('Invalid module path: ' + path);
+ }
+
+ newPath.pop();
+ continue;
+ }
+
+ newPath.push(oldPath[i]);
+ }
+
+ newPath.unshift('');
+ return newPath.join('/');
+ };
+
+ /** Extract the non-directory portion of a path */
+ bravojs.basename = function bravojs_basename(path) {
+ if (typeof path !== 'string') {
+ path = path.toString();
+ }
+
+ const s = path.split('/').slice(-1).join('/');
+ if (!s) {
+ return path;
+ }
+
+ return s;
+ };
+
+ /** Extract the directory portion of a path */
+ bravojs.dirname = function bravojs_dirname(path) {
+ if (typeof path !== 'string') {
+ path = path.toString();
+ }
+
+ if (path.charAt(path.length - 1) === '/') {
+ return path.slice(0, -1);
+ }
+
+ const s = path.split('/').slice(0, -1).join('/');
+ if (!s) {
+ return '.';
+ }
+
+ return s;
+ };
+
+ /** Turn a module identifier and module directory into a canonical
+ * module.id.
+ */
+ bravojs.makeModuleId = function makeModuleId(relativeModuleDir, moduleIdentifier) {
+ let id;
+
+ if (moduleIdentifier === '') /* Special case for main module */
+ {
+ return '';
+ }
+
+ if (typeof moduleIdentifier !== 'string') {
+ throw new TypeError('Invalid module identifier: ' + moduleIdentifier.toSource());
+ }
+
+ if (moduleIdentifier.charAt(0) === '/') {
+ /* Absolute path. Not required by CommonJS but it makes dependency list optimization easier */
+ id = moduleIdentifier;
+ } else
+ if ((moduleIdentifier.indexOf('./') == 0) || (moduleIdentifier.indexOf('../') == 0)) {
+ /* Relative module path -- relative to relativeModuleDir */
+ id = relativeModuleDir + '/' + moduleIdentifier;
+ } else {
+ /* Top-level module. Since we don't implement require.paths,
+ * make it relative to the main module.
+ */
+ id = bravojs.mainModuleDir + '/' + moduleIdentifier;
+ }
-/** Extract the non-directory portion of a path */
-bravojs.basename = function bravojs_basename(path)
-{
- if (typeof path !== "string")
- path = path.toString();
+ return bravojs.realpath(id);
+ };
- var s = path.split('/').slice(-1).join('/');
- if (!s)
- return path;
- return s;
-}
+ /** Turn a script URL into a canonical module.id */
+ bravojs.URL_toId = function URL_toId(moduleURL, relaxValidation) {
+ let i;
-/** Extract the directory portion of a path */
-bravojs.dirname = function bravojs_dirname(path)
-{
- if (typeof path !== "string")
- path = path.toString();
+ /* Treat the whole web as our module repository.
+ * 'http://www.page.ca/a/b/module.js' has id '/www.page.ca/a/b/module'.
+ */
+ i = moduleURL.indexOf('://');
+ if (i == -1) {
+ throw new Error('Invalid module URL: ' + moduleURL);
+ }
- if (path.charAt(path.length - 1) === '/')
- return path.slice(0,-1);
+ id = moduleURL.slice(i + 2);
- var s = path.split('/').slice(0,-1).join('/');
- if (!s)
- return ".";
+ id = bravojs.realpath(id);
+ if ((i = id.indexOf('?')) != -1) {
+ id = id.slice(0, i);
+ }
- return s;
-}
+ if ((i = id.indexOf('#')) != -1) {
+ id = id.slice(0, i);
+ }
-/** Turn a module identifier and module directory into a canonical
- * module.id.
- */
-bravojs.makeModuleId = function makeModuleId(relativeModuleDir, moduleIdentifier)
-{
- var id;
-
- if (moduleIdentifier === '') /* Special case for main module */
- return '';
-
- if (typeof moduleIdentifier !== "string")
- throw new Error("Invalid module identifier: " + moduleIdentifier.toSource());
-
- if (moduleIdentifier.charAt(0) === '/')
- {
- /* Absolute path. Not required by CommonJS but it makes dependency list optimization easier */
- id = moduleIdentifier;
- }
- else
- if ((moduleIdentifier.indexOf("./") == 0) || (moduleIdentifier.indexOf("../") == 0))
- {
- /* Relative module path -- relative to relativeModuleDir */
- id = relativeModuleDir + "/" + moduleIdentifier;
- }
- else
- {
- /* Top-level module. Since we don't implement require.paths,
- * make it relative to the main module.
- */
- id = bravojs.mainModuleDir + "/" + moduleIdentifier;
- }
+ if (!relaxValidation && (id.slice(-3) != '.js')) {
+ throw new Error('Invalid module URL: ' + moduleURL);
+ }
- return bravojs.realpath(id);
-}
+ id = id.slice(0, -3);
-/** Turn a script URL into a canonical module.id */
-bravojs.URL_toId = function URL_toId(moduleURL, relaxValidation)
-{
- var i;
+ return id;
+ };
- /* Treat the whole web as our module repository.
- * 'http://www.page.ca/a/b/module.js' has id '/www.page.ca/a/b/module'.
- */
- i = moduleURL.indexOf("://");
- if (i == -1)
- throw new Error("Invalid module URL: " + moduleURL);
- id = moduleURL.slice(i + 2);
-
- id = bravojs.realpath(id);
- if ((i = id.indexOf('?')) != -1)
- id = id.slice(0, i);
- if ((i = id.indexOf('#')) != -1)
- id = id.slice(0, i);
-
- if (!relaxValidation && (id.slice(-3) != ".js"))
- throw new Error("Invalid module URL: " + moduleURL);
- id = id.slice(0,-3);
-
- return id;
-}
-
-/** Normalize a dependency array so that only unique and previously unprovided
+ /** Normalize a dependency array so that only unique and previously unprovided
* dependencies appear in the output list. The output list also canonicalizes
* the module names relative to the current require. Labeled dependencies are
* unboxed.
*/
-bravojs.normalizeDependencyArray = function bravojs_normalizeDependencyArray(dependencies)
-{
- var normalizedDependencies = [];
- var i, label;
-
- function addNormal(moduleIdentifier)
- {
- var id = require.id(moduleIdentifier);
-
- if (bravojs.requireMemo[id] || bravojs.pendingModuleDeclarations[id])
- return;
-
- normalizedDependencies.push(id);
- }
-
- for (i=0; i < dependencies.length; i++)
- {
- switch(typeof dependencies[i])
- {
- case "object":
- for (label in dependencies[i])
- {
- if (dependencies[i].hasOwnProperty(label))
- addNormal(dependencies[i][label]);
- }
- break;
-
- case "string":
- addNormal(dependencies[i]);
- break;
-
- default:
- throw new Error("Invalid dependency array value at position " + (i+1));
- }
- }
+ bravojs.normalizeDependencyArray = function bravojs_normalizeDependencyArray(dependencies) {
+ const normalizedDependencies = [];
+ let i; let label;
- return normalizedDependencies;
-}
+ function addNormal(moduleIdentifier) {
+ const id = require.id(moduleIdentifier);
+
+ if (bravojs.requireMemo[id] || bravojs.pendingModuleDeclarations[id]) {
+ return;
+ }
+
+ normalizedDependencies.push(id);
+ }
+
+ for (i = 0; i < dependencies.length; i++) {
+ switch (typeof dependencies[i]) {
+ case 'object':
+ for (label in dependencies[i]) {
+ if (dependencies[i].hasOwnProperty(label)) {
+ addNormal(dependencies[i][label]);
+ }
+ }
+
+ break;
+
+ case 'string':
+ addNormal(dependencies[i]);
+ break;
+
+ default:
+ throw new Error('Invalid dependency array value at position ' + (i + 1));
+ }
+ }
-/** Provide a module to the environment
+ return normalizedDependencies;
+ };
+
+ /** Provide a module to the environment
* @param dependencies A dependency array
* @param moduleFactoryFunction The function which will eventually be invoked
* to decorate the module's exports. If not specified,
@@ -268,246 +266,230 @@ bravojs.normalizeDependencyArray = function bravojs_normalizeDependencyArray(dep
* @param callback Optional function to run after the module has been
* provided to the environment
*/
-bravojs.provideModule = function bravojs_provideModule(dependencies, moduleFactory,
- id, callback)
-{
- /* Memoize the the factory, satistfy the dependencies, and invoke the callback */
- if (moduleFactory)
- require.memoize(id, dependencies, moduleFactory);
-
- if (dependencies)
- {
- module.provide(bravojs.normalizeDependencyArray(dependencies), callback);
- }
- else
- {
- if (callback)
- callback();
- }
-}
-
-/** Initialize a module. This makes the exports object available to require(),
+ bravojs.provideModule = function bravojs_provideModule(dependencies, moduleFactory,
+ id, callback) {
+ /* Memoize the the factory, satistfy the dependencies, and invoke the callback */
+ if (moduleFactory) {
+ require.memoize(id, dependencies, moduleFactory);
+ }
+
+ if (dependencies) {
+ module.provide(bravojs.normalizeDependencyArray(dependencies), callback);
+ } else if (callback) {
+ callback();
+ }
+ };
+
+ /** Initialize a module. This makes the exports object available to require(),
* runs the module factory function, and removes the factory function from
* the pendingModuleDeclarations object.
*/
-bravojs.initializeModule = function bravojs_initializeModule(id)
-{
- var moduleDir = id ? bravojs.dirname(id) : bravojs.mainModuleDir;
- var moduleFactory = bravojs.pendingModuleDeclarations[id].moduleFactory;
- var dependencies = bravojs.pendingModuleDeclarations[id].dependencies;
- var require, exports, module;
+ bravojs.initializeModule = function bravojs_initializeModule(id) {
+ const moduleDir = id ? bravojs.dirname(id) : bravojs.mainModuleDir;
+ const {moduleFactory} = bravojs.pendingModuleDeclarations[id];
+ const {dependencies} = bravojs.pendingModuleDeclarations[id];
+ let require; let exports; let module;
- delete bravojs.pendingModuleDeclarations[id];
+ delete bravojs.pendingModuleDeclarations[id];
- require = bravojs.requireFactory(moduleDir, dependencies);
- exports = bravojs.requireMemo[id] = {};
- module = new bravojs.Module(id, dependencies);
+ require = bravojs.requireFactory(moduleDir, dependencies);
+ exports = bravojs.requireMemo[id] = {};
+ module = new bravojs.Module(id, dependencies);
- moduleFactory(require, exports, module);
-}
+ moduleFactory(require, exports, module);
+ };
-/** Search the module memo and return the correct module's exports, or throw.
+ /** Search the module memo and return the correct module's exports, or throw.
* Searching the module memo will initialize a matching pending module factory.
*/
-bravojs.requireModule = function bravojs_requireModule(parentModuleDir, moduleIdentifier)
-{
- var id = bravojs.makeModuleId(parentModuleDir, moduleIdentifier);
+ bravojs.requireModule = function bravojs_requireModule(parentModuleDir, moduleIdentifier) {
+ const id = bravojs.makeModuleId(parentModuleDir, moduleIdentifier);
- if (!bravojs.requireMemo[id] && bravojs.pendingModuleDeclarations[id])
- bravojs.initializeModule(id);
+ if (!bravojs.requireMemo[id] && bravojs.pendingModuleDeclarations[id]) {
+ bravojs.initializeModule(id);
+ }
- if (id === null || !bravojs.requireMemo[id])
- throw new Error("Module " + id + " is not available.");
+ if (id === null || !bravojs.requireMemo[id]) {
+ throw new Error('Module ' + id + ' is not available.');
+ }
- return bravojs.requireMemo[id];
-}
+ return bravojs.requireMemo[id];
+ };
-/** Create a new require function, closing over it's path so that relative
+ /** Create a new require function, closing over it's path so that relative
* modules work as expected.
*/
-bravojs.requireFactory = function bravojs_requireFactory(moduleDir, dependencies)
-{
- var deps, i, label;
-
- function addLabeledDep(moduleIdentifier)
- {
- deps[label] = function bravojs_labeled_dependency()
- {
- return bravojs.requireModule(moduleDir, moduleIdentifier);
- }
- }
-
- if (dependencies)
- {
- for (i=0; i < dependencies.length; i++)
- {
- if (typeof dependencies[i] !== "object")
- continue;
-
- for (label in dependencies[i])
- {
- if (dependencies[i].hasOwnProperty(label))
- {
- if (!deps)
- deps = {};
+ bravojs.requireFactory = function bravojs_requireFactory(moduleDir, dependencies) {
+ let deps; let i; let label;
+
+ function addLabeledDep(moduleIdentifier) {
+ deps[label] = function bravojs_labeled_dependency() {
+ return bravojs.requireModule(moduleDir, moduleIdentifier);
+ };
+ }
+
+ if (dependencies) {
+ for (i = 0; i < dependencies.length; i++) {
+ if (typeof dependencies[i] !== 'object') {
+ continue;
+ }
+
+ for (label in dependencies[i]) {
+ if (dependencies[i].hasOwnProperty(label)) {
+ if (!deps) {
+ deps = {};
+ }
+
addLabeledDep(dependencies[i][label]);
- }
- }
- }
- }
+ }
+ }
+ }
+ }
- var newRequire = function require(moduleIdentifier)
- {
- if (deps && deps[moduleIdentifier])
- return deps[moduleIdentifier]();
- return bravojs.requireModule(moduleDir, moduleIdentifier);
- }
+ const newRequire = function require(moduleIdentifier) {
+ if (deps && deps[moduleIdentifier]) {
+ return deps[moduleIdentifier]();
+ }
+
+ return bravojs.requireModule(moduleDir, moduleIdentifier);
+ };
- newRequire.id = function require_id(moduleIdentifier)
- {
- return bravojs.makeModuleId(moduleDir, moduleIdentifier);
- }
+ newRequire.id = function require_id(moduleIdentifier) {
+ return bravojs.makeModuleId(moduleDir, moduleIdentifier);
+ };
- newRequire.canonicalize = function require_canonicalize(moduleIdentifier)
- {
- var id = bravojs.makeModuleId(moduleDir, moduleIdentifier);
+ newRequire.canonicalize = function require_canonicalize(moduleIdentifier) {
+ const id = bravojs.makeModuleId(moduleDir, moduleIdentifier);
- if (id === '')
- throw new Error("Cannot canonically name the resource bearing this main module");
+ if (id === '') {
+ throw new Error('Cannot canonically name the resource bearing this main module');
+ }
- return window.location.protocol + "/" + id + ".js";
- }
+ return window.location.protocol + '/' + id + '.js';
+ };
- newRequire.memoize = function require_memoize(id, dependencies, moduleFactory)
- {
- bravojs.pendingModuleDeclarations[id] = { moduleFactory: moduleFactory, dependencies: dependencies };
- }
+ newRequire.memoize = function require_memoize(id, dependencies, moduleFactory) {
+ bravojs.pendingModuleDeclarations[id] = {moduleFactory, dependencies};
+ };
- newRequire.isMemoized = function require_isMemoized(id)
- {
- return (bravojs.pendingModuleDeclarations[id] || bravojs.requireMemo[id]) ? true : false;
- }
+ newRequire.isMemoized = function require_isMemoized(id) {
+ return Boolean(bravojs.pendingModuleDeclarations[id] || bravojs.requireMemo[id]);
+ };
- return newRequire;
-}
+ return newRequire;
+ };
-/** Module object constructor
+ /** Module object constructor
*
* @param id The canonical module id
* @param dependencies The dependency list passed to module.declare
*/
-bravojs.Module = function bravojs_Module(id, dependencies)
-{
- this.id = id;
- this.protected = void 0;
- this.dependencies = dependencies;
-
- var i, label;
-
- /* Create module.deps array */
- this.deps = {};
-
- for (i=0; i < dependencies.length; i++)
- {
- if (typeof dependencies[i] === "string")
- continue;
-
- if (typeof dependencies[i] !== "object")
- throw new Error("Invalid " + typeof dependencies[i] + " element in dependency array at position " + i);
-
- /* Labeled dependency object */
- for (label in dependencies[i])
- {
- if (dependencies[i].hasOwnProperty(label))
- {
- this.deps[label] = function bravojs_lambda_module_deps()
- {
+ bravojs.Module = function bravojs_Module(id, dependencies) {
+ this.id = id;
+ this.protected = void 0;
+ this.dependencies = dependencies;
+
+ let i; let label;
+
+ /* Create module.deps array */
+ this.deps = {};
+
+ for (i = 0; i < dependencies.length; i++) {
+ if (typeof dependencies[i] === 'string') {
+ continue;
+ }
+
+ if (typeof dependencies[i] !== 'object') {
+ throw new TypeError('Invalid ' + typeof dependencies[i] + ' element in dependency array at position ' + i);
+ }
+
+ /* Labeled dependency object */
+ for (label in dependencies[i]) {
+ if (dependencies[i].hasOwnProperty(label)) {
+ this.deps[label] = function bravojs_lambda_module_deps() {
bravojs.requireModule(bravojs.dirname(id), dependencies[i][label]);
- };
- }
- }
- }
-}
+ };
+ }
+ }
+ }
+ };
-/** A module.declare suitable for use during DOM SCRIPT-tag insertion.
- *
+ /** A module.declare suitable for use during DOM SCRIPT-tag insertion.
+ *
* The general technique described below was invented by Kris Zyp.
*
- * In non-IE browsers, the script's onload event fires as soon as the
+ * In non-IE browsers, the script's onload event fires as soon as the
* script finishes running, so we just memoize the declaration without
* doing anything. After the script is loaded, we do the "real" work
* as the onload event also supplies the script's URI, which we use
* to generate the canonical module id.
- *
+ *
* In IE browsers, the event can fire when the tag is being inserted
- * in the DOM, or sometime thereafter. In the first case, we read a
+ * in the DOM, or sometime thereafter. In the first case, we read a
* memo we left behind when we started inserting the tag; in the latter,
* we look for interactive scripts.
*
- * Event Action
+ * Event Action
* ------------------------- ------------------------------------------------------------------------------------
* Inject Script Tag onload event populated with URI
* scriptTagMemo populated with URI
* IE pulls from cache cname derived in module.declare from scriptTagMemo, invoke provideModule
* IE pulls from http cname derived in module.declare from script.src, invoke provideModule
- * Non-IE loads script onload event triggered, most recent incomplete module.declare is completed,
+ * Non-IE loads script onload event triggered, most recent incomplete module.declare is completed,
* deriving the cname from the onload event.
*/
-bravojs.Module.prototype.declare = function bravojs_Module_declare(dependencies, moduleFactory)
-{
- var stm;
-
- if (typeof dependencies === "function")
- {
- moduleFactory = dependencies;
- dependencies = [];
- }
-
- stm = bravojs.scriptTagMemo;
- if (stm && stm.id === '') /* Static HTML module */
- {
- delete bravojs.scriptTagMemo;
- bravojs.provideModule(dependencies, moduleFactory, stm.id, stm.callback);
- return;
- }
-
- if (stm)
- throw new Error("Bug");
-
- if (document.addEventListener) /* non-IE, defer work to script's onload event which will happen immediately */
- {
- bravojs.scriptTagMemo = { dependencies: dependencies, moduleFactory: moduleFactory };
- return;
- }
-
- stm = bravojs.scriptTagMemoIE;
- delete bravojs.scriptTagMemoIE;
-
- if (stm && stm.id) /* IE, pulling from cache */
- {
- bravojs.provideModule(dependencies, moduleFactory, stm.id, stm.callback);
- return;
- }
-
- /* Assume IE fetching from remote */
- var scripts = document.getElementsByTagName("SCRIPT");
- var i;
-
- for (i = 0; i < scripts.length; i++)
- {
- if (scripts[i].readyState === "interactive")
- {
- bravojs.provideModule(dependencies, moduleFactory, bravojs.URL_toId(scripts[i].src), stm.callback);
- return;
- }
- }
-
- throw new Error("Could not determine module's canonical name from script-tag loader");
-}
-
-/** A module.provide suitable for a generic web-server back end. Loads one module at
+ bravojs.Module.prototype.declare = function bravojs_Module_declare(dependencies, moduleFactory) {
+ let stm;
+
+ if (typeof dependencies === 'function') {
+ moduleFactory = dependencies;
+ dependencies = [];
+ }
+
+ stm = bravojs.scriptTagMemo;
+ if (stm && stm.id === '') /* Static HTML module */
+ {
+ delete bravojs.scriptTagMemo;
+ bravojs.provideModule(dependencies, moduleFactory, stm.id, stm.callback);
+ return;
+ }
+
+ if (stm) {
+ throw new Error('Bug');
+ }
+
+ if (document.addEventListener) /* Non-IE, defer work to script's onload event which will happen immediately */
+ {
+ bravojs.scriptTagMemo = {dependencies, moduleFactory};
+ return;
+ }
+
+ stm = bravojs.scriptTagMemoIE;
+ delete bravojs.scriptTagMemoIE;
+
+ if (stm && stm.id) /* IE, pulling from cache */
+ {
+ bravojs.provideModule(dependencies, moduleFactory, stm.id, stm.callback);
+ return;
+ }
+
+ /* Assume IE fetching from remote */
+ const scripts = document.querySelectorAll('SCRIPT');
+ let i;
+
+ for (i = 0; i < scripts.length; i++) {
+ if (scripts[i].readyState === 'interactive') {
+ bravojs.provideModule(dependencies, moduleFactory, bravojs.URL_toId(scripts[i].src), stm.callback);
+ return;
+ }
+ }
+
+ throw new Error('Could not determine module\'s canonical name from script-tag loader');
+ };
+
+ /** A module.provide suitable for a generic web-server back end. Loads one module at
* a time in continuation-passing style, eventually invoking the passed callback.
- *
+ *
* A more effecient function could be written to take advantage of a web server
* which might aggregate and transport more than one module per HTTP request.
*
@@ -515,26 +497,29 @@ bravojs.Module.prototype.declare = function bravojs_Module_declare(dependencies,
* @param callback The callback to invoke once all dependencies have been
* provided to the environment. Optional.
*/
-bravojs.Module.prototype.provide = function bravojs_Module_provide(dependencies, callback)
-{
- var self = arguments.callee;
+ bravojs.Module.prototype.provide = function bravojs_Module_provide(dependencies, callback) {
+ const self = arguments.callee;
- if ((typeof dependencies !== "object") || (dependencies.length !== 0 && !dependencies.length))
- throw new Error("Invalid dependency array: " + dependencies.toString());
+ if ((typeof dependencies !== 'object') || (dependencies.length !== 0 && !dependencies.length)) {
+ throw new Error('Invalid dependency array: ' + dependencies.toString());
+ }
- dependencies = bravojs.normalizeDependencyArray(dependencies);
+ dependencies = bravojs.normalizeDependencyArray(dependencies);
- if (dependencies.length === 0)
- {
- if (callback)
- callback();
- return;
- }
+ if (dependencies.length === 0) {
+ if (callback) {
+ callback();
+ }
- module.load(dependencies[0], function bravojs_lambda_provideNextDep() { self(dependencies.slice(1), callback) });
-}
+ return;
+ }
+
+ module.load(dependencies[0], () => {
+ self(dependencies.slice(1), callback);
+ });
+ };
-/** A module.load suitable for a generic web-server back end. The module is
+ /** A module.load suitable for a generic web-server back end. The module is
* loaded by injecting a SCRIPT tag into the DOM.
*
* @param moduleIdentifier Module to load
@@ -542,213 +527,209 @@ bravojs.Module.prototype.provide = function bravojs_Module_provide(dependencies,
*
* @see bravojs_Module_declare
*/
-bravojs.Module.prototype.load = function bravojs_Module_load(moduleIdentifier, callback)
-{
- if (window.module.hasOwnProperty("declare"))
- delete window.module.declare;
-
- var script = document.createElement('SCRIPT');
- script.setAttribute("type","text/javascript");
- script.setAttribute("src", require.canonicalize(moduleIdentifier) + "?1");
-
- if (document.addEventListener) /* Non-IE; see bravojs_Module_declare */
- {
- script.onload = function bravojs_lambda_script_onload()
- {
- /* stm contains info from recently-run module.declare() */
- var stm = bravojs.scriptTagMemo;
- if (typeof stm === "undefined")
- throw new Error("Module '" + moduleIdentifier + "' did not invoke module.declare!");
-
- delete bravojs.scriptTagMemo;
- bravojs.provideModule(stm.dependencies, stm.moduleFactory, require.id(moduleIdentifier), callback);
- }
-
- script.onerror = function bravojs_lambda_script_onerror()
- {
- var id = require.id(moduleIdentifier);
- bravojs.pendingModuleDeclarations[id] = null; /* Mark null so we don't try to run, but also don't try to reload */
- callback();
- }
- }
- else
- {
- bravojs.scriptTagMemoIE = { moduleIdentifier: moduleIdentifier, callback: callback };
-
- script.onreadystatechange = function bravojs_lambda_script_onreadystatechange()
- {
- if (this.readyState != "loaded")
- return;
-
- /* failed load below */
- var id = require.id(moduleIdentifier);
-
- if (!bravojs.pendingModuleDeclarations[id] && !bravojs.requireMemo[id] && id === bravojs.scriptTagMemoIE.moduleIdentifier)
- {
- bravojs.pendingModuleDeclarations[id] = null; /* Mark null so we don't try to run, but also don't try to reload */
- callback();
- }
- }
- }
-
- document.getElementsByTagName("HEAD")[0].appendChild(script);
-}
-
-bravojs.Module.prototype.eventually = function(cb) { cb(); };
-
-/** Shim the environment to have CommonJS ES-5 requirements (if needed),
+ bravojs.Module.prototype.load = function bravojs_Module_load(moduleIdentifier, callback) {
+ if (window.module.hasOwnProperty('declare')) {
+ delete window.module.declare;
+ }
+
+ const script = document.createElement('SCRIPT');
+ script.setAttribute('type', 'text/javascript');
+ script.setAttribute('src', require.canonicalize(moduleIdentifier) + '?1');
+
+ if (document.addEventListener) /* Non-IE; see bravojs_Module_declare */
+ {
+ script.addEventListener('load', () => {
+ /* Stm contains info from recently-run module.declare() */
+ const stm = bravojs.scriptTagMemo;
+ if (typeof stm === 'undefined') {
+ throw new TypeError('Module \'' + moduleIdentifier + '\' did not invoke module.declare!');
+ }
+
+ delete bravojs.scriptTagMemo;
+ bravojs.provideModule(stm.dependencies, stm.moduleFactory, require.id(moduleIdentifier), callback);
+ });
+
+ script.addEventListener('error', () => {
+ const id = require.id(moduleIdentifier);
+ bravojs.pendingModuleDeclarations[id] = null; /* Mark null so we don't try to run, but also don't try to reload */
+ callback();
+ });
+ } else {
+ bravojs.scriptTagMemoIE = {moduleIdentifier, callback};
+
+ script.onreadystatechange = function bravojs_lambda_script_onreadystatechange() {
+ if (this.readyState != 'loaded') {
+ return;
+ }
+
+ /* Failed load below */
+ const id = require.id(moduleIdentifier);
+
+ if (!bravojs.pendingModuleDeclarations[id] && !bravojs.requireMemo[id] && id === bravojs.scriptTagMemoIE.moduleIdentifier) {
+ bravojs.pendingModuleDeclarations[id] = null; /* Mark null so we don't try to run, but also don't try to reload */
+ callback();
+ }
+ };
+ }
+
+ document.querySelectorAll('HEAD')[0].append(script);
+ };
+
+ bravojs.Module.prototype.eventually = function (cb) {
+ cb();
+ };
+
+ /** Shim the environment to have CommonJS ES-5 requirements (if needed),
* the execute the callback
*/
-bravojs.es5_shim_then = function bravojs_es5_shim_then(callback)
-{
- if (!Array.prototype.indexOf)
- {
- /* Load ES-5 shim into the environment before executing the main module */
- var script = document.createElement('SCRIPT');
- script.setAttribute("type","text/javascript");
- script.setAttribute("src", bravojs.dirname(bravojs.url) + "/global-es5.js?1");
-
- if (document.addEventListener)
- script.onload = callback;
- else
- {
- script.onreadystatechange = function()
- {
- if (this.readyState === "loaded")
- callback();
- }
- }
-
- document.getElementsByTagName("HEAD")[0].appendChild(script);
- }
- else
- {
- callback();
- }
-}
-
-/** Reload a module, violating the CommonJS singleton paradigm and
+ bravojs.es5_shim_then = function bravojs_es5_shim_then(callback) {
+ if (!Array.prototype.indexOf) {
+ /* Load ES-5 shim into the environment before executing the main module */
+ const script = document.createElement('SCRIPT');
+ script.setAttribute('type', 'text/javascript');
+ script.setAttribute('src', bravojs.dirname(bravojs.url) + '/global-es5.js?1');
+
+ if (document.addEventListener) {
+ script.addEventListener('load', callback);
+ } else {
+ script.onreadystatechange = function () {
+ if (this.readyState === 'loaded') {
+ callback();
+ }
+ };
+ }
+
+ document.querySelectorAll('HEAD')[0].append(script);
+ } else {
+ callback();
+ }
+ };
+
+ /** Reload a module, violating the CommonJS singleton paradigm and
* potentially introducing bugs in to the program using this function --
* as references to the previous instance of the module may still be
* held by the application program.
*/
-bravojs.reloadModule = function(id, callback)
-{
- delete bravojs.pendingModuleDeclarations[id];
- delete bravojs.requireMemo[id];
- module.provide([id], callback);
-}
-
-/** Main module bootstrap */
-bravojs.initializeMainModule = function bravojs_initializeMainModule(dependencies, moduleFactory, moduleIdentifier)
-{
- if (module.hasOwnProperty("declare")) /* special extra-module environment bootstrap declare needs to go */
- delete module.declare;
-
- if (module.constructor.prototype.main)
- throw new Error("Main module has already been initialized!");
-
- bravojs.es5_shim_then
- (
- (function()
- {
- bravojs.provideModule(dependencies, moduleFactory, moduleIdentifier, function bravojs_lambda_requireMain() { module.constructor.prototype.main = require(moduleIdentifier); })
- })
- );
-}
-
-/** Run a module which is not declared in the HTML document and make it the program module.
+ bravojs.reloadModule = function (id, callback) {
+ delete bravojs.pendingModuleDeclarations[id];
+ delete bravojs.requireMemo[id];
+ module.provide([id], callback);
+ };
+
+ /** Main module bootstrap */
+ bravojs.initializeMainModule = function bravojs_initializeMainModule(dependencies, moduleFactory, moduleIdentifier) {
+ if (module.hasOwnProperty('declare')) /* Special extra-module environment bootstrap declare needs to go */
+ {
+ delete module.declare;
+ }
+
+ if (module.constructor.prototype.main) {
+ throw new Error('Main module has already been initialized!');
+ }
+
+ bravojs.es5_shim_then
+ (
+ (() => {
+ bravojs.provideModule(dependencies, moduleFactory, moduleIdentifier, () => {
+ module.constructor.prototype.main = require(moduleIdentifier);
+ });
+ })
+ );
+ };
+
+ /** Run a module which is not declared in the HTML document and make it the program module.
* @param dependencies [optional] A list of dependencies to sastify before running the mdoule
* @param moduleIdentifier moduleIdentifier, relative to dirname(window.location.href). This function
* adjusts the module path such that the program module's directory is the
* top-level module directory before the dependencies are resolved.
* @param callback [optional] Callback to invoke once the main module has been initialized
*/
-bravojs.runExternalMainModule = function bravojs_runExternalProgram(dependencies, moduleIdentifier, callback)
-{
- if (arguments.length === 1 || typeof moduleIdentifier === "function")
- {
- callback = moduleIdentifier;
- moduleIdentifier = dependencies;
- dependencies = [];
- }
-
- delete module.declare;
-
- if (moduleIdentifier.charAt(0) === '/')
- bravojs.mainModuleDir = bravojs.dirname(moduleIdentifier);
- else
- bravojs.mainModuleDir = bravojs.dirname(bravojs.URL_toId(window.location.href + ".js"), true) + "/" + bravojs.dirname(moduleIdentifier);
-
- moduleIdentifier = bravojs.basename(moduleIdentifier);
-
- bravojs.es5_shim_then(
- function() {
- module.provide(dependencies.concat([moduleIdentifier]),
- function bravojs_runMainModule() {
+ bravojs.runExternalMainModule = function bravojs_runExternalProgram(dependencies, moduleIdentifier, callback) {
+ if (arguments.length === 1 || typeof moduleIdentifier === 'function') {
+ callback = moduleIdentifier;
+ moduleIdentifier = dependencies;
+ dependencies = [];
+ }
+
+ delete module.declare;
+
+ if (moduleIdentifier.charAt(0) === '/') {
+ bravojs.mainModuleDir = bravojs.dirname(moduleIdentifier);
+ } else {
+ bravojs.mainModuleDir = bravojs.dirname(bravojs.URL_toId(window.location.href + '.js'), true) + '/' + bravojs.dirname(moduleIdentifier);
+ }
+
+ moduleIdentifier = bravojs.basename(moduleIdentifier);
+
+ bravojs.es5_shim_then(
+ () => {
+ module.provide(dependencies.concat([moduleIdentifier]),
+ () => {
bravojs.initializeMainModule(dependencies, '', moduleIdentifier);
- if (callback)
- callback();
- })
+ if (callback) {
+ callback();
+ }
+ });
});
-}
+ };
-bravojs.reset();
+ bravojs.reset();
-/** Set the BravoJS URL, so that BravoJS can load components
+ /** Set the BravoJS URL, so that BravoJS can load components
* relative to its install dir. The HTML script element that
* loads BravoJS must either have the ID BravoJS, or be the
* very first script in the document.
- */
-(function bravojs_setURL()
-{
- var i;
- var script;
-
- script = document.getElementById("BravoJS");
- if (!script)
- script = document.getElementsByTagName("SCRIPT")[0];
-
- bravojs.url = script.src;
- i = bravojs.url.indexOf("?");
- if (i !== -1)
- bravojs.url = bravojs.url.slice(0,i);
- i = bravojs.url.indexOf("#");
- if (i !== -1)
- bravojs.url = bravojs.url.slice(0,i);
-
- if (bravojs.basename(bravojs.url) !== "bravo.js")
- throw new Error("Could not determine BravoJS URL. BravoJS must be the first script, or have id='BravoJS'");
-})();
-
-/** Diagnostic Aids */
-var print = bravojs.print;
-if (!window.onerror)
-{
- window.onerror = function window_onerror(message, url, line)
- {
- var scripts, i;
-
- print("\n * Error: " + message + "\n" +
- " in: " + url + "\n" +
- " line: " + line);
- }
-}
+ */
+ (function bravojs_setURL() {
+ let i;
+ let script;
+
+ script = document.querySelector('#BravoJS');
+ if (!script) {
+ script = document.querySelectorAll('SCRIPT')[0];
+ }
+
+ bravojs.url = script.src;
+ i = bravojs.url.indexOf('?');
+ if (i !== -1) {
+ bravojs.url = bravojs.url.slice(0, i);
+ }
+
+ i = bravojs.url.indexOf('#');
+ if (i !== -1) {
+ bravojs.url = bravojs.url.slice(0, i);
+ }
+
+ if (bravojs.basename(bravojs.url) !== 'bravo.js') {
+ throw new Error('Could not determine BravoJS URL. BravoJS must be the first script, or have id=\'BravoJS\'');
+ }
+ })();
+
+ /** Diagnostic Aids */
+ const {print} = bravojs;
+ if (!window.onerror) {
+ window.addEventListener('error', (message, url, line) => {
+ let scripts; let i;
+
+ print('\n * Error: ' + message + '\n' +
+ ' in: ' + url + '\n' +
+ ' line: ' + line);
+ });
+ }
-/* Module.declare function which handles main modules inline SCRIPT tags.
+ /* Module.declare function which handles main modules inline SCRIPT tags.
* This function gets deleted as soon as it runs, allowing the module.declare
* from the prototype take over. Modules created from this function have
* the empty string as module.id.
*/
-module.declare = function main_module_declare(dependencies, moduleFactory)
-{
- if (typeof dependencies === "function")
- {
- moduleFactory = dependencies;
- dependencies = [];
- }
-
- bravojs.initializeMainModule(dependencies, moduleFactory, '');
+ module.declare = function main_module_declare(dependencies, moduleFactory) {
+ if (typeof dependencies === 'function') {
+ moduleFactory = dependencies;
+ dependencies = [];
+ }
+
+ bravojs.initializeMainModule(dependencies, moduleFactory, '');
+ };
+} catch (error) {
+ bravojs.errorReporter(error);
}
-
-} catch(e) { bravojs.errorReporter(e); }
diff --git a/demos/twitter_backbone/vendor/global-es5.js b/demos/twitter_backbone/vendor/global-es5.js
index 58e6fb87..c5ce4c1a 100644
--- a/demos/twitter_backbone/vendor/global-es5.js
+++ b/demos/twitter_backbone/vendor/global-es5.js
@@ -30,18 +30,18 @@
// =====
//
-// ES5 15.4.3.2
+// ES5 15.4.3.2
if (!Array.isArray) {
- Array.isArray = function(obj) {
- return Object.prototype.toString.call(obj) == "[object Array]";
+ Array.isArray = function (obj) {
+ return Object.prototype.toString.call(obj) == '[object Array]';
};
}
// ES5 15.4.4.18
if (!Array.prototype.forEach) {
- Array.prototype.forEach = function(block, thisObject) {
- var len = this.length >>> 0;
- for (var i = 0; i < len; i++) {
+ Array.prototype.forEach = function (block, thisObject) {
+ const len = this.length >>> 0;
+ for (let i = 0; i < len; i++) {
if (i in this) {
block.call(thisObject, this[i], i, this);
}
@@ -52,16 +52,18 @@ if (!Array.prototype.forEach) {
// ES5 15.4.4.19
// https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Objects/Array/map
if (!Array.prototype.map) {
- Array.prototype.map = function(fun /*, thisp*/) {
- var len = this.length >>> 0;
- if (typeof fun != "function")
- throw new TypeError();
-
- var res = new Array(len);
- var thisp = arguments[1];
- for (var i = 0; i < len; i++) {
- if (i in this)
+ Array.prototype.map = function (fun /* , thisp */) {
+ const len = this.length >>> 0;
+ if (typeof fun !== 'function') {
+ throw new TypeError();
+ }
+
+ const res = new Array(len);
+ const thisp = arguments[1];
+ for (let i = 0; i < len; i++) {
+ if (i in this) {
res[i] = fun.call(thisp, this[i], i, this);
+ }
}
return res;
@@ -70,34 +72,43 @@ if (!Array.prototype.map) {
// ES5 15.4.4.20
if (!Array.prototype.filter) {
- Array.prototype.filter = function (block /*, thisp */) {
- var values = [];
- var thisp = arguments[1];
- for (var i = 0; i < this.length; i++)
- if (block.call(thisp, this[i]))
+ Array.prototype.filter = function (block /* , thisp */) {
+ const values = [];
+ const thisp = arguments[1];
+ for (let i = 0; i < this.length; i++) {
+ if (block.call(thisp, this[i])) {
values.push(this[i]);
+ }
+ }
+
return values;
};
}
// ES5 15.4.4.16
if (!Array.prototype.every) {
- Array.prototype.every = function (block /*, thisp */) {
- var thisp = arguments[1];
- for (var i = 0; i < this.length; i++)
- if (!block.call(thisp, this[i]))
+ Array.prototype.every = function (block /* , thisp */) {
+ const thisp = arguments[1];
+ for (let i = 0; i < this.length; i++) {
+ if (!block.call(thisp, this[i])) {
return false;
+ }
+ }
+
return true;
};
}
// ES5 15.4.4.17
if (!Array.prototype.some) {
- Array.prototype.some = function (block /*, thisp */) {
- var thisp = arguments[1];
- for (var i = 0; i < this.length; i++)
- if (block.call(thisp, this[i]))
+ Array.prototype.some = function (block /* , thisp */) {
+ const thisp = arguments[1];
+ for (let i = 0; i < this.length; i++) {
+ if (block.call(thisp, this[i])) {
return true;
+ }
+ }
+
return false;
};
}
@@ -105,16 +116,18 @@ if (!Array.prototype.some) {
// ES5 15.4.4.21
// https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Objects/Array/reduce
if (!Array.prototype.reduce) {
- Array.prototype.reduce = function(fun /*, initial*/) {
- var len = this.length >>> 0;
- if (typeof fun != "function")
+ Array.prototype.reduce = function (fun /* , initial */) {
+ const len = this.length >>> 0;
+ if (typeof fun !== 'function') {
throw new TypeError();
+ }
- // no value to return if no initial value and an empty array
- if (len == 0 && arguments.length == 1)
+ // No value to return if no initial value and an empty array
+ if (len == 0 && arguments.length == 1) {
throw new TypeError();
+ }
- var i = 0;
+ let i = 0;
if (arguments.length >= 2) {
var rv = arguments[1];
} else {
@@ -124,15 +137,17 @@ if (!Array.prototype.reduce) {
break;
}
- // if array contains no values, no initial value to return
- if (++i >= len)
+ // If array contains no values, no initial value to return
+ if (++i >= len) {
throw new TypeError();
+ }
} while (true);
}
for (; i < len; i++) {
- if (i in this)
+ if (i in this) {
rv = fun.call(null, rv, this[i], i, this);
+ }
}
return rv;
@@ -142,16 +157,18 @@ if (!Array.prototype.reduce) {
// ES5 15.4.4.22
// https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Objects/Array/reduceRight
if (!Array.prototype.reduceRight) {
- Array.prototype.reduceRight = function(fun /*, initial*/) {
- var len = this.length >>> 0;
- if (typeof fun != "function")
+ Array.prototype.reduceRight = function (fun /* , initial */) {
+ const len = this.length >>> 0;
+ if (typeof fun !== 'function') {
throw new TypeError();
+ }
- // no value to return if no initial value, empty array
- if (len == 0 && arguments.length == 1)
+ // No value to return if no initial value, empty array
+ if (len == 0 && arguments.length == 1) {
throw new TypeError();
+ }
- var i = len - 1;
+ let i = len - 1;
if (arguments.length >= 2) {
var rv = arguments[1];
} else {
@@ -161,15 +178,17 @@ if (!Array.prototype.reduceRight) {
break;
}
- // if array contains no values, no initial value to return
- if (--i < 0)
+ // If array contains no values, no initial value to return
+ if (--i < 0) {
throw new TypeError();
+ }
} while (true);
}
for (; i >= 0; i--) {
- if (i in this)
+ if (i in this) {
rv = fun.call(null, rv, this[i], i, this);
+ }
}
return rv;
@@ -178,41 +197,59 @@ if (!Array.prototype.reduceRight) {
// ES5 15.4.4.14
if (!Array.prototype.indexOf) {
- Array.prototype.indexOf = function (value /*, fromIndex */ ) {
- var length = this.length;
- if (!length)
+ Array.prototype.indexOf = function (value /* , fromIndex */) {
+ const {length} = this;
+ if (!length) {
return -1;
- var i = arguments[1] || 0;
- if (i >= length)
+ }
+
+ let i = arguments[1] || 0;
+ if (i >= length) {
return -1;
- if (i < 0)
+ }
+
+ if (i < 0) {
i += length;
+ }
+
for (; i < length; i++) {
- if (!Object.prototype.hasOwnProperty.call(this, i))
+ if (!Object.prototype.hasOwnProperty.call(this, i)) {
continue;
- if (value === this[i])
+ }
+
+ if (value === this[i]) {
return i;
+ }
}
+
return -1;
};
}
// ES5 15.4.4.15
if (!Array.prototype.lastIndexOf) {
- Array.prototype.lastIndexOf = function (value /*, fromIndex */) {
- var length = this.length;
- if (!length)
+ Array.prototype.lastIndexOf = function (value /* , fromIndex */) {
+ const {length} = this;
+ if (!length) {
return -1;
- var i = arguments[1] || length;
- if (i < 0)
+ }
+
+ let i = arguments[1] || length;
+ if (i < 0) {
i += length;
+ }
+
i = Math.min(i, length - 1);
for (; i >= 0; i--) {
- if (!Object.prototype.hasOwnProperty.call(this, i))
+ if (!Object.prototype.hasOwnProperty.call(this, i)) {
continue;
- if (value === this[i])
+ }
+
+ if (value === this[i]) {
return i;
+ }
}
+
return -1;
};
}
@@ -220,13 +257,13 @@ if (!Array.prototype.lastIndexOf) {
//
// Object
// ======
-//
+//
// ES5 15.2.3.2
if (!Object.getPrototypeOf) {
Object.getPrototypeOf = function (object) {
return object.__proto__;
- // or undefined if not available in this engine
+ // Or undefined if not available in this engine
};
}
@@ -244,34 +281,43 @@ if (!Object.getOwnPropertyNames) {
};
}
-// ES5 15.2.3.5
+// ES5 15.2.3.5
if (!Object.create) {
- Object.create = function(prototype, properties) {
- if (typeof prototype != "object" || prototype === null)
- throw new TypeError("typeof prototype["+(typeof prototype)+"] != 'object'");
- function Type() {};
+ Object.create = function (prototype, properties) {
+ if (typeof prototype !== 'object' || prototype === null) {
+ throw new TypeError('typeof prototype[' + (typeof prototype) + '] != \'object\'');
+ }
+
+ function Type() {}
Type.prototype = prototype;
- var object = new Type();
- if (typeof properties !== "undefined")
+ const object = new Type();
+ if (typeof properties !== 'undefined') {
Object.defineProperties(object, properties);
+ }
+
return object;
};
}
// ES5 15.2.3.6
if (!Object.defineProperty) {
- Object.defineProperty = function(object, property, descriptor) {
- var has = Object.prototype.hasOwnProperty;
- if (typeof descriptor == "object" && object.__defineGetter__) {
- if (has.call(descriptor, "value")) {
+ Object.defineProperty = function (object, property, descriptor) {
+ const has = Object.prototype.hasOwnProperty;
+ if (typeof descriptor === 'object' && object.__defineGetter__) {
+ if (has.call(descriptor, 'value')) {
if (!object.__lookupGetter__(property) && !object.__lookupSetter__(property))
- // data property defined and no pre-existing accessors
+ // Data property defined and no pre-existing accessors
+ {
object[property] = descriptor.value;
- if (has.call(descriptor, "get") || has.call(descriptor, "set"))
- // descriptor has a value property but accessor already exists
- throw new TypeError("Object doesn't support this action");
+ }
+
+ if (has.call(descriptor, 'get') || has.call(descriptor, 'set'))
+ // Descriptor has a value property but accessor already exists
+ {
+ throw new TypeError('Object doesn\'t support this action');
+ }
}
- // fail silently if "writable", "enumerable", or "configurable"
+ // Fail silently if "writable", "enumerable", or "configurable"
// are requested but not supported
/*
// alternate approach:
@@ -285,22 +331,28 @@ if (!Object.defineProperty) {
"support configurable, enumerable, or writable."
);
*/
- else if (typeof descriptor.get == "function")
+ else if (typeof descriptor.get === 'function') {
object.__defineGetter__(property, descriptor.get);
- if (typeof descriptor.set == "function")
+ }
+
+ if (typeof descriptor.set === 'function') {
object.__defineSetter__(property, descriptor.set);
+ }
}
+
return object;
};
}
// ES5 15.2.3.7
if (!Object.defineProperties) {
- Object.defineProperties = function(object, properties) {
- for (var property in properties) {
- if (Object.prototype.hasOwnProperty.call(properties, property))
+ Object.defineProperties = function (object, properties) {
+ for (const property in properties) {
+ if (Object.prototype.hasOwnProperty.call(properties, property)) {
Object.defineProperty(object, property, properties[property]);
+ }
}
+
return object;
};
}
@@ -317,16 +369,16 @@ if (!Object.freeze) {
Object.freeze = function (object) {
return object;
};
-} else if (require("./engine").engine.indexOf("rhino") >= 0) {
+} else if (require('./engine').engine.includes('rhino')) {
// TODO feature-detect
// XXX workaround for a Rhino bug.
- var freeze = Object.freeze;
+ const {freeze} = Object;
Object.freeze = function (object) {
- if (typeof object == "function") {
+ if (typeof object === 'function') {
return object;
- } else {
- return freeze(object);
}
+
+ return freeze(object);
};
}
@@ -361,12 +413,13 @@ if (!Object.isExtensible) {
// ES5 15.2.3.14
if (!Object.keys) {
Object.keys = function (object) {
- var keys = [];
- for (var name in object) {
+ const keys = [];
+ for (const name in object) {
if (Object.prototype.hasOwnProperty.call(object, name)) {
keys.push(name);
}
}
+
return keys;
};
}
@@ -380,16 +433,16 @@ if (!Object.keys) {
// Format a Date object as a string according to a subset of the ISO-8601 standard.
// Useful in Atom, among other things.
if (!Date.prototype.toISOString) {
- Date.prototype.toISOString = function() {
+ Date.prototype.toISOString = function () {
return (
- this.getFullYear() + "-" +
- (this.getMonth() + 1) + "-" +
- this.getDate() + "T" +
- this.getHours() + ":" +
- this.getMinutes() + ":" +
- this.getSeconds() + "Z"
- );
- }
+ this.getFullYear() + '-' +
+ (this.getMonth() + 1) + '-' +
+ this.getDate() + 'T' +
+ this.getHours() + ':' +
+ this.getMinutes() + ':' +
+ this.getSeconds() + 'Z'
+ );
+ };
}
// ES5 15.9.4.4
@@ -414,8 +467,10 @@ if (!Date.prototype.toJSON) {
// 4. Let toISO be the result of calling the [[Get]] internal method of
// O with argument "toISOString".
// 5. If IsCallable(toISO) is false, throw a TypeError exception.
- if (typeof this.toISOString != "function")
+ if (typeof this.toISOString !== 'function') {
throw new TypeError();
+ }
+
// 6. Return the result of calling the [[Call]] internal method of
// toISO with O as the this value and an empty argument list.
return this.toISOString();
@@ -436,67 +491,68 @@ if (!Date.prototype.toJSON) {
// Date.parse
// based on work shared by Daniel Friesen (dantman)
// http://gist.github.com/303249
-if (isNaN(Date.parse("T00:00"))) {
+if (isNaN(Date.parse('T00:00'))) {
// XXX global assignment won't work in embeddings that use
// an alternate object for the context.
- Date = (function(NativeDate) {
-
+ Date = (function (NativeDate) {
// Date.length === 7
- var Date = function(Y, M, D, h, m, s, ms) {
- var length = arguments.length;
+ var Date = function (Y, M, D, h, m, s, ms) {
+ const {length} = arguments;
if (this instanceof NativeDate) {
- var date = length === 1 && String(Y) === Y ? // isString(Y)
+ const date = length === 1 && String(Y) === Y ? // IsString(Y)
// We explicitly pass it through parse:
new NativeDate(Date.parse(Y)) :
// We have to manually make calls depending on argument
// length here
length >= 7 ? new NativeDate(Y, M, D, h, m, s, ms) :
- length >= 6 ? new NativeDate(Y, M, D, h, m, s) :
- length >= 5 ? new NativeDate(Y, M, D, h, m) :
- length >= 4 ? new NativeDate(Y, M, D, h) :
- length >= 3 ? new NativeDate(Y, M, D) :
- length >= 2 ? new NativeDate(Y, M) :
- length >= 1 ? new NativeDate(Y) :
- new NativeDate();
+ length >= 6 ? new NativeDate(Y, M, D, h, m, s) :
+ length >= 5 ? new NativeDate(Y, M, D, h, m) :
+ length >= 4 ? new NativeDate(Y, M, D, h) :
+ length >= 3 ? new NativeDate(Y, M, D) :
+ length >= 2 ? new NativeDate(Y, M) :
+ (length >= 1 ? new NativeDate(Y) :
+ new NativeDate());
// Prevent mixups with unfixed Date object
date.constructor = Date;
return date;
}
- return NativeDate.apply(this, arguments);
+
+ return Reflect.apply(NativeDate, this, arguments);
};
// 15.9.1.15 Date Time String Format
- var isoDateExpression = new RegExp("^" +
- "(?:" + // optional year-month-day
- "(" + // year capture
- "(?:[+-]\\d\\d)?" + // 15.9.1.15.1 Extended years
- "\\d\\d\\d\\d" + // four-digit year
- ")" +
- "(?:-" + // optional month-day
- "(\\d\\d)" + // month capture
- "(?:-" + // optional day
- "(\\d\\d)" + // day capture
- ")?" +
- ")?" +
- ")?" +
- "(?:T" + // hour:minute:second.subsecond
- "(\\d\\d)" + // hour capture
- ":(\\d\\d)" + // minute capture
- "(?::" + // optional :second.subsecond
- "(\\d\\d)" + // second capture
- "(?:\\.(\\d\\d\\d))?" + // milisecond capture
- ")?" +
- ")?" +
- "(?:" + // time zone
- "Z|" + // UTC capture
- "([+-])(\\d\\d):(\\d\\d)" + // timezone offset
- // capture sign, hour, minute
- ")?" +
- "$");
+ const isoDateExpression = new RegExp('^' +
+ '(?:' + // Optional year-month-day
+ '(' + // Year capture
+ '(?:[+-]\\d\\d)?' + // 15.9.1.15.1 Extended years
+ '\\d\\d\\d\\d' + // Four-digit year
+ ')' +
+ '(?:-' + // Optional month-day
+ '(\\d\\d)' + // Month capture
+ '(?:-' + // Optional day
+ '(\\d\\d)' + // Day capture
+ ')?' +
+ ')?' +
+ ')?' +
+ '(?:T' + // Hour:minute:second.subsecond
+ '(\\d\\d)' + // Hour capture
+ ':(\\d\\d)' + // Minute capture
+ '(?::' + // Optional :second.subsecond
+ '(\\d\\d)' + // Second capture
+ '(?:\\.(\\d\\d\\d))?' + // Milisecond capture
+ ')?' +
+ ')?' +
+ '(?:' + // Time zone
+ 'Z|' + // UTC capture
+ '([+-])(\\d\\d):(\\d\\d)' + // Timezone offset
+ // capture sign, hour, minute
+ ')?' +
+ '$');
// Copy any custom methods a 3rd party library may have added
- for (var key in NativeDate)
+ for (const key in NativeDate) {
Date[key] = NativeDate[key];
+ }
// Copy "native" methods explicitly; they may be non-enumerable
Date.now = NativeDate.now;
@@ -507,67 +563,76 @@ if (isNaN(Date.parse("T00:00"))) {
// Upgrade Date.parse to handle the ISO dates we use
// TODO review specification to ascertain whether it is
// necessary to implement partial ISO date strings.
- Date.parse = function(string) {
- var match = isoDateExpression.exec(string);
+ Date.parse = function (string) {
+ const match = isoDateExpression.exec(string);
if (match) {
- match.shift(); // kill match[0], the full match
+ match.shift(); // Kill match[0], the full match
// recognize times without dates before normalizing the
// numeric values, for later use
- var timeOnly = match[0] === undefined;
- // parse numerics
- for (var i = 0; i < 10; i++) {
- // skip + or - for the timezone offset
- if (i === 7)
+ const timeOnly = match[0] === undefined;
+ // Parse numerics
+ for (let i = 0; i < 10; i++) {
+ // Skip + or - for the timezone offset
+ if (i === 7) {
continue;
+ }
+
// Note: parseInt would read 0-prefix numbers as
// octal. Number constructor or unary + work better
// here:
- match[i] = +(match[i] || (i < 3 ? 1 : 0));
- // match[1] is the month. Months are 0-11 in JavaScript
+ match[i] = Number(match[i] || (i < 3 ? 1 : 0));
+ // Match[1] is the month. Months are 0-11 in JavaScript
// Date objects, but 1-12 in ISO notation, so we
// decrement.
- if (i === 1)
+ if (i === 1) {
match[i]--;
+ }
}
- // if no year-month-date is provided, return a milisecond
+
+ // If no year-month-date is provided, return a milisecond
// quantity instead of a UTC date number value.
- if (timeOnly)
+ if (timeOnly) {
return ((match[3] * 60 + match[4]) * 60 + match[5]) * 1000 + match[6];
+ }
- // account for an explicit time zone offset if provided
- var offset = (match[8] * 60 + match[9]) * 60 * 1000;
- if (match[6] === "-")
+ // Account for an explicit time zone offset if provided
+ let offset = (match[8] * 60 + match[9]) * 60 * 1000;
+ if (match[6] === '-') {
offset = -offset;
+ }
return NativeDate.UTC.apply(this, match.slice(0, 7)) + offset;
}
- return NativeDate.parse.apply(this, arguments);
+
+ return Reflect.apply(NativeDate.parse, this, arguments);
};
return Date;
})(Date);
}
-//
+//
// Function
// ========
-//
+//
// ES-5 15.3.4.5
// http://www.ecma-international.org/publications/files/drafts/tc39-2009-025.pdf
-var slice = Array.prototype.slice;
+const {slice} = Array.prototype;
if (!Function.prototype.bind) {
Function.prototype.bind = function (that) { // .length is 1
// 1. Let Target be the this value.
- var target = this;
+ const target = this;
// 2. If IsCallable(Target) is false, throw a TypeError exception.
- // XXX this gets pretty close, for all intents and purposes, letting
+ // XXX this gets pretty close, for all intents and purposes, letting
// some duck-types slide
- if (typeof target.apply != "function" || typeof target.call != "function")
+ if (typeof target.apply !== 'function' || typeof target.call !== 'function') {
return new TypeError();
+ }
+
// 3. Let A be a new (possibly empty) internal list of all of the
// argument values provided after thisArg (arg1, arg2 etc), in order.
- var args = slice.call(arguments);
+ const args = slice.call(arguments);
// 4. Let F be a new native ECMAScript object.
// 9. Set the [[Prototype]] internal property of F to the standard
// built-in Function prototype object as specified in 15.3.3.1.
@@ -580,7 +645,6 @@ if (!Function.prototype.bind) {
// 13. The [[Scope]] internal property of F is unused and need not
// exist.
var bound = function () {
-
if (this instanceof bound) {
// 15.3.4.5.2 [[Construct]]
// When the [[Construct]] internal method of a function object,
@@ -596,38 +660,35 @@ if (!Function.prototype.bind) {
// list boundArgs in the same order followed by the same
// values as the list ExtraArgs in the same order.
- var self = Object.create(target.prototype);
+ const self = Object.create(target.prototype);
target.apply(self, args.concat(slice.call(arguments)));
return self;
-
- } else {
- // 15.3.4.5.1 [[Call]]
- // When the [[Call]] internal method of a function object, F,
- // which was created using the bind function is called with a
- // this value and a list of arguments ExtraArgs the following
- // steps are taken:
- // 1. Let boundArgs be the value of F's [[BoundArgs]] internal
- // property.
- // 2. Let boundThis be the value of F's [[BoundThis]] internal
- // property.
- // 3. Let target be the value of F's [[TargetFunction]] internal
- // property.
- // 4. Let args be a new list containing the same values as the list
- // boundArgs in the same order followed by the same values as
- // the list ExtraArgs in the same order. 5. Return the
- // result of calling the [[Call]] internal method of target
- // providing boundThis as the this value and providing args
- // as the arguments.
-
- // equiv: target.call(this, ...boundArgs, ...args)
- return target.call.apply(
- target,
- args.concat(slice.call(arguments))
- );
-
}
-
+ // 15.3.4.5.1 [[Call]]
+ // When the [[Call]] internal method of a function object, F,
+ // which was created using the bind function is called with a
+ // this value and a list of arguments ExtraArgs the following
+ // steps are taken:
+ // 1. Let boundArgs be the value of F's [[BoundArgs]] internal
+ // property.
+ // 2. Let boundThis be the value of F's [[BoundThis]] internal
+ // property.
+ // 3. Let target be the value of F's [[TargetFunction]] internal
+ // property.
+ // 4. Let args be a new list containing the same values as the list
+ // boundArgs in the same order followed by the same values as
+ // the list ExtraArgs in the same order. 5. Return the
+ // result of calling the [[Call]] internal method of target
+ // providing boundThis as the this value and providing args
+ // as the arguments.
+
+ // equiv: target.call(this, ...boundArgs, ...args)
+ return target.call.apply(
+ target,
+ args.concat(slice.call(arguments))
+ );
};
+
// 5. Set the [[TargetFunction]] internal property of F to Target.
// extra:
bound.bound = target;
@@ -640,13 +701,13 @@ if (!Function.prototype.bind) {
bound.boundArgs = args;
bound.length = (
// 14. If the [[Class]] internal property of Target is "Function", then
- typeof target == "function" ?
- // a. Let L be the length property of Target minus the length of A.
+ typeof target === 'function' ?
+ // A. Let L be the length property of Target minus the length of A.
// b. Set the length own property of F to either 0 or L, whichever is larger.
- Math.max(target.length - args.length, 0) :
+ Math.max(target.length - args.length, 0) :
// 15. Else set the length own property of F to 0.
- 0
- )
+ 0
+ );
// 16. The length own property of F is given attributes as specified in
// 15.3.5.1.
// TODO
@@ -677,8 +738,8 @@ if (!Function.prototype.bind) {
// ES5 15.5.4.20
if (!String.prototype.trim) {
// http://blog.stevenlevithan.com/archives/faster-trim-javascript
- var trimBeginRegexp = /^\s\s*/;
- var trimEndRegexp = /\s\s*$/;
+ const trimBeginRegexp = /^\s\s*/;
+ const trimEndRegexp = /\s\s*$/;
String.prototype.trim = function () {
return String(this).replace(trimBeginRegexp, '').replace(trimEndRegexp, '');
};
diff --git a/demos/twitter_backbone/vendor/twig.js b/demos/twitter_backbone/vendor/twig.js
index 2eebc11d..00914b98 100644
--- a/demos/twitter_backbone/vendor/twig.js
+++ b/demos/twitter_backbone/vendor/twig.js
@@ -1,19 +1,18 @@
/**
- * Twig.js 0.7.2
+ * Twig.js 0.8.9
*
- * @copyright 2011-2013 John Roepke
+ * @copyright 2011-2015 John Roepke and the Twig.js Contributors
* @license Available under the BSD 2-Clause License
* @link https://github.com/justjohn/twig.js
*/
var Twig = (function (Twig) {
- Twig.VERSION = "0.7.2";
+ Twig.VERSION = "0.8.9";
return Twig;
})(Twig || {});
// Twig.js
-// Copyright (c) 2011-2013 John Roepke
// Available under the BSD 2-Clause License
// https://github.com/justjohn/twig.js
@@ -132,6 +131,18 @@ var Twig = (function (Twig) {
// 8. return undefined
};
+ Twig.merge = function(target, source, onlyChanged) {
+ Twig.forEach(Object.keys(source), function (key) {
+ if (onlyChanged && !(key in target)) {
+ return;
+ }
+
+ target[key] = source[key]
+ });
+
+ return target;
+ };
+
/**
* Exception thrown by twig.js.
*/
@@ -155,18 +166,35 @@ var Twig = (function (Twig) {
*/
Twig.log = {
trace: function() {if (Twig.trace && console) {console.log(Array.prototype.slice.call(arguments));}},
- debug: function() {if (Twig.debug && console) {console.log(Array.prototype.slice.call(arguments));}},
+ debug: function() {if (Twig.debug && console) {console.log(Array.prototype.slice.call(arguments));}}
};
- if (typeof console !== "undefined" &&
- typeof console.log !== "undefined") {
- Twig.log.error = function() {
- console.log.apply(console, arguments);
+
+ if (typeof console !== "undefined") {
+ if (typeof console.error !== "undefined") {
+ Twig.log.error = function() {
+ console.error.apply(console, arguments);
+ }
+ } else if (typeof console.log !== "undefined") {
+ Twig.log.error = function() {
+ console.log.apply(console, arguments);
+ }
}
} else {
Twig.log.error = function(){};
}
+ /**
+ * Wrapper for child context objects in Twig.
+ *
+ * @param {Object} context Values to initialize the context with.
+ */
+ Twig.ChildContext = function(context) {
+ var ChildContext = function ChildContext() {};
+ ChildContext.prototype = context;
+ return new ChildContext();
+ };
+
/**
* Container for methods related to handling high level template tokens
* (for example: {{ expression }}, {% logic %}, {# comment #}, raw data)
@@ -177,10 +205,16 @@ var Twig = (function (Twig) {
* Token types.
*/
Twig.token.type = {
- output: 'output',
- logic: 'logic',
- comment: 'comment',
- raw: 'raw'
+ output: 'output',
+ logic: 'logic',
+ comment: 'comment',
+ raw: 'raw',
+ output_whitespace_pre: 'output_whitespace_pre',
+ output_whitespace_post: 'output_whitespace_post',
+ output_whitespace_both: 'output_whitespace_both',
+ logic_whitespace_pre: 'logic_whitespace_pre',
+ logic_whitespace_post: 'logic_whitespace_post',
+ logic_whitespace_both: 'logic_whitespace_both'
};
/**
@@ -192,6 +226,44 @@ var Twig = (function (Twig) {
open: '{% raw %}',
close: '{% endraw %}'
},
+ {
+ type: Twig.token.type.raw,
+ open: '{% verbatim %}',
+ close: '{% endverbatim %}'
+ },
+ // *Whitespace type tokens*
+ //
+ // These typically take the form `{{- expression -}}` or `{{- expression }}` or `{{ expression -}}`.
+ {
+ type: Twig.token.type.output_whitespace_pre,
+ open: '{{-',
+ close: '}}'
+ },
+ {
+ type: Twig.token.type.output_whitespace_post,
+ open: '{{',
+ close: '-}}'
+ },
+ {
+ type: Twig.token.type.output_whitespace_both,
+ open: '{{-',
+ close: '-}}'
+ },
+ {
+ type: Twig.token.type.logic_whitespace_pre,
+ open: '{%-',
+ close: '%}'
+ },
+ {
+ type: Twig.token.type.logic_whitespace_post,
+ open: '{%',
+ close: '-%}'
+ },
+ {
+ type: Twig.token.type.logic_whitespace_both,
+ open: '{%-',
+ close: '-%}'
+ },
// *Output type tokens*
//
// These typically take the form `{{ expression }}`.
@@ -228,25 +300,69 @@ var Twig = (function (Twig) {
Twig.token.findStart = function (template) {
var output = {
position: null,
+ close_position: null,
def: null
},
i,
token_template,
- first_key_position;
+ first_key_position,
+ close_key_position;
for (i=0;i= 0) {
+ //This token matches the template
+ if (token_template.open.length !== token_template.close.length) {
+ //This token has mismatched closing and opening tags
+ if (close_key_position < 0) {
+ //This token's closing tag does not match the template
+ continue;
+ }
+ }
+ }
// Does this token occur before any other types?
if (first_key_position >= 0 && (output.position === null || first_key_position < output.position)) {
output.position = first_key_position;
output.def = token_template;
+ output.close_position = close_key_position;
+ } else if (first_key_position >= 0 && output.position !== null && first_key_position === output.position) {
+ /*This token exactly matches another token,
+ greedily match to check if this token has a greater specificity*/
+ if (token_template.open.length > output.def.open.length) {
+ //This token's opening tag is more specific than the previous match
+ output.position = first_key_position;
+ output.def = token_template;
+ output.close_position = close_key_position;
+ } else if (token_template.open.length === output.def.open.length) {
+ if (token_template.close.length > output.def.close.length) {
+ //This token's opening tag is as specific as the previous match,
+ //but the closing tag has greater specificity
+ if (close_key_position >= 0 && close_key_position < output.close_position) {
+ //This token's closing tag exists in the template,
+ //and it occurs sooner than the previous match
+ output.position = first_key_position;
+ output.def = token_template;
+ output.close_position = close_key_position;
+ }
+ } else if (close_key_position >= 0 && close_key_position < output.close_position) {
+ //This token's closing tag is not more specific than the previous match,
+ //but it occurs sooner than the previous match
+ output.position = first_key_position;
+ output.def = token_template;
+ output.close_position = close_key_position;
+ }
+ }
}
}
+ delete output['close_position'];
+
return output;
};
@@ -286,6 +402,11 @@ var Twig = (function (Twig) {
if (token_def.type === Twig.token.type.comment) {
break;
}
+ // Ignore quotes within raw tag
+ // Fixes #283
+ if (token_def.type === Twig.token.type.raw) {
+ break;
+ }
l = Twig.token.strings.length;
for (i = 0; i < l; i += 1) {
@@ -361,9 +482,16 @@ var Twig = (function (Twig) {
value: template.substring(0, end).trim()
});
- if ( found_token.def.type === "logic" && template.substr( end + found_token.def.close.length, 1 ) === "\n" ) {
- // Newlines directly after logic tokens are ignored
- end += 1;
+ if (template.substr( end + found_token.def.close.length, 1 ) === "\n") {
+ switch (found_token.def.type) {
+ case "logic_whitespace_pre":
+ case "logic_whitespace_post":
+ case "logic_whitespace_both":
+ case "logic":
+ // Newlines directly after logic tokens are ignored
+ end += 1;
+ break;
+ }
}
template = template.substr(end + found_token.def.close.length);
@@ -399,8 +527,14 @@ var Twig = (function (Twig) {
unclosed_token = null,
// Temporary previous token.
prev_token = null,
+ // Temporary previous output.
+ prev_output = null,
+ // Temporary previous intermediate output.
+ prev_intermediate_output = null,
// The previous token's template
prev_template = null,
+ // Token lookahead
+ next_token = null,
// The output token
tok_output = null,
@@ -409,8 +543,87 @@ var Twig = (function (Twig) {
open = null,
next = null;
+ var compile_output = function(token) {
+ Twig.expression.compile.apply(this, [token]);
+ if (stack.length > 0) {
+ intermediate_output.push(token);
+ } else {
+ output.push(token);
+ }
+ };
+
+ var compile_logic = function(token) {
+ // Compile the logic token
+ logic_token = Twig.logic.compile.apply(this, [token]);
+
+ type = logic_token.type;
+ open = Twig.logic.handler[type].open;
+ next = Twig.logic.handler[type].next;
+
+ Twig.log.trace("Twig.compile: ", "Compiled logic token to ", logic_token,
+ " next is: ", next, " open is : ", open);
+
+ // Not a standalone token, check logic stack to see if this is expected
+ if (open !== undefined && !open) {
+ prev_token = stack.pop();
+ prev_template = Twig.logic.handler[prev_token.type];
+
+ if (Twig.indexOf(prev_template.next, type) < 0) {
+ throw new Error(type + " not expected after a " + prev_token.type);
+ }
+
+ prev_token.output = prev_token.output || [];
+
+ prev_token.output = prev_token.output.concat(intermediate_output);
+ intermediate_output = [];
+
+ tok_output = {
+ type: Twig.token.type.logic,
+ token: prev_token
+ };
+ if (stack.length > 0) {
+ intermediate_output.push(tok_output);
+ } else {
+ output.push(tok_output);
+ }
+ }
+
+ // This token requires additional tokens to complete the logic structure.
+ if (next !== undefined && next.length > 0) {
+ Twig.log.trace("Twig.compile: ", "Pushing ", logic_token, " to logic stack.");
+
+ if (stack.length > 0) {
+ // Put any currently held output into the output list of the logic operator
+ // currently at the head of the stack before we push a new one on.
+ prev_token = stack.pop();
+ prev_token.output = prev_token.output || [];
+ prev_token.output = prev_token.output.concat(intermediate_output);
+ stack.push(prev_token);
+ intermediate_output = [];
+ }
+
+ // Push the new logic token onto the logic stack
+ stack.push(logic_token);
+
+ } else if (open !== undefined && open) {
+ tok_output = {
+ type: Twig.token.type.logic,
+ token: logic_token
+ };
+ // Standalone token (like {% set ... %}
+ if (stack.length > 0) {
+ intermediate_output.push(tok_output);
+ } else {
+ output.push(tok_output);
+ }
+ }
+ };
+
while (tokens.length > 0) {
token = tokens.shift();
+ prev_output = output[output.length - 1];
+ prev_intermediate_output = intermediate_output[intermediate_output.length - 1];
+ next_token = tokens[0];
Twig.log.trace("Compiling token ", token);
switch (token.type) {
case Twig.token.type.raw:
@@ -422,83 +635,84 @@ var Twig = (function (Twig) {
break;
case Twig.token.type.logic:
- // Compile the logic token
- logic_token = Twig.logic.compile.apply(this, [token]);
-
- type = logic_token.type;
- open = Twig.logic.handler[type].open;
- next = Twig.logic.handler[type].next;
+ compile_logic.call(this, token);
+ break;
- Twig.log.trace("Twig.compile: ", "Compiled logic token to ", logic_token,
- " next is: ", next, " open is : ", open);
+ // Do nothing, comments should be ignored
+ case Twig.token.type.comment:
+ break;
- // Not a standalone token, check logic stack to see if this is expected
- if (open !== undefined && !open) {
- prev_token = stack.pop();
- prev_template = Twig.logic.handler[prev_token.type];
+ case Twig.token.type.output:
+ compile_output.call(this, token);
+ break;
- if (Twig.indexOf(prev_template.next, type) < 0) {
- throw new Error(type + " not expected after a " + prev_token.type);
+ //Kill whitespace ahead and behind this token
+ case Twig.token.type.logic_whitespace_pre:
+ case Twig.token.type.logic_whitespace_post:
+ case Twig.token.type.logic_whitespace_both:
+ case Twig.token.type.output_whitespace_pre:
+ case Twig.token.type.output_whitespace_post:
+ case Twig.token.type.output_whitespace_both:
+ if (token.type !== Twig.token.type.output_whitespace_post && token.type !== Twig.token.type.logic_whitespace_post) {
+ if (prev_output) {
+ //If the previous output is raw, pop it off
+ if (prev_output.type === Twig.token.type.raw) {
+ output.pop();
+
+ //If the previous output is not just whitespace, trim it
+ if (prev_output.value.match(/^\s*$/) === null) {
+ prev_output.value = prev_output.value.trim();
+ //Repush the previous output
+ output.push(prev_output);
+ }
+ }
}
- prev_token.output = prev_token.output || [];
+ if (prev_intermediate_output) {
+ //If the previous intermediate output is raw, pop it off
+ if (prev_intermediate_output.type === Twig.token.type.raw) {
+ intermediate_output.pop();
- prev_token.output = prev_token.output.concat(intermediate_output);
- intermediate_output = [];
-
- tok_output = {
- type: Twig.token.type.logic,
- token: prev_token
- };
- if (stack.length > 0) {
- intermediate_output.push(tok_output);
- } else {
- output.push(tok_output);
+ //If the previous output is not just whitespace, trim it
+ if (prev_intermediate_output.value.match(/^\s*$/) === null) {
+ prev_intermediate_output.value = prev_intermediate_output.value.trim();
+ //Repush the previous intermediate output
+ intermediate_output.push(prev_intermediate_output);
+ }
+ }
}
}
- // This token requires additional tokens to complete the logic structure.
- if (next !== undefined && next.length > 0) {
- Twig.log.trace("Twig.compile: ", "Pushing ", logic_token, " to logic stack.");
-
- if (stack.length > 0) {
- // Put any currently held output into the output list of the logic operator
- // currently at the head of the stack before we push a new one on.
- prev_token = stack.pop();
- prev_token.output = prev_token.output || [];
- prev_token.output = prev_token.output.concat(intermediate_output);
- stack.push(prev_token);
- intermediate_output = [];
- }
+ //Compile this token
+ switch (token.type) {
+ case Twig.token.type.output_whitespace_pre:
+ case Twig.token.type.output_whitespace_post:
+ case Twig.token.type.output_whitespace_both:
+ compile_output.call(this, token);
+ break;
+ case Twig.token.type.logic_whitespace_pre:
+ case Twig.token.type.logic_whitespace_post:
+ case Twig.token.type.logic_whitespace_both:
+ compile_logic.call(this, token);
+ break;
+ }
- // Push the new logic token onto the logic stack
- stack.push(logic_token);
-
- } else if (open !== undefined && open) {
- tok_output = {
- type: Twig.token.type.logic,
- token: logic_token
- };
- // Standalone token (like {% set ... %}
- if (stack.length > 0) {
- intermediate_output.push(tok_output);
- } else {
- output.push(tok_output);
+ if (token.type !== Twig.token.type.output_whitespace_pre && token.type !== Twig.token.type.logic_whitespace_pre) {
+ if (next_token) {
+ //If the next token is raw, shift it out
+ if (next_token.type === Twig.token.type.raw) {
+ tokens.shift();
+
+ //If the next token is not just whitespace, trim it
+ if (next_token.value.match(/^\s*$/) === null) {
+ next_token.value = next_token.value.trim();
+ //Unshift the next token
+ tokens.unshift(next_token);
+ }
+ }
}
}
- break;
-
- // Do nothing, comments should be ignored
- case Twig.token.type.comment:
- break;
- case Twig.token.type.output:
- Twig.expression.compile.apply(this, [token]);
- if (stack.length > 0) {
- intermediate_output.push(token);
- } else {
- output.push(token);
- }
break;
}
@@ -541,16 +755,12 @@ var Twig = (function (Twig) {
chain = true,
that = this;
- // Default to an empty object if none provided
- context = context || { };
-
-
Twig.forEach(tokens, function parseToken(token) {
Twig.log.debug("Twig.parse: ", "Parsing token: ", token);
switch (token.type) {
case Twig.token.type.raw:
- output.push(token.value);
+ output.push(Twig.filters.raw(token.value));
break;
case Twig.token.type.logic:
@@ -572,6 +782,10 @@ var Twig = (function (Twig) {
// Do nothing, comments should be ignored
break;
+ //Fall through whitespace to output
+ case Twig.token.type.output_whitespace_pre:
+ case Twig.token.type.output_whitespace_post:
+ case Twig.token.type.output_whitespace_both:
case Twig.token.type.output:
Twig.log.debug("Twig.parse: ", "Output token: ", token.stack);
// Parse the given expression in the given context
@@ -579,7 +793,7 @@ var Twig = (function (Twig) {
break;
}
});
- return output.join("");
+ return Twig.output.apply(this, [output]);
} catch (ex) {
Twig.log.error("Error parsing twig template " + this.id + ": ");
if (ex.stack) {
@@ -619,8 +833,51 @@ var Twig = (function (Twig) {
return tokens;
};
+ /**
+ * Join the output token's stack and escape it if needed
+ *
+ * @param {Array} Output token's stack
+ *
+ * @return {string|String} Autoescaped output
+ */
+ Twig.output = function(output) {
+ if (!this.options.autoescape) {
+ return output.join("");
+ }
+
+ var strategy = 'html';
+ if(typeof this.options.autoescape == 'string')
+ strategy = this.options.autoescape;
+
+ // [].map would be better but it's not supported by IE8-
+ var escaped_output = [];
+ Twig.forEach(output, function (str) {
+ if (str && (str.twig_markup !== true && str.twig_markup != strategy)) {
+ str = Twig.filters.escape(str, [ strategy ]);
+ }
+ escaped_output.push(str);
+ });
+ return Twig.Markup(escaped_output.join(""));
+ }
+
// Namespace for template storage and retrieval
Twig.Templates = {
+ /**
+ * Registered template loaders - use Twig.Templates.registerLoader to add supported loaders
+ * @type {Object}
+ */
+ loaders: {},
+
+ /**
+ * Registered template parsers - use Twig.Templates.registerParser to add supported parsers
+ * @type {Object}
+ */
+ parsers: {},
+
+ /**
+ * Cached / loaded templates
+ * @type {Object}
+ */
registry: {}
};
@@ -635,12 +892,131 @@ var Twig = (function (Twig) {
Twig.validateId = function(id) {
if (id === "prototype") {
throw new Twig.Error(id + " is not a valid twig identifier");
- } else if (Twig.Templates.registry.hasOwnProperty(id)) {
+ } else if (Twig.cache && Twig.Templates.registry.hasOwnProperty(id)) {
throw new Twig.Error("There is already a template with the ID " + id);
}
return true;
}
+ /**
+ * Register a template loader
+ *
+ * @example
+ * Twig.extend(function(Twig) {
+ * Twig.Templates.registerLoader('custom_loader', function(location, params, callback, error_callback) {
+ * // ... load the template ...
+ * params.data = loadedTemplateData;
+ * // create and return the template
+ * var template = new Twig.Template(params);
+ * if (typeof callback === 'function') {
+ * callback(template);
+ * }
+ * return template;
+ * });
+ * });
+ *
+ * @param {String} method_name The method this loader is intended for (ajax, fs)
+ * @param {Function} func The function to execute when loading the template
+ * @param {Object|undefined} scope Optional scope parameter to bind func to
+ *
+ * @throws Twig.Error
+ *
+ * @return {void}
+ */
+ Twig.Templates.registerLoader = function(method_name, func, scope) {
+ if (typeof func !== 'function') {
+ throw new Twig.Error('Unable to add loader for ' + method_name + ': Invalid function reference given.');
+ }
+ if (scope) {
+ func = func.bind(scope);
+ }
+ this.loaders[method_name] = func;
+ };
+
+ /**
+ * Remove a registered loader
+ *
+ * @param {String} method_name The method name for the loader you wish to remove
+ *
+ * @return {void}
+ */
+ Twig.Templates.unRegisterLoader = function(method_name) {
+ if (this.isRegisteredLoader(method_name)) {
+ delete this.loaders[method_name];
+ }
+ };
+
+ /**
+ * See if a loader is registered by its method name
+ *
+ * @param {String} method_name The name of the loader you are looking for
+ *
+ * @return {boolean}
+ */
+ Twig.Templates.isRegisteredLoader = function(method_name) {
+ return this.loaders.hasOwnProperty(method_name);
+ };
+
+ /**
+ * Register a template parser
+ *
+ * @example
+ * Twig.extend(function(Twig) {
+ * Twig.Templates.registerParser('custom_parser', function(params) {
+ * // this template source can be accessed in params.data
+ * var template = params.data
+ *
+ * // ... custom process that modifies the template
+ *
+ * // return the parsed template
+ * return template;
+ * });
+ * });
+ *
+ * @param {String} method_name The method this parser is intended for (twig, source)
+ * @param {Function} func The function to execute when parsing the template
+ * @param {Object|undefined} scope Optional scope parameter to bind func to
+ *
+ * @throws Twig.Error
+ *
+ * @return {void}
+ */
+ Twig.Templates.registerParser = function(method_name, func, scope) {
+ if (typeof func !== 'function') {
+ throw new Twig.Error('Unable to add parser for ' + method_name + ': Invalid function regerence given.');
+ }
+
+ if (scope) {
+ func = func.bind(scope);
+ }
+
+ this.parsers[method_name] = func;
+ };
+
+ /**
+ * Remove a registered parser
+ *
+ * @param {String} method_name The method name for the parser you wish to remove
+ *
+ * @return {void}
+ */
+ Twig.Templates.unRegisterParser = function(method_name) {
+ if (this.isRegisteredParser(method_name)) {
+ delete this.parsers[method_name];
+ }
+ };
+
+ /**
+ * See if a parser is registered by its method name
+ *
+ * @param {String} method_name The name of the parser you are looking for
+ *
+ * @return {boolean}
+ */
+ Twig.Templates.isRegisteredParser = function(method_name) {
+ return this.parsers.hasOwnProperty(method_name);
+ };
+
/**
* Save a template object to the store.
*
@@ -676,6 +1052,8 @@ var Twig = (function (Twig) {
* Defaults to true.
* method: What method should be used to load the template
* (fs or ajax)
+ * parser: What method should be used to parse the template
+ * (twig or source)
* precompiled: Has the template already been compiled.
*
* @param {string} location The remote URL to load as a template.
@@ -686,119 +1064,34 @@ var Twig = (function (Twig) {
*
*/
Twig.Templates.loadRemote = function(location, params, callback, error_callback) {
- var id = params.id,
- method = params.method,
- async = params.async,
- precompiled = params.precompiled,
- template = null;
+ var loader;
// Default to async
- if (async === undefined) async = true;
+ if (params.async === undefined) {
+ params.async = true;
+ }
// Default to the URL so the template is cached.
- if (id === undefined) {
- id = location;
+ if (params.id === undefined) {
+ params.id = location;
}
- params.id = id;
// Check for existing template
- if (Twig.cache && Twig.Templates.registry.hasOwnProperty(id)) {
+ if (Twig.cache && Twig.Templates.registry.hasOwnProperty(params.id)) {
// A template is already saved with the given id.
- if (callback) {
- callback(Twig.Templates.registry[id]);
+ if (typeof callback === 'function') {
+ callback(Twig.Templates.registry[params.id]);
}
- return Twig.Templates.registry[id];
+ // TODO: if async, return deferred promise
+ return Twig.Templates.registry[params.id];
}
- if (method == 'ajax') {
- if (typeof XMLHttpRequest == "undefined") {
- throw new Twig.Error("Unsupported platform: Unable to do remote requests " +
- "because there is no XMLHTTPRequest implementation");
- }
-
- var xmlhttp = new XMLHttpRequest();
- xmlhttp.onreadystatechange = function() {
- var data = null;
-
- if(xmlhttp.readyState == 4) {
- if (xmlhttp.status == 200) {
- Twig.log.debug("Got template ", xmlhttp.responseText);
-
- if (precompiled === true) {
- data = JSON.parse(xmlhttp.responseText);
- } else {
- data = xmlhttp.responseText;
- }
-
- params.url = location;
- params.data = data;
-
- template = new Twig.Template(params);
-
- if (callback) {
- callback(template);
- }
- } else {
- if (error_callback) {
- error_callback(xmlhttp);
- }
- }
- }
- };
- xmlhttp.open("GET", location, async);
- xmlhttp.send();
-
- } else { // if method = 'fs'
- // Create local scope
- (function() {
- var fs = require('fs'),
- path = require('path'),
- data = null,
- loadTemplateFn = function(err, data) {
- if (err) {
- if (error_callback) {
- error_callback(err);
- }
- return;
- }
-
- if (precompiled === true) {
- data = JSON.parse(data);
- }
-
- params.data = data;
- params.path = location;
+ //if the parser name hasn't been set, default it to twig
+ params.parser = params.parser || 'twig';
- // template is in data
- template = new Twig.Template(params);
-
- if (callback) {
- callback(template);
- }
- };
-
- if (async === true) {
- fs.stat(location, function (err, stats) {
- if (err || !stats.isFile())
- throw new Twig.Error("Unable to find template file " + location);
-
- fs.readFile(location, 'utf8', loadTemplateFn);
- });
- } else {
- if (!fs.statSync(location).isFile())
- throw new Twig.Error("Unable to find template file " + location);
-
- data = fs.readFileSync(location, 'utf8');
- loadTemplateFn(undefined, data);
- }
- })();
- }
- if (async === false) {
- return template;
- } else {
- // placeholder for now, should eventually return a deferred object.
- return true;
- }
+ // Assume 'fs' if the loader is not defined
+ loader = this.loaders[params.method] || this.loaders.fs;
+ return loader.apply(this, arguments);
};
// Determine object type
@@ -826,6 +1119,8 @@ var Twig = (function (Twig) {
base = params.base,
path = params.path,
url = params.url,
+ name = params.name,
+ method = params.method,
// parser options
options = params.options;
@@ -841,16 +1136,18 @@ var Twig = (function (Twig) {
// options: {
// Compiler/parser options
//
- // strict_variables: true/false
+ // strictVariables: true/false
// Should missing variable/keys emit an error message. If false, they default to null.
// }
// }
//
this.id = id;
+ this.method = method;
this.base = base;
this.path = path;
this.url = url;
+ this.name = name;
this.macros = macros;
this.options = options;
@@ -870,6 +1167,8 @@ var Twig = (function (Twig) {
Twig.Template.prototype.reset = function(blocks) {
Twig.log.debug("Twig.Template.reset", "Reseting template " + this.id);
this.blocks = {};
+ this.importedBlocks = [];
+ this.originalBlockTokens = {};
this.child = {
blocks: blocks || {}
};
@@ -909,10 +1208,10 @@ var Twig = (function (Twig) {
// check for the template file via include
if (!ext_template) {
- url = relativePath(this, this.extend);
+ url = Twig.path.parsePath(this, this.extend);
ext_template = Twig.Templates.loadRemote(url, {
- method: this.url?'ajax':'fs',
+ method: this.getLoaderMethod(),
base: this.base,
async: false,
id: url,
@@ -938,21 +1237,33 @@ var Twig = (function (Twig) {
Twig.Template.prototype.importFile = function(file) {
var url, sub_template;
- if ( !this.url && !this.path && this.options.allowInlineIncludes ) {
+ if (!this.url && this.options.allowInlineIncludes) {
+ file = this.path ? this.path + '/' + file : file;
sub_template = Twig.Templates.load(file);
- sub_template.options = this.options;
- if ( sub_template ) {
- return sub_template;
+
+ if (!sub_template) {
+ sub_template = Twig.Templates.loadRemote(url, {
+ id: file,
+ method: this.getLoaderMethod(),
+ async: false,
+ options: this.options
+ });
+
+ if (!sub_template) {
+ throw new Twig.Error("Unable to find the template " + file);
+ }
}
- throw new Twig.Error("Didn't find the inline template by id");
+ sub_template.options = this.options;
+
+ return sub_template;
}
- url = relativePath(this, file);
+ url = Twig.path.parsePath(this, file);
// Load blocks from an external file
sub_template = Twig.Templates.loadRemote(url, {
- method: this.url?'ajax':'fs',
+ method: this.getLoaderMethod(),
base: this.base,
async: false,
options: this.options,
@@ -976,16 +1287,17 @@ var Twig = (function (Twig) {
Twig.forEach(Object.keys(sub_template.blocks), function(key) {
if (override || that.blocks[key] === undefined) {
that.blocks[key] = sub_template.blocks[key];
+ that.importedBlocks.push(key);
}
});
};
Twig.Template.prototype.importMacros = function(file) {
- var url = relativePath(this, file);
+ var url = Twig.path.parsePath(this, file);
// load remote template
var remoteTemplate = Twig.Templates.loadRemote(url, {
- method: this.url?'ajax':'fs',
+ method: this.getLoaderMethod(),
async: false,
id: url
});
@@ -993,76 +1305,181 @@ var Twig = (function (Twig) {
return remoteTemplate;
};
+ Twig.Template.prototype.getLoaderMethod = function() {
+ if (this.path) {
+ return 'fs';
+ }
+ if (this.url) {
+ return 'ajax';
+ }
+ return this.method || 'fs';
+ };
+
Twig.Template.prototype.compile = function(options) {
// compile the template into raw JS
return Twig.compiler.compile(this, options);
};
/**
- * Generate the relative canonical version of a url based on the given base path and file path.
+ * Create safe output
*
- * @param {string} template The Twig.Template.
- * @param {string} file The file path, relative to the base path.
+ * @param {string} Content safe to output
*
- * @return {string} The canonical version of the path.
+ * @return {String} Content wrapped into a String
*/
- function relativePath(template, file) {
- var base,
- base_path,
- sep_chr = "/",
- new_path = [],
- val;
- if (template.url) {
- if (typeof template.base !== 'undefined') {
- base = template.base + ((template.base.charAt(template.base.length-1) === '/') ? '' : '/');
- } else {
- base = template.url;
- }
- } else if (template.path) {
- // Get the system-specific path separator
- var path = require("path"),
- sep = path.sep || sep_chr,
- relative = new RegExp("^\\.{1,2}" + sep.replace("\\", "\\\\"));
- file = file.replace(/\//g, sep);
+ Twig.Markup = function(content, strategy) {
+ if(typeof strategy == 'undefined') {
+ strategy = true;
+ }
- if (template.base !== undefined && file.match(relative) == null) {
- file = file.replace(template.base, '');
- base = template.base + sep;
- } else {
- base = template.path;
- }
+ if (typeof content === 'string' && content.length > 0) {
+ content = new String(content);
+ content.twig_markup = strategy;
+ }
+ return content;
+ };
- base = base.replace(sep+sep, sep);
- sep_chr = sep;
- } else {
- throw new Twig.Error("Cannot extend an inline template.");
+ return Twig;
+
+}) (Twig || { });
+
+(function(Twig) {
+
+ 'use strict';
+
+ Twig.Templates.registerLoader('ajax', function(location, params, callback, error_callback) {
+ var template,
+ xmlhttp,
+ precompiled = params.precompiled,
+ parser = this.parsers[params.parser] || this.parser.twig;
+
+ if (typeof XMLHttpRequest === "undefined") {
+ throw new Twig.Error('Unsupported platform: Unable to do ajax requests ' +
+ 'because there is no "XMLHTTPRequest" implementation');
}
- base_path = base.split(sep_chr);
+ xmlhttp = new XMLHttpRequest();
+ xmlhttp.onreadystatechange = function() {
+ var data = null;
- // Remove file from url
- base_path.pop();
- base_path = base_path.concat(file.split(sep_chr));
+ if(xmlhttp.readyState === 4) {
+ if (xmlhttp.status === 200 || (window.cordova && xmlhttp.status == 0)) {
+ Twig.log.debug("Got template ", xmlhttp.responseText);
- while (base_path.length > 0) {
- val = base_path.shift();
- if (val == ".") {
- // Ignore
- } else if (val == ".." && new_path.length > 0 && new_path[new_path.length-1] != "..") {
- new_path.pop();
- } else {
- new_path.push(val);
+ if (precompiled === true) {
+ data = JSON.parse(xmlhttp.responseText);
+ } else {
+ data = xmlhttp.responseText;
+ }
+
+ params.url = location;
+ params.data = data;
+
+ template = parser.call(this, params);
+
+ if (typeof callback === 'function') {
+ callback(template);
+ }
+ } else {
+ if (typeof error_callback === 'function') {
+ error_callback(xmlhttp);
+ }
+ }
}
+ };
+ xmlhttp.open("GET", location, !!params.async);
+ xmlhttp.send();
+
+ if (params.async) {
+ // TODO: return deferred promise
+ return true;
+ } else {
+ return template;
}
+ });
- return new_path.join(sep_chr);
+}(Twig));(function(Twig) {
+ 'use strict';
+
+ var fs, path;
+
+ try {
+ // require lib dependencies at runtime
+ fs = require('fs');
+ path = require('path');
+ } catch (e) {
+ // NOTE: this is in a try/catch to avoid errors cross platform
}
- return Twig;
+ Twig.Templates.registerLoader('fs', function(location, params, callback, error_callback) {
+ var template,
+ data = null,
+ precompiled = params.precompiled,
+ parser = this.parsers[params.parser] || this.parser.twig;
-}) (Twig || { });
+ if (!fs || !path) {
+ throw new Twig.Error('Unsupported platform: Unable to load from file ' +
+ 'because there is no "fs" or "path" implementation');
+ }
+
+ var loadTemplateFn = function(err, data) {
+ if (err) {
+ if (typeof error_callback === 'function') {
+ error_callback(err);
+ }
+ return;
+ }
+
+ if (precompiled === true) {
+ data = JSON.parse(data);
+ }
+
+ params.data = data;
+ params.path = params.path || location;
+ // template is in data
+ template = parser.call(this, params);
+
+ if (typeof callback === 'function') {
+ callback(template);
+ }
+ };
+ params.path = params.path || location;
+
+ if (params.async) {
+ fs.stat(params.path, function (err, stats) {
+ if (err || !stats.isFile()) {
+ throw new Twig.Error('Unable to find template file ' + location);
+ }
+ fs.readFile(params.path, 'utf8', loadTemplateFn);
+ });
+ // TODO: return deferred promise
+ return true;
+ } else {
+ if (!fs.statSync(params.path).isFile()) {
+ throw new Twig.Error('Unable to find template file ' + location);
+ }
+ data = fs.readFileSync(params.path, 'utf8');
+ loadTemplateFn(undefined, data);
+ return template
+ }
+ });
+
+}(Twig));(function(Twig){
+ 'use strict';
+
+ Twig.Templates.registerParser('source', function(params) {
+ return params.data || '';
+ });
+})(Twig);
+(function(Twig){
+ 'use strict';
+
+ Twig.Templates.registerParser('twig', function(params) {
+ return new Twig.Template(params);
+ });
+})(Twig);
// The following methods are from MDN and are available under a
// [MIT License](http://www.opensource.org/licenses/mit-license.php) or are
// [Public Domain](https://developer.mozilla.org/Project:Copyrights).
@@ -1107,132 +1524,207 @@ var Twig = (function(Twig) {
Twig.lib = { };
/**
- sprintf() for JavaScript 0.7-beta1
- http://www.diveintojavascript.com/projects/javascript-sprintf
+ sprintf() for JavaScript 1.0.3
+ https://github.com/alexei/sprintf.js
**/
- var sprintf = (function() {
- function get_type(variable) {
- return Object.prototype.toString.call(variable).slice(8, -1).toLowerCase();
- }
- function str_repeat(input, multiplier) {
- for (var output = []; multiplier > 0; output[--multiplier] = input) {/* do nothing */}
- return output.join('');
+ var sprintfLib = (function() {
+ var re = {
+ not_string: /[^s]/,
+ number: /[diefg]/,
+ json: /[j]/,
+ not_json: /[^j]/,
+ text: /^[^\x25]+/,
+ modulo: /^\x25{2}/,
+ placeholder: /^\x25(?:([1-9]\d*)\$|\(([^\)]+)\))?(\+)?(0|'[^$])?(-)?(\d+)?(?:\.(\d+))?([b-gijosuxX])/,
+ key: /^([a-z_][a-z_\d]*)/i,
+ key_access: /^\.([a-z_][a-z_\d]*)/i,
+ index_access: /^\[(\d+)\]/,
+ sign: /^[\+\-]/
+ }
+
+ function sprintf() {
+ var key = arguments[0], cache = sprintf.cache
+ if (!(cache[key] && cache.hasOwnProperty(key))) {
+ cache[key] = sprintf.parse(key)
}
+ return sprintf.format.call(null, cache[key], arguments)
+ }
+
+ sprintf.format = function(parse_tree, argv) {
+ var cursor = 1, tree_length = parse_tree.length, node_type = "", arg, output = [], i, k, match, pad, pad_character, pad_length, is_positive = true, sign = ""
+ for (i = 0; i < tree_length; i++) {
+ node_type = get_type(parse_tree[i])
+ if (node_type === "string") {
+ output[output.length] = parse_tree[i]
+ }
+ else if (node_type === "array") {
+ match = parse_tree[i] // convenience purposes only
+ if (match[2]) { // keyword argument
+ arg = argv[cursor]
+ for (k = 0; k < match[2].length; k++) {
+ if (!arg.hasOwnProperty(match[2][k])) {
+ throw new Error(sprintf("[sprintf] property '%s' does not exist", match[2][k]))
+ }
+ arg = arg[match[2][k]]
+ }
+ }
+ else if (match[1]) { // positional argument (explicit)
+ arg = argv[match[1]]
+ }
+ else { // positional argument (implicit)
+ arg = argv[cursor++]
+ }
- var str_format = function() {
- if (!str_format.cache.hasOwnProperty(arguments[0])) {
- str_format.cache[arguments[0]] = str_format.parse(arguments[0]);
+ if (get_type(arg) == "function") {
+ arg = arg()
}
- return str_format.format.call(null, str_format.cache[arguments[0]], arguments);
- };
- str_format.format = function(parse_tree, argv) {
- var cursor = 1, tree_length = parse_tree.length, node_type = '', arg, output = [], i, k, match, pad, pad_character, pad_length;
- for (i = 0; i < tree_length; i++) {
- node_type = get_type(parse_tree[i]);
- if (node_type === 'string') {
- output.push(parse_tree[i]);
- }
- else if (node_type === 'array') {
- match = parse_tree[i]; // convenience purposes only
- if (match[2]) { // keyword argument
- arg = argv[cursor];
- for (k = 0; k < match[2].length; k++) {
- if (!arg.hasOwnProperty(match[2][k])) {
- throw(sprintf('[sprintf] property "%s" does not exist', match[2][k]));
- }
- arg = arg[match[2][k]];
- }
- }
- else if (match[1]) { // positional argument (explicit)
- arg = argv[match[1]];
- }
- else { // positional argument (implicit)
- arg = argv[cursor++];
- }
+ if (re.not_string.test(match[8]) && re.not_json.test(match[8]) && (get_type(arg) != "number" && isNaN(arg))) {
+ throw new TypeError(sprintf("[sprintf] expecting number but found %s", get_type(arg)))
+ }
+
+ if (re.number.test(match[8])) {
+ is_positive = arg >= 0
+ }
+
+ switch (match[8]) {
+ case "b":
+ arg = arg.toString(2)
+ break
+ case "c":
+ arg = String.fromCharCode(arg)
+ break
+ case "d":
+ case "i":
+ arg = parseInt(arg, 10)
+ break
+ case "j":
+ arg = JSON.stringify(arg, null, match[6] ? parseInt(match[6]) : 0)
+ break
+ case "e":
+ arg = match[7] ? arg.toExponential(match[7]) : arg.toExponential()
+ break
+ case "f":
+ arg = match[7] ? parseFloat(arg).toFixed(match[7]) : parseFloat(arg)
+ break
+ case "g":
+ arg = match[7] ? parseFloat(arg).toPrecision(match[7]) : parseFloat(arg)
+ break
+ case "o":
+ arg = arg.toString(8)
+ break
+ case "s":
+ arg = ((arg = String(arg)) && match[7] ? arg.substring(0, match[7]) : arg)
+ break
+ case "u":
+ arg = arg >>> 0
+ break
+ case "x":
+ arg = arg.toString(16)
+ break
+ case "X":
+ arg = arg.toString(16).toUpperCase()
+ break
+ }
+ if (re.json.test(match[8])) {
+ output[output.length] = arg
+ }
+ else {
+ if (re.number.test(match[8]) && (!is_positive || match[3])) {
+ sign = is_positive ? "+" : "-"
+ arg = arg.toString().replace(re.sign, "")
+ }
+ else {
+ sign = ""
+ }
+ pad_character = match[4] ? match[4] === "0" ? "0" : match[4].charAt(1) : " "
+ pad_length = match[6] - (sign + arg).length
+ pad = match[6] ? (pad_length > 0 ? str_repeat(pad_character, pad_length) : "") : ""
+ output[output.length] = match[5] ? sign + arg + pad : (pad_character === "0" ? sign + pad + arg : pad + sign + arg)
+ }
+ }
+ }
+ return output.join("")
+ }
+
+ sprintf.cache = {}
- if (/[^s]/.test(match[8]) && (get_type(arg) != 'number')) {
- throw(sprintf('[sprintf] expecting number but found %s', get_type(arg)));
- }
- switch (match[8]) {
- case 'b': arg = arg.toString(2); break;
- case 'c': arg = String.fromCharCode(arg); break;
- case 'd': arg = parseInt(arg, 10); break;
- case 'e': arg = match[7] ? arg.toExponential(match[7]) : arg.toExponential(); break;
- case 'f': arg = match[7] ? parseFloat(arg).toFixed(match[7]) : parseFloat(arg); break;
- case 'o': arg = arg.toString(8); break;
- case 's': arg = ((arg = String(arg)) && match[7] ? arg.substring(0, match[7]) : arg); break;
- case 'u': arg = Math.abs(arg); break;
- case 'x': arg = arg.toString(16); break;
- case 'X': arg = arg.toString(16).toUpperCase(); break;
- }
- arg = (/[def]/.test(match[8]) && match[3] && arg >= 0 ? '+'+ arg : arg);
- pad_character = match[4] ? match[4] == '0' ? '0' : match[4].charAt(1) : ' ';
- pad_length = match[6] - String(arg).length;
- pad = match[6] ? str_repeat(pad_character, pad_length) : '';
- output.push(match[5] ? arg + pad : pad + arg);
+ sprintf.parse = function(fmt) {
+ var _fmt = fmt, match = [], parse_tree = [], arg_names = 0
+ while (_fmt) {
+ if ((match = re.text.exec(_fmt)) !== null) {
+ parse_tree[parse_tree.length] = match[0]
+ }
+ else if ((match = re.modulo.exec(_fmt)) !== null) {
+ parse_tree[parse_tree.length] = "%"
+ }
+ else if ((match = re.placeholder.exec(_fmt)) !== null) {
+ if (match[2]) {
+ arg_names |= 1
+ var field_list = [], replacement_field = match[2], field_match = []
+ if ((field_match = re.key.exec(replacement_field)) !== null) {
+ field_list[field_list.length] = field_match[1]
+ while ((replacement_field = replacement_field.substring(field_match[0].length)) !== "") {
+ if ((field_match = re.key_access.exec(replacement_field)) !== null) {
+ field_list[field_list.length] = field_match[1]
+ }
+ else if ((field_match = re.index_access.exec(replacement_field)) !== null) {
+ field_list[field_list.length] = field_match[1]
+ }
+ else {
+ throw new SyntaxError("[sprintf] failed to parse named argument key")
+ }
}
+ }
+ else {
+ throw new SyntaxError("[sprintf] failed to parse named argument key")
+ }
+ match[2] = field_list
}
- return output.join('');
- };
+ else {
+ arg_names |= 2
+ }
+ if (arg_names === 3) {
+ throw new Error("[sprintf] mixing positional and named placeholders is not (yet) supported")
+ }
+ parse_tree[parse_tree.length] = match
+ }
+ else {
+ throw new SyntaxError("[sprintf] unexpected placeholder")
+ }
+ _fmt = _fmt.substring(match[0].length)
+ }
+ return parse_tree
+ }
- str_format.cache = {};
+ var vsprintf = function(fmt, argv, _argv) {
+ _argv = (argv || []).slice(0)
+ _argv.splice(0, 0, fmt)
+ return sprintf.apply(null, _argv)
+ }
- str_format.parse = function(fmt) {
- var _fmt = fmt, match = [], parse_tree = [], arg_names = 0;
- while (_fmt) {
- if ((match = /^[^\x25]+/.exec(_fmt)) !== null) {
- parse_tree.push(match[0]);
- }
- else if ((match = /^\x25{2}/.exec(_fmt)) !== null) {
- parse_tree.push('%');
- }
- else if ((match = /^\x25(?:([1-9]\d*)\$|\(([^\)]+)\))?(\+)?(0|'[^$])?(-)?(\d+)?(?:\.(\d+))?([b-fosuxX])/.exec(_fmt)) !== null) {
- if (match[2]) {
- arg_names |= 1;
- var field_list = [], replacement_field = match[2], field_match = [];
- if ((field_match = /^([a-z_][a-z_\d]*)/i.exec(replacement_field)) !== null) {
- field_list.push(field_match[1]);
- while ((replacement_field = replacement_field.substring(field_match[0].length)) !== '') {
- if ((field_match = /^\.([a-z_][a-z_\d]*)/i.exec(replacement_field)) !== null) {
- field_list.push(field_match[1]);
- }
- else if ((field_match = /^\[(\d+)\]/.exec(replacement_field)) !== null) {
- field_list.push(field_match[1]);
- }
- else {
- throw('[sprintf] huh?');
- }
- }
- }
- else {
- throw('[sprintf] huh?');
- }
- match[2] = field_list;
- }
- else {
- arg_names |= 2;
- }
- if (arg_names === 3) {
- throw('[sprintf] mixing positional and named placeholders is not (yet) supported');
- }
- parse_tree.push(match);
- }
- else {
- throw('[sprintf] huh?');
- }
- _fmt = _fmt.substring(match[0].length);
- }
- return parse_tree;
- };
+ /**
+ * helpers
+ */
+ function get_type(variable) {
+ return Object.prototype.toString.call(variable).slice(8, -1).toLowerCase()
+ }
- return str_format;
+ function str_repeat(input, multiplier) {
+ return Array(multiplier + 1).join(input)
+ }
+
+ /**
+ * export
+ */
+ return {
+ sprintf: sprintf,
+ vsprintf: vsprintf
+ }
})();
- var vsprintf = function(fmt, argv) {
- argv.unshift(fmt);
- return sprintf.apply(null, argv);
- };
+ var sprintf = sprintfLib.sprintf;
+ var vsprintf = sprintfLib.vsprintf;
// Expose to Twig
Twig.lib.sprintf = sprintf;
@@ -1443,8 +1935,8 @@ var Twig = (function(Twig) {
Twig.lib.parseISO8601Date = function (s){
// Taken from http://n8v.enteuxis.org/2010/12/parsing-iso-8601-dates-in-javascript/
// parenthese matches:
- // year month day hours minutes seconds
- // dotmilliseconds
+ // year month day hours minutes seconds
+ // dotmilliseconds
// tzstring plusminus hours minutes
var re = /(\d{4})-(\d\d)-(\d\d)T(\d\d):(\d\d):(\d\d)(\.\d+)?(Z|([+-])(\d\d):(\d\d))/;
@@ -1455,7 +1947,7 @@ var Twig = (function(Twig) {
// ["2010-12-07T11:00:00.000-09:00", "2010", "12", "07", "11",
// "00", "00", ".000", "-09:00", "-", "09", "00"]
// "2010-12-07T11:00:00.000Z" parses to:
- // ["2010-12-07T11:00:00.000Z", "2010", "12", "07", "11",
+ // ["2010-12-07T11:00:00.000Z", "2010", "12", "07", "11",
// "00", "00", ".000", "Z", undefined, undefined, undefined]
if (! d) {
@@ -1475,7 +1967,7 @@ var Twig = (function(Twig) {
var ms = Date.UTC(d[1], d[2] - 1, d[3], d[4], d[5], d[6]);
// if there are milliseconds, add them
- if (d[7] > 0) {
+ if (d[7] > 0) {
ms += Math.round(d[7] * 1000);
}
@@ -1496,196 +1988,300 @@ var Twig = (function(Twig) {
return new Date(ms);
};
- Twig.lib.strtotime = function (str, now) {
- // http://kevin.vanzonneveld.net
- // + original by: Caio Ariede (http://caioariede.com)
- // + improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
- // + input by: David
- // + improved by: Caio Ariede (http://caioariede.com)
- // + improved by: Brett Zamir (http://brett-zamir.me)
- // + bugfixed by: Wagner B. Soares
- // + bugfixed by: Artur Tchernychev
- // % note 1: Examples all have a fixed timestamp to prevent tests to fail because of variable time(zones)
- // * example 1: strtotime('+1 day', 1129633200);
- // * returns 1: 1129719600
- // * example 2: strtotime('+1 week 2 days 4 hours 2 seconds', 1129633200);
- // * returns 2: 1130425202
- // * example 3: strtotime('last month', 1129633200);
- // * returns 3: 1127041200
- // * example 4: strtotime('2009-05-04 08:30:00');
- // * returns 4: 1241418600
- var i, l, match, s, parse = '';
-
- str = str.replace(/\s{2,}|^\s|\s$/g, ' '); // unecessary spaces
- str = str.replace(/[\t\r\n]/g, ''); // unecessary chars
- if (str === 'now') {
- return now === null || isNaN(now) ? new Date().getTime() / 1000 | 0 : now | 0;
- } else if (!isNaN(parse = Date.parse(str))) {
- return parse / 1000 | 0;
- } else if (now) {
- now = new Date(now * 1000); // Accept PHP-style seconds
- } else {
- now = new Date();
- }
-
- var upperCaseStr = str;
-
- str = str.toLowerCase();
-
- var __is = {
- day: {
- 'sun': 0,
- 'mon': 1,
- 'tue': 2,
- 'wed': 3,
- 'thu': 4,
- 'fri': 5,
- 'sat': 6
- },
- mon: [
- 'jan',
- 'feb',
- 'mar',
- 'apr',
- 'may',
- 'jun',
- 'jul',
- 'aug',
- 'sep',
- 'oct',
- 'nov',
- 'dec'
- ]
- };
-
- var process = function (m) {
- var ago = (m[2] && m[2] === 'ago');
- var num = (num = m[0] === 'last' ? -1 : 1) * (ago ? -1 : 1);
-
- switch (m[0]) {
- case 'last':
- case 'next':
- switch (m[1].substring(0, 3)) {
- case 'yea':
- now.setFullYear(now.getFullYear() + num);
- break;
- case 'wee':
- now.setDate(now.getDate() + (num * 7));
- break;
- case 'day':
- now.setDate(now.getDate() + num);
- break;
- case 'hou':
- now.setHours(now.getHours() + num);
- break;
- case 'min':
- now.setMinutes(now.getMinutes() + num);
- break;
- case 'sec':
- now.setSeconds(now.getSeconds() + num);
- break;
- case 'mon':
- if (m[1] === "month") {
- now.setMonth(now.getMonth() + num);
- break;
- }
- // fall through
- default:
- var day = __is.day[m[1].substring(0, 3)];
- if (typeof day !== 'undefined') {
- var diff = day - now.getDay();
- if (diff === 0) {
- diff = 7 * num;
- } else if (diff > 0) {
- if (m[0] === 'last') {
- diff -= 7;
- }
- } else {
- if (m[0] === 'next') {
- diff += 7;
- }
- }
- now.setDate(now.getDate() + diff);
- now.setHours(0, 0, 0, 0); // when jumping to a specific last/previous day of week, PHP sets the time to 00:00:00
- }
- }
- break;
-
- default:
- if (/\d+/.test(m[0])) {
- num *= parseInt(m[0], 10);
-
- switch (m[1].substring(0, 3)) {
- case 'yea':
- now.setFullYear(now.getFullYear() + num);
- break;
- case 'mon':
- now.setMonth(now.getMonth() + num);
- break;
- case 'wee':
- now.setDate(now.getDate() + (num * 7));
- break;
- case 'day':
- now.setDate(now.getDate() + num);
- break;
- case 'hou':
- now.setHours(now.getHours() + num);
- break;
- case 'min':
- now.setMinutes(now.getMinutes() + num);
- break;
- case 'sec':
- now.setSeconds(now.getSeconds() + num);
- break;
- }
- } else {
- return false;
- }
- break;
- }
- return true;
- };
-
- match = str.match(/^(\d{2,4}-\d{2}-\d{2})(?:\s(\d{1,2}:\d{2}(:\d{2})?)?(?:\.(\d+))?)?$/);
- if (match !== null) {
- if (!match[2]) {
- match[2] = '00:00:00';
- } else if (!match[3]) {
- match[2] += ':00';
- }
-
- s = match[1].split(/-/g);
-
- s[1] = __is.mon[s[1] - 1] || s[1];
- s[0] = +s[0];
-
- s[0] = (s[0] >= 0 && s[0] <= 69) ? '20' + (s[0] < 10 ? '0' + s[0] : s[0] + '') : (s[0] >= 70 && s[0] <= 99) ? '19' + s[0] : s[0] + '';
- return parseInt(this.strtotime(s[2] + ' ' + s[1] + ' ' + s[0] + ' ' + match[2]) + (match[4] ? match[4] / 1000 : ''), 10);
- }
-
- var regex = '([+-]?\\d+\\s' + '(years?|months?|weeks?|days?|hours?|min|minutes?|sec|seconds?' + '|sun\\.?|sunday|mon\\.?|monday|tue\\.?|tuesday|wed\\.?|wednesday' + '|thu\\.?|thursday|fri\\.?|friday|sat\\.?|saturday)' + '|(last|next)\\s' + '(years?|months?|weeks?|days?|hours?|min|minutes?|sec|seconds?' + '|sun\\.?|sunday|mon\\.?|monday|tue\\.?|tuesday|wed\\.?|wednesday' + '|thu\\.?|thursday|fri\\.?|friday|sat\\.?|saturday))' + '(\\sago)?';
-
- match = str.match(new RegExp(regex, 'gi')); // Brett: seems should be case insensitive per docs, so added 'i'
- if (match === null) {
- // Try to parse ISO8601 in IE8
- try {
- num = Twig.lib.parseISO8601Date(upperCaseStr);
- if (num) {
- return num / 1000 | 0;
- }
- } catch (err) {
- return false;
- }
- return false;
- }
-
- for (i = 0, l = match.length; i < l; i++) {
- if (!process(match[i].split(' '))) {
- return false;
- }
- }
-
- return now.getTime() / 1000 | 0;
+ Twig.lib.strtotime = function (text, now) {
+ // discuss at: http://phpjs.org/functions/strtotime/
+ // version: 1109.2016
+ // original by: Caio Ariede (http://caioariede.com)
+ // improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
+ // improved by: Caio Ariede (http://caioariede.com)
+ // improved by: A. Matías Quezada (http://amatiasq.com)
+ // improved by: preuter
+ // improved by: Brett Zamir (http://brett-zamir.me)
+ // improved by: Mirko Faber
+ // input by: David
+ // bugfixed by: Wagner B. Soares
+ // bugfixed by: Artur Tchernychev
+ // bugfixed by: Stephan Bösch-Plepelits (http://github.com/plepe)
+ // note: Examples all have a fixed timestamp to prevent tests to fail because of variable time(zones)
+ // example 1: strtotime('+1 day', 1129633200);
+ // returns 1: 1129719600
+ // example 2: strtotime('+1 week 2 days 4 hours 2 seconds', 1129633200);
+ // returns 2: 1130425202
+ // example 3: strtotime('last month', 1129633200);
+ // returns 3: 1127041200
+ // example 4: strtotime('2009-05-04 08:30:00 GMT');
+ // returns 4: 1241425800
+ // example 5: strtotime('2009-05-04 08:30:00+00');
+ // returns 5: 1241425800
+ // example 6: strtotime('2009-05-04 08:30:00+02:00');
+ // returns 6: 1241418600
+ // example 7: strtotime('2009-05-04T08:30:00Z');
+ // returns 7: 1241425800
+
+ var parsed, match, today, year, date, days, ranges, len, times, regex, i, fail = false;
+
+ if (!text) {
+ return fail;
+ }
+
+ // Unecessary spaces
+ text = text.replace(/^\s+|\s+$/g, '')
+ .replace(/\s{2,}/g, ' ')
+ .replace(/[\t\r\n]/g, '')
+ .toLowerCase();
+
+ // in contrast to php, js Date.parse function interprets:
+ // dates given as yyyy-mm-dd as in timezone: UTC,
+ // dates with "." or "-" as MDY instead of DMY
+ // dates with two-digit years differently
+ // etc...etc...
+ // ...therefore we manually parse lots of common date formats
+ match = text.match(
+ /^(\d{1,4})([\-\.\/\:])(\d{1,2})([\-\.\/\:])(\d{1,4})(?:\s(\d{1,2}):(\d{2})?:?(\d{2})?)?(?:\s([A-Z]+)?)?$/);
+
+ if (match && match[2] === match[4]) {
+ if (match[1] > 1901) {
+ switch (match[2]) {
+ case '-':
+ {
+ // YYYY-M-D
+ if (match[3] > 12 || match[5] > 31) {
+ return fail;
+ }
+
+ return new Date(match[1], parseInt(match[3], 10) - 1, match[5],
+ match[6] || 0, match[7] || 0, match[8] || 0, match[9] || 0) / 1000;
+ }
+ case '.':
+ {
+ // YYYY.M.D is not parsed by strtotime()
+ return fail;
+ }
+ case '/':
+ {
+ // YYYY/M/D
+ if (match[3] > 12 || match[5] > 31) {
+ return fail;
+ }
+
+ return new Date(match[1], parseInt(match[3], 10) - 1, match[5],
+ match[6] || 0, match[7] || 0, match[8] || 0, match[9] || 0) / 1000;
+ }
+ }
+ } else if (match[5] > 1901) {
+ switch (match[2]) {
+ case '-':
+ {
+ // D-M-YYYY
+ if (match[3] > 12 || match[1] > 31) {
+ return fail;
+ }
+
+ return new Date(match[5], parseInt(match[3], 10) - 1, match[1],
+ match[6] || 0, match[7] || 0, match[8] || 0, match[9] || 0) / 1000;
+ }
+ case '.':
+ {
+ // D.M.YYYY
+ if (match[3] > 12 || match[1] > 31) {
+ return fail;
+ }
+
+ return new Date(match[5], parseInt(match[3], 10) - 1, match[1],
+ match[6] || 0, match[7] || 0, match[8] || 0, match[9] || 0) / 1000;
+ }
+ case '/':
+ {
+ // M/D/YYYY
+ if (match[1] > 12 || match[3] > 31) {
+ return fail;
+ }
+
+ return new Date(match[5], parseInt(match[1], 10) - 1, match[3],
+ match[6] || 0, match[7] || 0, match[8] || 0, match[9] || 0) / 1000;
+ }
+ }
+ } else {
+ switch (match[2]) {
+ case '-':
+ {
+ // YY-M-D
+ if (match[3] > 12 || match[5] > 31 || (match[1] < 70 && match[1] > 38)) {
+ return fail;
+ }
+
+ year = match[1] >= 0 && match[1] <= 38 ? +match[1] + 2000 : match[1];
+ return new Date(year, parseInt(match[3], 10) - 1, match[5],
+ match[6] || 0, match[7] || 0, match[8] || 0, match[9] || 0) / 1000;
+ }
+ case '.':
+ {
+ // D.M.YY or H.MM.SS
+ if (match[5] >= 70) {
+ // D.M.YY
+ if (match[3] > 12 || match[1] > 31) {
+ return fail;
+ }
+
+ return new Date(match[5], parseInt(match[3], 10) - 1, match[1],
+ match[6] || 0, match[7] || 0, match[8] || 0, match[9] || 0) / 1000;
+ }
+ if (match[5] < 60 && !match[6]) {
+ // H.MM.SS
+ if (match[1] > 23 || match[3] > 59) {
+ return fail;
+ }
+
+ today = new Date();
+ return new Date(today.getFullYear(), today.getMonth(), today.getDate(),
+ match[1] || 0, match[3] || 0, match[5] || 0, match[9] || 0) / 1000;
+ }
+
+ // invalid format, cannot be parsed
+ return fail;
+ }
+ case '/':
+ {
+ // M/D/YY
+ if (match[1] > 12 || match[3] > 31 || (match[5] < 70 && match[5] > 38)) {
+ return fail;
+ }
+
+ year = match[5] >= 0 && match[5] <= 38 ? +match[5] + 2000 : match[5];
+ return new Date(year, parseInt(match[1], 10) - 1, match[3],
+ match[6] || 0, match[7] || 0, match[8] || 0, match[9] || 0) / 1000;
+ }
+ case ':':
+ {
+ // HH:MM:SS
+ if (match[1] > 23 || match[3] > 59 || match[5] > 59) {
+ return fail;
+ }
+
+ today = new Date();
+ return new Date(today.getFullYear(), today.getMonth(), today.getDate(),
+ match[1] || 0, match[3] || 0, match[5] || 0) / 1000;
+ }
+ }
+ }
+ }
+
+ // other formats and "now" should be parsed by Date.parse()
+ if (text === 'now') {
+ return now === null || isNaN(now) ? new Date()
+ .getTime() / 1000 | 0 : now | 0;
+ }
+ if (!isNaN(parsed = Date.parse(text))) {
+ return parsed / 1000 | 0;
+ }
+ // Browsers != Chrome have problems parsing ISO 8601 date strings, as they do
+ // not accept lower case characters, space, or shortened time zones.
+ // Therefore, fix these problems and try again.
+ // Examples:
+ // 2015-04-15 20:33:59+02
+ // 2015-04-15 20:33:59z
+ // 2015-04-15t20:33:59+02:00
+ if (match = text.match(/^([0-9]{4}-[0-9]{2}-[0-9]{2})[ t]([0-9]{2}:[0-9]{2}:[0-9]{2}(\.[0-9]+)?)([\+-][0-9]{2}(:[0-9]{2})?|z)/)) {
+ // fix time zone information
+ if (match[4] == 'z') {
+ match[4] = 'Z';
+ }
+ else if (match[4].match(/^([\+-][0-9]{2})$/)) {
+ match[4] = match[4] + ':00';
+ }
+
+ if (!isNaN(parsed = Date.parse(match[1] + 'T' + match[2] + match[4]))) {
+ return parsed / 1000 | 0;
+ }
+ }
+
+ date = now ? new Date(now * 1000) : new Date();
+ days = {
+ 'sun': 0,
+ 'mon': 1,
+ 'tue': 2,
+ 'wed': 3,
+ 'thu': 4,
+ 'fri': 5,
+ 'sat': 6
+ };
+ ranges = {
+ 'yea': 'FullYear',
+ 'mon': 'Month',
+ 'day': 'Date',
+ 'hou': 'Hours',
+ 'min': 'Minutes',
+ 'sec': 'Seconds'
+ };
+
+ function lastNext(type, range, modifier) {
+ var diff, day = days[range];
+
+ if (typeof day !== 'undefined') {
+ diff = day - date.getDay();
+
+ if (diff === 0) {
+ diff = 7 * modifier;
+ } else if (diff > 0 && type === 'last') {
+ diff -= 7;
+ } else if (diff < 0 && type === 'next') {
+ diff += 7;
+ }
+
+ date.setDate(date.getDate() + diff);
+ }
+ }
+
+ function process(val) {
+ var splt = val.split(' '), // Todo: Reconcile this with regex using \s, taking into account browser issues with split and regexes
+ type = splt[0],
+ range = splt[1].substring(0, 3),
+ typeIsNumber = /\d+/.test(type),
+ ago = splt[2] === 'ago',
+ num = (type === 'last' ? -1 : 1) * (ago ? -1 : 1);
+
+ if (typeIsNumber) {
+ num *= parseInt(type, 10);
+ }
+
+ if (ranges.hasOwnProperty(range) && !splt[1].match(/^mon(day|\.)?$/i)) {
+ return date['set' + ranges[range]](date['get' + ranges[range]]() + num);
+ }
+
+ if (range === 'wee') {
+ return date.setDate(date.getDate() + (num * 7));
+ }
+
+ if (type === 'next' || type === 'last') {
+ lastNext(type, range, num);
+ } else if (!typeIsNumber) {
+ return false;
+ }
+
+ return true;
+ }
+
+ times = '(years?|months?|weeks?|days?|hours?|minutes?|min|seconds?|sec' +
+ '|sunday|sun\\.?|monday|mon\\.?|tuesday|tue\\.?|wednesday|wed\\.?' +
+ '|thursday|thu\\.?|friday|fri\\.?|saturday|sat\\.?)';
+ regex = '([+-]?\\d+\\s' + times + '|' + '(last|next)\\s' + times + ')(\\sago)?';
+
+ match = text.match(new RegExp(regex, 'gi'));
+ if (!match) {
+ return fail;
+ }
+
+ for (i = 0, len = match.length; i < len; i++) {
+ if (!process(match[i])) {
+ return fail;
+ }
+ }
+
+ // ECMAScript 5 only
+ // if (!match.every(process))
+ // return false;
+
+ return (date.getTime() / 1000);
};
Twig.lib.is = function(type, obj) {
@@ -1776,13 +2372,236 @@ var Twig = (function(Twig) {
}
return (isHalf ? value : Math.round(value)) / m;
- }
+ };
+
+ Twig.lib.max = function max() {
+ // discuss at: http://phpjs.org/functions/max/
+ // original by: Onno Marsman
+ // revised by: Onno Marsman
+ // improved by: Jack
+ // note: Long code cause we're aiming for maximum PHP compatibility
+ // example 1: max(1, 3, 5, 6, 7);
+ // returns 1: 7
+ // example 2: max([2, 4, 5]);
+ // returns 2: 5
+ // example 3: max(0, 'hello');
+ // returns 3: 0
+ // example 4: max('hello', 0);
+ // returns 4: 'hello'
+ // example 5: max(-1, 'hello');
+ // returns 5: 'hello'
+ // example 6: max([2, 4, 8], [2, 5, 7]);
+ // returns 6: [2, 5, 7]
+
+ var ar, retVal, i = 0,
+ n = 0,
+ argv = arguments,
+ argc = argv.length,
+ _obj2Array = function(obj) {
+ if (Object.prototype.toString.call(obj) === '[object Array]') {
+ return obj;
+ } else {
+ var ar = [];
+ for (var i in obj) {
+ if (obj.hasOwnProperty(i)) {
+ ar.push(obj[i]);
+ }
+ }
+ return ar;
+ }
+ }, //function _obj2Array
+ _compare = function(current, next) {
+ var i = 0,
+ n = 0,
+ tmp = 0,
+ nl = 0,
+ cl = 0;
+
+ if (current === next) {
+ return 0;
+ } else if (typeof current === 'object') {
+ if (typeof next === 'object') {
+ current = _obj2Array(current);
+ next = _obj2Array(next);
+ cl = current.length;
+ nl = next.length;
+ if (nl > cl) {
+ return 1;
+ } else if (nl < cl) {
+ return -1;
+ }
+ for (i = 0, n = cl; i < n; ++i) {
+ tmp = _compare(current[i], next[i]);
+ if (tmp == 1) {
+ return 1;
+ } else if (tmp == -1) {
+ return -1;
+ }
+ }
+ return 0;
+ }
+ return -1;
+ } else if (typeof next === 'object') {
+ return 1;
+ } else if (isNaN(next) && !isNaN(current)) {
+ if (current == 0) {
+ return 0;
+ }
+ return (current < 0 ? 1 : -1);
+ } else if (isNaN(current) && !isNaN(next)) {
+ if (next == 0) {
+ return 0;
+ }
+ return (next > 0 ? 1 : -1);
+ }
+
+ if (next == current) {
+ return 0;
+ }
+ return (next > current ? 1 : -1);
+ }; //function _compare
+ if (argc === 0) {
+ throw new Error('At least one value should be passed to max()');
+ } else if (argc === 1) {
+ if (typeof argv[0] === 'object') {
+ ar = _obj2Array(argv[0]);
+ } else {
+ throw new Error('Wrong parameter count for max()');
+ }
+ if (ar.length === 0) {
+ throw new Error('Array must contain at least one element for max()');
+ }
+ } else {
+ ar = argv;
+ }
+
+ retVal = ar[0];
+ for (i = 1, n = ar.length; i < n; ++i) {
+ if (_compare(retVal, ar[i]) == 1) {
+ retVal = ar[i];
+ }
+ }
+
+ return retVal;
+ };
+
+ Twig.lib.min = function min() {
+ // discuss at: http://phpjs.org/functions/min/
+ // original by: Onno Marsman
+ // revised by: Onno Marsman
+ // improved by: Jack
+ // note: Long code cause we're aiming for maximum PHP compatibility
+ // example 1: min(1, 3, 5, 6, 7);
+ // returns 1: 1
+ // example 2: min([2, 4, 5]);
+ // returns 2: 2
+ // example 3: min(0, 'hello');
+ // returns 3: 0
+ // example 4: min('hello', 0);
+ // returns 4: 'hello'
+ // example 5: min(-1, 'hello');
+ // returns 5: -1
+ // example 6: min([2, 4, 8], [2, 5, 7]);
+ // returns 6: [2, 4, 8]
+
+ var ar, retVal, i = 0,
+ n = 0,
+ argv = arguments,
+ argc = argv.length,
+ _obj2Array = function(obj) {
+ if (Object.prototype.toString.call(obj) === '[object Array]') {
+ return obj;
+ }
+ var ar = [];
+ for (var i in obj) {
+ if (obj.hasOwnProperty(i)) {
+ ar.push(obj[i]);
+ }
+ }
+ return ar;
+ }, //function _obj2Array
+ _compare = function(current, next) {
+ var i = 0,
+ n = 0,
+ tmp = 0,
+ nl = 0,
+ cl = 0;
+
+ if (current === next) {
+ return 0;
+ } else if (typeof current === 'object') {
+ if (typeof next === 'object') {
+ current = _obj2Array(current);
+ next = _obj2Array(next);
+ cl = current.length;
+ nl = next.length;
+ if (nl > cl) {
+ return 1;
+ } else if (nl < cl) {
+ return -1;
+ }
+ for (i = 0, n = cl; i < n; ++i) {
+ tmp = _compare(current[i], next[i]);
+ if (tmp == 1) {
+ return 1;
+ } else if (tmp == -1) {
+ return -1;
+ }
+ }
+ return 0;
+ }
+ return -1;
+ } else if (typeof next === 'object') {
+ return 1;
+ } else if (isNaN(next) && !isNaN(current)) {
+ if (current == 0) {
+ return 0;
+ }
+ return (current < 0 ? 1 : -1);
+ } else if (isNaN(current) && !isNaN(next)) {
+ if (next == 0) {
+ return 0;
+ }
+ return (next > 0 ? 1 : -1);
+ }
+
+ if (next == current) {
+ return 0;
+ }
+ return (next > current ? 1 : -1);
+ }; //function _compare
+
+ if (argc === 0) {
+ throw new Error('At least one value should be passed to min()');
+ } else if (argc === 1) {
+ if (typeof argv[0] === 'object') {
+ ar = _obj2Array(argv[0]);
+ } else {
+ throw new Error('Wrong parameter count for min()');
+ }
+
+ if (ar.length === 0) {
+ throw new Error('Array must contain at least one element for min()');
+ }
+ } else {
+ ar = argv;
+ }
+
+ retVal = ar[0];
+
+ for (i = 1, n = ar.length; i < n; ++i) {
+ if (_compare(retVal, ar[i]) == -1) {
+ retVal = ar[i];
+ }
+ }
+
+ return retVal;
+ };
return Twig;
})(Twig || { });
// Twig.js
-// Copyright (c) 2011-2013 John Roepke
// Available under the BSD 2-Clause License
// https://github.com/justjohn/twig.js
@@ -1812,6 +2631,7 @@ var Twig = (function (Twig) {
endset: 'Twig.logic.type.endset',
filter: 'Twig.logic.type.filter',
endfilter: 'Twig.logic.type.endfilter',
+ shortblock: 'Twig.logic.type.shortblock',
block: 'Twig.logic.type.block',
endblock: 'Twig.logic.type.endblock',
extends_: 'Twig.logic.type.extends',
@@ -1822,7 +2642,9 @@ var Twig = (function (Twig) {
macro: 'Twig.logic.type.macro',
endmacro: 'Twig.logic.type.endmacro',
import_: 'Twig.logic.type.import',
- from: 'Twig.logic.type.from'
+ from: 'Twig.logic.type.from',
+ embed: 'Twig.logic.type.embed',
+ endembed: 'Twig.logic.type.endembed'
};
@@ -1855,7 +2677,7 @@ var Twig = (function (Twig) {
* Format: {% if expression %}
*/
type: Twig.logic.type.if_,
- regex: /^if\s+([^\s].+)$/,
+ regex: /^if\s+([\s\S]+)$/,
next: [
Twig.logic.type.else_,
Twig.logic.type.elseif,
@@ -2024,8 +2846,8 @@ var Twig = (function (Twig) {
// Parse expression
var result = Twig.expression.parse.apply(this, [token.expression, context]),
output = [],
- len,
- index = 0,
+ len,
+ index = 0,
keyset,
that = this,
conditional = token.conditional,
@@ -2042,10 +2864,12 @@ var Twig = (function (Twig) {
parent: context
};
},
+ // run once for each iteration of the loop
loop = function(key, value) {
- var inner_context = Twig.lib.copy(context);
+ var inner_context = Twig.ChildContext(context);
inner_context[token.value_var] = value;
+
if (token.key_var) {
inner_context[token.key_var] = key;
}
@@ -2059,22 +2883,32 @@ var Twig = (function (Twig) {
output.push(Twig.parse.apply(that, [token.output, inner_context]));
index += 1;
}
+
+ // Delete loop-related variables from the context
+ delete inner_context['loop'];
+ delete inner_context[token.value_var];
+ delete inner_context[token.key_var];
+
+ // Merge in values that exist in context but have changed
+ // in inner_context.
+ Twig.merge(context, inner_context, true);
};
- if (result instanceof Array) {
+
+ if (Twig.lib.is('Array', result)) {
len = result.length;
Twig.forEach(result, function (value) {
var key = index;
loop(key, value);
});
- } else if (result instanceof Object) {
+ } else if (Twig.lib.is('Object', result)) {
if (result._keys !== undefined) {
keyset = result._keys;
} else {
keyset = Object.keys(result);
}
- len = keyset.length;
+ len = keyset.length;
Twig.forEach(keyset, function(key) {
// Ignore the _keys property, it's internal to twig.js
if (key === "_keys") return;
@@ -2088,7 +2922,7 @@ var Twig = (function (Twig) {
return {
chain: continue_chain,
- output: output.join("")
+ output: Twig.output.apply(this, [output])
};
}
},
@@ -2110,7 +2944,7 @@ var Twig = (function (Twig) {
* Format: {% set key = expression %}
*/
type: Twig.logic.type.set,
- regex: /^set\s+([a-zA-Z0-9_,\s]+)\s*=\s*(.+)$/,
+ regex: /^set\s+([a-zA-Z0-9_,\s]+)\s*=\s*([\s\S]+)$/,
next: [ ],
open: true,
compile: function (token) {
@@ -2132,8 +2966,6 @@ var Twig = (function (Twig) {
var value = Twig.expression.parse.apply(this, [token.expression, context]),
key = token.key;
- // set on both the global and local context
- this.context[key] = value;
context[key] = value;
return {
@@ -2254,23 +3086,44 @@ var Twig = (function (Twig) {
return token;
},
parse: function (token, context, chain) {
- var block_output = "",
- output = "",
- hasParent = this.blocks[token.block] && this.blocks[token.block].indexOf(Twig.placeholders.parent) > -1;
+ var block_output,
+ output,
+ isImported = Twig.indexOf(this.importedBlocks, token.block) > -1,
+ hasParent = this.blocks[token.block] && Twig.indexOf(this.blocks[token.block], Twig.placeholders.parent) > -1;
- // Don't override previous blocks
+ // Don't override previous blocks unless they're imported with "use"
// Loops should be exempted as well.
- if (this.blocks[token.block] === undefined || hasParent || context.loop) {
- block_output = Twig.expression.parse.apply(this, [{
- type: Twig.expression.type.string,
- value: Twig.parse.apply(this, [token.output, context])
- }, context]);
+ if (this.blocks[token.block] === undefined || isImported || hasParent || context.loop || token.overwrite) {
+ if (token.expression) {
+ // Short blocks have output as an expression on the open tag (no body)
+ block_output = Twig.expression.parse.apply(this, [{
+ type: Twig.expression.type.string,
+ value: Twig.expression.parse.apply(this, [token.output, context])
+ }, context]);
+ } else {
+ block_output = Twig.expression.parse.apply(this, [{
+ type: Twig.expression.type.string,
+ value: Twig.parse.apply(this, [token.output, context])
+ }, context]);
+ }
+
+ if (isImported) {
+ // once the block is overridden, remove it from the list of imported blocks
+ this.importedBlocks.splice(this.importedBlocks.indexOf(token.block), 1);
+ }
if (hasParent) {
- this.blocks[token.block] = this.blocks[token.block].replace(Twig.placeholders.parent, block_output);
+ this.blocks[token.block] = Twig.Markup(this.blocks[token.block].replace(Twig.placeholders.parent, block_output));
} else {
this.blocks[token.block] = block_output;
}
+
+ this.originalBlockTokens[token.block] = {
+ type: token.type,
+ block: token.block,
+ output: token.output,
+ overwrite: true
+ };
}
// Check if a child block has been set from a template extending this one.
@@ -2286,6 +3139,32 @@ var Twig = (function (Twig) {
};
}
},
+ {
+ /**
+ * Block shorthand logic tokens.
+ *
+ * Format: {% block title expression %}
+ */
+ type: Twig.logic.type.shortblock,
+ regex: /^block\s+([a-zA-Z0-9_]+)\s+(.+)$/,
+ next: [ ],
+ open: true,
+ compile: function (token) {
+ token.expression = token.match[2].trim();
+
+ token.output = Twig.expression.compile({
+ type: Twig.expression.type.expression,
+ value: token.expression
+ }).stack;
+
+ token.block = token.match[1].trim();
+ delete token.match;
+ return token;
+ },
+ parse: function (token, context, chain) {
+ return Twig.logic.handler[Twig.logic.type.block].parse.apply(this, arguments);
+ }
+ },
{
/**
* End block logic tokens.
@@ -2335,7 +3214,7 @@ var Twig = (function (Twig) {
/**
* Block logic tokens.
*
- * Format: {% extends "template.twig" %}
+ * Format: {% use "template.twig" %}
*/
type: Twig.logic.type.use,
regex: /^use\s+(.+)$/,
@@ -2372,7 +3251,7 @@ var Twig = (function (Twig) {
* Format: {% includes "template.twig" [with {some: 'values'} only] %}
*/
type: Twig.logic.type.include,
- regex: /^include\s+(ignore missing\s+)?(.+?)\s*(?:with\s+(.+?))?\s*(only)?$/,
+ regex: /^include\s+(ignore missing\s+)?(.+?)\s*(?:with\s+([\S\s]+?))?\s*(only)?$/,
next: [ ],
open: true,
compile: function (token) {
@@ -2409,10 +3288,7 @@ var Twig = (function (Twig) {
template;
if (!token.only) {
- for (i in context) {
- if (context.hasOwnProperty(i))
- innerContext[i] = context[i];
- }
+ innerContext = Twig.ChildContext(context);
}
if (token.withStack !== undefined) {
@@ -2426,8 +3302,12 @@ var Twig = (function (Twig) {
var file = Twig.expression.parse.apply(this, [token.stack, innerContext]);
- // Import file
- template = this.importFile(file);
+ if (file instanceof Twig.Template) {
+ template = file;
+ } else {
+ // Import file
+ template = this.importFile(file);
+ }
return {
chain: chain,
@@ -2474,14 +3354,14 @@ var Twig = (function (Twig) {
*
*/
type: Twig.logic.type.macro,
- regex: /^macro\s+([a-zA-Z0-9_]+)\s?\((([a-zA-Z0-9_]+(,\s?)?)*)\)$/,
+ regex: /^macro\s+([a-zA-Z0-9_]+)\s*\(\s*((?:[a-zA-Z0-9_]+(?:,\s*)?)*)\s*\)$/,
next: [
Twig.logic.type.endmacro
],
open: true,
compile: function (token) {
var macroName = token.match[1],
- parameters = token.match[2].split(/[ ,]+/);
+ parameters = token.match[2].split(/[\s,]+/);
//TODO: Clean up duplicate check
for (var i=0; i -1;
-
} else {
var el;
for (el in b) {
@@ -4089,7 +5066,6 @@ var Twig = (function (Twig) {
})( Twig || { } );
// Twig.js
-// Copyright (c) 2011-2013 John Roepke
// Available under the BSD 2-Clause License
// https://github.com/justjohn/twig.js
@@ -4156,7 +5132,7 @@ var Twig = (function (Twig) {
return value.reverse();
} else if (is("String", value)) {
return value.split("").reverse().join("");
- } else if (value instanceof Object) {
+ } else if (is("Object", value)) {
var keys = value._keys || Object.keys(value).reverse();
value._keys = keys;
return value;
@@ -4165,16 +5141,48 @@ var Twig = (function (Twig) {
sort: function(value) {
if (is("Array", value)) {
return value.sort();
- } else if (value instanceof Object) {
+ } else if (is('Object', value)) {
// Sorting objects isn't obvious since the order of
- // returned keys isn't guaranteedin JavaScript.
+ // returned keys isn't guaranteed in JavaScript.
// Because of this we use a "hidden" key called _keys to
// store the keys in the order we want to return them.
delete value._keys;
var keys = Object.keys(value),
sorted_keys = keys.sort(function(a, b) {
- return value[a] > value[b];
+ var a1, a2;
+
+ // if a and b are comparable, we're fine :-)
+ if((value[a] > value[b]) == !(value[a] <= value[b])) {
+ return value[a] > value[b] ? 1 :
+ value[a] < value[b] ? -1 :
+ 0;
+ }
+ // if a and b can be parsed as numbers, we can compare
+ // their numeric value
+ else if(!isNaN(a1 = parseFloat(value[a])) &&
+ !isNaN(b1 = parseFloat(value[b]))) {
+ return a1 > b1 ? 1 :
+ a1 < b1 ? -1 :
+ 0;
+ }
+ // if one of the values is a string, we convert the
+ // other value to string as well
+ else if(typeof value[a] == 'string') {
+ return value[a] > value[b].toString() ? 1 :
+ value[a] < value[b].toString() ? -1 :
+ 0;
+ }
+ else if(typeof value[b] == 'string') {
+ return value[a].toString() > value[b] ? 1 :
+ value[a].toString() < value[b] ? -1 :
+ 0;
+ }
+ // everything failed - return 'null' as sign, that
+ // the values are not comparable
+ else {
+ return null;
+ }
});
value._keys = sorted_keys;
return value;
@@ -4201,7 +5209,9 @@ var Twig = (function (Twig) {
return;
}
- return encodeURIComponent(value);
+ var result = encodeURIComponent(value);
+ result = result.replace("'", "%27");
+ return result;
},
join: function(value, params) {
if (value === undefined || value === null){
@@ -4215,7 +5225,7 @@ var Twig = (function (Twig) {
if (params && params[0]) {
join_str = params[0];
}
- if (value instanceof Array) {
+ if (is("Array", value)) {
output = value;
} else {
keyset = value._keys || Object.keys(value);
@@ -4229,23 +5239,45 @@ var Twig = (function (Twig) {
return output.join(join_str);
},
"default": function(value, params) {
- if (params === undefined || params.length !== 1) {
+ if (params !== undefined && params.length > 1) {
throw new Twig.Error("default filter expects one argument");
}
if (value === undefined || value === null || value === '' ) {
+ if (params === undefined) {
+ return '';
+ }
+
return params[0];
} else {
return value;
}
},
json_encode: function(value) {
- if (value && value.hasOwnProperty( "_keys" ) ) {
- delete value._keys;
- }
if(value === undefined || value === null) {
return "null";
}
- return JSON.stringify(value);
+ else if ((typeof value == 'object') && (is("Array", value))) {
+ output = [];
+
+ Twig.forEach(value, function(v) {
+ output.push(Twig.filters.json_encode(v));
+ });
+
+ return "[" + output.join(",") + "]";
+ }
+ else if (typeof value == 'object') {
+ var keyset = value._keys || Object.keys(value),
+ output = [];
+
+ Twig.forEach(keyset, function(key) {
+ output.push(JSON.stringify(key) + ":" + Twig.filters.json_encode(value[key]));
+ });
+
+ return "{" + output.join(",") + "}";
+ }
+ else {
+ return JSON.stringify(value);
+ }
},
merge: function(value, params) {
var obj = [],
@@ -4253,21 +5285,21 @@ var Twig = (function (Twig) {
keyset = [];
// Check to see if all the objects being merged are arrays
- if (!(value instanceof Array)) {
+ if (!is("Array", value)) {
// Create obj as an Object
obj = { };
} else {
Twig.forEach(params, function(param) {
- if (!(param instanceof Array)) {
+ if (!is("Array", param)) {
obj = { };
}
});
}
- if (!(obj instanceof Array)) {
+ if (!is("Array", obj)) {
obj._keys = [];
}
- if (value instanceof Array) {
+ if (is("Array", value)) {
Twig.forEach(value, function(val) {
if (obj._keys) obj._keys.push(arr_index);
obj[arr_index] = val;
@@ -4295,7 +5327,7 @@ var Twig = (function (Twig) {
// mixin the merge arrays
Twig.forEach(params, function(param) {
- if (param instanceof Array) {
+ if (is("Array", param)) {
Twig.forEach(param, function(val) {
if (obj._keys) obj._keys.push(arr_index);
obj[arr_index] = val;
@@ -4321,12 +5353,9 @@ var Twig = (function (Twig) {
return obj;
},
date: function(value, params) {
- if (value === undefined||value === null){
- return;
- }
-
var date = Twig.functions.date(value);
- return Twig.lib.formatDate(date, params[0]);
+ var format = params && params.length ? params[0] : 'F j, Y H:i';
+ return Twig.lib.formatDate(date, format);
},
date_modify: function(value, params) {
@@ -4383,20 +5412,92 @@ var Twig = (function (Twig) {
return Twig.lib.strip_tags(value);
},
- escape: function(value) {
+ escape: function(value, params) {
if (value === undefined|| value === null){
return;
}
- return value.toString().replace(/&/g, "&")
- .replace(//g, ">")
- .replace(/"/g, """)
- .replace(/'/g, "'");
+
+ var strategy = "html";
+ if(params && params.length && params[0] !== true)
+ strategy = params[0];
+
+ if(strategy == "html") {
+ var raw_value = value.toString().replace(/&/g, "&")
+ .replace(//g, ">")
+ .replace(/"/g, """)
+ .replace(/'/g, "'");
+ return Twig.Markup(raw_value, 'html');
+ } else if(strategy == "js") {
+ var raw_value = value.toString();
+ var result = "";
+
+ for(var i = 0; i < raw_value.length; i++) {
+ if(raw_value[i].match(/^[a-zA-Z0-9,\._]$/))
+ result += raw_value[i];
+ else {
+ var char_code = raw_value.charCodeAt(i);
+
+ if(char_code < 0x80)
+ result += "\\x" + char_code.toString(16).toUpperCase();
+ else
+ result += Twig.lib.sprintf("\\u%04s", char_code.toString(16).toUpperCase());
+ }
+ }
+
+ return Twig.Markup(result, 'js');
+ } else if(strategy == "css") {
+ var raw_value = value.toString();
+ var result = "";
+
+ for(var i = 0; i < raw_value.length; i++) {
+ if(raw_value[i].match(/^[a-zA-Z0-9]$/))
+ result += raw_value[i];
+ else {
+ var char_code = raw_value.charCodeAt(i);
+ result += "\\" + char_code.toString(16).toUpperCase() + " ";
+ }
+ }
+
+ return Twig.Markup(result, 'css');
+ } else if(strategy == "url") {
+ var result = Twig.filters.url_encode(value);
+ return Twig.Markup(result, 'url');
+ } else if(strategy == "html_attr") {
+ var raw_value = value.toString();
+ var result = "";
+
+ for(var i = 0; i < raw_value.length; i++) {
+ if(raw_value[i].match(/^[a-zA-Z0-9,\.\-_]$/))
+ result += raw_value[i];
+ else if(raw_value[i].match(/^[&<>"]$/))
+ result += raw_value[i].replace(/&/g, "&")
+ .replace(//g, ">")
+ .replace(/"/g, """);
+ else {
+ var char_code = raw_value.charCodeAt(i);
+
+ // The following replaces characters undefined in HTML with
+ // the hex entity for the Unicode replacement character.
+ if(char_code <= 0x1f && char_code != 0x09 && char_code != 0x0a && char_code != 0x0d)
+ result += "�";
+ else if(char_code < 0x80)
+ result += Twig.lib.sprintf("%02s;", char_code.toString(16).toUpperCase());
+ else
+ result += Twig.lib.sprintf("%04s;", char_code.toString(16).toUpperCase());
+ }
+ }
+
+ return Twig.Markup(result, 'html_attr');
+ } else {
+ throw new Twig.Error("escape strategy unsupported");
+ }
},
/* Alias of escape */
- "e": function(value) {
- return Twig.filters.escape(value);
+ "e": function(value, params) {
+ return Twig.filters.escape(value, params);
},
nl2br: function(value) {
@@ -4411,7 +5512,9 @@ var Twig = (function (Twig) {
.replace(/\r/g, br)
.replace(/\n/g, br);
- return Twig.lib.replaceAll(value, linebreak_tag, "\n");
+ value = Twig.lib.replaceAll(value, linebreak_tag, "\n");
+
+ return Twig.Markup(value);
},
/**
@@ -4470,6 +5573,39 @@ var Twig = (function (Twig) {
return whitespace.indexOf(str.charAt(0)) === -1 ? str : '';
},
+ truncate: function (value, params) {
+ var length = 30,
+ preserve = false,
+ separator = '...';
+
+ value = value + '';
+ if (params) {
+ if (params[0]) {
+ length = params[0];
+ }
+ if (params[1]) {
+ preserve = params[1];
+ }
+ if (params[2]) {
+ separator = params[2];
+ }
+ }
+
+ if (value.length > length) {
+
+ if (preserve) {
+ length = value.indexOf(' ', length);
+ if (length === -1) {
+ return value;
+ }
+ }
+
+ value = value.substr(0, length) + separator;
+ }
+
+ return value;
+ },
+
slice: function(value, params) {
if (value === undefined || value === null) {
return;
@@ -4507,9 +5643,9 @@ var Twig = (function (Twig) {
},
first: function(value) {
- if (value instanceof Array) {
+ if (is("Array", value)) {
return value[0];
- } else if (value instanceof Object) {
+ } else if (is("Object", value)) {
if ('_keys' in value) {
return value[value._keys[0]];
}
@@ -4595,8 +5731,7 @@ var Twig = (function (Twig) {
return value[value.length - 1];
},
raw: function(value) {
- //Raw filter shim
- return value;
+ return Twig.Markup(value);
},
batch: function(items, params) {
var size = params.shift(),
@@ -4669,7 +5804,6 @@ var Twig = (function (Twig) {
})(Twig || { });
// Twig.js
-// Copyright (c) 2011-2013 John Roepke
// 2012 Hadrien Lanneau
// Available under the BSD 2-Clause License
// https://github.com/justjohn/twig.js
@@ -4678,6 +5812,11 @@ var Twig = (function (Twig) {
//
// This file handles parsing filters.
var Twig = (function (Twig) {
+ /**
+ * @constant
+ * @type {string}
+ */
+ var TEMPLATE_NOT_FOUND_MESSAGE = 'Template "{name}" is not defined.';
// Determine object type
function is(type, obj) {
@@ -4739,19 +5878,19 @@ var Twig = (function (Twig) {
},
dump: function() {
var EOL = '\n',
- indentChar = ' ',
- indentTimes = 0,
- out = '',
- args = Array.prototype.slice.call(arguments),
- indent = function(times) {
- var ind = '';
+ indentChar = ' ',
+ indentTimes = 0,
+ out = '',
+ args = Array.prototype.slice.call(arguments),
+ indent = function(times) {
+ var ind = '';
while (times > 0) {
times--;
ind += indentChar;
}
return ind;
},
- displayVar = function(variable) {
+ displayVar = function(variable) {
out += indent(indentTimes);
if (typeof(variable) === 'object') {
dumpVar(variable);
@@ -4765,41 +5904,41 @@ var Twig = (function (Twig) {
out += 'bool(' + variable + ')' + EOL;
}
},
- dumpVar = function(variable) {
- var i;
- if (variable === null) {
- out += 'NULL' + EOL;
- } else if (variable === undefined) {
- out += 'undefined' + EOL;
- } else if (typeof variable === 'object') {
- out += indent(indentTimes) + typeof(variable);
- indentTimes++;
- out += '(' + (function(obj) {
- var size = 0, key;
- for (key in obj) {
- if (obj.hasOwnProperty(key)) {
- size++;
- }
- }
- return size;
- })(variable) + ') {' + EOL;
- for (i in variable) {
- out += indent(indentTimes) + '[' + i + ']=> ' + EOL;
- displayVar(variable[i]);
- }
- indentTimes--;
- out += indent(indentTimes) + '}' + EOL;
- } else {
- displayVar(variable);
- }
- };
-
- // handle no argument case by dumping the entire render context
- if (args.length == 0) args.push(this.context);
-
- Twig.forEach(args, function(variable) {
- dumpVar(variable);
- });
+ dumpVar = function(variable) {
+ var i;
+ if (variable === null) {
+ out += 'NULL' + EOL;
+ } else if (variable === undefined) {
+ out += 'undefined' + EOL;
+ } else if (typeof variable === 'object') {
+ out += indent(indentTimes) + typeof(variable);
+ indentTimes++;
+ out += '(' + (function(obj) {
+ var size = 0, key;
+ for (key in obj) {
+ if (obj.hasOwnProperty(key)) {
+ size++;
+ }
+ }
+ return size;
+ })(variable) + ') {' + EOL;
+ for (i in variable) {
+ out += indent(indentTimes) + '[' + i + ']=> ' + EOL;
+ displayVar(variable[i]);
+ }
+ indentTimes--;
+ out += indent(indentTimes) + '}' + EOL;
+ } else {
+ displayVar(variable);
+ }
+ };
+
+ // handle no argument case by dumping the entire render context
+ if (args.length == 0) args.push(this.context);
+
+ Twig.forEach(args, function(variable) {
+ dumpVar(variable);
+ });
return out;
},
@@ -4810,7 +5949,12 @@ var Twig = (function (Twig) {
} else if (Twig.lib.is("Date", date)) {
dateObj = date;
} else if (Twig.lib.is("String", date)) {
- dateObj = new Date(Twig.lib.strtotime(date) * 1000);
+ if (date.match(/^[0-9]+$/)) {
+ dateObj = new Date(date * 1000);
+ }
+ else {
+ dateObj = new Date(Twig.lib.strtotime(date) * 1000);
+ }
} else if (Twig.lib.is("Number", date)) {
// timestamp
dateObj = new Date(date * 1000);
@@ -4820,14 +5964,18 @@ var Twig = (function (Twig) {
return dateObj;
},
block: function(block) {
- return this.blocks[block];
+ if (this.originalBlockTokens[block]) {
+ return Twig.logic.parse.apply(this, [this.originalBlockTokens[block], this.context]).output;
+ } else {
+ return this.blocks[block];
+ }
},
parent: function() {
// Add a placeholder
return Twig.placeholders.parent;
},
attribute: function(object, method, params) {
- if (object instanceof Object) {
+ if (Twig.lib.is('Object', object)) {
if (object.hasOwnProperty(method)) {
if (typeof object[method] === "function") {
return object[method].apply(undefined, params);
@@ -4839,6 +5987,130 @@ var Twig = (function (Twig) {
}
// Array will return element 0-index
return object[method] || undefined;
+ },
+ max: function(values) {
+ if(Twig.lib.is("Object", values)) {
+ delete values["_keys"];
+ return Twig.lib.max(values);
+ }
+
+ return Twig.lib.max.apply(null, arguments);
+ },
+ min: function(values) {
+ if(Twig.lib.is("Object", values)) {
+ delete values["_keys"];
+ return Twig.lib.min(values);
+ }
+
+ return Twig.lib.min.apply(null, arguments);
+ },
+ template_from_string: function(template) {
+ if (template === undefined) {
+ template = '';
+ }
+ return Twig.Templates.parsers.twig({
+ options: this.options,
+ data: template
+ });
+ },
+ random: function(value) {
+ var LIMIT_INT31 = 0x80000000;
+
+ function getRandomNumber(n) {
+ var random = Math.floor(Math.random() * LIMIT_INT31);
+ var limits = [0, n];
+ var min = Math.min.apply(null, limits),
+ max = Math.max.apply(null, limits);
+ return min + Math.floor((max - min + 1) * random / LIMIT_INT31);
+ }
+
+ if(Twig.lib.is("Number", value)) {
+ return getRandomNumber(value);
+ }
+
+ if(Twig.lib.is("String", value)) {
+ return value.charAt(getRandomNumber(value.length-1));
+ }
+
+ if(Twig.lib.is("Array", value)) {
+ return value[getRandomNumber(value.length-1)];
+ }
+
+ if(Twig.lib.is("Object", value)) {
+ var keys = Object.keys(value);
+ return value[keys[getRandomNumber(keys.length-1)]];
+ }
+
+ return getRandomNumber(LIMIT_INT31-1);
+ },
+
+ /**
+ * Returns the content of a template without rendering it
+ * @param {string} name
+ * @param {boolean} [ignore_missing=false]
+ * @returns {string}
+ */
+ source: function(name, ignore_missing) {
+ var templateSource;
+ var templateFound = false;
+ var isNodeEnvironment = typeof module !== 'undefined' && typeof module.exports !== 'undefined' && typeof window === 'undefined';
+ var loader;
+ var path;
+
+ //if we are running in a node.js environment, set the loader to 'fs' and ensure the
+ // path is relative to the CWD of the running script
+ //else, set the loader to 'ajax' and set the path to the value of name
+ if (isNodeEnvironment) {
+ loader = 'fs';
+ path = __dirname + '/' + name;
+ } else {
+ loader = 'ajax';
+ path = name;
+ }
+
+ //build the params object
+ var params = {
+ id: name,
+ path: path,
+ method: loader,
+ parser: 'source',
+ async: false,
+ fetchTemplateSource: true
+ };
+
+ //default ignore_missing to false
+ if (typeof ignore_missing === 'undefined') {
+ ignore_missing = false;
+ }
+
+ //try to load the remote template
+ //
+ //on exception, log it
+ try {
+ templateSource = Twig.Templates.loadRemote(name, params);
+
+ //if the template is undefined or null, set the template to an empty string and do NOT flip the
+ // boolean indicating we found the template
+ //
+ //else, all is good! flip the boolean indicating we found the template
+ if (typeof templateSource === 'undefined' || templateSource === null) {
+ templateSource = '';
+ } else {
+ templateFound = true;
+ }
+ } catch (e) {
+ Twig.log.debug('Twig.functions.source: ', 'Problem loading template ', e);
+ }
+
+ //if the template was NOT found AND we are not ignoring missing templates, return the same message
+ // that is returned by the PHP implementation of the twig source() function
+ //
+ //else, return the template source
+ if (!templateFound && !ignore_missing) {
+ return TEMPLATE_NOT_FOUND_MESSAGE.replace('{name}', name);
+ } else {
+ return templateSource;
+ }
}
};
@@ -4857,7 +6129,119 @@ var Twig = (function (Twig) {
})(Twig || { });
// Twig.js
-// Copyright (c) 2011-2013 John Roepke
+// Available under the BSD 2-Clause License
+// https://github.com/justjohn/twig.js
+
+// ## twig.path.js
+//
+// This file handles path parsing
+var Twig = (function (Twig) {
+ "use strict";
+
+ /**
+ * Namespace for path handling.
+ */
+ Twig.path = {};
+
+ /**
+ * Generate the canonical version of a url based on the given base path and file path and in
+ * the previously registered namespaces.
+ *
+ * @param {string} template The Twig Template
+ * @param {string} file The file path, may be relative and may contain namespaces.
+ *
+ * @return {string} The canonical version of the path
+ */
+ Twig.path.parsePath = function(template, file) {
+ var namespaces = null,
+ file = file || "";
+
+ if (typeof template === 'object' && typeof template.options === 'object') {
+ namespaces = template.options.namespaces;
+ }
+
+ if (typeof namespaces === 'object' && (file.indexOf('::') > 0) || file.indexOf('@') >= 0){
+ for (var k in namespaces){
+ if (namespaces.hasOwnProperty(k)) {
+ file = file.replace(k + '::', namespaces[k]);
+ file = file.replace('@' + k, namespaces[k]);
+ }
+ }
+
+ return file;
+ }
+
+ return Twig.path.relativePath(template, file);
+ };
+
+ /**
+ * Generate the relative canonical version of a url based on the given base path and file path.
+ *
+ * @param {Twig.Template} template The Twig.Template.
+ * @param {string} file The file path, relative to the base path.
+ *
+ * @return {string} The canonical version of the path.
+ */
+ Twig.path.relativePath = function(template, file) {
+ var base,
+ base_path,
+ sep_chr = "/",
+ new_path = [],
+ file = file || "",
+ val;
+
+ if (template.url) {
+ if (typeof template.base !== 'undefined') {
+ base = template.base + ((template.base.charAt(template.base.length-1) === '/') ? '' : '/');
+ } else {
+ base = template.url;
+ }
+ } else if (template.path) {
+ // Get the system-specific path separator
+ var path = require("path"),
+ sep = path.sep || sep_chr,
+ relative = new RegExp("^\\.{1,2}" + sep.replace("\\", "\\\\"));
+ file = file.replace(/\//g, sep);
+
+ if (template.base !== undefined && file.match(relative) == null) {
+ file = file.replace(template.base, '');
+ base = template.base + sep;
+ } else {
+ base = path.normalize(template.path);
+ }
+
+ base = base.replace(sep+sep, sep);
+ sep_chr = sep;
+ } else if ((template.name || template.id) && template.method && template.method !== 'fs' && template.method !== 'ajax') {
+ // Custom registered loader
+ base = template.base || template.name || template.id;
+ } else {
+ throw new Twig.Error("Cannot extend an inline template.");
+ }
+
+ base_path = base.split(sep_chr);
+
+ // Remove file from url
+ base_path.pop();
+ base_path = base_path.concat(file.split(sep_chr));
+
+ while (base_path.length > 0) {
+ val = base_path.shift();
+ if (val == ".") {
+ // Ignore
+ } else if (val == ".." && new_path.length > 0 && new_path[new_path.length-1] != "..") {
+ new_path.pop();
+ } else {
+ new_path.push(val);
+ }
+ }
+
+ return new_path.join(sep_chr);
+ };
+
+ return Twig;
+}) (Twig || { });
+// Twig.js
// Available under the BSD 2-Clause License
// https://github.com/justjohn/twig.js
@@ -4899,6 +6283,9 @@ var Twig = (function (Twig) {
},
sameas: function(value, params) {
return value === params[0];
+ },
+ iterable: function(value) {
+ return value && (Twig.lib.is("Array", value) || Twig.lib.is("Object", value));
}
/*
constant ?
@@ -4919,7 +6306,6 @@ var Twig = (function (Twig) {
return Twig;
})( Twig || { } );
// Twig.js
-// Copyright (c) 2011-2013 John Roepke
// Available under the BSD 2-Clause License
// https://github.com/justjohn/twig.js
@@ -4944,12 +6330,15 @@ var Twig = (function (Twig) {
'use strict';
var id = params.id,
options = {
- strict_variables: params.strict_variables || false,
+ strictVariables: params.strictVariables || false,
+ // TODO: turn autoscape on in the next major version
+ autoescape: params.autoescape != null && params.autoescape || false,
allowInlineIncludes: params.allowInlineIncludes || false,
- rethrow: params.rethrow || false
+ rethrow: params.rethrow || false,
+ namespaces: params.namespaces
};
- if (id) {
+ if (Twig.cache && id) {
Twig.validateId(id);
}
@@ -4961,8 +6350,9 @@ var Twig = (function (Twig) {
}
if (params.data !== undefined) {
- return new Twig.Template({
+ return Twig.Templates.parsers.twig({
data: params.data,
+ path: params.hasOwnProperty('path') ? params.path : undefined,
module: params.module,
id: id,
options: options
@@ -4974,10 +6364,27 @@ var Twig = (function (Twig) {
}
return Twig.Templates.load(params.ref);
+ } else if (params.method !== undefined) {
+ if (!Twig.Templates.isRegisteredLoader(params.method)) {
+ throw new Twig.Error('Loader for "' + params.method + '" is not defined.');
+ }
+ return Twig.Templates.loadRemote(params.name || params.href || params.path || id || undefined, {
+ id: id,
+ method: params.method,
+ parser: params.parser || 'twig',
+ base: params.base,
+ module: params.module,
+ precompiled: params.precompiled,
+ async: params.async,
+ options: options
+
+ }, params.load, params.error);
+
} else if (params.href !== undefined) {
return Twig.Templates.loadRemote(params.href, {
id: id,
method: 'ajax',
+ parser: params.parser || 'twig',
base: params.base,
module: params.module,
precompiled: params.precompiled,
@@ -4990,6 +6397,7 @@ var Twig = (function (Twig) {
return Twig.Templates.loadRemote(params.path, {
id: id,
method: 'fs',
+ parser: params.parser || 'twig',
base: params.base,
module: params.module,
precompiled: params.precompiled,
@@ -5059,32 +6467,37 @@ var Twig = (function (Twig) {
* @param {string} path The location of the template file on disk.
* @param {Object|Function} The options or callback.
* @param {Function} fn callback.
+ *
+ * @throws Twig.Error
*/
-
Twig.exports.renderFile = function(path, options, fn) {
// handle callback in options
- if ('function' == typeof options) {
+ if (typeof options === 'function') {
fn = options;
options = {};
}
options = options || {};
+ var settings = options.settings || {};
+
var params = {
- path: path,
- base: options.settings['views'],
- load: function(template) {
- // render and return template
- fn(null, template.render(options));
- }
- };
+ path: path,
+ base: settings.views,
+ load: function(template) {
+ // render and return template
+ fn(null, template.render(options));
+ }
+ };
// mixin any options provided to the express app.
- var view_options = options.settings['twig options'];
+ var view_options = settings['twig options'];
if (view_options) {
- for (var option in view_options) if (view_options.hasOwnProperty(option)) {
- params[option] = view_options[option];
+ for (var option in view_options) {
+ if (view_options.hasOwnProperty(option)) {
+ params[option] = view_options[option];
+ }
}
}
@@ -5103,13 +6516,15 @@ var Twig = (function (Twig) {
*/
Twig.exports.cache = function(cache) {
Twig.cache = cache;
- }
+ };
+
+ //We need to export the path module so we can effectively test it
+ Twig.exports.path = Twig.path;
return Twig;
}) (Twig || { });
// Twig.js
-// Copyright (c) 2011-2013 John Roepke
// Available under the BSD 2-Clause License
// https://github.com/justjohn/twig.js
@@ -5165,7 +6580,6 @@ var Twig = (function (Twig) {
return Twig;
})(Twig || {});
// Twig.js
-// Copyright (c) 2011-2013 John Roepke
// Available under the BSD 2-Clause License
// https://github.com/justjohn/twig.js
diff --git a/demos/twitter_backbone/vendor/underscore.js b/demos/twitter_backbone/vendor/underscore.js
index bcd604c7..7d7dd10d 100644
--- a/demos/twitter_backbone/vendor/underscore.js
+++ b/demos/twitter_backbone/vendor/underscore.js
@@ -1,34 +1,733 @@
module.declare([], function (require, exports, module) {
-
// Underscore.js 1.2.2
-// (c) 2011 Jeremy Ashkenas, DocumentCloud Inc.
-// Underscore is freely distributable under the MIT license.
-// Portions of Underscore are inspired or borrowed from Prototype,
-// Oliver Steele's Functional, and John Resig's Micro-Templating.
-// For all details and documentation:
-// http://documentcloud.github.com/underscore
-(function(){function r(a,c,d){if(a===c)return a!==0||1/a==1/c;if(a==null||c==null)return a===c;if(a._chain)a=a._wrapped;if(c._chain)c=c._wrapped;if(b.isFunction(a.isEqual))return a.isEqual(c);if(b.isFunction(c.isEqual))return c.isEqual(a);var e=l.call(a);if(e!=l.call(c))return false;switch(e){case "[object String]":return String(a)==String(c);case "[object Number]":return a=+a,c=+c,a!=a?c!=c:a==0?1/a==1/c:a==c;case "[object Date]":case "[object Boolean]":return+a==+c;case "[object RegExp]":return a.source==
-c.source&&a.global==c.global&&a.multiline==c.multiline&&a.ignoreCase==c.ignoreCase}if(typeof a!="object"||typeof c!="object")return false;for(var f=d.length;f--;)if(d[f]==a)return true;d.push(a);var f=0,g=true;if(e=="[object Array]"){if(f=a.length,g=f==c.length)for(;f--;)if(!(g=f in a==f in c&&r(a[f],c[f],d)))break}else{if("constructor"in a!="constructor"in c||a.constructor!=c.constructor)return false;for(var h in a)if(m.call(a,h)&&(f++,!(g=m.call(c,h)&&r(a[h],c[h],d))))break;if(g){for(h in c)if(m.call(c,
-h)&&!f--)break;g=!f}}d.pop();return g}var s=this,F=s._,o={},k=Array.prototype,p=Object.prototype,i=k.slice,G=k.unshift,l=p.toString,m=p.hasOwnProperty,v=k.forEach,w=k.map,x=k.reduce,y=k.reduceRight,z=k.filter,A=k.every,B=k.some,q=k.indexOf,C=k.lastIndexOf,p=Array.isArray,H=Object.keys,t=Function.prototype.bind,b=function(a){return new n(a)};if(typeof exports!=="undefined"){if(typeof module!=="undefined"&&module.exports)exports=module.exports=b;exports._=b}else typeof define==="function"&&define.amd?
-define("underscore",function(){return b}):s._=b;b.VERSION="1.2.2";var j=b.each=b.forEach=function(a,c,b){if(a!=null)if(v&&a.forEach===v)a.forEach(c,b);else if(a.length===+a.length)for(var e=0,f=a.length;e=e.computed&&(e={value:a,computed:b})});return e.value};b.min=function(a,c,d){if(!c&&b.isArray(a))return Math.min.apply(Math,a);if(!c&&b.isEmpty(a))return Infinity;var e={computed:Infinity};j(a,function(a,b,h){b=c?c.call(d,a,b,h):a;bd?1:0}),"value")};b.groupBy=function(a,c){var d={},e=b.isFunction(c)?c:function(a){return a[c]};j(a,function(a,c){var b=e(a,c);(d[b]||(d[b]=[])).push(a)});return d};b.sortedIndex=function(a,c,d){d||(d=b.identity);for(var e=0,f=a.length;e<
-f;){var g=e+f>>1;d(a[g])=0})})};b.difference=function(a,c){return b.filter(a,function(a){return!b.include(c,a)})};b.zip=function(){for(var a=i.call(arguments),c=b.max(b.pluck(a,"length")),d=Array(c),e=0;e=0;d--)b=[a[d].apply(this,b)];return b[0]}};b.after=function(a,b){return a<=0?b():function(){if(--a<1)return b.apply(this,arguments)}};b.keys=H||function(a){if(a!==
-Object(a))throw new TypeError("Invalid object");var b=[],d;for(d in a)m.call(a,d)&&(b[b.length]=d);return b};b.values=function(a){return b.map(a,b.identity)};b.functions=b.methods=function(a){var c=[],d;for(d in a)b.isFunction(a[d])&&c.push(d);return c.sort()};b.extend=function(a){j(i.call(arguments,1),function(b){for(var d in b)b[d]!==void 0&&(a[d]=b[d])});return a};b.defaults=function(a){j(i.call(arguments,1),function(b){for(var d in b)a[d]==null&&(a[d]=b[d])});return a};b.clone=function(a){return!b.isObject(a)?
-a:b.isArray(a)?a.slice():b.extend({},a)};b.tap=function(a,b){b(a);return a};b.isEqual=function(a,b){return r(a,b,[])};b.isEmpty=function(a){if(b.isArray(a)||b.isString(a))return a.length===0;for(var c in a)if(m.call(a,c))return false;return true};b.isElement=function(a){return!!(a&&a.nodeType==1)};b.isArray=p||function(a){return l.call(a)=="[object Array]"};b.isObject=function(a){return a===Object(a)};b.isArguments=l.call(arguments)=="[object Arguments]"?function(a){return l.call(a)=="[object Arguments]"}:
-function(a){return!(!a||!m.call(a,"callee"))};b.isFunction=function(a){return l.call(a)=="[object Function]"};b.isString=function(a){return l.call(a)=="[object String]"};b.isNumber=function(a){return l.call(a)=="[object Number]"};b.isNaN=function(a){return a!==a};b.isBoolean=function(a){return a===true||a===false||l.call(a)=="[object Boolean]"};b.isDate=function(a){return l.call(a)=="[object Date]"};b.isRegExp=function(a){return l.call(a)=="[object RegExp]"};b.isNull=function(a){return a===null};
-b.isUndefined=function(a){return a===void 0};b.noConflict=function(){s._=F;return this};b.identity=function(a){return a};b.times=function(a,b,d){for(var e=0;e /g,">").replace(/"/g,""").replace(/'/g,"'").replace(/\//g,"/")};b.mixin=function(a){j(b.functions(a),function(c){I(c,b[c]=a[c])})};var J=0;b.uniqueId=function(a){var b=J++;return a?a+b:b};b.templateSettings={evaluate:/<%([\s\S]+?)%>/g,
-interpolate:/<%=([\s\S]+?)%>/g,escape:/<%-([\s\S]+?)%>/g};b.template=function(a,c){var d=b.templateSettings,d="var __p=[],print=function(){__p.push.apply(__p,arguments);};with(obj||{}){__p.push('"+a.replace(/\\/g,"\\\\").replace(/'/g,"\\'").replace(d.escape,function(a,b){return"',_.escape("+b.replace(/\\'/g,"'")+"),'"}).replace(d.interpolate,function(a,b){return"',"+b.replace(/\\'/g,"'")+",'"}).replace(d.evaluate||null,function(a,b){return"');"+b.replace(/\\'/g,"'").replace(/[\r\n\t]/g," ")+";__p.push('"}).replace(/\r/g,
-"\\r").replace(/\n/g,"\\n").replace(/\t/g,"\\t")+"');}return __p.join('');",e=new Function("obj","_",d);return c?e(c,b):function(a){return e(a,b)}};var n=function(a){this._wrapped=a};b.prototype=n.prototype;var u=function(a,c){return c?b(a).chain():a},I=function(a,c){n.prototype[a]=function(){var a=i.call(arguments);G.call(a,this._wrapped);return u(c.apply(b,a),this._chain)}};b.mixin(b);j("pop,push,reverse,shift,sort,splice,unshift".split(","),function(a){var b=k[a];n.prototype[a]=function(){b.apply(this._wrapped,
-arguments);return u(this._wrapped,this._chain)}});j(["concat","join","slice"],function(a){var b=k[a];n.prototype[a]=function(){return u(b.apply(this._wrapped,arguments),this._chain)}});n.prototype.chain=function(){this._chain=true;return this};n.prototype.value=function(){return this._wrapped}}).call(this);
+ // (c) 2011 Jeremy Ashkenas, DocumentCloud Inc.
+ // Underscore is freely distributable under the MIT license.
+ // Portions of Underscore are inspired or borrowed from Prototype,
+ // Oliver Steele's Functional, and John Resig's Micro-Templating.
+ // For all details and documentation:
+ // http://documentcloud.github.com/underscore
+ (function () {
+ function r(a, c, d) {
+ if (a === c) {
+ return a !== 0 || 1 / a == 1 / c;
+ }
+
+ if (a == null || c == null) {
+ return a === c;
+ }
+
+ if (a._chain) {
+ a = a._wrapped;
+ }
+
+ if (c._chain) {
+ c = c._wrapped;
+ }
+
+ if (b.isFunction(a.isEqual)) {
+ return a.isEqual(c);
+ }
+
+ if (b.isFunction(c.isEqual)) {
+ return c.isEqual(a);
+ }
+
+ const e = l.call(a); if (e != l.call(c)) {
+ return false;
+ }
+
+ switch (e) {
+ case '[object String]': return String(a) == String(c); case '[object Number]': return a = Number(a), c = Number(c), a != a ? c != c : (a == 0 ? 1 / a == 1 / c : a == c); case '[object Date]': case '[object Boolean]': return Number(a) == Number(c); case '[object RegExp]': return a.source ==
+c.source && a.global == c.global && a.multiline == c.multiline && a.ignoreCase == c.ignoreCase;
+ }
+
+ if (typeof a !== 'object' || typeof c !== 'object') {
+ return false;
+ }
+
+ for (var f = d.length; f--;) {
+ if (d[f] == a) {
+ return true;
+ }
+ }
+
+ d.push(a); var f = 0; let g = true; if (e == '[object Array]') {
+ if (f = a.length, g = f == c.length) {
+ for (;f--;) {
+ if (!(g = f in a == f in c && r(a[f], c[f], d))) {
+ break;
+ }
+ }
+ }
+ } else {
+ if ('constructor' in a != 'constructor' in c || a.constructor != c.constructor) {
+ return false;
+ }
+
+ for (var h in a) {
+ if (m.call(a, h) && (f++, !(g = m.call(c, h) && r(a[h], c[h], d)))) {
+ break;
+ }
+ }
+
+ if (g) {
+ for (h in c) {
+ if (m.call(c,
+ h) && !f--) {
+ break;
+ }
+ }
+
+ g = !f;
+ }
+ }
+
+ d.pop(); return g;
+ }
+
+ const s = this; const F = s._; const o = {}; const k = Array.prototype; var p = Object.prototype; const i = k.slice; const G = k.unshift; var l = p.toString; var m = p.hasOwnProperty; const v = k.forEach; const w = k.map; const x = k.reduce; const y = k.reduceRight; const z = k.filter; const A = k.every; const B = k.some; const q = k.indexOf; const C = k.lastIndexOf; var p = Array.isArray; const H = Object.keys; const t = Function.prototype.bind; var b = function (a) {
+ return new n(a);
+ };
+
+ if (typeof exports !== 'undefined') {
+ if (typeof module !== 'undefined' && module.exports) {
+ exports = module.exports = b;
+ }
+
+ exports._ = b;
+ } else {
+ typeof define === 'function' && define.amd ?
+ define('underscore', () => {
+ return b;
+ }) : s._ = b;
+ }
+
+ b.VERSION = '1.2.2'; const j = b.each = b.forEach = function (a, c, b) {
+ if (a != null) {
+ if (v && a.forEach === v) {
+ a.forEach(c, b);
+ } else if (a.length === Number(a.length)) {
+ for (var e = 0, f = a.length; e < f; e++) {
+ if (e in a && c.call(b, a[e], e, a) === o) {
+ break;
+ }
+ }
+ } else {
+ for (e in a) {
+ if (m.call(a, e) && c.call(b, a[e], e, a) === o) {
+ break;
+ }
+ }
+ }
+ }
+ };
+
+ b.map = function (a, c, b) {
+ const e = []; if (a == null) {
+ return e;
+ }
+
+ if (w && a.map === w) {
+ return a.map(c, b);
+ }
+
+ j(a, (a, g, h) => {
+ e[e.length] = c.call(b, a, g, h);
+ }); return e;
+ };
+
+ b.reduce = b.foldl = b.inject = function (a, c, d, e) {
+ let f =
+d !== void 0; a == null && (a = []); if (x && a.reduce === x) {
+ return e && (c = b.bind(c, e)), f ? a.reduce(c, d) : a.reduce(c);
+ }
+
+ j(a, (a, b, i) => {
+ f ? d = c.call(e, d, a, b, i) : (d = a, f = true);
+ }); if (!f) {
+ throw new TypeError('Reduce of empty array with no initial value');
+ }
+
+ return d;
+ };
+
+ b.reduceRight = b.foldr = function (a, c, d, e) {
+ a == null && (a = []); if (y && a.reduceRight === y) {
+ return e && (c = b.bind(c, e)), d !== void 0 ? a.reduceRight(c, d) : a.reduceRight(c);
+ }
+
+ a = (b.isArray(a) ? a.slice() : b.toArray(a)).reverse(); return b.reduce(a, c, d, e);
+ };
+
+ b.find = b.detect = function (a, c, b) {
+ let e;
+ D(a, (a, g, h) => {
+ if (c.call(b, a, g, h)) {
+ return e = a, true;
+ }
+ }); return e;
+ };
+
+ b.filter = b.select = function (a, c, b) {
+ const e = []; if (a == null) {
+ return e;
+ }
+
+ if (z && a.filter === z) {
+ return a.filter(c, b);
+ }
+
+ j(a, (a, g, h) => {
+ c.call(b, a, g, h) && (e[e.length] = a);
+ }); return e;
+ };
+
+ b.reject = function (a, c, b) {
+ const e = []; if (a == null) {
+ return e;
+ }
+
+ j(a, (a, g, h) => {
+ c.call(b, a, g, h) || (e[e.length] = a);
+ }); return e;
+ };
+
+ b.every = b.all = function (a, c, b) {
+ let e = true; if (a == null) {
+ return e;
+ }
+
+ if (A && a.every === A) {
+ return a.every(c, b);
+ }
+
+ j(a, (a, g, h) => {
+ if (!(e = e && c.call(b, a, g, h))) {
+ return o;
+ }
+ });
+ return e;
+ };
+
+ var D = b.some = b.any = function (a, c, d) {
+ var c = c || b.identity; let e = false; if (a == null) {
+ return e;
+ }
+
+ if (B && a.some === B) {
+ return a.some(c, d);
+ }
+
+ j(a, (a, b, h) => {
+ if (e || (e = c.call(d, a, b, h))) {
+ return o;
+ }
+ }); return Boolean(e);
+ };
+
+ b.include = b.contains = function (a, c) {
+ let b = false; if (a == null) {
+ return b;
+ }
+
+ return q && a.indexOf === q ? a.includes(c) : b = D(a, a => {
+ return a === c;
+ });
+ };
+
+ b.invoke = function (a, c) {
+ const d = i.call(arguments, 2); return b.map(a, a => {
+ return (c.call ? c || a : a[c]).apply(a, d);
+ });
+ };
+
+ b.pluck = function (a, c) {
+ return b.map(a, a => {
+ return a[c];
+ });
+ };
+
+ b.max = function (a, c, d) {
+ if (!c && b.isArray(a)) {
+ return Math.max.apply(Math, a);
+ }
+
+ if (!c && b.isEmpty(a)) {
+ return -Infinity;
+ }
+
+ let e = {computed: -Infinity}; j(a, (a, b, h) => {
+ b = c ? c.call(d, a, b, h) : a; b >= e.computed && (e = {value: a, computed: b});
+ }); return e.value;
+ };
+
+ b.min = function (a, c, d) {
+ if (!c && b.isArray(a)) {
+ return Math.min.apply(Math, a);
+ }
+
+ if (!c && b.isEmpty(a)) {
+ return Infinity;
+ }
+
+ let e = {computed: Infinity}; j(a, (a, b, h) => {
+ b = c ? c.call(d, a, b, h) : a; b < e.computed && (e = {value: a, computed: b});
+ }); return e.value;
+ };
+
+ b.shuffle = function (a) {
+ const c = []; let b;
+ j(a, (a, f) => {
+ f == 0 ? c[0] = a : (b = Math.floor(Math.random() * (f + 1)), c[f] = c[b], c[b] = a);
+ }); return c;
+ };
+
+ b.sortBy = function (a, c, d) {
+ return b.pluck(b.map(a, (a, b, g) => {
+ return {value: a, criteria: c.call(d, a, b, g)};
+ }).sort((a, c) => {
+ const b = a.criteria; const d = c.criteria; return b < d ? -1 : (b > d ? 1 : 0);
+ }), 'value');
+ };
+
+ b.groupBy = function (a, c) {
+ const d = {}; const e = b.isFunction(c) ? c : function (a) {
+ return a[c];
+ };
+
+ j(a, (a, c) => {
+ const b = e(a, c); (d[b] || (d[b] = [])).push(a);
+ }); return d;
+ };
+
+ b.sortedIndex = function (a, c, d) {
+ d || (d = b.identity); for (var e = 0, f = a.length; e <
+f;) {
+ const g = e + f >> 1; d(a[g]) < d(c) ? e = g + 1 : f = g;
+ }
+
+ return e;
+ };
+
+ b.toArray = function (a) {
+ return !a ? [] : a.toArray ? a.toArray() : b.isArray(a) ? i.call(a) : (b.isArguments(a) ? i.call(a) : b.values(a));
+ };
+
+ b.size = function (a) {
+ return b.toArray(a).length;
+ };
+
+ b.first = b.head = function (a, b, d) {
+ return b != null && !d ? i.call(a, 0, b) : a[0];
+ };
+
+ b.initial = function (a, b, d) {
+ return i.call(a, 0, a.length - (b == null || d ? 1 : b));
+ };
+
+ b.last = function (a, b, d) {
+ return b != null && !d ? i.call(a, Math.max(a.length - b, 0)) : a[a.length - 1];
+ };
+
+ b.rest = b.tail = function (a, b, d) {
+ return i.call(a, b == null ||
+d ? 1 : b);
+ };
+
+ b.compact = function (a) {
+ return b.filter(a, a => {
+ return Boolean(a);
+ });
+ };
+
+ b.flatten = function (a, c) {
+ return b.reduce(a, (a, e) => {
+ if (b.isArray(e)) {
+ return a.concat(c ? e : b.flatten(e));
+ }
+
+ a[a.length] = e; return a;
+ }, []);
+ };
+
+ b.without = function (a) {
+ return b.difference(a, i.call(arguments, 1));
+ };
+
+ b.uniq = b.unique = function (a, c, d) {
+ var d = d ? b.map(a, d) : a; const e = []; b.reduce(d, (d, g, h) => {
+ if (h == 0 || (c === true ? b.last(d) != g : !b.include(d, g))) {
+ d[d.length] = g, e[e.length] = a[h];
+ }
+
+ return d;
+ }, []); return e;
+ };
+
+ b.union = function () {
+ return b.uniq(b.flatten(arguments,
+ true));
+ };
+
+ b.intersection = b.intersect = function (a) {
+ const c = i.call(arguments, 1); return b.filter(b.uniq(a), a => {
+ return b.every(c, c => {
+ return b.includes(c, a);
+ });
+ });
+ };
+
+ b.difference = function (a, c) {
+ return b.filter(a, a => {
+ return !b.include(c, a);
+ });
+ };
+
+ b.zip = function () {
+ for (var a = i.call(arguments), c = b.max(b.pluck(a, 'length')), d = new Array(c), e = 0; e < c; e++) {
+ d[e] = b.pluck(a, String(e));
+ }
+
+ return d;
+ };
+
+ b.indexOf = function (a, c, d) {
+ if (a == null) {
+ return -1;
+ }
+
+ let e; if (d) {
+ return d = b.sortedIndex(a, c), a[d] === c ? d : -1;
+ }
+
+ if (q && a.indexOf === q) {
+ return a.indexOf(c);
+ }
+
+ for (d = 0, e = a.length; d < e; d++) {
+ if (a[d] === c) {
+ return d;
+ }
+ }
+
+ return -1;
+ };
+
+ b.lastIndexOf = function (a, b) {
+ if (a == null) {
+ return -1;
+ }
+
+ if (C && a.lastIndexOf === C) {
+ return a.lastIndexOf(b);
+ }
+
+ for (let d = a.length; d--;) {
+ if (a[d] === b) {
+ return d;
+ }
+ }
+
+ return -1;
+ };
+
+ b.range = function (a, b, d) {
+ arguments.length <= 1 && (b = a || 0, a = 0); for (var d = arguments[2] || 1, e = Math.max(Math.ceil((b - a) / d), 0), f = 0, g = new Array(e); f < e;) {
+ g[f++] = a, a += d;
+ }
+
+ return g;
+ };
+
+ const E = function () {}; b.bind = function (a, c) {
+ let d; let e; if (a.bind === t && t) {
+ return t.apply(a, i.call(arguments, 1));
+ }
+
+ if (!b.isFunction(a)) {
+ throw new TypeError();
+ }
+
+ e = i.call(arguments, 2); return d = function () {
+ if (!(this instanceof d)) {
+ return a.apply(c, e.concat(i.call(arguments)));
+ }
+
+ E.prototype = a.prototype; const b = new E(); const
+ g = a.apply(b, e.concat(i.call(arguments))); return new Object(g) === g ? g : b;
+ };
+ };
+
+ b.bindAll = function (a) {
+ let c = i.call(arguments, 1); c.length == 0 && (c = b.functions(a)); j(c, c => {
+ a[c] = b.bind(a[c], a);
+ }); return a;
+ };
+
+ b.memoize = function (a, c) {
+ const d = {}; c || (c = b.identity); return function () {
+ const b = Reflect.apply(c, this, arguments); return m.call(d, b) ? d[b] : d[b] = Reflect.apply(a, this, arguments);
+ };
+ };
+
+ b.delay =
+function (a, b) {
+ const d = i.call(arguments, 2); return setTimeout(() => {
+ return a.apply(a, d);
+ }, b);
+};
+
+ b.defer = function (a) {
+ return b.delay.apply(b, [a, 1].concat(i.call(arguments, 1)));
+ };
+
+ b.throttle = function (a, c) {
+ let d; let e; let f; let g; let h; const i = b.debounce(() => {
+ h = g = false;
+ }, c); return function () {
+ d = this; e = arguments; let b; f || (f = setTimeout(() => {
+ f = null; h && a.apply(d, e); i();
+ }, c)); g ? h = true : a.apply(d, e); i(); g = true;
+ };
+ };
+
+ b.debounce = function (a, b) {
+ let d; return function () {
+ const e = this; const f = arguments; clearTimeout(d); d = setTimeout(() => {
+ d =
+null; a.apply(e, f);
+ }, b);
+ };
+ };
+
+ b.once = function (a) {
+ let b = false; let d; return function () {
+ if (b) {
+ return d;
+ }
+
+ b = true; return d = Reflect.apply(a, this, arguments);
+ };
+ };
+
+ b.wrap = function (a, b) {
+ return function () {
+ const d = [a].concat(i.call(arguments)); return b.apply(this, d);
+ };
+ };
+
+ b.compose = function () {
+ const a = i.call(arguments); return function () {
+ for (var b = i.call(arguments), d = a.length - 1; d >= 0; d--) {
+ b = [a[d].apply(this, b)];
+ }
+
+ return b[0];
+ };
+ };
+
+ b.after = function (a, b) {
+ return a <= 0 ? b() : function () {
+ if (--a < 1) {
+ return Reflect.apply(b, this, arguments);
+ }
+ };
+ };
+
+ b.keys = H || function (a) {
+ if (a !==
+new Object(a)) {
+ throw new TypeError('Invalid object');
+ }
+
+ const b = []; let d; for (d in a) {
+ m.call(a, d) && (b[b.length] = d);
+ }
+
+ return b;
+ };
+
+ b.values = function (a) {
+ return b.map(a, b.identity);
+ };
+
+ b.functions = b.methods = function (a) {
+ const c = []; let d; for (d in a) {
+ b.isFunction(a[d]) && c.push(d);
+ }
+
+ return c.sort();
+ };
+
+ b.extend = function (a) {
+ j(i.call(arguments, 1), b => {
+ for (const d in b) {
+ b[d] !== void 0 && (a[d] = b[d]);
+ }
+ }); return a;
+ };
+
+ b.defaults = function (a) {
+ j(i.call(arguments, 1), b => {
+ for (const d in b) {
+ a[d] == null && (a[d] = b[d]);
+ }
+ }); return a;
+ };
+
+ b.clone = function (a) {
+ return !b.isObject(a) ?
+ a : (b.isArray(a) ? a.slice() : b.extend({}, a));
+ };
+
+ b.tap = function (a, b) {
+ b(a); return a;
+ };
+
+ b.isEqual = function (a, b) {
+ return r(a, b, []);
+ };
+
+ b.isEmpty = function (a) {
+ if (b.isArray(a) || b.isString(a)) {
+ return a.length === 0;
+ }
+
+ for (const c in a) {
+ if (m.call(a, c)) {
+ return false;
+ }
+ }
+
+ return true;
+ };
+
+ b.isElement = function (a) {
+ return Boolean(a && a.nodeType == 1);
+ };
+
+ b.isArray = p || function (a) {
+ return l.call(a) == '[object Array]';
+ };
+
+ b.isObject = function (a) {
+ return a === new Object(a);
+ };
+
+ b.isArguments = l.call(arguments) == '[object Arguments]' ? function (a) {
+ return l.call(a) == '[object Arguments]';
+ } :
+ function (a) {
+ return !(!a || !m.call(a, 'callee'));
+ };
+
+ b.isFunction = function (a) {
+ return l.call(a) == '[object Function]';
+ };
+
+ b.isString = function (a) {
+ return l.call(a) == '[object String]';
+ };
+
+ b.isNumber = function (a) {
+ return l.call(a) == '[object Number]';
+ };
+
+ b.isNaN = function (a) {
+ return a !== a;
+ };
+
+ b.isBoolean = function (a) {
+ return a === true || a === false || l.call(a) == '[object Boolean]';
+ };
+
+ b.isDate = function (a) {
+ return l.call(a) == '[object Date]';
+ };
+
+ b.isRegExp = function (a) {
+ return l.call(a) == '[object RegExp]';
+ };
+
+ b.isNull = function (a) {
+ return a === null;
+ };
+
+ b.isUndefined = function (a) {
+ return a === void 0;
+ };
+
+ b.noConflict = function () {
+ s._ = F; return this;
+ };
+
+ b.identity = function (a) {
+ return a;
+ };
+
+ b.times = function (a, b, d) {
+ for (let e = 0; e < a; e++) {
+ b.call(d, e);
+ }
+ };
+
+ b.escape = function (a) {
+ return (String(a)).replace(/&/g, '&').replace(//g, '>').replace(/"/g, '"').replace(/'/g, ''').replace(/\//g, '/');
+ };
+
+ b.mixin = function (a) {
+ j(b.functions(a), c => {
+ I(c, b[c] = a[c]);
+ });
+ };
+
+ let J = 0; b.uniqueId = function (a) {
+ const b = J++; return a ? a + b : b;
+ };
+
+ b.templateSettings = {evaluate: /<%([\s\S]+?)%>/g,
+ interpolate: /<%=([\s\S]+?)%>/g, escape: /<%-([\s\S]+?)%>/g}; b.template = function (a, c) {
+ var d = b.templateSettings; var d = 'var __p=[],print=function(){__p.push.apply(__p,arguments);};with(obj||{}){__p.push(\'' + a.replace(/\\/g, '\\\\').replace(/'/g, '\\\'').replace(d.escape, (a, b) => {
+ return '\',_.escape(' + b.replace(/\\'/g, '\'') + '),\'';
+ }).replace(d.interpolate, (a, b) => {
+ return '\',' + b.replace(/\\'/g, '\'') + ',\'';
+ }).replace(d.evaluate || null, (a, b) => {
+ return '\');' + b.replace(/\\'/g, '\'').replace(/[\r\n\t]/g, ' ') + ';__p.push(\'';
+ }).replace(/\r/g,
+ '\\r').replace(/\n/g, '\\n').replace(/\t/g, '\\t') + '\');}return __p.join(\'\');'; const e = new Function('obj', '_', d); return c ? e(c, b) : function (a) {
+ return e(a, b);
+ };
+ };
+
+ var n = function (a) {
+ this._wrapped = a;
+ };
+
+ b.prototype = n.prototype; const u = function (a, c) {
+ return c ? b(a).chain() : a;
+ };
+
+ var I = function (a, c) {
+ n.prototype[a] = function () {
+ const a = i.call(arguments); G.call(a, this._wrapped); return u(c.apply(b, a), this._chain);
+ };
+ };
+
+ b.mixin(b); j('pop,push,reverse,shift,sort,splice,unshift'.split(','), a => {
+ const b = k[a]; n.prototype[a] = function () {
+ b.apply(this._wrapped,
+ arguments); return u(this._wrapped, this._chain);
+ };
+ }); j(['concat', 'join', 'slice'], a => {
+ const b = k[a]; n.prototype[a] = function () {
+ return u(b.apply(this._wrapped, arguments), this._chain);
+ };
+ }); n.prototype.chain = function () {
+ this._chain = true; return this;
+ };
+ n.prototype.value = function () {
+ return this._wrapped;
+ };
+ }).call(this);
});
diff --git a/docs/.vitepress/config/en.mjs b/docs/.vitepress/config/en.mjs
new file mode 100644
index 00000000..67bac6ee
--- /dev/null
+++ b/docs/.vitepress/config/en.mjs
@@ -0,0 +1,99 @@
+import { defineConfig } from "vitepress";
+
+export const en = defineConfig({
+ lang: "en-US",
+ description: "JS port of the Twig templating language",
+
+ themeConfig: {
+ nav: nav(),
+
+ sidebar: {
+ "/guide/": { base: "/guide/", items: sidebarGuide() },
+ "/reference/": {
+ base: "/reference/",
+ items: sidebarReference()
+ }
+ },
+
+ editLink: {
+ pattern:
+ "https://github.com/twigjs/twig.js/edit/master/docs/:path",
+ text: "Edit this page on GitHub"
+ },
+
+ outline: {
+ level: "deep"
+ },
+
+ footer: {
+ message: "Docs released under the MIT License.",
+ copyright: `Copyright © ${new Date().getFullYear()} twig.js`
+ }
+ }
+});
+
+function nav() {
+ return [
+ {
+ text: "Guide",
+ link: "/guide/what-is-it",
+ activeMatch: "/guide/"
+ },
+ {
+ text: "Reference",
+ link: "/reference/compiling-templates",
+ activeMatch: "/reference/"
+ },
+ {
+ text: "1.7.1",
+ items: [
+ {
+ text: "Release Notes",
+ link:
+ "https://github.com/twigjs/twig.js/releases/tag/v1.17.1",
+ target: "_blank"
+ },
+ {
+ text: "Contributing",
+ link:
+ "https://github.com/twigjs/twig.js/blob/master/.github/contributing.md",
+ target: "_blank"
+ }
+ ]
+ }
+ ];
+}
+
+function sidebarGuide() {
+ return [
+ {
+ text: "introduce",
+ items: [
+ { text: "What is it?", link: "what-is-it" },
+ { text: "Getting Started", link: "getting-started" },
+ { text: "Using twig.js", link: "using-twigjs" },
+ { text: "Available Extensions", link: "available-extensions" }
+ ]
+ }
+ ];
+}
+
+function sidebarReference() {
+ return [
+ {
+ text: "Reference",
+ items: [
+ { text: "Compiling Templates", link: "compiling-templates" },
+ { text: "Extending twig.js", link: "extending-twigjs" },
+ {
+ text: "Extending twig.js With Custom Tags",
+ link: "extending-twigjs-with-custom-tags"
+ },
+ {
+ text: "Implementation Notes",
+ link: "implementation-notes"
+ }
+ ]
+ }
+ ];
+}
diff --git a/docs/.vitepress/config/index.mjs b/docs/.vitepress/config/index.mjs
new file mode 100644
index 00000000..1e7b12e4
--- /dev/null
+++ b/docs/.vitepress/config/index.mjs
@@ -0,0 +1,20 @@
+import { defineConfig } from "vitepress";
+import { shared } from "./shared.mjs";
+import { zh } from "./zh.mjs";
+import { en } from "./en.mjs";
+
+
+
+const config = {
+ ...shared,
+
+ locales: {
+ root: { label: "English", ...en },
+ zh: { label: "简体中文", ...zh },
+ },
+}
+
+
+
+
+export default defineConfig(config);
diff --git a/docs/.vitepress/config/shared.mjs b/docs/.vitepress/config/shared.mjs
new file mode 100644
index 00000000..5945b9a1
--- /dev/null
+++ b/docs/.vitepress/config/shared.mjs
@@ -0,0 +1,50 @@
+import { defineConfig } from "vitepress";
+
+import { search as zhSearch } from "./zh.mjs";
+
+export const shared = defineConfig({
+ title: "twig.js",
+
+ base:'/twig.js/',
+
+ rewrites: {
+ "en/:rest*": ":rest*",
+ },
+
+ lastUpdated: true,
+ cleanUrls: true,
+ metaChunk: true,
+
+ markdown: {
+ image: {
+ lazyLoading: true,
+ },
+ lineNumbers: true,
+ container: {
+ tipLabel: "提示",
+ warningLabel: "警告",
+ dangerLabel: "危险",
+ infoLabel: "信息",
+ detailsLabel: "详细信息",
+ },
+ },
+
+ head: [["link", { rel: "icon", href: "favicon.svg", type: "image/svg+xml" }]],
+
+ themeConfig: {
+ logo: { src: "/logo-mini.svg", width: 24, height: 24 },
+
+ socialLinks: [
+ { icon: "github", link: "https://github.com/twigjs/twig.js" },
+ ],
+
+ search: {
+ provider: "local",
+ options: {
+ locales: {
+ ...zhSearch,
+ },
+ },
+ },
+ },
+});
diff --git a/docs/.vitepress/config/zh.mjs b/docs/.vitepress/config/zh.mjs
new file mode 100644
index 00000000..999a5a91
--- /dev/null
+++ b/docs/.vitepress/config/zh.mjs
@@ -0,0 +1,160 @@
+import { defineConfig } from "vitepress";
+
+export const zh = defineConfig({
+ lang: "zh-Hans",
+ description: "Twig模板语言的JS移植",
+
+ themeConfig: {
+ nav: nav(),
+
+ sidebar: {
+ "/zh/guide/": { base: "/zh/guide/", items: sidebarGuide() },
+ "/zh/reference/": {
+ base: "/zh/reference/",
+ items: sidebarReference()
+ }
+ },
+
+ editLink: {
+ pattern: "https://github.com/twigjs/twig.js/edit/master/docs/:path",
+ text: "在 GitHub 上编辑此页面"
+ },
+
+ footer: {
+ message: "该文档 基于 MIT 许可发布",
+ copyright: `版权所有 © ${new Date().getFullYear()} twig.js`
+ },
+
+ docFooter: {
+ prev: "上一页",
+ next: "下一页"
+ },
+
+ outline: {
+ label: "页面导航",
+ level: "deep"
+ },
+
+ lastUpdated: {
+ text: "最后更新于",
+ formatOptions: {
+ dateStyle: "short",
+ timeStyle: "medium"
+ }
+ },
+
+ langMenuLabel: "多语言",
+ returnToTopLabel: "回到顶部",
+ sidebarMenuLabel: "菜单",
+ darkModeSwitchLabel: "主题",
+ lightModeSwitchTitle: "切换到浅色模式",
+ darkModeSwitchTitle: "切换到深色模式",
+
+ notFound: {
+ title: "找不到页面",
+ quote: "如果你不改变方向,并且一直走下去,你最终会到达现在前进的地方",
+ linkLabel: "回到首页",
+ linkText: "带我回家"
+ }
+ }
+});
+
+function nav() {
+ return [
+ {
+ text: "指南",
+ link: "/zh/guide/what-is-it",
+ activeMatch: "/zh/guide/"
+ },
+ {
+ text: "参考",
+ link: "/zh/reference/compiling-templates",
+ activeMatch: "/zh/reference/"
+ },
+ {
+ text: "1.7.1",
+ items: [
+ {
+ text: "变更日志",
+ link: "https://github.com/twigjs/twig.js/releases/tag/v1.17.1",
+ target: "_blank"
+ },
+ {
+ text: "贡献指南",
+ link:
+ "https://github.com/twigjs/twig.js/blob/master/.github/contributing.md",
+ target: "_blank"
+ }
+ ]
+ }
+ ];
+}
+
+function sidebarGuide() {
+ return [
+ {
+ text: "介绍",
+ items: [
+ { text: "是什么?", link: "what-is-it" },
+ { text: "快速开始", link: "getting-started" }
+ ]
+ }
+ ];
+}
+
+function sidebarReference() {
+ return [
+ {
+ text: "参考",
+ items: [{ text: "编译模板", link: "compiling-templates" }]
+ }
+ ];
+}
+
+export const search = {
+ zh: {
+ placeholder: "搜索文档",
+ translations: {
+ button: {
+ buttonText: "搜索文档",
+ buttonAriaLabel: "搜索文档"
+ },
+ modal: {
+ searchBox: {
+ resetButtonTitle: "清除查询条件",
+ resetButtonAriaLabel: "清除查询条件",
+ cancelButtonText: "取消",
+ cancelButtonAriaLabel: "取消"
+ },
+ startScreen: {
+ recentSearchesTitle: "搜索历史",
+ noRecentSearchesText: "没有搜索历史",
+ saveRecentSearchButtonTitle: "保存至搜索历史",
+ removeRecentSearchButtonTitle: "从搜索历史中移除",
+ favoriteSearchesTitle: "收藏",
+ removeFavoriteSearchButtonTitle: "从收藏中移除"
+ },
+ errorScreen: {
+ titleText: "无法获取结果",
+ helpText: "你可能需要检查你的网络连接"
+ },
+ footer: {
+ selectText: "选择",
+ navigateText: "切换",
+ closeText: "关闭",
+ searchByText: "搜索提供者"
+ },
+
+ noResultsText: "无法找到相关结果",
+ resetButtonTitle: "重置搜索",
+ displayDetails: "显示详情视图",
+ noResultsScreen: {
+ noResultsText: "无法找到相关结果",
+ suggestedQueryText: "你可以尝试查询",
+ reportMissingResultsText: "你认为该查询应该有结果?",
+ reportMissingResultsLinkText: "点击反馈"
+ }
+ }
+ }
+ }
+};
diff --git a/docs/.vitepress/theme/custom.css b/docs/.vitepress/theme/custom.css
new file mode 100644
index 00000000..efce2c66
--- /dev/null
+++ b/docs/.vitepress/theme/custom.css
@@ -0,0 +1,110 @@
+:root {
+ --color-1: #adc433;
+ --color-2: #60932a;
+
+ --vp-code-bg: #f9f2f4;
+ --vp-code-color: #c7254e;
+
+ --vp-home-hero-name-color: transparent;
+ --vp-home-hero-name-background: linear-gradient(
+ 120deg,
+ var(--color-1) 30%,
+ var(--color-2)
+ );
+
+ --vp-home-hero-image-background-image: linear-gradient(
+ 135deg,
+ var(--color-1) 10%,
+ var(--color-2) 100%
+ );
+ --vp-home-hero-image-filter: blur(150px);
+
+ --vp-c-brand-1: var(--color-1);
+ --vp-button-brand-bg: var(--color-1);
+ --vp-button-brand-hover-bg: var(--color-2);
+ --vp-c-brand-2: var(--color-2);
+
+ --vp-sidebar-bg-color: #fff;
+}
+
+.dark {
+ --vp-sidebar-bg-color: #1e1e20;
+}
+
+.VPLink.link.VPNavBarMenuLink {
+ background: linear-gradient(
+ to right,
+ var(--vp-c-brand-1),
+ var(--vp-c-brand-1)
+ )
+ no-repeat right bottom;
+ background-size: 0 2px;
+ transition: background-size 0.3s;
+
+ &:hover {
+ background-position-x: left;
+ background-size: 100% 2px;
+ }
+
+ &.active {
+ background: linear-gradient(to right, var(--vp-c-brand), var(--vp-c-brand))
+ no-repeat right bottom;
+ background-size: 100% 2px;
+ }
+}
+
+*::-webkit-scrollbar {
+ width: 5px;
+ height: 1px;
+}
+
+*::-webkit-scrollbar-thumb {
+ background-color: transparent;
+ border-radius: 3px;
+}
+
+*:hover::-webkit-scrollbar-thumb {
+ background-color: #6a708028;
+ border-radius: 3px;
+}
+
+*::-webkit-scrollbar-thumb:hover {
+ background-color: #6a708028;
+ border-radius: 3px;
+}
+
+*::-webkit-scrollbar-track {
+ border-radius: 5px;
+ background: transparent;
+}
+
+*::-webkit-scrollbar-track:hover {
+ background-color: transparent;
+}
+
+html[lang="zh-Hans"] {
+ --vp-code-copy-copied-text-content: "已复制";
+}
+
+html[lang="en-US"] {
+ --vp-code-copy-copied-text-content: "Copied!";
+}
+
+.vp-doc {
+ .demo-preview [class*="language-"] code {
+ color: unset;
+ padding: 0;
+ }
+
+ a {
+ display: inline-block;
+ }
+}
+
+.medium-zoom-overlay {
+ z-index: 30;
+}
+
+.medium-zoom-image--opened {
+ z-index: 31;
+}
diff --git a/docs/.vitepress/theme/index.mjs b/docs/.vitepress/theme/index.mjs
new file mode 100644
index 00000000..c385948a
--- /dev/null
+++ b/docs/.vitepress/theme/index.mjs
@@ -0,0 +1,16 @@
+// .vitepress/theme/index.js
+import DefaultTheme from "vitepress/theme";
+import { watch } from "vue";
+import { useRoute } from "vitepress";
+
+import "./custom.css";
+
+export default {
+ ...DefaultTheme,
+ setup() {
+ const route = useRoute();
+ watch(
+ () => route.path,
+ );
+ },
+};
diff --git a/docs/docco.css b/docs/docco.css
deleted file mode 100644
index f690a079..00000000
--- a/docs/docco.css
+++ /dev/null
@@ -1,500 +0,0 @@
-/*--------------------- Typography ----------------------------*/
-
-@font-face {
- font-family: 'aller-light';
- src: url('public/fonts/aller-light.eot');
- src: url('public/fonts/aller-light.eot?#iefix') format('embedded-opentype'),
- url('public/fonts/aller-light.woff') format('woff'),
- url('public/fonts/aller-light.ttf') format('truetype');
- font-weight: normal;
- font-style: normal;
-}
-
-@font-face {
- font-family: 'aller-bold';
- src: url('public/fonts/aller-bold.eot');
- src: url('public/fonts/aller-bold.eot?#iefix') format('embedded-opentype'),
- url('public/fonts/aller-bold.woff') format('woff'),
- url('public/fonts/aller-bold.ttf') format('truetype');
- font-weight: normal;
- font-style: normal;
-}
-
-@font-face {
- font-family: 'novecento-bold';
- src: url('public/fonts/novecento-bold.eot');
- src: url('public/fonts/novecento-bold.eot?#iefix') format('embedded-opentype'),
- url('public/fonts/novecento-bold.woff') format('woff'),
- url('public/fonts/novecento-bold.ttf') format('truetype');
- font-weight: normal;
- font-style: normal;
-}
-
-/*--------------------- Layout ----------------------------*/
-html { height: 100%; }
-body {
- font-family: "aller-light";
- font-size: 14px;
- line-height: 18px;
- color: #30404f;
- margin: 0; padding: 0;
- height:100%;
-}
-#container { min-height: 100%; }
-
-a {
- color: #000;
-}
-
-b, strong {
- font-weight: normal;
- font-family: "aller-bold";
-}
-
-p, ul, ol {
- margin: 15px 0 0px;
-}
-
-h1, h2, h3, h4, h5, h6 {
- color: #112233;
- line-height: 1em;
- font-weight: normal;
- font-family: "novecento-bold";
- text-transform: uppercase;
- margin: 30px 0 15px 0;
-}
-
-h1 {
- margin-top: 40px;
-}
-
-hr {
- border: 0;
- background: 1px solid #ddd;
- height: 1px;
- margin: 20px 0;
-}
-
-pre, tt, code {
- font-size: 12px; line-height: 16px;
- font-family: Menlo, Monaco, Consolas, "Lucida Console", monospace;
- margin: 0; padding: 0;
-}
- .annotation pre {
- display: block;
- margin: 0;
- padding: 7px 10px;
- background: #fcfcfc;
- -moz-box-shadow: inset 0 0 10px rgba(0,0,0,0.1);
- -webkit-box-shadow: inset 0 0 10px rgba(0,0,0,0.1);
- box-shadow: inset 0 0 10px rgba(0,0,0,0.1);
- overflow-x: auto;
- }
- .annotation pre code {
- border: 0;
- padding: 0;
- background: transparent;
- }
-
-
-blockquote {
- border-left: 5px solid #ccc;
- margin: 0;
- padding: 1px 0 1px 1em;
-}
- .sections blockquote p {
- font-family: Menlo, Consolas, Monaco, monospace;
- font-size: 12px; line-height: 16px;
- color: #999;
- margin: 10px 0 0;
- white-space: pre-wrap;
- }
-
-ul.sections {
- list-style: none;
- padding:0 0 5px 0;;
- margin:0;
-}
-
-/*
- Force border-box so that % widths fit the parent
- container without overlap because of margin/padding.
-
- More Info : http://www.quirksmode.org/css/box.html
-*/
-ul.sections > li > div {
- -moz-box-sizing: border-box; /* firefox */
- -ms-box-sizing: border-box; /* ie */
- -webkit-box-sizing: border-box; /* webkit */
- -khtml-box-sizing: border-box; /* konqueror */
- box-sizing: border-box; /* css3 */
-}
-
-
-/*---------------------- Jump Page -----------------------------*/
-#jump_to, #jump_page {
- margin: 0;
- background: white;
- -webkit-box-shadow: 0 0 25px #777; -moz-box-shadow: 0 0 25px #777;
- -webkit-border-bottom-left-radius: 5px; -moz-border-radius-bottomleft: 5px;
- font: 16px Arial;
- cursor: pointer;
- text-align: right;
- list-style: none;
-}
-
-#jump_to a {
- text-decoration: none;
-}
-
-#jump_to a.large {
- display: none;
-}
-#jump_to a.small {
- font-size: 22px;
- font-weight: bold;
- color: #676767;
-}
-
-#jump_to, #jump_wrapper {
- position: fixed;
- right: 0; top: 0;
- padding: 10px 15px;
- margin:0;
-}
-
-#jump_wrapper {
- display: none;
- padding:0;
-}
-
-#jump_to:hover #jump_wrapper {
- display: block;
-}
-
-#jump_page {
- padding: 5px 0 3px;
- margin: 0 0 25px 25px;
-}
-
-#jump_page .source {
- display: block;
- padding: 15px;
- text-decoration: none;
- border-top: 1px solid #eee;
-}
-
-#jump_page .source:hover {
- background: #f5f5ff;
-}
-
-#jump_page .source:first-child {
-}
-
-/*---------------------- Low resolutions (> 320px) ---------------------*/
-@media only screen and (min-width: 320px) {
- .pilwrap { display: none; }
-
- ul.sections > li > div {
- display: block;
- padding:5px 10px 0 10px;
- }
-
- ul.sections > li > div.annotation ul, ul.sections > li > div.annotation ol {
- padding-left: 30px;
- }
-
- ul.sections > li > div.content {
- background: #f5f5ff;
- overflow-x:auto;
- -webkit-box-shadow: inset 0 0 5px #e5e5ee;
- box-shadow: inset 0 0 5px #e5e5ee;
- border: 1px solid #dedede;
- margin:5px 10px 5px 10px;
- padding-bottom: 5px;
- }
-
- ul.sections > li > div.annotation pre {
- margin: 7px 0 7px;
- padding-left: 15px;
- }
-
- ul.sections > li > div.annotation p tt, .annotation code {
- background: #f8f8ff;
- border: 1px solid #dedede;
- font-size: 12px;
- padding: 0 0.2em;
- }
-}
-
-/*---------------------- (> 481px) ---------------------*/
-@media only screen and (min-width: 481px) {
- #container {
- position: relative;
- }
- body {
- background-color: #F5F5FF;
- font-size: 15px;
- line-height: 21px;
- }
- pre, tt, code {
- line-height: 18px;
- }
- p, ul, ol {
- margin: 0 0 15px;
- }
-
-
- #jump_to {
- padding: 5px 10px;
- }
- #jump_wrapper {
- padding: 0;
- }
- #jump_to, #jump_page {
- font: 10px Arial;
- text-transform: uppercase;
- }
- #jump_page .source {
- padding: 5px 10px;
- }
- #jump_to a.large {
- display: inline-block;
- }
- #jump_to a.small {
- display: none;
- }
-
-
-
- #background {
- position: absolute;
- top: 0; bottom: 0;
- width: 350px;
- background: #fff;
- border-right: 1px solid #e5e5ee;
- z-index: -1;
- }
-
- ul.sections > li > div.annotation ul, ul.sections > li > div.annotation ol {
- padding-left: 40px;
- }
-
- ul.sections > li {
- white-space: nowrap;
- }
-
- ul.sections > li > div {
- display: inline-block;
- }
-
- ul.sections > li > div.annotation {
- max-width: 350px;
- min-width: 350px;
- min-height: 5px;
- padding: 13px;
- overflow-x: hidden;
- white-space: normal;
- vertical-align: top;
- text-align: left;
- }
- ul.sections > li > div.annotation pre {
- margin: 15px 0 15px;
- padding-left: 15px;
- }
-
- ul.sections > li > div.content {
- padding: 13px;
- vertical-align: top;
- background: #f5f5ff;
- border: none;
- -webkit-box-shadow: none;
- box-shadow: none;
- }
-
- .pilwrap {
- position: relative;
- display: inline;
- }
-
- .pilcrow {
- font: 12px Arial;
- text-decoration: none;
- color: #454545;
- position: absolute;
- top: 3px; left: -20px;
- padding: 1px 2px;
- opacity: 0;
- -webkit-transition: opacity 0.2s linear;
- }
- .for-h1 .pilcrow {
- top: 47px;
- }
- .for-h2 .pilcrow, .for-h3 .pilcrow, .for-h4 .pilcrow {
- top: 35px;
- }
-
- ul.sections > li > div.annotation:hover .pilcrow {
- opacity: 1;
- }
-}
-
-/*---------------------- (> 1025px) ---------------------*/
-@media only screen and (min-width: 1025px) {
-
- body {
- font-size: 16px;
- line-height: 24px;
- }
-
- #background {
- width: 525px;
- }
- ul.sections > li > div.annotation {
- max-width: 525px;
- min-width: 525px;
- padding: 10px 25px 1px 50px;
- }
- ul.sections > li > div.content {
- padding: 9px 15px 16px 25px;
- }
-}
-
-/*---------------------- Syntax Highlighting -----------------------------*/
-
-td.linenos { background-color: #f0f0f0; padding-right: 10px; }
-span.lineno { background-color: #f0f0f0; padding: 0 5px 0 5px; }
-/*
-
-github.com style (c) Vasily Polovnyov
-
-*/
-
-pre code {
- display: block; padding: 0.5em;
- color: #000;
- background: #f8f8ff
-}
-
-pre .comment,
-pre .template_comment,
-pre .diff .header,
-pre .javadoc {
- color: #408080;
- font-style: italic
-}
-
-pre .keyword,
-pre .assignment,
-pre .literal,
-pre .css .rule .keyword,
-pre .winutils,
-pre .javascript .title,
-pre .lisp .title,
-pre .subst {
- color: #954121;
- /*font-weight: bold*/
-}
-
-pre .number,
-pre .hexcolor {
- color: #40a070
-}
-
-pre .string,
-pre .tag .value,
-pre .phpdoc,
-pre .tex .formula {
- color: #219161;
-}
-
-pre .title,
-pre .id {
- color: #19469D;
-}
-pre .params {
- color: #00F;
-}
-
-pre .javascript .title,
-pre .lisp .title,
-pre .subst {
- font-weight: normal
-}
-
-pre .class .title,
-pre .haskell .label,
-pre .tex .command {
- color: #458;
- font-weight: bold
-}
-
-pre .tag,
-pre .tag .title,
-pre .rules .property,
-pre .django .tag .keyword {
- color: #000080;
- font-weight: normal
-}
-
-pre .attribute,
-pre .variable,
-pre .instancevar,
-pre .lisp .body {
- color: #008080
-}
-
-pre .regexp {
- color: #B68
-}
-
-pre .class {
- color: #458;
- font-weight: bold
-}
-
-pre .symbol,
-pre .ruby .symbol .string,
-pre .ruby .symbol .keyword,
-pre .ruby .symbol .keymethods,
-pre .lisp .keyword,
-pre .tex .special,
-pre .input_number {
- color: #990073
-}
-
-pre .builtin,
-pre .constructor,
-pre .built_in,
-pre .lisp .title {
- color: #0086b3
-}
-
-pre .preprocessor,
-pre .pi,
-pre .doctype,
-pre .shebang,
-pre .cdata {
- color: #999;
- font-weight: bold
-}
-
-pre .deletion {
- background: #fdd
-}
-
-pre .addition {
- background: #dfd
-}
-
-pre .diff .change {
- background: #0086b3
-}
-
-pre .chunk {
- color: #aaa
-}
-
-pre .tex .formula {
- opacity: 0.5;
-}
diff --git a/docs/en/guide/available-extensions.md b/docs/en/guide/available-extensions.md
new file mode 100644
index 00000000..19a3692b
--- /dev/null
+++ b/docs/en/guide/available-extensions.md
@@ -0,0 +1,9 @@
+# Available Extensions
+
+## Markdown Tag
+
+Compile markdown right in your templates with `{% markdown %}…{% endmarkdown %}` or `{% markdown 'path/to/file.md' %}{% endmarkdown %}` syntax. Uses [marked](https://github.com/chjj/marked) compiler, works well with [gulp-twig](https://github.com/zimmen/gulp-twig), provides typescript definitions, thoroughly tested. See [readme](https://github.com/ianbytchek/twig-js-markdown) for more details.
+
+
+Source: [ianbytchek/twig-js-markdown](https://github.com/ianbytchek/twig-js-markdown)
+Npm: [twig-markdown](https://www.npmjs.com/package/twig-markdown)
\ No newline at end of file
diff --git a/docs/en/guide/getting-started.md b/docs/en/guide/getting-started.md
new file mode 100644
index 00000000..d909bf54
--- /dev/null
+++ b/docs/en/guide/getting-started.md
@@ -0,0 +1,32 @@
+# Getting Started
+
+## Installation
+
+You can get Twig.js by any of the following methods:
+
+### Git:
+
+
+
+1. Clone the repository
+
+`git clone git://github.com/justjohn/twig.js.git`
+
+2. Download an archive of the latest as a [zip](https://github.com/justjohn/twig.js/zipball/master) or [tgz](https://github.com/justjohn/twig.js/tarball/master)
+
+The files `twig.js` and `twig.min.js` may not be up-to-date (they will be rebuilt when releasing a new version). Run `make` (or `make -B` to force building) to create these files.
+
+### NPM:
+
+```bash
+npm install --save-dev twig
+```
+
+### Yarn:
+
+```bash
+yarn add --dev twig
+```
+
+
+
diff --git a/docs/en/guide/using-twigjs.md b/docs/en/guide/using-twigjs.md
new file mode 100644
index 00000000..2c26ee70
--- /dev/null
+++ b/docs/en/guide/using-twigjs.md
@@ -0,0 +1,185 @@
+# Basic Usage
+
+
+## Node Usage
+
+
+
+### Usage without Express
+
+If you don't want to use Express, you can render a template with the following method:
+
+```js
+Twig.renderFile("./path/to/someFile.twig", { foo: "bar" }, (err, html) => {
+ html; // compiled string
+});
+```
+
+### Usage with Express
+
+Twig.js is compatible with Express 2 and 3 and can be setup with the following code:
+
+#### Express 2
+
+`app.js`
+
+```js
+var twig = require("twig"),
+ app = require("express").createServer();
+
+app.configure(function() {
+ app.set("view engine", "twig");
+ app.set("view options", { layout: false });
+
+ // This section is optional and used to configure twig.
+ app.set("twig options", {
+ strict_variables: false
+ });
+});
+
+app.register("twig", twig);
+
+app.get("/", function(req, res) {
+ res.render("index", {
+ message: "Hello World"
+ });
+});
+
+app.listen(9999);
+```
+
+#### Express 3
+
+`app.js`
+
+```js
+var express = require("express"),
+ app = express();
+
+app.configure(function() {
+ app.set("views", __dirname + "/views");
+ app.set("view engine", "twig");
+
+ // This section is optional and can be used to configure twig.
+ app.set("twig options", {
+ strict_variables: false
+ });
+});
+
+app.get("/", function(req, res) {
+ res.render("index", {
+ message: "Hello World"
+ });
+});
+
+app.listen(9999);
+```
+
+#### views/index.twig
+
+```twig
+Message of the moment: {{ message }}
+```
+
+## Browser Usage
+From the browser, Twig.js can be used with inline templates or templates loaded from AJAX.
+
+### Inline Templates
+
+```js
+var template = Twig.twig({
+ id: "list", // id is optional, but useful for referencing the template later
+ data: "{% for value in list %}{{ value }}, {% endfor %}"
+});
+
+var output = template.render({
+ list: ["one", "two", "three"]
+});
+
+// output = "one, two, three, "
+```
+If an id is provided when you create a template, you can reference the template anywhere else in your application by using the ref parameter:
+
+```js
+// Elsewhere in your application
+var output = Twig.twig({ ref: "list" }).render({
+ list: ["a", "b", "c"]
+});
+
+// output = "a, b, c, "
+```
+
+### AJAX Templates
+
+Templates can also be loaded via ajax by setting the href parameter in the twig() options.
+
+
+__templates/posts.twig__
+
+```twig
+{% for post in posts %}
+
+
+ {{ post.body }}
+
+{% endfor %}
+```
+
+__app.js__
+
+```js
+var template = twig({
+ id: "posts",
+ href: "templates/posts.twig",
+ // for this example we'll block until the template is loaded
+ async: false
+
+ // The default is to load asynchronously, and call the load function
+ // when the template is loaded.
+
+ // load: function(template) { }
+});
+```
+
+Once you've loaded templates, you can access them via their id and render them when you have data.
+
+
+
+```js
+posts = { ... }; // data from somewhere like an AJAX callback
+
+// render the template
+var postsHTML = twig({ ref: "posts" }).render(posts);
+
+// Display the rendered template
+document.getElementById("posts").innerHTML = postsHTML;
+```
+
+
+
+### Namespaces
+
+```js
+var template = Twig.twig({
+ data: 'your-template',
+ namespaces: { 'my-project': 'path/to/views/folder/' }
+}).render();
+```
+
+When referencing another template, instead of using the relative path you can use the namespaces that were previously defined.
+
+
+Ex:
+
+```twig
+{# your-template.twig #}
+{% extends "my-project::template.twig" %}
+```
+
+The "my-project::" will now point to "path/to/views/folder/". It works with the `@` sign too:
+
+```twig
+{% include '@my-project/template.twig' %}
+```
\ No newline at end of file
diff --git a/docs/en/guide/what-is-it.md b/docs/en/guide/what-is-it.md
new file mode 100644
index 00000000..b93e775b
--- /dev/null
+++ b/docs/en/guide/what-is-it.md
@@ -0,0 +1,17 @@
+# What is Twig.js?
+
+Twig.js is a pure JavaScript implementation of the [Twig](https://twig.symfony.com/) PHP templating language
+
+The goal is to provide a library that is compatible with both browsers and server side containers such as node.js.
+
+Twig.js is currently a work in progress and supports a limited subset of the Twig templating language (with more coming).
+
+## NEWS
+
+- 6/10/2016 - Twig is now available as a template engine in [Keystone.js](http://keystonejs.com/)
+
+## Implementation Details
+
+See the [implementation details](/reference/implementation-notes) page for a list of supported filters/functions/tags/tests.
+
+
diff --git a/docs/en/index.md b/docs/en/index.md
new file mode 100644
index 00000000..019f693d
--- /dev/null
+++ b/docs/en/index.md
@@ -0,0 +1,31 @@
+---
+# https://vitepress.dev/reference/default-theme-home-page
+layout: home
+
+hero:
+ image:
+ src: /logo-large.svg
+ alt: Twig.js
+ name: Twig.js
+ text: JS port of the Twig templating language
+ tagline: The goal is to provide a library that is compatible with both browsers and server side JavaScript environments such as node.js.
+
+ actions:
+ - theme: brand
+ text: What is Twig.js?
+ link: /guide/what-is-it
+ - theme: alt
+ text: Quickstart
+ link: /guide/getting-started
+ - theme: alt
+ text: GitHub
+ link: https://github.com/twigjs/twig.js
+
+features:
+ - icon: ✨
+ title: Continuous support
+ details: Twig.js is currently a work in progress and supports a limited subset of the Twig templating language (with more coming).
+ - icon: ✨
+ title: No additional learning costs
+ details: As long as you know the Twig template syntax, you can quickly get started
+---
diff --git a/docs/en/reference/compiling-templates.md b/docs/en/reference/compiling-templates.md
new file mode 100644
index 00000000..f19a9702
--- /dev/null
+++ b/docs/en/reference/compiling-templates.md
@@ -0,0 +1,65 @@
+# Compiling Templates
+
+## CLI
+
+Twig.js templates can be compiled into output JS files through the twigjs command. Currently the output is a tokenized form of the template, but in future the template will be transformed into a JavaScript file.
+
+The syntax for the twigjs command is:
+
+```bash
+twigjs [options] input.twig | directory ...
+_______________________________________________________________________________
+
+twigjs can take a list of files and/or a directories as input. If a file is
+provided, it is compiled, if a directory is provided, all files matching *.twig
+in the directory are compiled. The pattern can be overridden with --pattern
+
+--help Print this help message.
+
+--output ... What directory should twigjs output to. By default twigjs will
+ write to the same directory as the input file.
+
+--module ... Should the output be written in module format. Supported formats:
+ node: Node.js / CommonJS 1.1 modules
+ amd: RequireJS / Asynchronous modules (requires --twig)
+ cjs2: CommonJS 2.0 draft8 modules (requires --twig)
+
+--twig ... Used with --module. The location relative to the output directory
+ of twig.js. (used for module dependency resolution).
+
+--pattern ... If parsing a directory of files, what files should be compiled.
+ Defaults to *.twig.
+```
+
+## Common use cases
+
+### Create templates to include in a web site
+
+To transform a directory of twig files into a directory of js files to include using script tags, you can use the following command:
+
+```bash
+twigjs --output templates/ src/
+```
+
+This will take all `*.twig` files in the `src/` directory and it's subdirectories and output them into the `templates` directory following the same directory structure and adding `.js` to the filenames.
+
+See the `demos/compiler/basic` demo for a usage example.
+
+### Create templates that can be required with Node.js
+
+To create JS template files that can be included in Node.js with `require` you can specify the output module format with the `--module` flag.
+
+```bash
+twigjs --module node --output templates/ src/
+```
+
+This will output JS template files that export the Twig template so you can use it with:
+
+```bash
+var template = require("./templates/block.twig").template;
+
+```
+
+Note that these template are compliant with the CommonJS Modules/1.1 spec, so they can be used in any environment which support such modules. The only requirement is that `require("twig")` resolves to the Twig.js library.
+
+See the `demos/compiler/node` demo for a usage example.
diff --git a/docs/en/reference/extending-twigjs-with-custom-tags.md b/docs/en/reference/extending-twigjs-with-custom-tags.md
new file mode 100644
index 00000000..68c7cc05
--- /dev/null
+++ b/docs/en/reference/extending-twigjs-with-custom-tags.md
@@ -0,0 +1,145 @@
+# Extending twig.js With Custom Tags
+
+Extending twig.js with new tag types is handled differently than filters or functions, since tags require access to the internal twig.js parsers. This means you have to do the extension through the `Twig.extends` function, which allows access to the internal Twig object.
+
+
+```js
+Twig.extend(function(Twig) {
+ // In the context of this functions, Twig new refers to the internal Twig object.
+ // this allows access to functionality that is normally not exposed.
+ // The external Twig object is available as Twig.exports
+
+ ... extend tags here ...
+ Twig.exports.extendTag({...});
+});
+```
+There are two different ways to use tags in twig.js: single tags, or sets of tags (ie. start/end tags).
+
+To see examples of each type, you can take a look at this test: [https://github.com/justjohn/twig.js/blob/master/test/test.extends.js](https://github.com/justjohn/twig.js/blob/master/test/test.extends.js)
+
+---
+The first example of extending twig.js is to create a tag that passes a value from the template to the application.
+
+The syntax we'll use is '{% flag "ajax" %}'
+
+```js
+// place to keep flags
+var flags = {};
+
+// expose the internal Twig object for extension
+Twig.extend(function(Twig) {
+ Twig.exports.extendTag({
+ // unique name for tag type
+ type: "flag",
+ // regex match for tag (flag white-space anything)
+ regex: /^flag\s+(.+)$/,
+ // this is a standalone tag and doesn't require a following tag
+ next: [ ],
+ open: true,
+
+ // runs on matched tokens when the template is loaded. (once per template)
+ compile: function (token) {
+ var expression = token.match[1];
+
+ // Compile the expression. (turns the string into tokens)
+ token.stack = Twig.expression.compile.apply(this, [{
+ type: Twig.expression.type.expression,
+ value: expression
+ }]).stack;
+
+ delete token.match;
+ return token;
+ },
+
+ // Runs when the template is rendered
+ parse: function (token, context, chain) {
+ // parse the tokens into a value with the render context
+ var name = Twig.expression.parse.apply(this, [token.stack, context]),
+ output = '';
+
+ flags[name] = true;
+
+ return {
+ chain: false,
+ output: output
+ };
+ }
+ });
+});
+
+var template = twig({data:"{% flag 'enabled' %}"}).render();
+
+flags.enabled.should.equal(true);
+```
+
+
+Tags can also be created and chained together. The following example shows how you could use {% auth 'level' %}...{% endauth %} tags to limit content to certain users.
+
+```js
+// demo data
+var App = {
+ user: "john",
+ users: {
+ john: {level: "admin"},
+ tom: {level: "user"}
+ }
+};
+
+Twig.extend(function(Twig) {
+ // example of extending a tag type that would
+ // restrict content to the specified "level"
+ Twig.exports.extendTag({
+ // unique name for tag type
+ type: "auth",
+ // regex for matching tag
+ regex: /^auth\s+(.+)$/,
+
+ // what type of tags can follow this one.
+ next: ["endauth"], // match the type of the end tag
+ open: true,
+ compile: function (token) {
+ var expression = token.match[1];
+
+ // turn the string expression into tokens.
+ token.stack = Twig.expression.compile.apply(this, [{
+ type: Twig.expression.type.expression,
+ value: expression
+ }]).stack;
+
+ delete token.match; // cleanup
+ return token;
+ },
+ parse: function (token, context, chain) {
+ var level = Twig.expression.parse.apply(this, [token.stack, context]),
+ output = "";
+
+ // check level of current user
+ if (App.users[App.currentUser].level == level) {
+ output = Twig.parse.apply(this, [token.output, context]);
+ }
+
+ return {
+ chain: chain,
+ output: output
+ };
+ }
+ });
+
+ // a matching end tag type
+ Twig.exports.extendTag({
+ type: "endauth",
+ regex: /^endauth$/,
+ next: [ ],
+ open: false
+ });
+});
+
+var template = twig({data:"Welcome{% auth 'admin' %} ADMIN{% endauth %}!"});
+
+App.currentUser = "john";
+template.render().should.equal("Welcome ADMIN!");
+
+App.currentUser = "tom";
+template.render().should.equal("Welcome!");
+```
+
diff --git a/docs/en/reference/extending-twigjs.md b/docs/en/reference/extending-twigjs.md
new file mode 100644
index 00000000..06b319d5
--- /dev/null
+++ b/docs/en/reference/extending-twigjs.md
@@ -0,0 +1,72 @@
+# Extending twig.js
+
+There are several aspects of twig.js that can be extended with custom functionality.
+
+They are:
+
+1. Functions
+2. Filters
+3. Tests
+4. Tags
+
+## Functions
+
+Custom functions can be added through `Twig.extendFunction(name, definition)`
+
+For example, a function that repeats a value could look like:
+
+```js
+Twig.extendFunction("repeat", function(value, times) {
+ return new Array(times + 1).join(value);
+});
+```
+
+And you can use it in a template like:
+
+
+```
+{{ repeat("_.", 10) }}
+{# output: _._._._._._._._._._. #}
+```
+
+## Filters
+
+Custom filters can be added through `Twig.extendFilter(name, definition)`
+
+For example, if you wanted to add a filter that reversed words in a sentence, you could do the following:
+
+```js
+Twig.extendFilter("backwords", function(value) {
+ return value.split(" ").reverse().join(" ");
+});
+```
+
+Then, in your templates you can use:
+
+
+
+```
+{{ "a quick brown fox"|backwords }}
+outputs: fox brown quick a
+```
+
+Custom filters with arguments are also supported:
+
+```js
+Twig.extendFilter('catify', (value, args) =>
+ args.reduce(
+ (newString, toCatify) => newString.replace(toCatify, 'cat'),
+ value
+ )
+);
+```
+
+```
+{{ "the quick brown fox jumps over the lazy dog"|catify('fox', 'dog') }}
+outputs: the quick brown cat jumps over the lazy cat
+```
+## Tests
+
+## Tags
+
+See [Extending twig.js with Custom Tags](https://github.com/justjohn/twig.js/wiki/Extending-twig.js-With-Custom-Tags)
diff --git a/docs/en/reference/implementation-notes.md b/docs/en/reference/implementation-notes.md
new file mode 100644
index 00000000..d6c4d8cb
--- /dev/null
+++ b/docs/en/reference/implementation-notes.md
@@ -0,0 +1,143 @@
+# Implementation Notes
+
+## Differences / Implementation Notes
+
+- named arguments (e.g. `|filter(param = value)`) are not supported. See [#410](https://github.com/twigjs/twig.js/issues/410)
+- currently twig.js does not have the same auto-escaping that Twig does.
+
+## Feature Support
+
+### Built-in Tags
+
+Docs: [Twig 3.x tags](https://twig.symfony.com/doc/3.x/tags/index.html)
+Example syntax: `{% tagName %}`
+
+- `apply`: ???
+- `autoescape`: ???
+- `block`: Supported
+- `cache`: ???
+- `deprecated`: ???
+- `do`: ???
+- `embed`: Supported
+- `extends`: Supported
+- `flush`: N/A
+- `for`: Supported
+- `from`: Supported
+- `if`: Supported
+- `import`: Supported
+- `include`: Supported
+- `macro`: Supported
+- `sandbox`: ???
+- `set`: Supported
+- `use`: Supported
+- `verbatim`: Supported
+- `with`: Supported
+
+### Built-in Filters
+
+Docs: [Twig 3.x filters](https://twig.symfony.com/doc/3.x/filters/index.html)
+Example syntax: `{{ variable|filterName }}`
+
+- `abs`: Supported
+- `batch`: Supported
+- `capitalize`: Supported
+- `column`: ???
+- `convert_encoding`: N/A
+- `country_name`: ???
+- `currency_name`: ???
+- `currency_symbol`: ???
+- `data_uri`: ???
+- `date`: Supported
+- `date_modify`: Supported
+- `default`: Supported
+- `escape`: Supported
+- `filter`: Supported
+- `first`: Supported
+- `format`: Supported
+- `format_currency`: ???
+- `format_date`: ???
+- `format_datetime`: ???
+- `format_number`: ???
+- `format_time`: ???
+- `html_to_markdown`: ???
+- `inky_to_html`: ???
+- `inline_css`: ???
+- `join`: Supported
+- `json_encode`: Supported
+- `keys`: Supported
+- `language_name`: ???
+- `last`: Supported
+- `length`: Supported
+- `locale_name`: ???
+- `lower`: Supported
+- `map`: ???
+- `markdown_to_html`: ???
+- `merge`: Supported
+- `nl2br`: Supported
+- `number_format`: Supported
+- `raw`: ???
+- `replace`: Supported
+- `reverse`: Supported
+- `round`: Supported
+- `slice`: Supported
+- `sort`: Supported
+- `spaceless`: Supported
+- `split`: Supported
+- `striptags`: Supported
+- `timezone_name`: ???
+- `title`: Supported
+- `trim`: Supported
+- `u`: ???
+- `upper`: Supported
+- `url_encode`: Supported
+
+### Built-in Functions
+
+Docs: [Twig 3.x functions](https://twig.symfony.com/doc/3.x/functions/index.html)
+Example syntax: `{{ functionName(arguments) }}`
+
+- `attribute`: ???
+- `block`: ???
+- `constant`: ???
+- `cycle`: ???
+- `date`: ???
+- `dump`: ???
+- `html_classes`: ???
+- `include`: Throws error: "include function does not exist and is not defined in the context" https://github.com/twigjs/twig.js/issues/392
+- `max`: ???
+- `min`: ???
+- `parent`: ???
+- `random`: ???
+- `range`: ???
+- `source`: ???
+- `country_timezones`: ???
+- `template_from_string`: ???
+
+### Built-in Tests
+
+Docs: [Twig 3.x tests](https://twig.symfony.com/doc/3.x/tests/index.html)
+Example syntax: `{{ expression is testName }}`
+
+- `constant`:
+- `defined`: Supported
+- `divisibleby`: Supported
+- `empty`: Supported
+- `even`: Supported
+- `iterable`: Supported
+- `null` / `none`: Supported
+- `odd`: Supported
+- `sameas`: Supported
+
+### Built-in Operators
+
+Docs: [Twig 3.x operators](https://twig.symfony.com/doc/3.x/templates.html#expressions)
+Example syntax: `{{ expression operator expression }}`
+
+- `in`: Supported
+- `is`: Supported
+- Math (`+`, `-`, `/`, `%`, `*`, `**`): Supported
+- Logic (`and`, `or`, `not`, `()`): Supported
+- Bitwise (`b-and`, `b-or`, `b-xor`): Supported
+- Comparisons (`==`, `!=`, `<`, `>`, `>=`, `<=`, `===`): Supported
+- Others (`..`, `|`, `~`, `.`, `[]`, `?:`): Supported
+- Null-coalescing (`??`): Supported
\ No newline at end of file
diff --git a/docs/licenses.md b/docs/licenses.md
deleted file mode 100644
index 949a254a..00000000
--- a/docs/licenses.md
+++ /dev/null
@@ -1,177 +0,0 @@
-## LICENSE for the sprintf and vsprintf functions is src/lib/twig.lib.js
-
-
- Copyright (c) Alexandru Marasteanu
- All rights reserved.
-
- Redistribution and use 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 sprintf() for JavaScript nor the
- names of its contributors may be used to endorse or promote products
- derived from this software without specific prior written permission.
-
- 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 Alexandru Marasteanu 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.
-
-
-## LICENSE for the Date.format function is src/lib/twig.lib.js
-
- Copyright (c) 2010 Christopher West
-
- 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.
-
-
-## LICENSE for the strip_tags function in src/twig.lib.js and range function
-## in src/twig.functions.js
-
- This is version: 3.26
- php.js is copyright 2011 Kevin van Zonneveld.
-
- Portions copyright Brett Zamir (http://brett-zamir.me), Kevin van Zonneveld
- (http://kevin.vanzonneveld.net), Onno Marsman, Theriault, Michael White
- (http://getsprink.com), Waldo Malqui Silva, Paulo Freitas, Jack, Jonas
- Raoni Soares Silva (http://www.jsfromhell.com), Philip Peterson, Legaev
- Andrey, Ates Goral (http://magnetiq.com), Alex, Ratheous, Martijn Wieringa,
- Rafał Kukawski (http://blog.kukawski.pl), lmeyrick
- (https://sourceforge.net/projects/bcmath-js/), Nate, Philippe Baumann,
- Enrique Gonzalez, Webtoolkit.info (http://www.webtoolkit.info/), Carlos R.
- L. Rodrigues (http://www.jsfromhell.com), Ash Searle
- (http://hexmen.com/blog/), Jani Hartikainen, travc, Ole Vrijenhoek,
- Erkekjetter, Michael Grier, Rafał Kukawski (http://kukawski.pl), Johnny
- Mast (http://www.phpvrouwen.nl), T.Wild, d3x,
- http://stackoverflow.com/questions/57803/how-to-convert-decimal-to-hex-in-javascript,
- Rafał Kukawski (http://blog.kukawski.pl/), stag019, pilus, WebDevHobo
- (http://webdevhobo.blogspot.com/), marrtins, GeekFG
- (http://geekfg.blogspot.com), Andrea Giammarchi
- (http://webreflection.blogspot.com), Arpad Ray (mailto:arpad@php.net),
- gorthaur, Paul Smith, Tim de Koning (http://www.kingsquare.nl), Joris, Oleg
- Eremeev, Steve Hilder, majak, gettimeofday, KELAN, Josh Fraser
- (http://onlineaspect.com/2007/06/08/auto-detect-a-time-zone-with-javascript/),
- Marc Palau, Kevin van Zonneveld (http://kevin.vanzonneveld.net/), Martin
- (http://www.erlenwiese.de/), Breaking Par Consulting Inc
- (http://www.breakingpar.com/bkp/home.nsf/0/87256B280015193F87256CFB006C45F7),
- Chris, Mirek Slugen, saulius, Alfonso Jimenez
- (http://www.alfonsojimenez.com), Diplom@t (http://difane.com/), felix,
- Mailfaker (http://www.weedem.fr/), Tyler Akins (http://rumkin.com), Caio
- Ariede (http://caioariede.com), Robin, Kankrelune
- (http://www.webfaktory.info/), Karol Kowalski, Imgen Tata
- (http://www.myipdf.com/), mdsjack (http://www.mdsjack.bo.it), Dreamer,
- Felix Geisendoerfer (http://www.debuggable.com/felix), Lars Fischer, AJ,
- David, Aman Gupta, Michael White, Public Domain
- (http://www.json.org/json2.js), Steven Levithan
- (http://blog.stevenlevithan.com), Sakimori, Pellentesque Malesuada,
- Thunder.m, Dj (http://phpjs.org/functions/htmlentities:425#comment_134018),
- Steve Clay, David James, Francois, class_exists, nobbler, T. Wild, Itsacon
- (http://www.itsacon.net/), date, Ole Vrijenhoek (http://www.nervous.nl/),
- Fox, Raphael (Ao RUDLER), Marco, noname, Mateusz "loonquawl" Zalega, Frank
- Forte, Arno, ger, mktime, john (http://www.jd-tech.net), Nick Kolosov
- (http://sammy.ru), marc andreu, Scott Cariss, Douglas Crockford
- (http://javascript.crockford.com), madipta, Slawomir Kaniecki,
- ReverseSyntax, Nathan, Alex Wilson, kenneth, Bayron Guevara, Adam Wallner
- (http://web2.bitbaro.hu/), paulo kuong, jmweb, Lincoln Ramsay, djmix,
- Pyerre, Jon Hohle, Thiago Mata (http://thiagomata.blog.com), lmeyrick
- (https://sourceforge.net/projects/bcmath-js/this.), Linuxworld, duncan,
- Gilbert, Sanjoy Roy, Shingo, sankai, Oskar Larsson Högfeldt
- (http://oskar-lh.name/), Denny Wardhana, 0m3r, Everlasto, Subhasis Deb,
- josh, jd, Pier Paolo Ramon (http://www.mastersoup.com/), P, merabi, Soren
- Hansen, Eugene Bulkin (http://doubleaw.com/), Der Simon
- (http://innerdom.sourceforge.net/), echo is bad, Ozh, XoraX
- (http://www.xorax.info), EdorFaus, JB, J A R, Marc Jansen, Francesco, LH,
- Stoyan Kyosev (http://www.svest.org/), nord_ua, omid
- (http://phpjs.org/functions/380:380#comment_137122), Brad Touesnard, MeEtc
- (http://yass.meetcweb.com), Peter-Paul Koch
- (http://www.quirksmode.org/js/beat.html), Olivier Louvignes
- (http://mg-crea.com/), T0bsn, Tim Wiel, Bryan Elliott, Jalal Berrami,
- Martin, JT, David Randall, Thomas Beaucourt (http://www.webapp.fr), taith,
- vlado houba, Pierre-Luc Paour, Kristof Coomans (SCK-CEN Belgian Nucleair
- Research Centre), Martin Pool, Kirk Strobeck, Rick Waldron, Brant Messenger
- (http://www.brantmessenger.com/), Devan Penner-Woelk, Saulo Vallory, Wagner
- B. Soares, Artur Tchernychev, Valentina De Rosa, Jason Wong
- (http://carrot.org/), Christoph, Daniel Esteban, strftime, Mick@el, rezna,
- Simon Willison (http://simonwillison.net), Anton Ongson, Gabriel Paderni,
- Marco van Oort, penutbutterjelly, Philipp Lenssen, Bjorn Roesbeke
- (http://www.bjornroesbeke.be/), Bug?, Eric Nagel, Tomasz Wesolowski,
- Evertjan Garretsen, Bobby Drake, Blues (http://tech.bluesmoon.info/), Luke
- Godfrey, Pul, uestla, Alan C, Ulrich, Rafal Kukawski, Yves Sucaet,
- sowberry, Norman "zEh" Fuchs, hitwork, Zahlii, johnrembo, Nick Callen,
- Steven Levithan (stevenlevithan.com), ejsanders, Scott Baker, Brian Tafoya
- (http://www.premasolutions.com/), Philippe Jausions
- (http://pear.php.net/user/jausions), Aidan Lister
- (http://aidanlister.com/), Rob, e-mike, HKM, ChaosNo1, metjay, strcasecmp,
- strcmp, Taras Bogach, jpfle, Alexander Ermolaev
- (http://snippets.dzone.com/user/AlexanderErmolaev), DxGx, kilops, Orlando,
- dptr1988, Le Torbi, James (http://www.james-bell.co.uk/), Pedro Tainha
- (http://www.pedrotainha.com), James, Arnout Kazemier
- (http://www.3rd-Eden.com), Chris McMacken, gabriel paderni, Yannoo,
- FGFEmperor, baris ozdil, Tod Gentille, Greg Frazier, jakes, 3D-GRAF, Allan
- Jensen (http://www.winternet.no), Howard Yeend, Benjamin Lupton, davook,
- daniel airton wermann (http://wermann.com.br), Atli Þór, Maximusya, Ryan
- W Tenney (http://ryan.10e.us), Alexander M Beedie, fearphage
- (http://http/my.opera.com/fearphage/), Nathan Sepulveda, Victor, Matteo,
- Billy, stensi, Cord, Manish, T.J. Leahy, Riddler
- (http://www.frontierwebdev.com/), Rafał Kukawski, FremyCompany, Matt
- Bradley, Tim de Koning, Luis Salazar (http://www.freaky-media.com/), Diogo
- Resende, Rival, Andrej Pavlovic, Garagoth, Le Torbi
- (http://www.letorbi.de/), Dino, Josep Sanz (http://www.ws3.es/), rem,
- Russell Walker (http://www.nbill.co.uk/), Jamie Beck
- (http://www.terabit.ca/), setcookie, Michael, YUI Library:
- http://developer.yahoo.com/yui/docs/YAHOO.util.DateLocale.html, Blues at
- http://hacks.bluesmoon.info/strftime/strftime.js, Ben
- (http://benblume.co.uk/), DtTvB
- (http://dt.in.th/2008-09-16.string-length-in-bytes.html), Andreas, William,
- meo, incidence, Cagri Ekin, Amirouche, Amir Habibi
- (http://www.residence-mixte.com/), Luke Smith (http://lucassmith.name),
- Kheang Hok Chin (http://www.distantia.ca/), Jay Klehr, Lorenzo Pisani,
- Tony, Yen-Wei Liu, Greenseed, mk.keck, Leslie Hoare, dude, booeyOH, Ben
- Bryan
-
- Dual licensed under the MIT (MIT-LICENSE.txt)
- and GPL (GPL-LICENSE.txt) licenses.
-
- 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 KEVIN VAN ZONNEVELD 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/docs/package-lock.json b/docs/package-lock.json
new file mode 100644
index 00000000..b123e5ef
--- /dev/null
+++ b/docs/package-lock.json
@@ -0,0 +1,3348 @@
+{
+ "name": "docs",
+ "version": "1.0.0",
+ "lockfileVersion": 2,
+ "requires": true,
+ "packages": {
+ "": {
+ "name": "docs",
+ "version": "1.0.0",
+ "dependencies": {
+ "vitepress": "^1.4.3"
+ }
+ },
+ "node_modules/@algolia/autocomplete-core": {
+ "version": "1.9.3",
+ "resolved": "https://registry.npmjs.org/@algolia/autocomplete-core/-/autocomplete-core-1.9.3.tgz",
+ "integrity": "sha512-009HdfugtGCdC4JdXUbVJClA0q0zh24yyePn+KUGk3rP7j8FEe/m5Yo/z65gn6nP/cM39PxpzqKrL7A6fP6PPw==",
+ "dependencies": {
+ "@algolia/autocomplete-plugin-algolia-insights": "1.9.3",
+ "@algolia/autocomplete-shared": "1.9.3"
+ }
+ },
+ "node_modules/@algolia/autocomplete-plugin-algolia-insights": {
+ "version": "1.9.3",
+ "resolved": "https://registry.npmjs.org/@algolia/autocomplete-plugin-algolia-insights/-/autocomplete-plugin-algolia-insights-1.9.3.tgz",
+ "integrity": "sha512-a/yTUkcO/Vyy+JffmAnTWbr4/90cLzw+CC3bRbhnULr/EM0fGNvM13oQQ14f2moLMcVDyAx/leczLlAOovhSZg==",
+ "dependencies": {
+ "@algolia/autocomplete-shared": "1.9.3"
+ },
+ "peerDependencies": {
+ "search-insights": ">= 1 < 3"
+ }
+ },
+ "node_modules/@algolia/autocomplete-preset-algolia": {
+ "version": "1.17.6",
+ "resolved": "https://registry.npmjs.org/@algolia/autocomplete-preset-algolia/-/autocomplete-preset-algolia-1.17.6.tgz",
+ "integrity": "sha512-Cvg5JENdSCMuClwhJ1ON1/jSuojaYMiUW2KePm18IkdCzPJj/NXojaOxw58RFtQFpJgfVW8h2E8mEoDtLlMdeA==",
+ "dependencies": {
+ "@algolia/autocomplete-shared": "1.17.6"
+ },
+ "peerDependencies": {
+ "@algolia/client-search": ">= 4.9.1 < 6",
+ "algoliasearch": ">= 4.9.1 < 6"
+ }
+ },
+ "node_modules/@algolia/autocomplete-preset-algolia/node_modules/@algolia/autocomplete-shared": {
+ "version": "1.17.6",
+ "resolved": "https://registry.npmjs.org/@algolia/autocomplete-shared/-/autocomplete-shared-1.17.6.tgz",
+ "integrity": "sha512-aq/3V9E00Tw2GC/PqgyPGXtqJUlVc17v4cn1EUhSc+O/4zd04Uwb3UmPm8KDaYQQOrkt1lwvCj2vG2wRE5IKhw==",
+ "peerDependencies": {
+ "@algolia/client-search": ">= 4.9.1 < 6",
+ "algoliasearch": ">= 4.9.1 < 6"
+ }
+ },
+ "node_modules/@algolia/autocomplete-shared": {
+ "version": "1.9.3",
+ "resolved": "https://registry.npmjs.org/@algolia/autocomplete-shared/-/autocomplete-shared-1.9.3.tgz",
+ "integrity": "sha512-Wnm9E4Ye6Rl6sTTqjoymD+l8DjSTHsHboVRYrKgEt8Q7UHm9nYbqhN/i0fhUYA3OAEH7WA8x3jfpnmJm3rKvaQ==",
+ "peerDependencies": {
+ "@algolia/client-search": ">= 4.9.1 < 6",
+ "algoliasearch": ">= 4.9.1 < 6"
+ }
+ },
+ "node_modules/@algolia/client-abtesting": {
+ "version": "5.12.0",
+ "resolved": "https://registry.npmjs.org/@algolia/client-abtesting/-/client-abtesting-5.12.0.tgz",
+ "integrity": "sha512-hx4eVydkm3yrFCFxmcBtSzI/ykt0cZ6sDWch+v3JTgKpD2WtosMJU3Upv1AjQ4B6COSHCOWEX3vfFxW6OoH6aA==",
+ "dependencies": {
+ "@algolia/client-common": "5.12.0",
+ "@algolia/requester-browser-xhr": "5.12.0",
+ "@algolia/requester-fetch": "5.12.0",
+ "@algolia/requester-node-http": "5.12.0"
+ },
+ "engines": {
+ "node": ">= 14.0.0"
+ }
+ },
+ "node_modules/@algolia/client-analytics": {
+ "version": "5.12.0",
+ "resolved": "https://registry.npmjs.org/@algolia/client-analytics/-/client-analytics-5.12.0.tgz",
+ "integrity": "sha512-EpTsSv6IW8maCfXCDIptgT7+mQJj7pImEkcNUnxR8yUKAHzTogTXv9yGm2WXOZFVuwstd2i0sImhQ1Vz8RH/hA==",
+ "dependencies": {
+ "@algolia/client-common": "5.12.0",
+ "@algolia/requester-browser-xhr": "5.12.0",
+ "@algolia/requester-fetch": "5.12.0",
+ "@algolia/requester-node-http": "5.12.0"
+ },
+ "engines": {
+ "node": ">= 14.0.0"
+ }
+ },
+ "node_modules/@algolia/client-common": {
+ "version": "5.12.0",
+ "resolved": "https://registry.npmjs.org/@algolia/client-common/-/client-common-5.12.0.tgz",
+ "integrity": "sha512-od3WmO8qxyfNhKc+K3D17tvun3IMs/xMNmxCG9MiElAkYVbPPTRUYMkRneCpmJyQI0hNx2/EA4kZgzVfQjO86Q==",
+ "engines": {
+ "node": ">= 14.0.0"
+ }
+ },
+ "node_modules/@algolia/client-insights": {
+ "version": "5.12.0",
+ "resolved": "https://registry.npmjs.org/@algolia/client-insights/-/client-insights-5.12.0.tgz",
+ "integrity": "sha512-8alajmsYUd+7vfX5lpRNdxqv3Xx9clIHLUItyQK0Z6gwGMbVEFe6YYhgDtwslMAP0y6b0WeJEIZJMLgT7VYpRw==",
+ "dependencies": {
+ "@algolia/client-common": "5.12.0",
+ "@algolia/requester-browser-xhr": "5.12.0",
+ "@algolia/requester-fetch": "5.12.0",
+ "@algolia/requester-node-http": "5.12.0"
+ },
+ "engines": {
+ "node": ">= 14.0.0"
+ }
+ },
+ "node_modules/@algolia/client-personalization": {
+ "version": "5.12.0",
+ "resolved": "https://registry.npmjs.org/@algolia/client-personalization/-/client-personalization-5.12.0.tgz",
+ "integrity": "sha512-bUV9HtfkTBgpoVhxFrMkmVPG03ZN1Rtn51kiaEtukucdk3ggjR9Qu1YUfRSU2lFgxr9qJc8lTxwfvhjCeJRcqw==",
+ "dependencies": {
+ "@algolia/client-common": "5.12.0",
+ "@algolia/requester-browser-xhr": "5.12.0",
+ "@algolia/requester-fetch": "5.12.0",
+ "@algolia/requester-node-http": "5.12.0"
+ },
+ "engines": {
+ "node": ">= 14.0.0"
+ }
+ },
+ "node_modules/@algolia/client-query-suggestions": {
+ "version": "5.12.0",
+ "resolved": "https://registry.npmjs.org/@algolia/client-query-suggestions/-/client-query-suggestions-5.12.0.tgz",
+ "integrity": "sha512-Q5CszzGWfxbIDs9DJ/QJsL7bP6h+lJMg27KxieEnI9KGCu0Jt5iFA3GkREkgRZxRdzlHbZKkrIzhtHVbSHw/rg==",
+ "dependencies": {
+ "@algolia/client-common": "5.12.0",
+ "@algolia/requester-browser-xhr": "5.12.0",
+ "@algolia/requester-fetch": "5.12.0",
+ "@algolia/requester-node-http": "5.12.0"
+ },
+ "engines": {
+ "node": ">= 14.0.0"
+ }
+ },
+ "node_modules/@algolia/client-search": {
+ "version": "5.12.0",
+ "resolved": "https://registry.npmjs.org/@algolia/client-search/-/client-search-5.12.0.tgz",
+ "integrity": "sha512-R3qzEytgVLHOGNri+bpta6NtTt7YtkvUe/QBcAmMDjW4Jk1P0eBYIPfvnzIPbINRsLxIq9fZs9uAYBgsrts4Zg==",
+ "dependencies": {
+ "@algolia/client-common": "5.12.0",
+ "@algolia/requester-browser-xhr": "5.12.0",
+ "@algolia/requester-fetch": "5.12.0",
+ "@algolia/requester-node-http": "5.12.0"
+ },
+ "engines": {
+ "node": ">= 14.0.0"
+ }
+ },
+ "node_modules/@algolia/ingestion": {
+ "version": "1.12.0",
+ "resolved": "https://registry.npmjs.org/@algolia/ingestion/-/ingestion-1.12.0.tgz",
+ "integrity": "sha512-zpHo6qhR22tL8FsdSI4DvEraPDi/019HmMrCFB/TUX98yzh5ooAU7sNW0qPL1I7+S++VbBmNzJOEU9VI8tEC8A==",
+ "dependencies": {
+ "@algolia/client-common": "5.12.0",
+ "@algolia/requester-browser-xhr": "5.12.0",
+ "@algolia/requester-fetch": "5.12.0",
+ "@algolia/requester-node-http": "5.12.0"
+ },
+ "engines": {
+ "node": ">= 14.0.0"
+ }
+ },
+ "node_modules/@algolia/monitoring": {
+ "version": "1.12.0",
+ "resolved": "https://registry.npmjs.org/@algolia/monitoring/-/monitoring-1.12.0.tgz",
+ "integrity": "sha512-i2AJZED/zf4uhxezAJUhMKoL5QoepCBp2ynOYol0N76+TSoohaMADdPnWCqOULF4RzOwrG8wWynAwBlXsAI1RQ==",
+ "dependencies": {
+ "@algolia/client-common": "5.12.0",
+ "@algolia/requester-browser-xhr": "5.12.0",
+ "@algolia/requester-fetch": "5.12.0",
+ "@algolia/requester-node-http": "5.12.0"
+ },
+ "engines": {
+ "node": ">= 14.0.0"
+ }
+ },
+ "node_modules/@algolia/recommend": {
+ "version": "5.12.0",
+ "resolved": "https://registry.npmjs.org/@algolia/recommend/-/recommend-5.12.0.tgz",
+ "integrity": "sha512-0jmZyKvYnB/Bj5c7WKsKedOUjnr0UtXm0LVFUdQrxXfqOqvWv9n6Vpr65UjdYG4Q49kRQxhlwtal9WJYrYymXg==",
+ "dependencies": {
+ "@algolia/client-common": "5.12.0",
+ "@algolia/requester-browser-xhr": "5.12.0",
+ "@algolia/requester-fetch": "5.12.0",
+ "@algolia/requester-node-http": "5.12.0"
+ },
+ "engines": {
+ "node": ">= 14.0.0"
+ }
+ },
+ "node_modules/@algolia/requester-browser-xhr": {
+ "version": "5.12.0",
+ "resolved": "https://registry.npmjs.org/@algolia/requester-browser-xhr/-/requester-browser-xhr-5.12.0.tgz",
+ "integrity": "sha512-KxwleraFuVoEGCoeW6Y1RAEbgBMS7SavqeyzWdtkJc6mXeCOJXn1iZitb8Tyn2FcpMNUKlSm0adrUTt7G47+Ow==",
+ "dependencies": {
+ "@algolia/client-common": "5.12.0"
+ },
+ "engines": {
+ "node": ">= 14.0.0"
+ }
+ },
+ "node_modules/@algolia/requester-fetch": {
+ "version": "5.12.0",
+ "resolved": "https://registry.npmjs.org/@algolia/requester-fetch/-/requester-fetch-5.12.0.tgz",
+ "integrity": "sha512-FuDZXUGU1pAg2HCnrt8+q1VGHKChV/LhvjvZlLOT7e56GJie6p+EuLu4/hMKPOVuQQ8XXtrTHKIU3Lw+7O5/bQ==",
+ "dependencies": {
+ "@algolia/client-common": "5.12.0"
+ },
+ "engines": {
+ "node": ">= 14.0.0"
+ }
+ },
+ "node_modules/@algolia/requester-node-http": {
+ "version": "5.12.0",
+ "resolved": "https://registry.npmjs.org/@algolia/requester-node-http/-/requester-node-http-5.12.0.tgz",
+ "integrity": "sha512-ncDDY7CxZhMs6LIoPl+vHFQceIBhYPY5EfuGF1V7beO0U38xfsCYEyutEFB2kRzf4D9Gqppn3iWX71sNtrKcuw==",
+ "dependencies": {
+ "@algolia/client-common": "5.12.0"
+ },
+ "engines": {
+ "node": ">= 14.0.0"
+ }
+ },
+ "node_modules/@babel/helper-string-parser": {
+ "version": "7.25.9",
+ "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.25.9.tgz",
+ "integrity": "sha512-4A/SCr/2KLd5jrtOMFzaKjVtAei3+2r/NChoBNoZ3EyP/+GlhoaEGoWOZUmFmoITP7zOJyHIMm+DYRd8o3PvHA==",
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-validator-identifier": {
+ "version": "7.25.9",
+ "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.25.9.tgz",
+ "integrity": "sha512-Ed61U6XJc3CVRfkERJWDz4dJwKe7iLmmJsbOGu9wSloNSFttHV0I8g6UAgb7qnK5ly5bGLPd4oXZlxCdANBOWQ==",
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/parser": {
+ "version": "7.26.2",
+ "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.26.2.tgz",
+ "integrity": "sha512-DWMCZH9WA4Maitz2q21SRKHo9QXZxkDsbNZoVD62gusNtNBBqDg9i7uOhASfTfIGNzW+O+r7+jAlM8dwphcJKQ==",
+ "dependencies": {
+ "@babel/types": "^7.26.0"
+ },
+ "bin": {
+ "parser": "bin/babel-parser.js"
+ },
+ "engines": {
+ "node": ">=6.0.0"
+ }
+ },
+ "node_modules/@babel/types": {
+ "version": "7.26.0",
+ "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.26.0.tgz",
+ "integrity": "sha512-Z/yiTPj+lDVnF7lWeKCIJzaIkI0vYO87dMpZ4bg4TDrFe4XXLFWL1TbXU27gBP3QccxV9mZICCrnjnYlJjXHOA==",
+ "dependencies": {
+ "@babel/helper-string-parser": "^7.25.9",
+ "@babel/helper-validator-identifier": "^7.25.9"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@docsearch/css": {
+ "version": "3.6.3",
+ "resolved": "https://registry.npmjs.org/@docsearch/css/-/css-3.6.3.tgz",
+ "integrity": "sha512-3uvbg8E7rhqE1C4oBAK3tGlS2qfhi9zpfZgH/yjDPF73vd9B41urVIKujF4rczcF4E3qs34SedhehiDJ4UdNBA=="
+ },
+ "node_modules/@docsearch/js": {
+ "version": "3.6.3",
+ "resolved": "https://registry.npmjs.org/@docsearch/js/-/js-3.6.3.tgz",
+ "integrity": "sha512-2mBFomaN6VijyQQGwieERDu9GeE0hlv9TQRZBTOYsPQW7/vqtd4hnHEkbBbaBRiS4PYcy+UhikbMuDExJs63UA==",
+ "dependencies": {
+ "@docsearch/react": "3.6.3",
+ "preact": "^10.0.0"
+ }
+ },
+ "node_modules/@docsearch/react": {
+ "version": "3.6.3",
+ "resolved": "https://registry.npmjs.org/@docsearch/react/-/react-3.6.3.tgz",
+ "integrity": "sha512-2munr4uBuZq1PG+Ge+F+ldIdxb3Wi8OmEIv2tQQb4RvEvvph+xtQkxwHzVIEnt5s+HecwucuXwB+3JhcZboFLg==",
+ "dependencies": {
+ "@algolia/autocomplete-core": "1.9.3",
+ "@algolia/autocomplete-preset-algolia": "1.17.6",
+ "@docsearch/css": "3.6.3",
+ "algoliasearch": "^5.11.0"
+ },
+ "peerDependencies": {
+ "@types/react": ">= 16.8.0 < 19.0.0",
+ "react": ">= 16.8.0 < 19.0.0",
+ "react-dom": ">= 16.8.0 < 19.0.0",
+ "search-insights": ">= 1 < 3"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ },
+ "react": {
+ "optional": true
+ },
+ "react-dom": {
+ "optional": true
+ },
+ "search-insights": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@esbuild/aix-ppc64": {
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.21.5.tgz",
+ "integrity": "sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ==",
+ "cpu": [
+ "ppc64"
+ ],
+ "optional": true,
+ "os": [
+ "aix"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/android-arm": {
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.21.5.tgz",
+ "integrity": "sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg==",
+ "cpu": [
+ "arm"
+ ],
+ "optional": true,
+ "os": [
+ "android"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/android-arm64": {
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.21.5.tgz",
+ "integrity": "sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A==",
+ "cpu": [
+ "arm64"
+ ],
+ "optional": true,
+ "os": [
+ "android"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/android-x64": {
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.21.5.tgz",
+ "integrity": "sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA==",
+ "cpu": [
+ "x64"
+ ],
+ "optional": true,
+ "os": [
+ "android"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/darwin-arm64": {
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.21.5.tgz",
+ "integrity": "sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ==",
+ "cpu": [
+ "arm64"
+ ],
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/darwin-x64": {
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.21.5.tgz",
+ "integrity": "sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw==",
+ "cpu": [
+ "x64"
+ ],
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/freebsd-arm64": {
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.21.5.tgz",
+ "integrity": "sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g==",
+ "cpu": [
+ "arm64"
+ ],
+ "optional": true,
+ "os": [
+ "freebsd"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/freebsd-x64": {
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.21.5.tgz",
+ "integrity": "sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ==",
+ "cpu": [
+ "x64"
+ ],
+ "optional": true,
+ "os": [
+ "freebsd"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/linux-arm": {
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.21.5.tgz",
+ "integrity": "sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA==",
+ "cpu": [
+ "arm"
+ ],
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/linux-arm64": {
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.21.5.tgz",
+ "integrity": "sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q==",
+ "cpu": [
+ "arm64"
+ ],
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/linux-ia32": {
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.21.5.tgz",
+ "integrity": "sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg==",
+ "cpu": [
+ "ia32"
+ ],
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/linux-loong64": {
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.21.5.tgz",
+ "integrity": "sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg==",
+ "cpu": [
+ "loong64"
+ ],
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/linux-mips64el": {
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.21.5.tgz",
+ "integrity": "sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg==",
+ "cpu": [
+ "mips64el"
+ ],
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/linux-ppc64": {
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.21.5.tgz",
+ "integrity": "sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w==",
+ "cpu": [
+ "ppc64"
+ ],
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/linux-riscv64": {
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.21.5.tgz",
+ "integrity": "sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA==",
+ "cpu": [
+ "riscv64"
+ ],
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/linux-s390x": {
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.21.5.tgz",
+ "integrity": "sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A==",
+ "cpu": [
+ "s390x"
+ ],
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/linux-x64": {
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.21.5.tgz",
+ "integrity": "sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ==",
+ "cpu": [
+ "x64"
+ ],
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/netbsd-x64": {
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.21.5.tgz",
+ "integrity": "sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg==",
+ "cpu": [
+ "x64"
+ ],
+ "optional": true,
+ "os": [
+ "netbsd"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/openbsd-x64": {
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.21.5.tgz",
+ "integrity": "sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow==",
+ "cpu": [
+ "x64"
+ ],
+ "optional": true,
+ "os": [
+ "openbsd"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/sunos-x64": {
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.21.5.tgz",
+ "integrity": "sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg==",
+ "cpu": [
+ "x64"
+ ],
+ "optional": true,
+ "os": [
+ "sunos"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/win32-arm64": {
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.21.5.tgz",
+ "integrity": "sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A==",
+ "cpu": [
+ "arm64"
+ ],
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/win32-ia32": {
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.21.5.tgz",
+ "integrity": "sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA==",
+ "cpu": [
+ "ia32"
+ ],
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/win32-x64": {
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.21.5.tgz",
+ "integrity": "sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw==",
+ "cpu": [
+ "x64"
+ ],
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@jridgewell/sourcemap-codec": {
+ "version": "1.5.0",
+ "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz",
+ "integrity": "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ=="
+ },
+ "node_modules/@rollup/rollup-android-arm-eabi": {
+ "version": "4.24.3",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.24.3.tgz",
+ "integrity": "sha512-ufb2CH2KfBWPJok95frEZZ82LtDl0A6QKTa8MoM+cWwDZvVGl5/jNb79pIhRvAalUu+7LD91VYR0nwRD799HkQ==",
+ "cpu": [
+ "arm"
+ ],
+ "optional": true,
+ "os": [
+ "android"
+ ]
+ },
+ "node_modules/@rollup/rollup-android-arm64": {
+ "version": "4.24.3",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.24.3.tgz",
+ "integrity": "sha512-iAHpft/eQk9vkWIV5t22V77d90CRofgR2006UiCjHcHJFVI1E0oBkQIAbz+pLtthFw3hWEmVB4ilxGyBf48i2Q==",
+ "cpu": [
+ "arm64"
+ ],
+ "optional": true,
+ "os": [
+ "android"
+ ]
+ },
+ "node_modules/@rollup/rollup-darwin-arm64": {
+ "version": "4.24.3",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.24.3.tgz",
+ "integrity": "sha512-QPW2YmkWLlvqmOa2OwrfqLJqkHm7kJCIMq9kOz40Zo9Ipi40kf9ONG5Sz76zszrmIZZ4hgRIkez69YnTHgEz1w==",
+ "cpu": [
+ "arm64"
+ ],
+ "optional": true,
+ "os": [
+ "darwin"
+ ]
+ },
+ "node_modules/@rollup/rollup-darwin-x64": {
+ "version": "4.24.3",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.24.3.tgz",
+ "integrity": "sha512-KO0pN5x3+uZm1ZXeIfDqwcvnQ9UEGN8JX5ufhmgH5Lz4ujjZMAnxQygZAVGemFWn+ZZC0FQopruV4lqmGMshow==",
+ "cpu": [
+ "x64"
+ ],
+ "optional": true,
+ "os": [
+ "darwin"
+ ]
+ },
+ "node_modules/@rollup/rollup-freebsd-arm64": {
+ "version": "4.24.3",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.24.3.tgz",
+ "integrity": "sha512-CsC+ZdIiZCZbBI+aRlWpYJMSWvVssPuWqrDy/zi9YfnatKKSLFCe6fjna1grHuo/nVaHG+kiglpRhyBQYRTK4A==",
+ "cpu": [
+ "arm64"
+ ],
+ "optional": true,
+ "os": [
+ "freebsd"
+ ]
+ },
+ "node_modules/@rollup/rollup-freebsd-x64": {
+ "version": "4.24.3",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.24.3.tgz",
+ "integrity": "sha512-F0nqiLThcfKvRQhZEzMIXOQG4EeX61im61VYL1jo4eBxv4aZRmpin6crnBJQ/nWnCsjH5F6J3W6Stdm0mBNqBg==",
+ "cpu": [
+ "x64"
+ ],
+ "optional": true,
+ "os": [
+ "freebsd"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-arm-gnueabihf": {
+ "version": "4.24.3",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.24.3.tgz",
+ "integrity": "sha512-KRSFHyE/RdxQ1CSeOIBVIAxStFC/hnBgVcaiCkQaVC+EYDtTe4X7z5tBkFyRoBgUGtB6Xg6t9t2kulnX6wJc6A==",
+ "cpu": [
+ "arm"
+ ],
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-arm-musleabihf": {
+ "version": "4.24.3",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.24.3.tgz",
+ "integrity": "sha512-h6Q8MT+e05zP5BxEKz0vi0DhthLdrNEnspdLzkoFqGwnmOzakEHSlXfVyA4HJ322QtFy7biUAVFPvIDEDQa6rw==",
+ "cpu": [
+ "arm"
+ ],
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-arm64-gnu": {
+ "version": "4.24.3",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.24.3.tgz",
+ "integrity": "sha512-fKElSyXhXIJ9pqiYRqisfirIo2Z5pTTve5K438URf08fsypXrEkVmShkSfM8GJ1aUyvjakT+fn2W7Czlpd/0FQ==",
+ "cpu": [
+ "arm64"
+ ],
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-arm64-musl": {
+ "version": "4.24.3",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.24.3.tgz",
+ "integrity": "sha512-YlddZSUk8G0px9/+V9PVilVDC6ydMz7WquxozToozSnfFK6wa6ne1ATUjUvjin09jp34p84milxlY5ikueoenw==",
+ "cpu": [
+ "arm64"
+ ],
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-powerpc64le-gnu": {
+ "version": "4.24.3",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.24.3.tgz",
+ "integrity": "sha512-yNaWw+GAO8JjVx3s3cMeG5Esz1cKVzz8PkTJSfYzE5u7A+NvGmbVFEHP+BikTIyYWuz0+DX9kaA3pH9Sqxp69g==",
+ "cpu": [
+ "ppc64"
+ ],
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-riscv64-gnu": {
+ "version": "4.24.3",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.24.3.tgz",
+ "integrity": "sha512-lWKNQfsbpv14ZCtM/HkjCTm4oWTKTfxPmr7iPfp3AHSqyoTz5AgLemYkWLwOBWc+XxBbrU9SCokZP0WlBZM9lA==",
+ "cpu": [
+ "riscv64"
+ ],
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-s390x-gnu": {
+ "version": "4.24.3",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.24.3.tgz",
+ "integrity": "sha512-HoojGXTC2CgCcq0Woc/dn12wQUlkNyfH0I1ABK4Ni9YXyFQa86Fkt2Q0nqgLfbhkyfQ6003i3qQk9pLh/SpAYw==",
+ "cpu": [
+ "s390x"
+ ],
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-x64-gnu": {
+ "version": "4.24.3",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.24.3.tgz",
+ "integrity": "sha512-mnEOh4iE4USSccBOtcrjF5nj+5/zm6NcNhbSEfR3Ot0pxBwvEn5QVUXcuOwwPkapDtGZ6pT02xLoPaNv06w7KQ==",
+ "cpu": [
+ "x64"
+ ],
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-x64-musl": {
+ "version": "4.24.3",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.24.3.tgz",
+ "integrity": "sha512-rMTzawBPimBQkG9NKpNHvquIUTQPzrnPxPbCY1Xt+mFkW7pshvyIS5kYgcf74goxXOQk0CP3EoOC1zcEezKXhw==",
+ "cpu": [
+ "x64"
+ ],
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-win32-arm64-msvc": {
+ "version": "4.24.3",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.24.3.tgz",
+ "integrity": "sha512-2lg1CE305xNvnH3SyiKwPVsTVLCg4TmNCF1z7PSHX2uZY2VbUpdkgAllVoISD7JO7zu+YynpWNSKAtOrX3AiuA==",
+ "cpu": [
+ "arm64"
+ ],
+ "optional": true,
+ "os": [
+ "win32"
+ ]
+ },
+ "node_modules/@rollup/rollup-win32-ia32-msvc": {
+ "version": "4.24.3",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.24.3.tgz",
+ "integrity": "sha512-9SjYp1sPyxJsPWuhOCX6F4jUMXGbVVd5obVpoVEi8ClZqo52ViZewA6eFz85y8ezuOA+uJMP5A5zo6Oz4S5rVQ==",
+ "cpu": [
+ "ia32"
+ ],
+ "optional": true,
+ "os": [
+ "win32"
+ ]
+ },
+ "node_modules/@rollup/rollup-win32-x64-msvc": {
+ "version": "4.24.3",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.24.3.tgz",
+ "integrity": "sha512-HGZgRFFYrMrP3TJlq58nR1xy8zHKId25vhmm5S9jETEfDf6xybPxsavFTJaufe2zgOGYJBskGlj49CwtEuFhWQ==",
+ "cpu": [
+ "x64"
+ ],
+ "optional": true,
+ "os": [
+ "win32"
+ ]
+ },
+ "node_modules/@shikijs/core": {
+ "version": "1.22.2",
+ "resolved": "https://registry.npmjs.org/@shikijs/core/-/core-1.22.2.tgz",
+ "integrity": "sha512-bvIQcd8BEeR1yFvOYv6HDiyta2FFVePbzeowf5pPS1avczrPK+cjmaxxh0nx5QzbON7+Sv0sQfQVciO7bN72sg==",
+ "dependencies": {
+ "@shikijs/engine-javascript": "1.22.2",
+ "@shikijs/engine-oniguruma": "1.22.2",
+ "@shikijs/types": "1.22.2",
+ "@shikijs/vscode-textmate": "^9.3.0",
+ "@types/hast": "^3.0.4",
+ "hast-util-to-html": "^9.0.3"
+ }
+ },
+ "node_modules/@shikijs/engine-javascript": {
+ "version": "1.22.2",
+ "resolved": "https://registry.npmjs.org/@shikijs/engine-javascript/-/engine-javascript-1.22.2.tgz",
+ "integrity": "sha512-iOvql09ql6m+3d1vtvP8fLCVCK7BQD1pJFmHIECsujB0V32BJ0Ab6hxk1ewVSMFA58FI0pR2Had9BKZdyQrxTw==",
+ "dependencies": {
+ "@shikijs/types": "1.22.2",
+ "@shikijs/vscode-textmate": "^9.3.0",
+ "oniguruma-to-js": "0.4.3"
+ }
+ },
+ "node_modules/@shikijs/engine-oniguruma": {
+ "version": "1.22.2",
+ "resolved": "https://registry.npmjs.org/@shikijs/engine-oniguruma/-/engine-oniguruma-1.22.2.tgz",
+ "integrity": "sha512-GIZPAGzQOy56mGvWMoZRPggn0dTlBf1gutV5TdceLCZlFNqWmuc7u+CzD0Gd9vQUTgLbrt0KLzz6FNprqYAxlA==",
+ "dependencies": {
+ "@shikijs/types": "1.22.2",
+ "@shikijs/vscode-textmate": "^9.3.0"
+ }
+ },
+ "node_modules/@shikijs/transformers": {
+ "version": "1.22.2",
+ "resolved": "https://registry.npmjs.org/@shikijs/transformers/-/transformers-1.22.2.tgz",
+ "integrity": "sha512-8f78OiBa6pZDoZ53lYTmuvpFPlWtevn23bzG+azpPVvZg7ITax57o/K3TC91eYL3OMJOO0onPbgnQyZjRos8XQ==",
+ "dependencies": {
+ "shiki": "1.22.2"
+ }
+ },
+ "node_modules/@shikijs/types": {
+ "version": "1.22.2",
+ "resolved": "https://registry.npmjs.org/@shikijs/types/-/types-1.22.2.tgz",
+ "integrity": "sha512-NCWDa6LGZqTuzjsGfXOBWfjS/fDIbDdmVDug+7ykVe1IKT4c1gakrvlfFYp5NhAXH/lyqLM8wsAPo5wNy73Feg==",
+ "dependencies": {
+ "@shikijs/vscode-textmate": "^9.3.0",
+ "@types/hast": "^3.0.4"
+ }
+ },
+ "node_modules/@shikijs/vscode-textmate": {
+ "version": "9.3.0",
+ "resolved": "https://registry.npmjs.org/@shikijs/vscode-textmate/-/vscode-textmate-9.3.0.tgz",
+ "integrity": "sha512-jn7/7ky30idSkd/O5yDBfAnVt+JJpepofP/POZ1iMOxK59cOfqIgg/Dj0eFsjOTMw+4ycJN0uhZH/Eb0bs/EUA=="
+ },
+ "node_modules/@types/estree": {
+ "version": "1.0.6",
+ "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.6.tgz",
+ "integrity": "sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw=="
+ },
+ "node_modules/@types/hast": {
+ "version": "3.0.4",
+ "resolved": "https://registry.npmjs.org/@types/hast/-/hast-3.0.4.tgz",
+ "integrity": "sha512-WPs+bbQw5aCj+x6laNGWLH3wviHtoCv/P3+otBhbOhJgG8qtpdAMlTCxLtsTWA7LH1Oh/bFCHsBn0TPS5m30EQ==",
+ "dependencies": {
+ "@types/unist": "*"
+ }
+ },
+ "node_modules/@types/linkify-it": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/@types/linkify-it/-/linkify-it-5.0.0.tgz",
+ "integrity": "sha512-sVDA58zAw4eWAffKOaQH5/5j3XeayukzDk+ewSsnv3p4yJEZHCCzMDiZM8e0OUrRvmpGZ85jf4yDHkHsgBNr9Q=="
+ },
+ "node_modules/@types/markdown-it": {
+ "version": "14.1.2",
+ "resolved": "https://registry.npmjs.org/@types/markdown-it/-/markdown-it-14.1.2.tgz",
+ "integrity": "sha512-promo4eFwuiW+TfGxhi+0x3czqTYJkG8qB17ZUJiVF10Xm7NLVRSLUsfRTU/6h1e24VvRnXCx+hG7li58lkzog==",
+ "dependencies": {
+ "@types/linkify-it": "^5",
+ "@types/mdurl": "^2"
+ }
+ },
+ "node_modules/@types/mdast": {
+ "version": "4.0.4",
+ "resolved": "https://registry.npmjs.org/@types/mdast/-/mdast-4.0.4.tgz",
+ "integrity": "sha512-kGaNbPh1k7AFzgpud/gMdvIm5xuECykRR+JnWKQno9TAXVa6WIVCGTPvYGekIDL4uwCZQSYbUxNBSb1aUo79oA==",
+ "dependencies": {
+ "@types/unist": "*"
+ }
+ },
+ "node_modules/@types/mdurl": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/@types/mdurl/-/mdurl-2.0.0.tgz",
+ "integrity": "sha512-RGdgjQUZba5p6QEFAVx2OGb8rQDL/cPRG7GiedRzMcJ1tYnUANBncjbSB1NRGwbvjcPeikRABz2nshyPk1bhWg=="
+ },
+ "node_modules/@types/unist": {
+ "version": "3.0.3",
+ "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.3.tgz",
+ "integrity": "sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q=="
+ },
+ "node_modules/@types/web-bluetooth": {
+ "version": "0.0.20",
+ "resolved": "https://registry.npmjs.org/@types/web-bluetooth/-/web-bluetooth-0.0.20.tgz",
+ "integrity": "sha512-g9gZnnXVq7gM7v3tJCWV/qw7w+KeOlSHAhgF9RytFyifW6AF61hdT2ucrYhPq9hLs5JIryeupHV3qGk95dH9ow=="
+ },
+ "node_modules/@ungap/structured-clone": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.2.0.tgz",
+ "integrity": "sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ=="
+ },
+ "node_modules/@vitejs/plugin-vue": {
+ "version": "5.1.4",
+ "resolved": "https://registry.npmjs.org/@vitejs/plugin-vue/-/plugin-vue-5.1.4.tgz",
+ "integrity": "sha512-N2XSI2n3sQqp5w7Y/AN/L2XDjBIRGqXko+eDp42sydYSBeJuSm5a1sLf8zakmo8u7tA8NmBgoDLA1HeOESjp9A==",
+ "engines": {
+ "node": "^18.0.0 || >=20.0.0"
+ },
+ "peerDependencies": {
+ "vite": "^5.0.0",
+ "vue": "^3.2.25"
+ }
+ },
+ "node_modules/@vue/compiler-core": {
+ "version": "3.5.12",
+ "resolved": "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.5.12.tgz",
+ "integrity": "sha512-ISyBTRMmMYagUxhcpyEH0hpXRd/KqDU4ymofPgl2XAkY9ZhQ+h0ovEZJIiPop13UmR/54oA2cgMDjgroRelaEw==",
+ "dependencies": {
+ "@babel/parser": "^7.25.3",
+ "@vue/shared": "3.5.12",
+ "entities": "^4.5.0",
+ "estree-walker": "^2.0.2",
+ "source-map-js": "^1.2.0"
+ }
+ },
+ "node_modules/@vue/compiler-dom": {
+ "version": "3.5.12",
+ "resolved": "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.5.12.tgz",
+ "integrity": "sha512-9G6PbJ03uwxLHKQ3P42cMTi85lDRvGLB2rSGOiQqtXELat6uI4n8cNz9yjfVHRPIu+MsK6TE418Giruvgptckg==",
+ "dependencies": {
+ "@vue/compiler-core": "3.5.12",
+ "@vue/shared": "3.5.12"
+ }
+ },
+ "node_modules/@vue/compiler-sfc": {
+ "version": "3.5.12",
+ "resolved": "https://registry.npmjs.org/@vue/compiler-sfc/-/compiler-sfc-3.5.12.tgz",
+ "integrity": "sha512-2k973OGo2JuAa5+ZlekuQJtitI5CgLMOwgl94BzMCsKZCX/xiqzJYzapl4opFogKHqwJk34vfsaKpfEhd1k5nw==",
+ "dependencies": {
+ "@babel/parser": "^7.25.3",
+ "@vue/compiler-core": "3.5.12",
+ "@vue/compiler-dom": "3.5.12",
+ "@vue/compiler-ssr": "3.5.12",
+ "@vue/shared": "3.5.12",
+ "estree-walker": "^2.0.2",
+ "magic-string": "^0.30.11",
+ "postcss": "^8.4.47",
+ "source-map-js": "^1.2.0"
+ }
+ },
+ "node_modules/@vue/compiler-ssr": {
+ "version": "3.5.12",
+ "resolved": "https://registry.npmjs.org/@vue/compiler-ssr/-/compiler-ssr-3.5.12.tgz",
+ "integrity": "sha512-eLwc7v6bfGBSM7wZOGPmRavSWzNFF6+PdRhE+VFJhNCgHiF8AM7ccoqcv5kBXA2eWUfigD7byekvf/JsOfKvPA==",
+ "dependencies": {
+ "@vue/compiler-dom": "3.5.12",
+ "@vue/shared": "3.5.12"
+ }
+ },
+ "node_modules/@vue/devtools-api": {
+ "version": "7.6.2",
+ "resolved": "https://registry.npmjs.org/@vue/devtools-api/-/devtools-api-7.6.2.tgz",
+ "integrity": "sha512-NCT0ujqlwAhoFvCsAG7G5qS8w/A/dhvFSt2BhmNxyqgpYDrf9CG1zYyWLQkE3dsZ+5lCT6ULUic2VKNaE07Vzg==",
+ "dependencies": {
+ "@vue/devtools-kit": "^7.6.2"
+ }
+ },
+ "node_modules/@vue/devtools-kit": {
+ "version": "7.6.2",
+ "resolved": "https://registry.npmjs.org/@vue/devtools-kit/-/devtools-kit-7.6.2.tgz",
+ "integrity": "sha512-k61BxHRmcTtIQZFouF9QWt9nCCNtSdw12lhg8VNtHq5/XOBGD+ewiK27a40UJ8UPYoCJvi80hbvbYr5E/Zeu1g==",
+ "dependencies": {
+ "@vue/devtools-shared": "^7.6.2",
+ "birpc": "^0.2.19",
+ "hookable": "^5.5.3",
+ "mitt": "^3.0.1",
+ "perfect-debounce": "^1.0.0",
+ "speakingurl": "^14.0.1",
+ "superjson": "^2.2.1"
+ }
+ },
+ "node_modules/@vue/devtools-shared": {
+ "version": "7.6.2",
+ "resolved": "https://registry.npmjs.org/@vue/devtools-shared/-/devtools-shared-7.6.2.tgz",
+ "integrity": "sha512-lcjyJ7hCC0W0kNwnCGMLVTMvDLoZgjcq9BvboPgS+6jQyDul7fpzRSKTGtGhCHoxrDox7qBAKGbAl2Rcf7GE1A==",
+ "dependencies": {
+ "rfdc": "^1.4.1"
+ }
+ },
+ "node_modules/@vue/reactivity": {
+ "version": "3.5.12",
+ "resolved": "https://registry.npmjs.org/@vue/reactivity/-/reactivity-3.5.12.tgz",
+ "integrity": "sha512-UzaN3Da7xnJXdz4Okb/BGbAaomRHc3RdoWqTzlvd9+WBR5m3J39J1fGcHes7U3za0ruYn/iYy/a1euhMEHvTAg==",
+ "dependencies": {
+ "@vue/shared": "3.5.12"
+ }
+ },
+ "node_modules/@vue/runtime-core": {
+ "version": "3.5.12",
+ "resolved": "https://registry.npmjs.org/@vue/runtime-core/-/runtime-core-3.5.12.tgz",
+ "integrity": "sha512-hrMUYV6tpocr3TL3Ad8DqxOdpDe4zuQY4HPY3X/VRh+L2myQO8MFXPAMarIOSGNu0bFAjh1yBkMPXZBqCk62Uw==",
+ "dependencies": {
+ "@vue/reactivity": "3.5.12",
+ "@vue/shared": "3.5.12"
+ }
+ },
+ "node_modules/@vue/runtime-dom": {
+ "version": "3.5.12",
+ "resolved": "https://registry.npmjs.org/@vue/runtime-dom/-/runtime-dom-3.5.12.tgz",
+ "integrity": "sha512-q8VFxR9A2MRfBr6/55Q3umyoN7ya836FzRXajPB6/Vvuv0zOPL+qltd9rIMzG/DbRLAIlREmnLsplEF/kotXKA==",
+ "dependencies": {
+ "@vue/reactivity": "3.5.12",
+ "@vue/runtime-core": "3.5.12",
+ "@vue/shared": "3.5.12",
+ "csstype": "^3.1.3"
+ }
+ },
+ "node_modules/@vue/server-renderer": {
+ "version": "3.5.12",
+ "resolved": "https://registry.npmjs.org/@vue/server-renderer/-/server-renderer-3.5.12.tgz",
+ "integrity": "sha512-I3QoeDDeEPZm8yR28JtY+rk880Oqmj43hreIBVTicisFTx/Dl7JpG72g/X7YF8hnQD3IFhkky5i2bPonwrTVPg==",
+ "dependencies": {
+ "@vue/compiler-ssr": "3.5.12",
+ "@vue/shared": "3.5.12"
+ },
+ "peerDependencies": {
+ "vue": "3.5.12"
+ }
+ },
+ "node_modules/@vue/shared": {
+ "version": "3.5.12",
+ "resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.5.12.tgz",
+ "integrity": "sha512-L2RPSAwUFbgZH20etwrXyVyCBu9OxRSi8T/38QsvnkJyvq2LufW2lDCOzm7t/U9C1mkhJGWYfCuFBCmIuNivrg=="
+ },
+ "node_modules/@vueuse/core": {
+ "version": "11.2.0",
+ "resolved": "https://registry.npmjs.org/@vueuse/core/-/core-11.2.0.tgz",
+ "integrity": "sha512-JIUwRcOqOWzcdu1dGlfW04kaJhW3EXnnjJJfLTtddJanymTL7lF1C0+dVVZ/siLfc73mWn+cGP1PE1PKPruRSA==",
+ "dependencies": {
+ "@types/web-bluetooth": "^0.0.20",
+ "@vueuse/metadata": "11.2.0",
+ "@vueuse/shared": "11.2.0",
+ "vue-demi": ">=0.14.10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/antfu"
+ }
+ },
+ "node_modules/@vueuse/core/node_modules/vue-demi": {
+ "version": "0.14.10",
+ "resolved": "https://registry.npmjs.org/vue-demi/-/vue-demi-0.14.10.tgz",
+ "integrity": "sha512-nMZBOwuzabUO0nLgIcc6rycZEebF6eeUfaiQx9+WSk8e29IbLvPU9feI6tqW4kTo3hvoYAJkMh8n8D0fuISphg==",
+ "hasInstallScript": true,
+ "bin": {
+ "vue-demi-fix": "bin/vue-demi-fix.js",
+ "vue-demi-switch": "bin/vue-demi-switch.js"
+ },
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/antfu"
+ },
+ "peerDependencies": {
+ "@vue/composition-api": "^1.0.0-rc.1",
+ "vue": "^3.0.0-0 || ^2.6.0"
+ },
+ "peerDependenciesMeta": {
+ "@vue/composition-api": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@vueuse/integrations": {
+ "version": "11.2.0",
+ "resolved": "https://registry.npmjs.org/@vueuse/integrations/-/integrations-11.2.0.tgz",
+ "integrity": "sha512-zGXz3dsxNHKwiD9jPMvR3DAxQEOV6VWIEYTGVSB9PNpk4pTWR+pXrHz9gvXWcP2sTk3W2oqqS6KwWDdntUvNVA==",
+ "dependencies": {
+ "@vueuse/core": "11.2.0",
+ "@vueuse/shared": "11.2.0",
+ "vue-demi": ">=0.14.10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/antfu"
+ },
+ "peerDependencies": {
+ "async-validator": "^4",
+ "axios": "^1",
+ "change-case": "^5",
+ "drauu": "^0.4",
+ "focus-trap": "^7",
+ "fuse.js": "^7",
+ "idb-keyval": "^6",
+ "jwt-decode": "^4",
+ "nprogress": "^0.2",
+ "qrcode": "^1.5",
+ "sortablejs": "^1",
+ "universal-cookie": "^7"
+ },
+ "peerDependenciesMeta": {
+ "async-validator": {
+ "optional": true
+ },
+ "axios": {
+ "optional": true
+ },
+ "change-case": {
+ "optional": true
+ },
+ "drauu": {
+ "optional": true
+ },
+ "focus-trap": {
+ "optional": true
+ },
+ "fuse.js": {
+ "optional": true
+ },
+ "idb-keyval": {
+ "optional": true
+ },
+ "jwt-decode": {
+ "optional": true
+ },
+ "nprogress": {
+ "optional": true
+ },
+ "qrcode": {
+ "optional": true
+ },
+ "sortablejs": {
+ "optional": true
+ },
+ "universal-cookie": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@vueuse/integrations/node_modules/vue-demi": {
+ "version": "0.14.10",
+ "resolved": "https://registry.npmjs.org/vue-demi/-/vue-demi-0.14.10.tgz",
+ "integrity": "sha512-nMZBOwuzabUO0nLgIcc6rycZEebF6eeUfaiQx9+WSk8e29IbLvPU9feI6tqW4kTo3hvoYAJkMh8n8D0fuISphg==",
+ "hasInstallScript": true,
+ "bin": {
+ "vue-demi-fix": "bin/vue-demi-fix.js",
+ "vue-demi-switch": "bin/vue-demi-switch.js"
+ },
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/antfu"
+ },
+ "peerDependencies": {
+ "@vue/composition-api": "^1.0.0-rc.1",
+ "vue": "^3.0.0-0 || ^2.6.0"
+ },
+ "peerDependenciesMeta": {
+ "@vue/composition-api": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@vueuse/metadata": {
+ "version": "11.2.0",
+ "resolved": "https://registry.npmjs.org/@vueuse/metadata/-/metadata-11.2.0.tgz",
+ "integrity": "sha512-L0ZmtRmNx+ZW95DmrgD6vn484gSpVeRbgpWevFKXwqqQxW9hnSi2Ppuh2BzMjnbv4aJRiIw8tQatXT9uOB23dQ==",
+ "funding": {
+ "url": "https://github.com/sponsors/antfu"
+ }
+ },
+ "node_modules/@vueuse/shared": {
+ "version": "11.2.0",
+ "resolved": "https://registry.npmjs.org/@vueuse/shared/-/shared-11.2.0.tgz",
+ "integrity": "sha512-VxFjie0EanOudYSgMErxXfq6fo8vhr5ICI+BuE3I9FnX7ePllEsVrRQ7O6Q1TLgApeLuPKcHQxAXpP+KnlrJsg==",
+ "dependencies": {
+ "vue-demi": ">=0.14.10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/antfu"
+ }
+ },
+ "node_modules/@vueuse/shared/node_modules/vue-demi": {
+ "version": "0.14.10",
+ "resolved": "https://registry.npmjs.org/vue-demi/-/vue-demi-0.14.10.tgz",
+ "integrity": "sha512-nMZBOwuzabUO0nLgIcc6rycZEebF6eeUfaiQx9+WSk8e29IbLvPU9feI6tqW4kTo3hvoYAJkMh8n8D0fuISphg==",
+ "hasInstallScript": true,
+ "bin": {
+ "vue-demi-fix": "bin/vue-demi-fix.js",
+ "vue-demi-switch": "bin/vue-demi-switch.js"
+ },
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/antfu"
+ },
+ "peerDependencies": {
+ "@vue/composition-api": "^1.0.0-rc.1",
+ "vue": "^3.0.0-0 || ^2.6.0"
+ },
+ "peerDependenciesMeta": {
+ "@vue/composition-api": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/algoliasearch": {
+ "version": "5.12.0",
+ "resolved": "https://registry.npmjs.org/algoliasearch/-/algoliasearch-5.12.0.tgz",
+ "integrity": "sha512-psGBRYdGgik8I6m28iAB8xpubvjEt7UQU+w5MAJUA2324WHiGoHap5BPkkjB14rMaXeRts6pmOsrVIglGyOVwg==",
+ "dependencies": {
+ "@algolia/client-abtesting": "5.12.0",
+ "@algolia/client-analytics": "5.12.0",
+ "@algolia/client-common": "5.12.0",
+ "@algolia/client-insights": "5.12.0",
+ "@algolia/client-personalization": "5.12.0",
+ "@algolia/client-query-suggestions": "5.12.0",
+ "@algolia/client-search": "5.12.0",
+ "@algolia/ingestion": "1.12.0",
+ "@algolia/monitoring": "1.12.0",
+ "@algolia/recommend": "5.12.0",
+ "@algolia/requester-browser-xhr": "5.12.0",
+ "@algolia/requester-fetch": "5.12.0",
+ "@algolia/requester-node-http": "5.12.0"
+ },
+ "engines": {
+ "node": ">= 14.0.0"
+ }
+ },
+ "node_modules/birpc": {
+ "version": "0.2.19",
+ "resolved": "https://registry.npmjs.org/birpc/-/birpc-0.2.19.tgz",
+ "integrity": "sha512-5WeXXAvTmitV1RqJFppT5QtUiz2p1mRSYU000Jkft5ZUCLJIk4uQriYNO50HknxKwM6jd8utNc66K1qGIwwWBQ==",
+ "funding": {
+ "url": "https://github.com/sponsors/antfu"
+ }
+ },
+ "node_modules/ccount": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/ccount/-/ccount-2.0.1.tgz",
+ "integrity": "sha512-eyrF0jiFpY+3drT6383f1qhkbGsLSifNAjA61IUjZjmLCWjItY6LB9ft9YhoDgwfmclB2zhu51Lc7+95b8NRAg==",
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/wooorm"
+ }
+ },
+ "node_modules/character-entities-html4": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/character-entities-html4/-/character-entities-html4-2.1.0.tgz",
+ "integrity": "sha512-1v7fgQRj6hnSwFpq1Eu0ynr/CDEw0rXo2B61qXrLNdHZmPKgb7fqS1a2JwF0rISo9q77jDI8VMEHoApn8qDoZA==",
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/wooorm"
+ }
+ },
+ "node_modules/character-entities-legacy": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/character-entities-legacy/-/character-entities-legacy-3.0.0.tgz",
+ "integrity": "sha512-RpPp0asT/6ufRm//AJVwpViZbGM/MkjQFxJccQRHmISF/22NBtsHqAWmL+/pmkPWoIUJdWyeVleTl1wydHATVQ==",
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/wooorm"
+ }
+ },
+ "node_modules/comma-separated-tokens": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/comma-separated-tokens/-/comma-separated-tokens-2.0.3.tgz",
+ "integrity": "sha512-Fu4hJdvzeylCfQPp9SGWidpzrMs7tTrlu6Vb8XGaRGck8QSNZJJp538Wrb60Lax4fPwR64ViY468OIUTbRlGZg==",
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/wooorm"
+ }
+ },
+ "node_modules/copy-anything": {
+ "version": "3.0.5",
+ "resolved": "https://registry.npmjs.org/copy-anything/-/copy-anything-3.0.5.tgz",
+ "integrity": "sha512-yCEafptTtb4bk7GLEQoM8KVJpxAfdBJYaXyzQEgQQQgYrZiDp8SJmGKlYza6CYjEDNstAdNdKA3UuoULlEbS6w==",
+ "dependencies": {
+ "is-what": "^4.1.8"
+ },
+ "engines": {
+ "node": ">=12.13"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/mesqueeb"
+ }
+ },
+ "node_modules/csstype": {
+ "version": "3.1.3",
+ "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz",
+ "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw=="
+ },
+ "node_modules/dequal": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/dequal/-/dequal-2.0.3.tgz",
+ "integrity": "sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==",
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/devlop": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/devlop/-/devlop-1.1.0.tgz",
+ "integrity": "sha512-RWmIqhcFf1lRYBvNmr7qTNuyCt/7/ns2jbpp1+PalgE/rDQcBT0fioSMUpJ93irlUhC5hrg4cYqe6U+0ImW0rA==",
+ "dependencies": {
+ "dequal": "^2.0.0"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/wooorm"
+ }
+ },
+ "node_modules/entities": {
+ "version": "4.5.0",
+ "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz",
+ "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==",
+ "engines": {
+ "node": ">=0.12"
+ },
+ "funding": {
+ "url": "https://github.com/fb55/entities?sponsor=1"
+ }
+ },
+ "node_modules/esbuild": {
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.21.5.tgz",
+ "integrity": "sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw==",
+ "hasInstallScript": true,
+ "bin": {
+ "esbuild": "bin/esbuild"
+ },
+ "engines": {
+ "node": ">=12"
+ },
+ "optionalDependencies": {
+ "@esbuild/aix-ppc64": "0.21.5",
+ "@esbuild/android-arm": "0.21.5",
+ "@esbuild/android-arm64": "0.21.5",
+ "@esbuild/android-x64": "0.21.5",
+ "@esbuild/darwin-arm64": "0.21.5",
+ "@esbuild/darwin-x64": "0.21.5",
+ "@esbuild/freebsd-arm64": "0.21.5",
+ "@esbuild/freebsd-x64": "0.21.5",
+ "@esbuild/linux-arm": "0.21.5",
+ "@esbuild/linux-arm64": "0.21.5",
+ "@esbuild/linux-ia32": "0.21.5",
+ "@esbuild/linux-loong64": "0.21.5",
+ "@esbuild/linux-mips64el": "0.21.5",
+ "@esbuild/linux-ppc64": "0.21.5",
+ "@esbuild/linux-riscv64": "0.21.5",
+ "@esbuild/linux-s390x": "0.21.5",
+ "@esbuild/linux-x64": "0.21.5",
+ "@esbuild/netbsd-x64": "0.21.5",
+ "@esbuild/openbsd-x64": "0.21.5",
+ "@esbuild/sunos-x64": "0.21.5",
+ "@esbuild/win32-arm64": "0.21.5",
+ "@esbuild/win32-ia32": "0.21.5",
+ "@esbuild/win32-x64": "0.21.5"
+ }
+ },
+ "node_modules/estree-walker": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz",
+ "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w=="
+ },
+ "node_modules/focus-trap": {
+ "version": "7.6.0",
+ "resolved": "https://registry.npmjs.org/focus-trap/-/focus-trap-7.6.0.tgz",
+ "integrity": "sha512-1td0l3pMkWJLFipobUcGaf+5DTY4PLDDrcqoSaKP8ediO/CoWCCYk/fT/Y2A4e6TNB+Sh6clRJCjOPPnKoNHnQ==",
+ "dependencies": {
+ "tabbable": "^6.2.0"
+ }
+ },
+ "node_modules/fsevents": {
+ "version": "2.3.3",
+ "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz",
+ "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==",
+ "hasInstallScript": true,
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": "^8.16.0 || ^10.6.0 || >=11.0.0"
+ }
+ },
+ "node_modules/hast-util-to-html": {
+ "version": "9.0.3",
+ "resolved": "https://registry.npmjs.org/hast-util-to-html/-/hast-util-to-html-9.0.3.tgz",
+ "integrity": "sha512-M17uBDzMJ9RPCqLMO92gNNUDuBSq10a25SDBI08iCCxmorf4Yy6sYHK57n9WAbRAAaU+DuR4W6GN9K4DFZesYg==",
+ "dependencies": {
+ "@types/hast": "^3.0.0",
+ "@types/unist": "^3.0.0",
+ "ccount": "^2.0.0",
+ "comma-separated-tokens": "^2.0.0",
+ "hast-util-whitespace": "^3.0.0",
+ "html-void-elements": "^3.0.0",
+ "mdast-util-to-hast": "^13.0.0",
+ "property-information": "^6.0.0",
+ "space-separated-tokens": "^2.0.0",
+ "stringify-entities": "^4.0.0",
+ "zwitch": "^2.0.4"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/unified"
+ }
+ },
+ "node_modules/hast-util-whitespace": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/hast-util-whitespace/-/hast-util-whitespace-3.0.0.tgz",
+ "integrity": "sha512-88JUN06ipLwsnv+dVn+OIYOvAuvBMy/Qoi6O7mQHxdPXpjy+Cd6xRkWwux7DKO+4sYILtLBRIKgsdpS2gQc7qw==",
+ "dependencies": {
+ "@types/hast": "^3.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/unified"
+ }
+ },
+ "node_modules/hookable": {
+ "version": "5.5.3",
+ "resolved": "https://registry.npmjs.org/hookable/-/hookable-5.5.3.tgz",
+ "integrity": "sha512-Yc+BQe8SvoXH1643Qez1zqLRmbA5rCL+sSmk6TVos0LWVfNIB7PGncdlId77WzLGSIB5KaWgTaNTs2lNVEI6VQ=="
+ },
+ "node_modules/html-void-elements": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/html-void-elements/-/html-void-elements-3.0.0.tgz",
+ "integrity": "sha512-bEqo66MRXsUGxWHV5IP0PUiAWwoEjba4VCzg0LjFJBpchPaTfyfCKTG6bc5F8ucKec3q5y6qOdGyYTSBEvhCrg==",
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/wooorm"
+ }
+ },
+ "node_modules/is-what": {
+ "version": "4.1.16",
+ "resolved": "https://registry.npmjs.org/is-what/-/is-what-4.1.16.tgz",
+ "integrity": "sha512-ZhMwEosbFJkA0YhFnNDgTM4ZxDRsS6HqTo7qsZM08fehyRYIYa0yHu5R6mgo1n/8MgaPBXiPimPD77baVFYg+A==",
+ "engines": {
+ "node": ">=12.13"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/mesqueeb"
+ }
+ },
+ "node_modules/magic-string": {
+ "version": "0.30.12",
+ "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.12.tgz",
+ "integrity": "sha512-Ea8I3sQMVXr8JhN4z+H/d8zwo+tYDgHE9+5G4Wnrwhs0gaK9fXTKx0Tw5Xwsd/bCPTTZNRAdpyzvoeORe9LYpw==",
+ "dependencies": {
+ "@jridgewell/sourcemap-codec": "^1.5.0"
+ }
+ },
+ "node_modules/mark.js": {
+ "version": "8.11.1",
+ "resolved": "https://registry.npmjs.org/mark.js/-/mark.js-8.11.1.tgz",
+ "integrity": "sha512-1I+1qpDt4idfgLQG+BNWmrqku+7/2bi5nLf4YwF8y8zXvmfiTBY3PV3ZibfrjBueCByROpuBjLLFCajqkgYoLQ=="
+ },
+ "node_modules/mdast-util-to-hast": {
+ "version": "13.2.0",
+ "resolved": "https://registry.npmjs.org/mdast-util-to-hast/-/mdast-util-to-hast-13.2.0.tgz",
+ "integrity": "sha512-QGYKEuUsYT9ykKBCMOEDLsU5JRObWQusAolFMeko/tYPufNkRffBAQjIE+99jbA87xv6FgmjLtwjh9wBWajwAA==",
+ "dependencies": {
+ "@types/hast": "^3.0.0",
+ "@types/mdast": "^4.0.0",
+ "@ungap/structured-clone": "^1.0.0",
+ "devlop": "^1.0.0",
+ "micromark-util-sanitize-uri": "^2.0.0",
+ "trim-lines": "^3.0.0",
+ "unist-util-position": "^5.0.0",
+ "unist-util-visit": "^5.0.0",
+ "vfile": "^6.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/unified"
+ }
+ },
+ "node_modules/micromark-util-character": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.0.tgz",
+ "integrity": "sha512-KvOVV+X1yLBfs9dCBSopq/+G1PcgT3lAK07mC4BzXi5E7ahzMAF8oIupDDJ6mievI6F+lAATkbQQlQixJfT3aQ==",
+ "funding": [
+ {
+ "type": "GitHub Sponsors",
+ "url": "https://github.com/sponsors/unifiedjs"
+ },
+ {
+ "type": "OpenCollective",
+ "url": "https://opencollective.com/unified"
+ }
+ ],
+ "dependencies": {
+ "micromark-util-symbol": "^2.0.0",
+ "micromark-util-types": "^2.0.0"
+ }
+ },
+ "node_modules/micromark-util-encode": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/micromark-util-encode/-/micromark-util-encode-2.0.0.tgz",
+ "integrity": "sha512-pS+ROfCXAGLWCOc8egcBvT0kf27GoWMqtdarNfDcjb6YLuV5cM3ioG45Ys2qOVqeqSbjaKg72vU+Wby3eddPsA==",
+ "funding": [
+ {
+ "type": "GitHub Sponsors",
+ "url": "https://github.com/sponsors/unifiedjs"
+ },
+ {
+ "type": "OpenCollective",
+ "url": "https://opencollective.com/unified"
+ }
+ ]
+ },
+ "node_modules/micromark-util-sanitize-uri": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/micromark-util-sanitize-uri/-/micromark-util-sanitize-uri-2.0.0.tgz",
+ "integrity": "sha512-WhYv5UEcZrbAtlsnPuChHUAsu/iBPOVaEVsntLBIdpibO0ddy8OzavZz3iL2xVvBZOpolujSliP65Kq0/7KIYw==",
+ "funding": [
+ {
+ "type": "GitHub Sponsors",
+ "url": "https://github.com/sponsors/unifiedjs"
+ },
+ {
+ "type": "OpenCollective",
+ "url": "https://opencollective.com/unified"
+ }
+ ],
+ "dependencies": {
+ "micromark-util-character": "^2.0.0",
+ "micromark-util-encode": "^2.0.0",
+ "micromark-util-symbol": "^2.0.0"
+ }
+ },
+ "node_modules/micromark-util-symbol": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz",
+ "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==",
+ "funding": [
+ {
+ "type": "GitHub Sponsors",
+ "url": "https://github.com/sponsors/unifiedjs"
+ },
+ {
+ "type": "OpenCollective",
+ "url": "https://opencollective.com/unified"
+ }
+ ]
+ },
+ "node_modules/micromark-util-types": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/micromark-util-types/-/micromark-util-types-2.0.0.tgz",
+ "integrity": "sha512-oNh6S2WMHWRZrmutsRmDDfkzKtxF+bc2VxLC9dvtrDIRFln627VsFP6fLMgTryGDljgLPjkrzQSDcPrjPyDJ5w==",
+ "funding": [
+ {
+ "type": "GitHub Sponsors",
+ "url": "https://github.com/sponsors/unifiedjs"
+ },
+ {
+ "type": "OpenCollective",
+ "url": "https://opencollective.com/unified"
+ }
+ ]
+ },
+ "node_modules/minisearch": {
+ "version": "7.1.0",
+ "resolved": "https://registry.npmjs.org/minisearch/-/minisearch-7.1.0.tgz",
+ "integrity": "sha512-tv7c/uefWdEhcu6hvrfTihflgeEi2tN6VV7HJnCjK6VxM75QQJh4t9FwJCsA2EsRS8LCnu3W87CuGPWMocOLCA=="
+ },
+ "node_modules/mitt": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/mitt/-/mitt-3.0.1.tgz",
+ "integrity": "sha512-vKivATfr97l2/QBCYAkXYDbrIWPM2IIKEl7YPhjCvKlG3kE2gm+uBo6nEXK3M5/Ffh/FLpKExzOQ3JJoJGFKBw=="
+ },
+ "node_modules/nanoid": {
+ "version": "3.3.7",
+ "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.7.tgz",
+ "integrity": "sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==",
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/ai"
+ }
+ ],
+ "bin": {
+ "nanoid": "bin/nanoid.cjs"
+ },
+ "engines": {
+ "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1"
+ }
+ },
+ "node_modules/oniguruma-to-js": {
+ "version": "0.4.3",
+ "resolved": "https://registry.npmjs.org/oniguruma-to-js/-/oniguruma-to-js-0.4.3.tgz",
+ "integrity": "sha512-X0jWUcAlxORhOqqBREgPMgnshB7ZGYszBNspP+tS9hPD3l13CdaXcHbgImoHUHlrvGx/7AvFEkTRhAGYh+jzjQ==",
+ "dependencies": {
+ "regex": "^4.3.2"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/antfu"
+ }
+ },
+ "node_modules/perfect-debounce": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/perfect-debounce/-/perfect-debounce-1.0.0.tgz",
+ "integrity": "sha512-xCy9V055GLEqoFaHoC1SoLIaLmWctgCUaBaWxDZ7/Zx4CTyX7cJQLJOok/orfjZAh9kEYpjJa4d0KcJmCbctZA=="
+ },
+ "node_modules/picocolors": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz",
+ "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA=="
+ },
+ "node_modules/postcss": {
+ "version": "8.4.47",
+ "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.47.tgz",
+ "integrity": "sha512-56rxCq7G/XfB4EkXq9Egn5GCqugWvDFjafDOThIdMBsI15iqPqR5r15TfSr1YPYeEI19YeaXMCbY6u88Y76GLQ==",
+ "funding": [
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/postcss/"
+ },
+ {
+ "type": "tidelift",
+ "url": "https://tidelift.com/funding/github/npm/postcss"
+ },
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/ai"
+ }
+ ],
+ "dependencies": {
+ "nanoid": "^3.3.7",
+ "picocolors": "^1.1.0",
+ "source-map-js": "^1.2.1"
+ },
+ "engines": {
+ "node": "^10 || ^12 || >=14"
+ }
+ },
+ "node_modules/preact": {
+ "version": "10.24.3",
+ "resolved": "https://registry.npmjs.org/preact/-/preact-10.24.3.tgz",
+ "integrity": "sha512-Z2dPnBnMUfyQfSQ+GBdsGa16hz35YmLmtTLhM169uW944hYL6xzTYkJjC07j+Wosz733pMWx0fgON3JNw1jJQA==",
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/preact"
+ }
+ },
+ "node_modules/property-information": {
+ "version": "6.5.0",
+ "resolved": "https://registry.npmjs.org/property-information/-/property-information-6.5.0.tgz",
+ "integrity": "sha512-PgTgs/BlvHxOu8QuEN7wi5A0OmXaBcHpmCSTehcs6Uuu9IkDIEo13Hy7n898RHfrQ49vKCoGeWZSaAK01nwVig==",
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/wooorm"
+ }
+ },
+ "node_modules/regex": {
+ "version": "4.3.3",
+ "resolved": "https://registry.npmjs.org/regex/-/regex-4.3.3.tgz",
+ "integrity": "sha512-r/AadFO7owAq1QJVeZ/nq9jNS1vyZt+6t1p/E59B56Rn2GCya+gr1KSyOzNL/er+r+B7phv5jG2xU2Nz1YkmJg=="
+ },
+ "node_modules/rfdc": {
+ "version": "1.4.1",
+ "resolved": "https://registry.npmjs.org/rfdc/-/rfdc-1.4.1.tgz",
+ "integrity": "sha512-q1b3N5QkRUWUl7iyylaaj3kOpIT0N2i9MqIEQXP73GVsN9cw3fdx8X63cEmWhJGi2PPCF23Ijp7ktmd39rawIA=="
+ },
+ "node_modules/rollup": {
+ "version": "4.24.3",
+ "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.24.3.tgz",
+ "integrity": "sha512-HBW896xR5HGmoksbi3JBDtmVzWiPAYqp7wip50hjQ67JbDz61nyoMPdqu1DvVW9asYb2M65Z20ZHsyJCMqMyDg==",
+ "dependencies": {
+ "@types/estree": "1.0.6"
+ },
+ "bin": {
+ "rollup": "dist/bin/rollup"
+ },
+ "engines": {
+ "node": ">=18.0.0",
+ "npm": ">=8.0.0"
+ },
+ "optionalDependencies": {
+ "@rollup/rollup-android-arm-eabi": "4.24.3",
+ "@rollup/rollup-android-arm64": "4.24.3",
+ "@rollup/rollup-darwin-arm64": "4.24.3",
+ "@rollup/rollup-darwin-x64": "4.24.3",
+ "@rollup/rollup-freebsd-arm64": "4.24.3",
+ "@rollup/rollup-freebsd-x64": "4.24.3",
+ "@rollup/rollup-linux-arm-gnueabihf": "4.24.3",
+ "@rollup/rollup-linux-arm-musleabihf": "4.24.3",
+ "@rollup/rollup-linux-arm64-gnu": "4.24.3",
+ "@rollup/rollup-linux-arm64-musl": "4.24.3",
+ "@rollup/rollup-linux-powerpc64le-gnu": "4.24.3",
+ "@rollup/rollup-linux-riscv64-gnu": "4.24.3",
+ "@rollup/rollup-linux-s390x-gnu": "4.24.3",
+ "@rollup/rollup-linux-x64-gnu": "4.24.3",
+ "@rollup/rollup-linux-x64-musl": "4.24.3",
+ "@rollup/rollup-win32-arm64-msvc": "4.24.3",
+ "@rollup/rollup-win32-ia32-msvc": "4.24.3",
+ "@rollup/rollup-win32-x64-msvc": "4.24.3",
+ "fsevents": "~2.3.2"
+ }
+ },
+ "node_modules/search-insights": {
+ "version": "2.17.2",
+ "resolved": "https://registry.npmjs.org/search-insights/-/search-insights-2.17.2.tgz",
+ "integrity": "sha512-zFNpOpUO+tY2D85KrxJ+aqwnIfdEGi06UH2+xEb+Bp9Mwznmauqc9djbnBibJO5mpfUPPa8st6Sx65+vbeO45g==",
+ "peer": true
+ },
+ "node_modules/shiki": {
+ "version": "1.22.2",
+ "resolved": "https://registry.npmjs.org/shiki/-/shiki-1.22.2.tgz",
+ "integrity": "sha512-3IZau0NdGKXhH2bBlUk4w1IHNxPh6A5B2sUpyY+8utLu2j/h1QpFkAaUA1bAMxOWWGtTWcAh531vnS4NJKS/lA==",
+ "dependencies": {
+ "@shikijs/core": "1.22.2",
+ "@shikijs/engine-javascript": "1.22.2",
+ "@shikijs/engine-oniguruma": "1.22.2",
+ "@shikijs/types": "1.22.2",
+ "@shikijs/vscode-textmate": "^9.3.0",
+ "@types/hast": "^3.0.4"
+ }
+ },
+ "node_modules/source-map-js": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz",
+ "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/space-separated-tokens": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/space-separated-tokens/-/space-separated-tokens-2.0.2.tgz",
+ "integrity": "sha512-PEGlAwrG8yXGXRjW32fGbg66JAlOAwbObuqVoJpv/mRgoWDQfgH1wDPvtzWyUSNAXBGSk8h755YDbbcEy3SH2Q==",
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/wooorm"
+ }
+ },
+ "node_modules/speakingurl": {
+ "version": "14.0.1",
+ "resolved": "https://registry.npmjs.org/speakingurl/-/speakingurl-14.0.1.tgz",
+ "integrity": "sha512-1POYv7uv2gXoyGFpBCmpDVSNV74IfsWlDW216UPjbWufNf+bSU6GdbDsxdcxtfwb4xlI3yxzOTKClUosxARYrQ==",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/stringify-entities": {
+ "version": "4.0.4",
+ "resolved": "https://registry.npmjs.org/stringify-entities/-/stringify-entities-4.0.4.tgz",
+ "integrity": "sha512-IwfBptatlO+QCJUo19AqvrPNqlVMpW9YEL2LIVY+Rpv2qsjCGxaDLNRgeGsQWJhfItebuJhsGSLjaBbNSQ+ieg==",
+ "dependencies": {
+ "character-entities-html4": "^2.0.0",
+ "character-entities-legacy": "^3.0.0"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/wooorm"
+ }
+ },
+ "node_modules/superjson": {
+ "version": "2.2.1",
+ "resolved": "https://registry.npmjs.org/superjson/-/superjson-2.2.1.tgz",
+ "integrity": "sha512-8iGv75BYOa0xRJHK5vRLEjE2H/i4lulTjzpUXic3Eg8akftYjkmQDa8JARQ42rlczXyFR3IeRoeFCc7RxHsYZA==",
+ "dependencies": {
+ "copy-anything": "^3.0.2"
+ },
+ "engines": {
+ "node": ">=16"
+ }
+ },
+ "node_modules/tabbable": {
+ "version": "6.2.0",
+ "resolved": "https://registry.npmjs.org/tabbable/-/tabbable-6.2.0.tgz",
+ "integrity": "sha512-Cat63mxsVJlzYvN51JmVXIgNoUokrIaT2zLclCXjRd8boZ0004U4KCs/sToJ75C6sdlByWxpYnb5Boif1VSFew=="
+ },
+ "node_modules/trim-lines": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/trim-lines/-/trim-lines-3.0.1.tgz",
+ "integrity": "sha512-kRj8B+YHZCc9kQYdWfJB2/oUl9rA99qbowYYBtr4ui4mZyAQ2JpvVBd/6U2YloATfqBhBTSMhTpgBHtU0Mf3Rg==",
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/wooorm"
+ }
+ },
+ "node_modules/unist-util-is": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-6.0.0.tgz",
+ "integrity": "sha512-2qCTHimwdxLfz+YzdGfkqNlH0tLi9xjTnHddPmJwtIG9MGsdbutfTc4P+haPD7l7Cjxf/WZj+we5qfVPvvxfYw==",
+ "dependencies": {
+ "@types/unist": "^3.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/unified"
+ }
+ },
+ "node_modules/unist-util-position": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/unist-util-position/-/unist-util-position-5.0.0.tgz",
+ "integrity": "sha512-fucsC7HjXvkB5R3kTCO7kUjRdrS0BJt3M/FPxmHMBOm8JQi2BsHAHFsy27E0EolP8rp0NzXsJ+jNPyDWvOJZPA==",
+ "dependencies": {
+ "@types/unist": "^3.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/unified"
+ }
+ },
+ "node_modules/unist-util-stringify-position": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-4.0.0.tgz",
+ "integrity": "sha512-0ASV06AAoKCDkS2+xw5RXJywruurpbC4JZSm7nr7MOt1ojAzvyyaO+UxZf18j8FCF6kmzCZKcAgN/yu2gm2XgQ==",
+ "dependencies": {
+ "@types/unist": "^3.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/unified"
+ }
+ },
+ "node_modules/unist-util-visit": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-5.0.0.tgz",
+ "integrity": "sha512-MR04uvD+07cwl/yhVuVWAtw+3GOR/knlL55Nd/wAdblk27GCVt3lqpTivy/tkJcZoNPzTwS1Y+KMojlLDhoTzg==",
+ "dependencies": {
+ "@types/unist": "^3.0.0",
+ "unist-util-is": "^6.0.0",
+ "unist-util-visit-parents": "^6.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/unified"
+ }
+ },
+ "node_modules/unist-util-visit-parents": {
+ "version": "6.0.1",
+ "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-6.0.1.tgz",
+ "integrity": "sha512-L/PqWzfTP9lzzEa6CKs0k2nARxTdZduw3zyh8d2NVBnsyvHjSX4TWse388YrrQKbvI8w20fGjGlhgT96WwKykw==",
+ "dependencies": {
+ "@types/unist": "^3.0.0",
+ "unist-util-is": "^6.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/unified"
+ }
+ },
+ "node_modules/vfile": {
+ "version": "6.0.3",
+ "resolved": "https://registry.npmjs.org/vfile/-/vfile-6.0.3.tgz",
+ "integrity": "sha512-KzIbH/9tXat2u30jf+smMwFCsno4wHVdNmzFyL+T/L3UGqqk6JKfVqOFOZEpZSHADH1k40ab6NUIXZq422ov3Q==",
+ "dependencies": {
+ "@types/unist": "^3.0.0",
+ "vfile-message": "^4.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/unified"
+ }
+ },
+ "node_modules/vfile-message": {
+ "version": "4.0.2",
+ "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-4.0.2.tgz",
+ "integrity": "sha512-jRDZ1IMLttGj41KcZvlrYAaI3CfqpLpfpf+Mfig13viT6NKvRzWZ+lXz0Y5D60w6uJIBAOGq9mSHf0gktF0duw==",
+ "dependencies": {
+ "@types/unist": "^3.0.0",
+ "unist-util-stringify-position": "^4.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/unified"
+ }
+ },
+ "node_modules/vite": {
+ "version": "5.4.10",
+ "resolved": "https://registry.npmjs.org/vite/-/vite-5.4.10.tgz",
+ "integrity": "sha512-1hvaPshuPUtxeQ0hsVH3Mud0ZanOLwVTneA1EgbAM5LhaZEqyPWGRQ7BtaMvUrTDeEaC8pxtj6a6jku3x4z6SQ==",
+ "dependencies": {
+ "esbuild": "^0.21.3",
+ "postcss": "^8.4.43",
+ "rollup": "^4.20.0"
+ },
+ "bin": {
+ "vite": "bin/vite.js"
+ },
+ "engines": {
+ "node": "^18.0.0 || >=20.0.0"
+ },
+ "funding": {
+ "url": "https://github.com/vitejs/vite?sponsor=1"
+ },
+ "optionalDependencies": {
+ "fsevents": "~2.3.3"
+ },
+ "peerDependencies": {
+ "@types/node": "^18.0.0 || >=20.0.0",
+ "less": "*",
+ "lightningcss": "^1.21.0",
+ "sass": "*",
+ "sass-embedded": "*",
+ "stylus": "*",
+ "sugarss": "*",
+ "terser": "^5.4.0"
+ },
+ "peerDependenciesMeta": {
+ "@types/node": {
+ "optional": true
+ },
+ "less": {
+ "optional": true
+ },
+ "lightningcss": {
+ "optional": true
+ },
+ "sass": {
+ "optional": true
+ },
+ "sass-embedded": {
+ "optional": true
+ },
+ "stylus": {
+ "optional": true
+ },
+ "sugarss": {
+ "optional": true
+ },
+ "terser": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/vitepress": {
+ "version": "1.4.3",
+ "resolved": "https://registry.npmjs.org/vitepress/-/vitepress-1.4.3.tgz",
+ "integrity": "sha512-956c2K2Mr0ubY9bTc2lCJD3g0mgo0mARB1iJC/BqUt4s0AM8Wl60wSU4zbFnzV7X2miFK1XJDKzGZnuEN90umw==",
+ "dependencies": {
+ "@docsearch/css": "^3.6.2",
+ "@docsearch/js": "^3.6.2",
+ "@shikijs/core": "^1.22.2",
+ "@shikijs/transformers": "^1.22.2",
+ "@shikijs/types": "^1.22.2",
+ "@types/markdown-it": "^14.1.2",
+ "@vitejs/plugin-vue": "^5.1.4",
+ "@vue/devtools-api": "^7.5.4",
+ "@vue/shared": "^3.5.12",
+ "@vueuse/core": "^11.1.0",
+ "@vueuse/integrations": "^11.1.0",
+ "focus-trap": "^7.6.0",
+ "mark.js": "8.11.1",
+ "minisearch": "^7.1.0",
+ "shiki": "^1.22.2",
+ "vite": "^5.4.10",
+ "vue": "^3.5.12"
+ },
+ "bin": {
+ "vitepress": "bin/vitepress.js"
+ },
+ "peerDependencies": {
+ "markdown-it-mathjax3": "^4",
+ "postcss": "^8"
+ },
+ "peerDependenciesMeta": {
+ "markdown-it-mathjax3": {
+ "optional": true
+ },
+ "postcss": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/vue": {
+ "version": "3.5.12",
+ "resolved": "https://registry.npmjs.org/vue/-/vue-3.5.12.tgz",
+ "integrity": "sha512-CLVZtXtn2ItBIi/zHZ0Sg1Xkb7+PU32bJJ8Bmy7ts3jxXTcbfsEfBivFYYWz1Hur+lalqGAh65Coin0r+HRUfg==",
+ "dependencies": {
+ "@vue/compiler-dom": "3.5.12",
+ "@vue/compiler-sfc": "3.5.12",
+ "@vue/runtime-dom": "3.5.12",
+ "@vue/server-renderer": "3.5.12",
+ "@vue/shared": "3.5.12"
+ },
+ "peerDependencies": {
+ "typescript": "*"
+ },
+ "peerDependenciesMeta": {
+ "typescript": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/zwitch": {
+ "version": "2.0.4",
+ "resolved": "https://registry.npmjs.org/zwitch/-/zwitch-2.0.4.tgz",
+ "integrity": "sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A==",
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/wooorm"
+ }
+ }
+ },
+ "dependencies": {
+ "@algolia/autocomplete-core": {
+ "version": "1.9.3",
+ "resolved": "https://registry.npmjs.org/@algolia/autocomplete-core/-/autocomplete-core-1.9.3.tgz",
+ "integrity": "sha512-009HdfugtGCdC4JdXUbVJClA0q0zh24yyePn+KUGk3rP7j8FEe/m5Yo/z65gn6nP/cM39PxpzqKrL7A6fP6PPw==",
+ "requires": {
+ "@algolia/autocomplete-plugin-algolia-insights": "1.9.3",
+ "@algolia/autocomplete-shared": "1.9.3"
+ }
+ },
+ "@algolia/autocomplete-plugin-algolia-insights": {
+ "version": "1.9.3",
+ "resolved": "https://registry.npmjs.org/@algolia/autocomplete-plugin-algolia-insights/-/autocomplete-plugin-algolia-insights-1.9.3.tgz",
+ "integrity": "sha512-a/yTUkcO/Vyy+JffmAnTWbr4/90cLzw+CC3bRbhnULr/EM0fGNvM13oQQ14f2moLMcVDyAx/leczLlAOovhSZg==",
+ "requires": {
+ "@algolia/autocomplete-shared": "1.9.3"
+ }
+ },
+ "@algolia/autocomplete-preset-algolia": {
+ "version": "1.17.6",
+ "resolved": "https://registry.npmjs.org/@algolia/autocomplete-preset-algolia/-/autocomplete-preset-algolia-1.17.6.tgz",
+ "integrity": "sha512-Cvg5JENdSCMuClwhJ1ON1/jSuojaYMiUW2KePm18IkdCzPJj/NXojaOxw58RFtQFpJgfVW8h2E8mEoDtLlMdeA==",
+ "requires": {
+ "@algolia/autocomplete-shared": "1.17.6"
+ },
+ "dependencies": {
+ "@algolia/autocomplete-shared": {
+ "version": "1.17.6",
+ "resolved": "https://registry.npmjs.org/@algolia/autocomplete-shared/-/autocomplete-shared-1.17.6.tgz",
+ "integrity": "sha512-aq/3V9E00Tw2GC/PqgyPGXtqJUlVc17v4cn1EUhSc+O/4zd04Uwb3UmPm8KDaYQQOrkt1lwvCj2vG2wRE5IKhw==",
+ "requires": {}
+ }
+ }
+ },
+ "@algolia/autocomplete-shared": {
+ "version": "1.9.3",
+ "resolved": "https://registry.npmjs.org/@algolia/autocomplete-shared/-/autocomplete-shared-1.9.3.tgz",
+ "integrity": "sha512-Wnm9E4Ye6Rl6sTTqjoymD+l8DjSTHsHboVRYrKgEt8Q7UHm9nYbqhN/i0fhUYA3OAEH7WA8x3jfpnmJm3rKvaQ==",
+ "requires": {}
+ },
+ "@algolia/client-abtesting": {
+ "version": "5.12.0",
+ "resolved": "https://registry.npmjs.org/@algolia/client-abtesting/-/client-abtesting-5.12.0.tgz",
+ "integrity": "sha512-hx4eVydkm3yrFCFxmcBtSzI/ykt0cZ6sDWch+v3JTgKpD2WtosMJU3Upv1AjQ4B6COSHCOWEX3vfFxW6OoH6aA==",
+ "requires": {
+ "@algolia/client-common": "5.12.0",
+ "@algolia/requester-browser-xhr": "5.12.0",
+ "@algolia/requester-fetch": "5.12.0",
+ "@algolia/requester-node-http": "5.12.0"
+ }
+ },
+ "@algolia/client-analytics": {
+ "version": "5.12.0",
+ "resolved": "https://registry.npmjs.org/@algolia/client-analytics/-/client-analytics-5.12.0.tgz",
+ "integrity": "sha512-EpTsSv6IW8maCfXCDIptgT7+mQJj7pImEkcNUnxR8yUKAHzTogTXv9yGm2WXOZFVuwstd2i0sImhQ1Vz8RH/hA==",
+ "requires": {
+ "@algolia/client-common": "5.12.0",
+ "@algolia/requester-browser-xhr": "5.12.0",
+ "@algolia/requester-fetch": "5.12.0",
+ "@algolia/requester-node-http": "5.12.0"
+ }
+ },
+ "@algolia/client-common": {
+ "version": "5.12.0",
+ "resolved": "https://registry.npmjs.org/@algolia/client-common/-/client-common-5.12.0.tgz",
+ "integrity": "sha512-od3WmO8qxyfNhKc+K3D17tvun3IMs/xMNmxCG9MiElAkYVbPPTRUYMkRneCpmJyQI0hNx2/EA4kZgzVfQjO86Q=="
+ },
+ "@algolia/client-insights": {
+ "version": "5.12.0",
+ "resolved": "https://registry.npmjs.org/@algolia/client-insights/-/client-insights-5.12.0.tgz",
+ "integrity": "sha512-8alajmsYUd+7vfX5lpRNdxqv3Xx9clIHLUItyQK0Z6gwGMbVEFe6YYhgDtwslMAP0y6b0WeJEIZJMLgT7VYpRw==",
+ "requires": {
+ "@algolia/client-common": "5.12.0",
+ "@algolia/requester-browser-xhr": "5.12.0",
+ "@algolia/requester-fetch": "5.12.0",
+ "@algolia/requester-node-http": "5.12.0"
+ }
+ },
+ "@algolia/client-personalization": {
+ "version": "5.12.0",
+ "resolved": "https://registry.npmjs.org/@algolia/client-personalization/-/client-personalization-5.12.0.tgz",
+ "integrity": "sha512-bUV9HtfkTBgpoVhxFrMkmVPG03ZN1Rtn51kiaEtukucdk3ggjR9Qu1YUfRSU2lFgxr9qJc8lTxwfvhjCeJRcqw==",
+ "requires": {
+ "@algolia/client-common": "5.12.0",
+ "@algolia/requester-browser-xhr": "5.12.0",
+ "@algolia/requester-fetch": "5.12.0",
+ "@algolia/requester-node-http": "5.12.0"
+ }
+ },
+ "@algolia/client-query-suggestions": {
+ "version": "5.12.0",
+ "resolved": "https://registry.npmjs.org/@algolia/client-query-suggestions/-/client-query-suggestions-5.12.0.tgz",
+ "integrity": "sha512-Q5CszzGWfxbIDs9DJ/QJsL7bP6h+lJMg27KxieEnI9KGCu0Jt5iFA3GkREkgRZxRdzlHbZKkrIzhtHVbSHw/rg==",
+ "requires": {
+ "@algolia/client-common": "5.12.0",
+ "@algolia/requester-browser-xhr": "5.12.0",
+ "@algolia/requester-fetch": "5.12.0",
+ "@algolia/requester-node-http": "5.12.0"
+ }
+ },
+ "@algolia/client-search": {
+ "version": "5.12.0",
+ "resolved": "https://registry.npmjs.org/@algolia/client-search/-/client-search-5.12.0.tgz",
+ "integrity": "sha512-R3qzEytgVLHOGNri+bpta6NtTt7YtkvUe/QBcAmMDjW4Jk1P0eBYIPfvnzIPbINRsLxIq9fZs9uAYBgsrts4Zg==",
+ "requires": {
+ "@algolia/client-common": "5.12.0",
+ "@algolia/requester-browser-xhr": "5.12.0",
+ "@algolia/requester-fetch": "5.12.0",
+ "@algolia/requester-node-http": "5.12.0"
+ }
+ },
+ "@algolia/ingestion": {
+ "version": "1.12.0",
+ "resolved": "https://registry.npmjs.org/@algolia/ingestion/-/ingestion-1.12.0.tgz",
+ "integrity": "sha512-zpHo6qhR22tL8FsdSI4DvEraPDi/019HmMrCFB/TUX98yzh5ooAU7sNW0qPL1I7+S++VbBmNzJOEU9VI8tEC8A==",
+ "requires": {
+ "@algolia/client-common": "5.12.0",
+ "@algolia/requester-browser-xhr": "5.12.0",
+ "@algolia/requester-fetch": "5.12.0",
+ "@algolia/requester-node-http": "5.12.0"
+ }
+ },
+ "@algolia/monitoring": {
+ "version": "1.12.0",
+ "resolved": "https://registry.npmjs.org/@algolia/monitoring/-/monitoring-1.12.0.tgz",
+ "integrity": "sha512-i2AJZED/zf4uhxezAJUhMKoL5QoepCBp2ynOYol0N76+TSoohaMADdPnWCqOULF4RzOwrG8wWynAwBlXsAI1RQ==",
+ "requires": {
+ "@algolia/client-common": "5.12.0",
+ "@algolia/requester-browser-xhr": "5.12.0",
+ "@algolia/requester-fetch": "5.12.0",
+ "@algolia/requester-node-http": "5.12.0"
+ }
+ },
+ "@algolia/recommend": {
+ "version": "5.12.0",
+ "resolved": "https://registry.npmjs.org/@algolia/recommend/-/recommend-5.12.0.tgz",
+ "integrity": "sha512-0jmZyKvYnB/Bj5c7WKsKedOUjnr0UtXm0LVFUdQrxXfqOqvWv9n6Vpr65UjdYG4Q49kRQxhlwtal9WJYrYymXg==",
+ "requires": {
+ "@algolia/client-common": "5.12.0",
+ "@algolia/requester-browser-xhr": "5.12.0",
+ "@algolia/requester-fetch": "5.12.0",
+ "@algolia/requester-node-http": "5.12.0"
+ }
+ },
+ "@algolia/requester-browser-xhr": {
+ "version": "5.12.0",
+ "resolved": "https://registry.npmjs.org/@algolia/requester-browser-xhr/-/requester-browser-xhr-5.12.0.tgz",
+ "integrity": "sha512-KxwleraFuVoEGCoeW6Y1RAEbgBMS7SavqeyzWdtkJc6mXeCOJXn1iZitb8Tyn2FcpMNUKlSm0adrUTt7G47+Ow==",
+ "requires": {
+ "@algolia/client-common": "5.12.0"
+ }
+ },
+ "@algolia/requester-fetch": {
+ "version": "5.12.0",
+ "resolved": "https://registry.npmjs.org/@algolia/requester-fetch/-/requester-fetch-5.12.0.tgz",
+ "integrity": "sha512-FuDZXUGU1pAg2HCnrt8+q1VGHKChV/LhvjvZlLOT7e56GJie6p+EuLu4/hMKPOVuQQ8XXtrTHKIU3Lw+7O5/bQ==",
+ "requires": {
+ "@algolia/client-common": "5.12.0"
+ }
+ },
+ "@algolia/requester-node-http": {
+ "version": "5.12.0",
+ "resolved": "https://registry.npmjs.org/@algolia/requester-node-http/-/requester-node-http-5.12.0.tgz",
+ "integrity": "sha512-ncDDY7CxZhMs6LIoPl+vHFQceIBhYPY5EfuGF1V7beO0U38xfsCYEyutEFB2kRzf4D9Gqppn3iWX71sNtrKcuw==",
+ "requires": {
+ "@algolia/client-common": "5.12.0"
+ }
+ },
+ "@babel/helper-string-parser": {
+ "version": "7.25.9",
+ "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.25.9.tgz",
+ "integrity": "sha512-4A/SCr/2KLd5jrtOMFzaKjVtAei3+2r/NChoBNoZ3EyP/+GlhoaEGoWOZUmFmoITP7zOJyHIMm+DYRd8o3PvHA=="
+ },
+ "@babel/helper-validator-identifier": {
+ "version": "7.25.9",
+ "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.25.9.tgz",
+ "integrity": "sha512-Ed61U6XJc3CVRfkERJWDz4dJwKe7iLmmJsbOGu9wSloNSFttHV0I8g6UAgb7qnK5ly5bGLPd4oXZlxCdANBOWQ=="
+ },
+ "@babel/parser": {
+ "version": "7.26.2",
+ "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.26.2.tgz",
+ "integrity": "sha512-DWMCZH9WA4Maitz2q21SRKHo9QXZxkDsbNZoVD62gusNtNBBqDg9i7uOhASfTfIGNzW+O+r7+jAlM8dwphcJKQ==",
+ "requires": {
+ "@babel/types": "^7.26.0"
+ }
+ },
+ "@babel/types": {
+ "version": "7.26.0",
+ "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.26.0.tgz",
+ "integrity": "sha512-Z/yiTPj+lDVnF7lWeKCIJzaIkI0vYO87dMpZ4bg4TDrFe4XXLFWL1TbXU27gBP3QccxV9mZICCrnjnYlJjXHOA==",
+ "requires": {
+ "@babel/helper-string-parser": "^7.25.9",
+ "@babel/helper-validator-identifier": "^7.25.9"
+ }
+ },
+ "@docsearch/css": {
+ "version": "3.6.3",
+ "resolved": "https://registry.npmjs.org/@docsearch/css/-/css-3.6.3.tgz",
+ "integrity": "sha512-3uvbg8E7rhqE1C4oBAK3tGlS2qfhi9zpfZgH/yjDPF73vd9B41urVIKujF4rczcF4E3qs34SedhehiDJ4UdNBA=="
+ },
+ "@docsearch/js": {
+ "version": "3.6.3",
+ "resolved": "https://registry.npmjs.org/@docsearch/js/-/js-3.6.3.tgz",
+ "integrity": "sha512-2mBFomaN6VijyQQGwieERDu9GeE0hlv9TQRZBTOYsPQW7/vqtd4hnHEkbBbaBRiS4PYcy+UhikbMuDExJs63UA==",
+ "requires": {
+ "@docsearch/react": "3.6.3",
+ "preact": "^10.0.0"
+ }
+ },
+ "@docsearch/react": {
+ "version": "3.6.3",
+ "resolved": "https://registry.npmjs.org/@docsearch/react/-/react-3.6.3.tgz",
+ "integrity": "sha512-2munr4uBuZq1PG+Ge+F+ldIdxb3Wi8OmEIv2tQQb4RvEvvph+xtQkxwHzVIEnt5s+HecwucuXwB+3JhcZboFLg==",
+ "requires": {
+ "@algolia/autocomplete-core": "1.9.3",
+ "@algolia/autocomplete-preset-algolia": "1.17.6",
+ "@docsearch/css": "3.6.3",
+ "algoliasearch": "^5.11.0"
+ }
+ },
+ "@esbuild/aix-ppc64": {
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.21.5.tgz",
+ "integrity": "sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ==",
+ "optional": true
+ },
+ "@esbuild/android-arm": {
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.21.5.tgz",
+ "integrity": "sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg==",
+ "optional": true
+ },
+ "@esbuild/android-arm64": {
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.21.5.tgz",
+ "integrity": "sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A==",
+ "optional": true
+ },
+ "@esbuild/android-x64": {
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.21.5.tgz",
+ "integrity": "sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA==",
+ "optional": true
+ },
+ "@esbuild/darwin-arm64": {
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.21.5.tgz",
+ "integrity": "sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ==",
+ "optional": true
+ },
+ "@esbuild/darwin-x64": {
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.21.5.tgz",
+ "integrity": "sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw==",
+ "optional": true
+ },
+ "@esbuild/freebsd-arm64": {
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.21.5.tgz",
+ "integrity": "sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g==",
+ "optional": true
+ },
+ "@esbuild/freebsd-x64": {
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.21.5.tgz",
+ "integrity": "sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ==",
+ "optional": true
+ },
+ "@esbuild/linux-arm": {
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.21.5.tgz",
+ "integrity": "sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA==",
+ "optional": true
+ },
+ "@esbuild/linux-arm64": {
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.21.5.tgz",
+ "integrity": "sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q==",
+ "optional": true
+ },
+ "@esbuild/linux-ia32": {
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.21.5.tgz",
+ "integrity": "sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg==",
+ "optional": true
+ },
+ "@esbuild/linux-loong64": {
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.21.5.tgz",
+ "integrity": "sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg==",
+ "optional": true
+ },
+ "@esbuild/linux-mips64el": {
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.21.5.tgz",
+ "integrity": "sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg==",
+ "optional": true
+ },
+ "@esbuild/linux-ppc64": {
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.21.5.tgz",
+ "integrity": "sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w==",
+ "optional": true
+ },
+ "@esbuild/linux-riscv64": {
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.21.5.tgz",
+ "integrity": "sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA==",
+ "optional": true
+ },
+ "@esbuild/linux-s390x": {
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.21.5.tgz",
+ "integrity": "sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A==",
+ "optional": true
+ },
+ "@esbuild/linux-x64": {
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.21.5.tgz",
+ "integrity": "sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ==",
+ "optional": true
+ },
+ "@esbuild/netbsd-x64": {
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.21.5.tgz",
+ "integrity": "sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg==",
+ "optional": true
+ },
+ "@esbuild/openbsd-x64": {
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.21.5.tgz",
+ "integrity": "sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow==",
+ "optional": true
+ },
+ "@esbuild/sunos-x64": {
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.21.5.tgz",
+ "integrity": "sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg==",
+ "optional": true
+ },
+ "@esbuild/win32-arm64": {
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.21.5.tgz",
+ "integrity": "sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A==",
+ "optional": true
+ },
+ "@esbuild/win32-ia32": {
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.21.5.tgz",
+ "integrity": "sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA==",
+ "optional": true
+ },
+ "@esbuild/win32-x64": {
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.21.5.tgz",
+ "integrity": "sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw==",
+ "optional": true
+ },
+ "@jridgewell/sourcemap-codec": {
+ "version": "1.5.0",
+ "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz",
+ "integrity": "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ=="
+ },
+ "@rollup/rollup-android-arm-eabi": {
+ "version": "4.24.3",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.24.3.tgz",
+ "integrity": "sha512-ufb2CH2KfBWPJok95frEZZ82LtDl0A6QKTa8MoM+cWwDZvVGl5/jNb79pIhRvAalUu+7LD91VYR0nwRD799HkQ==",
+ "optional": true
+ },
+ "@rollup/rollup-android-arm64": {
+ "version": "4.24.3",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.24.3.tgz",
+ "integrity": "sha512-iAHpft/eQk9vkWIV5t22V77d90CRofgR2006UiCjHcHJFVI1E0oBkQIAbz+pLtthFw3hWEmVB4ilxGyBf48i2Q==",
+ "optional": true
+ },
+ "@rollup/rollup-darwin-arm64": {
+ "version": "4.24.3",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.24.3.tgz",
+ "integrity": "sha512-QPW2YmkWLlvqmOa2OwrfqLJqkHm7kJCIMq9kOz40Zo9Ipi40kf9ONG5Sz76zszrmIZZ4hgRIkez69YnTHgEz1w==",
+ "optional": true
+ },
+ "@rollup/rollup-darwin-x64": {
+ "version": "4.24.3",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.24.3.tgz",
+ "integrity": "sha512-KO0pN5x3+uZm1ZXeIfDqwcvnQ9UEGN8JX5ufhmgH5Lz4ujjZMAnxQygZAVGemFWn+ZZC0FQopruV4lqmGMshow==",
+ "optional": true
+ },
+ "@rollup/rollup-freebsd-arm64": {
+ "version": "4.24.3",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.24.3.tgz",
+ "integrity": "sha512-CsC+ZdIiZCZbBI+aRlWpYJMSWvVssPuWqrDy/zi9YfnatKKSLFCe6fjna1grHuo/nVaHG+kiglpRhyBQYRTK4A==",
+ "optional": true
+ },
+ "@rollup/rollup-freebsd-x64": {
+ "version": "4.24.3",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.24.3.tgz",
+ "integrity": "sha512-F0nqiLThcfKvRQhZEzMIXOQG4EeX61im61VYL1jo4eBxv4aZRmpin6crnBJQ/nWnCsjH5F6J3W6Stdm0mBNqBg==",
+ "optional": true
+ },
+ "@rollup/rollup-linux-arm-gnueabihf": {
+ "version": "4.24.3",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.24.3.tgz",
+ "integrity": "sha512-KRSFHyE/RdxQ1CSeOIBVIAxStFC/hnBgVcaiCkQaVC+EYDtTe4X7z5tBkFyRoBgUGtB6Xg6t9t2kulnX6wJc6A==",
+ "optional": true
+ },
+ "@rollup/rollup-linux-arm-musleabihf": {
+ "version": "4.24.3",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.24.3.tgz",
+ "integrity": "sha512-h6Q8MT+e05zP5BxEKz0vi0DhthLdrNEnspdLzkoFqGwnmOzakEHSlXfVyA4HJ322QtFy7biUAVFPvIDEDQa6rw==",
+ "optional": true
+ },
+ "@rollup/rollup-linux-arm64-gnu": {
+ "version": "4.24.3",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.24.3.tgz",
+ "integrity": "sha512-fKElSyXhXIJ9pqiYRqisfirIo2Z5pTTve5K438URf08fsypXrEkVmShkSfM8GJ1aUyvjakT+fn2W7Czlpd/0FQ==",
+ "optional": true
+ },
+ "@rollup/rollup-linux-arm64-musl": {
+ "version": "4.24.3",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.24.3.tgz",
+ "integrity": "sha512-YlddZSUk8G0px9/+V9PVilVDC6ydMz7WquxozToozSnfFK6wa6ne1ATUjUvjin09jp34p84milxlY5ikueoenw==",
+ "optional": true
+ },
+ "@rollup/rollup-linux-powerpc64le-gnu": {
+ "version": "4.24.3",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.24.3.tgz",
+ "integrity": "sha512-yNaWw+GAO8JjVx3s3cMeG5Esz1cKVzz8PkTJSfYzE5u7A+NvGmbVFEHP+BikTIyYWuz0+DX9kaA3pH9Sqxp69g==",
+ "optional": true
+ },
+ "@rollup/rollup-linux-riscv64-gnu": {
+ "version": "4.24.3",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.24.3.tgz",
+ "integrity": "sha512-lWKNQfsbpv14ZCtM/HkjCTm4oWTKTfxPmr7iPfp3AHSqyoTz5AgLemYkWLwOBWc+XxBbrU9SCokZP0WlBZM9lA==",
+ "optional": true
+ },
+ "@rollup/rollup-linux-s390x-gnu": {
+ "version": "4.24.3",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.24.3.tgz",
+ "integrity": "sha512-HoojGXTC2CgCcq0Woc/dn12wQUlkNyfH0I1ABK4Ni9YXyFQa86Fkt2Q0nqgLfbhkyfQ6003i3qQk9pLh/SpAYw==",
+ "optional": true
+ },
+ "@rollup/rollup-linux-x64-gnu": {
+ "version": "4.24.3",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.24.3.tgz",
+ "integrity": "sha512-mnEOh4iE4USSccBOtcrjF5nj+5/zm6NcNhbSEfR3Ot0pxBwvEn5QVUXcuOwwPkapDtGZ6pT02xLoPaNv06w7KQ==",
+ "optional": true
+ },
+ "@rollup/rollup-linux-x64-musl": {
+ "version": "4.24.3",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.24.3.tgz",
+ "integrity": "sha512-rMTzawBPimBQkG9NKpNHvquIUTQPzrnPxPbCY1Xt+mFkW7pshvyIS5kYgcf74goxXOQk0CP3EoOC1zcEezKXhw==",
+ "optional": true
+ },
+ "@rollup/rollup-win32-arm64-msvc": {
+ "version": "4.24.3",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.24.3.tgz",
+ "integrity": "sha512-2lg1CE305xNvnH3SyiKwPVsTVLCg4TmNCF1z7PSHX2uZY2VbUpdkgAllVoISD7JO7zu+YynpWNSKAtOrX3AiuA==",
+ "optional": true
+ },
+ "@rollup/rollup-win32-ia32-msvc": {
+ "version": "4.24.3",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.24.3.tgz",
+ "integrity": "sha512-9SjYp1sPyxJsPWuhOCX6F4jUMXGbVVd5obVpoVEi8ClZqo52ViZewA6eFz85y8ezuOA+uJMP5A5zo6Oz4S5rVQ==",
+ "optional": true
+ },
+ "@rollup/rollup-win32-x64-msvc": {
+ "version": "4.24.3",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.24.3.tgz",
+ "integrity": "sha512-HGZgRFFYrMrP3TJlq58nR1xy8zHKId25vhmm5S9jETEfDf6xybPxsavFTJaufe2zgOGYJBskGlj49CwtEuFhWQ==",
+ "optional": true
+ },
+ "@shikijs/core": {
+ "version": "1.22.2",
+ "resolved": "https://registry.npmjs.org/@shikijs/core/-/core-1.22.2.tgz",
+ "integrity": "sha512-bvIQcd8BEeR1yFvOYv6HDiyta2FFVePbzeowf5pPS1avczrPK+cjmaxxh0nx5QzbON7+Sv0sQfQVciO7bN72sg==",
+ "requires": {
+ "@shikijs/engine-javascript": "1.22.2",
+ "@shikijs/engine-oniguruma": "1.22.2",
+ "@shikijs/types": "1.22.2",
+ "@shikijs/vscode-textmate": "^9.3.0",
+ "@types/hast": "^3.0.4",
+ "hast-util-to-html": "^9.0.3"
+ }
+ },
+ "@shikijs/engine-javascript": {
+ "version": "1.22.2",
+ "resolved": "https://registry.npmjs.org/@shikijs/engine-javascript/-/engine-javascript-1.22.2.tgz",
+ "integrity": "sha512-iOvql09ql6m+3d1vtvP8fLCVCK7BQD1pJFmHIECsujB0V32BJ0Ab6hxk1ewVSMFA58FI0pR2Had9BKZdyQrxTw==",
+ "requires": {
+ "@shikijs/types": "1.22.2",
+ "@shikijs/vscode-textmate": "^9.3.0",
+ "oniguruma-to-js": "0.4.3"
+ }
+ },
+ "@shikijs/engine-oniguruma": {
+ "version": "1.22.2",
+ "resolved": "https://registry.npmjs.org/@shikijs/engine-oniguruma/-/engine-oniguruma-1.22.2.tgz",
+ "integrity": "sha512-GIZPAGzQOy56mGvWMoZRPggn0dTlBf1gutV5TdceLCZlFNqWmuc7u+CzD0Gd9vQUTgLbrt0KLzz6FNprqYAxlA==",
+ "requires": {
+ "@shikijs/types": "1.22.2",
+ "@shikijs/vscode-textmate": "^9.3.0"
+ }
+ },
+ "@shikijs/transformers": {
+ "version": "1.22.2",
+ "resolved": "https://registry.npmjs.org/@shikijs/transformers/-/transformers-1.22.2.tgz",
+ "integrity": "sha512-8f78OiBa6pZDoZ53lYTmuvpFPlWtevn23bzG+azpPVvZg7ITax57o/K3TC91eYL3OMJOO0onPbgnQyZjRos8XQ==",
+ "requires": {
+ "shiki": "1.22.2"
+ }
+ },
+ "@shikijs/types": {
+ "version": "1.22.2",
+ "resolved": "https://registry.npmjs.org/@shikijs/types/-/types-1.22.2.tgz",
+ "integrity": "sha512-NCWDa6LGZqTuzjsGfXOBWfjS/fDIbDdmVDug+7ykVe1IKT4c1gakrvlfFYp5NhAXH/lyqLM8wsAPo5wNy73Feg==",
+ "requires": {
+ "@shikijs/vscode-textmate": "^9.3.0",
+ "@types/hast": "^3.0.4"
+ }
+ },
+ "@shikijs/vscode-textmate": {
+ "version": "9.3.0",
+ "resolved": "https://registry.npmjs.org/@shikijs/vscode-textmate/-/vscode-textmate-9.3.0.tgz",
+ "integrity": "sha512-jn7/7ky30idSkd/O5yDBfAnVt+JJpepofP/POZ1iMOxK59cOfqIgg/Dj0eFsjOTMw+4ycJN0uhZH/Eb0bs/EUA=="
+ },
+ "@types/estree": {
+ "version": "1.0.6",
+ "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.6.tgz",
+ "integrity": "sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw=="
+ },
+ "@types/hast": {
+ "version": "3.0.4",
+ "resolved": "https://registry.npmjs.org/@types/hast/-/hast-3.0.4.tgz",
+ "integrity": "sha512-WPs+bbQw5aCj+x6laNGWLH3wviHtoCv/P3+otBhbOhJgG8qtpdAMlTCxLtsTWA7LH1Oh/bFCHsBn0TPS5m30EQ==",
+ "requires": {
+ "@types/unist": "*"
+ }
+ },
+ "@types/linkify-it": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/@types/linkify-it/-/linkify-it-5.0.0.tgz",
+ "integrity": "sha512-sVDA58zAw4eWAffKOaQH5/5j3XeayukzDk+ewSsnv3p4yJEZHCCzMDiZM8e0OUrRvmpGZ85jf4yDHkHsgBNr9Q=="
+ },
+ "@types/markdown-it": {
+ "version": "14.1.2",
+ "resolved": "https://registry.npmjs.org/@types/markdown-it/-/markdown-it-14.1.2.tgz",
+ "integrity": "sha512-promo4eFwuiW+TfGxhi+0x3czqTYJkG8qB17ZUJiVF10Xm7NLVRSLUsfRTU/6h1e24VvRnXCx+hG7li58lkzog==",
+ "requires": {
+ "@types/linkify-it": "^5",
+ "@types/mdurl": "^2"
+ }
+ },
+ "@types/mdast": {
+ "version": "4.0.4",
+ "resolved": "https://registry.npmjs.org/@types/mdast/-/mdast-4.0.4.tgz",
+ "integrity": "sha512-kGaNbPh1k7AFzgpud/gMdvIm5xuECykRR+JnWKQno9TAXVa6WIVCGTPvYGekIDL4uwCZQSYbUxNBSb1aUo79oA==",
+ "requires": {
+ "@types/unist": "*"
+ }
+ },
+ "@types/mdurl": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/@types/mdurl/-/mdurl-2.0.0.tgz",
+ "integrity": "sha512-RGdgjQUZba5p6QEFAVx2OGb8rQDL/cPRG7GiedRzMcJ1tYnUANBncjbSB1NRGwbvjcPeikRABz2nshyPk1bhWg=="
+ },
+ "@types/unist": {
+ "version": "3.0.3",
+ "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.3.tgz",
+ "integrity": "sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q=="
+ },
+ "@types/web-bluetooth": {
+ "version": "0.0.20",
+ "resolved": "https://registry.npmjs.org/@types/web-bluetooth/-/web-bluetooth-0.0.20.tgz",
+ "integrity": "sha512-g9gZnnXVq7gM7v3tJCWV/qw7w+KeOlSHAhgF9RytFyifW6AF61hdT2ucrYhPq9hLs5JIryeupHV3qGk95dH9ow=="
+ },
+ "@ungap/structured-clone": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.2.0.tgz",
+ "integrity": "sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ=="
+ },
+ "@vitejs/plugin-vue": {
+ "version": "5.1.4",
+ "resolved": "https://registry.npmjs.org/@vitejs/plugin-vue/-/plugin-vue-5.1.4.tgz",
+ "integrity": "sha512-N2XSI2n3sQqp5w7Y/AN/L2XDjBIRGqXko+eDp42sydYSBeJuSm5a1sLf8zakmo8u7tA8NmBgoDLA1HeOESjp9A==",
+ "requires": {}
+ },
+ "@vue/compiler-core": {
+ "version": "3.5.12",
+ "resolved": "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.5.12.tgz",
+ "integrity": "sha512-ISyBTRMmMYagUxhcpyEH0hpXRd/KqDU4ymofPgl2XAkY9ZhQ+h0ovEZJIiPop13UmR/54oA2cgMDjgroRelaEw==",
+ "requires": {
+ "@babel/parser": "^7.25.3",
+ "@vue/shared": "3.5.12",
+ "entities": "^4.5.0",
+ "estree-walker": "^2.0.2",
+ "source-map-js": "^1.2.0"
+ }
+ },
+ "@vue/compiler-dom": {
+ "version": "3.5.12",
+ "resolved": "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.5.12.tgz",
+ "integrity": "sha512-9G6PbJ03uwxLHKQ3P42cMTi85lDRvGLB2rSGOiQqtXELat6uI4n8cNz9yjfVHRPIu+MsK6TE418Giruvgptckg==",
+ "requires": {
+ "@vue/compiler-core": "3.5.12",
+ "@vue/shared": "3.5.12"
+ }
+ },
+ "@vue/compiler-sfc": {
+ "version": "3.5.12",
+ "resolved": "https://registry.npmjs.org/@vue/compiler-sfc/-/compiler-sfc-3.5.12.tgz",
+ "integrity": "sha512-2k973OGo2JuAa5+ZlekuQJtitI5CgLMOwgl94BzMCsKZCX/xiqzJYzapl4opFogKHqwJk34vfsaKpfEhd1k5nw==",
+ "requires": {
+ "@babel/parser": "^7.25.3",
+ "@vue/compiler-core": "3.5.12",
+ "@vue/compiler-dom": "3.5.12",
+ "@vue/compiler-ssr": "3.5.12",
+ "@vue/shared": "3.5.12",
+ "estree-walker": "^2.0.2",
+ "magic-string": "^0.30.11",
+ "postcss": "^8.4.47",
+ "source-map-js": "^1.2.0"
+ }
+ },
+ "@vue/compiler-ssr": {
+ "version": "3.5.12",
+ "resolved": "https://registry.npmjs.org/@vue/compiler-ssr/-/compiler-ssr-3.5.12.tgz",
+ "integrity": "sha512-eLwc7v6bfGBSM7wZOGPmRavSWzNFF6+PdRhE+VFJhNCgHiF8AM7ccoqcv5kBXA2eWUfigD7byekvf/JsOfKvPA==",
+ "requires": {
+ "@vue/compiler-dom": "3.5.12",
+ "@vue/shared": "3.5.12"
+ }
+ },
+ "@vue/devtools-api": {
+ "version": "7.6.2",
+ "resolved": "https://registry.npmjs.org/@vue/devtools-api/-/devtools-api-7.6.2.tgz",
+ "integrity": "sha512-NCT0ujqlwAhoFvCsAG7G5qS8w/A/dhvFSt2BhmNxyqgpYDrf9CG1zYyWLQkE3dsZ+5lCT6ULUic2VKNaE07Vzg==",
+ "requires": {
+ "@vue/devtools-kit": "^7.6.2"
+ }
+ },
+ "@vue/devtools-kit": {
+ "version": "7.6.2",
+ "resolved": "https://registry.npmjs.org/@vue/devtools-kit/-/devtools-kit-7.6.2.tgz",
+ "integrity": "sha512-k61BxHRmcTtIQZFouF9QWt9nCCNtSdw12lhg8VNtHq5/XOBGD+ewiK27a40UJ8UPYoCJvi80hbvbYr5E/Zeu1g==",
+ "requires": {
+ "@vue/devtools-shared": "^7.6.2",
+ "birpc": "^0.2.19",
+ "hookable": "^5.5.3",
+ "mitt": "^3.0.1",
+ "perfect-debounce": "^1.0.0",
+ "speakingurl": "^14.0.1",
+ "superjson": "^2.2.1"
+ }
+ },
+ "@vue/devtools-shared": {
+ "version": "7.6.2",
+ "resolved": "https://registry.npmjs.org/@vue/devtools-shared/-/devtools-shared-7.6.2.tgz",
+ "integrity": "sha512-lcjyJ7hCC0W0kNwnCGMLVTMvDLoZgjcq9BvboPgS+6jQyDul7fpzRSKTGtGhCHoxrDox7qBAKGbAl2Rcf7GE1A==",
+ "requires": {
+ "rfdc": "^1.4.1"
+ }
+ },
+ "@vue/reactivity": {
+ "version": "3.5.12",
+ "resolved": "https://registry.npmjs.org/@vue/reactivity/-/reactivity-3.5.12.tgz",
+ "integrity": "sha512-UzaN3Da7xnJXdz4Okb/BGbAaomRHc3RdoWqTzlvd9+WBR5m3J39J1fGcHes7U3za0ruYn/iYy/a1euhMEHvTAg==",
+ "requires": {
+ "@vue/shared": "3.5.12"
+ }
+ },
+ "@vue/runtime-core": {
+ "version": "3.5.12",
+ "resolved": "https://registry.npmjs.org/@vue/runtime-core/-/runtime-core-3.5.12.tgz",
+ "integrity": "sha512-hrMUYV6tpocr3TL3Ad8DqxOdpDe4zuQY4HPY3X/VRh+L2myQO8MFXPAMarIOSGNu0bFAjh1yBkMPXZBqCk62Uw==",
+ "requires": {
+ "@vue/reactivity": "3.5.12",
+ "@vue/shared": "3.5.12"
+ }
+ },
+ "@vue/runtime-dom": {
+ "version": "3.5.12",
+ "resolved": "https://registry.npmjs.org/@vue/runtime-dom/-/runtime-dom-3.5.12.tgz",
+ "integrity": "sha512-q8VFxR9A2MRfBr6/55Q3umyoN7ya836FzRXajPB6/Vvuv0zOPL+qltd9rIMzG/DbRLAIlREmnLsplEF/kotXKA==",
+ "requires": {
+ "@vue/reactivity": "3.5.12",
+ "@vue/runtime-core": "3.5.12",
+ "@vue/shared": "3.5.12",
+ "csstype": "^3.1.3"
+ }
+ },
+ "@vue/server-renderer": {
+ "version": "3.5.12",
+ "resolved": "https://registry.npmjs.org/@vue/server-renderer/-/server-renderer-3.5.12.tgz",
+ "integrity": "sha512-I3QoeDDeEPZm8yR28JtY+rk880Oqmj43hreIBVTicisFTx/Dl7JpG72g/X7YF8hnQD3IFhkky5i2bPonwrTVPg==",
+ "requires": {
+ "@vue/compiler-ssr": "3.5.12",
+ "@vue/shared": "3.5.12"
+ }
+ },
+ "@vue/shared": {
+ "version": "3.5.12",
+ "resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.5.12.tgz",
+ "integrity": "sha512-L2RPSAwUFbgZH20etwrXyVyCBu9OxRSi8T/38QsvnkJyvq2LufW2lDCOzm7t/U9C1mkhJGWYfCuFBCmIuNivrg=="
+ },
+ "@vueuse/core": {
+ "version": "11.2.0",
+ "resolved": "https://registry.npmjs.org/@vueuse/core/-/core-11.2.0.tgz",
+ "integrity": "sha512-JIUwRcOqOWzcdu1dGlfW04kaJhW3EXnnjJJfLTtddJanymTL7lF1C0+dVVZ/siLfc73mWn+cGP1PE1PKPruRSA==",
+ "requires": {
+ "@types/web-bluetooth": "^0.0.20",
+ "@vueuse/metadata": "11.2.0",
+ "@vueuse/shared": "11.2.0",
+ "vue-demi": ">=0.14.10"
+ },
+ "dependencies": {
+ "vue-demi": {
+ "version": "0.14.10",
+ "resolved": "https://registry.npmjs.org/vue-demi/-/vue-demi-0.14.10.tgz",
+ "integrity": "sha512-nMZBOwuzabUO0nLgIcc6rycZEebF6eeUfaiQx9+WSk8e29IbLvPU9feI6tqW4kTo3hvoYAJkMh8n8D0fuISphg==",
+ "requires": {}
+ }
+ }
+ },
+ "@vueuse/integrations": {
+ "version": "11.2.0",
+ "resolved": "https://registry.npmjs.org/@vueuse/integrations/-/integrations-11.2.0.tgz",
+ "integrity": "sha512-zGXz3dsxNHKwiD9jPMvR3DAxQEOV6VWIEYTGVSB9PNpk4pTWR+pXrHz9gvXWcP2sTk3W2oqqS6KwWDdntUvNVA==",
+ "requires": {
+ "@vueuse/core": "11.2.0",
+ "@vueuse/shared": "11.2.0",
+ "vue-demi": ">=0.14.10"
+ },
+ "dependencies": {
+ "vue-demi": {
+ "version": "0.14.10",
+ "resolved": "https://registry.npmjs.org/vue-demi/-/vue-demi-0.14.10.tgz",
+ "integrity": "sha512-nMZBOwuzabUO0nLgIcc6rycZEebF6eeUfaiQx9+WSk8e29IbLvPU9feI6tqW4kTo3hvoYAJkMh8n8D0fuISphg==",
+ "requires": {}
+ }
+ }
+ },
+ "@vueuse/metadata": {
+ "version": "11.2.0",
+ "resolved": "https://registry.npmjs.org/@vueuse/metadata/-/metadata-11.2.0.tgz",
+ "integrity": "sha512-L0ZmtRmNx+ZW95DmrgD6vn484gSpVeRbgpWevFKXwqqQxW9hnSi2Ppuh2BzMjnbv4aJRiIw8tQatXT9uOB23dQ=="
+ },
+ "@vueuse/shared": {
+ "version": "11.2.0",
+ "resolved": "https://registry.npmjs.org/@vueuse/shared/-/shared-11.2.0.tgz",
+ "integrity": "sha512-VxFjie0EanOudYSgMErxXfq6fo8vhr5ICI+BuE3I9FnX7ePllEsVrRQ7O6Q1TLgApeLuPKcHQxAXpP+KnlrJsg==",
+ "requires": {
+ "vue-demi": ">=0.14.10"
+ },
+ "dependencies": {
+ "vue-demi": {
+ "version": "0.14.10",
+ "resolved": "https://registry.npmjs.org/vue-demi/-/vue-demi-0.14.10.tgz",
+ "integrity": "sha512-nMZBOwuzabUO0nLgIcc6rycZEebF6eeUfaiQx9+WSk8e29IbLvPU9feI6tqW4kTo3hvoYAJkMh8n8D0fuISphg==",
+ "requires": {}
+ }
+ }
+ },
+ "algoliasearch": {
+ "version": "5.12.0",
+ "resolved": "https://registry.npmjs.org/algoliasearch/-/algoliasearch-5.12.0.tgz",
+ "integrity": "sha512-psGBRYdGgik8I6m28iAB8xpubvjEt7UQU+w5MAJUA2324WHiGoHap5BPkkjB14rMaXeRts6pmOsrVIglGyOVwg==",
+ "requires": {
+ "@algolia/client-abtesting": "5.12.0",
+ "@algolia/client-analytics": "5.12.0",
+ "@algolia/client-common": "5.12.0",
+ "@algolia/client-insights": "5.12.0",
+ "@algolia/client-personalization": "5.12.0",
+ "@algolia/client-query-suggestions": "5.12.0",
+ "@algolia/client-search": "5.12.0",
+ "@algolia/ingestion": "1.12.0",
+ "@algolia/monitoring": "1.12.0",
+ "@algolia/recommend": "5.12.0",
+ "@algolia/requester-browser-xhr": "5.12.0",
+ "@algolia/requester-fetch": "5.12.0",
+ "@algolia/requester-node-http": "5.12.0"
+ }
+ },
+ "birpc": {
+ "version": "0.2.19",
+ "resolved": "https://registry.npmjs.org/birpc/-/birpc-0.2.19.tgz",
+ "integrity": "sha512-5WeXXAvTmitV1RqJFppT5QtUiz2p1mRSYU000Jkft5ZUCLJIk4uQriYNO50HknxKwM6jd8utNc66K1qGIwwWBQ=="
+ },
+ "ccount": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/ccount/-/ccount-2.0.1.tgz",
+ "integrity": "sha512-eyrF0jiFpY+3drT6383f1qhkbGsLSifNAjA61IUjZjmLCWjItY6LB9ft9YhoDgwfmclB2zhu51Lc7+95b8NRAg=="
+ },
+ "character-entities-html4": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/character-entities-html4/-/character-entities-html4-2.1.0.tgz",
+ "integrity": "sha512-1v7fgQRj6hnSwFpq1Eu0ynr/CDEw0rXo2B61qXrLNdHZmPKgb7fqS1a2JwF0rISo9q77jDI8VMEHoApn8qDoZA=="
+ },
+ "character-entities-legacy": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/character-entities-legacy/-/character-entities-legacy-3.0.0.tgz",
+ "integrity": "sha512-RpPp0asT/6ufRm//AJVwpViZbGM/MkjQFxJccQRHmISF/22NBtsHqAWmL+/pmkPWoIUJdWyeVleTl1wydHATVQ=="
+ },
+ "comma-separated-tokens": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/comma-separated-tokens/-/comma-separated-tokens-2.0.3.tgz",
+ "integrity": "sha512-Fu4hJdvzeylCfQPp9SGWidpzrMs7tTrlu6Vb8XGaRGck8QSNZJJp538Wrb60Lax4fPwR64ViY468OIUTbRlGZg=="
+ },
+ "copy-anything": {
+ "version": "3.0.5",
+ "resolved": "https://registry.npmjs.org/copy-anything/-/copy-anything-3.0.5.tgz",
+ "integrity": "sha512-yCEafptTtb4bk7GLEQoM8KVJpxAfdBJYaXyzQEgQQQgYrZiDp8SJmGKlYza6CYjEDNstAdNdKA3UuoULlEbS6w==",
+ "requires": {
+ "is-what": "^4.1.8"
+ }
+ },
+ "csstype": {
+ "version": "3.1.3",
+ "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz",
+ "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw=="
+ },
+ "dequal": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/dequal/-/dequal-2.0.3.tgz",
+ "integrity": "sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA=="
+ },
+ "devlop": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/devlop/-/devlop-1.1.0.tgz",
+ "integrity": "sha512-RWmIqhcFf1lRYBvNmr7qTNuyCt/7/ns2jbpp1+PalgE/rDQcBT0fioSMUpJ93irlUhC5hrg4cYqe6U+0ImW0rA==",
+ "requires": {
+ "dequal": "^2.0.0"
+ }
+ },
+ "entities": {
+ "version": "4.5.0",
+ "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz",
+ "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw=="
+ },
+ "esbuild": {
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.21.5.tgz",
+ "integrity": "sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw==",
+ "requires": {
+ "@esbuild/aix-ppc64": "0.21.5",
+ "@esbuild/android-arm": "0.21.5",
+ "@esbuild/android-arm64": "0.21.5",
+ "@esbuild/android-x64": "0.21.5",
+ "@esbuild/darwin-arm64": "0.21.5",
+ "@esbuild/darwin-x64": "0.21.5",
+ "@esbuild/freebsd-arm64": "0.21.5",
+ "@esbuild/freebsd-x64": "0.21.5",
+ "@esbuild/linux-arm": "0.21.5",
+ "@esbuild/linux-arm64": "0.21.5",
+ "@esbuild/linux-ia32": "0.21.5",
+ "@esbuild/linux-loong64": "0.21.5",
+ "@esbuild/linux-mips64el": "0.21.5",
+ "@esbuild/linux-ppc64": "0.21.5",
+ "@esbuild/linux-riscv64": "0.21.5",
+ "@esbuild/linux-s390x": "0.21.5",
+ "@esbuild/linux-x64": "0.21.5",
+ "@esbuild/netbsd-x64": "0.21.5",
+ "@esbuild/openbsd-x64": "0.21.5",
+ "@esbuild/sunos-x64": "0.21.5",
+ "@esbuild/win32-arm64": "0.21.5",
+ "@esbuild/win32-ia32": "0.21.5",
+ "@esbuild/win32-x64": "0.21.5"
+ }
+ },
+ "estree-walker": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz",
+ "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w=="
+ },
+ "focus-trap": {
+ "version": "7.6.0",
+ "resolved": "https://registry.npmjs.org/focus-trap/-/focus-trap-7.6.0.tgz",
+ "integrity": "sha512-1td0l3pMkWJLFipobUcGaf+5DTY4PLDDrcqoSaKP8ediO/CoWCCYk/fT/Y2A4e6TNB+Sh6clRJCjOPPnKoNHnQ==",
+ "requires": {
+ "tabbable": "^6.2.0"
+ }
+ },
+ "fsevents": {
+ "version": "2.3.3",
+ "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz",
+ "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==",
+ "optional": true
+ },
+ "hast-util-to-html": {
+ "version": "9.0.3",
+ "resolved": "https://registry.npmjs.org/hast-util-to-html/-/hast-util-to-html-9.0.3.tgz",
+ "integrity": "sha512-M17uBDzMJ9RPCqLMO92gNNUDuBSq10a25SDBI08iCCxmorf4Yy6sYHK57n9WAbRAAaU+DuR4W6GN9K4DFZesYg==",
+ "requires": {
+ "@types/hast": "^3.0.0",
+ "@types/unist": "^3.0.0",
+ "ccount": "^2.0.0",
+ "comma-separated-tokens": "^2.0.0",
+ "hast-util-whitespace": "^3.0.0",
+ "html-void-elements": "^3.0.0",
+ "mdast-util-to-hast": "^13.0.0",
+ "property-information": "^6.0.0",
+ "space-separated-tokens": "^2.0.0",
+ "stringify-entities": "^4.0.0",
+ "zwitch": "^2.0.4"
+ }
+ },
+ "hast-util-whitespace": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/hast-util-whitespace/-/hast-util-whitespace-3.0.0.tgz",
+ "integrity": "sha512-88JUN06ipLwsnv+dVn+OIYOvAuvBMy/Qoi6O7mQHxdPXpjy+Cd6xRkWwux7DKO+4sYILtLBRIKgsdpS2gQc7qw==",
+ "requires": {
+ "@types/hast": "^3.0.0"
+ }
+ },
+ "hookable": {
+ "version": "5.5.3",
+ "resolved": "https://registry.npmjs.org/hookable/-/hookable-5.5.3.tgz",
+ "integrity": "sha512-Yc+BQe8SvoXH1643Qez1zqLRmbA5rCL+sSmk6TVos0LWVfNIB7PGncdlId77WzLGSIB5KaWgTaNTs2lNVEI6VQ=="
+ },
+ "html-void-elements": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/html-void-elements/-/html-void-elements-3.0.0.tgz",
+ "integrity": "sha512-bEqo66MRXsUGxWHV5IP0PUiAWwoEjba4VCzg0LjFJBpchPaTfyfCKTG6bc5F8ucKec3q5y6qOdGyYTSBEvhCrg=="
+ },
+ "is-what": {
+ "version": "4.1.16",
+ "resolved": "https://registry.npmjs.org/is-what/-/is-what-4.1.16.tgz",
+ "integrity": "sha512-ZhMwEosbFJkA0YhFnNDgTM4ZxDRsS6HqTo7qsZM08fehyRYIYa0yHu5R6mgo1n/8MgaPBXiPimPD77baVFYg+A=="
+ },
+ "magic-string": {
+ "version": "0.30.12",
+ "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.12.tgz",
+ "integrity": "sha512-Ea8I3sQMVXr8JhN4z+H/d8zwo+tYDgHE9+5G4Wnrwhs0gaK9fXTKx0Tw5Xwsd/bCPTTZNRAdpyzvoeORe9LYpw==",
+ "requires": {
+ "@jridgewell/sourcemap-codec": "^1.5.0"
+ }
+ },
+ "mark.js": {
+ "version": "8.11.1",
+ "resolved": "https://registry.npmjs.org/mark.js/-/mark.js-8.11.1.tgz",
+ "integrity": "sha512-1I+1qpDt4idfgLQG+BNWmrqku+7/2bi5nLf4YwF8y8zXvmfiTBY3PV3ZibfrjBueCByROpuBjLLFCajqkgYoLQ=="
+ },
+ "mdast-util-to-hast": {
+ "version": "13.2.0",
+ "resolved": "https://registry.npmjs.org/mdast-util-to-hast/-/mdast-util-to-hast-13.2.0.tgz",
+ "integrity": "sha512-QGYKEuUsYT9ykKBCMOEDLsU5JRObWQusAolFMeko/tYPufNkRffBAQjIE+99jbA87xv6FgmjLtwjh9wBWajwAA==",
+ "requires": {
+ "@types/hast": "^3.0.0",
+ "@types/mdast": "^4.0.0",
+ "@ungap/structured-clone": "^1.0.0",
+ "devlop": "^1.0.0",
+ "micromark-util-sanitize-uri": "^2.0.0",
+ "trim-lines": "^3.0.0",
+ "unist-util-position": "^5.0.0",
+ "unist-util-visit": "^5.0.0",
+ "vfile": "^6.0.0"
+ }
+ },
+ "micromark-util-character": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.0.tgz",
+ "integrity": "sha512-KvOVV+X1yLBfs9dCBSopq/+G1PcgT3lAK07mC4BzXi5E7ahzMAF8oIupDDJ6mievI6F+lAATkbQQlQixJfT3aQ==",
+ "requires": {
+ "micromark-util-symbol": "^2.0.0",
+ "micromark-util-types": "^2.0.0"
+ }
+ },
+ "micromark-util-encode": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/micromark-util-encode/-/micromark-util-encode-2.0.0.tgz",
+ "integrity": "sha512-pS+ROfCXAGLWCOc8egcBvT0kf27GoWMqtdarNfDcjb6YLuV5cM3ioG45Ys2qOVqeqSbjaKg72vU+Wby3eddPsA=="
+ },
+ "micromark-util-sanitize-uri": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/micromark-util-sanitize-uri/-/micromark-util-sanitize-uri-2.0.0.tgz",
+ "integrity": "sha512-WhYv5UEcZrbAtlsnPuChHUAsu/iBPOVaEVsntLBIdpibO0ddy8OzavZz3iL2xVvBZOpolujSliP65Kq0/7KIYw==",
+ "requires": {
+ "micromark-util-character": "^2.0.0",
+ "micromark-util-encode": "^2.0.0",
+ "micromark-util-symbol": "^2.0.0"
+ }
+ },
+ "micromark-util-symbol": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz",
+ "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw=="
+ },
+ "micromark-util-types": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/micromark-util-types/-/micromark-util-types-2.0.0.tgz",
+ "integrity": "sha512-oNh6S2WMHWRZrmutsRmDDfkzKtxF+bc2VxLC9dvtrDIRFln627VsFP6fLMgTryGDljgLPjkrzQSDcPrjPyDJ5w=="
+ },
+ "minisearch": {
+ "version": "7.1.0",
+ "resolved": "https://registry.npmjs.org/minisearch/-/minisearch-7.1.0.tgz",
+ "integrity": "sha512-tv7c/uefWdEhcu6hvrfTihflgeEi2tN6VV7HJnCjK6VxM75QQJh4t9FwJCsA2EsRS8LCnu3W87CuGPWMocOLCA=="
+ },
+ "mitt": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/mitt/-/mitt-3.0.1.tgz",
+ "integrity": "sha512-vKivATfr97l2/QBCYAkXYDbrIWPM2IIKEl7YPhjCvKlG3kE2gm+uBo6nEXK3M5/Ffh/FLpKExzOQ3JJoJGFKBw=="
+ },
+ "nanoid": {
+ "version": "3.3.7",
+ "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.7.tgz",
+ "integrity": "sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g=="
+ },
+ "oniguruma-to-js": {
+ "version": "0.4.3",
+ "resolved": "https://registry.npmjs.org/oniguruma-to-js/-/oniguruma-to-js-0.4.3.tgz",
+ "integrity": "sha512-X0jWUcAlxORhOqqBREgPMgnshB7ZGYszBNspP+tS9hPD3l13CdaXcHbgImoHUHlrvGx/7AvFEkTRhAGYh+jzjQ==",
+ "requires": {
+ "regex": "^4.3.2"
+ }
+ },
+ "perfect-debounce": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/perfect-debounce/-/perfect-debounce-1.0.0.tgz",
+ "integrity": "sha512-xCy9V055GLEqoFaHoC1SoLIaLmWctgCUaBaWxDZ7/Zx4CTyX7cJQLJOok/orfjZAh9kEYpjJa4d0KcJmCbctZA=="
+ },
+ "picocolors": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz",
+ "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA=="
+ },
+ "postcss": {
+ "version": "8.4.47",
+ "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.47.tgz",
+ "integrity": "sha512-56rxCq7G/XfB4EkXq9Egn5GCqugWvDFjafDOThIdMBsI15iqPqR5r15TfSr1YPYeEI19YeaXMCbY6u88Y76GLQ==",
+ "requires": {
+ "nanoid": "^3.3.7",
+ "picocolors": "^1.1.0",
+ "source-map-js": "^1.2.1"
+ }
+ },
+ "preact": {
+ "version": "10.24.3",
+ "resolved": "https://registry.npmjs.org/preact/-/preact-10.24.3.tgz",
+ "integrity": "sha512-Z2dPnBnMUfyQfSQ+GBdsGa16hz35YmLmtTLhM169uW944hYL6xzTYkJjC07j+Wosz733pMWx0fgON3JNw1jJQA=="
+ },
+ "property-information": {
+ "version": "6.5.0",
+ "resolved": "https://registry.npmjs.org/property-information/-/property-information-6.5.0.tgz",
+ "integrity": "sha512-PgTgs/BlvHxOu8QuEN7wi5A0OmXaBcHpmCSTehcs6Uuu9IkDIEo13Hy7n898RHfrQ49vKCoGeWZSaAK01nwVig=="
+ },
+ "regex": {
+ "version": "4.3.3",
+ "resolved": "https://registry.npmjs.org/regex/-/regex-4.3.3.tgz",
+ "integrity": "sha512-r/AadFO7owAq1QJVeZ/nq9jNS1vyZt+6t1p/E59B56Rn2GCya+gr1KSyOzNL/er+r+B7phv5jG2xU2Nz1YkmJg=="
+ },
+ "rfdc": {
+ "version": "1.4.1",
+ "resolved": "https://registry.npmjs.org/rfdc/-/rfdc-1.4.1.tgz",
+ "integrity": "sha512-q1b3N5QkRUWUl7iyylaaj3kOpIT0N2i9MqIEQXP73GVsN9cw3fdx8X63cEmWhJGi2PPCF23Ijp7ktmd39rawIA=="
+ },
+ "rollup": {
+ "version": "4.24.3",
+ "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.24.3.tgz",
+ "integrity": "sha512-HBW896xR5HGmoksbi3JBDtmVzWiPAYqp7wip50hjQ67JbDz61nyoMPdqu1DvVW9asYb2M65Z20ZHsyJCMqMyDg==",
+ "requires": {
+ "@rollup/rollup-android-arm-eabi": "4.24.3",
+ "@rollup/rollup-android-arm64": "4.24.3",
+ "@rollup/rollup-darwin-arm64": "4.24.3",
+ "@rollup/rollup-darwin-x64": "4.24.3",
+ "@rollup/rollup-freebsd-arm64": "4.24.3",
+ "@rollup/rollup-freebsd-x64": "4.24.3",
+ "@rollup/rollup-linux-arm-gnueabihf": "4.24.3",
+ "@rollup/rollup-linux-arm-musleabihf": "4.24.3",
+ "@rollup/rollup-linux-arm64-gnu": "4.24.3",
+ "@rollup/rollup-linux-arm64-musl": "4.24.3",
+ "@rollup/rollup-linux-powerpc64le-gnu": "4.24.3",
+ "@rollup/rollup-linux-riscv64-gnu": "4.24.3",
+ "@rollup/rollup-linux-s390x-gnu": "4.24.3",
+ "@rollup/rollup-linux-x64-gnu": "4.24.3",
+ "@rollup/rollup-linux-x64-musl": "4.24.3",
+ "@rollup/rollup-win32-arm64-msvc": "4.24.3",
+ "@rollup/rollup-win32-ia32-msvc": "4.24.3",
+ "@rollup/rollup-win32-x64-msvc": "4.24.3",
+ "@types/estree": "1.0.6",
+ "fsevents": "~2.3.2"
+ }
+ },
+ "search-insights": {
+ "version": "2.17.2",
+ "resolved": "https://registry.npmjs.org/search-insights/-/search-insights-2.17.2.tgz",
+ "integrity": "sha512-zFNpOpUO+tY2D85KrxJ+aqwnIfdEGi06UH2+xEb+Bp9Mwznmauqc9djbnBibJO5mpfUPPa8st6Sx65+vbeO45g==",
+ "peer": true
+ },
+ "shiki": {
+ "version": "1.22.2",
+ "resolved": "https://registry.npmjs.org/shiki/-/shiki-1.22.2.tgz",
+ "integrity": "sha512-3IZau0NdGKXhH2bBlUk4w1IHNxPh6A5B2sUpyY+8utLu2j/h1QpFkAaUA1bAMxOWWGtTWcAh531vnS4NJKS/lA==",
+ "requires": {
+ "@shikijs/core": "1.22.2",
+ "@shikijs/engine-javascript": "1.22.2",
+ "@shikijs/engine-oniguruma": "1.22.2",
+ "@shikijs/types": "1.22.2",
+ "@shikijs/vscode-textmate": "^9.3.0",
+ "@types/hast": "^3.0.4"
+ }
+ },
+ "source-map-js": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz",
+ "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA=="
+ },
+ "space-separated-tokens": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/space-separated-tokens/-/space-separated-tokens-2.0.2.tgz",
+ "integrity": "sha512-PEGlAwrG8yXGXRjW32fGbg66JAlOAwbObuqVoJpv/mRgoWDQfgH1wDPvtzWyUSNAXBGSk8h755YDbbcEy3SH2Q=="
+ },
+ "speakingurl": {
+ "version": "14.0.1",
+ "resolved": "https://registry.npmjs.org/speakingurl/-/speakingurl-14.0.1.tgz",
+ "integrity": "sha512-1POYv7uv2gXoyGFpBCmpDVSNV74IfsWlDW216UPjbWufNf+bSU6GdbDsxdcxtfwb4xlI3yxzOTKClUosxARYrQ=="
+ },
+ "stringify-entities": {
+ "version": "4.0.4",
+ "resolved": "https://registry.npmjs.org/stringify-entities/-/stringify-entities-4.0.4.tgz",
+ "integrity": "sha512-IwfBptatlO+QCJUo19AqvrPNqlVMpW9YEL2LIVY+Rpv2qsjCGxaDLNRgeGsQWJhfItebuJhsGSLjaBbNSQ+ieg==",
+ "requires": {
+ "character-entities-html4": "^2.0.0",
+ "character-entities-legacy": "^3.0.0"
+ }
+ },
+ "superjson": {
+ "version": "2.2.1",
+ "resolved": "https://registry.npmjs.org/superjson/-/superjson-2.2.1.tgz",
+ "integrity": "sha512-8iGv75BYOa0xRJHK5vRLEjE2H/i4lulTjzpUXic3Eg8akftYjkmQDa8JARQ42rlczXyFR3IeRoeFCc7RxHsYZA==",
+ "requires": {
+ "copy-anything": "^3.0.2"
+ }
+ },
+ "tabbable": {
+ "version": "6.2.0",
+ "resolved": "https://registry.npmjs.org/tabbable/-/tabbable-6.2.0.tgz",
+ "integrity": "sha512-Cat63mxsVJlzYvN51JmVXIgNoUokrIaT2zLclCXjRd8boZ0004U4KCs/sToJ75C6sdlByWxpYnb5Boif1VSFew=="
+ },
+ "trim-lines": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/trim-lines/-/trim-lines-3.0.1.tgz",
+ "integrity": "sha512-kRj8B+YHZCc9kQYdWfJB2/oUl9rA99qbowYYBtr4ui4mZyAQ2JpvVBd/6U2YloATfqBhBTSMhTpgBHtU0Mf3Rg=="
+ },
+ "unist-util-is": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-6.0.0.tgz",
+ "integrity": "sha512-2qCTHimwdxLfz+YzdGfkqNlH0tLi9xjTnHddPmJwtIG9MGsdbutfTc4P+haPD7l7Cjxf/WZj+we5qfVPvvxfYw==",
+ "requires": {
+ "@types/unist": "^3.0.0"
+ }
+ },
+ "unist-util-position": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/unist-util-position/-/unist-util-position-5.0.0.tgz",
+ "integrity": "sha512-fucsC7HjXvkB5R3kTCO7kUjRdrS0BJt3M/FPxmHMBOm8JQi2BsHAHFsy27E0EolP8rp0NzXsJ+jNPyDWvOJZPA==",
+ "requires": {
+ "@types/unist": "^3.0.0"
+ }
+ },
+ "unist-util-stringify-position": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-4.0.0.tgz",
+ "integrity": "sha512-0ASV06AAoKCDkS2+xw5RXJywruurpbC4JZSm7nr7MOt1ojAzvyyaO+UxZf18j8FCF6kmzCZKcAgN/yu2gm2XgQ==",
+ "requires": {
+ "@types/unist": "^3.0.0"
+ }
+ },
+ "unist-util-visit": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-5.0.0.tgz",
+ "integrity": "sha512-MR04uvD+07cwl/yhVuVWAtw+3GOR/knlL55Nd/wAdblk27GCVt3lqpTivy/tkJcZoNPzTwS1Y+KMojlLDhoTzg==",
+ "requires": {
+ "@types/unist": "^3.0.0",
+ "unist-util-is": "^6.0.0",
+ "unist-util-visit-parents": "^6.0.0"
+ }
+ },
+ "unist-util-visit-parents": {
+ "version": "6.0.1",
+ "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-6.0.1.tgz",
+ "integrity": "sha512-L/PqWzfTP9lzzEa6CKs0k2nARxTdZduw3zyh8d2NVBnsyvHjSX4TWse388YrrQKbvI8w20fGjGlhgT96WwKykw==",
+ "requires": {
+ "@types/unist": "^3.0.0",
+ "unist-util-is": "^6.0.0"
+ }
+ },
+ "vfile": {
+ "version": "6.0.3",
+ "resolved": "https://registry.npmjs.org/vfile/-/vfile-6.0.3.tgz",
+ "integrity": "sha512-KzIbH/9tXat2u30jf+smMwFCsno4wHVdNmzFyL+T/L3UGqqk6JKfVqOFOZEpZSHADH1k40ab6NUIXZq422ov3Q==",
+ "requires": {
+ "@types/unist": "^3.0.0",
+ "vfile-message": "^4.0.0"
+ }
+ },
+ "vfile-message": {
+ "version": "4.0.2",
+ "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-4.0.2.tgz",
+ "integrity": "sha512-jRDZ1IMLttGj41KcZvlrYAaI3CfqpLpfpf+Mfig13viT6NKvRzWZ+lXz0Y5D60w6uJIBAOGq9mSHf0gktF0duw==",
+ "requires": {
+ "@types/unist": "^3.0.0",
+ "unist-util-stringify-position": "^4.0.0"
+ }
+ },
+ "vite": {
+ "version": "5.4.10",
+ "resolved": "https://registry.npmjs.org/vite/-/vite-5.4.10.tgz",
+ "integrity": "sha512-1hvaPshuPUtxeQ0hsVH3Mud0ZanOLwVTneA1EgbAM5LhaZEqyPWGRQ7BtaMvUrTDeEaC8pxtj6a6jku3x4z6SQ==",
+ "requires": {
+ "esbuild": "^0.21.3",
+ "fsevents": "~2.3.3",
+ "postcss": "^8.4.43",
+ "rollup": "^4.20.0"
+ }
+ },
+ "vitepress": {
+ "version": "1.4.3",
+ "resolved": "https://registry.npmjs.org/vitepress/-/vitepress-1.4.3.tgz",
+ "integrity": "sha512-956c2K2Mr0ubY9bTc2lCJD3g0mgo0mARB1iJC/BqUt4s0AM8Wl60wSU4zbFnzV7X2miFK1XJDKzGZnuEN90umw==",
+ "requires": {
+ "@docsearch/css": "^3.6.2",
+ "@docsearch/js": "^3.6.2",
+ "@shikijs/core": "^1.22.2",
+ "@shikijs/transformers": "^1.22.2",
+ "@shikijs/types": "^1.22.2",
+ "@types/markdown-it": "^14.1.2",
+ "@vitejs/plugin-vue": "^5.1.4",
+ "@vue/devtools-api": "^7.5.4",
+ "@vue/shared": "^3.5.12",
+ "@vueuse/core": "^11.1.0",
+ "@vueuse/integrations": "^11.1.0",
+ "focus-trap": "^7.6.0",
+ "mark.js": "8.11.1",
+ "minisearch": "^7.1.0",
+ "shiki": "^1.22.2",
+ "vite": "^5.4.10",
+ "vue": "^3.5.12"
+ }
+ },
+ "vue": {
+ "version": "3.5.12",
+ "resolved": "https://registry.npmjs.org/vue/-/vue-3.5.12.tgz",
+ "integrity": "sha512-CLVZtXtn2ItBIi/zHZ0Sg1Xkb7+PU32bJJ8Bmy7ts3jxXTcbfsEfBivFYYWz1Hur+lalqGAh65Coin0r+HRUfg==",
+ "requires": {
+ "@vue/compiler-dom": "3.5.12",
+ "@vue/compiler-sfc": "3.5.12",
+ "@vue/runtime-dom": "3.5.12",
+ "@vue/server-renderer": "3.5.12",
+ "@vue/shared": "3.5.12"
+ }
+ },
+ "zwitch": {
+ "version": "2.0.4",
+ "resolved": "https://registry.npmjs.org/zwitch/-/zwitch-2.0.4.tgz",
+ "integrity": "sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A=="
+ }
+ }
+}
diff --git a/docs/package.json b/docs/package.json
new file mode 100644
index 00000000..65f1da47
--- /dev/null
+++ b/docs/package.json
@@ -0,0 +1,12 @@
+{
+ "name": "docs",
+ "version": "1.0.0",
+ "scripts": {
+ "docs:dev": "vitepress dev . --open",
+ "docs:build": "vitepress build .",
+ "docs:preview": "vitepress preview ."
+ },
+ "dependencies": {
+ "vitepress": "^1.4.3"
+ }
+}
diff --git a/docs/public/favicon.svg b/docs/public/favicon.svg
new file mode 100644
index 00000000..a91ec13a
--- /dev/null
+++ b/docs/public/favicon.svg
@@ -0,0 +1,6 @@
+
+
+
\ No newline at end of file
diff --git a/docs/public/fonts/aller-bold.eot b/docs/public/fonts/aller-bold.eot
deleted file mode 100644
index 1b32532a..00000000
Binary files a/docs/public/fonts/aller-bold.eot and /dev/null differ
diff --git a/docs/public/fonts/aller-bold.ttf b/docs/public/fonts/aller-bold.ttf
deleted file mode 100644
index dc4cc9c2..00000000
Binary files a/docs/public/fonts/aller-bold.ttf and /dev/null differ
diff --git a/docs/public/fonts/aller-bold.woff b/docs/public/fonts/aller-bold.woff
deleted file mode 100644
index fa16fd0a..00000000
Binary files a/docs/public/fonts/aller-bold.woff and /dev/null differ
diff --git a/docs/public/fonts/aller-light.eot b/docs/public/fonts/aller-light.eot
deleted file mode 100644
index 40bd654b..00000000
Binary files a/docs/public/fonts/aller-light.eot and /dev/null differ
diff --git a/docs/public/fonts/aller-light.ttf b/docs/public/fonts/aller-light.ttf
deleted file mode 100644
index c2c72902..00000000
Binary files a/docs/public/fonts/aller-light.ttf and /dev/null differ
diff --git a/docs/public/fonts/aller-light.woff b/docs/public/fonts/aller-light.woff
deleted file mode 100644
index 81a09d18..00000000
Binary files a/docs/public/fonts/aller-light.woff and /dev/null differ
diff --git a/docs/public/fonts/novecento-bold.eot b/docs/public/fonts/novecento-bold.eot
deleted file mode 100644
index 98a9a7fb..00000000
Binary files a/docs/public/fonts/novecento-bold.eot and /dev/null differ
diff --git a/docs/public/fonts/novecento-bold.ttf b/docs/public/fonts/novecento-bold.ttf
deleted file mode 100644
index 2af39b08..00000000
Binary files a/docs/public/fonts/novecento-bold.ttf and /dev/null differ
diff --git a/docs/public/fonts/novecento-bold.woff b/docs/public/fonts/novecento-bold.woff
deleted file mode 100644
index de558b5a..00000000
Binary files a/docs/public/fonts/novecento-bold.woff and /dev/null differ
diff --git a/docs/public/logo-large.svg b/docs/public/logo-large.svg
new file mode 100644
index 00000000..ab1e5638
--- /dev/null
+++ b/docs/public/logo-large.svg
@@ -0,0 +1,6 @@
+
+
+
\ No newline at end of file
diff --git a/docs/public/logo-mini.svg b/docs/public/logo-mini.svg
new file mode 100644
index 00000000..0c96804e
--- /dev/null
+++ b/docs/public/logo-mini.svg
@@ -0,0 +1,6 @@
+
+
+
\ No newline at end of file
diff --git a/docs/public/stylesheets/normalize.css b/docs/public/stylesheets/normalize.css
deleted file mode 100644
index 73abb76f..00000000
--- a/docs/public/stylesheets/normalize.css
+++ /dev/null
@@ -1,375 +0,0 @@
-/*! normalize.css v2.0.1 | MIT License | git.io/normalize */
-
-/* ==========================================================================
- HTML5 display definitions
- ========================================================================== */
-
-/*
- * Corrects `block` display not defined in IE 8/9.
- */
-
-article,
-aside,
-details,
-figcaption,
-figure,
-footer,
-header,
-hgroup,
-nav,
-section,
-summary {
- display: block;
-}
-
-/*
- * Corrects `inline-block` display not defined in IE 8/9.
- */
-
-audio,
-canvas,
-video {
- display: inline-block;
-}
-
-/*
- * Prevents modern browsers from displaying `audio` without controls.
- * Remove excess height in iOS 5 devices.
- */
-
-audio:not([controls]) {
- display: none;
- height: 0;
-}
-
-/*
- * Addresses styling for `hidden` attribute not present in IE 8/9.
- */
-
-[hidden] {
- display: none;
-}
-
-/* ==========================================================================
- Base
- ========================================================================== */
-
-/*
- * 1. Sets default font family to sans-serif.
- * 2. Prevents iOS text size adjust after orientation change, without disabling
- * user zoom.
- */
-
-html {
- font-family: sans-serif; /* 1 */
- -webkit-text-size-adjust: 100%; /* 2 */
- -ms-text-size-adjust: 100%; /* 2 */
-}
-
-/*
- * Removes default margin.
- */
-
-body {
- margin: 0;
-}
-
-/* ==========================================================================
- Links
- ========================================================================== */
-
-/*
- * Addresses `outline` inconsistency between Chrome and other browsers.
- */
-
-a:focus {
- outline: thin dotted;
-}
-
-/*
- * Improves readability when focused and also mouse hovered in all browsers.
- */
-
-a:active,
-a:hover {
- outline: 0;
-}
-
-/* ==========================================================================
- Typography
- ========================================================================== */
-
-/*
- * Addresses `h1` font sizes within `section` and `article` in Firefox 4+,
- * Safari 5, and Chrome.
- */
-
-h1 {
- font-size: 2em;
-}
-
-/*
- * Addresses styling not present in IE 8/9, Safari 5, and Chrome.
- */
-
-abbr[title] {
- border-bottom: 1px dotted;
-}
-
-/*
- * Addresses style set to `bolder` in Firefox 4+, Safari 5, and Chrome.
- */
-
-b,
-strong {
- font-weight: bold;
-}
-
-/*
- * Addresses styling not present in Safari 5 and Chrome.
- */
-
-dfn {
- font-style: italic;
-}
-
-/*
- * Addresses styling not present in IE 8/9.
- */
-
-mark {
- background: #ff0;
- color: #000;
-}
-
-
-/*
- * Corrects font family set oddly in Safari 5 and Chrome.
- */
-
-code,
-kbd,
-pre,
-samp {
- font-family: monospace, serif;
- font-size: 1em;
-}
-
-/*
- * Improves readability of pre-formatted text in all browsers.
- */
-
-pre {
- white-space: pre;
- white-space: pre-wrap;
- word-wrap: break-word;
-}
-
-/*
- * Sets consistent quote types.
- */
-
-q {
- quotes: "\201C" "\201D" "\2018" "\2019";
-}
-
-/*
- * Addresses inconsistent and variable font size in all browsers.
- */
-
-small {
- font-size: 80%;
-}
-
-/*
- * Prevents `sub` and `sup` affecting `line-height` in all browsers.
- */
-
-sub,
-sup {
- font-size: 75%;
- line-height: 0;
- position: relative;
- vertical-align: baseline;
-}
-
-sup {
- top: -0.5em;
-}
-
-sub {
- bottom: -0.25em;
-}
-
-/* ==========================================================================
- Embedded content
- ========================================================================== */
-
-/*
- * Removes border when inside `a` element in IE 8/9.
- */
-
-img {
- border: 0;
-}
-
-/*
- * Corrects overflow displayed oddly in IE 9.
- */
-
-svg:not(:root) {
- overflow: hidden;
-}
-
-/* ==========================================================================
- Figures
- ========================================================================== */
-
-/*
- * Addresses margin not present in IE 8/9 and Safari 5.
- */
-
-figure {
- margin: 0;
-}
-
-/* ==========================================================================
- Forms
- ========================================================================== */
-
-/*
- * Define consistent border, margin, and padding.
- */
-
-fieldset {
- border: 1px solid #c0c0c0;
- margin: 0 2px;
- padding: 0.35em 0.625em 0.75em;
-}
-
-/*
- * 1. Corrects color not being inherited in IE 8/9.
- * 2. Remove padding so people aren't caught out if they zero out fieldsets.
- */
-
-legend {
- border: 0; /* 1 */
- padding: 0; /* 2 */
-}
-
-/*
- * 1. Corrects font family not being inherited in all browsers.
- * 2. Corrects font size not being inherited in all browsers.
- * 3. Addresses margins set differently in Firefox 4+, Safari 5, and Chrome
- */
-
-button,
-input,
-select,
-textarea {
- font-family: inherit; /* 1 */
- font-size: 100%; /* 2 */
- margin: 0; /* 3 */
-}
-
-/*
- * Addresses Firefox 4+ setting `line-height` on `input` using `!important` in
- * the UA stylesheet.
- */
-
-button,
-input {
- line-height: normal;
-}
-
-/*
- * 1. Avoid the WebKit bug in Android 4.0.* where (2) destroys native `audio`
- * and `video` controls.
- * 2. Corrects inability to style clickable `input` types in iOS.
- * 3. Improves usability and consistency of cursor style between image-type
- * `input` and others.
- */
-
-button,
-html input[type="button"], /* 1 */
-input[type="reset"],
-input[type="submit"] {
- -webkit-appearance: button; /* 2 */
- cursor: pointer; /* 3 */
-}
-
-/*
- * Re-set default cursor for disabled elements.
- */
-
-button[disabled],
-input[disabled] {
- cursor: default;
-}
-
-/*
- * 1. Addresses box sizing set to `content-box` in IE 8/9.
- * 2. Removes excess padding in IE 8/9.
- */
-
-input[type="checkbox"],
-input[type="radio"] {
- box-sizing: border-box; /* 1 */
- padding: 0; /* 2 */
-}
-
-/*
- * 1. Addresses `appearance` set to `searchfield` in Safari 5 and Chrome.
- * 2. Addresses `box-sizing` set to `border-box` in Safari 5 and Chrome
- * (include `-moz` to future-proof).
- */
-
-input[type="search"] {
- -webkit-appearance: textfield; /* 1 */
- -moz-box-sizing: content-box;
- -webkit-box-sizing: content-box; /* 2 */
- box-sizing: content-box;
-}
-
-/*
- * Removes inner padding and search cancel button in Safari 5 and Chrome
- * on OS X.
- */
-
-input[type="search"]::-webkit-search-cancel-button,
-input[type="search"]::-webkit-search-decoration {
- -webkit-appearance: none;
-}
-
-/*
- * Removes inner padding and border in Firefox 4+.
- */
-
-button::-moz-focus-inner,
-input::-moz-focus-inner {
- border: 0;
- padding: 0;
-}
-
-/*
- * 1. Removes default vertical scrollbar in IE 8/9.
- * 2. Improves readability and alignment in all browsers.
- */
-
-textarea {
- overflow: auto; /* 1 */
- vertical-align: top; /* 2 */
-}
-
-/* ==========================================================================
- Tables
- ========================================================================== */
-
-/*
- * Remove most spacing between table cells.
- */
-
-table {
- border-collapse: collapse;
- border-spacing: 0;
-}
\ No newline at end of file
diff --git a/docs/release checklist.md b/docs/release checklist.md
deleted file mode 100644
index e3fecc14..00000000
--- a/docs/release checklist.md
+++ /dev/null
@@ -1,7 +0,0 @@
-Steps to release twig.js
-
-1. Update version in package.json
-2. Update version in bower.json
-3. Update version in src/twig.header.js
-4. `git tag` new version
-
diff --git a/docs/tests.md b/docs/tests.md
deleted file mode 100644
index 5ae399c6..00000000
--- a/docs/tests.md
+++ /dev/null
@@ -1,2622 +0,0 @@
-# TOC
- - [Twig.js Blocks ->](#twigjs-blocks--)
- - [block function ->](#twigjs-blocks---block-function--)
- - [Twig.js Control Structures ->](#twigjs-control-structures--)
- - [if tag ->](#twigjs-control-structures---if-tag--)
- - [for tag ->](#twigjs-control-structures---for-tag--)
- - [set tag ->](#twigjs-control-structures---set-tag--)
- - [Twig.js Core ->](#twigjs-core--)
- - [Key Notation ->](#twigjs-core---key-notation--)
- - [Context ->](#twigjs-core---context--)
- - [Twig.js Expressions ->](#twigjs-expressions--)
- - [Basic Operators ->](#twigjs-expressions---basic-operators--)
- - [Comparison Operators ->](#twigjs-expressions---comparison-operators--)
- - [Other Operators ->](#twigjs-expressions---other-operators--)
- - [Twig.js Extensions ->](#twigjs-extensions--)
- - [Twig.js Filters ->](#twigjs-filters--)
- - [url_encode ->](#twigjs-filters---url_encode--)
- - [json_encode ->](#twigjs-filters---json_encode--)
- - [upper ->](#twigjs-filters---upper--)
- - [lower ->](#twigjs-filters---lower--)
- - [capitalize ->](#twigjs-filters---capitalize--)
- - [title ->](#twigjs-filters---title--)
- - [length ->](#twigjs-filters---length--)
- - [sort ->](#twigjs-filters---sort--)
- - [reverse ->](#twigjs-filters---reverse--)
- - [keys ->](#twigjs-filters---keys--)
- - [merge ->](#twigjs-filters---merge--)
- - [join ->](#twigjs-filters---join--)
- - [default ->](#twigjs-filters---default--)
- - [date ->](#twigjs-filters---date--)
- - [replace ->](#twigjs-filters---replace--)
- - [format ->](#twigjs-filters---format--)
- - [striptags ->](#twigjs-filters---striptags--)
- - [escape ->](#twigjs-filters---escape--)
- - [e ->](#twigjs-filters---e--)
- - [nl2br ->](#twigjs-filters---nl2br--)
- - [trim ->](#twigjs-filters---trim--)
- - [number_format ->](#twigjs-filters---number_format--)
- - [slice ->](#twigjs-filters---slice--)
- - [abs ->](#twigjs-filters---abs--)
- - [first ->](#twigjs-filters---first--)
- - [split ->](#twigjs-filters---split--)
- - [batch ->](#twigjs-filters---batch--)
- - [last ->](#twigjs-filters---last--)
- - [round ->](#twigjs-filters---round--)
- - [Twig.js Loader ->](#twigjs-loader--)
- - [Twig.js Include ->](#twigjs-include--)
- - [Twig.js Functions ->](#twigjs-functions--)
- - [Built-in Functions ->](#twigjs-functions---built-in-functions--)
- - [range ->](#twigjs-functions---built-in-functions---range--)
- - [cycle ->](#twigjs-functions---built-in-functions---cycle--)
- - [date ->](#twigjs-functions---built-in-functions---date--)
- - [dump ->](#twigjs-functions---built-in-functions---dump--)
- - [block ->](#twigjs-functions---built-in-functions---block--)
- - [attribute ->](#twigjs-functions---built-in-functions---attribute--)
- - [Twig.js Macro ->](#twigjs-macro--)
- - [Twig.js Optional Functionality ->](#twigjs-optional-functionality--)
- - [Twig.js Regression Tests ->](#twigjs-regression-tests--)
- - [Twig.js Tags ->](#twigjs-tags--)
- - [Twig.js Tests ->](#twigjs-tests--)
- - [empty test ->](#twigjs-tests---empty-test--)
- - [odd test ->](#twigjs-tests---odd-test--)
- - [even test ->](#twigjs-tests---even-test--)
- - [divisibleby test ->](#twigjs-tests---divisibleby-test--)
- - [defined test ->](#twigjs-tests---defined-test--)
- - [none test ->](#twigjs-tests---none-test--)
- - [sameas test ->](#twigjs-tests---sameas-test--)
-
-
-
-# Twig.js Blocks ->
-should load a parent template and render the default values.
-
-```js
-twig({
- id: 'remote-no-extends',
- path: 'test/templates/template.twig',
- async: false
-});
-
-// Load the template
-twig({ref: 'remote-no-extends'}).render({ }).should.equal( "Default Title - body" );
-```
-
-should understand {% endblock title %} syntax.
-
-```js
-twig({
- id: 'endblock-extended-syntax',
- path: 'test/templates/blocks-extended-syntax.twig',
- async: false
-});
-
-// Load the template
-twig({ref: 'endblock-extended-syntax'}).render({ }).should.equal( "This is the only thing." );
-```
-
-should load a child template and replace the parent block's content.
-
-```js
-// Test loading a template from a remote endpoint
-twig({
- id: 'child-extends',
- path: 'test/templates/child.twig',
-
- load: function(template) {
- template.render({ base: "template.twig" }).should.equal( "Other Title - child" );
- done();
- }
-});
-```
-
-should have access to a parent block content.
-
-```js
-// Test loading a template from a remote endpoint
-twig({
- id: 'child-parent',
- path: 'test/templates/child-parent.twig',
-
- load: function(template) {
- template.render({
- base: "template.twig",
- inner: ':value'
- }).should.equal( "Other Title - body:value:child" );
- done();
- }
-});
-```
-
-should include blocks from another template for horizontal reuse.
-
-```js
-// Test horizontal reuse
-twig({
- id: 'use',
- path: 'test/templates/use.twig',
-
- load: function(template) {
- // Load the template
- template.render({ place: "diner" }).should.equal("Coming soon to a diner near you!" );
- done();
- }
-});
-```
-
-should make the contents of blocks available after they're rendered.
-
-```js
-// Test rendering and loading one block
-twig({
- id: 'blocks',
- path: 'test/templates/blocks.twig',
-
- load: function(template) {
- // Render the template with the blocks parameter
- template.render({ place: "block" }, {output: 'blocks'}).msg.should.equal("Coming soon to a block near you!" );
- done();
- }
-});
-```
-
-should render nested blocks.
-
-```js
-// Test rendering of blocks within blocks
-twig({
- id: 'blocks-nested',
- path: 'test/templates/blocks-nested.twig',
-
- load: function(template) {
- template.render({ }).should.equal( "parent:child" )
- done();
- }
-})
-```
-
-should render extended nested blocks.
-
-```js
-// Test rendering of blocks within blocks
-twig({
- id: 'child-blocks-nested',
- path: 'test/templates/child-blocks-nested.twig',
-
- load: function(template) {
- template.render({ base: "template.twig" }).should.equal( "Default Title - parent:child" );
- done();
- }
-})
-```
-
-should be able to extend to a absolute template path.
-
-```js
-// Test loading a template from a remote endpoint
-twig({
- base: 'test/templates',
- path: 'test/templates/a/child.twig',
-
- load: function(template) {
- template.render({ base: "b/template.twig" }).should.equal( "Other Title - child" );
- done();
- }
-});
-```
-
-should extends blocks inline.
-
-```js
-twig({
- id: 'inline-parent-template',
- data: 'Title: {% block title %}parent{% endblock %}'
-});
-
-twig({
- allowInlineIncludes: true,
- data: '{% extends "inline-parent-template" %}{% block title %}child{% endblock %}'
-}).render().should.equal("Title: child");
-```
-
-
-## block function ->
-should render block content from an included block.
-
-```js
-twig({
- path: 'test/templates/block-function.twig',
-
- load: function(template) {
- template.render({
- base: "block-function-parent.twig",
- val: "abcd"
- })
- .should.equal( "Child content = abcd / Result: Child content = abcd" );
-
- done();
- }
-})
-```
-
-should render block content from a parent block.
-
-```js
-twig({
- path: 'test/templates/block-parent.twig',
-
- load: function(template) {
- template.render({
- base: "block-function-parent.twig"
- })
- .should.equal( "parent block / Result: parent block" );
-
- done();
- }
-})
-```
-
-should render block content with outer context.
-
-```js
-twig({
- path: 'test/templates/block-outer-context.twig',
-
- load: function(template) {
- template.render({
- base: "block-outer-context.twig",
- items: ["twig", "js", "rocks"]
- })
- .should.equal( "Hello twig!Hello js!Hello rocks!twigjsrocks" );
-
- done();
- }
-})
-```
-
-
-# Twig.js Control Structures ->
-
-## if tag ->
-should parse the contents of the if block if the expression is true.
-
-```js
-var test_template = twig({data: '{% if test %}true{% endif%}'});
-test_template.render({test: true}).should.equal("true" );
-test_template.render({test: false}).should.equal("" );
-```
-
-should call the if or else blocks based on the expression result.
-
-```js
-var test_template = twig({data: '{% if test %}true{% endif%}'});
-test_template.render({test: true}).should.equal("true" );
-test_template.render({test: false}).should.equal("" );
-```
-
-should support elseif.
-
-```js
-var test_template = twig({data: '{% if test %}1{% elseif other %}2{%else%}3{% endif%}'});
-test_template.render({test: true, other:false}).should.equal("1" );
-test_template.render({test: true, other:true}).should.equal("1" );
-test_template.render({test: false, other:true}).should.equal("2" );
-test_template.render({test: false, other:false}).should.equal("3" );
-```
-
-should be able to nest.
-
-```js
-var test_template = twig({data: '{% if test %}{% if test2 %}true{% else %}false{% endif%}{% else %}not{% endif%}'});
-test_template.render({test: true, test2: true}).should.equal("true" );
-test_template.render({test: true, test2: false}).should.equal("false" );
-test_template.render({test: false, test2: true}).should.equal("not" );
-test_template.render({test: false, test2: false}).should.equal("not" );
-```
-
-
-## for tag ->
-should provide value only for array input.
-
-```js
-var test_template = twig({data: '{% for value in test %}{{ value }}{% endfor %}'});
-test_template.render({test: [1,2,3,4]}).should.equal("1234" );
-test_template.render({test: []}).should.equal("" );
-```
-
-should provide both key and value for array input.
-
-```js
-var test_template = twig({data: '{% for key,value in test %}{{key}}:{{ value }}{% endfor %}'});
-test_template.render({test: [1,2,3,4]}).should.equal("0:11:22:33:4" );
-test_template.render({test: []}).should.equal("" );
-```
-
-should provide value only for object input.
-
-```js
-var test_template = twig({data: '{% for value in test %}{{ value }}{% endfor %}'});
-test_template.render({test: {one: 1, two: 2, three: 3}}).should.equal("123" );
-test_template.render({test: {}}).should.equal("" );
-```
-
-should provide both key and value for object input.
-
-```js
-var test_template = twig({data: '{% for key, value in test %}{{key}}:{{ value }}{% endfor %}'});
-test_template.render({test: {one: 1, two: 2, three: 3}}).should.equal("one:1two:2three:3" );
-test_template.render({test: {}}).should.equal("" );
-```
-
-should support else if the input is empty.
-
-```js
-var test_template = twig({data: '{% for key,value in test %}{{ value }}{% else %}else{% endfor %}'});
-test_template.render({test: [1,2,3,4]}).should.equal("1234" );
-test_template.render({test: []}).should.equal("else" );
-```
-
-should be able to nest.
-
-```js
-var test_template = twig({data: '{% for key,list in test %}{% for val in list %}{{ val }}{%endfor %}.{% else %}else{% endfor %}'});
-test_template.render({test: [[1,2],[3,4],[5,6]]}).should.equal("12.34.56." );
-test_template.render({test: []}).should.equal("else" );
-```
-
-should have a loop context item available for arrays.
-
-```js
-var test_template = twig({data: '{% for key,value in test %}{{ loop.index }}{% endfor %}'});
-test_template.render({test: [1,2,3,4]}).should.equal("1234" );
-test_template = twig({data: '{% for key,value in test %}{{ loop.index0 }}{% endfor %}'});
-test_template.render({test: [1,2,3,4]}).should.equal("0123" );
-test_template = twig({data: '{% for key,value in test %}{{ loop.revindex }}{% endfor %}'});
-test_template.render({test: [1,2,3,4]}).should.equal("4321" );
-test_template = twig({data: '{% for key,value in test %}{{ loop.revindex0 }}{% endfor %}'});
-test_template.render({test: [1,2,3,4]}).should.equal("3210" );
-test_template = twig({data: '{% for key,value in test %}{{ loop.length }}{% endfor %}'});
-test_template.render({test: [1,2,3,4]}).should.equal("4444" );
-test_template = twig({data: '{% for key,value in test %}{{ loop.first }}{% endfor %}'});
-test_template.render({test: [1,2,3,4]}).should.equal("truefalsefalsefalse" );
-test_template = twig({data: '{% for key,value in test %}{{ loop.last }}{% endfor %}'});
-test_template.render({test: [1,2,3,4]}).should.equal("falsefalsefalsetrue" );
-```
-
-should have a loop context item available for objects.
-
-```js
-var test_template = twig({data: '{% for key,value in test %}{{ loop.index }}{% endfor %}'});
-test_template.render({test: {a:1,b:2,c:3,d:4}}).should.equal("1234" );
-test_template = twig({data: '{% for key,value in test %}{{ loop.index0 }}{% endfor %}'});
-test_template.render({test: {a:1,b:2,c:3,d:4}}).should.equal("0123" );
-test_template = twig({data: '{% for key,value in test %}{{ loop.revindex }}{% endfor %}'});
-test_template.render({test: {a:1,b:2,c:3,d:4}}).should.equal("4321" );
-test_template = twig({data: '{% for key,value in test %}{{ loop.revindex0 }}{% endfor %}'});
-test_template.render({test: {a:1,b:2,c:3,d:4}}).should.equal("3210" );
-test_template = twig({data: '{% for key,value in test %}{{ loop.length }}{% endfor %}'});
-test_template.render({test: {a:1,b:2,c:3,d:4}}).should.equal("4444" );
-test_template = twig({data: '{% for key,value in test %}{{ loop.first }}{% endfor %}'});
-test_template.render({test: {a:1,b:2,c:3,d:4}}).should.equal("truefalsefalsefalse" );
-test_template = twig({data: '{% for key,value in test %}{{ loop.last }}{% endfor %}'});
-test_template.render({test: {a:1,b:2,c:3,d:4}}).should.equal("falsefalsefalsetrue" );
-```
-
-should have a loop context item available in child loops objects.
-
-```js
-var test_template = twig({data: '{% for value in test %}{% for value in inner %}({{ loop.parent.loop.index }},{{ loop.index }}){% endfor %}{% endfor %}'});
-test_template.render({test: {a:1,b:2}, inner:[1,2,3]}).should.equal("(1,1)(1,2)(1,3)(2,1)(2,2)(2,3)");
-```
-
-should support conditionals on for loops.
-
-```js
-var test_template = twig({data: '{% for value in test if false %}{{ value }},{% endfor %}'});
-test_template.render({test: ["one", "two", "a", "b", "other"]}).should.equal("");
-
-test_template = twig({data: '{% for value in test if true %}{{ value }}{% endfor %}'});
-test_template.render({test: ["a", "s", "d", "f"]}).should.equal("asdf");
-
-test_template = twig({data: '{% for value in test if value|length > 2 %}{{ value }},{% endfor %}'});
-test_template.render({test: ["one", "two", "a", "b", "other"]}).should.equal("one,two,other,");
-
-test_template = twig({data: '{% for key,item in test if item.show %}{{key}}:{{ item.value }},{% endfor %}'});
-test_template.render({test: {
- a: {show:true, value: "one"},
- b: {show:false, value: "two"},
- c: {show:true, value: "three"}}}).should.equal("a:one,c:three,");
-```
-
-
-## set tag ->
-should set the global context from within a for loop.
-
-```js
-var test_template = twig({data: '{% set value="wrong" %}{% for value in [1] %}{% set value="right" %}{% endfor %}{{value}}'});
-test_template.render().should.equal("right");
-```
-
-
-# Twig.js Core ->
-should save and load a template by reference.
-
-```js
-// Define and save a template
- twig({
- id: 'test',
- data: '{{ "test" }}'
- });
-// Load and render the template
- twig({ref: 'test'}).render()
- .should.equal("test");
-```
-
-should ignore comments.
-
-```js
-twig({data: 'good {# comment #}morning'}).render().should.equal("good morning");
-twig({data: 'good{#comment#}morning'}).render().should.equal("goodmorning");
-```
-
-should ignore output tags within comments.
-
-```js
-twig({data: 'good {# {{ "Hello" }} #}morning'}).render().should.equal("good morning");
-twig({data: 'good{#c}}om{{m{{ent#}morning'}).render().should.equal("goodmorning");
-```
-
-should ignore logic tags within comments.
-
-```js
-twig({data: 'test {# {% bad syntax if not in comment %} #}test'}).render().should.equal("test test");
-twig({data: '{##}{##}test{# %}}}%}%{%{{% #}pass'}).render().should.equal("testpass");
-```
-
-should ignore quotation marks within comments.
-
-```js
-twig({data: "good {# don't stop #}morning"}).render().should.equal("good morning");
-twig({data: 'good{#"dont stop"#}morning'}).render().should.equal("goodmorning");
-twig({data: 'good {# "don\'t stop" #}morning'}).render().should.equal("good morning");
-twig({data: 'good{#"\'#}morning'}).render().should.equal("goodmorning");
-twig({data: 'good {#"\'"\'"\'#} day'}).render().should.equal("good day");
-twig({data: "a {# ' #}b{# ' #} c"}).render().should.equal("a b c");
-```
-
-should be able to parse output tags with tag ends in strings.
-
-```js
-// Really all we care about here is not throwing exceptions.
-twig({data: '{{ "test" }}'}).render().should.equal("test");
-twig({data: '{{ " }} " }}'}).render().should.equal(" }} ");
-twig({data: '{{ " \\"}} " }}'}).render().should.equal(' "}} ');
-twig({data: "{{ ' }} ' }}"}).render().should.equal(" }} ");
-twig({data: "{{ ' \\'}} ' }}"}).render().should.equal(" '}} ");
-
-twig({data: '{{ " \'}} " }}'}).render().should.equal(" '}} ");
-twig({data: "{{ ' \"}} ' }}"}).render().should.equal(' "}} ');
-```
-
-should be able to output numbers.
-
-```js
-twig({data: '{{ 12 }}'}).render().should.equal( "12" );
-twig({data: '{{ 12.64 }}'}).render().should.equal( "12.64" );
-twig({data: '{{ 0.64 }}'}).render().should.equal("0.64" );
-```
-
-should be able to output booleans.
-
-```js
-twig({data: '{{ true }}'}).render().should.equal( "true" );
-twig({data: '{{ false }}'}).render().should.equal( "false" );
-```
-
-should be able to output strings.
-
-```js
-twig({data: '{{ "double" }}'}).render().should.equal("double");
-twig({data: "{{ 'single' }}"}).render().should.equal('single');
-twig({data: '{{ "dou\'ble" }}'}).render().should.equal("dou'ble");
-twig({data: "{{ 'sin\"gle' }}"}).render().should.equal('sin"gle');
-twig({data: '{{ "dou\\"ble" }}'}).render().should.equal("dou\"ble");
-twig({data: "{{ 'sin\\'gle' }}"}).render().should.equal("sin'gle");
-```
-
-should be able to output arrays.
-
-```js
-twig({data: '{{ [1] }}'}).render().should.equal("1" );
-twig({data: '{{ [1,2 ,3 ] }}'}).render().should.equal("1,2,3" );
-twig({data: '{{ [1,2 ,3 , val ] }}'}).render({val: 4}).should.equal("1,2,3,4" );
-twig({data: '{{ ["[to",\'the\' ,"string]" ] }}'}).render().should.equal('[to,the,string]' );
-twig({data: '{{ ["[to",\'the\' ,"str\\"ing]" ] }}'}).render().should.equal('[to,the,str"ing]' );
-```
-
-should be able to output parse expressions in an array.
-
-```js
-twig({data: '{{ [1,2 ,1+2 ] }}'}).render().should.equal("1,2,3" );
-twig({data: '{{ [1,2 ,3 , "-", [4,5, 6] ] }}'}).render({val: 4}).should.equal("1,2,3,-,4,5,6" );
-twig({data: '{{ [a,b ,(1+2) * a ] }}'}).render({a:1,b:2}).should.equal("1,2,3" );
-```
-
-should be able to output variables.
-
-```js
-twig({data: '{{ orp }}'}).render({ orp: "test"}).should.equal("test");
-twig({data: '{{ val }}'}).render({ val: function() {
- return "test"
- }}).should.equal("test");
-```
-
-should recognize null.
-
-```js
-twig({data: '{{ null == val }}'}).render({val: null}).should.equal( "true" );
-twig({data: '{{ null == val }}'}).render({val: undefined}).should.equal( "true" );
-
-twig({data: '{{ null == val }}'}).render({val: "test"}).should.equal( "false" );
-twig({data: '{{ null == val }}'}).render({val: 0}).should.equal( "false" );
-twig({data: '{{ null == val }}'}).render({val: false}).should.equal( "false" );
-```
-
-should recognize object literals.
-
-```js
-twig({data: '{% set at = {"foo": "test", bar: "other", 1:"zip"} %}{{ at.foo ~ at.bar ~ at.1 }}'}).render().should.equal( "testotherzip" );
-```
-
-should recognize null in an object.
-
-```js
-twig({data: '{% set at = {"foo": null} %}{{ at.foo == val }}'}).render({val: null}).should.equal( "true" );
-```
-
-should support set capture.
-
-```js
-twig({data: '{% set foo %}bar{% endset %}{{foo}}'}).render().should.equal( "bar" );
-```
-
-should support raw data.
-
-```js
-twig({
- data: "before {% raw %}{{ test }} {% test2 %} {{{% endraw %} after"
-}).render().should.equal(
- "before {{ test }} {% test2 %} {{ after"
-);
-```
-
-
-## Key Notation ->
-should support dot key notation.
-
-```js
-twig({data: '{{ key.value }} {{ key.sub.test }}'}).render({
- key: {
- value: "test",
- sub: {
- test: "value"
- }
- }
-}).should.equal("test value");
-```
-
-should support square bracket key notation.
-
-```js
-twig({data: '{{ key["value"] }} {{ key[\'sub\']["test"] }}'}).render({
- key: {
- value: "test",
- sub: {
- test: "value"
- }
- }
-}).should.equal("test value");
-```
-
-should support mixed dot and bracket key notation.
-
-```js
-twig({data: '{{ key["value"] }} {{ key.sub[key.value] }} {{ s.t["u"].v["w"] }}'}).render({
- key: {
- value: "test",
- sub: {
- test: "value"
- }
- },
- s: { t: { u: { v: { w: 'x' } } } }
-}).should.equal("test value x" );
-```
-
-should support dot key notation after a function.
-
-```js
-var test_template = twig({data: '{{ key.fn().value }}'});
-var output = test_template.render({
- key: {
- fn: function() {
- return {
- value: "test"
- }
- }
- }
-});
-output.should.equal("test");
-```
-
-should support bracket key notation after a function.
-
-```js
-var test_template = twig({data: '{{ key.fn()["value"] }}'});
-var output = test_template.render({
- key: {
- fn: function() {
- return {
- value: "test 2"
- }
- }
- }
-});
-output.should.equal("test 2");
-```
-
-should check for getKey methods if a key doesn't exist..
-
-```js
-twig({data: '{{ obj.value }}'}).render({
- obj: {
- getValue: function() {
- return "val";
- },
- isValue: function() {
- return "not val";
- }
- }
-}).should.equal("val");
-```
-
-should check for isKey methods if a key doesn't exist..
-
-```js
-twig({data: '{{ obj.value }}'}).render({
- obj: {
- isValue: function() {
- return "val";
- }
- }
-}).should.equal("val");
-```
-
-should check for getKey methods on prototype objects..
-
-```js
-var object = {
- getValue: function() {
- return "val";
- }
- };
-function Subobj() {};
-Subobj.prototype = object;
-var subobj = new Subobj();
-
- twig({data: '{{ obj.value }}'}).render({
- obj: subobj
- }).should.equal("val");
-```
-
-should return null if a period key doesn't exist..
-
-```js
-twig({data: '{{ obj.value == null }}'}).render({
- obj: {}
-}).should.equal("true");
-```
-
-should return null if a bracket key doesn't exist..
-
-```js
-twig({data: '{{ obj["value"] == null }}'}).render({
- obj: {}
-}).should.equal("true");
-```
-
-
-## Context ->
-should be supported.
-
-```js
-twig({data: '{{ _context.value }}'}).render({
- value: "test"
-}).should.equal("test");
-```
-
-should be an object even if it's not passed.
-
-```js
-twig({data: '{{ _context|json_encode }}'}).render().should.equal("{}");
-```
-
-should support {% set %} tag.
-
-```js
-twig({data: '{% set value = "test" %}{{ _context.value }}'}).render().should.equal("test");
-```
-
-should work correctly with properties named dynamically.
-
-```js
-twig({data: '{{ _context[key] }}'}).render({
- key: "value",
- value: "test"
-}).should.equal("test");
-```
-
-should not allow to override context using {% set %}.
-
-```js
-twig({data: '{% set _context = "test" %}{{ _context|json_encode }}'}).render().should.equal('{"_context":"test"}');
-twig({data: '{% set _context = "test" %}{{ _context._context }}'}).render().should.equal("test");
-```
-
-
-# Twig.js Expressions ->
-
-## Basic Operators ->
-should parse parenthesis.
-
-```js
-var test_template = twig({data: '{{ a - (b + c) }}'}),
- d = {a: 10, b: 4, c: 2},
- output = test_template.render(d);
-
-output.should.equal( (d.a - (d.b + d.c)).toString() );
-```
-
-should parse nested parenthesis.
-
-```js
-var test_template = twig({data: '{{ a - ((b) + (1 + c)) }}'}),
- d = {a: 10, b: 4, c: 2},
- output = test_template.render(d);
-
-output.should.equal( (d.a - (d.b + 1 + d.c)).toString() );
-```
-
-should add numbers.
-
-```js
-var test_template = twig({data: '{{ a + b }}'});
-numeric_test_data.forEach(function(pair) {
- var output = test_template.render(pair);
- output.should.equal( (pair.a + pair.b).toString() );
-});
-```
-
-should subtract numbers.
-
-```js
-var test_template = twig({data: '{{ a - b }}'});
-numeric_test_data.forEach(function(pair) {
- var output = test_template.render(pair);
- output.should.equal( (pair.a - pair.b).toString() );
-});
-```
-
-should multiply numbers.
-
-```js
-var test_template = twig({data: '{{ a * b }}'});
-numeric_test_data.forEach(function(pair) {
- var output = test_template.render(pair);
- output.should.equal((pair.a * pair.b).toString() );
-});
-```
-
-should divide numbers.
-
-```js
-var test_template = twig({data: '{{ a / b }}'});
-numeric_test_data.forEach(function(pair) {
- var output = test_template.render(pair);
- output.should.equal((pair.a / pair.b).toString() );
-});
-```
-
-should divide numbers and return an int result.
-
-```js
-var test_template = twig({data: '{{ a // b }}'});
-numeric_test_data.forEach(function(pair) {
- var output = test_template.render(pair);
- // Get expected truncated result
- var c = parseInt(pair.a/pair.b);
-
- output.should.equal(c.toString() );
-});
-```
-
-should raise numbers to a power.
-
-```js
-var test_template = twig({data: '{{ a ** b }}'});
-var pow_test_data = [
- {a: 2, b:3, c: 8}
- , {a: 4, b:.5, c: 2}
- , {a: 5, b: 1, c: 5}
-];
-pow_test_data.forEach(function(pair) {
- var output = test_template.render(pair);
- output.should.equal(pair.c.toString() );
-});
-```
-
-should concatanate values.
-
-```js
-twig({data: '{{ "test" ~ a }}'}).render({a:1234}).should.equal("test1234");
-twig({data: '{{ a ~ "test" ~ a }}'}).render({a:1234}).should.equal("1234test1234");
-twig({data: '{{ "this" ~ "test" }}'}).render({a:1234}).should.equal("thistest");
-
-// Test numbers
-var test_template = twig({data: '{{ a ~ b }}'});
-numeric_test_data.forEach(function(pair) {
- var output = test_template.render(pair);
- output.should.equal(pair.a.toString() + pair.b.toString());
-});
-// Test strings
-test_template = twig({data: '{{ a ~ b }}'});
-string_data.forEach(function(pair) {
- var output = test_template.render(pair);
- output.should.equal(pair.a.toString() + pair.b.toString());
-});
-```
-
-should handle multiple chained operations.
-
-```js
-var data = {a: 4.5, b: 10, c: 12, d: -0.25, e:0, f: 65, g: 21, h: -0.0002};
-var test_template = twig({data: '{{a/b+c*d-e+f/g*h}}'});
-var output = test_template.render(data);
-var expected = data.a / data.b + data.c * data.d - data.e + data.f / data.g * data.h;
-output.should.equal(expected.toString());
-```
-
-should handle parenthesis in chained operations.
-
-```js
-var data = {a: 4.5, b: 10, c: 12, d: -0.25, e:0, f: 65, g: 21, h: -0.0002};
-var test_template = twig({data: '{{a /(b+c )*d-(e+f)/(g*h)}}'});
-var output = test_template.render(data);
-var expected = data.a / (data.b + data.c) * data.d - (data.e + data.f) / (data.g * data.h);
-output.should.equal(expected.toString());
-```
-
-
-## Comparison Operators ->
-should support less then.
-
-```js
-var test_template = twig({data: '{{ a < b }}'});
-numeric_test_data.forEach(function(pair) {
- var output = test_template.render(pair);
- output.should.equal((pair.a < pair.b).toString() );
-});
-```
-
-should support less then or equal.
-
-```js
-var test_template = twig({data: '{{ a <= b }}'});
-numeric_test_data.forEach(function(pair) {
- var output = test_template.render(pair);
- output.should.equal((pair.a <= pair.b).toString() );
-});
-```
-
-should support greater then.
-
-```js
-var test_template = twig({data: '{{ a > b }}'});
-numeric_test_data.forEach(function(pair) {
- var output = test_template.render(pair);
- output.should.equal((pair.a > pair.b).toString() );
-});
-```
-
-should support greater then or equal.
-
-```js
-var test_template = twig({data: '{{ a >= b }}'});
-numeric_test_data.forEach(function(pair) {
- var output = test_template.render(pair);
- output.should.equal((pair.a >= pair.b).toString() );
-});
-```
-
-should support equals.
-
-```js
-var test_template = twig({data: '{{ a == b }}'});
-boolean_data.forEach(function(pair) {
- var output = test_template.render(pair);
- output.should.equal((pair.a == pair.b).toString() );
-});
-equality_data.forEach(function(pair) {
- var output = test_template.render(pair);
- output.should.equal((pair.a == pair.b).toString() );
-});
-```
-
-should support not equals.
-
-```js
-var test_template = twig({data: '{{ a != b }}'});
-boolean_data.forEach(function(pair) {
- var output = test_template.render(pair);
- output.should.equal((pair.a != pair.b).toString() );
-});
-equality_data.forEach(function(pair) {
- var output = test_template.render(pair);
- output.should.equal((pair.a != pair.b).toString() );
-});
-```
-
-should support boolean or.
-
-```js
-var test_template = twig({data: '{{ a or b }}'});
-boolean_data.forEach(function(pair) {
- var output = test_template.render(pair);
- output.should.equal((pair.a || pair.b).toString() );
-});
-```
-
-should support boolean and.
-
-```js
-var test_template = twig({data: '{{ a and b }}'});
-boolean_data.forEach(function(pair) {
- var output = test_template.render(pair);
- output.should.equal((pair.a && pair.b).toString() );
-});
-```
-
-should support boolean not.
-
-```js
-var test_template = twig({data: '{{ not a }}'});
-test_template.render({a:false}).should.equal(true.toString());
-test_template.render({a:true}).should.equal(false.toString());
-```
-
-
-## Other Operators ->
-should support the ternary operator.
-
-```js
-var test_template = twig({data: '{{ a ? b:c }}'})
- , output_t = test_template.render({a: true, b: "one", c: "two"})
- , output_f = test_template.render({a: false, b: "one", c: "two"});
-
-output_t.should.equal( "one" );
-output_f.should.equal( "two" );
-```
-
-should support the ternary operator with objects in it.
-
-```js
-var test_template2 = twig({data: '{{ (a ? {"a":e+f}:{"a":1}).a }}'})
- , output2 = test_template2.render({a: true, b: false, e: 1, f: 2});
-
-output2.should.equal( "3" );
-```
-
-should support the ternary operator inside objects.
-
-```js
-var test_template2 = twig({data: '{{ {"b" : a or b ? {"a":e+f}:{"a":1} }.b.a }}'})
- , output2 = test_template2.render({a: false, b: false, e: 1, f: 2});
-
-output2.should.equal( "1" );
-```
-
-should support in/containment functionality for arrays.
-
-```js
-var test_template = twig({data: '{{ "a" in ["a", "b", "c"] }}'});
-test_template.render().should.equal(true.toString());
-
-var test_template = twig({data: '{{ "d" in ["a", "b", "c"] }}'});
-test_template.render().should.equal(false.toString());
-```
-
-should support not in/containment functionality for arrays.
-
-```js
-var test_template = twig({data: '{{ "a" not in ["a", "b", "c"] }}'});
-test_template.render().should.equal(false.toString());
-
-var test_template = twig({data: '{{ "d" not in ["a", "b", "c"] }}'});
-test_template.render().should.equal(true.toString());
-```
-
-should support in/containment functionality for strings.
-
-```js
-var test_template = twig({data: '{{ "at" in "hat" }}'});
-test_template.render().should.equal(true.toString());
-
-var test_template = twig({data: '{{ "d" in "not" }}'});
-test_template.render().should.equal(false.toString());
-```
-
-should support not in/containment functionality for strings.
-
-```js
-var test_template = twig({data: '{{ "at" not in "hat" }}'});
-test_template.render().should.equal(false.toString());
-
-var test_template = twig({data: '{{ "d" not in "not" }}'});
-test_template.render().should.equal(true.toString());
-```
-
-should support in/containment functionality for objects.
-
-```js
-var test_template = twig({data: '{{ "value" in {"key" : "value", "2": "other"} }}'});
-test_template.render().should.equal(true.toString());
-
-var test_template = twig({data: '{{ "d" in {"key_a" : "no"} }}'});
-test_template.render().should.equal(false.toString());
-```
-
-should support not in/containment functionality for objects.
-
-```js
-var test_template = twig({data: '{{ "value" not in {"key" : "value", "2": "other"} }}'});
-test_template.render().should.equal(false.toString());
-
-var test_template = twig({data: '{{ "d" not in {"key_a" : "no"} }}'});
-test_template.render().should.equal(true.toString());
-```
-
-
-# Twig.js Extensions ->
-should be able to extend a meta-type tag.
-
-```js
-var flags = {};
-
-Twig.extend(function(Twig) {
- Twig.exports.extendTag({
- type: "flag",
- regex: /^flag\s+(.+)$/,
- next: [ ],
- open: true,
- compile: function (token) {
- var expression = token.match[1];
-
- // Compile the expression.
- token.stack = Twig.expression.compile.apply(this, [{
- type: Twig.expression.type.expression,
- value: expression
- }]).stack;
-
- delete token.match;
- return token;
- },
- parse: function (token, context, chain) {
- var name = Twig.expression.parse.apply(this, [token.stack, context]),
- output = '';
-
- flags[name] = true;
-
- return {
- chain: false,
- output: output
- };
- }
- });
-});
-
-var template = twig({data:"{% flag 'enabled' %}"}).render();
-flags.enabled.should.equal(true);
-```
-
-should be able to extend paired tags.
-
-```js
-// demo data
-var App = {
- user: "john",
- users: {
- john: {level: "admin"},
- tom: {level: "user"}
- }
-};
-
-Twig.extend(function(Twig) {
- // example of extending a tag type that would
- // restrict content to the specified "level"
- Twig.exports.extendTag({
- type: "auth",
- regex: /^auth\s+(.+)$/,
- next: ["endauth"], // match the type of the end tag
- open: true,
- compile: function (token) {
- var expression = token.match[1];
-
- // turn the string expression into tokens.
- token.stack = Twig.expression.compile.apply(this, [{
- type: Twig.expression.type.expression,
- value: expression
- }]).stack;
-
- delete token.match;
- return token;
- },
- parse: function (token, context, chain) {
- var level = Twig.expression.parse.apply(this, [token.stack, context]),
- output = "";
-
- if (App.users[App.currentUser].level == level)
- {
- output = Twig.parse.apply(this, [token.output, context]);
- }
-
- return {
- chain: chain,
- output: output
- };
- }
- });
- Twig.exports.extendTag({
- type: "endauth",
- regex: /^endauth$/,
- next: [ ],
- open: false
- });
-});
-
-var template = twig({data:"Welcome{% auth 'admin' %} ADMIN{% endauth %}!"});
-
- App.currentUser = "john";
-template.render().should.equal("Welcome ADMIN!");
-
- App.currentUser = "tom";
- template.render().should.equal("Welcome!");
-```
-
-
-# Twig.js Filters ->
-should chain.
-
-```js
-var test_template = twig({data: '{{ ["a", "b", "c"]|keys|reverse }}' });
-test_template.render().should.equal("2,1,0");
-```
-
-
-## url_encode ->
-should encode URLs.
-
-```js
-var test_template = twig({data: '{{ "http://google.com/?q=twig.js"|url_encode() }}' });
-test_template.render().should.equal("http%3A%2F%2Fgoogle.com%2F%3Fq%3Dtwig.js" );
-```
-
-should handle undefined.
-
-```js
-var test_template = twig({data: '{{ undef|url_encode() }}' });
-test_template.render().should.equal("" );
-```
-
-
-## json_encode ->
-should encode strings to json.
-
-```js
-var test_template = twig({data: '{{ test|json_encode }}' });
-test_template.render({test:'value'}).should.equal('"value"' );
-```
-
-should encode numbers to json.
-
-```js
-var test_template = twig({data: '{{ test|json_encode }}' });
-test_template.render({test:21}).should.equal('21' );
-```
-
-should encode arrays to json.
-
-```js
-var test_template = twig({data: '{{ [1,"b",3]|json_encode }}' });
-test_template.render().should.equal('[1,"b",3]' );
-```
-
-should encode objects to json.
-
-```js
-var test_template = twig({data: '{{ {"a":[1,"b",3]}|json_encode }}' });
-test_template.render().should.equal('{"a":[1,"b",3]}' );
-```
-
-should handle undefined.
-
-```js
-var test_template = twig({data: '{{ undef|json_encode }}' });
-test_template.render().should.equal("null" );
-```
-
-
-## upper ->
-should convert text to uppercase.
-
-```js
-var test_template = twig({data: '{{ "hello"|upper }}' });
-test_template.render().should.equal("HELLO" );
-```
-
-should handle undefined.
-
-```js
-var test_template = twig({data: '{{ undef|upper }}' });
-test_template.render().should.equal("" );
-```
-
-
-## lower ->
-should convert text to lowercase.
-
-```js
-var test_template = twig({data: '{{ "HELLO"|lower }}' });
-test_template.render().should.equal("hello" );
-```
-
-should handle undefined.
-
-```js
-var test_template = twig({data: '{{ undef|lower }}' });
-test_template.render().should.equal("" );
-```
-
-
-## capitalize ->
-should capitalize the first word in a string.
-
-```js
-var test_template = twig({data: '{{ "hello world"|capitalize }}' });
-test_template.render().should.equal("Hello world" );
-
-var test_template2 = twig({data: '{{ "HELLO WORLD"|capitalize }}' });
-test_template2.render().should.equal("Hello world" );
-```
-
-should handle undefined.
-
-```js
-var test_template = twig({data: '{{ undef|capitalize }}' });
-test_template.render().should.equal("" );
-```
-
-
-## title ->
-should capitalize all the words in a string.
-
-```js
-var test_template = twig({data: '{{ "hello world"|title }}' });
-test_template.render().should.equal("Hello World" );
-
-var test_template2 = twig({data: '{{ "HELLO WORLD"|title }}' });
-test_template2.render().should.equal("Hello World" );
-```
-
-should handle undefined.
-
-```js
-var test_template = twig({data: '{{ undef|title }}' });
-test_template.render().should.equal("" );
-```
-
-
-## length ->
-should determine the length of a string.
-
-```js
-var test_template = twig({data: '{{ "test"|length }}' });
-test_template.render().should.equal("4");
-```
-
-should determine the length of an array.
-
-```js
-var test_template = twig({data: '{{ [1,2,4,76,"tesrt"]|length }}' });
-test_template.render().should.equal("5");
-```
-
-should determine the length of an object.
-
-```js
-var test_template = twig({data: '{{ {"a": "b", "c": "1", "test": "test"}|length }}' });
-test_template.render().should.equal("3");
-```
-
-should handle undefined.
-
-```js
-var test_template = twig({data: '{{ undef|length }}' });
-test_template.render().should.equal("0" );
-```
-
-
-## sort ->
-should sort an array.
-
-```js
-var test_template = twig({data: '{{ [1,5,2,7]|sort }}' });
-test_template.render().should.equal("1,2,5,7" );
-
-test_template = twig({data: '{{ ["test","abc",2,7]|sort }}' });
-test_template.render().should.equal("2,7,abc,test" );
-```
-
-should sort an object.
-
-```js
-var test_template = twig({data: "{% set obj = {'c': 1,'d': 5,'t': 2,'e':7}|sort %}{% for key,value in obj|sort %}{{key}}:{{value}} {%endfor %}" });
-test_template.render().should.equal("c:1 t:2 d:5 e:7 " );
-
-test_template = twig({data: "{% set obj = {'m':'test','z':'abc','a':2,'y':7} %}{% for key,value in obj|sort %}{{key}}:{{value}} {%endfor %}" });
-test_template.render().should.equal("a:2 y:7 z:abc m:test " );
-```
-
-should handle undefined.
-
-```js
-var test_template = twig({data: '{% set obj = undef|sort %}{% for key, value in obj|sort %}{{key}}:{{value}}{%endfor%}' });
-test_template.render().should.equal("" );
-```
-
-
-## reverse ->
-should reverse an array.
-
-```js
-var test_template = twig({data: '{{ ["a", "b", "c"]|reverse }}' });
-test_template.render().should.equal("c,b,a" );
-```
-
-should reverse an object.
-
-```js
-
-```
-
-should handle undefined.
-
-```js
-var test_template = twig({data: '{{ undef|reverse }}' });
-test_template.render().should.equal("" );
-```
-
-
-## keys ->
-should return the keys of an array.
-
-```js
-var test_template = twig({data: '{{ ["a", "b", "c"]|keys }}' });
-test_template.render().should.equal("0,1,2" );
-```
-
-should return the keys of an object.
-
-```js
-var test_template = twig({data: '{{ {"a": 1, "b": 4, "c": 5}|keys }}' });
-test_template.render().should.equal("a,b,c" );
-
-test_template = twig({data: '{{ {"0":"a", "1":"b", "2":"c"}|keys }}' });
-test_template.render().should.equal("0,1,2" );
-```
-
-should handle undefined.
-
-```js
-var test_template = twig({data: '{{ undef|keys }}' });
-test_template.render().should.equal("" );
-```
-
-
-## merge ->
-should merge two objects into an object.
-
-```js
-// Object merging
-var test_template = twig({data: '{% set obj= {"a":"test", "b":"1"}|merge({"b":2,"c":3}) %}{% for key in obj|keys|sort %}{{key}}:{{obj[key]}} {%endfor %}' });
-test_template.render().should.equal('a:test b:2 c:3 ' );
-```
-
-should merge two arrays into and array.
-
-```js
-// Array merging
-var test_template = twig({data: '{% set obj= ["a", "b"]|merge(["c", "d"]) %}{% for key in obj|keys|sort %}{{key}}:{{obj[key]}} {%endfor %}' });
-test_template.render().should.equal('0:a 1:b 2:c 3:d ' );
-```
-
-should merge an object and an array into an object.
-
-```js
-// Mixed merging
-var test_template = twig({data: '{% set obj= ["a", "b"]|merge({"a": "c", "3":4}, ["c", "d"]) %}{% for key in obj|keys|sort %}{{key}}:{{obj[key]}} {%endfor %}' });
-test_template.render().should.equal('0:a 1:b 3:4 4:c 5:d a:c ' );
-
-// Mixed merging(2)
-test_template = twig({data: '{% set obj= {"1":"a", "a":"b"}|merge(["c", "d"]) %}{% for key in obj|keys %}{{key}}:{{obj[key]}} {%endfor %}' });
-test_template.render().should.equal('1:a a:b 2:c 3:d ' );
-```
-
-
-## join ->
-should join all values in an object.
-
-```js
-var test_template = twig({data: '{{ {"a":"1", "b": "b", "c":test}|join("-") }}' });
-test_template.render({"test": "t"}).should.equal("1-b-t" );
-```
-
-should joing all values in an array.
-
-```js
-var test_template = twig({data: '{{ [1,2,4,76]|join }}' });
-test_template.render().should.equal("12476" );
-test_template = twig({data: '{{ [1+ 5,2,4,76]|join("-" ~ ".") }}' });
-test_template.render().should.equal("6-.2-.4-.76" );
-```
-
-should handle undefined.
-
-```js
-var test_template = twig({data: '{{ undef|join }}' });
-test_template.render().should.equal("" );
-```
-
-
-## default ->
-should not provide the default value if a key is defined and not empty.
-
-```js
-var test_template = twig({data: '{{ var|default("Not Defined") }}' });
-test_template.render({"var":"value"}).should.equal("value" );
-```
-
-should provide a default value if a key is not defined.
-
-```js
-var test_template = twig({data: '{{ var|default("Not Defined") }}' });
-test_template.render().should.equal("Not Defined" );
-```
-
-should provide a default value if a value is empty.
-
-```js
-var test_template = twig({data: '{{ ""|default("Empty String") }}' });
-test_template.render().should.equal("Empty String" );
-
-test_template = twig({data: '{{ var.key|default("Empty Key") }}' });
-test_template.render({'var':{}}).should.equal("Empty Key" );
-```
-
-
-## date ->
-should recognize timestamps.
-
-```js
-var template = twig({data: '{{ 27571323556|date("d/m/Y @ H:i:s") }}'})
- , date = new Date(27571323556000); // 13/09/2843 @ 08:59:16 EST
-
-template.render().should.equal( stringDate(date) );
-```
-
-should recognize string date formats.
-
-```js
-var template = twig({data: '{{ "Tue Aug 14 08:52:15 +0000 2007"|date("d/m/Y @ H:i:s") }}'})
- , date = new Date(1187081535000); // 14/08/2007 @ 04:52:15 EST
-
-template.render().should.equal( stringDate(date) );
-```
-
-should handle undefined.
-
-```js
-var test_template = twig({data: '{{ undef|date("d/m/Y @ H:i:s") }}' });
-test_template.render().should.equal( "" );
-```
-
-
-## replace ->
-should replace strings provided in a map.
-
-```js
-var template = twig({data: '{{ "I like %this% and %that%. Seriously, I like %this% and %that%."|replace({"%this%": foo, "%that%": "bar"}) }}'});
-template.render({foo: "foo"}).should.equal("I like foo and bar. Seriously, I like foo and bar." );
-```
-
-should handle undefined.
-
-```js
-var test_template = twig({data: '{{ undef|replace }}' });
-test_template.render().should.equal("" );
-```
-
-
-## format ->
-should replace formatting tags with parameters.
-
-```js
-var template = twig({data: '{{ "I like %s and %s."|format(foo, "bar") }}'});
-template.render({foo: "foo"}).should.equal("I like foo and bar." );
-```
-
-should handle undefined.
-
-```js
-var test_template = twig({data: '{{ undef|format }}' });
-test_template.render().should.equal("" );
-```
-
-
-## striptags ->
-should remove tags from a value.
-
-```js
-var template = twig({data: '{{ "Test paragraph.
Other text "|striptags }}'});
-template.render().should.equal("Test paragraph. Other text" );
-```
-
-should handle undefined.
-
-```js
-var test_template = twig({data: '{{ undef|striptags }}' });
-test_template.render().should.equal("" );
-```
-
-
-## escape ->
-should convert unsafe characters to HTML entities.
-
-```js
-var template = twig({data: '{{ "Test paragraph.
Other text "|escape }}'});
-template.render().should.equal("<p>Test paragraph.</p><!-- Comment --> <a href='#fragment\'>Other text</a>" );
-```
-
-should handle undefined.
-
-```js
-var test_template = twig({data: '{{ undef|escape }}' });
-test_template.render().should.equal("" );
-```
-
-
-## e ->
-should alias escape function with e.
-
-```js
-var template = twig({data: '{{ "Test paragraph.
Other text "|e }}'});
-template.render().should.equal("<p>Test paragraph.</p><!-- Comment --> <a href='#fragment\'>Other text</a>" );
-```
-
-should handle undefined.
-
-```js
-var test_template = twig({data: '{{ undef|e }}' });
-test_template.render().should.equal("" );
-```
-
-
-## nl2br ->
-should convert newlines into html breaks.
-
-```js
-var template = twig({data: '{{ test|nl2br }}'});
-template.render({ test: 'Line 1\r\nLine 2\nLine 3\rLine 4\n\n' })
- .should.equal("Line 1 \nLine 2 \nLine 3 \nLine 4 \n \n");
-```
-
-should handle undefined.
-
-```js
-var test_template = twig({data: '{{ undef|nl2br }}' });
-test_template.render().should.equal("" );
-```
-
-
-## trim ->
-should trim whitespace from strings.
-
-```js
-var template = twig({data: '{{ test|trim }}'});
-template.render({ test: '\r\n Test\n ' }).should.equal("Test");
-```
-
-should handle undefined.
-
-```js
-var test_template = twig({data: '{{ undef|trim }}' });
-test_template.render().should.equal("" );
-```
-
-
-## number_format ->
-should round to nearest integer if no parameters.
-
-```js
-var template = twig({data: '{{ 1234.56|number_format }}'});
-template.render().should.equal("1,235");
-```
-
-should have customizable precision.
-
-```js
-var template = twig({data: '{{ 1234.567890123|number_format(4) }}'});
-template.render().should.equal("1,234.5679");
-```
-
-should have a customizable decimal seperator.
-
-```js
-var template = twig({data: '{{ 1234.567890123|number_format(2,",") }}'});
-template.render().should.equal("1,234,57");
-```
-
-should have a customizable thousands seperator.
-
-```js
-var template = twig({data: '{{ 1234.5678|number_format(2,","," ") }}'});
-template.render().should.equal("1 234,57");
-```
-
-should handle blank seperators.
-
-```js
-var template = twig({data: '{{ 1234.5678|number_format(2,"","") }}'});
-template.render().should.equal("123457");
-```
-
-should handle undefined.
-
-```js
-var test_template = twig({data: '{{ undef|number_format }}' });
-test_template.render().should.equal("0");
-```
-
-
-## slice ->
-should slice a string.
-
-```js
-var test_template = twig({data: "{{ '12345'|slice(1, 2) }}" });
-test_template.render().should.equal("23");
-```
-
-should slice a string to the end.
-
-```js
-var test_template = twig({data: "{{ '12345'|slice(2) }}" });
-test_template.render().should.equal("345");
-```
-
-should slice a string from the start.
-
-```js
-var test_template = twig({data: "{{ '12345'|slice(null, 2) }}" });
-test_template.render().should.equal("12");
-```
-
-should slice a string from a negative offset.
-
-```js
-var test_template = twig({data: "{{ '12345'|slice(-2, 1) }}" });
-test_template.render().should.equal("4");
-```
-
-should slice a string from a negative offset to end of string.
-
-```js
-var test_template = twig({data: "{{ '12345'|slice(-2) }}" });
-test_template.render().should.equal("45");
-```
-
-should slice an array.
-
-```js
-var test_template = twig({data: "{{ [1, 2, 3, 4, 5]|slice(1, 2)|join(',') }}" });
-test_template.render().should.equal("2,3");
-```
-
-should slice an array to the end.
-
-```js
-var test_template = twig({data: "{{ [1, 2, 3, 4, 5]|slice(2)|join(',') }}" });
-test_template.render().should.equal("3,4,5");
-```
-
-should slice an array from the start.
-
-```js
-var test_template = twig({data: "{{ [1, 2, 3, 4, 5]|slice(null, 2)|join(',') }}" });
-test_template.render().should.equal("1,2");
-```
-
-should slice an array from a negative offset.
-
-```js
-var test_template = twig({data: "{{ [1, 2, 3, 4, 5]|slice(-2, 1)|join(',') }}" });
-test_template.render().should.equal("4");
-```
-
-should slice an array from a negative offset to the end of the array.
-
-```js
-var test_template = twig({data: "{{ [1, 2, 3, 4, 5]|slice(-4)|join(',') }}" });
-test_template.render().should.equal("2,3,4,5");
-```
-
-
-## abs ->
-should convert negative numbers to its absolute value.
-
-```js
-var test_template = twig({data: "{{ '-7.365'|abs }}"});
-test_template.render().should.equal("7.365");
-```
-
-should not alter absolute numbers.
-
-```js
-var test_template = twig({data: "{{ 95|abs }}"});
-test_template.render().should.equal("95");
-```
-
-
-## first ->
-should return first item in array.
-
-```js
-var test_template = twig({data: "{{ ['a', 'b', 'c', 'd']|first }}"});
-test_template.render().should.equal("a");
-```
-
-should return first member of object.
-
-```js
-var test_template = twig({data: "{{ { item1: 'a', item2: 'b', item3: 'c', item4: 'd'}|first }}"});
-test_template.render().should.equal("a");
-```
-
-should not fail when passed empty obj, arr or str.
-
-```js
-var test_template = twig({data: "{{ {}|first }}"});
-test_template.render().should.equal("");
-
-var test_template = twig({data: "{{ []|first }}"});
-test_template.render().should.equal("");
-
-var test_template = twig({data: "{{ myemptystr|first }}"});
-test_template.render({myemptystr: ""}).should.equal("");
-```
-
-should return first character in string.
-
-```js
-var test_template = twig({data: "{{ 'abcde'|first }}"});
-test_template.render().should.equal("a");
-```
-
-
-## split ->
-should split string with a separator.
-
-```js
-var test_template = twig({data: "{{ 'one-two-three'|split('-') }}"});
-test_template.render().should.equal("one,two,three");
-```
-
-should split string with a separator and positive limit.
-
-```js
-var test_template = twig({data: "{{ 'one-two-three-four-five'|split('-', 3) }}"});
-test_template.render().should.equal("one,two,three-four-five");
-```
-
-should split string with a separator and negative limit.
-
-```js
-var test_template = twig({data: "{{ 'one-two-three-four-five'|split('-', -2) }}"});
-test_template.render().should.equal("one,two,three");
-```
-
-should split with empty separator.
-
-```js
-var test_template = twig({data: "{{ '123'|split('') }}"});
-test_template.render().should.equal("1,2,3");
-```
-
-should split with empty separator and limit.
-
-```js
-var test_template = twig({data: "{{ 'aabbcc'|split('', 2) }}"});
-test_template.render().should.equal("aa,bb,cc");
-```
-
-
-## batch ->
-should work with arrays that require filling (with fill specified).
-
-```js
-var test_template = twig({data: "{{ ['a', 'b', 'c', 'd', 'e', 'f', 'g']|batch(3, 'x') }}"});
-test_template.render().should.equal("a,b,c,d,e,f,g,x,x");
-```
-
-should work with arrays that require filling (without fill specified).
-
-```js
-var test_template = twig({data: "{{ ['a', 'b', 'c', 'd', 'e', 'f', 'g']|batch(3) }}"});
-test_template.render().should.equal("a,b,c,d,e,f,g");
-```
-
-should work with arrays that do not require filling (with fill specified).
-
-```js
-var test_template = twig({data: "{{ ['a', 'b', 'c', 'd', 'e', 'f']|batch(3, 'x') }}"});
-test_template.render().should.equal("a,b,c,d,e,f");
-```
-
-should work with arrays that do not require filling (without fill specified).
-
-```js
-var test_template = twig({data: "{{ ['a', 'b', 'c', 'd', 'e', 'f']|batch(3) }}"});
-test_template.render().should.equal("a,b,c,d,e,f");
-```
-
-should return an empty result for an empty array.
-
-```js
-var test_template = twig({data: "{{ []|batch(3, 'x') }}"});
-test_template.render().should.equal("");
-```
-
-
-## last ->
-should return last character in string.
-
-```js
-var test_template = twig({data: "{{ 'abcd'|last }}"});
-test_template.render().should.equal("d");
-```
-
-should return last item in array.
-
-```js
-var test_template = twig({data: "{{ ['a', 'b', 'c', 'd']|last }}"});
-test_template.render().should.equal("d");
-```
-
-should return last item in a sorted object.
-
-```js
-var test_template = twig({data: "{{ {'m':1, 'z':5, 'a':3}|sort|last }}" });
-test_template.render().should.equal("5");
-```
-
-
-## round ->
-should round up (common).
-
-```js
-var test_template = twig({data: "{{ 2.7|round }}"});
-test_template.render().should.equal("3");
-```
-
-should round down (common).
-
-```js
-var test_template = twig({data: "{{ 2.1|round }}"});
-test_template.render().should.equal("2");
-```
-
-should truncate input when input decimal places exceeds precision (floor).
-
-```js
-var test_template = twig({data: "{{ 2.1234|round(3, 'floor') }}" });
-test_template.render().should.equal("2.123");
-```
-
-should round up (ceil).
-
-```js
-var test_template = twig({data: "{{ 2.1|round(0, 'ceil') }}" });
-test_template.render().should.equal("3");
-```
-
-should truncate precision when a negative precision is passed (common).
-
-```js
-var test_template = twig({data: "{{ 21.3|round(-1)}}" });
-test_template.render().should.equal("20");
-```
-
-should round up and truncate precision when a negative precision is passed (ceil).
-
-```js
-var test_template = twig({data: "{{ 21.3|round(-1, 'ceil')}}" });
-test_template.render().should.equal("30");
-```
-
-should round down and truncate precision when a negative precision is passed (floor).
-
-```js
-var test_template = twig({data: "{{ 21.3|round(-1, 'ceil')}}" });
-test_template.render().should.equal("30");
-```
-
-
-# Twig.js Loader ->
-should load a template from the filesystem asynchronously.
-
-```js
-twig({
- id: 'fs-node-async',
- path: 'test/templates/test.twig',
- load: function(template) {
- // Render the template
- template.render({
- test: "yes",
- flag: true
- }).should.equal("Test template = yes\n\nFlag set!");
-
- done();
- }
-});
-```
-
-should load a template from the filesystem synchronously.
-
-```js
-var template = twig({
- id: 'fs-node-sync',
- path: 'test/templates/test.twig',
- async: false
-});
-// Render the template
-template.render({
- test: "yes",
- flag: true
-}).should.equal("Test template = yes\n\nFlag set!");
-```
-
-
-# Twig.js Include ->
-should load an included template with no context.
-
-```js
-twig({
- id: 'include',
- path: 'test/templates/include.twig',
- async: false
-});
-
-// Load the template
-twig({ref: 'include'}).render({test: 'tst'}).should.equal( "BeforeTest template = tst\n\nAfter" );
-```
-
-should load an included template with additional context.
-
-```js
-twig({
- id: 'include-with',
- path: 'test/templates/include-with.twig',
- async: false
-});
-
-// Load the template
-twig({ref: 'include-with'}).render({test: 'tst'}).should.equal( "template: before,tst-mid-template: after,tst" );
-```
-
-should load an included template with only additional context.
-
-```js
-twig({
- id: 'include-only',
- path: 'test/templates/include-only.twig',
- async: false
-});
-
-// Load the template
-twig({ref: 'include-only'}).render({test: 'tst'}).should.equal( "template: before,-mid-template: after," );
-```
-
-
-# Twig.js Functions ->
-should allow you to define a function.
-
-```js
-twig({data: '{{ square(a) }}'}).render({a:4}).should.equal("16");
-```
-
-should chain with other expressions.
-
-```js
-twig({data: '{{ square(a) + 4 }}'}).render({a:4}).should.equal("20");
-```
-
-should chain with filters.
-
-```js
-twig({data: '{{ echo(a)|default("foo") }}'}).render().should.equal("foo");
-```
-
-should work in for loop expressions.
-
-```js
-twig({data: '{% for i in list(1, 2, 3) %}{{ i }},{% endfor %}'}).render().should.equal("1,2,3,");
-```
-
-should be able to differentiate between a function and a variable.
-
-```js
-twig({data: '{{ square ( square ) + square }}'}).render({square: 2}).should.equal("6");
-```
-
-should work with boolean operations.
-
-```js
-twig({data: '{% if echo(true) or echo(false) %}yes{% endif %}'}).render().should.equal("yes");
-```
-
-should execute functions passed as context values.
-
-```js
-twig({
- data: '{{ value }}'
-}).render({
- value: function() {
- return "test";
- }
-}).should.equal("test");
-```
-
-should execute functions passed as context values with this mapped to the context.
-
-```js
-twig({
- data: '{{ value }}'
-}).render({
- test: "value",
- value: function() {
- return this.test;
- }
-}).should.equal("value");
-```
-
-should execute functions passed as context values with arguments.
-
-```js
-twig({
- data: '{{ value(1, "test") }}'
-}).render({
- value: function(a, b, c) {
- return a + "-" + b + "-" + (c===undefined?"true":"false");
- }
-}).should.equal("1-test-true");
-```
-
-should execute functions passed as context value parameters with this mapped to the context.
-
-```js
-twig({
- data: '{{ value }}'
-}).render({
- test: "value",
- value: function() {
- return this.test;
- }
-}).should.equal("value");
-```
-
-should execute functions passed as context object parameters.
-
-```js
-twig({
- data: '{{ obj.value }}'
-}).render({
- obj: {
- value: function() {
- return "test";
- }
- }
-}).should.equal("test");
-```
-
-should execute functions passed as context object parameters with arguments.
-
-```js
-twig({
- data: '{{ obj.value(1, "test") }}'
-}).render({
- obj: {
- value: function(a, b, c) {
- return a + "-" + b + "-" + (c===undefined?"true":"false");
- }
- }
-}).should.equal("1-test-true");
-```
-
-should execute functions passed as context object parameters.
-
-```js
-twig({
- data: '{{ obj["value"] }}'
-}).render({
- obj: {
- value: function() {
- return "test";
- }
- }
-}).should.equal("test");
-```
-
-should execute functions passed as context object parameters with arguments.
-
-```js
-twig({
- data: '{{ obj["value"](1, "test") }}'
-}).render({
- obj: {
- value: function(a, b, c) {
- return a + "-" + b + "-" + (c===undefined?"true":"false");
- }
- }
-}).should.equal("1-test-true");
-```
-
-
-## Built-in Functions ->
-
-### range ->
-should work over a range of numbers.
-
-```js
-twig({data: '{% for i in range(0, 3) %}{{ i }},{% endfor %}'}).render().should.equal("0,1,2,3,");
-```
-
-should work over a range of letters.
-
-```js
-twig({data: '{% for i in range("a", "c") %}{{ i }},{% endfor %}'}).render().should.equal("a,b,c,");
-```
-
-should work with an interval.
-
-```js
-twig({data: '{% for i in range(1, 15, 3) %}{{ i }},{% endfor %}'}).render().should.equal("1,4,7,10,13,");
-```
-
-should work with .. invocation.
-
-```js
-twig({data: '{% for i in 0..3 %}{{ i }},{% endfor %}'}).render().should.equal("0,1,2,3,");
-twig({data: '{% for i in "a" .. "c" %}{{ i }},{% endfor %}'}).render().should.equal("a,b,c,");
-```
-
-
-### cycle ->
-should cycle through an array of values.
-
-```js
-twig({data: '{% for i in range(0, 3) %}{{ cycle(["odd", "even"], i) }};{% endfor %}'}).render().should.equal("odd;even;odd;even;");
-```
-
-
-### date ->
-should understand timestamps.
-
-```js
-var date = new Date(946706400 * 1000);
-twig({data: '{{ date(946706400)|date("d/m/Y @ H:i:s") }}'}).render().should.equal(stringDate(date));
-```
-
-should understand relative dates.
-
-```js
-twig({data: '{{ date("+1 day") > date() }}'}).render().should.equal("true");
-twig({data: '{{ date("-1 day") > date() }}'}).render().should.equal("false");
-```
-
-should support 'now' as a date parameter.
-
-```js
-twig({data: '{{ date("now") }}' }).render().should.equal(new Date().toString());
-```
-
-should understand exact dates.
-
-```js
-var date = new Date("June 20, 2010 UTC");
-
-twig({data: '{{ date("June 20, 2010 UTC")|date("d/m/Y @ H:i:s") }}'}).render().should.equal(stringDate(date));
-```
-
-
-### dump ->
-should output formatted number.
-
-```js
-twig({data: '{{ dump(test) }}' }).render({ test: 5 }).should.equal('number(5)' + EOL);
-```
-
-should output formatted string.
-
-```js
-twig({data: '{{ dump(test) }}' }).render({ test: "String" }).should.equal('string(6) "String"' + EOL);
-```
-
-should output formatted boolean.
-
-```js
-twig({data: '{{ dump(test) }}' }).render({ test: true }).should.equal('bool(true)' + EOL);
-```
-
-should output formatted null.
-
-```js
-twig({data: '{{ dump(test) }}' }).render({ test: null }).should.equal('NULL' + EOL);
-```
-
-should output formatted object.
-
-```js
-twig({data: '{{ dump(test) }}' }).render({ test: {} }).should.equal('object(0) {' + EOL + '}' + EOL);
-```
-
-should output formatted array.
-
-```js
-twig({data: '{{ dump(test) }}' }).render({ test: [] }).should.equal('object(0) {' + EOL + '}' + EOL);
-```
-
-should output formatted undefined.
-
-```js
-twig({data: '{{ dump(test) }}' }).render({ test: undefined }).should.equal('undefined' + EOL);
-```
-
-
-### block ->
-should render the content of blocks.
-
-```js
-twig({data: '{% block title %}Content - {{ val }}{% endblock %} Title: {{ block("title") }}'}).render({ val: "test" })
- .should.equal("Content - test Title: Content - test");
-```
-
-
-### attribute ->
-should access attribute of an object.
-
-```js
-twig({data: '{{ attribute(obj, key) }}' }).render({
- obj: { name: "Twig.js"},
- key: "name"
-})
-.should.equal("Twig.js");
-```
-
-should call function of attribute of an object.
-
-```js
-twig({data: '{{ attribute(obj, key, params) }}' }).render({
- obj: {
- name: function(first, last) {
- return first+'.'+last;
- }
- },
- key: "name",
- params: ['Twig', 'js']
- })
- .should.equal("Twig.js");
-```
-
-should return undefined for missing attribute of an object.
-
-```js
-twig({data: '{{ attribute(obj, key, params) }}' }).render({
- obj: {
- name: function(first, last) {
- return first+'.'+last;
- }
- },
- key: "missing",
- params: ['Twig', 'js']
- })
- .should.equal("");
-```
-
-should return element of an array.
-
-```js
-twig({data: '{{ attribute(arr, 0) }}' }).render({
- arr: ['Twig', 'js']
- })
- .should.equal("Twig");
-```
-
-should return undef for array beyond index size.
-
-```js
-twig({data: '{{ attribute(arr, 100) }}' }).render({
- arr: ['Twig', 'js']
- })
- .should.equal("");
-```
-
-
-# Twig.js Macro ->
-it should load macro.
-
-```js
-twig({
- id: 'macro',
- path: 'test/templates/macro.twig',
- async: false
-});
-// Load the template
-twig({ref: 'macro'}).render({ }).should.equal( '' );
-```
-
-it should import macro.
-
-```js
-twig({
- id: 'import-macro',
- path: 'test/templates/import.twig',
- async: false
-});
-// Load the template
-twig({ref: 'import-macro'}).render({ }).trim().should.equal( "Hello World" );
-```
-
-it should run macro with self reference.
-
-```js
-twig({
- id: 'import-macro-self',
- path: 'test/templates/macro-self.twig',
- async: false
-});
-// Load the template
-twig({ref: 'import-macro-self'}).render({ }).trim().should.equal( '
' );
-```
-
-it should run wrapped macro with self reference.
-
-```js
-twig({
- id: 'import-wrapped-macro-self',
- path: 'test/templates/macro-wrapped.twig',
- async: false
-});
-// Load the template
-twig({ref: 'import-wrapped-macro-self'}).render({ }).trim().should.equal( '
' );
-```
-
-it should run wrapped macro with context and self reference.
-
-```js
-twig({
- id: 'import-macro-context-self',
- path: 'test/templates/macro-context.twig',
- async: false
-});
-// Load the template
-twig({ref: 'import-macro-context-self'}).render({ 'greetings': 'Howdy' }).trim().should.equal( 'Howdy Twigjs' );
-```
-
-it should run wrapped macro inside blocks.
-
-```js
-twig({
- id: 'import-macro-inside-block',
- path: 'test/templates/macro-blocks.twig',
- async: false
-});
-// Load the template
-twig({ref: 'import-macro-inside-block'}).render({ }).trim().should.equal( 'Welcome Twig Js
' );
-```
-
-it should import selected macros from template.
-
-```js
-twig({
- id: 'from-macro-import',
- path: 'test/templates/from.twig',
- async: false
-});
-// Load the template
-twig({ref: 'from-macro-import'}).render({ }).trim().should.equal( 'Twig.js
' );
-```
-
-
-# Twig.js Optional Functionality ->
-should support inline includes by ID.
-
-```js
-twig({
- id: 'other',
- data: 'another template'
-});
-
-var template = twig({
- allowInlineIncludes: true,
- data: 'template with {% include "other" %}'
- }),
- output = template.render()
-
-output.should.equal("template with another template");
-```
-
-
-# Twig.js Regression Tests ->
-#47 should not match variables starting with not.
-
-```js
-// Define and save a template
-twig({data: '{% for note in notes %}{{note}}{% endfor %}'}).render({notes:['a', 'b', 'c']}).should.equal("abc");
-```
-
-#56 functions work inside parentheses.
-
-```js
-// Define and save a template
-Twig.extendFunction('custom', function(value) {
- return true;
-});
-
-twig({data: '{% if (custom("val") and custom("val")) %}out{% endif %}'}).render({}).should.equal("out");
-```
-
-#83 Support for trailing commas in arrays.
-
-```js
-twig({data: '{{ [1,2,3,4,] }}'}).render().should.equal("1,2,3,4");
-```
-
-#83 Support for trailing commas in objects.
-
-```js
-twig({data: '{{ {a:1, b:2, c:3, } }}'}).render();
-```
-
-
-# Twig.js Tags ->
-should support spaceless.
-
-```js
-twig({
- data: "{% spaceless %}\n b i \n
{% endspaceless %}"
-}).render().should.equal(
- "b i
"
-);
-```
-
-
-# Twig.js Tests ->
-
-## empty test ->
-should identify numbers as not empty.
-
-```js
-// number
-twig({data: '{{ 1 is empty }}'}).render().should.equal("false" );
-twig({data: '{{ 0 is empty }}'}).render().should.equal("false" );
-```
-
-should identify empty strings.
-
-```js
-// String
-twig({data: '{{ "" is empty }}'}).render().should.equal("true" );
-twig({data: '{{ "test" is empty }}'}).render().should.equal("false" );
-```
-
-should identify empty arrays.
-
-```js
-// Array
-twig({data: '{{ [] is empty }}'}).render().should.equal("true" );
-twig({data: '{{ ["1"] is empty }}'}).render().should.equal("false" );
-```
-
-should identify empty objects.
-
-```js
-// Object
-twig({data: '{{ {} is empty }}'}).render().should.equal("true" );
-twig({data: '{{ {"a":"b"} is empty }}'}).render().should.equal("false" );
-twig({data: '{{ {"a":"b"} is not empty }}'}).render().should.equal("true" );
-```
-
-
-## odd test ->
-should identify a number as odd.
-
-```js
-twig({data: '{{ (1 + 4) is odd }}'}).render().should.equal("true" );
-twig({data: '{{ 6 is odd }}'}).render().should.equal("false" );
-```
-
-
-## even test ->
-should identify a number as even.
-
-```js
-twig({data: '{{ (1 + 4) is even }}'}).render().should.equal("false" );
-twig({data: '{{ 6 is even }}'}).render().should.equal("true" );
-```
-
-
-## divisibleby test ->
-should determine if a number is divisible by the given number.
-
-```js
-twig({data: '{{ 5 is divisibleby(3) }}'}).render().should.equal("false" );
-twig({data: '{{ 6 is divisibleby(3) }}'}).render().should.equal("true" );
-```
-
-
-## defined test ->
-should identify a key as defined if it exists in the render context.
-
-```js
-twig({data: '{{ key is defined }}'}).render().should.equal("false" );
-twig({data: '{{ key is defined }}'}).render({key: "test"}).should.equal( "true" );
-```
-
-
-## none test ->
-should identify a key as none if it exists in the render context and is null.
-
-```js
-twig({data: '{{ key is none }}'}).render().should.equal("false");
-twig({data: '{{ key is none }}'}).render({key: "test"}).should.equal("false");
-twig({data: '{{ key is none }}'}).render({key: null}).should.equal("true");
-twig({data: '{{ key is null }}'}).render({key: null}).should.equal("true");
-```
-
-
-## sameas test ->
-should identify the exact same type as true.
-
-```js
-twig({data: '{{ true is sameas(true) }}'}).render().should.equal("true");
-twig({data: '{{ a is sameas(1) }}'}).render({a: 1}).should.equal("true");
-twig({data: '{{ a is sameas("test") }}'}).render({a: "test"}).should.equal("true");
-twig({data: '{{ a is sameas(true) }}'}).render({a: true}).should.equal("true");
-```
-
-should identify the different types as false.
-
-```js
-twig({data: '{{ false is sameas(true) }}'}).render().should.equal("false");
-twig({data: '{{ true is sameas(1) }}'}).render().should.equal("false");
-twig({data: '{{ false is sameas("") }}'}).render().should.equal("false");
-twig({data: '{{ a is sameas(1) }}'}).render({a: "1"}).should.equal("false");
-```
-
diff --git a/docs/twig.html b/docs/twig.html
deleted file mode 100644
index acfb6651..00000000
--- a/docs/twig.html
+++ /dev/null
@@ -1,8736 +0,0 @@
-
-
-
-
- twig.js
-
-
-
-
-
-
-
-
-
-
-
-
-
twig.js
-
-
-
-
-
-
-
-
-
-
-var Twig = (function (Twig) {
-
- Twig.VERSION = "0.7.2" ;
-
- return Twig;
-})(Twig || {});
-
-
-
-
-
-
-
-
-
Twig.js
-Copyright (c) 2011-2013 John Roepke
-Available under the BSD 2-Clause License
-https://github.com/justjohn/twig.js
-
-
-
- var Twig = (function (Twig) {
- "use strict" ;
-
-
-
-
-
-
-
-
-
twig.core.js
-
This file handles template level tokenizing, compiling and parsing.
-
-
-
- Twig.trace = false ;
- Twig.debug = false ;
-
-
-
-
-
-
-
-
-
Default caching to true for the improved performance it offers
-
-
-
- Twig.cache = true ;
-
- Twig.placeholders = {
- parent: "{{|PARENT|}}"
- };
-
-
- Twig.indexOf = function (arr, searchElement ) {
- if (Array.prototype.hasOwnProperty("indexOf" )) {
- return arr.indexOf(searchElement);
- }
- if (arr === void 0 || arr === null ) {
- throw new TypeError();
- }
- var t = Object(arr);
- var len = t.length >>> 0 ;
- if (len === 0 ) {
- return -1 ;
- }
- var n = 0 ;
- if (arguments.length > 0 ) {
- n = Number(arguments[1 ]);
- if (n !== n) {
- n = 0 ;
- } else if (n !== 0 && n !== Infinity && n !== -Infinity ) {
- n = (n > 0 || -1 ) * Math.floor(Math.abs(n));
- }
- }
- if (n >= len) {
-
-
-
-
-
-
-
-
-
console.log("indexOf not found1 ", JSON.stringify(searchElement), JSON.stringify(arr));
-
-
-
- return -1 ;
- }
- var k = n >= 0 ? n : Math.max(len - Math.abs(n), 0 );
- for (; k < len; k++) {
- if (k in t && t[k] === searchElement) {
- return k;
- }
- }
- if (arr == searchElement) {
- return 0 ;
- }
-
-
-
-
-
-
-
-
-
console.log("indexOf not found2 ", JSON.stringify(searchElement), JSON.stringify(arr));
-
-
-
- return -1 ;
- }
-
- Twig.forEach = function (arr, callback, thisArg) {
- if (Array.prototype.forEach ) {
- return arr.forEach(callback, thisArg);
- }
-
- var T, k;
-
- if ( arr == null ) {
- throw new TypeError( " this is null or not defined" );
- }
-
-
-
-
-
-
-
-
-
-Let O be the result of calling ToObject passing the |this| value as the argument.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-Let lenValue be the result of calling the Get internal method of O with the argument "length".
-Let len be ToUint32(lenValue).
-
-
-
-
- var len = O.length >>> 0 ;
-
-
-
-
-
-
-
- if ( {}.toString.call(callback) != "[object Function]" ) {
- throw new TypeError( callback + " is not a function" );
- }
-
-
-
-
-
-
-
-
-
-If thisArg was supplied, let T be thisArg; else let T be undefined.
-
-
-
-
- if ( thisArg ) {
- T = thisArg;
- }
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-Repeat, while k < len
-
-
-
-
- while ( k < len ) {
-
- var kValue;
-
-
-
-
-
-
-
-
-
a. Let Pk be ToString(k).
- This is implicit for LHS operands of the in operator
-b. Let kPresent be the result of calling the HasProperty internal method of O with argument Pk.
- This step can be combined with c
-c. If kPresent is true, then
-
-
-
-
-
-
-
-
-
-
-
-
-
i. Let kValue be the result of calling the Get internal method of O with argument Pk.
-
-
-
-
-
-
-
-
-
-
-
-
-
ii. Call the Call internal method of callback with T as the this value and
-argument list containing kValue, k, and O.
-
-
-
- callback.call( T, kValue, k, O );
- }
-
-
-
-
-
-
-
-
-
d. Increase k by 1.
-
-
-
-
-
-
-
-
-
-
-
-
-
-return undefined
-
-
-
-
- };
-
-
- Twig.Error = function (message) {
- this .message = message;
- this .name = "TwigException" ;
- this .type = "TwigException" ;
- };
-
-
- Twig.Error.prototype.toString = function () {
- var output = this .name + ": " + this .message;
-
- return output;
- };
-
-
- Twig.log = {
- trace: function () {if (Twig.trace && console) {console.log(Array.prototype.slice.call(arguments));}},
- debug: function () {if (Twig.debug && console) {console.log(Array.prototype.slice.call(arguments));}},
- };
-
- if (typeof console !== "undefined" &&
- typeof console.log !== "undefined" ) {
- Twig.log.error = function () {
- console.log.apply(console, arguments);
- }
- } else {
- Twig.log.error = function () { };
- }
-
-
- Twig.token = {};
-
-
- Twig.token.type = {
- output: 'output' ,
- logic: 'logic' ,
- comment: 'comment' ,
- raw: 'raw'
- };
-
-
- Twig.token.definitions = [
- {
- type: Twig.token.type.raw,
- open: '{% raw %}' ,
- close: '{% endraw %}'
- },
-
-
-
-
-
-
-
-
-
Output type tokens
-
These typically take the form {{ expression }}
.
-
-
-
- {
- type: Twig.token.type.output,
- open: '{{' ,
- close: '}}'
- },
-
-
-
-
-
-
-
-
-
Logic type tokens
-
These typically take a form like {% if expression %}
or {% endif %}
-
-
-
- {
- type: Twig.token.type.logic,
- open: '{%' ,
- close: '%}'
- },
-
-
-
-
-
-
-
-
-
Comment type tokens
-
These take the form {# anything #}
-
-
-
- {
- type: Twig.token.type.comment,
- open: '{#' ,
- close: '#}'
- }
- ];
-
-
-
- Twig.token.strings = ['"' , "'" ];
-
- Twig.token.findStart = function (template) {
- var output = {
- position: null ,
- def: null
- },
- i,
- token_template,
- first_key_position;
-
- for (i=0 ;i<Twig.token.definitions.length;i++) {
- token_template = Twig.token.definitions[i];
- first_key_position = template.indexOf(token_template.open);
-
- Twig.log.trace("Twig.token.findStart: " , "Searching for " , token_template.open, " found at " , first_key_position);
-
-
-
-
-
-
-
-
-
Does this token occur before any other types?
-
-
-
- if (first_key_position >= 0 && (output.position === null || first_key_position < output.position)) {
- output.position = first_key_position;
- output.def = token_template;
- }
- }
-
- return output;
- };
-
- Twig.token.findEnd = function (template, token_def, start) {
- var end = null ,
- found = false ,
- offset = 0 ,
-
-
-
-
-
-
-
-
-
String position variables
-
-
-
- str_pos = null ,
- str_found = null ,
- pos = null ,
- end_offset = null ,
- this_str_pos = null ,
- end_str_pos = null ,
-
-
-
-
-
-
-
-
-
For loop variables
-
-
-
- i,
- l;
-
- while (!found) {
- str_pos = null ;
- str_found = null ;
- pos = template.indexOf(token_def.close, offset);
-
- if (pos >= 0 ) {
- end = pos;
- found = true ;
- } else {
-
-
-
-
-
-
-
-
-
throw an exception
-
-
-
- throw new Twig.Error("Unable to find closing bracket '" + token_def.close +
- "'" + " opened near template position " + start);
- }
-
-
-
-
-
-
-
- if (token_def.type === Twig.token.type.comment) {
- break ;
- }
-
- l = Twig.token.strings.length;
- for (i = 0 ; i < l; i += 1 ) {
- this_str_pos = template.indexOf(Twig.token.strings[i], offset);
-
- if (this_str_pos > 0 && this_str_pos < pos &&
- (str_pos === null || this_str_pos < str_pos)) {
- str_pos = this_str_pos;
- str_found = Twig.token.strings[i];
- }
- }
-
-
-
-
-
-
-
-
-
We found a string before the end of the token, now find the string's end and set the search offset to it
-
-
-
- if (str_pos !== null ) {
- end_offset = str_pos + 1 ;
- end = null ;
- found = false ;
- while (true ) {
- end_str_pos = template.indexOf(str_found, end_offset);
- if (end_str_pos < 0 ) {
- throw "Unclosed string in template" ;
- }
-
-
-
-
-
-
-
-
-
Ignore escaped quotes
-
-
-
- if (template.substr(end_str_pos - 1 , 1 ) !== "\\" ) {
- offset = end_str_pos + 1 ;
- break ;
- } else {
- end_offset = end_str_pos + 1 ;
- }
- }
- }
- }
- return end;
- };
-
-
- Twig.tokenize = function (template) {
- var tokens = [],
-
-
-
-
-
-
-
-
-
An offset for reporting errors locations in the template.
-
-
-
-
-
-
-
-
-
-
-
-
-
The start and type of the first token found in the template.
-
-
-
-
-
-
-
-
-
-
-
-
-
The end position of the matched token.
-
-
-
- end = null ;
-
- while (template.length > 0 ) {
-
-
-
-
-
-
-
-
-
Find the first occurance of any token type in the template
-
-
-
- found_token = Twig.token.findStart(template);
-
- Twig.log.trace("Twig.tokenize: " , "Found token: " , found_token);
-
- if (found_token.position !== null ) {
-
-
-
-
-
-
-
-
-
Add a raw type token for anything before the start of the token
-
-
-
- if (found_token.position > 0 ) {
- tokens.push({
- type: Twig.token.type.raw,
- value: template.substring(0 , found_token.position)
- });
- }
- template = template.substr(found_token.position + found_token.def.open.length);
- error_offset += found_token.position + found_token.def.open.length;
-
-
-
-
-
-
-
-
-
Find the end of the token
-
-
-
- end = Twig.token.findEnd(template, found_token.def, error_offset);
-
- Twig.log.trace("Twig.tokenize: " , "Token ends at " , end);
-
- tokens.push({
- type: found_token.def.type,
- value: template.substring(0 , end).trim()
- });
-
- if ( found_token.def.type === "logic" && template.substr( end + found_token.def.close.length, 1 ) === "\n" ) {
-
-
-
-
-
-
-
-
-
Newlines directly after logic tokens are ignored
-
-
-
- end += 1 ;
- }
-
- template = template.substr(end + found_token.def.close.length);
-
-
-
-
-
-
-
-
-
Increment the position in the template
-
-
-
- error_offset += end + found_token.def.close.length;
-
- } else {
-
-
-
-
-
-
-
-
-
No more tokens -> add the rest of the template as a raw-type token
-
-
-
- tokens.push({
- type: Twig.token.type.raw,
- value: template
- });
- template = '' ;
- }
- }
-
- return tokens;
- };
-
-
- Twig.compile = function (tokens) {
- try {
-
-
-
-
-
-
-
-
-
Output and intermediate stacks
-
-
-
- var output = [],
- stack = [],
-
-
-
-
-
-
-
-
-
The tokens between open and close tags
-
-
-
- intermediate_output = [],
-
- token = null ,
- logic_token = null ,
- unclosed_token = null ,
-
-
-
-
-
-
-
-
-
Temporary previous token.
-
-
-
-
-
-
-
-
-
-
-
-
-
The previous token's template
-
-
-
-
-
-
-
-
-
-
-
-
-
The output token
-
-
-
-
-
-
-
-
-
-
-
-
-
Logic Token values
-
-
-
- type = null ,
- open = null ,
- next = null ;
-
- while (tokens.length > 0 ) {
- token = tokens.shift();
- Twig.log.trace("Compiling token " , token);
- switch (token.type) {
- case Twig.token.type.raw:
- if (stack.length > 0 ) {
- intermediate_output.push(token);
- } else {
- output.push(token);
- }
- break ;
-
- case Twig.token.type.logic:
-
-
-
-
-
-
-
-
-
Compile the logic token
-
-
-
- logic_token = Twig.logic.compile.apply(this , [token]);
-
- type = logic_token.type;
- open = Twig.logic.handler[type].open;
- next = Twig.logic.handler[type].next;
-
- Twig.log.trace("Twig.compile: " , "Compiled logic token to " , logic_token,
- " next is: " , next, " open is : " , open);
-
-
-
-
-
-
-
-
-
Not a standalone token, check logic stack to see if this is expected
-
-
-
- if (open !== undefined && !open) {
- prev_token = stack.pop();
- prev_template = Twig.logic.handler[prev_token.type];
-
- if (Twig.indexOf(prev_template.next, type) < 0 ) {
- throw new Error(type + " not expected after a " + prev_token.type);
- }
-
- prev_token.output = prev_token.output || [];
-
- prev_token.output = prev_token.output.concat(intermediate_output);
- intermediate_output = [];
-
- tok_output = {
- type: Twig.token.type.logic,
- token: prev_token
- };
- if (stack.length > 0 ) {
- intermediate_output.push(tok_output);
- } else {
- output.push(tok_output);
- }
- }
-
-
-
-
-
-
-
-
-
This token requires additional tokens to complete the logic structure.
-
-
-
- if (next !== undefined && next.length > 0 ) {
- Twig.log.trace("Twig.compile: " , "Pushing " , logic_token, " to logic stack." );
-
- if (stack.length > 0 ) {
-
-
-
-
-
-
-
-
-
Put any currently held output into the output list of the logic operator
-currently at the head of the stack before we push a new one on.
-
-
-
- prev_token = stack.pop();
- prev_token.output = prev_token.output || [];
- prev_token.output = prev_token.output.concat(intermediate_output);
- stack.push(prev_token);
- intermediate_output = [];
- }
-
-
-
-
-
-
-
-
-
Push the new logic token onto the logic stack
-
-
-
- stack.push(logic_token);
-
- } else if (open !== undefined && open) {
- tok_output = {
- type: Twig.token.type.logic,
- token: logic_token
- };
-
-
-
-
-
-
-
-
-
Standalone token (like {% set ... %}
-
-
-
- if (stack.length > 0 ) {
- intermediate_output.push(tok_output);
- } else {
- output.push(tok_output);
- }
- }
- break ;
-
-
-
-
-
-
-
-
-
Do nothing, comments should be ignored
-
-
-
- case Twig.token.type.comment:
- break ;
-
- case Twig.token.type.output:
- Twig.expression.compile.apply(this , [token]);
- if (stack.length > 0 ) {
- intermediate_output.push(token);
- } else {
- output.push(token);
- }
- break ;
- }
-
- Twig.log.trace("Twig.compile: " , " Output: " , output,
- " Logic Stack: " , stack,
- " Pending Output: " , intermediate_output );
- }
-
-
-
-
-
-
-
-
-
Verify that there are no logic tokens left in the stack.
-
-
-
- if (stack.length > 0 ) {
- unclosed_token = stack.pop();
- throw new Error("Unable to find an end tag for " + unclosed_token.type +
- ", expecting one of " + unclosed_token.next);
- }
- return output;
- } catch (ex) {
- Twig.log.error("Error compiling twig template " + this .id + ": " );
- if (ex.stack) {
- Twig.log.error(ex.stack);
- } else {
- Twig.log.error(ex.toString());
- }
-
- if (this .options.rethrow) throw ex;
- }
- };
-
-
- Twig.parse = function (tokens, context) {
- try {
- var output = [],
-
-
-
-
-
-
-
-
-
Track logic chains
-
-
-
- chain = true ,
- that = this ;
-
-
-
-
-
-
-
-
-
Default to an empty object if none provided
-
-
-
- context = context || { };
-
-
- Twig.forEach(tokens, function parseToken (token) {
- Twig.log.debug("Twig.parse: " , "Parsing token: " , token);
-
- switch (token.type) {
- case Twig.token.type.raw:
- output.push(token.value);
- break ;
-
- case Twig.token.type.logic:
- var logic_token = token.token,
- logic = Twig.logic.parse.apply(that, [logic_token, context, chain]);
-
- if (logic.chain !== undefined ) {
- chain = logic.chain;
- }
- if (logic.context !== undefined ) {
- context = logic.context;
- }
- if (logic.output !== undefined ) {
- output.push(logic.output);
- }
- break ;
-
- case Twig.token.type.comment:
-
-
-
-
-
-
-
-
-
Do nothing, comments should be ignored
-
-
-
- break ;
-
- case Twig.token.type.output:
- Twig.log.debug("Twig.parse: " , "Output token: " , token.stack);
-
-
-
-
-
-
-
-
-
Parse the given expression in the given context
-
-
-
- output.push(Twig.expression.parse.apply(that, [token.stack, context]));
- break ;
- }
- });
- return output.join("" );
- } catch (ex) {
- Twig.log.error("Error parsing twig template " + this .id + ": " );
- if (ex.stack) {
- Twig.log.error(ex.stack);
- } else {
- Twig.log.error(ex.toString());
- }
-
- if (this .options.rethrow) throw ex;
-
- if (Twig.debug) {
- return ex.toString();
- }
- }
- };
-
-
- Twig.prepare = function (data) {
- var tokens, raw_tokens;
-
-
-
-
-
-
-
- Twig.log.debug("Twig.prepare: " , "Tokenizing " , data);
- raw_tokens = Twig.tokenize.apply(this , [data]);
-
-
-
-
-
-
-
- Twig.log.debug("Twig.prepare: " , "Compiling " , raw_tokens);
- tokens = Twig.compile.apply(this , [raw_tokens]);
-
- Twig.log.debug("Twig.prepare: " , "Compiled " , tokens);
-
- return tokens;
- };
-
-
-
-
-
-
-
-
-
Namespace for template storage and retrieval
-
-
-
- Twig.Templates = {
- registry: {}
- };
-
-
- Twig.validateId = function (id) {
- if (id === "prototype" ) {
- throw new Twig.Error(id + " is not a valid twig identifier" );
- } else if (Twig.Templates.registry.hasOwnProperty(id)) {
- throw new Twig.Error("There is already a template with the ID " + id);
- }
- return true ;
- }
-
-
- Twig.Templates.save = function (template) {
- if (template.id === undefined ) {
- throw new Twig.Error("Unable to save template with no id" );
- }
- Twig.Templates.registry[template.id] = template;
- };
-
-
- Twig.Templates.load = function (id) {
- if (!Twig.Templates.registry.hasOwnProperty(id)) {
- return null ;
- }
- return Twig.Templates.registry[id];
- };
-
-
- Twig.Templates.loadRemote = function (location, params, callback, error_callback) {
- var id = params.id,
- method = params.method,
- async = params.async,
- precompiled = params.precompiled,
- template = null ;
-
-
-
-
-
-
-
-
-
Default to async
-
-
-
- if (async === undefined ) async = true ;
-
-
-
-
-
-
-
-
-
Default to the URL so the template is cached.
-
-
-
- if (id === undefined ) {
- id = location;
- }
- params.id = id;
-
-
-
-
-
-
-
-
-
Check for existing template
-
-
-
- if (Twig.cache && Twig.Templates.registry.hasOwnProperty(id)) {
-
-
-
-
-
-
-
-
-
A template is already saved with the given id.
-
-
-
- if (callback) {
- callback(Twig.Templates.registry[id]);
- }
- return Twig.Templates.registry[id];
- }
-
- if (method == 'ajax' ) {
- if (typeof XMLHttpRequest == "undefined" ) {
- throw new Twig.Error("Unsupported platform: Unable to do remote requests " +
- "because there is no XMLHTTPRequest implementation" );
- }
-
- var xmlhttp = new XMLHttpRequest();
- xmlhttp.onreadystatechange = function () {
- var data = null ;
-
- if (xmlhttp.readyState == 4 ) {
- if (xmlhttp.status == 200 ) {
- Twig.log.debug("Got template " , xmlhttp.responseText);
-
- if (precompiled === true ) {
- data = JSON.parse(xmlhttp.responseText);
- } else {
- data = xmlhttp.responseText;
- }
-
- params.url = location;
- params.data = data;
-
- template = new Twig.Template(params);
-
- if (callback) {
- callback(template);
- }
- } else {
- if (error_callback) {
- error_callback(xmlhttp);
- }
- }
- }
- };
- xmlhttp.open("GET" , location, async);
- xmlhttp.send();
-
- } else {
-
-
-
-
-
-
-
-
-
Create local scope
-
-
-
- (function () {
- var fs = require('fs' ),
- path = require('path' ),
- data = null ,
- loadTemplateFn = function (err, data) {
- if (err) {
- if (error_callback) {
- error_callback(err);
- }
- return ;
- }
-
- if (precompiled === true ) {
- data = JSON.parse(data);
- }
-
- params.data = data;
- params.path = location;
-
-
-
-
-
-
-
-
-
template is in data
-
-
-
- template = new Twig.Template(params);
-
- if (callback) {
- callback(template);
- }
- };
-
- if (async === true ) {
- fs.stat(location, function (err, stats) {
- if (err || !stats.isFile())
- throw new Twig.Error("Unable to find template file " + location);
-
- fs.readFile(location, 'utf8' , loadTemplateFn);
- });
- } else {
- if (!fs.statSync(location).isFile())
- throw new Twig.Error("Unable to find template file " + location);
-
- data = fs.readFileSync(location, 'utf8' );
- loadTemplateFn(undefined , data);
- }
- })();
- }
- if (async === false ) {
- return template;
- } else {
-
-
-
-
-
-
-
-
-
placeholder for now, should eventually return a deferred object.
-
-
-
-
-
-
-
-
-
-
-
-
-
Determine object type
-
-
-
- function is (type, obj) {
- var clas = Object.prototype.toString.call(obj).slice(8 , -1 );
- return obj !== undefined && obj !== null && clas === type;
- }
-
-
- Twig.Template = function ( params ) {
- var data = params.data,
- id = params.id,
- blocks = params.blocks,
- macros = params.macros || {},
- base = params.base,
- path = params.path,
- url = params.url,
-
-
-
-
-
-
-
- options = params.options;
-
-
-
-
-
-
-
-
-
What is stored in a Twig.Template
-
The Twig Template hold several chucks of data.
-
{
- id: The token ID (if any)
- tokens: The list of tokens that makes up this template.
- blocks: The list of block this template contains.
- base: The base template (if any)
- options: {
- Compiler/parser options
-
- strict_variables: true/false
- Should missing variable/keys emit an error message. If false, they default to null.
- }
-}
-
-
-
- this .id = id;
- this .base = base;
- this .path = path;
- this .url = url;
- this .macros = macros;
- this .options = options;
-
- this .reset(blocks);
-
- if (is('String' , data)) {
- this .tokens = Twig.prepare.apply(this , [data]);
- } else {
- this .tokens = data;
- }
-
- if (id !== undefined ) {
- Twig.Templates.save(this );
- }
- };
-
- Twig.Template.prototype.reset = function (blocks) {
- Twig.log.debug("Twig.Template.reset" , "Reseting template " + this .id);
- this .blocks = {};
- this .child = {
- blocks: blocks || {}
- };
- this .extend = null ;
- };
-
- Twig.Template.prototype.render = function (context, params) {
- params = params || {};
-
- var output,
- url;
-
- this .context = context || {};
-
-
-
-
-
-
-
-
-
Clear any previous state
-
-
-
- this .reset();
- if (params.blocks) {
- this .blocks = params.blocks;
- }
- if (params.macros) {
- this .macros = params.macros;
- }
-
- output = Twig.parse.apply(this , [this .tokens, this .context]);
-
-
-
-
-
-
-
-
-
Does this template extend another
-
-
-
- if (this .extend) {
- var ext_template;
-
-
-
-
-
-
-
-
-
check if the template is provided inline
-
-
-
- if ( this .options.allowInlineIncludes ) {
- ext_template = Twig.Templates.load(this .extend);
- if ( ext_template ) {
- ext_template.options = this .options;
- }
- }
-
-
-
-
-
-
-
-
-
check for the template file via include
-
-
-
- if (!ext_template) {
- url = relativePath(this , this .extend);
-
- ext_template = Twig.Templates.loadRemote(url, {
- method: this .url?'ajax' :'fs' ,
- base: this .base,
- async: false ,
- id: url,
- options: this .options
- });
- }
-
- this .parent = ext_template;
-
- return this .parent.render(this .context, {
- blocks: this .blocks
- });
- }
-
- if (params.output == 'blocks' ) {
- return this .blocks;
- } else if (params.output == 'macros' ) {
- return this .macros;
- } else {
- return output;
- }
- };
-
- Twig.Template.prototype.importFile = function (file) {
- var url, sub_template;
- if ( !this .url && !this .path && this .options.allowInlineIncludes ) {
- sub_template = Twig.Templates.load(file);
- sub_template.options = this .options;
- if ( sub_template ) {
- return sub_template;
- }
-
- throw new Twig.Error("Didn't find the inline template by id" );
- }
-
- url = relativePath(this , file);
-
-
-
-
-
-
-
-
-
Load blocks from an external file
-
-
-
- sub_template = Twig.Templates.loadRemote(url, {
- method: this .url?'ajax' :'fs' ,
- base: this .base,
- async: false ,
- options: this .options,
- id: url
- });
-
- return sub_template;
- };
-
- Twig.Template.prototype.importBlocks = function (file, override) {
- var sub_template = this .importFile(file),
- context = this .context,
- that = this ,
- key;
-
- override = override || false ;
-
- sub_template.render(context);
-
-
-
-
-
-
-
- Twig.forEach(Object.keys(sub_template.blocks), function (key) {
- if (override || that.blocks[key] === undefined ) {
- that.blocks[key] = sub_template.blocks[key];
- }
- });
- };
-
- Twig.Template.prototype.importMacros = function (file) {
- var url = relativePath(this , file);
-
-
-
-
-
-
-
-
-
load remote template
-
-
-
- var remoteTemplate = Twig.Templates.loadRemote(url, {
- method: this .url?'ajax' :'fs' ,
- async: false ,
- id: url
- });
-
- return remoteTemplate;
- };
-
- Twig.Template.prototype.compile = function (options) {
-
-
-
-
-
-
-
-
-
compile the template into raw JS
-
-
-
- return Twig.compiler.compile(this , options);
- };
-
-
- function relativePath (template, file) {
- var base,
- base_path,
- sep_chr = "/" ,
- new_path = [],
- val;
-
- if (template.url) {
- if (typeof template.base !== 'undefined' ) {
- base = template.base + ((template.base.charAt(template.base.length-1 ) === '/' ) ? '' : '/' );
- } else {
- base = template.url;
- }
- } else if (template.path) {
-
-
-
-
-
-
-
-
-
Get the system-specific path separator
-
-
-
- var path = require("path" ),
- sep = path.sep || sep_chr,
- relative = new RegExp("^\\.{1,2}" + sep.replace("\\" , "\\\\" ));
- file = file.replace(/\//g , sep);
-
- if (template.base !== undefined && file.match(relative) == null ) {
- file = file.replace(template.base, '' );
- base = template.base + sep;
- } else {
- base = template.path;
- }
-
- base = base.replace(sep+sep, sep);
- sep_chr = sep;
- } else {
- throw new Twig.Error("Cannot extend an inline template." );
- }
-
- base_path = base.split(sep_chr);
-
-
-
-
-
-
-
-
-
Remove file from url
-
-
-
- base_path.pop();
- base_path = base_path.concat(file.split(sep_chr));
-
- while (base_path.length > 0 ) {
- val = base_path.shift();
- if (val == "." ) {
-
-
-
-
-
-
-
- } else if (val == ".." && new_path.length > 0 && new_path[new_path.length-1 ] != ".." ) {
- new_path.pop();
- } else {
- new_path.push(val);
- }
- }
-
- return new_path.join(sep_chr);
- }
-
- return Twig;
-
-}) (Twig || { });
-
-
-
-
-
-
-
-
-
The following methods are from MDN and are available under a
-MIT License or are
-Public Domain .
-
See:
-
-
twig.fills.js
-
This file contains fills for backwards compatability.
-
-
-
- (function () {
- "use strict" ;
-
-
-
-
-
-
-
-
-
Handle methods that don't yet exist in every browser
-
-
-
- if (!String.prototype.trim) {
- String.prototype.trim = function () {
- return this .replace(/^\s+|\s+$/g ,'' );
- }
- };
-
- if (!Object.keys) Object.keys = function (o) {
- if (o !== Object(o)) {
- throw new TypeError('Object.keys called on non-object' );
- }
- var ret = [], p;
- for (p in o) if (Object.prototype.hasOwnProperty.call(o, p)) ret.push(p);
- return ret;
- }
-
-})();
-
-
-
-
-
-
-
-
-
twig.lib.js
-
This file contains 3rd party libraries used within twig.
-
Copies of the licenses for the code included here can be found in the
-LICENSES.md file.
-
-
-
- var Twig = (function (Twig) {
-
-
-
-
-
-
-
-
-
Namespace for libraries
-
-
-
- Twig.lib = { };
-
-
- var sprintf = (function () {
- function get_type (variable) {
- return Object.prototype.toString.call(variable).slice(8 , -1 ).toLowerCase();
- }
- function str_repeat (input, multiplier) {
- for (var output = []; multiplier > 0 ; output[--multiplier] = input) {}
- return output.join('' );
- }
-
- var str_format = function () {
- if (!str_format.cache.hasOwnProperty(arguments[0 ])) {
- str_format.cache[arguments[0 ]] = str_format.parse(arguments[0 ]);
- }
- return str_format.format.call(null , str_format.cache[arguments[0 ]], arguments);
- };
-
- str_format.format = function (parse_tree, argv) {
- var cursor = 1 , tree_length = parse_tree.length, node_type = '' , arg, output = [], i, k, match, pad, pad_character, pad_length;
- for (i = 0 ; i < tree_length; i++) {
- node_type = get_type(parse_tree[i]);
- if (node_type === 'string' ) {
- output.push(parse_tree[i]);
- }
- else if (node_type === 'array' ) {
- match = parse_tree[i];
- if (match[2 ]) {
- arg = argv[cursor];
- for (k = 0 ; k < match[2 ].length; k++) {
- if (!arg.hasOwnProperty(match[2 ][k])) {
- throw (sprintf('[sprintf] property "%s" does not exist' , match[2 ][k]));
- }
- arg = arg[match[2 ][k]];
- }
- }
- else if (match[1 ]) {
- arg = argv[match[1 ]];
- }
- else {
- arg = argv[cursor++];
- }
-
- if (/[^s]/ .test(match[8 ]) && (get_type(arg) != 'number' )) {
- throw (sprintf('[sprintf] expecting number but found %s' , get_type(arg)));
- }
- switch (match[8 ]) {
- case 'b' : arg = arg.toString(2 ); break ;
- case 'c' : arg = String.fromCharCode(arg); break ;
- case 'd' : arg = parseInt(arg, 10 ); break ;
- case 'e' : arg = match[7 ] ? arg.toExponential(match[7 ]) : arg.toExponential(); break ;
- case 'f' : arg = match[7 ] ? parseFloat(arg).toFixed(match[7 ]) : parseFloat(arg); break ;
- case 'o' : arg = arg.toString(8 ); break ;
- case 's' : arg = ((arg = String(arg)) && match[7 ] ? arg.substring(0 , match[7 ]) : arg); break ;
- case 'u' : arg = Math.abs(arg); break ;
- case 'x' : arg = arg.toString(16 ); break ;
- case 'X' : arg = arg.toString(16 ).toUpperCase(); break ;
- }
- arg = (/[def]/ .test(match[8 ]) && match[3 ] && arg >= 0 ? '+' + arg : arg);
- pad_character = match[4 ] ? match[4 ] == '0' ? '0' : match[4 ].charAt(1 ) : ' ' ;
- pad_length = match[6 ] - String(arg).length;
- pad = match[6 ] ? str_repeat(pad_character, pad_length) : '' ;
- output.push(match[5 ] ? arg + pad : pad + arg);
- }
- }
- return output.join('' );
- };
-
- str_format.cache = {};
-
- str_format.parse = function (fmt) {
- var _fmt = fmt, match = [], parse_tree = [], arg_names = 0 ;
- while (_fmt) {
- if ((match = /^[^\x25]+/ .exec(_fmt)) !== null ) {
- parse_tree.push(match[0 ]);
- }
- else if ((match = /^\x25{2}/ .exec(_fmt)) !== null ) {
- parse_tree.push('%' );
- }
- else if ((match = /^\x25(?:([1-9]\d*)\$|\(([^\)]+)\))?(\+)?(0|'[^$])?(-)?(\d+)?(?:\.(\d+))?([b-fosuxX])/ .exec(_fmt)) !== null ) {
- if (match[2 ]) {
- arg_names |= 1 ;
- var field_list = [], replacement_field = match[2 ], field_match = [];
- if ((field_match = /^([a-z_][a-z_\d]*)/i .exec(replacement_field)) !== null ) {
- field_list.push(field_match[1 ]);
- while ((replacement_field = replacement_field.substring(field_match[0 ].length)) !== '' ) {
- if ((field_match = /^\.([a-z_][a-z_\d]*)/i .exec(replacement_field)) !== null ) {
- field_list.push(field_match[1 ]);
- }
- else if ((field_match = /^\[(\d+)\]/ .exec(replacement_field)) !== null ) {
- field_list.push(field_match[1 ]);
- }
- else {
- throw ('[sprintf] huh?' );
- }
- }
- }
- else {
- throw ('[sprintf] huh?' );
- }
- match[2 ] = field_list;
- }
- else {
- arg_names |= 2 ;
- }
- if (arg_names === 3 ) {
- throw ('[sprintf] mixing positional and named placeholders is not (yet) supported' );
- }
- parse_tree.push(match);
- }
- else {
- throw ('[sprintf] huh?' );
- }
- _fmt = _fmt.substring(match[0 ].length);
- }
- return parse_tree;
- };
-
- return str_format;
- })();
-
- var vsprintf = function (fmt, argv) {
- argv.unshift(fmt);
- return sprintf.apply(null , argv);
- };
-
-
-
-
-
-
-
- Twig.lib.sprintf = sprintf;
- Twig.lib.vsprintf = vsprintf;
-
-
-
- ; (function () {
- var shortDays = "Sun,Mon,Tue,Wed,Thu,Fri,Sat" .split("," );
- var fullDays = "Sunday,Monday,Tuesday,Wednesday,Thursday,Friday,Saturday" .split("," );
- var shortMonths = "Jan,Feb,Mar,Apr,May,Jun,Jul,Aug,Sep,Oct,Nov,Dec" .split("," );
- var fullMonths = "January,February,March,April,May,June,July,August,September,October,November,December" .split("," );
- function getOrdinalFor (intNum) {
- return (((intNum = Math.abs(intNum) % 100 ) % 10 == 1 && intNum != 11 ) ? "st"
- : (intNum % 10 == 2 && intNum != 12 ) ? "nd" : (intNum % 10 == 3
- && intNum != 13 ) ? "rd" : "th" );
- }
- function getISO8601Year (aDate) {
- var d = new Date(aDate.getFullYear() + 1 , 0 , 4 );
- if ((d - aDate) / 86400000 < 7 && (aDate.getDay() + 6 ) % 7 < (d.getDay() + 6 ) % 7 )
- return d.getFullYear();
- if (aDate.getMonth() > 0 || aDate.getDate() >= 4 )
- return aDate.getFullYear();
- return aDate.getFullYear() - (((aDate.getDay() + 6 ) % 7 - aDate.getDate() > 2 ) ? 1 : 0 );
- }
- function getISO8601Week (aDate) {
-
-
-
-
-
-
-
-
-
Get a day during the first week of the year.
-
-
-
- var d = new Date(getISO8601Year(aDate), 0 , 4 );
-
-
-
-
-
-
-
-
-
Get the first monday of the year.
-
-
-
- d.setDate(d.getDate() - (d.getDay() + 6 ) % 7 );
- return parseInt((aDate - d) / 604800000 ) + 1 ;
- }
- Twig.lib.formatDate = function (date, format) {
-
-
-
-
-
-
-
-
-
/
-/ Gets a string for this date, formatted according to the given format
-/ string.
-/
-/
-/ The format of the output date string. The format string works in a
-/ nearly identical way to the PHP date function which is highlighted here:
-/ http://php.net/manual/en/function.date.php .
-/ The only difference is the fact that "u" signifies milliseconds
-/ instead of microseconds. The following characters are recognized in
-/ the format parameter string:
-/ d - Day of the month, 2 digits with leading zeros
-/ D - A textual representation of a day, three letters
-/ j - Day of the month without leading zeros
-/ l (lowercase 'L') - A full textual representation of the day of the week
-/ N - ISO-8601 numeric representation of the day of the week (starting from 1)
-/ S - English ordinal suffix for the day of the month, 2 characters st,
-/ nd, rd or th. Works well with j.
-/ w - Numeric representation of the day of the week (starting from 0)
-/ z - The day of the year (starting from 0)
-/ W - ISO-8601 week number of year, weeks starting on Monday
-/ F - A full textual representation of a month, such as January or March
-/ m - Numeric representation of a month, with leading zeros
-/ M - A short textual representation of a month, three letters
-/ n - Numeric representation of a month, without leading zeros
-/ t - Number of days in the given month
-/ L - Whether it's a leap year
-/ o - ISO-8601 year number. This has the same value as Y, except that if
-/ the ISO week number (W) belongs to the previous or next year, that
-/ year is used instead.
-/ Y - A full numeric representation of a year, 4 digits
-/ y - A two digit representation of a year
-/ a - Lowercase Ante meridiem and Post meridiem
-/ A - Uppercase Ante meridiem and Post meridiem
-/ B - Swatch Internet time
-/ g - 12-hour format of an hour without leading zeros
-/ G - 24-hour format of an hour without leading zeros
-/ h - 12-hour format of an hour with leading zeros
-/ H - 24-hour format of an hour with leading zeros
-/ i - Minutes with leading zeros
-/ s - Seconds, with leading zeros
-/ u - Milliseconds
-/ U - Seconds since the Unix Epoch (January 1 1970 00:00:00 GMT)
-/
-/
-/ Returns the string for this date, formatted according to the given
-/ format string.
-/
-If the format was not passed, use the default toString method.
-
-
-
- if (typeof format !== "string" || /^\s*$/ .test(format))
- return date + "" ;
- var jan1st = new Date(date.getFullYear(), 0 , 1 );
- var me = date;
- return format.replace(/[dDjlNSwzWFmMntLoYyaABgGhHisuU]/g , function (option) {
- switch (option) {
-
-
-
-
-
-
-
-
-
Day of the month, 2 digits with leading zeros
-
-
-
- case "d" : return ("0" + me.getDate()).replace(/^.+(..)$/ , "$1" );
-
-
-
-
-
-
-
-
-
A textual representation of a day, three letters
-
-
-
- case "D" : return shortDays[me.getDay()];
-
-
-
-
-
-
-
-
-
Day of the month without leading zeros
-
-
-
- case "j" : return me.getDate();
-
-
-
-
-
-
-
-
-
A full textual representation of the day of the week
-
-
-
- case "l" : return fullDays[me.getDay()];
-
-
-
-
-
-
-
-
-
ISO-8601 numeric representation of the day of the week
-
-
-
- case "N" : return (me.getDay() + 6 ) % 7 + 1 ;
-
-
-
-
-
-
-
-
-
English ordinal suffix for the day of the month, 2 characters
-
-
-
- case "S" : return getOrdinalFor(me.getDate());
-
-
-
-
-
-
-
-
-
Numeric representation of the day of the week
-
-
-
- case "w" : return me.getDay();
-
-
-
-
-
-
-
-
-
The day of the year (starting from 0)
-
-
-
- case "z" : return Math.ceil((jan1st - me) / 86400000 );
-
-
-
-
-
-
-
-
-
ISO-8601 week number of year, weeks starting on Monday
-
-
-
- case "W" : return ("0" + getISO8601Week(me)).replace(/^.(..)$/ , "$1" );
-
-
-
-
-
-
-
-
-
A full textual representation of a month, such as January or March
-
-
-
- case "F" : return fullMonths[me.getMonth()];
-
-
-
-
-
-
-
-
-
Numeric representation of a month, with leading zeros
-
-
-
- case "m" : return ("0" + (me.getMonth() + 1 )).replace(/^.+(..)$/ , "$1" );
-
-
-
-
-
-
-
-
-
A short textual representation of a month, three letters
-
-
-
- case "M" : return shortMonths[me.getMonth()];
-
-
-
-
-
-
-
-
-
Numeric representation of a month, without leading zeros
-
-
-
- case "n" : return me.getMonth() + 1 ;
-
-
-
-
-
-
-
-
-
Number of days in the given month
-
-
-
- case "t" : return new Date(me.getFullYear(), me.getMonth() + 1 , -1 ).getDate();
-
-
-
-
-
-
-
-
-
Whether it's a leap year
-
-
-
- case "L" : return new Date(me.getFullYear(), 1 , 29 ).getDate() == 29 ? 1 : 0 ;
-
-
-
-
-
-
-
-
-
ISO-8601 year number. This has the same value as Y, except that if the
-ISO week number (W) belongs to the previous or next year, that year is
-used instead.
-
-
-
- case "o" : return getISO8601Year(me);
-
-
-
-
-
-
-
-
-
A full numeric representation of a year, 4 digits
-
-
-
- case "Y" : return me.getFullYear();
-
-
-
-
-
-
-
-
-
A two digit representation of a year
-
-
-
- case "y" : return (me.getFullYear() + "" ).replace(/^.+(..)$/ , "$1" );
-
-
-
-
-
-
-
-
-
Lowercase Ante meridiem and Post meridiem
-
-
-
- case "a" : return me.getHours() < 12 ? "am" : "pm" ;
-
-
-
-
-
-
-
-
-
Uppercase Ante meridiem and Post meridiem
-
-
-
- case "A" : return me.getHours() < 12 ? "AM" : "PM" ;
-
-
-
-
-
-
-
-
-
Swatch Internet time
-
-
-
- case "B" : return Math.floor((((me.getUTCHours() + 1 ) % 24 ) + me.getUTCMinutes() / 60 + me.getUTCSeconds() / 3600 ) * 1000 / 24 );
-
-
-
-
-
-
-
-
-
12-hour format of an hour without leading zeros
-
-
-
- case "g" : return me.getHours() % 12 != 0 ? me.getHours() % 12 : 12 ;
-
-
-
-
-
-
-
-
-
24-hour format of an hour without leading zeros
-
-
-
- case "G" : return me.getHours();
-
-
-
-
-
-
-
-
-
12-hour format of an hour with leading zeros
-
-
-
- case "h" : return ("0" + (me.getHours() % 12 != 0 ? me.getHours() % 12 : 12 )).replace(/^.+(..)$/ , "$1" );
-
-
-
-
-
-
-
-
-
24-hour format of an hour with leading zeros
-
-
-
- case "H" : return ("0" + me.getHours()).replace(/^.+(..)$/ , "$1" );
-
-
-
-
-
-
-
-
-
Minutes with leading zeros
-
-
-
- case "i" : return ("0" + me.getMinutes()).replace(/^.+(..)$/ , "$1" );
-
-
-
-
-
-
-
-
-
Seconds, with leading zeros
-
-
-
- case "s" : return ("0" + me.getSeconds()).replace(/^.+(..)$/ , "$1" );
-
-
-
-
-
-
-
- case "u" : return me.getMilliseconds();
-
-
-
-
-
-
-
-
-
Seconds since the Unix Epoch (January 1 1970 00:00:00 GMT)
-
-
-
- case "U" : return me.getTime() / 1000 ;
- }
- });
- };
- })();
-
- Twig.lib.strip_tags = function (input, allowed) {
-
-
-
-
-
-
-
- allowed = (((allowed || "" ) + "" ).toLowerCase().match(/<[a-z][a-z0-9]*>/g ) || []).join('' );
- var tags = /<\/?([a-z][a-z0-9]*)\b[^>]*>/gi ,
- commentsAndPhpTags = /<!--[\s\S]*?-->|<\?(?:php)?[\s\S]*?\?>/gi ;
- return input.replace(commentsAndPhpTags, '' ).replace(tags, function ($0, $1) {
- return allowed.indexOf('<' + $1. toLowerCase() + '>' ) > -1 ? $0 : '' ;
- });
- }
-
- Twig.lib.parseISO8601Date = function (s) {
-
-
-
-
-
-
-
- var re = /(\d{4})-(\d\d)-(\d\d)T(\d\d):(\d\d):(\d\d)(\.\d+)?(Z|([+-])(\d\d):(\d\d))/ ;
-
- var d = [];
- d = s.match(re);
-
-
-
-
-
-
-
-
-
"2010-12-07T11:00:00.000-09:00" parses to:
- ["2010-12-07T11:00:00.000-09:00", "2010", "12", "07", "11",
- "00", "00", ".000", "-09:00", "-", "09", "00"]
-"2010-12-07T11:00:00.000Z" parses to:
- ["2010-12-07T11:00:00.000Z", "2010", "12", "07", "11",
- "00", "00", ".000", "Z", undefined, undefined, undefined]
-
-
-
- if (! d) {
- throw "Couldn't parse ISO 8601 date string '" + s + "'" ;
- }
-
-
-
-
-
-
-
-
-
parse strings, leading zeros into proper ints
-
-
-
- var a = [1 ,2 ,3 ,4 ,5 ,6 ,10 ,11 ];
- for (var i in a) {
- d[a[i]] = parseInt(d[a[i]], 10 );
- }
- d[7 ] = parseFloat(d[7 ]);
-
-
-
-
-
-
-
- var ms = Date.UTC(d[1 ], d[2 ] - 1 , d[3 ], d[4 ], d[5 ], d[6 ]);
-
-
-
-
-
-
-
-
-
if there are milliseconds, add them
-
-
-
- if (d[7 ] > 0 ) {
- ms += Math.round(d[7 ] * 1000 );
- }
-
-
-
-
-
-
-
-
-
if there's a timezone, calculate it
-
-
-
- if (d[8 ] != "Z" && d[10 ]) {
- var offset = d[10 ] * 60 * 60 * 1000 ;
- if (d[11 ]) {
- offset += d[11 ] * 60 * 1000 ;
- }
- if (d[9 ] == "-" ) {
- ms -= offset;
- }
- else {
- ms += offset;
- }
- }
-
- return new Date(ms);
- };
-
- Twig.lib.strtotime = function (str, now) {
-
-
-
-
-
-
-
-
-
http://kevin.vanzonneveld.net
-
-original by: Caio Ariede (http://caioariede.com )
-improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net )
-input by: David
-improved by: Caio Ariede (http://caioariede.com )
-improved by: Brett Zamir (http://brett-zamir.me )
-bugfixed by: Wagner B. Soares
-bugfixed by: Artur Tchernychev
-% note 1: Examples all have a fixed timestamp to prevent tests to fail because of variable time(zones)
-example 1: strtotime('+1 day', 1129633200);
-returns 1: 1129719600
-example 2: strtotime('+1 week 2 days 4 hours 2 seconds', 1129633200);
-returns 2: 1130425202
-example 3: strtotime('last month', 1129633200);
-returns 3: 1127041200
-example 4: strtotime('2009-05-04 08:30:00');
-returns 4: 1241418600
-
-
-
-
- var i, l, match, s, parse = '' ;
-
- str = str.replace(/\s{2,}|^\s|\s$/g , ' ' );
- str = str.replace(/[\t\r\n]/g , '' );
- if (str === 'now' ) {
- return now === null || isNaN(now) ? new Date().getTime() / 1000 | 0 : now | 0 ;
- } else if (!isNaN(parse = Date.parse(str))) {
- return parse / 1000 | 0 ;
- } else if (now) {
- now = new Date(now * 1000 );
- } else {
- now = new Date();
- }
-
- var upperCaseStr = str;
-
- str = str.toLowerCase();
-
- var __is = {
- day: {
- 'sun' : 0 ,
- 'mon' : 1 ,
- 'tue' : 2 ,
- 'wed' : 3 ,
- 'thu' : 4 ,
- 'fri' : 5 ,
- 'sat' : 6
- },
- mon: [
- 'jan' ,
- 'feb' ,
- 'mar' ,
- 'apr' ,
- 'may' ,
- 'jun' ,
- 'jul' ,
- 'aug' ,
- 'sep' ,
- 'oct' ,
- 'nov' ,
- 'dec'
- ]
- };
-
- var process = function (m) {
- var ago = (m[2 ] && m[2 ] === 'ago' );
- var num = (num = m[0 ] === 'last' ? -1 : 1 ) * (ago ? -1 : 1 );
-
- switch (m[0 ]) {
- case 'last' :
- case 'next' :
- switch (m[1 ].substring(0 , 3 )) {
- case 'yea' :
- now.setFullYear(now.getFullYear() + num);
- break ;
- case 'wee' :
- now.setDate(now.getDate() + (num * 7 ));
- break ;
- case 'day' :
- now.setDate(now.getDate() + num);
- break ;
- case 'hou' :
- now.setHours(now.getHours() + num);
- break ;
- case 'min' :
- now.setMinutes(now.getMinutes() + num);
- break ;
- case 'sec' :
- now.setSeconds(now.getSeconds() + num);
- break ;
- case 'mon' :
- if (m[1 ] === "month" ) {
- now.setMonth(now.getMonth() + num);
- break ;
- }
-
-
-
-
-
-
-
- default :
- var day = __is.day[m[1 ].substring(0 , 3 )];
- if (typeof day !== 'undefined' ) {
- var diff = day - now.getDay();
- if (diff === 0 ) {
- diff = 7 * num;
- } else if (diff > 0 ) {
- if (m[0 ] === 'last' ) {
- diff -= 7 ;
- }
- } else {
- if (m[0 ] === 'next' ) {
- diff += 7 ;
- }
- }
- now.setDate(now.getDate() + diff);
- now.setHours(0 , 0 , 0 , 0 );
- }
- }
- break ;
-
- default :
- if (/\d+/ .test(m[0 ])) {
- num *= parseInt(m[0 ], 10 );
-
- switch (m[1 ].substring(0 , 3 )) {
- case 'yea' :
- now.setFullYear(now.getFullYear() + num);
- break ;
- case 'mon' :
- now.setMonth(now.getMonth() + num);
- break ;
- case 'wee' :
- now.setDate(now.getDate() + (num * 7 ));
- break ;
- case 'day' :
- now.setDate(now.getDate() + num);
- break ;
- case 'hou' :
- now.setHours(now.getHours() + num);
- break ;
- case 'min' :
- now.setMinutes(now.getMinutes() + num);
- break ;
- case 'sec' :
- now.setSeconds(now.getSeconds() + num);
- break ;
- }
- } else {
- return false ;
- }
- break ;
- }
- return true ;
- };
-
- match = str.match(/^(\d{2,4}-\d{2}-\d{2})(?:\s(\d{1,2}:\d{2}(:\d{2})?)?(?:\.(\d+))?)?$/ );
- if (match !== null ) {
- if (!match[2 ]) {
- match[2 ] = '00:00:00' ;
- } else if (!match[3 ]) {
- match[2 ] += ':00' ;
- }
-
- s = match[1 ].split(/-/g );
-
- s[1 ] = __is.mon[s[1 ] - 1 ] || s[1 ];
- s[0 ] = +s[0 ];
-
- s[0 ] = (s[0 ] >= 0 && s[0 ] <= 69 ) ? '20' + (s[0 ] < 10 ? '0' + s[0 ] : s[0 ] + '' ) : (s[0 ] >= 70 && s[0 ] <= 99 ) ? '19' + s[0 ] : s[0 ] + '' ;
- return parseInt(this .strtotime(s[2 ] + ' ' + s[1 ] + ' ' + s[0 ] + ' ' + match[2 ]) + (match[4 ] ? match[4 ] / 1000 : '' ), 10 );
- }
-
- var regex = '([+-]?\\d+\\s' + '(years?|months?|weeks?|days?|hours?|min|minutes?|sec|seconds?' + '|sun\\.?|sunday|mon\\.?|monday|tue\\.?|tuesday|wed\\.?|wednesday' + '|thu\\.?|thursday|fri\\.?|friday|sat\\.?|saturday)' + '|(last|next)\\s' + '(years?|months?|weeks?|days?|hours?|min|minutes?|sec|seconds?' + '|sun\\.?|sunday|mon\\.?|monday|tue\\.?|tuesday|wed\\.?|wednesday' + '|thu\\.?|thursday|fri\\.?|friday|sat\\.?|saturday))' + '(\\sago)?' ;
-
- match = str.match(new RegExp(regex, 'gi' ));
- if (match === null ) {
-
-
-
-
-
-
-
-
-
Try to parse ISO8601 in IE8
-
-
-
- try {
- num = Twig.lib.parseISO8601Date(upperCaseStr);
- if (num) {
- return num / 1000 | 0 ;
- }
- } catch (err) {
- return false ;
- }
- return false ;
- }
-
- for (i = 0 , l = match.length; i < l; i++) {
- if (!process(match[i].split(' ' ))) {
- return false ;
- }
- }
-
- return now.getTime() / 1000 | 0 ;
- };
-
- Twig.lib.is = function (type, obj) {
- var clas = Object.prototype.toString.call(obj).slice(8 , -1 );
- return obj !== undefined && obj !== null && clas === type;
- };
-
-
-
-
-
-
-
-
-
shallow-copy an object
-
-
-
- Twig.lib.copy = function (src) {
- var target = {},
- key;
- for (key in src)
- target[key] = src[key];
-
- return target;
- };
-
- Twig.lib.replaceAll = function (string, search, replace) {
- return string.split(search).join(replace);
- };
-
-
-
-
-
-
-
-
-
chunk an array (arr) into arrays of (size) items, returns an array of arrays, or an empty array on invalid input
-
-
-
- Twig.lib.chunkArray = function (arr, size) {
- var returnVal = [],
- x = 0 ,
- len = arr.length;
-
- if (size < 1 || !Twig.lib.is("Array" , arr)) {
- return [];
- }
-
- while (x < len) {
- returnVal.push(arr.slice(x, x += size));
- }
-
- return returnVal;
- };
-
- Twig.lib.round = function round (value, precision, mode) {
-
-
-
-
-
-
-
-
-
discuss at: http://phpjs.org/functions/round/
-original by: Philip Peterson
- revised by: Onno Marsman
- revised by: T.Wild
- revised by: Rafał Kukawski (http://blog.kukawski.pl/ )
- input by: Greenseed
- input by: meo
- input by: William
- input by: Josep Sanz (http://www.ws3.es/ )
-bugfixed by: Brett Zamir (http://brett-zamir.me )
- note: Great work. Ideas for improvement:
- note: - code more compliant with developer guidelines
- note: - for implementing PHP constant arguments look at
- note: the pathinfo() function, it offers the greatest
- note: flexibility & compatibility possible
- example 1: round(1241757, -3);
- returns 1: 1242000
- example 2: round(3.6);
- returns 2: 4
- example 3: round(2.835, 2);
- returns 3: 2.84
- example 4: round(1.1749999999999, 2);
- returns 4: 1.17
- example 5: round(58551.799999999996, 2);
- returns 5: 58551.8
-
-
-
- var m, f, isHalf, sgn;
- precision |= 0 ;
- m = Math.pow(10 , precision);
- value *= m;
- sgn = (value > 0 ) | -(value < 0 );
- isHalf = value % 1 === 0.5 * sgn;
- f = Math.floor(value);
-
- if (isHalf) {
- switch (mode) {
- case 'PHP_ROUND_HALF_DOWN' :
- value = f + (sgn < 0 );
- break ;
- case 'PHP_ROUND_HALF_EVEN' :
- value = f + (f % 2 * sgn);
- break ;
- case 'PHP_ROUND_HALF_ODD' :
- value = f + !(f % 2 );
- break ;
- default :
- value = f + (sgn > 0 );
- }
- }
-
- return (isHalf ? value : Math.round(value)) / m;
- }
-
- return Twig;
-
-})(Twig || { });
-
-
-
-
-
-
-
-
-
Twig.js
-Copyright (c) 2011-2013 John Roepke
-Available under the BSD 2-Clause License
-https://github.com/justjohn/twig.js
-
twig.logic.js
-
This file handles tokenizing, compiling and parsing logic tokens. {% ... %}
-
-
-
- var Twig = (function (Twig) {
- "use strict" ;
-
-
- Twig.logic = {};
-
-
- Twig.logic.type = {
- if_: 'Twig.logic.type.if' ,
- endif: 'Twig.logic.type.endif' ,
- for_: 'Twig.logic.type.for' ,
- endfor: 'Twig.logic.type.endfor' ,
- else_: 'Twig.logic.type.else' ,
- elseif: 'Twig.logic.type.elseif' ,
- set: 'Twig.logic.type.set' ,
- setcapture:'Twig.logic.type.setcapture' ,
- endset: 'Twig.logic.type.endset' ,
- filter: 'Twig.logic.type.filter' ,
- endfilter: 'Twig.logic.type.endfilter' ,
- block: 'Twig.logic.type.block' ,
- endblock: 'Twig.logic.type.endblock' ,
- extends_: 'Twig.logic.type.extends' ,
- use: 'Twig.logic.type.use' ,
- include: 'Twig.logic.type.include' ,
- spaceless: 'Twig.logic.type.spaceless' ,
- endspaceless: 'Twig.logic.type.endspaceless' ,
- macro: 'Twig.logic.type.macro' ,
- endmacro: 'Twig.logic.type.endmacro' ,
- import_: 'Twig.logic.type.import' ,
- from: 'Twig.logic.type.from'
- };
-
-
-
-
-
-
-
-
-
Regular expressions for handling logic tokens.
-
Properties:
-
type: The type of expression this matches
-
- regex: A regular expression that matches the format of the token
-
- next: What logic tokens (if any) pop this token off the logic stack. If empty, the
- logic token is assumed to not require an end tag and isn't push onto the stack.
-
- open: Does this tag open a logic expression or is it standalone. For example,
- {% endif %} cannot exist without an opening {% if ... %} tag, so open = false.
-
Functions:
-
compile: A function that handles compiling the token into an output token ready for
- parsing with the parse function.
-
- parse: A function that parses the compiled token into output (HTML / whatever the
- template represents).
-
-
-
- Twig.logic.definitions = [
- {
-
- type: Twig.logic.type.if_,
- regex: /^if\s+([^\s].+)$/ ,
- next: [
- Twig.logic.type.else_,
- Twig.logic.type.elseif,
- Twig.logic.type.endif
- ],
- open: true ,
- compile: function (token) {
- var expression = token.match[1 ];
-
-
-
-
-
-
-
-
-
Compile the expression.
-
-
-
- token.stack = Twig.expression.compile.apply(this , [{
- type: Twig.expression.type.expression,
- value: expression
- }]).stack;
- delete token.match;
- return token;
- },
- parse: function (token, context, chain) {
- var output = '' ,
-
-
-
-
-
-
-
-
-
Parse the expression
-
-
-
- result = Twig.expression.parse.apply(this , [token.stack, context]);
-
-
-
-
-
-
-
-
-
Start a new logic chain
-
-
-
- chain = true ;
-
- if (result) {
- chain = false ;
-
-
-
-
-
-
-
-
-
parse if output
-
-
-
- output = Twig.parse.apply(this , [token.output, context]);
- }
- return {
- chain: chain,
- output: output
- };
- }
- },
- {
-
- type: Twig.logic.type.elseif,
- regex: /^elseif\s+([^\s].*)$/ ,
- next: [
- Twig.logic.type.else_,
- Twig.logic.type.elseif,
- Twig.logic.type.endif
- ],
- open: false ,
- compile: function (token) {
- var expression = token.match[1 ];
-
-
-
-
-
-
-
-
-
Compile the expression.
-
-
-
- token.stack = Twig.expression.compile.apply(this , [{
- type: Twig.expression.type.expression,
- value: expression
- }]).stack;
- delete token.match;
- return token;
- },
- parse: function (token, context, chain) {
- var output = '' ;
-
- if (chain && Twig.expression.parse.apply(this , [token.stack, context]) === true ) {
- chain = false ;
-
-
-
-
-
-
-
-
-
parse if output
-
-
-
- output = Twig.parse.apply(this , [token.output, context]);
- }
-
- return {
- chain: chain,
- output: output
- };
- }
- },
- {
-
- type: Twig.logic.type.else_,
- regex: /^else$/ ,
- next: [
- Twig.logic.type.endif,
- Twig.logic.type.endfor
- ],
- open: false ,
- parse: function (token, context, chain) {
- var output = '' ;
- if (chain) {
- output = Twig.parse.apply(this , [token.output, context]);
- }
- return {
- chain: chain,
- output: output
- };
- }
- },
- {
-
- type: Twig.logic.type.endif,
- regex: /^endif$/ ,
- next: [ ],
- open: false
- },
- {
-
- type: Twig.logic.type.for_,
- regex: /^for\s+([a-zA-Z0-9_,\s]+)\s+in\s+([^\s].*?)(?:\s+if\s+([^\s].*))?$/ ,
- next: [
- Twig.logic.type.else_,
- Twig.logic.type.endfor
- ],
- open: true ,
- compile: function (token) {
- var key_value = token.match[1 ],
- expression = token.match[2 ],
- conditional = token.match[3 ],
- kv_split = null ;
-
- token.key_var = null ;
- token.value_var = null ;
-
- if (key_value.indexOf("," ) >= 0 ) {
- kv_split = key_value.split(',' );
- if (kv_split.length === 2 ) {
- token.key_var = kv_split[0 ].trim();
- token.value_var = kv_split[1 ].trim();
- } else {
- throw new Twig.Error("Invalid expression in for loop: " + key_value);
- }
- } else {
- token.value_var = key_value;
- }
-
-
-
-
-
-
-
-
-
Valid expressions for a for loop
- for item in expression
- for key,item in expression
-
Compile the expression.
-
-
-
- token.expression = Twig.expression.compile.apply(this , [{
- type: Twig.expression.type.expression,
- value: expression
- }]).stack;
-
-
-
-
-
-
-
-
-
Compile the conditional (if available)
-
-
-
- if (conditional) {
- token.conditional = Twig.expression.compile.apply(this , [{
- type: Twig.expression.type.expression,
- value: conditional
- }]).stack;
- }
-
- delete token.match;
- return token;
- },
- parse: function (token, context, continue_chain) {
-
-
-
-
-
-
-
-
-
Parse expression
-
-
-
- var result = Twig.expression.parse.apply(this , [token.expression, context]),
- output = [],
- len,
- index = 0 ,
- keyset,
- that = this ,
- conditional = token.conditional,
- buildLoop = function (index, len) {
- var isConditional = conditional !== undefined ;
- return {
- index: index+1 ,
- index0: index,
- revindex: isConditional?undefined :len-index,
- revindex0: isConditional?undefined :len-index-1 ,
- first: (index === 0 ),
- last: isConditional?undefined :(index === len-1 ),
- length: isConditional?undefined :len,
- parent: context
- };
- },
- loop = function (key, value) {
- var inner_context = Twig.lib.copy(context);
-
- inner_context[token.value_var] = value;
- if (token.key_var) {
- inner_context[token.key_var] = key;
- }
-
-
-
-
-
-
-
- inner_context.loop = buildLoop(index, len);
-
- if (conditional === undefined ||
- Twig.expression.parse.apply(that, [conditional, inner_context]))
- {
- output.push(Twig.parse.apply(that, [token.output, inner_context]));
- index += 1 ;
- }
- };
-
- if (result instanceof Array) {
- len = result.length;
- Twig.forEach(result, function (value) {
- var key = index;
-
- loop(key, value);
- });
- } else if (result instanceof Object) {
- if (result._keys !== undefined ) {
- keyset = result._keys;
- } else {
- keyset = Object.keys(result);
- }
- len = keyset.length;
- Twig.forEach(keyset, function (key) {
-
-
-
-
-
-
-
-
-
Ignore the _keys property, it's internal to twig.js
-
-
-
- if (key === "_keys" ) return ;
-
- loop(key, result[key]);
- });
- }
-
-
-
-
-
-
-
-
-
Only allow else statements if no output was generated
-
-
-
- continue_chain = (output.length === 0 );
-
- return {
- chain: continue_chain,
- output: output.join("" )
- };
- }
- },
- {
-
- type: Twig.logic.type.endfor,
- regex: /^endfor$/ ,
- next: [ ],
- open: false
- },
- {
-
- type: Twig.logic.type.set,
- regex: /^set\s+([a-zA-Z0-9_,\s]+)\s*=\s*(.+)$/ ,
- next: [ ],
- open: true ,
- compile: function (token) {
- var key = token.match[1 ].trim(),
- expression = token.match[2 ],
-
-
-
-
-
-
-
-
-
Compile the expression.
-
-
-
- expression_stack = Twig.expression.compile.apply(this , [{
- type: Twig.expression.type.expression,
- value: expression
- }]).stack;
-
- token.key = key;
- token.expression = expression_stack;
-
- delete token.match;
- return token;
- },
- parse: function (token, context, continue_chain) {
- var value = Twig.expression.parse.apply(this , [token.expression, context]),
- key = token.key;
-
-
-
-
-
-
-
-
-
set on both the global and local context
-
-
-
- this .context[key] = value;
- context[key] = value;
-
- return {
- chain: continue_chain,
- context: context
- };
- }
- },
- {
-
- type: Twig.logic.type.setcapture,
- regex: /^set\s+([a-zA-Z0-9_,\s]+)$/ ,
- next: [
- Twig.logic.type.endset
- ],
- open: true ,
- compile: function (token) {
- var key = token.match[1 ].trim();
-
- token.key = key;
-
- delete token.match;
- return token;
- },
- parse: function (token, context, continue_chain) {
-
- var value = Twig.parse.apply(this , [token.output, context]),
- key = token.key;
-
-
-
-
-
-
-
-
-
set on both the global and local context
-
-
-
- this .context[key] = value;
- context[key] = value;
-
- return {
- chain: continue_chain,
- context: context
- };
- }
- },
- {
-
- type: Twig.logic.type.endset,
- regex: /^endset$/ ,
- next: [ ],
- open: false
- },
- {
-
- type: Twig.logic.type.filter,
- regex: /^filter\s+(.+)$/ ,
- next: [
- Twig.logic.type.endfilter
- ],
- open: true ,
- compile: function (token) {
- var expression = "|" + token.match[1 ].trim();
-
-
-
-
-
-
-
-
-
Compile the expression.
-
-
-
- token.stack = Twig.expression.compile.apply(this , [{
- type: Twig.expression.type.expression,
- value: expression
- }]).stack;
- delete token.match;
- return token;
- },
- parse: function (token, context, chain) {
- var unfiltered = Twig.parse.apply(this , [token.output, context]),
- stack = [{
- type: Twig.expression.type.string,
- value: unfiltered
- }].concat(token.stack);
-
- var output = Twig.expression.parse.apply(this , [stack, context]);
-
- return {
- chain: chain,
- output: output
- };
- }
- },
- {
-
- type: Twig.logic.type.endfilter,
- regex: /^endfilter$/ ,
- next: [ ],
- open: false
- },
- {
-
- type: Twig.logic.type.block,
- regex: /^block\s+([a-zA-Z0-9_]+)$/ ,
- next: [
- Twig.logic.type.endblock
- ],
- open: true ,
- compile: function (token) {
- token.block = token.match[1 ].trim();
- delete token.match;
- return token;
- },
- parse: function (token, context, chain) {
- var block_output = "" ,
- output = "" ,
- hasParent = this .blocks[token.block] && this .blocks[token.block].indexOf(Twig.placeholders.parent) > -1 ;
-
-
-
-
-
-
-
-
-
Don't override previous blocks
-Loops should be exempted as well.
-
-
-
- if (this .blocks[token.block] === undefined || hasParent || context.loop) {
- block_output = Twig.expression.parse.apply(this , [{
- type: Twig.expression.type.string,
- value: Twig.parse.apply(this , [token.output, context])
- }, context]);
-
- if (hasParent) {
- this .blocks[token.block] = this .blocks[token.block].replace(Twig.placeholders.parent, block_output);
- } else {
- this .blocks[token.block] = block_output;
- }
- }
-
-
-
-
-
-
-
-
-
Check if a child block has been set from a template extending this one.
-
-
-
- if (this .child.blocks[token.block]) {
- output = this .child.blocks[token.block];
- } else {
- output = this .blocks[token.block];
- }
-
- return {
- chain: chain,
- output: output
- };
- }
- },
- {
-
- type: Twig.logic.type.endblock,
- regex: /^endblock(?:\s+([a-zA-Z0-9_]+))?$/ ,
- next: [ ],
- open: false
- },
- {
-
- type: Twig.logic.type.extends_,
- regex: /^extends\s+(.+)$/ ,
- next: [ ],
- open: true ,
- compile: function (token) {
- var expression = token.match[1 ].trim();
- delete token.match;
-
- token.stack = Twig.expression.compile.apply(this , [{
- type: Twig.expression.type.expression,
- value: expression
- }]).stack;
-
- return token;
- },
- parse: function (token, context, chain) {
-
-
-
-
-
-
-
-
-
Resolve filename
-
-
-
- var file = Twig.expression.parse.apply(this , [token.stack, context]);
-
-
-
-
-
-
-
-
-
Set parent template
-
-
-
- this .extend = file;
-
- return {
- chain: chain,
- output: ''
- };
- }
- },
- {
-
- type: Twig.logic.type.use,
- regex: /^use\s+(.+)$/ ,
- next: [ ],
- open: true ,
- compile: function (token) {
- var expression = token.match[1 ].trim();
- delete token.match;
-
- token.stack = Twig.expression.compile.apply(this , [{
- type: Twig.expression.type.expression,
- value: expression
- }]).stack;
-
- return token;
- },
- parse: function (token, context, chain) {
-
-
-
-
-
-
-
-
-
Resolve filename
-
-
-
- var file = Twig.expression.parse.apply(this , [token.stack, context]);
-
-
-
-
-
-
-
- this .importBlocks(file);
-
- return {
- chain: chain,
- output: ''
- };
- }
- },
- {
-
- type: Twig.logic.type.include,
- regex: /^include\s+(ignore missing\s+)?(.+?)\s*(?:with\s+(.+?))?\s*(only)?$/ ,
- next: [ ],
- open: true ,
- compile: function (token) {
- var match = token.match,
- includeMissing = match[1 ] !== undefined ,
- expression = match[2 ].trim(),
- withContext = match[3 ],
- only = ((match[4 ] !== undefined ) && match[4 ].length);
-
- delete token.match;
-
- token.only = only;
- token.includeMissing = includeMissing;
-
- token.stack = Twig.expression.compile.apply(this , [{
- type: Twig.expression.type.expression,
- value: expression
- }]).stack;
-
- if (withContext !== undefined ) {
- token.withStack = Twig.expression.compile.apply(this , [{
- type: Twig.expression.type.expression,
- value: withContext.trim()
- }]).stack;
- }
-
- return token;
- },
- parse: function (token, context, chain) {
-
-
-
-
-
-
-
-
-
Resolve filename
-
-
-
- var innerContext = {},
- withContext,
- i,
- template;
-
- if (!token.only) {
- for (i in context) {
- if (context.hasOwnProperty(i))
- innerContext[i] = context[i];
- }
- }
-
- if (token.withStack !== undefined ) {
- withContext = Twig.expression.parse.apply(this , [token.withStack, context]);
-
- for (i in withContext) {
- if (withContext.hasOwnProperty(i))
- innerContext[i] = withContext[i];
- }
- }
-
- var file = Twig.expression.parse.apply(this , [token.stack, innerContext]);
-
-
-
-
-
-
-
- template = this .importFile(file);
-
- return {
- chain: chain,
- output: template.render(innerContext)
- };
- }
- },
- {
- type: Twig.logic.type.spaceless,
- regex: /^spaceless$/ ,
- next: [
- Twig.logic.type.endspaceless
- ],
- open: true ,
-
-
-
-
-
-
-
-
-
Parse the html and return it without any spaces between tags
-
-
-
- parse: function (token, context, chain) {
- var
- unfiltered = Twig.parse.apply(this , [token.output, context]),
-
-
-
-
-
-
-
-
-
A regular expression to find closing and opening tags with spaces between them
-
-
-
- rBetweenTagSpaces = />\s+</g ,
-
-
-
-
-
-
-
-
-
Replace all space between closing and opening html tags
-
-
-
- output = unfiltered.replace(rBetweenTagSpaces,'><' ).trim();
-
- return {
- chain: chain,
- output: output
- };
- }
- },
-
-
-
-
-
-
-
-
-
Add the {% endspaceless %} token
-
-
-
- {
- type: Twig.logic.type.endspaceless,
- regex: /^endspaceless$/ ,
- next: [ ],
- open: false
- },
- {
-
- type: Twig.logic.type.macro,
- regex: /^macro\s+([a-zA-Z0-9_]+)\s?\((([a-zA-Z0-9_]+(,\s?)?)*)\)$/ ,
- next: [
- Twig.logic.type.endmacro
- ],
- open: true ,
- compile: function (token) {
- var macroName = token.match[1 ],
- parameters = token.match[2 ].split(/[ ,]+/ );
-
-
-
-
-
-
-
-
-
TODO: Clean up duplicate check
-
-
-
- for (var i=0 ; i<parameters.length; i++) {
- for (var j=0 ; j<parameters.length; j++){
- if (parameters[i] === parameters[j] && i !== j) {
- throw new Twig.Error("Duplicate arguments for parameter: " + parameters[i]);
- }
- }
- }
-
- token.macroName = macroName;
- token.parameters = parameters;
-
- delete token.match;
- return token;
- },
- parse: function (token, context, chain) {
- var template = this ;
- this .macros[token.macroName] = function () {
-
-
-
-
-
-
-
-
-
Pass global context and other macros
-
-
-
- var macroContext = {
- _self: template.macros
- }
-
-
-
-
-
-
-
-
-
Add parameters from context to macroContext
-
-
-
- for (var i=0 ; i<token.parameters.length; i++) {
- var prop = token.parameters[i];
- if (typeof arguments[i] !== 'undefined' ) {
- macroContext[prop] = arguments[i];
- } else {
- macroContext[prop] = undefined ;
- }
- }
-
-
-
-
-
-
-
- return Twig.parse.apply(template, [token.output, macroContext])
- };
-
- return {
- chain: chain,
- output: ''
- };
-
- }
- },
- {
-
- type: Twig.logic.type.endmacro,
- regex: /^endmacro$/ ,
- next: [ ],
- open: false
- },
- {
-
- type: Twig.logic.type.import_,
- regex: /^import\s+(.+)\s+as\s+([a-zA-Z0-9_]+)$/ ,
- next: [ ],
- open: true ,
- compile: function (token) {
- var expression = token.match[1 ].trim(),
- contextName = token.match[2 ].trim();
- delete token.match;
-
- token.expression = expression;
- token.contextName = contextName;
-
- token.stack = Twig.expression.compile.apply(this , [{
- type: Twig.expression.type.expression,
- value: expression
- }]).stack;
-
- return token;
- },
- parse: function (token, context, chain) {
- if (token.expression !== "_self" ) {
- var file = Twig.expression.parse.apply(this , [token.stack, context]);
- var template = this .importMacros(file || token.expression);
- context[token.contextName] = template.render({}, {output: 'macros' });
- }
- else {
- context[token.contextName] = this .macros;
- }
-
- return {
- chain: chain,
- output: ''
- }
-
- }
- },
- {
-
- type: Twig.logic.type.from,
- regex: /^from\s+(.+)\s+import\s+([a-zA-Z0-9_, ]+)$/ ,
- next: [ ],
- open: true ,
- compile: function (token) {
- var expression = token.match[1 ].trim(),
- macroExpressions = token.match[2 ].trim().split(/[ ,]+/ ),
- macroNames = {};
-
- for (var i=0 ; i<macroExpressions.length; i++) {
- var res = macroExpressions[i];
-
-
-
-
-
-
-
-
-
match function as variable
-
-
-
- var macroMatch = res.match(/^([a-zA-Z0-9_]+)\s+(.+)\s+as\s+([a-zA-Z0-9_]+)$/ );
- if (macroMatch) {
- macroNames[macroMatch[1 ].trim()] = macroMatch[2 ].trim();
- }
- else if (res.match(/^([a-zA-Z0-9_]+)$/ )) {
- macroNames[res] = res;
- }
- else {
-
-
-
-
-
-
-
- }
-
- }
-
- delete token.match;
-
- token.expression = expression;
- token.macroNames = macroNames;
-
- token.stack = Twig.expression.compile.apply(this , [{
- type: Twig.expression.type.expression,
- value: expression
- }]).stack;
-
- return token;
- },
- parse: function (token, context, chain) {
- var macros;
-
- if (token.expression !== "_self" ) {
- var file = Twig.expression.parse.apply(this , [token.stack, context]);
- var template = this .importMacros(file || token.expression);
- macros = template.render({}, {output: 'macros' });
- }
- else {
- macros = this .macros;
- }
-
- for (var macroName in token.macroNames) {
- if (macros.hasOwnProperty(macroName)) {
- context[token.macroNames[macroName]] = macros[macroName];
- }
- }
-
- return {
- chain: chain,
- output: ''
- }
-
- }
- }
-
- ];
-
-
-
- Twig.logic.handler = {};
-
-
- Twig.logic.extendType = function (type, value) {
- value = value || ("Twig.logic.type" + type);
- Twig.logic.type[type] = value;
- };
-
-
- Twig.logic.extend = function (definition) {
-
- if (!definition.type) {
- throw new Twig.Error("Unable to extend logic definition. No type provided for " + definition);
- }
- if (Twig.logic.type[definition.type]) {
- throw new Twig.Error("Unable to extend logic definitions. Type " +
- definition.type + " is already defined." );
- } else {
- Twig.logic.extendType(definition.type);
- }
- Twig.logic.handler[definition.type] = definition;
- };
-
-
-
-
-
-
-
-
-
Extend with built-in expressions
-
-
-
- while (Twig.logic.definitions.length > 0 ) {
- Twig.logic.extend(Twig.logic.definitions.shift());
- }
-
-
- Twig.logic.compile = function (raw_token) {
- var expression = raw_token.value.trim(),
- token = Twig.logic.tokenize.apply(this , [expression]),
- token_template = Twig.logic.handler[token.type];
-
-
-
-
-
-
-
-
-
Check if the token needs compiling
-
-
-
- if (token_template.compile) {
- token = token_template.compile.apply(this , [token]);
- Twig.log.trace("Twig.logic.compile: " , "Compiled logic token to " , token);
- }
-
- return token;
- };
-
-
- Twig.logic.tokenize = function (expression) {
- var token = {},
- token_template_type = null ,
- token_type = null ,
- token_regex = null ,
- regex_array = null ,
- regex = null ,
- match = null ;
-
-
-
-
-
-
-
-
-
Ignore whitespace around expressions.
-
-
-
- expression = expression.trim();
-
- for (token_template_type in Twig.logic.handler) {
- if (Twig.logic.handler.hasOwnProperty(token_template_type)) {
-
-
-
-
-
-
-
-
-
Get the type and regex for this template type
-
-
-
- token_type = Twig.logic.handler[token_template_type].type;
- token_regex = Twig.logic.handler[token_template_type].regex;
-
-
-
-
-
-
-
-
-
Handle multiple regular expressions per type.
-
-
-
- regex_array = [];
- if (token_regex instanceof Array) {
- regex_array = token_regex;
- } else {
- regex_array.push(token_regex);
- }
-
-
-
-
-
-
-
-
-
Check regular expressions in the order they were specified in the definition.
-
-
-
- while (regex_array.length > 0 ) {
- regex = regex_array.shift();
- match = regex.exec(expression.trim());
- if (match !== null ) {
- token.type = token_type;
- token.match = match;
- Twig.log.trace("Twig.logic.tokenize: " , "Matched a " , token_type, " regular expression of " , match);
- return token;
- }
- }
- }
- }
-
-
-
-
-
-
-
-
-
No regex matches
-
-
-
- throw new Twig.Error("Unable to parse '" + expression.trim() + "'" );
- };
-
-
- Twig.logic.parse = function (token, context, chain) {
- var output = '' ,
- token_template;
-
- context = context || { };
-
- Twig.log.debug("Twig.logic.parse: " , "Parsing logic token " , token);
-
- token_template = Twig.logic.handler[token.type];
-
- if (token_template.parse) {
- output = token_template.parse.apply(this , [token, context, chain]);
- }
- return output;
- };
-
- return Twig;
-
-})(Twig || { });
-
-
-
-
-
-
-
-
-
Twig.js
-Copyright (c) 2011-2013 John Roepke
-Available under the BSD 2-Clause License
-https://github.com/justjohn/twig.js
-
twig.expression.js
-
This file handles tokenizing, compiling and parsing expressions.
-
-
-
- var Twig = (function (Twig) {
- "use strict" ;
-
-
- Twig.expression = { };
-
-
- Twig.expression.reservedWords = [
- "true" , "false" , "null" , "_context"
- ];
-
-
- Twig.expression.type = {
- comma: 'Twig.expression.type.comma' ,
- operator: {
- unary: 'Twig.expression.type.operator.unary' ,
- binary: 'Twig.expression.type.operator.binary'
- },
- string: 'Twig.expression.type.string' ,
- bool: 'Twig.expression.type.bool' ,
- array: {
- start: 'Twig.expression.type.array.start' ,
- end: 'Twig.expression.type.array.end'
- },
- object: {
- start: 'Twig.expression.type.object.start' ,
- end: 'Twig.expression.type.object.end'
- },
- parameter: {
- start: 'Twig.expression.type.parameter.start' ,
- end: 'Twig.expression.type.parameter.end'
- },
- key: {
- period: 'Twig.expression.type.key.period' ,
- brackets: 'Twig.expression.type.key.brackets'
- },
- filter: 'Twig.expression.type.filter' ,
- _function: 'Twig.expression.type._function' ,
- variable: 'Twig.expression.type.variable' ,
- number: 'Twig.expression.type.number' ,
- _null: 'Twig.expression.type.null' ,
- context: 'Twig.expression.type.context' ,
- test: 'Twig.expression.type.test'
- };
-
- Twig.expression.set = {
-
-
-
-
-
-
-
-
-
What can follow an expression (in general)
-
-
-
- operations: [
- Twig.expression.type.filter,
- Twig.expression.type.operator.unary,
- Twig.expression.type.operator.binary,
- Twig.expression.type.array.end,
- Twig.expression.type.object.end,
- Twig.expression.type.parameter.end,
- Twig.expression.type.comma,
- Twig.expression.type.test
- ],
- expressions: [
- Twig.expression.type._function,
- Twig.expression.type.bool,
- Twig.expression.type.string,
- Twig.expression.type.variable,
- Twig.expression.type.number,
- Twig.expression.type._null,
- Twig.expression.type.context,
- Twig.expression.type.parameter.start,
- Twig.expression.type.array.start,
- Twig.expression.type.object.start
- ]
- };
-
-
-
-
-
-
-
-
-
Most expressions allow a '.' or '[' after them, so we provide a convenience set
-
-
-
- Twig.expression.set.operations_extended = Twig.expression.set.operations.concat([
- Twig.expression.type.key.period,
- Twig.expression.type.key.brackets]);
-
-
-
-
-
-
-
-
-
Some commonly used compile and parse functions.
-
-
-
- Twig.expression.fn = {
- compile: {
- push: function (token, stack, output) {
- output.push(token);
- },
- push_both: function (token, stack, output) {
- output.push(token);
- stack.push(token);
- }
- },
- parse: {
- push: function (token, stack, context) {
- stack.push(token);
- },
- push_value: function (token, stack, context) {
- stack.push(token.value);
- }
- }
- };
-
-
-
-
-
-
-
-
-
The regular expressions and compile/parse logic used to match tokens in expressions.
-
Properties:
-
type: The type of expression this matches
-
- regex: One or more regular expressions that matche the format of the token.
-
- next: Valid tokens that can occur next in the expression.
-
Functions:
-
compile: A function that compiles the raw regular expression match into a token.
-
- parse: A function that parses the compiled token into output.
-
-
-
- Twig.expression.definitions = [
- {
- type: Twig.expression.type.test,
- regex: /^is\s+(not)?\s*([a-zA-Z_][a-zA-Z0-9_]*)/ ,
- next: Twig.expression.set.operations.concat([Twig.expression.type.parameter.start]),
- compile: function (token, stack, output) {
- token.filter = token.match[2 ];
- token.modifier = token.match[1 ];
- delete token.match;
- delete token.value;
- output.push(token);
- },
- parse: function (token, stack, context) {
- var value = stack.pop(),
- params = token.params && Twig.expression.parse.apply(this , [token.params, context]),
- result = Twig.test(token.filter, value, params);
-
- if (token.modifier == 'not' ) {
- stack.push(!result);
- } else {
- stack.push(result);
- }
- }
- },
- {
- type: Twig.expression.type.comma,
-
-
-
-
-
-
-
- regex: /^,/ ,
- next: Twig.expression.set.expressions.concat([Twig.expression.type.array.end, Twig.expression.type.object.end]),
- compile: function (token, stack, output) {
- var i = stack.length - 1 ,
- stack_token;
-
- delete token.match;
- delete token.value;
-
-
-
-
-
-
-
-
-
pop tokens off the stack until the start of the object
-
-
-
- for (;i >= 0 ; i--) {
- stack_token = stack.pop();
- if (stack_token.type === Twig.expression.type.object.start
- || stack_token.type === Twig.expression.type.parameter.start
- || stack_token.type === Twig.expression.type.array.start) {
- stack.push(stack_token);
- break ;
- }
- output.push(stack_token);
- }
- output.push(token);
- }
- },
- {
- type: Twig.expression.type.operator.binary,
-
-
-
-
-
-
-
-
-
Match any of +, , /, -, %, ~, <, <=, >, >=, !=, ==, * , ?, :, and, or, not
-
-
-
- regex: /(^[\+\-~%\?\:]|^[!=]==?|^[!<>]=?|^\*\*?|^\/\/?|^and\s+|^or\s+|^in\s+|^not in\s+|^\.\.)/ ,
- next: Twig.expression.set.expressions.concat([Twig.expression.type.operator.unary]),
- compile: function (token, stack, output) {
- delete token.match;
-
- token.value = token.value.trim();
- var value = token.value,
- operator = Twig.expression.operator.lookup(value, token);
-
- Twig.log.trace("Twig.expression.compile: " , "Operator: " , operator, " from " , value);
-
- while (stack.length > 0 &&
- (stack[stack.length-1 ].type == Twig.expression.type.operator.unary || stack[stack.length-1 ].type == Twig.expression.type.operator.binary) &&
- (
- (operator.associativity === Twig.expression.operator.leftToRight &&
- operator.precidence >= stack[stack.length-1 ].precidence) ||
-
- (operator.associativity === Twig.expression.operator.rightToLeft &&
- operator.precidence > stack[stack.length-1 ].precidence)
- )
- ) {
- var temp = stack.pop();
- output.push(temp);
- }
-
- if (value === ":" ) {
-
-
-
-
-
-
-
-
-
Check if this is a ternary or object key being set
-
-
-
- if (stack[stack.length - 1 ] && stack[stack.length-1 ].value === "?" ) {
-
-
-
-
-
-
-
-
-
Continue as normal for a ternary
-
-
-
-
-
-
-
-
-
-
-
-
-
This is not a ternary so we push the token to the output where it can be handled
- when the assocated object is closed.
-
-
-
- var key_token = output.pop();
-
- if (key_token.type === Twig.expression.type.string ||
- key_token.type === Twig.expression.type.variable ||
- key_token.type === Twig.expression.type.number) {
- token.key = key_token.value;
-
- } else {
- throw new Twig.Error("Unexpected value before ':' of " + key_token.type + " = " + key_token.value);
- }
-
- output.push(token);
- return ;
- }
- } else {
- stack.push(operator);
- }
- },
- parse: function (token, stack, context) {
- if (token.key) {
-
-
-
-
-
-
-
-
-
handle ternary ':' operator
-
-
-
- stack.push(token);
- } else {
- Twig.expression.operator.parse(token.value, stack);
- }
- }
- },
- {
- type: Twig.expression.type.operator.unary,
-
-
-
-
-
-
-
-
-
Match any of not
-
-
-
- regex: /(^not\s+)/ ,
- next: Twig.expression.set.expressions,
- compile: function (token, stack, output) {
- delete token.match;
-
- token.value = token.value.trim();
- var value = token.value,
- operator = Twig.expression.operator.lookup(value, token);
-
- Twig.log.trace("Twig.expression.compile: " , "Operator: " , operator, " from " , value);
-
- while (stack.length > 0 &&
- (stack[stack.length-1 ].type == Twig.expression.type.operator.unary || stack[stack.length-1 ].type == Twig.expression.type.operator.binary) &&
- (
- (operator.associativity === Twig.expression.operator.leftToRight &&
- operator.precidence >= stack[stack.length-1 ].precidence) ||
-
- (operator.associativity === Twig.expression.operator.rightToLeft &&
- operator.precidence > stack[stack.length-1 ].precidence)
- )
- ) {
- var temp = stack.pop();
- output.push(temp);
- }
-
- stack.push(operator);
- },
- parse: function (token, stack, context) {
- Twig.expression.operator.parse(token.value, stack);
- }
- },
- {
-
- type: Twig.expression.type.string,
-
-
-
-
-
-
-
- regex: /^(["'])(?:(?=(\\?))\2.)*?\1/ ,
- next: Twig.expression.set.operations,
- compile: function (token, stack, output) {
- var value = token.value;
- delete token.match
-
-
-
-
-
-
-
-
-
Remove the quotes from the string
-
-
-
- if (value.substring(0 , 1 ) === '"' ) {
- value = value.replace('\\"' , '"' );
- } else {
- value = value.replace("\\'" , "'" );
- }
- token.value = value.substring(1 , value.length-1 ).replace( /\\n/g , "\n" ).replace( /\\r/g , "\r" );
- Twig.log.trace("Twig.expression.compile: " , "String value: " , token.value);
- output.push(token);
- },
- parse: Twig.expression.fn.parse.push_value
- },
- {
-
- type: Twig.expression.type.parameter.start,
- regex: /^\(/ ,
- next: Twig.expression.set.expressions.concat([Twig.expression.type.parameter.end]),
- compile: Twig.expression.fn.compile.push_both,
- parse: Twig.expression.fn.parse.push
- },
- {
-
- type: Twig.expression.type.parameter.end,
- regex: /^\)/ ,
- next: Twig.expression.set.operations_extended,
- compile: function (token, stack, output) {
- var stack_token,
- end_token = token;
-
- stack_token = stack.pop();
- while (stack.length > 0 && stack_token.type != Twig.expression.type.parameter.start) {
- output.push(stack_token);
- stack_token = stack.pop();
- }
-
-
-
-
-
-
-
-
-
Move contents of parens into preceding filter
-
-
-
- var param_stack = [];
- while (token.type !== Twig.expression.type.parameter.start) {
-
-
-
-
-
-
-
-
-
Add token to arguments stack
-
-
-
- param_stack.unshift(token);
- token = output.pop();
- }
- param_stack.unshift(token);
-
- var is_expression = false ;
-
-
-
-
-
-
-
-
-
Get the token preceding the parameters
-
-
-
- token = output[output.length-1 ];
-
- if (token === undefined ||
- (token.type !== Twig.expression.type._function &&
- token.type !== Twig.expression.type.filter &&
- token.type !== Twig.expression.type.test &&
- token.type !== Twig.expression.type.key.brackets &&
- token.type !== Twig.expression.type.key.period)) {
-
- end_token.expression = true ;
-
-
-
-
-
-
-
-
-
remove start and end token from stack
-
-
-
- param_stack.pop();
- param_stack.shift();
-
- end_token.params = param_stack;
-
- output.push(end_token);
-
- } else {
- end_token.expression = false ;
- token.params = param_stack;
- }
- },
- parse: function (token, stack, context) {
- var new_array = [],
- array_ended = false ,
- value = null ;
-
- if (token.expression) {
- value = Twig.expression.parse.apply(this , [token.params, context])
- stack.push(value);
-
- } else {
-
- while (stack.length > 0 ) {
- value = stack.pop();
-
-
-
-
-
-
-
-
-
Push values into the array until the start of the array
-
-
-
- if (value && value.type && value.type == Twig.expression.type.parameter.start) {
- array_ended = true ;
- break ;
- }
- new_array.unshift(value);
- }
-
- if (!array_ended) {
- throw new Twig.Error("Expected end of parameter set." );
- }
-
- stack.push(new_array);
- }
- }
- },
- {
-
- type: Twig.expression.type.array.start,
- regex: /^\[/ ,
- next: Twig.expression.set.expressions.concat([Twig.expression.type.array.end]),
- compile: Twig.expression.fn.compile.push_both,
- parse: Twig.expression.fn.parse.push
- },
- {
-
- type: Twig.expression.type.array.end,
- regex: /^\]/ ,
- next: Twig.expression.set.operations_extended,
- compile: function (token, stack, output) {
- var i = stack.length - 1 ,
- stack_token;
-
-
-
-
-
-
-
-
-
pop tokens off the stack until the start of the object
-
-
-
- for (;i >= 0 ; i--) {
- stack_token = stack.pop();
- if (stack_token.type === Twig.expression.type.array.start) {
- break ;
- }
- output.push(stack_token);
- }
- output.push(token);
- },
- parse: function (token, stack, context) {
- var new_array = [],
- array_ended = false ,
- value = null ;
-
- while (stack.length > 0 ) {
- value = stack.pop();
-
-
-
-
-
-
-
-
-
Push values into the array until the start of the array
-
-
-
- if (value.type && value.type == Twig.expression.type.array.start) {
- array_ended = true ;
- break ;
- }
- new_array.unshift(value);
- }
- if (!array_ended) {
- throw new Twig.Error("Expected end of array." );
- }
-
- stack.push(new_array);
- }
- },
-
-
-
-
-
-
-
-
-
Token that represents the start of a hash map '}'
-
Hash maps take the form:
- { "key": 'value', "another_key": item }
-
Keys must be quoted (either single or double) and values can be any expression.
-
-
-
- {
- type: Twig.expression.type.object.start,
- regex: /^\{/ ,
- next: Twig.expression.set.expressions.concat([Twig.expression.type.object.end]),
- compile: Twig.expression.fn.compile.push_both,
- parse: Twig.expression.fn.parse.push
- },
-
-
-
-
-
-
-
-
-
Token that represents the end of a Hash Map '}'
-
This is where the logic for building the internal
-representation of a hash map is defined.
-
-
-
- {
- type: Twig.expression.type.object.end,
- regex: /^\}/ ,
- next: Twig.expression.set.operations_extended,
- compile: function (token, stack, output) {
- var i = stack.length-1 ,
- stack_token;
-
-
-
-
-
-
-
-
-
pop tokens off the stack until the start of the object
-
-
-
- for (;i >= 0 ; i--) {
- stack_token = stack.pop();
- if (stack_token && stack_token.type === Twig.expression.type.object.start) {
- break ;
- }
- output.push(stack_token);
- }
- output.push(token);
- },
- parse: function (end_token, stack, context) {
- var new_object = {},
- object_ended = false ,
- token = null ,
- token_key = null ,
- has_value = false ,
- value = null ;
-
- while (stack.length > 0 ) {
- token = stack.pop();
-
-
-
-
-
-
-
-
-
Push values into the array until the start of the object
-
-
-
- if (token && token.type && token.type === Twig.expression.type.object.start) {
- object_ended = true ;
- break ;
- }
- if (token && token.type && (token.type === Twig.expression.type.operator.binary || token.type === Twig.expression.type.operator.unary) && token.key) {
- if (!has_value) {
- throw new Twig.Error("Missing value for key '" + token.key + "' in object definition." );
- }
- new_object[token.key] = value;
-
-
-
-
-
-
-
-
-
Preserve the order that elements are added to the map
-This is necessary since JavaScript objects don't
-guarantee the order of keys
-
-
-
- if (new_object._keys === undefined ) new_object._keys = [];
- new_object._keys.unshift(token.key);
-
-
-
-
-
-
-
-
-
reset value check
-
-
-
- value = null ;
- has_value = false ;
-
- } else {
- has_value = true ;
- value = token;
- }
- }
- if (!object_ended) {
- throw new Twig.Error("Unexpected end of object." );
- }
-
- stack.push(new_object);
- }
- },
-
-
-
-
-
-
-
-
-
Token representing a filter
-
Filters can follow any expression and take the form:
- expression|filter(optional, args)
-
Filter parsing is done in the Twig.filters namespace.
-
-
-
- {
- type: Twig.expression.type.filter,
-
-
-
-
-
-
-
-
-
match a | then a letter or , then any number of letters, numbers, or -
-
-
-
- regex: /^\|\s?([a-zA-Z_][a-zA-Z0-9_\-]*)/ ,
- next: Twig.expression.set.operations_extended.concat([
- Twig.expression.type.parameter.start]),
- compile: function (token, stack, output) {
- token.value = token.match[1 ];
- output.push(token);
- },
- parse: function (token, stack, context) {
- var input = stack.pop(),
- params = token.params && Twig.expression.parse.apply(this , [token.params, context]);
-
- stack.push(Twig.filter.apply(this , [token.value, input, params]));
- }
- },
- {
- type: Twig.expression.type._function,
-
-
-
-
-
-
-
-
-
match any letter or , then any number of letters, numbers, or - followed by (
-
-
-
- regex: /^([a-zA-Z_][a-zA-Z0-9_]*)\s*\(/ ,
- next: Twig.expression.type.parameter.start,
- transform: function (match, tokens) {
- return '(' ;
- },
- compile: function (token, stack, output) {
- var fn = token.match[1 ];
- token.fn = fn;
-
-
-
-
-
-
-
- delete token.match;
- delete token.value;
-
- output.push(token);
- },
- parse: function (token, stack, context) {
- var params = token.params && Twig.expression.parse.apply(this , [token.params, context]),
- fn = token.fn,
- value;
-
- if (Twig.functions[fn]) {
-
-
-
-
-
-
-
-
-
Get the function from the built-in functions
-
-
-
- value = Twig.functions[fn].apply(this , params);
-
- } else if (typeof context[fn] == 'function' ) {
-
-
-
-
-
-
-
-
-
Get the function from the user/context defined functions
-
-
-
- value = context[fn].apply(context, params);
-
- } else {
- throw new Twig.Error(fn + ' function does not exist and is not defined in the context' );
- }
-
- stack.push(value);
- }
- },
-
-
-
-
-
-
-
-
-
Token representing a variable.
-
Variables can contain letters, numbers, underscores and
-dashes, but must start with a letter or underscore.
-
Variables are retrieved from the render context and take
-the value of 'undefined' if the given variable doesn't
-exist in the context.
-
-
-
- {
- type: Twig.expression.type.variable,
-
-
-
-
-
-
-
-
-
match any letter or , then any number of letters, numbers, or -
-
-
-
- regex: /^[a-zA-Z_][a-zA-Z0-9_]*/ ,
- next: Twig.expression.set.operations_extended.concat([
- Twig.expression.type.parameter.start]),
- compile: Twig.expression.fn.compile.push,
- validate: function (match, tokens) {
- return (Twig.indexOf(Twig.expression.reservedWords, match[0 ]) < 0 );
- },
- parse: function (token, stack, context) {
-
-
-
-
-
-
-
-
-
Get the variable from the context
-
-
-
- var value = Twig.expression.resolve(context[token.value], context);
- stack.push(value);
- }
- },
- {
- type: Twig.expression.type.key.period,
- regex: /^\.([a-zA-Z0-9_]+)/ ,
- next: Twig.expression.set.operations_extended.concat([
- Twig.expression.type.parameter.start]),
- compile: function (token, stack, output) {
- token.key = token.match[1 ];
- delete token.match;
- delete token.value;
-
- output.push(token);
- },
- parse: function (token, stack, context) {
- var params = token.params && Twig.expression.parse.apply(this , [token.params, context]),
- key = token.key,
- object = stack.pop(),
- value;
-
- if (object === null || object === undefined ) {
- if (this .options.strict_variables) {
- throw new Twig.Error("Can't access a key " + key + " on an null or undefined object." );
- } else {
- return null ;
- }
- }
-
- var capitalize = function (value) {return value.substr(0 , 1 ).toUpperCase() + value.substr(1 );};
-
-
-
-
-
-
-
-
-
Get the variable from the context
-
-
-
- if (typeof object === 'object' && key in object) {
- value = object[key];
- } else if (object["get" +capitalize(key)] !== undefined ) {
- value = object["get" +capitalize(key)];
- } else if (object["is" +capitalize(key)] !== undefined ) {
- value = object["is" +capitalize(key)];
- } else {
- value = null ;
- }
- stack.push(Twig.expression.resolve(value, object, params));
- }
- },
- {
- type: Twig.expression.type.key.brackets,
- regex: /^\[([^\]]*)\]/ ,
- next: Twig.expression.set.operations_extended.concat([
- Twig.expression.type.parameter.start]),
- compile: function (token, stack, output) {
- var match = token.match[1 ];
- delete token.value;
- delete token.match;
-
-
-
-
-
-
-
-
-
The expression stack for the key
-
-
-
- token.stack = Twig.expression.compile({
- value: match
- }).stack;
-
- output.push(token);
- },
- parse: function (token, stack, context) {
-
-
-
-
-
-
-
- var params = token.params && Twig.expression.parse.apply(this , [token.params, context]),
- key = Twig.expression.parse.apply(this , [token.stack, context]),
- object = stack.pop(),
- value;
-
- if (object === null || object === undefined ) {
- if (this .options.strict_variables) {
- throw new Twig.Error("Can't access a key " + key + " on an null or undefined object." );
- } else {
- return null ;
- }
- }
-
-
-
-
-
-
-
-
-
Get the variable from the context
-
-
-
- if (typeof object === 'object' && key in object) {
- value = object[key];
- } else {
- value = null ;
- }
- stack.push(Twig.expression.resolve(value, object, params));
- }
- },
- {
-
- type: Twig.expression.type._null,
-
-
-
-
-
-
-
- regex: /^null/ ,
- next: Twig.expression.set.operations,
- compile: function (token, stack, output) {
- delete token.match;
- token.value = null ;
- output.push(token);
- },
- parse: Twig.expression.fn.parse.push_value
- },
- {
-
- type: Twig.expression.type.context,
- regex: /^_context/ ,
- next: Twig.expression.set.operations_extended.concat([
- Twig.expression.type.parameter.start]),
- compile: Twig.expression.fn.compile.push,
- parse: function (token, stack, context) {
- stack.push(context);
- }
- },
- {
-
- type: Twig.expression.type.number,
-
-
-
-
-
-
-
- regex: /^\-?\d+(\.\d+)?/ ,
- next: Twig.expression.set.operations,
- compile: function (token, stack, output) {
- token.value = Number(token.value);
- output.push(token);
- },
- parse: Twig.expression.fn.parse.push_value
- },
- {
-
- type: Twig.expression.type.bool,
- regex: /^(true|false)/ ,
- next: Twig.expression.set.operations,
- compile: function (token, stack, output) {
- token.value = (token.match[0 ] == "true" );
- delete token.match;
- output.push(token);
- },
- parse: Twig.expression.fn.parse.push_value
- }
- ];
-
-
- Twig.expression.resolve = function (value, context, params) {
- if (typeof value == 'function' ) {
- return value.apply(context, params || []);
- } else {
- return value;
- }
- };
-
-
- Twig.expression.handler = {};
-
-
- Twig.expression.extendType = function (type) {
- Twig.expression.type[type] = "Twig.expression.type." + type;
- };
-
-
- Twig.expression.extend = function (definition) {
- if (!definition.type) {
- throw new Twig.Error("Unable to extend logic definition. No type provided for " + definition);
- }
- Twig.expression.handler[definition.type] = definition;
- };
-
-
-
-
-
-
-
-
-
Extend with built-in expressions
-
-
-
- while (Twig.expression.definitions.length > 0 ) {
- Twig.expression.extend(Twig.expression.definitions.shift());
- }
-
-
- Twig.expression.tokenize = function (expression) {
- var tokens = [],
-
-
-
-
-
-
-
-
-
Keep an offset of the location in the expression for error messages.
-
-
-
-
-
-
-
-
-
-
-
-
-
The valid next tokens of the previous token
-
-
-
-
-
-
-
-
-
-
-
-
-
Match information
-
-
-
- type, regex, regex_array,
-
-
-
-
-
-
-
-
-
The possible next token for the match
-
-
-
-
-
-
-
-
-
-
-
-
-
Has a match been found from the definitions
-
-
-
- match_found, invalid_matches = [], match_function;
-
- match_function = function () {
- var match = Array.prototype.slice.apply(arguments),
- string = match.pop(),
- offset = match.pop();
-
- Twig.log.trace("Twig.expression.tokenize" ,
- "Matched a " , type, " regular expression of " , match);
-
- if (next && Twig.indexOf(next, type) < 0 ) {
- invalid_matches.push(
- type + " cannot follow a " + tokens[tokens.length - 1 ].type +
- " at template:" + exp_offset + " near '" + match[0 ].substring(0 , 20 ) +
- "...'"
- );
-
-
-
-
-
-
-
-
-
Not a match, don't change the expression
-
-
-
-
-
-
-
-
-
-
-
-
-
Validate the token if a validation function is provided
-
-
-
- if (Twig.expression.handler[type].validate &&
- !Twig.expression.handler[type].validate(match, tokens)) {
- return match[0 ];
- }
-
- invalid_matches = [];
-
- tokens.push({
- type: type,
- value: match[0 ],
- match: match
- });
-
- match_found = true ;
- next = token_next;
- exp_offset += match[0 ].length;
-
-
-
-
-
-
-
-
-
Does the token need to return output back to the expression string
-e.g. a function match of cycle( might return the '(' back to the expression
-This allows look-ahead to differentiate between token types (e.g. functions and variable names)
-
-
-
- if (Twig.expression.handler[type].transform) {
- return Twig.expression.handler[type].transform(match, tokens);
- }
- return '' ;
- };
-
- Twig.log.debug("Twig.expression.tokenize" , "Tokenizing expression " , expression);
-
- while (expression.length > 0 ) {
- expression = expression.trim();
- for (type in Twig.expression.handler) {
- if (Twig.expression.handler.hasOwnProperty(type)) {
- token_next = Twig.expression.handler[type].next;
- regex = Twig.expression.handler[type].regex;
-
-
-
-
-
-
-
-
-
Twig.log.trace("Checking type ", type, " on ", expression);
-
-
-
- if (regex instanceof Array) {
- regex_array = regex;
- } else {
- regex_array = [regex];
- }
-
- match_found = false ;
- while (regex_array.length > 0 ) {
- regex = regex_array.pop();
- expression = expression.replace(regex, match_function);
- }
-
-
-
-
-
-
-
-
-
An expression token has been matched. Break the for loop and start trying to
- match the next template (if expression isn't empty.)
-
-
-
- if (match_found) {
- break ;
- }
- }
- }
- if (!match_found) {
- if (invalid_matches.length > 0 ) {
- throw new Twig.Error(invalid_matches.join(" OR " ));
- } else {
- throw new Twig.Error("Unable to parse '" + expression + "' at template position" + exp_offset);
- }
- }
- }
-
- Twig.log.trace("Twig.expression.tokenize" , "Tokenized to " , tokens);
- return tokens;
- };
-
-
- Twig.expression.compile = function (raw_token) {
- var expression = raw_token.value,
-
-
-
-
-
-
-
-
-
Tokenize expression
-
-
-
- tokens = Twig.expression.tokenize(expression),
- token = null ,
- output = [],
- stack = [],
- token_template = null ;
-
- Twig.log.trace("Twig.expression.compile: " , "Compiling " , expression);
-
-
-
-
-
-
-
- while (tokens.length > 0 ) {
- token = tokens.shift();
- token_template = Twig.expression.handler[token.type];
-
- Twig.log.trace("Twig.expression.compile: " , "Compiling " , token);
-
-
-
-
-
-
-
-
-
Compile the template
-
-
-
- token_template.compile && token_template.compile(token, stack, output);
-
- Twig.log.trace("Twig.expression.compile: " , "Stack is" , stack);
- Twig.log.trace("Twig.expression.compile: " , "Output is" , output);
- }
-
- while (stack.length > 0 ) {
- output.push(stack.pop());
- }
-
- Twig.log.trace("Twig.expression.compile: " , "Final output is" , output);
-
- raw_token.stack = output;
- delete raw_token.value;
-
- return raw_token;
- };
-
-
-
- Twig.expression.parse = function (tokens, context) {
- var that = this ;
-
-
-
-
-
-
-
-
-
If the token isn't an array, make it one.
-
-
-
- if (!(tokens instanceof Array)) {
- tokens = [tokens];
- }
-
-
-
-
-
-
-
-
-
The output stack
-
-
-
- var stack = [],
- token_template = null ;
-
- Twig.forEach(tokens, function (token) {
- token_template = Twig.expression.handler[token.type];
-
- token_template.parse && token_template.parse.apply(that, [token, stack, context]);
- });
-
-
-
-
-
-
-
-
-
Pop the final value off the stack
-
-
-
- return stack.pop();
- };
-
- return Twig;
-
-})( Twig || { } );
-
-
-
-
-
-
-
-
-
Twig.js
-Copyright (c) 2011-2013 John Roepke
-Available under the BSD 2-Clause License
-https://github.com/justjohn/twig.js
-
twig.expression.operator.js
-
This file handles operator lookups and parsing.
-
-
-
- var Twig = (function (Twig) {
- "use strict" ;
-
-
- Twig.expression.operator = {
- leftToRight: 'leftToRight' ,
- rightToLeft: 'rightToLeft'
- };
-
- var containment = function (a, b) {
- if (b.indexOf !== undefined ) {
-
-
-
-
-
-
-
- return a === b || a !== '' && b.indexOf(a) > -1 ;
-
- } else {
- var el;
- for (el in b) {
- if (b.hasOwnProperty(el) && b[el] === a) {
- return true ;
- }
- }
- return false ;
- }
- };
-
-
- Twig.expression.operator.lookup = function (operator, token) {
- switch (operator) {
- case ".." :
- case 'not in' :
- case 'in' :
- token.precidence = 20 ;
- token.associativity = Twig.expression.operator.leftToRight;
- break ;
-
- case ',' :
- token.precidence = 18 ;
- token.associativity = Twig.expression.operator.leftToRight;
- break ;
-
-
-
-
-
-
-
- case '?' :
- case ':' :
- token.precidence = 16 ;
- token.associativity = Twig.expression.operator.rightToLeft;
- break ;
-
- case 'or' :
- token.precidence = 14 ;
- token.associativity = Twig.expression.operator.leftToRight;
- break ;
-
- case 'and' :
- token.precidence = 13 ;
- token.associativity = Twig.expression.operator.leftToRight;
- break ;
-
- case '==' :
- case '!=' :
- token.precidence = 9 ;
- token.associativity = Twig.expression.operator.leftToRight;
- break ;
-
- case '<' :
- case '<=' :
- case '>' :
- case '>=' :
- token.precidence = 8 ;
- token.associativity = Twig.expression.operator.leftToRight;
- break ;
-
-
- case '~' :
- case '+' :
- case '-' :
- token.precidence = 6 ;
- token.associativity = Twig.expression.operator.leftToRight;
- break ;
-
- case '//' :
- case '**' :
- case '*' :
- case '/' :
- case '%' :
- token.precidence = 5 ;
- token.associativity = Twig.expression.operator.leftToRight;
- break ;
-
- case 'not' :
- token.precidence = 3 ;
- token.associativity = Twig.expression.operator.rightToLeft;
- break ;
-
- default :
- throw new Twig.Error(operator + " is an unknown operator." );
- }
- token.operator = operator;
- return token;
- };
-
-
- Twig.expression.operator.parse = function (operator, stack) {
- Twig.log.trace("Twig.expression.operator.parse: " , "Handling " , operator);
- var a, b, c;
- switch (operator) {
- case ':' :
-
-
-
-
-
-
-
- break ;
-
- case '?' :
- c = stack.pop();
- b = stack.pop();
- a = stack.pop();
- if (a) {
- stack.push(b);
- } else {
- stack.push(c);
- }
- break ;
-
- case '+' :
- b = parseFloat(stack.pop());
- a = parseFloat(stack.pop());
- stack.push(a + b);
- break ;
-
- case '-' :
- b = parseFloat(stack.pop());
- a = parseFloat(stack.pop());
- stack.push(a - b);
- break ;
-
- case '*' :
- b = parseFloat(stack.pop());
- a = parseFloat(stack.pop());
- stack.push(a * b);
- break ;
-
- case '/' :
- b = parseFloat(stack.pop());
- a = parseFloat(stack.pop());
- stack.push(a / b);
- break ;
-
- case '//' :
- b = parseFloat(stack.pop());
- a = parseFloat(stack.pop());
- stack.push(parseInt(a / b));
- break ;
-
- case '%' :
- b = parseFloat(stack.pop());
- a = parseFloat(stack.pop());
- stack.push(a % b);
- break ;
-
- case '~' :
- b = stack.pop();
- a = stack.pop();
- stack.push( (a !== undefined ? a.toString() : "" )
- + (b !== undefined ? b.toString() : "" ) );
- break ;
-
- case 'not' :
- case '!' :
- stack.push(!stack.pop());
- break ;
-
- case '<' :
- b = stack.pop();
- a = stack.pop();
- stack.push(a < b);
- break ;
-
- case '<=' :
- b = stack.pop();
- a = stack.pop();
- stack.push(a <= b);
- break ;
-
- case '>' :
- b = stack.pop();
- a = stack.pop();
- stack.push(a > b);
- break ;
-
- case '>=' :
- b = stack.pop();
- a = stack.pop();
- stack.push(a >= b);
- break ;
-
- case '===' :
- b = stack.pop();
- a = stack.pop();
- stack.push(a === b);
- break ;
-
- case '==' :
- b = stack.pop();
- a = stack.pop();
- stack.push(a == b);
- break ;
-
- case '!==' :
- b = stack.pop();
- a = stack.pop();
- stack.push(a !== b);
- break ;
-
- case '!=' :
- b = stack.pop();
- a = stack.pop();
- stack.push(a != b);
- break ;
-
- case 'or' :
- b = stack.pop();
- a = stack.pop();
- stack.push(a || b);
- break ;
-
- case 'and' :
- b = stack.pop();
- a = stack.pop();
- stack.push(a && b);
- break ;
-
- case '**' :
- b = stack.pop();
- a = stack.pop();
- stack.push(Math.pow(a, b));
- break ;
-
-
- case 'not in' :
- b = stack.pop();
- a = stack.pop();
- stack.push( !containment(a, b) );
- break ;
-
- case 'in' :
- b = stack.pop();
- a = stack.pop();
- stack.push( containment(a, b) );
- break ;
-
- case '..' :
- b = stack.pop();
- a = stack.pop();
- stack.push( Twig.functions.range(a, b) );
- break ;
-
- default :
- throw new Twig.Error(operator + " is an unknown operator." );
- }
- };
-
- return Twig;
-
-})( Twig || { } );
-
-
-
-
-
-
-
-
-
Twig.js
-Copyright (c) 2011-2013 John Roepke
-Available under the BSD 2-Clause License
-https://github.com/justjohn/twig.js
-
twig.filters.js
-
This file handles parsing filters.
-
-
-
- var Twig = (function (Twig) {
-
-
-
-
-
-
-
-
-
Determine object type
-
-
-
- function is (type, obj) {
- var clas = Object.prototype.toString.call(obj).slice(8 , -1 );
- return obj !== undefined && obj !== null && clas === type;
- }
-
- Twig.filters = {
-
-
-
-
-
-
-
- upper: function (value) {
- if ( typeof value !== "string" ) {
- return value;
- }
-
- return value.toUpperCase();
- },
- lower: function (value) {
- if ( typeof value !== "string" ) {
- return value;
- }
-
- return value.toLowerCase();
- },
- capitalize: function (value) {
- if ( typeof value !== "string" ) {
- return value;
- }
-
- return value.substr(0 , 1 ).toUpperCase() + value.toLowerCase().substr(1 );
- },
- title: function (value) {
- if ( typeof value !== "string" ) {
- return value;
- }
-
- return value.toLowerCase().replace( /(^|\s)([a-z])/g , function (m, p1, p2) {
- return p1 + p2.toUpperCase();
- });
- },
- length: function (value) {
- if (Twig.lib.is("Array" , value) || typeof value === "string" ) {
- return value.length;
- } else if (Twig.lib.is("Object" , value)) {
- if (value._keys === undefined ) {
- return Object.keys(value).length;
- } else {
- return value._keys.length;
- }
- } else {
- return 0 ;
- }
- },
-
-
-
-
-
-
-
-
-
Array/Object Filters
-
-
-
- reverse: function (value) {
- if (is("Array" , value)) {
- return value.reverse();
- } else if (is("String" , value)) {
- return value.split("" ).reverse().join("" );
- } else if (value instanceof Object) {
- var keys = value._keys || Object.keys(value).reverse();
- value._keys = keys;
- return value;
- }
- },
- sort: function (value) {
- if (is("Array" , value)) {
- return value.sort();
- } else if (value instanceof Object) {
-
-
-
-
-
-
-
-
-
Sorting objects isn't obvious since the order of
-returned keys isn't guaranteedin JavaScript.
-Because of this we use a "hidden" key called _keys to
-store the keys in the order we want to return them.
-
-
-
- delete value._keys;
- var keys = Object.keys(value),
- sorted_keys = keys.sort(function (a, b) {
- return value[a] > value[b];
- });
- value._keys = sorted_keys;
- return value;
- }
- },
- keys: function (value) {
- if (value === undefined || value === null ){
- return ;
- }
-
- var keyset = value._keys || Object.keys(value),
- output = [];
-
- Twig.forEach(keyset, function (key) {
- if (key === "_keys" ) return ;
- if (value.hasOwnProperty(key)) {
- output.push(key);
- }
- });
- return output;
- },
- url_encode: function (value) {
- if (value === undefined || value === null ){
- return ;
- }
-
- return encodeURIComponent(value);
- },
- join: function (value, params) {
- if (value === undefined || value === null ){
- return ;
- }
-
- var join_str = "" ,
- output = [],
- keyset = null ;
-
- if (params && params[0 ]) {
- join_str = params[0 ];
- }
- if (value instanceof Array) {
- output = value;
- } else {
- keyset = value._keys || Object.keys(value);
- Twig.forEach(keyset, function (key) {
- if (key === "_keys" ) return ;
- if (value.hasOwnProperty(key)) {
- output.push(value[key]);
- }
- });
- }
- return output.join(join_str);
- },
- "default" : function (value, params) {
- if (params === undefined || params.length !== 1 ) {
- throw new Twig.Error("default filter expects one argument" );
- }
- if (value === undefined || value === null || value === '' ) {
- return params[0 ];
- } else {
- return value;
- }
- },
- json_encode: function (value) {
- if (value && value.hasOwnProperty( "_keys" ) ) {
- delete value._keys;
- }
- if (value === undefined || value === null ) {
- return "null" ;
- }
- return JSON.stringify(value);
- },
- merge: function (value, params) {
- var obj = [],
- arr_index = 0 ,
- keyset = [];
-
-
-
-
-
-
-
-
-
Check to see if all the objects being merged are arrays
-
-
-
- if (!(value instanceof Array)) {
-
-
-
-
-
-
-
-
-
Create obj as an Object
-
-
-
- obj = { };
- } else {
- Twig.forEach(params, function (param) {
- if (!(param instanceof Array)) {
- obj = { };
- }
- });
- }
- if (!(obj instanceof Array)) {
- obj._keys = [];
- }
-
- if (value instanceof Array) {
- Twig.forEach(value, function (val) {
- if (obj._keys) obj._keys.push(arr_index);
- obj[arr_index] = val;
- arr_index++;
- });
- } else {
- keyset = value._keys || Object.keys(value);
- Twig.forEach(keyset, function (key) {
- obj[key] = value[key];
- obj._keys.push(key);
-
-
-
-
-
-
-
-
-
Handle edge case where a number index in an object is greater than
- the array counter. In such a case, the array counter is increased
- one past the index.
-
Example {{ ["a", "b"]|merge({"4":"value"}, ["c", "d"])
-Without this, d would have an index of "4" and overwrite the value
- of "value"
-
-
-
- var int_key = parseInt(key, 10 );
- if (!isNaN(int_key) && int_key >= arr_index) {
- arr_index = int_key + 1 ;
- }
- });
- }
-
-
-
-
-
-
-
-
-
mixin the merge arrays
-
-
-
- Twig.forEach(params, function (param) {
- if (param instanceof Array) {
- Twig.forEach(param, function (val) {
- if (obj._keys) obj._keys.push(arr_index);
- obj[arr_index] = val;
- arr_index++;
- });
- } else {
- keyset = param._keys || Object.keys(param);
- Twig.forEach(keyset, function (key) {
- if (!obj[key]) obj._keys.push(key);
- obj[key] = param[key];
-
- var int_key = parseInt(key, 10 );
- if (!isNaN(int_key) && int_key >= arr_index) {
- arr_index = int_key + 1 ;
- }
- });
- }
- });
- if (params.length === 0 ) {
- throw new Twig.Error("Filter merge expects at least one parameter" );
- }
-
- return obj;
- },
- date: function (value, params) {
- if (value === undefined ||value === null ){
- return ;
- }
-
- var date = Twig.functions.date(value);
- return Twig.lib.formatDate(date, params[0 ]);
- },
-
- date_modify: function (value, params) {
- if (value === undefined || value === null ) {
- return ;
- }
- if (params === undefined || params.length !== 1 ) {
- throw new Twig.Error("date_modify filter expects 1 argument" );
- }
-
- var modifyText = params[0 ], time;
-
- if (Twig.lib.is("Date" , value)) {
- time = Twig.lib.strtotime(modifyText, value.getTime() / 1000 );
- }
- if (Twig.lib.is("String" , value)) {
- time = Twig.lib.strtotime(modifyText, Twig.lib.strtotime(value));
- }
- if (Twig.lib.is("Number" , value)) {
- time = Twig.lib.strtotime(modifyText, value);
- }
-
- return new Date(time * 1000 );
- },
-
- replace: function (value, params) {
- if (value === undefined ||value === null ){
- return ;
- }
-
- var pairs = params[0 ],
- tag;
- for (tag in pairs) {
- if (pairs.hasOwnProperty(tag) && tag !== "_keys" ) {
- value = Twig.lib.replaceAll(value, tag, pairs[tag]);
- }
- }
- return value;
- },
-
- format: function (value, params) {
- if (value === undefined || value === null ){
- return ;
- }
-
- return Twig.lib.vsprintf(value, params);
- },
-
- striptags: function (value) {
- if (value === undefined || value === null ){
- return ;
- }
-
- return Twig.lib.strip_tags(value);
- },
-
- escape: function (value) {
- if (value === undefined || value === null ){
- return ;
- }
- return value.toString().replace(/&/g , "&" )
- .replace(/</g , "<" )
- .replace(/>/g , ">" )
- .replace(/"/g , """ )
- .replace(/'/g , "'" );
- },
-
-
- "e" : function (value) {
- return Twig.filters.escape(value);
- },
-
- nl2br: function (value) {
- if (value === undefined || value === null ){
- return ;
- }
- var linebreak_tag = "BACKSLASH_n_replace" ,
- br = "<br />" + linebreak_tag;
-
- value = Twig.filters.escape(value)
- .replace(/\r\n/g , br)
- .replace(/\r/g , br)
- .replace(/\n/g , br);
-
- return Twig.lib.replaceAll(value, linebreak_tag, "\n" );
- },
-
-
- number_format: function (value, params) {
- var number = value,
- decimals = (params && params[0 ]) ? params[0 ] : undefined ,
- dec = (params && params[1 ] !== undefined ) ? params[1 ] : "." ,
- sep = (params && params[2 ] !== undefined ) ? params[2 ] : "," ;
-
- number = (number + '' ).replace(/[^0-9+\-Ee.]/g , '' );
- var n = !isFinite(+number) ? 0 : +number,
- prec = !isFinite(+decimals) ? 0 : Math.abs(decimals),
- s = '' ,
- toFixedFix = function (n, prec) {
- var k = Math.pow(10 , prec);
- return '' + Math.round(n * k) / k;
- };
-
-
-
-
-
-
-
-
-
Fix for IE parseFloat(0.55).toFixed(0) = 0;
-
-
-
- s = (prec ? toFixedFix(n, prec) : '' + Math.round(n)).split('.' );
- if (s[0 ].length > 3 ) {
- s[0 ] = s[0 ].replace(/\B(?=(?:\d{3})+(?!\d))/g , sep);
- }
- if ((s[1 ] || '' ).length < prec) {
- s[1 ] = s[1 ] || '' ;
- s[1 ] += new Array(prec - s[1 ].length + 1 ).join('0' );
- }
- return s.join(dec);
- },
-
- trim: function (value, params) {
- if (value === undefined || value === null ){
- return ;
- }
-
- var str = Twig.filters.escape( '' + value ),
- whitespace;
- if ( params && params[0 ] ) {
- whitespace = '' + params[0 ];
- } else {
- whitespace = ' \n\r\t\f\x0b\xa0\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u200b\u2028\u2029\u3000' ;
- }
- for (var i = 0 ; i < str.length; i++) {
- if (whitespace.indexOf(str.charAt(i)) === -1 ) {
- str = str.substring(i);
- break ;
- }
- }
- for (i = str.length - 1 ; i >= 0 ; i--) {
- if (whitespace.indexOf(str.charAt(i)) === -1 ) {
- str = str.substring(0 , i + 1 );
- break ;
- }
- }
- return whitespace.indexOf(str.charAt(0 )) === -1 ? str : '' ;
- },
-
- slice: function (value, params) {
- if (value === undefined || value === null ) {
- return ;
- }
- if (params === undefined || params.length < 1 ) {
- throw new Twig.Error("slice filter expects at least 1 argument" );
- }
-
-
-
-
-
-
-
-
-
default to start of string
-
-
-
- var start = params[0 ] || 0 ;
-
-
-
-
-
-
-
-
-
default to length of string
-
-
-
- var length = params.length > 1 ? params[1 ] : value.length;
-
-
-
-
-
-
-
-
-
handle negative start values
-
-
-
- var startIndex = start >= 0 ? start : Math.max( value.length + start, 0 );
-
- if (Twig.lib.is("Array" , value)) {
- var output = [];
- for (var i = startIndex; i < startIndex + length && i < value.length; i++) {
- output.push(value[i]);
- }
- return output;
- } else if (Twig.lib.is("String" , value)) {
- return value.substr(startIndex, length);
- } else {
- throw new Twig.Error("slice filter expects value to be an array or string" );
- }
- },
-
- abs: function (value) {
- if (value === undefined || value === null ) {
- return ;
- }
-
- return Math.abs(value);
- },
-
- first: function (value) {
- if (value instanceof Array) {
- return value[0 ];
- } else if (value instanceof Object) {
- if ('_keys' in value) {
- return value[value._keys[0 ]];
- }
- } else if ( typeof value === "string" ) {
- return value.substr(0 , 1 );
- }
-
- return ;
- },
-
- split: function (value, params) {
- if (value === undefined || value === null ) {
- return ;
- }
- if (params === undefined || params.length < 1 || params.length > 2 ) {
- throw new Twig.Error("split filter expects 1 or 2 argument" );
- }
- if (Twig.lib.is("String" , value)) {
- var delimiter = params[0 ],
- limit = params[1 ],
- split = value.split(delimiter);
-
- if (limit === undefined ) {
-
- return split;
-
- } else if (limit < 0 ) {
-
- return value.split(delimiter, split.length + limit);
-
- } else {
-
- var limitedSplit = [];
-
- if (delimiter == '' ) {
-
-
-
-
-
-
-
-
-
empty delimiter
-"aabbcc"|split('', 2)
- -> ['aa', 'bb', 'cc']
-
-
-
- while (split.length > 0 ) {
- var temp = "" ;
- for (var i=0 ; i<limit && split.length > 0 ; i++) {
- temp += split.shift();
- }
- limitedSplit.push(temp);
- }
-
- } else {
-
-
-
-
-
-
-
-
-
non-empty delimiter
-"one,two,three,four,five"|split(',', 3)
- -> ['one', 'two', 'three,four,five']
-
-
-
- for (var i=0 ; i<limit-1 && split.length > 0 ; i++) {
- limitedSplit.push(split.shift());
- }
-
- if (split.length > 0 ) {
- limitedSplit.push(split.join(delimiter));
- }
- }
-
- return limitedSplit;
- }
-
- } else {
- throw new Twig.Error("split filter expects value to be a string" );
- }
- },
- last: function (value) {
- if (Twig.lib.is('Object' , value)) {
- var keys;
-
- if (value._keys === undefined ) {
- keys = Object.keys(value);
- } else {
- keys = value._keys;
- }
-
- return value[keys[keys.length - 1 ]];
- }
-
-
-
-
-
-
-
- return value[value.length - 1 ];
- },
- raw: function (value) {
-
-
-
-
-
-
-
-
-
Raw filter shim
-
-
-
- return value;
- },
- batch: function (items, params) {
- var size = params.shift(),
- fill = params.shift(),
- result,
- last,
- missing;
-
- if (!Twig.lib.is("Array" , items)) {
- throw new Twig.Error("batch filter expects items to be an array" );
- }
-
- if (!Twig.lib.is("Number" , size)) {
- throw new Twig.Error("batch filter expects size to be a number" );
- }
-
- size = Math.ceil(size);
-
- result = Twig.lib.chunkArray(items, size);
-
- if (fill && items.length % size != 0 ) {
- last = result.pop();
- missing = size - last.length;
-
- while (missing--) {
- last.push(fill);
- }
-
- result.push(last);
- }
-
- return result;
- },
- round: function (value, params) {
- params = params || [];
-
- var precision = params.length > 0 ? params[0 ] : 0 ,
- method = params.length > 1 ? params[1 ] : "common" ;
-
- value = parseFloat(value);
-
- if (precision && !Twig.lib.is("Number" , precision)) {
- throw new Twig.Error("round filter expects precision to be a number" );
- }
-
- if (method === "common" ) {
- return Twig.lib.round(value, precision);
- }
-
- if (!Twig.lib.is("Function" , Math[method])) {
- throw new Twig.Error("round filter expects method to be 'floor', 'ceil', or 'common'" );
- }
-
- return Math[method](value * Math.pow(10 , precision)) / Math.pow(10 , precision);
- }
- };
-
- Twig.filter = function (filter, value, params) {
- if (!Twig.filters[filter]) {
- throw "Unable to find filter " + filter;
- }
- return Twig.filters[filter].apply(this , [value, params]);
- };
-
- Twig.filter.extend = function (filter, definition) {
- Twig.filters[filter] = definition;
- };
-
- return Twig;
-
-})(Twig || { });
-
-
-
-
-
-
-
-
-
Twig.js
-Copyright (c) 2011-2013 John Roepke
- 2012 Hadrien Lanneau
-Available under the BSD 2-Clause License
-https://github.com/justjohn/twig.js
-
twig.functions.js
-
This file handles parsing filters.
-
-
-
- var Twig = (function (Twig) {
-
-
-
-
-
-
-
-
-
Determine object type
-
-
-
- function is (type, obj) {
- var clas = Object.prototype.toString.call(obj).slice(8 , -1 );
- return obj !== undefined && obj !== null && clas === type;
- }
-
- Twig.functions = {
-
-
-
-
-
-
-
- range: function (low, high, step) {
-
-
-
-
-
-
-
-
-
http://kevin.vanzonneveld.net
-
-original by: Waldo Malqui Silva
-example 1: range ( 0, 12 );
-returns 1: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]
-example 2: range( 0, 100, 10 );
-returns 2: [0, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100]
-example 3: range( 'a', 'i' );
-returns 3: ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i']
-example 4: range( 'c', 'a' );
-returns 4: ['c', 'b', 'a']
-
-
-
-
- var matrix = [];
- var inival, endval, plus;
- var walker = step || 1 ;
- var chars = false ;
-
- if (!isNaN(low) && !isNaN(high)) {
- inival = parseInt(low, 10 );
- endval = parseInt(high, 10 );
- } else if (isNaN(low) && isNaN(high)) {
- chars = true ;
- inival = low.charCodeAt(0 );
- endval = high.charCodeAt(0 );
- } else {
- inival = (isNaN(low) ? 0 : low);
- endval = (isNaN(high) ? 0 : high);
- }
-
- plus = ((inival > endval) ? false : true );
- if (plus) {
- while (inival <= endval) {
- matrix.push(((chars) ? String.fromCharCode(inival) : inival));
- inival += walker;
- }
- } else {
- while (inival >= endval) {
- matrix.push(((chars) ? String.fromCharCode(inival) : inival));
- inival -= walker;
- }
- }
-
- return matrix;
- },
- cycle: function (arr, i) {
- var pos = i % arr.length;
- return arr[pos];
- },
- dump: function () {
- var EOL = '\n' ,
- indentChar = ' ' ,
- indentTimes = 0 ,
- out = '' ,
- args = Array.prototype.slice.call(arguments),
- indent = function (times) {
- var ind = '' ;
- while (times > 0 ) {
- times--;
- ind += indentChar;
- }
- return ind;
- },
- displayVar = function (variable) {
- out += indent(indentTimes);
- if (typeof (variable) === 'object' ) {
- dumpVar(variable);
- } else if (typeof (variable) === 'function' ) {
- out += 'function()' + EOL;
- } else if (typeof (variable) === 'string' ) {
- out += 'string(' + variable.length + ') "' + variable + '"' + EOL;
- } else if (typeof (variable) === 'number' ) {
- out += 'number(' + variable + ')' + EOL;
- } else if (typeof (variable) === 'boolean' ) {
- out += 'bool(' + variable + ')' + EOL;
- }
- },
- dumpVar = function (variable) {
- var i;
- if (variable === null ) {
- out += 'NULL' + EOL;
- } else if (variable === undefined ) {
- out += 'undefined' + EOL;
- } else if (typeof variable === 'object' ) {
- out += indent(indentTimes) + typeof (variable);
- indentTimes++;
- out += '(' + (function (obj) {
- var size = 0 , key;
- for (key in obj) {
- if (obj.hasOwnProperty(key)) {
- size++;
- }
- }
- return size;
- })(variable) + ') {' + EOL;
- for (i in variable) {
- out += indent(indentTimes) + '[' + i + ']=> ' + EOL;
- displayVar(variable[i]);
- }
- indentTimes--;
- out += indent(indentTimes) + '}' + EOL;
- } else {
- displayVar(variable);
- }
- };
-
-
-
-
-
-
-
-
-
handle no argument case by dumping the entire render context
-
-
-
- if (args.length == 0 ) args.push(this .context);
-
- Twig.forEach(args, function (variable) {
- dumpVar(variable);
- });
-
- return out;
- },
- date: function (date, time) {
- var dateObj;
- if (date === undefined ) {
- dateObj = new Date();
- } else if (Twig.lib.is("Date" , date)) {
- dateObj = date;
- } else if (Twig.lib.is("String" , date)) {
- dateObj = new Date(Twig.lib.strtotime(date) * 1000 );
- } else if (Twig.lib.is("Number" , date)) {
-
-
-
-
-
-
-
- dateObj = new Date(date * 1000 );
- } else {
- throw new Twig.Error("Unable to parse date " + date);
- }
- return dateObj;
- },
- block: function (block) {
- return this .blocks[block];
- },
- parent: function () {
-
-
-
-
-
-
-
-
-
Add a placeholder
-
-
-
- return Twig.placeholders.parent;
- },
- attribute: function (object, method, params) {
- if (object instanceof Object) {
- if (object.hasOwnProperty(method)) {
- if (typeof object[method] === "function" ) {
- return object[method].apply(undefined , params);
- }
- else {
- return object[method];
- }
- }
- }
-
-
-
-
-
-
-
-
-
Array will return element 0-index
-
-
-
- return object[method] || undefined ;
- }
- };
-
- Twig._function = function (_function, value, params) {
- if (!Twig.functions[_function]) {
- throw "Unable to find function " + _function;
- }
- return Twig.functions[_function](value, params);
- };
-
- Twig._function.extend = function (_function, definition) {
- Twig.functions[_function] = definition;
- };
-
- return Twig;
-
-})(Twig || { });
-
-
-
-
-
-
-
-
-
Twig.js
-Copyright (c) 2011-2013 John Roepke
-Available under the BSD 2-Clause License
-https://github.com/justjohn/twig.js
-
twig.tests.js
-
This file handles expression tests. (is empty, is not defined, etc...)
-
-
-
- var Twig = (function (Twig) {
- "use strict" ;
- Twig.tests = {
- empty: function (value) {
- if (value === null || value === undefined ) return true ;
-
-
-
-
-
-
-
-
-
Handler numbers
-
-
-
- if (typeof value === "number" ) return false ;
-
-
-
-
-
-
-
-
-
Handle strings and arrays
-
-
-
- if (value.length && value.length > 0 ) return false ;
-
-
-
-
-
-
-
- for (var key in value) {
- if (value.hasOwnProperty(key)) return false ;
- }
- return true ;
- },
- odd: function (value) {
- return value % 2 === 1 ;
- },
- even: function (value) {
- return value % 2 === 0 ;
- },
- divisibleby: function (value, params) {
- return value % params[0 ] === 0 ;
- },
- defined: function (value) {
- return value !== undefined ;
- },
- none: function (value) {
- return value === null ;
- },
- 'null' : function (value) {
- return this .none(value);
- },
- sameas: function (value, params) {
- return value === params[0 ];
- }
-
- };
-
- Twig.test = function (test, value, params) {
- if (!Twig.tests[test]) {
- throw "Test " + test + " is not defined." ;
- }
- return Twig.tests[test](value, params);
- };
-
- Twig.test.extend = function (test, definition) {
- Twig.tests[test] = definition;
- };
-
- return Twig;
-})( Twig || { } );
-
-
-
-
-
-
-
-
-
Twig.js
-Copyright (c) 2011-2013 John Roepke
-Available under the BSD 2-Clause License
-https://github.com/justjohn/twig.js
-
twig.exports.js
-
This file provides extension points and other hooks into the twig functionality.
-
-
-
- var Twig = (function (Twig) {
- "use strict" ;
- Twig.exports = {
- VERSION: Twig.VERSION
- };
-
-
- Twig.exports.twig = function twig (params) {
- 'use strict' ;
- var id = params.id,
- options = {
- strict_variables: params.strict_variables || false ,
- allowInlineIncludes: params.allowInlineIncludes || false ,
- rethrow: params.rethrow || false
- };
-
- if (id) {
- Twig.validateId(id);
- }
-
- if (params.debug !== undefined ) {
- Twig.debug = params.debug;
- }
- if (params.trace !== undefined ) {
- Twig.trace = params.trace;
- }
-
- if (params.data !== undefined ) {
- return new Twig.Template({
- data: params.data,
- module: params.module,
- id: id,
- options: options
- });
-
- } else if (params.ref !== undefined ) {
- if (params.id !== undefined ) {
- throw new Twig.Error("Both ref and id cannot be set on a twig.js template." );
- }
- return Twig.Templates.load(params.ref);
-
- } else if (params.href !== undefined ) {
- return Twig.Templates.loadRemote(params.href, {
- id: id,
- method: 'ajax' ,
- base: params.base,
- module: params.module,
- precompiled: params.precompiled,
- async: params.async,
- options: options
-
- }, params.load, params.error);
-
- } else if (params.path !== undefined ) {
- return Twig.Templates.loadRemote(params.path, {
- id: id,
- method: 'fs' ,
- base: params.base,
- module: params.module,
- precompiled: params.precompiled,
- async: params.async,
- options: options
-
- }, params.load, params.error);
- }
- };
-
-
-
-
-
-
-
-
-
Extend Twig with a new filter.
-
-
-
- Twig.exports.extendFilter = function (filter, definition) {
- Twig.filter.extend(filter, definition);
- };
-
-
-
-
-
-
-
-
-
Extend Twig with a new function.
-
-
-
- Twig.exports.extendFunction = function (fn, definition) {
- Twig._function.extend(fn, definition);
- };
-
-
-
-
-
-
-
-
-
Extend Twig with a new test.
-
-
-
- Twig.exports.extendTest = function (test, definition) {
- Twig.test.extend(test, definition);
- };
-
-
-
-
-
-
-
-
-
Extend Twig with a new definition.
-
-
-
- Twig.exports.extendTag = function (definition) {
- Twig.logic.extend(definition);
- };
-
-
-
-
-
-
-
-
-
Provide an environment for extending Twig core.
-Calls fn with the internal Twig object.
-
-
-
- Twig.exports.extend = function (fn) {
- fn(Twig);
- };
-
-
-
- Twig.exports.compile = function (markup, options) {
- var id = options.filename,
- path = options.filename,
- template;
-
-
-
-
-
-
-
-
-
Try to load the template from the cache
-
-
-
- template = new Twig.Template({
- data: markup,
- path: path,
- id: id,
- options: options.settings['twig options' ]
- });
-
- return function (context) {
- return template.render(context);
- };
- };
-
-
-
- Twig.exports.renderFile = function (path, options, fn) {
-
-
-
-
-
-
-
-
-
handle callback in options
-
-
-
- if ('function' == typeof options) {
- fn = options;
- options = {};
- }
-
- options = options || {};
-
- var params = {
- path: path,
- base: options.settings['views' ],
- load: function (template) {
-
-
-
-
-
-
-
-
-
render and return template
-
-
-
- fn(null , template.render(options));
- }
- };
-
-
-
-
-
-
-
-
-
mixin any options provided to the express app.
-
-
-
- var view_options = options.settings['twig options' ];
-
- if (view_options) {
- for (var option in view_options) if (view_options.hasOwnProperty(option)) {
- params[option] = view_options[option];
- }
- }
-
- Twig.exports.twig(params);
- };
-
-
-
-
-
-
-
-
-
Express 3 handler
-
-
-
- Twig.exports.__express = Twig.exports.renderFile;
-
-
- Twig.exports.cache = function (cache) {
- Twig.cache = cache;
- }
-
- return Twig;
-}) (Twig || { });
-
-
-
-
-
-
-
-
-
Twig.js
-Copyright (c) 2011-2013 John Roepke
-Available under the BSD 2-Clause License
-https://github.com/justjohn/twig.js
-
twig.compiler.js
-
This file handles compiling templates into JS
-
-
-
- var Twig = (function (Twig) {
-
- Twig.compiler = {
- module: {}
- };
-
-
-
-
-
-
-
-
-
Compile a Twig Template to output.
-
-
-
- Twig.compiler.compile = function (template, options) {
-
-
-
-
-
-
-
- var tokens = JSON.stringify(template.tokens)
- , id = template.id
- , output;
-
- if (options.module) {
- if (Twig.compiler.module[options.module] === undefined ) {
- throw new Twig.Error("Unable to find module type " + options.module);
- }
- output = Twig.compiler.module[options.module](id, tokens, options.twig);
- } else {
- output = Twig.compiler.wrap(id, tokens);
- }
- return output;
- };
-
- Twig.compiler.module = {
- amd: function (id, tokens, pathToTwig) {
- return 'define(["' + pathToTwig + '"], function (Twig) {\n\tvar twig, templates;\ntwig = Twig.twig;\ntemplates = ' + Twig.compiler.wrap(id, tokens) + '\n\treturn templates;\n});' ;
- }
- , node: function (id, tokens) {
- return 'var twig = require("twig").twig;\n'
- + 'exports.template = ' + Twig.compiler.wrap(id, tokens)
- }
- , cjs2: function (id, tokens, pathToTwig) {
- return 'module.declare([{ twig: "' + pathToTwig + '" }], function (require, exports, module) {\n'
- + '\tvar twig = require("twig").twig;\n'
- + '\texports.template = ' + Twig.compiler.wrap(id, tokens)
- + '\n});'
- }
- };
-
- Twig.compiler.wrap = function (id, tokens) {
- return 'twig({id:"' +id.replace('"' , '\\"' )+'", data:' +tokens+', precompiled: true});\n' ;
- };
-
- return Twig;
-})(Twig || {});
-
-
-
-
-
-
-
-
-
Twig.js
-Copyright (c) 2011-2013 John Roepke
-Available under the BSD 2-Clause License
-https://github.com/justjohn/twig.js
-
twig.module.js
-
Provide a CommonJS/AMD/Node module export.
-
-
-
- if (typeof module !== 'undefined' && module.declare) {
-
-
-
-
-
-
-
-
-
Provide a CommonJS Modules/2.0 draft 8 module
-
-
-
- module.declare([], function (require, exports, module) {
-
-
-
-
-
-
-
-
-
Add exports from the Twig exports
-
-
-
- for (key in Twig.exports) {
- if (Twig.exports.hasOwnProperty(key)) {
- exports[key] = Twig.exports[key];
- }
- }
- });
-} else if (typeof define == 'function' && define.amd) {
- define(function () {
- return Twig.exports;
- });
-} else if (typeof module !== 'undefined' && module.exports) {
-
-
-
-
-
-
-
-
-
Provide a CommonJS Modules/1.1 module
-
-
-
- module.exports = Twig.exports;
-} else {
-
-
-
-
-
-
-
-
-
Export for browser use
-
-
-
- window.twig = Twig.exports.twig;
- window.Twig = Twig.exports;
-}
-
-
-
-
-
-
-
diff --git a/docs/wiki b/docs/wiki
deleted file mode 160000
index f5639d94..00000000
--- a/docs/wiki
+++ /dev/null
@@ -1 +0,0 @@
-Subproject commit f5639d94dbff85f16467ccfebb10312c8beb2930
diff --git a/docs/zh/guide/getting-started.md b/docs/zh/guide/getting-started.md
new file mode 100644
index 00000000..4d614e33
--- /dev/null
+++ b/docs/zh/guide/getting-started.md
@@ -0,0 +1,33 @@
+# 快速开始
+
+## 安装
+
+您可以通过以下任意一种方法获取Twig.js:
+
+### Git:
+
+
+1. 克隆仓库
+
+`git clone git://github.com/justjohn/twig.js.git`
+
+2. 下载最新的 [zip](https://github.com/justjohn/twig.js/zipball/master) 或 [tgz](https://github.com/justjohn/twig.js/tarball/master) 压缩包
+
+
+文件`twig.js`和`twig.min.js`可能不是最新的(发布新版本时将重建它们)。运行`make`(或`make -B`强制构建)来创建这些文件。
+
+### NPM:
+
+```bash
+npm install twig --save-dev
+```
+
+### Yarn:
+
+```bash
+yarn add twig --dev
+```
+
+
+
+
diff --git a/docs/zh/guide/what-is-it.md b/docs/zh/guide/what-is-it.md
new file mode 100644
index 00000000..d8a73f9f
--- /dev/null
+++ b/docs/zh/guide/what-is-it.md
@@ -0,0 +1,16 @@
+# 什么是Twig.js?
+
+
+Twig.js是[Twig](https://twig.symfony.com/)的纯JavaScript实现PHP模板语言
+
+目标是提供一个与浏览器和服务器端容器(如node.js)兼容的库。Twig.js目前正在开发中,支持Twig模板语言的一个有限子集(未来还会有更多)。
+
+## 新闻
+
+- 6/10/2016 - Twig 现在可以作为 [Keystone.js](http://keystonejs.com/) 中的模板引擎使用
+
+## 实现细节
+
+
+请参阅[实现细节](/reference/implementation-notes)页面,查看受支持的过滤器/函数/标签/测试的列表。
+
diff --git a/docs/zh/index.md b/docs/zh/index.md
new file mode 100644
index 00000000..e9b89c4a
--- /dev/null
+++ b/docs/zh/index.md
@@ -0,0 +1,31 @@
+---
+# https://vitepress.dev/reference/default-theme-home-page
+layout: home
+
+hero:
+ image:
+ src: /logo-large.svg
+ alt: Twig.js
+ name: Twig.js
+ text: Twig模板语言的JS移植
+ tagline: 目标是提供一个与浏览器和服务器端JavaScript环境(如node.js)兼容的库
+
+ actions:
+ - theme: brand
+ text: 什么是Twig.js?
+ link: /zh/guide/what-is-it
+ - theme: alt
+ text: 快速开始
+ link: /zh/guide/getting-started
+ - theme: alt
+ text: GitHub
+ link: https://github.com/twigjs/twig.js
+
+features:
+ - icon: ✨
+ title: 持续支持
+ details: Twig.js目前正在开发中,支持Twig模板语言的一个有限子集(未来还会有更多)
+ - icon: ✨
+ title: 无额外的学习成本
+ details: 只要你知道Twig模板语法,你就可以快速开始
+---
diff --git a/docs/zh/reference/compiling-templates.md b/docs/zh/reference/compiling-templates.md
new file mode 100644
index 00000000..66320dcb
--- /dev/null
+++ b/docs/zh/reference/compiling-templates.md
@@ -0,0 +1,5 @@
+# 模板编译
+
+
+todo...
+
diff --git a/lib/compile.js b/lib/compile.js
index 15a6ebe1..7f4154b7 100644
--- a/lib/compile.js
+++ b/lib/compile.js
@@ -1,99 +1,110 @@
-var Twig = require("../twig")
- , twig = Twig.twig
- , PATHS = require("./paths")
- , MINIMATCH = require("minimatch")
- , FS = require("fs")
- , WALK = require("walk");
+const FS = require('fs');
+const minimatch = require('minimatch');
+const WALK = require('walk');
+const Twig = require('..');
+const PATHS = require('./paths');
+
+const {twig} = Twig;
exports.defaults = {
- compress: false
- , pattern: "*\\.twig"
- , recursive: false
+ compress: false,
+ pattern: '*\\.twig',
+ recursive: false
};
-exports.compile = function(options, files) {
+exports.compile = function (options, files) {
// Create output template directory if necessary
if (options.output) {
PATHS.mkdir(options.output);
}
-
- files.forEach(function(file) {
- FS.stat(file, function(err, stats) {
+
+ files.forEach(file => {
+ FS.stat(file, (err, stats) => {
+ if (err) {
+ console.error('ERROR ' + file + ': Unable to stat file');
+ return;
+ }
+
if (stats.isDirectory()) {
parseTemplateFolder(file, options.pattern);
} else if (stats.isFile()) {
parseTemplateFile(file);
} else {
- console.log("ERROR " + file + ": Unable to stat file");
+ console.log('ERROR ' + file + ': Unknown file information');
}
});
});
-
+
function parseTemplateFolder(directory, pattern) {
- directory = PATHS.strip_slash(directory);
-
- // Get the files in the directory
- // Walker options
- var walker = WALK.walk(directory, { followLinks: false })
- , files = [];
-
- walker.on('file', function(root, stat, next) {
- // normalize (remove / from end if present)
- root = PATHS.strip_slash(root);
-
- // match against file pattern
- var name = stat.name
- , file = root + '/' + name;
- if (MINIMATCH(name, pattern)) {
+ directory = PATHS.stripSlash(directory);
+
+ // Get the files in the directory
+ // Walker options
+ const walker = WALK.walk(directory, {followLinks: false});
+ const files = [];
+
+ walker.on('file', (root, stat, next) => {
+ // Normalize (remove / from end if present)
+ root = PATHS.stripSlash(root);
+
+ // Match against file pattern
+ const {name} = stat;
+ const file = root + '/' + name;
+ if (minimatch(name, pattern)) {
parseTemplateFile(file, directory);
files.push(file);
}
+
next();
});
- walker.on('end', function() {
- // console.log(files);
+ walker.on('end', () => {
+ // Console.log(files);
});
}
function parseTemplateFile(file, base) {
- if (base) base = PATHS.strip_slash(base);
- var split_file = file.split("/")
- , output_file_name = split_file.pop()
- , output_file_base = PATHS.findBase(file)
- , output_directory = options.output
- , output_base = PATHS.removePath(base, output_file_base)
- , output_id
- , output_file;
-
- if (output_directory) {
+ if (base) {
+ base = PATHS.stripSlash(base);
+ }
+
+ const splitFile = file.split('/');
+ const outputFileName = splitFile.pop();
+ const outputFileBase = PATHS.findBase(file);
+ const outputDirectory = options.output;
+ let outputBase = PATHS.removePath(base, outputFileBase);
+ let outputId;
+ let outputFile;
+
+ if (outputDirectory) {
// Create template directory
- if (output_base !== "") {
- PATHS.mkdir(output_directory + "/" + output_base);
- output_base += "/";
+ if (outputBase !== '') {
+ PATHS.mkdir(outputDirectory + '/' + outputBase);
+ outputBase += '/';
}
- output_id = output_directory + "/" + output_base + output_file_name;
- output_file = output_id + ".js"
+
+ outputId = outputDirectory + '/' + outputBase + outputFileName;
+ outputFile = outputId + '.js';
} else {
- output_id = file;
- output_file = output_id + ".js"
+ outputId = file;
+ outputFile = outputId + '.js';
}
-
- var tpl = twig({
- id: output_id
- , path: file
- , load: function(template) {
- // compile!
- var output = template.compile(options);
-
- FS.writeFile(output_file, output, 'utf8', function(err) {
+
+ twig({
+ id: outputId,
+ path: file,
+ load(template) {
+ // Compile!
+ const output = template.compile(options);
+
+ FS.writeFile(outputFile, output, 'utf8', err => {
if (err) {
- console.log("Unable to compile " + file + ", error " + err);
+ console.log('Unable to compile ' + file + ', error ' + err);
} else {
- console.log("Compiled " + file + "\t-> " + output_file);
+ console.log('Compiled ' + file + '\t-> ' + outputFile);
}
});
}
});
}
-};
\ No newline at end of file
+};
diff --git a/lib/paths.js b/lib/paths.js
index 6e61c5ae..a55218fc 100644
--- a/lib/paths.js
+++ b/lib/paths.js
@@ -1,86 +1,83 @@
-var FS = require("fs")
- , sep_chr = '/';
-
-exports.relativePath = function(base, file) {
- var base_path = exports.normalize(base.split(sep_chr)),
- new_path = [],
- val;
+const FS = require('fs');
+
+const sepChr = '/';
+
+exports.relativePath = function (base, file) {
+ let basePath = exports.normalize(base.split(sepChr));
+ const newPath = [];
+ let val;
// Remove file from url
- base_path.pop();
- base_path = base_path.concat(file.split(sep_chr));
-
- while (base_path.length > 0) {
- val = base_path.shift();
- if (val == ".") {
+ basePath.pop();
+ basePath = basePath.concat(file.split(sepChr));
+
+ while (basePath.length > 0) {
+ val = basePath.shift();
+ if (val === '.') {
// Ignore
- } else if (val == ".." && new_path.length > 0 && new_path[new_path.length-1] != "..") {
- new_path.pop();
+ } else if (val === '..' && newPath.length > 0 && newPath[newPath.length - 1] !== '..') {
+ newPath.pop();
} else {
- new_path.push(val);
+ newPath.push(val);
}
}
- return new_path.join(sep_chr);
+ return newPath.join(sepChr);
};
-exports.findBase = function(file) {
- var paths = exports.normalize(file.split(sep_chr));
- // we want everything before the file
+exports.findBase = function (file) {
+ const paths = exports.normalize(file.split(sepChr));
+ // We want everything before the file
if (paths.length > 1) {
- // get rid of the filename
+ // Get rid of the filename
paths.pop();
- return paths.join(sep_chr) + sep_chr;
- } else {
- // we're in the file directory
- return "";
+ return paths.join(sepChr) + sepChr;
}
+
+ // We're in the file directory
+ return '';
};
-exports.removePath = function(path, file) {
- if (!path) return "";
-
- var base_path = exports.normalize(path.split(sep_chr))
- , file_path = exports.normalize(file.split(sep_chr))
- , val
- , file_val;
-
- // strip base path off of file path
- while(base_path.length > 0) {
- val = base_path.shift();
- if (val !== '') {
- file_val = file_path.shift();
- }
+exports.removePath = function (path, file) {
+ if (!path) {
+ return '';
}
- return file_path.join(sep_chr);
+
+ const filePath = exports.normalize(file.split(sepChr));
+
+ return filePath.join(sepChr);
};
-exports.normalize = function(file_arr) {
- var new_arr = []
- , val;
- while(file_arr.length > 0) {
- val = file_arr.shift();
+exports.normalize = function (fileArr) {
+ const newArr = [];
+ let val;
+ while (fileArr.length > 0) {
+ val = fileArr.shift();
if (val !== '') {
- new_arr.push(val);
+ newArr.push(val);
}
}
- return new_arr;
+
+ return newArr;
};
-exports.strip_slash = function(path) {
- if (path.substr(-1) == '/') path = path.substring(0, path.length-1);
+exports.stripSlash = function (path) {
+ if (path.slice(-1) === '/') {
+ path = path.slice(0, Math.max(0, path.length - 1));
+ }
+
return path;
};
-exports.mkdir = function(dir) {
+exports.mkdir = function (dir) {
try {
FS.mkdirSync(dir);
- } catch (err) {
- if (err.code == "EEXIST") {
+ } catch (error) {
+ if (error.code === 'EEXIST') {
// ignore if it's a "EEXIST" exeption
- } else {
- console.log(err);
- throw err;
+ } else {
+ console.log(error);
+ throw error;
}
}
};
diff --git a/node/build.js b/node/build.js
new file mode 100644
index 00000000..c09d6ca9
--- /dev/null
+++ b/node/build.js
@@ -0,0 +1,17 @@
+const child_process = require('child_process');
+const semver = require('semver');
+
+const environmentVariables = {...process.env};
+
+if (semver.satisfies(process.version, '>=17')) {
+ environmentVariables['NODE_OPTIONS'] = '--openssl-legacy-provider';
+}
+
+child_process.spawn(
+ 'webpack',
+ [],
+ {
+ env: environmentVariables,
+ stdio: 'inherit',
+ }
+);
diff --git a/package-lock.json b/package-lock.json
new file mode 100644
index 00000000..116fa7ec
--- /dev/null
+++ b/package-lock.json
@@ -0,0 +1,17808 @@
+{
+ "name": "twig",
+ "version": "1.17.1",
+ "lockfileVersion": 2,
+ "requires": true,
+ "packages": {
+ "": {
+ "version": "1.17.1",
+ "license": "BSD-2-Clause",
+ "dependencies": {
+ "@babel/runtime": "^7.8.4",
+ "locutus": "^2.0.11",
+ "minimatch": "3.0.x",
+ "walk": "2.3.x"
+ },
+ "bin": {
+ "twigjs": "bin/twigjs"
+ },
+ "devDependencies": {
+ "@babel/core": "^7.8.4",
+ "@babel/plugin-transform-runtime": "^7.8.3",
+ "@babel/preset-env": "^7.8.4",
+ "babel-loader": "^8.0.6",
+ "eslint-plugin-mocha": "^6.3.0",
+ "mocha": "^9.0.0",
+ "path-browserify": "^1.0.1",
+ "should": "^13.2.3",
+ "should-sinon": "0.0.6",
+ "sinon": "^9.0.0",
+ "terser-webpack-plugin": "^5.3.6",
+ "tokenizer2": "^2.0.1",
+ "webpack": "^5.75.0",
+ "webpack-cli": "^5.0.1",
+ "xo": "^0.26.1"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/@babel/code-frame": {
+ "version": "7.10.4",
+ "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.10.4.tgz",
+ "integrity": "sha512-vG6SvB6oYEhvgisZNFRmRCUkLz11c7rp+tbNTynGqc6mS1d5ATd/sGyV6W0KZZnXRKMTzZDRgQT3Ou9jhpAfUg==",
+ "dev": true,
+ "dependencies": {
+ "@babel/highlight": "^7.10.4"
+ }
+ },
+ "node_modules/@babel/compat-data": {
+ "version": "7.12.5",
+ "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.12.5.tgz",
+ "integrity": "sha512-DTsS7cxrsH3by8nqQSpFSyjSfSYl57D6Cf4q8dW3LK83tBKBDCkfcay1nYkXq1nIHXnpX8WMMb/O25HOy3h1zg==",
+ "dev": true
+ },
+ "node_modules/@babel/core": {
+ "version": "7.12.3",
+ "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.12.3.tgz",
+ "integrity": "sha512-0qXcZYKZp3/6N2jKYVxZv0aNCsxTSVCiK72DTiTYZAu7sjg73W0/aynWjMbiGd87EQL4WyA8reiJVh92AVla9g==",
+ "dev": true,
+ "dependencies": {
+ "@babel/code-frame": "^7.10.4",
+ "@babel/generator": "^7.12.1",
+ "@babel/helper-module-transforms": "^7.12.1",
+ "@babel/helpers": "^7.12.1",
+ "@babel/parser": "^7.12.3",
+ "@babel/template": "^7.10.4",
+ "@babel/traverse": "^7.12.1",
+ "@babel/types": "^7.12.1",
+ "convert-source-map": "^1.7.0",
+ "debug": "^4.1.0",
+ "gensync": "^1.0.0-beta.1",
+ "json5": "^2.1.2",
+ "lodash": "^4.17.19",
+ "resolve": "^1.3.2",
+ "semver": "^5.4.1",
+ "source-map": "^0.5.0"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/babel"
+ }
+ },
+ "node_modules/@babel/generator": {
+ "version": "7.12.5",
+ "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.12.5.tgz",
+ "integrity": "sha512-m16TQQJ8hPt7E+OS/XVQg/7U184MLXtvuGbCdA7na61vha+ImkyyNM/9DDA0unYCVZn3ZOhng+qz48/KBOT96A==",
+ "dev": true,
+ "dependencies": {
+ "@babel/types": "^7.12.5",
+ "jsesc": "^2.5.1",
+ "source-map": "^0.5.0"
+ }
+ },
+ "node_modules/@babel/helper-annotate-as-pure": {
+ "version": "7.10.4",
+ "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.10.4.tgz",
+ "integrity": "sha512-XQlqKQP4vXFB7BN8fEEerrmYvHp3fK/rBkRFz9jaJbzK0B1DSfej9Kc7ZzE8Z/OnId1jpJdNAZ3BFQjWG68rcA==",
+ "dev": true,
+ "dependencies": {
+ "@babel/types": "^7.10.4"
+ }
+ },
+ "node_modules/@babel/helper-builder-binary-assignment-operator-visitor": {
+ "version": "7.10.4",
+ "resolved": "https://registry.npmjs.org/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.10.4.tgz",
+ "integrity": "sha512-L0zGlFrGWZK4PbT8AszSfLTM5sDU1+Az/En9VrdT8/LmEiJt4zXt+Jve9DCAnQcbqDhCI+29y/L93mrDzddCcg==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-explode-assignable-expression": "^7.10.4",
+ "@babel/types": "^7.10.4"
+ }
+ },
+ "node_modules/@babel/helper-compilation-targets": {
+ "version": "7.12.5",
+ "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.12.5.tgz",
+ "integrity": "sha512-+qH6NrscMolUlzOYngSBMIOQpKUGPPsc61Bu5W10mg84LxZ7cmvnBHzARKbDoFxVvqqAbj6Tg6N7bSrWSPXMyw==",
+ "dev": true,
+ "dependencies": {
+ "@babel/compat-data": "^7.12.5",
+ "@babel/helper-validator-option": "^7.12.1",
+ "browserslist": "^4.14.5",
+ "semver": "^5.5.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0"
+ }
+ },
+ "node_modules/@babel/helper-create-class-features-plugin": {
+ "version": "7.12.1",
+ "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.12.1.tgz",
+ "integrity": "sha512-hkL++rWeta/OVOBTRJc9a5Azh5mt5WgZUGAKMD8JM141YsE08K//bp1unBBieO6rUKkIPyUE0USQ30jAy3Sk1w==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-function-name": "^7.10.4",
+ "@babel/helper-member-expression-to-functions": "^7.12.1",
+ "@babel/helper-optimise-call-expression": "^7.10.4",
+ "@babel/helper-replace-supers": "^7.12.1",
+ "@babel/helper-split-export-declaration": "^7.10.4"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0"
+ }
+ },
+ "node_modules/@babel/helper-create-regexp-features-plugin": {
+ "version": "7.12.1",
+ "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.12.1.tgz",
+ "integrity": "sha512-rsZ4LGvFTZnzdNZR5HZdmJVuXK8834R5QkF3WvcnBhrlVtF0HSIUC6zbreL9MgjTywhKokn8RIYRiq99+DLAxA==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-annotate-as-pure": "^7.10.4",
+ "@babel/helper-regex": "^7.10.4",
+ "regexpu-core": "^4.7.1"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0"
+ }
+ },
+ "node_modules/@babel/helper-define-map": {
+ "version": "7.10.5",
+ "resolved": "https://registry.npmjs.org/@babel/helper-define-map/-/helper-define-map-7.10.5.tgz",
+ "integrity": "sha512-fMw4kgFB720aQFXSVaXr79pjjcW5puTCM16+rECJ/plGS+zByelE8l9nCpV1GibxTnFVmUuYG9U8wYfQHdzOEQ==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-function-name": "^7.10.4",
+ "@babel/types": "^7.10.5",
+ "lodash": "^4.17.19"
+ }
+ },
+ "node_modules/@babel/helper-environment-visitor": {
+ "version": "7.22.20",
+ "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.22.20.tgz",
+ "integrity": "sha512-zfedSIzFhat/gFhWfHtgWvlec0nqB9YEIVrpuwjruLlXfUSnA8cJB0miHKwqDnQ7d32aKo2xt88/xZptwxbfhA==",
+ "dev": true,
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-explode-assignable-expression": {
+ "version": "7.12.1",
+ "resolved": "https://registry.npmjs.org/@babel/helper-explode-assignable-expression/-/helper-explode-assignable-expression-7.12.1.tgz",
+ "integrity": "sha512-dmUwH8XmlrUpVqgtZ737tK88v07l840z9j3OEhCLwKTkjlvKpfqXVIZ0wpK3aeOxspwGrf/5AP5qLx4rO3w5rA==",
+ "dev": true,
+ "dependencies": {
+ "@babel/types": "^7.12.1"
+ }
+ },
+ "node_modules/@babel/helper-function-name": {
+ "version": "7.10.4",
+ "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.10.4.tgz",
+ "integrity": "sha512-YdaSyz1n8gY44EmN7x44zBn9zQ1Ry2Y+3GTA+3vH6Mizke1Vw0aWDM66FOYEPw8//qKkmqOckrGgTYa+6sceqQ==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-get-function-arity": "^7.10.4",
+ "@babel/template": "^7.10.4",
+ "@babel/types": "^7.10.4"
+ }
+ },
+ "node_modules/@babel/helper-get-function-arity": {
+ "version": "7.10.4",
+ "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.10.4.tgz",
+ "integrity": "sha512-EkN3YDB+SRDgiIUnNgcmiD361ti+AVbL3f3Henf6dqqUyr5dMsorno0lJWJuLhDhkI5sYEpgj6y9kB8AOU1I2A==",
+ "dev": true,
+ "dependencies": {
+ "@babel/types": "^7.10.4"
+ }
+ },
+ "node_modules/@babel/helper-hoist-variables": {
+ "version": "7.10.4",
+ "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.10.4.tgz",
+ "integrity": "sha512-wljroF5PgCk2juF69kanHVs6vrLwIPNp6DLD+Lrl3hoQ3PpPPikaDRNFA+0t81NOoMt2DL6WW/mdU8k4k6ZzuA==",
+ "dev": true,
+ "dependencies": {
+ "@babel/types": "^7.10.4"
+ }
+ },
+ "node_modules/@babel/helper-member-expression-to-functions": {
+ "version": "7.12.1",
+ "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.12.1.tgz",
+ "integrity": "sha512-k0CIe3tXUKTRSoEx1LQEPFU9vRQfqHtl+kf8eNnDqb4AUJEy5pz6aIiog+YWtVm2jpggjS1laH68bPsR+KWWPQ==",
+ "dev": true,
+ "dependencies": {
+ "@babel/types": "^7.12.1"
+ }
+ },
+ "node_modules/@babel/helper-module-imports": {
+ "version": "7.12.5",
+ "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.12.5.tgz",
+ "integrity": "sha512-SR713Ogqg6++uexFRORf/+nPXMmWIn80TALu0uaFb+iQIUoR7bOC7zBWyzBs5b3tBBJXuyD0cRu1F15GyzjOWA==",
+ "dev": true,
+ "dependencies": {
+ "@babel/types": "^7.12.5"
+ }
+ },
+ "node_modules/@babel/helper-module-transforms": {
+ "version": "7.12.1",
+ "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.12.1.tgz",
+ "integrity": "sha512-QQzehgFAZ2bbISiCpmVGfiGux8YVFXQ0abBic2Envhej22DVXV9nCFaS5hIQbkyo1AdGb+gNME2TSh3hYJVV/w==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-module-imports": "^7.12.1",
+ "@babel/helper-replace-supers": "^7.12.1",
+ "@babel/helper-simple-access": "^7.12.1",
+ "@babel/helper-split-export-declaration": "^7.11.0",
+ "@babel/helper-validator-identifier": "^7.10.4",
+ "@babel/template": "^7.10.4",
+ "@babel/traverse": "^7.12.1",
+ "@babel/types": "^7.12.1",
+ "lodash": "^4.17.19"
+ }
+ },
+ "node_modules/@babel/helper-optimise-call-expression": {
+ "version": "7.10.4",
+ "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.10.4.tgz",
+ "integrity": "sha512-n3UGKY4VXwXThEiKrgRAoVPBMqeoPgHVqiHZOanAJCG9nQUL2pLRQirUzl0ioKclHGpGqRgIOkgcIJaIWLpygg==",
+ "dev": true,
+ "dependencies": {
+ "@babel/types": "^7.10.4"
+ }
+ },
+ "node_modules/@babel/helper-plugin-utils": {
+ "version": "7.10.4",
+ "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.10.4.tgz",
+ "integrity": "sha512-O4KCvQA6lLiMU9l2eawBPMf1xPP8xPfB3iEQw150hOVTqj/rfXz0ThTb4HEzqQfs2Bmo5Ay8BzxfzVtBrr9dVg==",
+ "dev": true
+ },
+ "node_modules/@babel/helper-regex": {
+ "version": "7.10.5",
+ "resolved": "https://registry.npmjs.org/@babel/helper-regex/-/helper-regex-7.10.5.tgz",
+ "integrity": "sha512-68kdUAzDrljqBrio7DYAEgCoJHxppJOERHOgOrDN7WjOzP0ZQ1LsSDRXcemzVZaLvjaJsJEESb6qt+znNuENDg==",
+ "dev": true,
+ "dependencies": {
+ "lodash": "^4.17.19"
+ }
+ },
+ "node_modules/@babel/helper-remap-async-to-generator": {
+ "version": "7.12.1",
+ "resolved": "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.12.1.tgz",
+ "integrity": "sha512-9d0KQCRM8clMPcDwo8SevNs+/9a8yWVVmaE80FGJcEP8N1qToREmWEGnBn8BUlJhYRFz6fqxeRL1sl5Ogsed7A==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-annotate-as-pure": "^7.10.4",
+ "@babel/helper-wrap-function": "^7.10.4",
+ "@babel/types": "^7.12.1"
+ }
+ },
+ "node_modules/@babel/helper-replace-supers": {
+ "version": "7.12.5",
+ "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.12.5.tgz",
+ "integrity": "sha512-5YILoed0ZyIpF4gKcpZitEnXEJ9UoDRki1Ey6xz46rxOzfNMAhVIJMoune1hmPVxh40LRv1+oafz7UsWX+vyWA==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-member-expression-to-functions": "^7.12.1",
+ "@babel/helper-optimise-call-expression": "^7.10.4",
+ "@babel/traverse": "^7.12.5",
+ "@babel/types": "^7.12.5"
+ }
+ },
+ "node_modules/@babel/helper-simple-access": {
+ "version": "7.12.1",
+ "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.12.1.tgz",
+ "integrity": "sha512-OxBp7pMrjVewSSC8fXDFrHrBcJATOOFssZwv16F3/6Xtc138GHybBfPbm9kfiqQHKhYQrlamWILwlDCeyMFEaA==",
+ "dev": true,
+ "dependencies": {
+ "@babel/types": "^7.12.1"
+ }
+ },
+ "node_modules/@babel/helper-skip-transparent-expression-wrappers": {
+ "version": "7.12.1",
+ "resolved": "https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.12.1.tgz",
+ "integrity": "sha512-Mf5AUuhG1/OCChOJ/HcADmvcHM42WJockombn8ATJG3OnyiSxBK/Mm5x78BQWvmtXZKHgbjdGL2kin/HOLlZGA==",
+ "dev": true,
+ "dependencies": {
+ "@babel/types": "^7.12.1"
+ }
+ },
+ "node_modules/@babel/helper-split-export-declaration": {
+ "version": "7.11.0",
+ "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.11.0.tgz",
+ "integrity": "sha512-74Vejvp6mHkGE+m+k5vHY93FX2cAtrw1zXrZXRlG4l410Nm9PxfEiVTn1PjDPV5SnmieiueY4AFg2xqhNFuuZg==",
+ "dev": true,
+ "dependencies": {
+ "@babel/types": "^7.11.0"
+ }
+ },
+ "node_modules/@babel/helper-string-parser": {
+ "version": "7.22.5",
+ "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.22.5.tgz",
+ "integrity": "sha512-mM4COjgZox8U+JcXQwPijIZLElkgEpO5rsERVDJTc2qfCDfERyob6k5WegS14SX18IIjv+XD+GrqNumY5JRCDw==",
+ "dev": true,
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-validator-identifier": {
+ "version": "7.10.4",
+ "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.10.4.tgz",
+ "integrity": "sha512-3U9y+43hz7ZM+rzG24Qe2mufW5KhvFg/NhnNph+i9mgCtdTCtMJuI1TMkrIUiK7Ix4PYlRF9I5dhqaLYA/ADXw==",
+ "dev": true
+ },
+ "node_modules/@babel/helper-validator-option": {
+ "version": "7.12.1",
+ "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.12.1.tgz",
+ "integrity": "sha512-YpJabsXlJVWP0USHjnC/AQDTLlZERbON577YUVO/wLpqyj6HAtVYnWaQaN0iUN+1/tWn3c+uKKXjRut5115Y2A==",
+ "dev": true
+ },
+ "node_modules/@babel/helper-wrap-function": {
+ "version": "7.12.3",
+ "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.12.3.tgz",
+ "integrity": "sha512-Cvb8IuJDln3rs6tzjW3Y8UeelAOdnpB8xtQ4sme2MSZ9wOxrbThporC0y/EtE16VAtoyEfLM404Xr1e0OOp+ow==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-function-name": "^7.10.4",
+ "@babel/template": "^7.10.4",
+ "@babel/traverse": "^7.10.4",
+ "@babel/types": "^7.10.4"
+ }
+ },
+ "node_modules/@babel/helpers": {
+ "version": "7.12.5",
+ "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.12.5.tgz",
+ "integrity": "sha512-lgKGMQlKqA8meJqKsW6rUnc4MdUk35Ln0ATDqdM1a/UpARODdI4j5Y5lVfUScnSNkJcdCRAaWkspykNoFg9sJA==",
+ "dev": true,
+ "dependencies": {
+ "@babel/template": "^7.10.4",
+ "@babel/traverse": "^7.12.5",
+ "@babel/types": "^7.12.5"
+ }
+ },
+ "node_modules/@babel/highlight": {
+ "version": "7.10.4",
+ "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.10.4.tgz",
+ "integrity": "sha512-i6rgnR/YgPEQzZZnbTHHuZdlE8qyoBNalD6F+q4vAFlcMEcqmkoG+mPqJYJCo63qPf74+Y1UZsl3l6f7/RIkmA==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-validator-identifier": "^7.10.4",
+ "chalk": "^2.0.0",
+ "js-tokens": "^4.0.0"
+ }
+ },
+ "node_modules/@babel/parser": {
+ "version": "7.12.5",
+ "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.12.5.tgz",
+ "integrity": "sha512-FVM6RZQ0mn2KCf1VUED7KepYeUWoVShczewOCfm3nzoBybaih51h+sYVVGthW9M6lPByEPTQf+xm27PBdlpwmQ==",
+ "dev": true,
+ "bin": {
+ "parser": "bin/babel-parser.js"
+ },
+ "engines": {
+ "node": ">=6.0.0"
+ }
+ },
+ "node_modules/@babel/plugin-proposal-async-generator-functions": {
+ "version": "7.12.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.12.1.tgz",
+ "integrity": "sha512-d+/o30tJxFxrA1lhzJqiUcEJdI6jKlNregCv5bASeGf2Q4MXmnwH7viDo7nhx1/ohf09oaH8j1GVYG/e3Yqk6A==",
+ "deprecated": "This proposal has been merged to the ECMAScript standard and thus this plugin is no longer maintained. Please use @babel/plugin-transform-async-generator-functions instead.",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.10.4",
+ "@babel/helper-remap-async-to-generator": "^7.12.1",
+ "@babel/plugin-syntax-async-generators": "^7.8.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-proposal-class-properties": {
+ "version": "7.12.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.12.1.tgz",
+ "integrity": "sha512-cKp3dlQsFsEs5CWKnN7BnSHOd0EOW8EKpEjkoz1pO2E5KzIDNV9Ros1b0CnmbVgAGXJubOYVBOGCT1OmJwOI7w==",
+ "deprecated": "This proposal has been merged to the ECMAScript standard and thus this plugin is no longer maintained. Please use @babel/plugin-transform-class-properties instead.",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-create-class-features-plugin": "^7.12.1",
+ "@babel/helper-plugin-utils": "^7.10.4"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-proposal-dynamic-import": {
+ "version": "7.12.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-dynamic-import/-/plugin-proposal-dynamic-import-7.12.1.tgz",
+ "integrity": "sha512-a4rhUSZFuq5W8/OO8H7BL5zspjnc1FLd9hlOxIK/f7qG4a0qsqk8uvF/ywgBA8/OmjsapjpvaEOYItfGG1qIvQ==",
+ "deprecated": "This proposal has been merged to the ECMAScript standard and thus this plugin is no longer maintained. Please use @babel/plugin-transform-dynamic-import instead.",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.10.4",
+ "@babel/plugin-syntax-dynamic-import": "^7.8.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-proposal-export-namespace-from": {
+ "version": "7.12.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-export-namespace-from/-/plugin-proposal-export-namespace-from-7.12.1.tgz",
+ "integrity": "sha512-6CThGf0irEkzujYS5LQcjBx8j/4aQGiVv7J9+2f7pGfxqyKh3WnmVJYW3hdrQjyksErMGBPQrCnHfOtna+WLbw==",
+ "deprecated": "This proposal has been merged to the ECMAScript standard and thus this plugin is no longer maintained. Please use @babel/plugin-transform-export-namespace-from instead.",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.10.4",
+ "@babel/plugin-syntax-export-namespace-from": "^7.8.3"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-proposal-json-strings": {
+ "version": "7.12.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-json-strings/-/plugin-proposal-json-strings-7.12.1.tgz",
+ "integrity": "sha512-GoLDUi6U9ZLzlSda2Df++VSqDJg3CG+dR0+iWsv6XRw1rEq+zwt4DirM9yrxW6XWaTpmai1cWJLMfM8qQJf+yw==",
+ "deprecated": "This proposal has been merged to the ECMAScript standard and thus this plugin is no longer maintained. Please use @babel/plugin-transform-json-strings instead.",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.10.4",
+ "@babel/plugin-syntax-json-strings": "^7.8.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-proposal-logical-assignment-operators": {
+ "version": "7.12.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-logical-assignment-operators/-/plugin-proposal-logical-assignment-operators-7.12.1.tgz",
+ "integrity": "sha512-k8ZmVv0JU+4gcUGeCDZOGd0lCIamU/sMtIiX3UWnUc5yzgq6YUGyEolNYD+MLYKfSzgECPcqetVcJP9Afe/aCA==",
+ "deprecated": "This proposal has been merged to the ECMAScript standard and thus this plugin is no longer maintained. Please use @babel/plugin-transform-logical-assignment-operators instead.",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.10.4",
+ "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-proposal-nullish-coalescing-operator": {
+ "version": "7.12.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-nullish-coalescing-operator/-/plugin-proposal-nullish-coalescing-operator-7.12.1.tgz",
+ "integrity": "sha512-nZY0ESiaQDI1y96+jk6VxMOaL4LPo/QDHBqL+SF3/vl6dHkTwHlOI8L4ZwuRBHgakRBw5zsVylel7QPbbGuYgg==",
+ "deprecated": "This proposal has been merged to the ECMAScript standard and thus this plugin is no longer maintained. Please use @babel/plugin-transform-nullish-coalescing-operator instead.",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.10.4",
+ "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-proposal-numeric-separator": {
+ "version": "7.12.5",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-numeric-separator/-/plugin-proposal-numeric-separator-7.12.5.tgz",
+ "integrity": "sha512-UiAnkKuOrCyjZ3sYNHlRlfuZJbBHknMQ9VMwVeX97Ofwx7RpD6gS2HfqTCh8KNUQgcOm8IKt103oR4KIjh7Q8g==",
+ "deprecated": "This proposal has been merged to the ECMAScript standard and thus this plugin is no longer maintained. Please use @babel/plugin-transform-numeric-separator instead.",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.10.4",
+ "@babel/plugin-syntax-numeric-separator": "^7.10.4"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-proposal-object-rest-spread": {
+ "version": "7.12.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.12.1.tgz",
+ "integrity": "sha512-s6SowJIjzlhx8o7lsFx5zmY4At6CTtDvgNQDdPzkBQucle58A6b/TTeEBYtyDgmcXjUTM+vE8YOGHZzzbc/ioA==",
+ "deprecated": "This proposal has been merged to the ECMAScript standard and thus this plugin is no longer maintained. Please use @babel/plugin-transform-object-rest-spread instead.",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.10.4",
+ "@babel/plugin-syntax-object-rest-spread": "^7.8.0",
+ "@babel/plugin-transform-parameters": "^7.12.1"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-proposal-optional-catch-binding": {
+ "version": "7.12.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-catch-binding/-/plugin-proposal-optional-catch-binding-7.12.1.tgz",
+ "integrity": "sha512-hFvIjgprh9mMw5v42sJWLI1lzU5L2sznP805zeT6rySVRA0Y18StRhDqhSxlap0oVgItRsB6WSROp4YnJTJz0g==",
+ "deprecated": "This proposal has been merged to the ECMAScript standard and thus this plugin is no longer maintained. Please use @babel/plugin-transform-optional-catch-binding instead.",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.10.4",
+ "@babel/plugin-syntax-optional-catch-binding": "^7.8.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-proposal-optional-chaining": {
+ "version": "7.12.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.12.1.tgz",
+ "integrity": "sha512-c2uRpY6WzaVDzynVY9liyykS+kVU+WRZPMPYpkelXH8KBt1oXoI89kPbZKKG/jDT5UK92FTW2fZkZaJhdiBabw==",
+ "deprecated": "This proposal has been merged to the ECMAScript standard and thus this plugin is no longer maintained. Please use @babel/plugin-transform-optional-chaining instead.",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.10.4",
+ "@babel/helper-skip-transparent-expression-wrappers": "^7.12.1",
+ "@babel/plugin-syntax-optional-chaining": "^7.8.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-proposal-private-methods": {
+ "version": "7.12.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-methods/-/plugin-proposal-private-methods-7.12.1.tgz",
+ "integrity": "sha512-mwZ1phvH7/NHK6Kf8LP7MYDogGV+DKB1mryFOEwx5EBNQrosvIczzZFTUmWaeujd5xT6G1ELYWUz3CutMhjE1w==",
+ "deprecated": "This proposal has been merged to the ECMAScript standard and thus this plugin is no longer maintained. Please use @babel/plugin-transform-private-methods instead.",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-create-class-features-plugin": "^7.12.1",
+ "@babel/helper-plugin-utils": "^7.10.4"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-proposal-unicode-property-regex": {
+ "version": "7.12.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-unicode-property-regex/-/plugin-proposal-unicode-property-regex-7.12.1.tgz",
+ "integrity": "sha512-MYq+l+PvHuw/rKUz1at/vb6nCnQ2gmJBNaM62z0OgH7B2W1D9pvkpYtlti9bGtizNIU1K3zm4bZF9F91efVY0w==",
+ "deprecated": "This proposal has been merged to the ECMAScript standard and thus this plugin is no longer maintained. Please use @babel/plugin-transform-unicode-property-regex instead.",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-create-regexp-features-plugin": "^7.12.1",
+ "@babel/helper-plugin-utils": "^7.10.4"
+ },
+ "engines": {
+ "node": ">=4"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-syntax-async-generators": {
+ "version": "7.8.4",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz",
+ "integrity": "sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.8.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-syntax-class-properties": {
+ "version": "7.12.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.1.tgz",
+ "integrity": "sha512-U40A76x5gTwmESz+qiqssqmeEsKvcSyvtgktrm0uzcARAmM9I1jR221f6Oq+GmHrcD+LvZDag1UTOTe2fL3TeA==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.10.4"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-syntax-dynamic-import": {
+ "version": "7.8.3",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-dynamic-import/-/plugin-syntax-dynamic-import-7.8.3.tgz",
+ "integrity": "sha512-5gdGbFon+PszYzqs83S3E5mpi7/y/8M9eC90MRTZfduQOYW76ig6SOSPNe41IG5LoP3FGBn2N0RjVDSQiS94kQ==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.8.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-syntax-export-namespace-from": {
+ "version": "7.8.3",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-export-namespace-from/-/plugin-syntax-export-namespace-from-7.8.3.tgz",
+ "integrity": "sha512-MXf5laXo6c1IbEbegDmzGPwGNTsHZmEy6QGznu5Sh2UCWvueywb2ee+CCE4zQiZstxU9BMoQO9i6zUFSY0Kj0Q==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.8.3"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-syntax-json-strings": {
+ "version": "7.8.3",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz",
+ "integrity": "sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.8.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-syntax-logical-assignment-operators": {
+ "version": "7.10.4",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz",
+ "integrity": "sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.10.4"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-syntax-nullish-coalescing-operator": {
+ "version": "7.8.3",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz",
+ "integrity": "sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.8.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-syntax-numeric-separator": {
+ "version": "7.10.4",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.10.4.tgz",
+ "integrity": "sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.10.4"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-syntax-object-rest-spread": {
+ "version": "7.8.3",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz",
+ "integrity": "sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.8.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-syntax-optional-catch-binding": {
+ "version": "7.8.3",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz",
+ "integrity": "sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.8.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-syntax-optional-chaining": {
+ "version": "7.8.3",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.8.3.tgz",
+ "integrity": "sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.8.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-syntax-top-level-await": {
+ "version": "7.12.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.12.1.tgz",
+ "integrity": "sha512-i7ooMZFS+a/Om0crxZodrTzNEPJHZrlMVGMTEpFAj6rYY/bKCddB0Dk/YxfPuYXOopuhKk/e1jV6h+WUU9XN3A==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.10.4"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-arrow-functions": {
+ "version": "7.12.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.12.1.tgz",
+ "integrity": "sha512-5QB50qyN44fzzz4/qxDPQMBCTHgxg3n0xRBLJUmBlLoU/sFvxVWGZF/ZUfMVDQuJUKXaBhbupxIzIfZ6Fwk/0A==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.10.4"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-async-to-generator": {
+ "version": "7.12.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.12.1.tgz",
+ "integrity": "sha512-SDtqoEcarK1DFlRJ1hHRY5HvJUj5kX4qmtpMAm2QnhOlyuMC4TMdCRgW6WXpv93rZeYNeLP22y8Aq2dbcDRM1A==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-module-imports": "^7.12.1",
+ "@babel/helper-plugin-utils": "^7.10.4",
+ "@babel/helper-remap-async-to-generator": "^7.12.1"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-block-scoped-functions": {
+ "version": "7.12.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.12.1.tgz",
+ "integrity": "sha512-5OpxfuYnSgPalRpo8EWGPzIYf0lHBWORCkj5M0oLBwHdlux9Ri36QqGW3/LR13RSVOAoUUMzoPI/jpE4ABcHoA==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.10.4"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-block-scoping": {
+ "version": "7.12.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.12.1.tgz",
+ "integrity": "sha512-zJyAC9sZdE60r1nVQHblcfCj29Dh2Y0DOvlMkcqSo0ckqjiCwNiUezUKw+RjOCwGfpLRwnAeQ2XlLpsnGkvv9w==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.10.4"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-classes": {
+ "version": "7.12.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.12.1.tgz",
+ "integrity": "sha512-/74xkA7bVdzQTBeSUhLLJgYIcxw/dpEpCdRDiHgPJ3Mv6uC11UhjpOhl72CgqbBCmt1qtssCyB2xnJm1+PFjog==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-annotate-as-pure": "^7.10.4",
+ "@babel/helper-define-map": "^7.10.4",
+ "@babel/helper-function-name": "^7.10.4",
+ "@babel/helper-optimise-call-expression": "^7.10.4",
+ "@babel/helper-plugin-utils": "^7.10.4",
+ "@babel/helper-replace-supers": "^7.12.1",
+ "@babel/helper-split-export-declaration": "^7.10.4",
+ "globals": "^11.1.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-computed-properties": {
+ "version": "7.12.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.12.1.tgz",
+ "integrity": "sha512-vVUOYpPWB7BkgUWPo4C44mUQHpTZXakEqFjbv8rQMg7TC6S6ZhGZ3otQcRH6u7+adSlE5i0sp63eMC/XGffrzg==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.10.4"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-destructuring": {
+ "version": "7.12.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.12.1.tgz",
+ "integrity": "sha512-fRMYFKuzi/rSiYb2uRLiUENJOKq4Gnl+6qOv5f8z0TZXg3llUwUhsNNwrwaT/6dUhJTzNpBr+CUvEWBtfNY1cw==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.10.4"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-dotall-regex": {
+ "version": "7.12.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.12.1.tgz",
+ "integrity": "sha512-B2pXeRKoLszfEW7J4Hg9LoFaWEbr/kzo3teWHmtFCszjRNa/b40f9mfeqZsIDLLt/FjwQ6pz/Gdlwy85xNckBA==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-create-regexp-features-plugin": "^7.12.1",
+ "@babel/helper-plugin-utils": "^7.10.4"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-duplicate-keys": {
+ "version": "7.12.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.12.1.tgz",
+ "integrity": "sha512-iRght0T0HztAb/CazveUpUQrZY+aGKKaWXMJ4uf9YJtqxSUe09j3wteztCUDRHs+SRAL7yMuFqUsLoAKKzgXjw==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.10.4"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-exponentiation-operator": {
+ "version": "7.12.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.12.1.tgz",
+ "integrity": "sha512-7tqwy2bv48q+c1EHbXK0Zx3KXd2RVQp6OC7PbwFNt/dPTAV3Lu5sWtWuAj8owr5wqtWnqHfl2/mJlUmqkChKug==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-builder-binary-assignment-operator-visitor": "^7.10.4",
+ "@babel/helper-plugin-utils": "^7.10.4"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-for-of": {
+ "version": "7.12.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.12.1.tgz",
+ "integrity": "sha512-Zaeq10naAsuHo7heQvyV0ptj4dlZJwZgNAtBYBnu5nNKJoW62m0zKcIEyVECrUKErkUkg6ajMy4ZfnVZciSBhg==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.10.4"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-function-name": {
+ "version": "7.12.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.12.1.tgz",
+ "integrity": "sha512-JF3UgJUILoFrFMEnOJLJkRHSk6LUSXLmEFsA23aR2O5CSLUxbeUX1IZ1YQ7Sn0aXb601Ncwjx73a+FVqgcljVw==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-function-name": "^7.10.4",
+ "@babel/helper-plugin-utils": "^7.10.4"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-literals": {
+ "version": "7.12.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.12.1.tgz",
+ "integrity": "sha512-+PxVGA+2Ag6uGgL0A5f+9rklOnnMccwEBzwYFL3EUaKuiyVnUipyXncFcfjSkbimLrODoqki1U9XxZzTvfN7IQ==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.10.4"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-member-expression-literals": {
+ "version": "7.12.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.12.1.tgz",
+ "integrity": "sha512-1sxePl6z9ad0gFMB9KqmYofk34flq62aqMt9NqliS/7hPEpURUCMbyHXrMPlo282iY7nAvUB1aQd5mg79UD9Jg==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.10.4"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-modules-amd": {
+ "version": "7.12.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.12.1.tgz",
+ "integrity": "sha512-tDW8hMkzad5oDtzsB70HIQQRBiTKrhfgwC/KkJeGsaNFTdWhKNt/BiE8c5yj19XiGyrxpbkOfH87qkNg1YGlOQ==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-module-transforms": "^7.12.1",
+ "@babel/helper-plugin-utils": "^7.10.4",
+ "babel-plugin-dynamic-import-node": "^2.3.3"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-modules-commonjs": {
+ "version": "7.12.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.12.1.tgz",
+ "integrity": "sha512-dY789wq6l0uLY8py9c1B48V8mVL5gZh/+PQ5ZPrylPYsnAvnEMjqsUXkuoDVPeVK+0VyGar+D08107LzDQ6pag==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-module-transforms": "^7.12.1",
+ "@babel/helper-plugin-utils": "^7.10.4",
+ "@babel/helper-simple-access": "^7.12.1",
+ "babel-plugin-dynamic-import-node": "^2.3.3"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-modules-systemjs": {
+ "version": "7.12.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.12.1.tgz",
+ "integrity": "sha512-Hn7cVvOavVh8yvW6fLwveFqSnd7rbQN3zJvoPNyNaQSvgfKmDBO9U1YL9+PCXGRlZD9tNdWTy5ACKqMuzyn32Q==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-hoist-variables": "^7.10.4",
+ "@babel/helper-module-transforms": "^7.12.1",
+ "@babel/helper-plugin-utils": "^7.10.4",
+ "@babel/helper-validator-identifier": "^7.10.4",
+ "babel-plugin-dynamic-import-node": "^2.3.3"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-modules-umd": {
+ "version": "7.12.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.12.1.tgz",
+ "integrity": "sha512-aEIubCS0KHKM0zUos5fIoQm+AZUMt1ZvMpqz0/H5qAQ7vWylr9+PLYurT+Ic7ID/bKLd4q8hDovaG3Zch2uz5Q==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-module-transforms": "^7.12.1",
+ "@babel/helper-plugin-utils": "^7.10.4"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-named-capturing-groups-regex": {
+ "version": "7.12.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.12.1.tgz",
+ "integrity": "sha512-tB43uQ62RHcoDp9v2Nsf+dSM8sbNodbEicbQNA53zHz8pWUhsgHSJCGpt7daXxRydjb0KnfmB+ChXOv3oADp1Q==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-create-regexp-features-plugin": "^7.12.1"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-new-target": {
+ "version": "7.12.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.12.1.tgz",
+ "integrity": "sha512-+eW/VLcUL5L9IvJH7rT1sT0CzkdUTvPrXC2PXTn/7z7tXLBuKvezYbGdxD5WMRoyvyaujOq2fWoKl869heKjhw==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.10.4"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-object-super": {
+ "version": "7.12.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.12.1.tgz",
+ "integrity": "sha512-AvypiGJH9hsquNUn+RXVcBdeE3KHPZexWRdimhuV59cSoOt5kFBmqlByorAeUlGG2CJWd0U+4ZtNKga/TB0cAw==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.10.4",
+ "@babel/helper-replace-supers": "^7.12.1"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-parameters": {
+ "version": "7.12.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.12.1.tgz",
+ "integrity": "sha512-xq9C5EQhdPK23ZeCdMxl8bbRnAgHFrw5EOC3KJUsSylZqdkCaFEXxGSBuTSObOpiiHHNyb82es8M1QYgfQGfNg==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.10.4"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-property-literals": {
+ "version": "7.12.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.12.1.tgz",
+ "integrity": "sha512-6MTCR/mZ1MQS+AwZLplX4cEySjCpnIF26ToWo942nqn8hXSm7McaHQNeGx/pt7suI1TWOWMfa/NgBhiqSnX0cQ==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.10.4"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-regenerator": {
+ "version": "7.12.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.12.1.tgz",
+ "integrity": "sha512-gYrHqs5itw6i4PflFX3OdBPMQdPbF4bj2REIUxlMRUFk0/ZOAIpDFuViuxPjUL7YC8UPnf+XG7/utJvqXdPKng==",
+ "dev": true,
+ "dependencies": {
+ "regenerator-transform": "^0.14.2"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-reserved-words": {
+ "version": "7.12.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.12.1.tgz",
+ "integrity": "sha512-pOnUfhyPKvZpVyBHhSBoX8vfA09b7r00Pmm1sH+29ae2hMTKVmSp4Ztsr8KBKjLjx17H0eJqaRC3bR2iThM54A==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.10.4"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-runtime": {
+ "version": "7.12.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.12.1.tgz",
+ "integrity": "sha512-Ac/H6G9FEIkS2tXsZjL4RAdS3L3WHxci0usAnz7laPWUmFiGtj7tIASChqKZMHTSQTQY6xDbOq+V1/vIq3QrWg==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-module-imports": "^7.12.1",
+ "@babel/helper-plugin-utils": "^7.10.4",
+ "resolve": "^1.8.1",
+ "semver": "^5.5.1"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-shorthand-properties": {
+ "version": "7.12.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.12.1.tgz",
+ "integrity": "sha512-GFZS3c/MhX1OusqB1MZ1ct2xRzX5ppQh2JU1h2Pnfk88HtFTM+TWQqJNfwkmxtPQtb/s1tk87oENfXJlx7rSDw==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.10.4"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-spread": {
+ "version": "7.12.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.12.1.tgz",
+ "integrity": "sha512-vuLp8CP0BE18zVYjsEBZ5xoCecMK6LBMMxYzJnh01rxQRvhNhH1csMMmBfNo5tGpGO+NhdSNW2mzIvBu3K1fng==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.10.4",
+ "@babel/helper-skip-transparent-expression-wrappers": "^7.12.1"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-sticky-regex": {
+ "version": "7.12.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.12.1.tgz",
+ "integrity": "sha512-CiUgKQ3AGVk7kveIaPEET1jNDhZZEl1RPMWdTBE1799bdz++SwqDHStmxfCtDfBhQgCl38YRiSnrMuUMZIWSUQ==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.10.4",
+ "@babel/helper-regex": "^7.10.4"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-template-literals": {
+ "version": "7.12.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.12.1.tgz",
+ "integrity": "sha512-b4Zx3KHi+taXB1dVRBhVJtEPi9h1THCeKmae2qP0YdUHIFhVjtpqqNfxeVAa1xeHVhAy4SbHxEwx5cltAu5apw==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.10.4"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-typeof-symbol": {
+ "version": "7.12.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.12.1.tgz",
+ "integrity": "sha512-EPGgpGy+O5Kg5pJFNDKuxt9RdmTgj5sgrus2XVeMp/ZIbOESadgILUbm50SNpghOh3/6yrbsH+NB5+WJTmsA7Q==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.10.4"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-unicode-escapes": {
+ "version": "7.12.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.12.1.tgz",
+ "integrity": "sha512-I8gNHJLIc7GdApm7wkVnStWssPNbSRMPtgHdmH3sRM1zopz09UWPS4x5V4n1yz/MIWTVnJ9sp6IkuXdWM4w+2Q==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.10.4"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-unicode-regex": {
+ "version": "7.12.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.12.1.tgz",
+ "integrity": "sha512-SqH4ClNngh/zGwHZOOQMTD+e8FGWexILV+ePMyiDJttAWRh5dhDL8rcl5lSgU3Huiq6Zn6pWTMvdPAb21Dwdyg==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-create-regexp-features-plugin": "^7.12.1",
+ "@babel/helper-plugin-utils": "^7.10.4"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/preset-env": {
+ "version": "7.12.1",
+ "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.12.1.tgz",
+ "integrity": "sha512-H8kxXmtPaAGT7TyBvSSkoSTUK6RHh61So05SyEbpmr0MCZrsNYn7mGMzzeYoOUCdHzww61k8XBft2TaES+xPLg==",
+ "dev": true,
+ "dependencies": {
+ "@babel/compat-data": "^7.12.1",
+ "@babel/helper-compilation-targets": "^7.12.1",
+ "@babel/helper-module-imports": "^7.12.1",
+ "@babel/helper-plugin-utils": "^7.10.4",
+ "@babel/helper-validator-option": "^7.12.1",
+ "@babel/plugin-proposal-async-generator-functions": "^7.12.1",
+ "@babel/plugin-proposal-class-properties": "^7.12.1",
+ "@babel/plugin-proposal-dynamic-import": "^7.12.1",
+ "@babel/plugin-proposal-export-namespace-from": "^7.12.1",
+ "@babel/plugin-proposal-json-strings": "^7.12.1",
+ "@babel/plugin-proposal-logical-assignment-operators": "^7.12.1",
+ "@babel/plugin-proposal-nullish-coalescing-operator": "^7.12.1",
+ "@babel/plugin-proposal-numeric-separator": "^7.12.1",
+ "@babel/plugin-proposal-object-rest-spread": "^7.12.1",
+ "@babel/plugin-proposal-optional-catch-binding": "^7.12.1",
+ "@babel/plugin-proposal-optional-chaining": "^7.12.1",
+ "@babel/plugin-proposal-private-methods": "^7.12.1",
+ "@babel/plugin-proposal-unicode-property-regex": "^7.12.1",
+ "@babel/plugin-syntax-async-generators": "^7.8.0",
+ "@babel/plugin-syntax-class-properties": "^7.12.1",
+ "@babel/plugin-syntax-dynamic-import": "^7.8.0",
+ "@babel/plugin-syntax-export-namespace-from": "^7.8.3",
+ "@babel/plugin-syntax-json-strings": "^7.8.0",
+ "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4",
+ "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.0",
+ "@babel/plugin-syntax-numeric-separator": "^7.10.4",
+ "@babel/plugin-syntax-object-rest-spread": "^7.8.0",
+ "@babel/plugin-syntax-optional-catch-binding": "^7.8.0",
+ "@babel/plugin-syntax-optional-chaining": "^7.8.0",
+ "@babel/plugin-syntax-top-level-await": "^7.12.1",
+ "@babel/plugin-transform-arrow-functions": "^7.12.1",
+ "@babel/plugin-transform-async-to-generator": "^7.12.1",
+ "@babel/plugin-transform-block-scoped-functions": "^7.12.1",
+ "@babel/plugin-transform-block-scoping": "^7.12.1",
+ "@babel/plugin-transform-classes": "^7.12.1",
+ "@babel/plugin-transform-computed-properties": "^7.12.1",
+ "@babel/plugin-transform-destructuring": "^7.12.1",
+ "@babel/plugin-transform-dotall-regex": "^7.12.1",
+ "@babel/plugin-transform-duplicate-keys": "^7.12.1",
+ "@babel/plugin-transform-exponentiation-operator": "^7.12.1",
+ "@babel/plugin-transform-for-of": "^7.12.1",
+ "@babel/plugin-transform-function-name": "^7.12.1",
+ "@babel/plugin-transform-literals": "^7.12.1",
+ "@babel/plugin-transform-member-expression-literals": "^7.12.1",
+ "@babel/plugin-transform-modules-amd": "^7.12.1",
+ "@babel/plugin-transform-modules-commonjs": "^7.12.1",
+ "@babel/plugin-transform-modules-systemjs": "^7.12.1",
+ "@babel/plugin-transform-modules-umd": "^7.12.1",
+ "@babel/plugin-transform-named-capturing-groups-regex": "^7.12.1",
+ "@babel/plugin-transform-new-target": "^7.12.1",
+ "@babel/plugin-transform-object-super": "^7.12.1",
+ "@babel/plugin-transform-parameters": "^7.12.1",
+ "@babel/plugin-transform-property-literals": "^7.12.1",
+ "@babel/plugin-transform-regenerator": "^7.12.1",
+ "@babel/plugin-transform-reserved-words": "^7.12.1",
+ "@babel/plugin-transform-shorthand-properties": "^7.12.1",
+ "@babel/plugin-transform-spread": "^7.12.1",
+ "@babel/plugin-transform-sticky-regex": "^7.12.1",
+ "@babel/plugin-transform-template-literals": "^7.12.1",
+ "@babel/plugin-transform-typeof-symbol": "^7.12.1",
+ "@babel/plugin-transform-unicode-escapes": "^7.12.1",
+ "@babel/plugin-transform-unicode-regex": "^7.12.1",
+ "@babel/preset-modules": "^0.1.3",
+ "@babel/types": "^7.12.1",
+ "core-js-compat": "^3.6.2",
+ "semver": "^5.5.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/preset-modules": {
+ "version": "0.1.4",
+ "resolved": "https://registry.npmjs.org/@babel/preset-modules/-/preset-modules-0.1.4.tgz",
+ "integrity": "sha512-J36NhwnfdzpmH41M1DrnkkgAqhZaqr/NBdPfQ677mLzlaXo+oDiv1deyCDtgAhz8p328otdob0Du7+xgHGZbKg==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.0.0",
+ "@babel/plugin-proposal-unicode-property-regex": "^7.4.4",
+ "@babel/plugin-transform-dotall-regex": "^7.4.4",
+ "@babel/types": "^7.4.4",
+ "esutils": "^2.0.2"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/runtime": {
+ "version": "7.12.5",
+ "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.12.5.tgz",
+ "integrity": "sha512-plcc+hbExy3McchJCEQG3knOsuh3HH+Prx1P6cLIkET/0dLuQDEnrT+s27Axgc9bqfsmNUNHfscgMUdBpC9xfg==",
+ "dependencies": {
+ "regenerator-runtime": "^0.13.4"
+ }
+ },
+ "node_modules/@babel/template": {
+ "version": "7.10.4",
+ "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.10.4.tgz",
+ "integrity": "sha512-ZCjD27cGJFUB6nmCB1Enki3r+L5kJveX9pq1SvAUKoICy6CZ9yD8xO086YXdYhvNjBdnekm4ZnaP5yC8Cs/1tA==",
+ "dev": true,
+ "dependencies": {
+ "@babel/code-frame": "^7.10.4",
+ "@babel/parser": "^7.10.4",
+ "@babel/types": "^7.10.4"
+ }
+ },
+ "node_modules/@babel/traverse": {
+ "version": "7.23.2",
+ "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.23.2.tgz",
+ "integrity": "sha512-azpe59SQ48qG6nu2CzcMLbxUudtN+dOM9kDbUqGq3HXUJRlo7i8fvPoxQUzYgLZ4cMVmuZgm8vvBpNeRhd6XSw==",
+ "dev": true,
+ "dependencies": {
+ "@babel/code-frame": "^7.22.13",
+ "@babel/generator": "^7.23.0",
+ "@babel/helper-environment-visitor": "^7.22.20",
+ "@babel/helper-function-name": "^7.23.0",
+ "@babel/helper-hoist-variables": "^7.22.5",
+ "@babel/helper-split-export-declaration": "^7.22.6",
+ "@babel/parser": "^7.23.0",
+ "@babel/types": "^7.23.0",
+ "debug": "^4.1.0",
+ "globals": "^11.1.0"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/traverse/node_modules/@babel/code-frame": {
+ "version": "7.22.13",
+ "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.22.13.tgz",
+ "integrity": "sha512-XktuhWlJ5g+3TJXc5upd9Ks1HutSArik6jf2eAjYFyIOf4ej3RN+184cZbzDvbPnuTJIUhPKKJE3cIsYTiAT3w==",
+ "dev": true,
+ "dependencies": {
+ "@babel/highlight": "^7.22.13",
+ "chalk": "^2.4.2"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/traverse/node_modules/@babel/generator": {
+ "version": "7.23.0",
+ "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.23.0.tgz",
+ "integrity": "sha512-lN85QRR+5IbYrMWM6Y4pE/noaQtg4pNiqeNGX60eqOfo6gtEj6uw/JagelB8vVztSd7R6M5n1+PQkDbHbBRU4g==",
+ "dev": true,
+ "dependencies": {
+ "@babel/types": "^7.23.0",
+ "@jridgewell/gen-mapping": "^0.3.2",
+ "@jridgewell/trace-mapping": "^0.3.17",
+ "jsesc": "^2.5.1"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/traverse/node_modules/@babel/helper-function-name": {
+ "version": "7.23.0",
+ "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.23.0.tgz",
+ "integrity": "sha512-OErEqsrxjZTJciZ4Oo+eoZqeW9UIiOcuYKRJA4ZAgV9myA+pOXhhmpfNCKjEH/auVfEYVFJ6y1Tc4r0eIApqiw==",
+ "dev": true,
+ "dependencies": {
+ "@babel/template": "^7.22.15",
+ "@babel/types": "^7.23.0"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/traverse/node_modules/@babel/helper-hoist-variables": {
+ "version": "7.22.5",
+ "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.22.5.tgz",
+ "integrity": "sha512-wGjk9QZVzvknA6yKIUURb8zY3grXCcOZt+/7Wcy8O2uctxhplmUPkOdlgoNhmdVee2c92JXbf1xpMtVNbfoxRw==",
+ "dev": true,
+ "dependencies": {
+ "@babel/types": "^7.22.5"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/traverse/node_modules/@babel/helper-split-export-declaration": {
+ "version": "7.22.6",
+ "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.22.6.tgz",
+ "integrity": "sha512-AsUnxuLhRYsisFiaJwvp1QF+I3KjD5FOxut14q/GzovUe6orHLesW2C7d754kRm53h5gqrz6sFl6sxc4BVtE/g==",
+ "dev": true,
+ "dependencies": {
+ "@babel/types": "^7.22.5"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/traverse/node_modules/@babel/helper-validator-identifier": {
+ "version": "7.22.20",
+ "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.20.tgz",
+ "integrity": "sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A==",
+ "dev": true,
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/traverse/node_modules/@babel/highlight": {
+ "version": "7.22.20",
+ "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.22.20.tgz",
+ "integrity": "sha512-dkdMCN3py0+ksCgYmGG8jKeGA/8Tk+gJwSYYlFGxG5lmhfKNoAy004YpLxpS1W2J8m/EK2Ew+yOs9pVRwO89mg==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-validator-identifier": "^7.22.20",
+ "chalk": "^2.4.2",
+ "js-tokens": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/traverse/node_modules/@babel/parser": {
+ "version": "7.23.0",
+ "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.23.0.tgz",
+ "integrity": "sha512-vvPKKdMemU85V9WE/l5wZEmImpCtLqbnTvqDS2U1fJ96KrxoW7KrXhNsNCblQlg8Ck4b85yxdTyelsMUgFUXiw==",
+ "dev": true,
+ "bin": {
+ "parser": "bin/babel-parser.js"
+ },
+ "engines": {
+ "node": ">=6.0.0"
+ }
+ },
+ "node_modules/@babel/traverse/node_modules/@babel/template": {
+ "version": "7.22.15",
+ "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.22.15.tgz",
+ "integrity": "sha512-QPErUVm4uyJa60rkI73qneDacvdvzxshT3kksGqlGWYdOTIUOwJ7RDUL8sGqslY1uXWSL6xMFKEXDS3ox2uF0w==",
+ "dev": true,
+ "dependencies": {
+ "@babel/code-frame": "^7.22.13",
+ "@babel/parser": "^7.22.15",
+ "@babel/types": "^7.22.15"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/traverse/node_modules/@babel/types": {
+ "version": "7.23.0",
+ "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.23.0.tgz",
+ "integrity": "sha512-0oIyUfKoI3mSqMvsxBdclDwxXKXAUA8v/apZbc+iSyARYou1o8ZGDxbUYyLFoW2arqS2jDGqJuZvv1d/io1axg==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-string-parser": "^7.22.5",
+ "@babel/helper-validator-identifier": "^7.22.20",
+ "to-fast-properties": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/types": {
+ "version": "7.12.6",
+ "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.12.6.tgz",
+ "integrity": "sha512-hwyjw6GvjBLiyy3W0YQf0Z5Zf4NpYejUnKFcfcUhZCSffoBBp30w6wP2Wn6pk31jMYZvcOrB/1b7cGXvEoKogA==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-validator-identifier": "^7.10.4",
+ "lodash": "^4.17.19",
+ "to-fast-properties": "^2.0.0"
+ }
+ },
+ "node_modules/@discoveryjs/json-ext": {
+ "version": "0.5.7",
+ "resolved": "https://registry.npmjs.org/@discoveryjs/json-ext/-/json-ext-0.5.7.tgz",
+ "integrity": "sha512-dBVuXR082gk3jsFp7Rd/JI4kytwGHecnCoTtXFb7DB6CNHp4rg5k1bhg0nWdLGLnOV71lmDzGQaLMy8iPLY0pw==",
+ "dev": true,
+ "engines": {
+ "node": ">=10.0.0"
+ }
+ },
+ "node_modules/@jridgewell/gen-mapping": {
+ "version": "0.3.2",
+ "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.2.tgz",
+ "integrity": "sha512-mh65xKQAzI6iBcFzwv28KVWSmCkdRBWoOh+bYQGW3+6OZvbbN3TqMGo5hqYxQniRcH9F2VZIoJCm4pa3BPDK/A==",
+ "dev": true,
+ "dependencies": {
+ "@jridgewell/set-array": "^1.0.1",
+ "@jridgewell/sourcemap-codec": "^1.4.10",
+ "@jridgewell/trace-mapping": "^0.3.9"
+ },
+ "engines": {
+ "node": ">=6.0.0"
+ }
+ },
+ "node_modules/@jridgewell/resolve-uri": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz",
+ "integrity": "sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w==",
+ "dev": true,
+ "engines": {
+ "node": ">=6.0.0"
+ }
+ },
+ "node_modules/@jridgewell/set-array": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.1.2.tgz",
+ "integrity": "sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==",
+ "dev": true,
+ "engines": {
+ "node": ">=6.0.0"
+ }
+ },
+ "node_modules/@jridgewell/source-map": {
+ "version": "0.3.2",
+ "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.2.tgz",
+ "integrity": "sha512-m7O9o2uR8k2ObDysZYzdfhb08VuEml5oWGiosa1VdaPZ/A6QyPkAJuwN0Q1lhULOf6B7MtQmHENS743hWtCrgw==",
+ "dev": true,
+ "dependencies": {
+ "@jridgewell/gen-mapping": "^0.3.0",
+ "@jridgewell/trace-mapping": "^0.3.9"
+ }
+ },
+ "node_modules/@jridgewell/sourcemap-codec": {
+ "version": "1.4.14",
+ "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz",
+ "integrity": "sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==",
+ "dev": true
+ },
+ "node_modules/@jridgewell/trace-mapping": {
+ "version": "0.3.17",
+ "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.17.tgz",
+ "integrity": "sha512-MCNzAp77qzKca9+W/+I0+sEpaUnZoeasnghNeVc41VZCEKaCH73Vq3BZZ/SzWIgrqE4H4ceI+p+b6C0mHf9T4g==",
+ "dev": true,
+ "dependencies": {
+ "@jridgewell/resolve-uri": "3.1.0",
+ "@jridgewell/sourcemap-codec": "1.4.14"
+ }
+ },
+ "node_modules/@mrmlnc/readdir-enhanced": {
+ "version": "2.2.1",
+ "resolved": "https://registry.npmjs.org/@mrmlnc/readdir-enhanced/-/readdir-enhanced-2.2.1.tgz",
+ "integrity": "sha512-bPHp6Ji8b41szTOcaP63VlnbbO5Ny6dwAATtY6JTjh5N2OLrb5Qk/Th5cRkRQhkWCt+EJsYrNB0MiL+Gpn6e3g==",
+ "dev": true,
+ "dependencies": {
+ "call-me-maybe": "^1.0.1",
+ "glob-to-regexp": "^0.3.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/@nodelib/fs.stat": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-1.1.3.tgz",
+ "integrity": "sha512-shAmDyaQC4H92APFoIaVDHCx5bStIocgvbwQyxPRrbUY20V1EYTbSDchWbuwlMG3V17cprZhA6+78JfB+3DTPw==",
+ "dev": true,
+ "engines": {
+ "node": ">= 6"
+ }
+ },
+ "node_modules/@sindresorhus/is": {
+ "version": "0.14.0",
+ "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-0.14.0.tgz",
+ "integrity": "sha512-9NET910DNaIPngYnLLPeg+Ogzqsi9uM4mSboU5y6p8S5DzMTVEsJZrawi+BoDNUVBa2DhJqQYUFvMDfgU062LQ==",
+ "dev": true,
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/@sinonjs/commons": {
+ "version": "1.8.1",
+ "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.8.1.tgz",
+ "integrity": "sha512-892K+kWUUi3cl+LlqEWIDrhvLgdL79tECi8JZUyq6IviKy/DNhuzCRlbHUjxK89f4ypPMMaFnFuR9Ie6DoIMsw==",
+ "dev": true,
+ "dependencies": {
+ "type-detect": "4.0.8"
+ }
+ },
+ "node_modules/@sinonjs/fake-timers": {
+ "version": "6.0.1",
+ "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-6.0.1.tgz",
+ "integrity": "sha512-MZPUxrmFubI36XS1DI3qmI0YdN1gks62JtFZvxR67ljjSNCeK6U08Zx4msEWOXuofgqUt6zPHSi1H9fbjR/NRA==",
+ "dev": true,
+ "dependencies": {
+ "@sinonjs/commons": "^1.7.0"
+ }
+ },
+ "node_modules/@sinonjs/formatio": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/@sinonjs/formatio/-/formatio-5.0.1.tgz",
+ "integrity": "sha512-KaiQ5pBf1MpS09MuA0kp6KBQt2JUOQycqVG1NZXvzeaXe5LGFqAKueIS0bw4w0P9r7KuBSVdUk5QjXsUdu2CxQ==",
+ "dev": true,
+ "dependencies": {
+ "@sinonjs/commons": "^1",
+ "@sinonjs/samsam": "^5.0.2"
+ }
+ },
+ "node_modules/@sinonjs/samsam": {
+ "version": "5.2.0",
+ "resolved": "https://registry.npmjs.org/@sinonjs/samsam/-/samsam-5.2.0.tgz",
+ "integrity": "sha512-CaIcyX5cDsjcW/ab7HposFWzV1kC++4HNsfnEdFJa7cP1QIuILAKV+BgfeqRXhcnSAc76r/Rh/O5C+300BwUIw==",
+ "dev": true,
+ "dependencies": {
+ "@sinonjs/commons": "^1.6.0",
+ "lodash.get": "^4.4.2",
+ "type-detect": "^4.0.8"
+ }
+ },
+ "node_modules/@sinonjs/text-encoding": {
+ "version": "0.7.1",
+ "resolved": "https://registry.npmjs.org/@sinonjs/text-encoding/-/text-encoding-0.7.1.tgz",
+ "integrity": "sha512-+iTbntw2IZPb/anVDbypzfQa+ay64MW0Zo8aJ8gZPWMMK6/OubMVb6lUPMagqjOPnmtauXnFCACVl3O7ogjeqQ==",
+ "dev": true
+ },
+ "node_modules/@szmarczak/http-timer": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-1.1.2.tgz",
+ "integrity": "sha512-XIB2XbzHTN6ieIjfIMV9hlVcfPU26s2vafYWQcZHWXHOxiaRZYEDKEwdl129Zyg50+foYV2jCgtrqSA6qNuNSA==",
+ "dev": true,
+ "dependencies": {
+ "defer-to-connect": "^1.0.1"
+ },
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/@types/eslint": {
+ "version": "8.4.10",
+ "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-8.4.10.tgz",
+ "integrity": "sha512-Sl/HOqN8NKPmhWo2VBEPm0nvHnu2LL3v9vKo8MEq0EtbJ4eVzGPl41VNPvn5E1i5poMk4/XD8UriLHpJvEP/Nw==",
+ "dev": true,
+ "dependencies": {
+ "@types/estree": "*",
+ "@types/json-schema": "*"
+ }
+ },
+ "node_modules/@types/eslint-scope": {
+ "version": "3.7.4",
+ "resolved": "https://registry.npmjs.org/@types/eslint-scope/-/eslint-scope-3.7.4.tgz",
+ "integrity": "sha512-9K4zoImiZc3HlIp6AVUDE4CWYx22a+lhSZMYNpbjW04+YF0KWj4pJXnEMjdnFTiQibFFmElcsasJXDbdI/EPhA==",
+ "dev": true,
+ "dependencies": {
+ "@types/eslint": "*",
+ "@types/estree": "*"
+ }
+ },
+ "node_modules/@types/estree": {
+ "version": "0.0.51",
+ "resolved": "https://registry.npmjs.org/@types/estree/-/estree-0.0.51.tgz",
+ "integrity": "sha512-CuPgU6f3eT/XgKKPqKd/gLZV1Xmvf1a2R5POBOGQa6uv82xpls89HU5zKeVoyR8XzHd1RGNOlQlvUe3CFkjWNQ==",
+ "dev": true
+ },
+ "node_modules/@types/glob": {
+ "version": "7.1.3",
+ "resolved": "https://registry.npmjs.org/@types/glob/-/glob-7.1.3.tgz",
+ "integrity": "sha512-SEYeGAIQIQX8NN6LDKprLjbrd5dARM5EXsd8GI/A5l0apYI1fGMWgPHSe4ZKL4eozlAyI+doUE9XbYS4xCkQ1w==",
+ "dev": true,
+ "dependencies": {
+ "@types/minimatch": "*",
+ "@types/node": "*"
+ }
+ },
+ "node_modules/@types/json-schema": {
+ "version": "7.0.11",
+ "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.11.tgz",
+ "integrity": "sha512-wOuvG1SN4Us4rez+tylwwwCV1psiNVOkJeM3AUWUNWg/jDQY2+HE/444y5gc+jBmRqASOm2Oeh5c1axHobwRKQ==",
+ "dev": true
+ },
+ "node_modules/@types/json5": {
+ "version": "0.0.29",
+ "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz",
+ "integrity": "sha1-7ihweulOEdK4J7y+UnC86n8+ce4=",
+ "dev": true
+ },
+ "node_modules/@types/minimatch": {
+ "version": "3.0.3",
+ "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.3.tgz",
+ "integrity": "sha512-tHq6qdbT9U1IRSGf14CL0pUlULksvY9OZ+5eEgl1N7t+OA3tGvNpxJCzuKQlsNgCVwbAs670L1vcVQi8j9HjnA==",
+ "dev": true
+ },
+ "node_modules/@types/node": {
+ "version": "14.14.6",
+ "resolved": "https://registry.npmjs.org/@types/node/-/node-14.14.6.tgz",
+ "integrity": "sha512-6QlRuqsQ/Ox/aJEQWBEJG7A9+u7oSYl3mem/K8IzxXG/kAGbV1YPD9Bg9Zw3vyxC/YP+zONKwy8hGkSt1jxFMw==",
+ "dev": true
+ },
+ "node_modules/@types/normalize-package-data": {
+ "version": "2.4.0",
+ "resolved": "https://registry.npmjs.org/@types/normalize-package-data/-/normalize-package-data-2.4.0.tgz",
+ "integrity": "sha512-f5j5b/Gf71L+dbqxIpQ4Z2WlmI/mPJ0fOkGGmFgtb6sAu97EPczzbS3/tJKxmcYDj55OX6ssqwDAWOHIYDRDGA==",
+ "dev": true
+ },
+ "node_modules/@ungap/promise-all-settled": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/@ungap/promise-all-settled/-/promise-all-settled-1.1.2.tgz",
+ "integrity": "sha512-sL/cEvJWAnClXw0wHk85/2L0G6Sj8UB0Ctc1TEMbKSsmpRosqhwj9gWgFRZSrBr2f9tiXISwNhCPmlfqUqyb9Q==",
+ "dev": true
+ },
+ "node_modules/@webassemblyjs/ast": {
+ "version": "1.11.1",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.11.1.tgz",
+ "integrity": "sha512-ukBh14qFLjxTQNTXocdyksN5QdM28S1CxHt2rdskFyL+xFV7VremuBLVbmCePj+URalXBENx/9Lm7lnhihtCSw==",
+ "dev": true,
+ "dependencies": {
+ "@webassemblyjs/helper-numbers": "1.11.1",
+ "@webassemblyjs/helper-wasm-bytecode": "1.11.1"
+ }
+ },
+ "node_modules/@webassemblyjs/floating-point-hex-parser": {
+ "version": "1.11.1",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.11.1.tgz",
+ "integrity": "sha512-iGRfyc5Bq+NnNuX8b5hwBrRjzf0ocrJPI6GWFodBFzmFnyvrQ83SHKhmilCU/8Jv67i4GJZBMhEzltxzcNagtQ==",
+ "dev": true
+ },
+ "node_modules/@webassemblyjs/helper-api-error": {
+ "version": "1.11.1",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.11.1.tgz",
+ "integrity": "sha512-RlhS8CBCXfRUR/cwo2ho9bkheSXG0+NwooXcc3PAILALf2QLdFyj7KGsKRbVc95hZnhnERon4kW/D3SZpp6Tcg==",
+ "dev": true
+ },
+ "node_modules/@webassemblyjs/helper-buffer": {
+ "version": "1.11.1",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.11.1.tgz",
+ "integrity": "sha512-gwikF65aDNeeXa8JxXa2BAk+REjSyhrNC9ZwdT0f8jc4dQQeDQ7G4m0f2QCLPJiMTTO6wfDmRmj/pW0PsUvIcA==",
+ "dev": true
+ },
+ "node_modules/@webassemblyjs/helper-numbers": {
+ "version": "1.11.1",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-numbers/-/helper-numbers-1.11.1.tgz",
+ "integrity": "sha512-vDkbxiB8zfnPdNK9Rajcey5C0w+QJugEglN0of+kmO8l7lDb77AnlKYQF7aarZuCrv+l0UvqL+68gSDr3k9LPQ==",
+ "dev": true,
+ "dependencies": {
+ "@webassemblyjs/floating-point-hex-parser": "1.11.1",
+ "@webassemblyjs/helper-api-error": "1.11.1",
+ "@xtuc/long": "4.2.2"
+ }
+ },
+ "node_modules/@webassemblyjs/helper-wasm-bytecode": {
+ "version": "1.11.1",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.11.1.tgz",
+ "integrity": "sha512-PvpoOGiJwXeTrSf/qfudJhwlvDQxFgelbMqtq52WWiXC6Xgg1IREdngmPN3bs4RoO83PnL/nFrxucXj1+BX62Q==",
+ "dev": true
+ },
+ "node_modules/@webassemblyjs/helper-wasm-section": {
+ "version": "1.11.1",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.11.1.tgz",
+ "integrity": "sha512-10P9No29rYX1j7F3EVPX3JvGPQPae+AomuSTPiF9eBQeChHI6iqjMIwR9JmOJXwpnn/oVGDk7I5IlskuMwU/pg==",
+ "dev": true,
+ "dependencies": {
+ "@webassemblyjs/ast": "1.11.1",
+ "@webassemblyjs/helper-buffer": "1.11.1",
+ "@webassemblyjs/helper-wasm-bytecode": "1.11.1",
+ "@webassemblyjs/wasm-gen": "1.11.1"
+ }
+ },
+ "node_modules/@webassemblyjs/ieee754": {
+ "version": "1.11.1",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.11.1.tgz",
+ "integrity": "sha512-hJ87QIPtAMKbFq6CGTkZYJivEwZDbQUgYd3qKSadTNOhVY7p+gfP6Sr0lLRVTaG1JjFj+r3YchoqRYxNH3M0GQ==",
+ "dev": true,
+ "dependencies": {
+ "@xtuc/ieee754": "^1.2.0"
+ }
+ },
+ "node_modules/@webassemblyjs/leb128": {
+ "version": "1.11.1",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.11.1.tgz",
+ "integrity": "sha512-BJ2P0hNZ0u+Th1YZXJpzW6miwqQUGcIHT1G/sf72gLVD9DZ5AdYTqPNbHZh6K1M5VmKvFXwGSWZADz+qBWxeRw==",
+ "dev": true,
+ "dependencies": {
+ "@xtuc/long": "4.2.2"
+ }
+ },
+ "node_modules/@webassemblyjs/utf8": {
+ "version": "1.11.1",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.11.1.tgz",
+ "integrity": "sha512-9kqcxAEdMhiwQkHpkNiorZzqpGrodQQ2IGrHHxCy+Ozng0ofyMA0lTqiLkVs1uzTRejX+/O0EOT7KxqVPuXosQ==",
+ "dev": true
+ },
+ "node_modules/@webassemblyjs/wasm-edit": {
+ "version": "1.11.1",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.11.1.tgz",
+ "integrity": "sha512-g+RsupUC1aTHfR8CDgnsVRVZFJqdkFHpsHMfJuWQzWU3tvnLC07UqHICfP+4XyL2tnr1amvl1Sdp06TnYCmVkA==",
+ "dev": true,
+ "dependencies": {
+ "@webassemblyjs/ast": "1.11.1",
+ "@webassemblyjs/helper-buffer": "1.11.1",
+ "@webassemblyjs/helper-wasm-bytecode": "1.11.1",
+ "@webassemblyjs/helper-wasm-section": "1.11.1",
+ "@webassemblyjs/wasm-gen": "1.11.1",
+ "@webassemblyjs/wasm-opt": "1.11.1",
+ "@webassemblyjs/wasm-parser": "1.11.1",
+ "@webassemblyjs/wast-printer": "1.11.1"
+ }
+ },
+ "node_modules/@webassemblyjs/wasm-gen": {
+ "version": "1.11.1",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.11.1.tgz",
+ "integrity": "sha512-F7QqKXwwNlMmsulj6+O7r4mmtAlCWfO/0HdgOxSklZfQcDu0TpLiD1mRt/zF25Bk59FIjEuGAIyn5ei4yMfLhA==",
+ "dev": true,
+ "dependencies": {
+ "@webassemblyjs/ast": "1.11.1",
+ "@webassemblyjs/helper-wasm-bytecode": "1.11.1",
+ "@webassemblyjs/ieee754": "1.11.1",
+ "@webassemblyjs/leb128": "1.11.1",
+ "@webassemblyjs/utf8": "1.11.1"
+ }
+ },
+ "node_modules/@webassemblyjs/wasm-opt": {
+ "version": "1.11.1",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.11.1.tgz",
+ "integrity": "sha512-VqnkNqnZlU5EB64pp1l7hdm3hmQw7Vgqa0KF/KCNO9sIpI6Fk6brDEiX+iCOYrvMuBWDws0NkTOxYEb85XQHHw==",
+ "dev": true,
+ "dependencies": {
+ "@webassemblyjs/ast": "1.11.1",
+ "@webassemblyjs/helper-buffer": "1.11.1",
+ "@webassemblyjs/wasm-gen": "1.11.1",
+ "@webassemblyjs/wasm-parser": "1.11.1"
+ }
+ },
+ "node_modules/@webassemblyjs/wasm-parser": {
+ "version": "1.11.1",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.11.1.tgz",
+ "integrity": "sha512-rrBujw+dJu32gYB7/Lup6UhdkPx9S9SnobZzRVL7VcBH9Bt9bCBLEuX/YXOOtBsOZ4NQrRykKhffRWHvigQvOA==",
+ "dev": true,
+ "dependencies": {
+ "@webassemblyjs/ast": "1.11.1",
+ "@webassemblyjs/helper-api-error": "1.11.1",
+ "@webassemblyjs/helper-wasm-bytecode": "1.11.1",
+ "@webassemblyjs/ieee754": "1.11.1",
+ "@webassemblyjs/leb128": "1.11.1",
+ "@webassemblyjs/utf8": "1.11.1"
+ }
+ },
+ "node_modules/@webassemblyjs/wast-printer": {
+ "version": "1.11.1",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.11.1.tgz",
+ "integrity": "sha512-IQboUWM4eKzWW+N/jij2sRatKMh99QEelo3Eb2q0qXkvPRISAj8Qxtmw5itwqK+TTkBuUIE45AxYPToqPtL5gg==",
+ "dev": true,
+ "dependencies": {
+ "@webassemblyjs/ast": "1.11.1",
+ "@xtuc/long": "4.2.2"
+ }
+ },
+ "node_modules/@webpack-cli/configtest": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/@webpack-cli/configtest/-/configtest-2.0.1.tgz",
+ "integrity": "sha512-njsdJXJSiS2iNbQVS0eT8A/KPnmyH4pv1APj2K0d1wrZcBLw+yppxOy4CGqa0OxDJkzfL/XELDhD8rocnIwB5A==",
+ "dev": true,
+ "engines": {
+ "node": ">=14.15.0"
+ },
+ "peerDependencies": {
+ "webpack": "5.x.x",
+ "webpack-cli": "5.x.x"
+ }
+ },
+ "node_modules/@webpack-cli/info": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/@webpack-cli/info/-/info-2.0.1.tgz",
+ "integrity": "sha512-fE1UEWTwsAxRhrJNikE7v4EotYflkEhBL7EbajfkPlf6E37/2QshOy/D48Mw8G5XMFlQtS6YV42vtbG9zBpIQA==",
+ "dev": true,
+ "engines": {
+ "node": ">=14.15.0"
+ },
+ "peerDependencies": {
+ "webpack": "5.x.x",
+ "webpack-cli": "5.x.x"
+ }
+ },
+ "node_modules/@webpack-cli/serve": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/@webpack-cli/serve/-/serve-2.0.1.tgz",
+ "integrity": "sha512-0G7tNyS+yW8TdgHwZKlDWYXFA6OJQnoLCQvYKkQP0Q2X205PSQ6RNUj0M+1OB/9gRQaUZ/ccYfaxd0nhaWKfjw==",
+ "dev": true,
+ "engines": {
+ "node": ">=14.15.0"
+ },
+ "peerDependencies": {
+ "webpack": "5.x.x",
+ "webpack-cli": "5.x.x"
+ },
+ "peerDependenciesMeta": {
+ "webpack-dev-server": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@xtuc/ieee754": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz",
+ "integrity": "sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==",
+ "dev": true
+ },
+ "node_modules/@xtuc/long": {
+ "version": "4.2.2",
+ "resolved": "https://registry.npmjs.org/@xtuc/long/-/long-4.2.2.tgz",
+ "integrity": "sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==",
+ "dev": true
+ },
+ "node_modules/acorn": {
+ "version": "8.8.1",
+ "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.1.tgz",
+ "integrity": "sha512-7zFpHzhnqYKrkYdUjF1HI1bzd0VygEGX8lFk4k5zVMqHEoES+P+7TKI+EvLO9WVMJ8eekdO0aDEK044xTXwPPA==",
+ "dev": true,
+ "bin": {
+ "acorn": "bin/acorn"
+ },
+ "engines": {
+ "node": ">=0.4.0"
+ }
+ },
+ "node_modules/acorn-import-assertions": {
+ "version": "1.8.0",
+ "resolved": "https://registry.npmjs.org/acorn-import-assertions/-/acorn-import-assertions-1.8.0.tgz",
+ "integrity": "sha512-m7VZ3jwz4eK6A4Vtt8Ew1/mNbP24u0FhdyfA7fSvnJR6LMdfOYnmuIrrJAgrYfYJ10F/otaHTtrtrtmHdMNzEw==",
+ "deprecated": "package has been renamed to acorn-import-attributes",
+ "dev": true,
+ "peerDependencies": {
+ "acorn": "^8"
+ }
+ },
+ "node_modules/acorn-jsx": {
+ "version": "5.3.1",
+ "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.1.tgz",
+ "integrity": "sha512-K0Ptm/47OKfQRpNQ2J/oIN/3QYiK6FwW+eJbILhsdxh2WTLdl+30o8aGdTbm5JbffpFFAg/g+zi1E+jvJha5ng==",
+ "dev": true,
+ "peerDependencies": {
+ "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0"
+ }
+ },
+ "node_modules/ajv": {
+ "version": "6.12.6",
+ "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz",
+ "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==",
+ "dev": true,
+ "dependencies": {
+ "fast-deep-equal": "^3.1.1",
+ "fast-json-stable-stringify": "^2.0.0",
+ "json-schema-traverse": "^0.4.1",
+ "uri-js": "^4.2.2"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/epoberezkin"
+ }
+ },
+ "node_modules/ajv-keywords": {
+ "version": "3.5.2",
+ "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz",
+ "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==",
+ "dev": true,
+ "peerDependencies": {
+ "ajv": "^6.9.1"
+ }
+ },
+ "node_modules/ansi-align": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/ansi-align/-/ansi-align-3.0.0.tgz",
+ "integrity": "sha512-ZpClVKqXN3RGBmKibdfWzqCY4lnjEuoNzU5T0oEFpfd/z5qJHVarukridD4juLO2FXMiwUQxr9WqQtaYa8XRYw==",
+ "dev": true,
+ "dependencies": {
+ "string-width": "^3.0.0"
+ }
+ },
+ "node_modules/ansi-align/node_modules/ansi-regex": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.1.tgz",
+ "integrity": "sha512-ILlv4k/3f6vfQ4OoP2AGvirOktlQ98ZEL1k9FaQjxa3L1abBgbuTDAdPOpvbGncC0BTVQrl+OM8xZGK6tWXt7g==",
+ "dev": true,
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/ansi-align/node_modules/string-width": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz",
+ "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==",
+ "dev": true,
+ "dependencies": {
+ "emoji-regex": "^7.0.1",
+ "is-fullwidth-code-point": "^2.0.0",
+ "strip-ansi": "^5.1.0"
+ },
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/ansi-align/node_modules/strip-ansi": {
+ "version": "5.2.0",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz",
+ "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==",
+ "dev": true,
+ "dependencies": {
+ "ansi-regex": "^4.1.0"
+ },
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/ansi-colors": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz",
+ "integrity": "sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==",
+ "dev": true,
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/ansi-escapes": {
+ "version": "4.3.1",
+ "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.1.tgz",
+ "integrity": "sha512-JWF7ocqNrp8u9oqpgV+wH5ftbt+cfvv+PTjOvKLT3AdYly/LmORARfEVT1iyjwN+4MqE5UmVKoAdIBqeoCHgLA==",
+ "dev": true,
+ "dependencies": {
+ "type-fest": "^0.11.0"
+ },
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/ansi-escapes/node_modules/type-fest": {
+ "version": "0.11.0",
+ "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.11.0.tgz",
+ "integrity": "sha512-OdjXJxnCN1AvyLSzeKIgXTXxV+99ZuXl3Hpo9XpJAv9MBcHrrJOQ5kV7ypXOuQie+AmWG25hLbiKdwYTifzcfQ==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/ansi-regex": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
+ "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/ansi-styles": {
+ "version": "3.2.1",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
+ "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
+ "dev": true,
+ "dependencies": {
+ "color-convert": "^1.9.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/anymatch": {
+ "version": "3.1.2",
+ "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz",
+ "integrity": "sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==",
+ "dev": true,
+ "dependencies": {
+ "normalize-path": "^3.0.0",
+ "picomatch": "^2.0.4"
+ },
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/argparse": {
+ "version": "1.0.10",
+ "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz",
+ "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==",
+ "dev": true,
+ "dependencies": {
+ "sprintf-js": "~1.0.2"
+ }
+ },
+ "node_modules/arr-diff": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz",
+ "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=",
+ "dev": true,
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/arr-flatten": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/arr-flatten/-/arr-flatten-1.1.0.tgz",
+ "integrity": "sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg==",
+ "dev": true,
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/arr-union": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/arr-union/-/arr-union-3.1.0.tgz",
+ "integrity": "sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ=",
+ "dev": true,
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/array-differ": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/array-differ/-/array-differ-3.0.0.tgz",
+ "integrity": "sha512-THtfYS6KtME/yIAhKjZ2ul7XI96lQGHRputJQHO80LAWQnuGP4iCIN8vdMRboGbIEYBwU33q8Tch1os2+X0kMg==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/array-find-index": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/array-find-index/-/array-find-index-1.0.2.tgz",
+ "integrity": "sha1-3wEKoSh+Fku9pvlyOwqWoexBh6E=",
+ "dev": true,
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/array-includes": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.1.tgz",
+ "integrity": "sha512-c2VXaCHl7zPsvpkFsw4nxvFie4fh1ur9bpcgsVkIjqn0H/Xwdg+7fv3n2r/isyS8EBj5b06M9kHyZuIr4El6WQ==",
+ "dev": true,
+ "dependencies": {
+ "define-properties": "^1.1.3",
+ "es-abstract": "^1.17.0",
+ "is-string": "^1.0.5"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/array-union": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/array-union/-/array-union-1.0.2.tgz",
+ "integrity": "sha1-mjRBDk9OPaI96jdb5b5w8kd47Dk=",
+ "dev": true,
+ "dependencies": {
+ "array-uniq": "^1.0.1"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/array-uniq": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/array-uniq/-/array-uniq-1.0.3.tgz",
+ "integrity": "sha1-r2rId6Jcx/dOBYiUdThY39sk/bY=",
+ "dev": true,
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/array-unique": {
+ "version": "0.3.2",
+ "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz",
+ "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=",
+ "dev": true,
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/array.prototype.flat": {
+ "version": "1.2.3",
+ "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.2.3.tgz",
+ "integrity": "sha512-gBlRZV0VSmfPIeWfuuy56XZMvbVfbEUnOXUvt3F/eUUUSyzlgLxhEX4YAEpxNAogRGehPSnfXyPtYyKAhkzQhQ==",
+ "dev": true,
+ "dependencies": {
+ "define-properties": "^1.1.3",
+ "es-abstract": "^1.17.0-next.1"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/arrify": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/arrify/-/arrify-2.0.1.tgz",
+ "integrity": "sha512-3duEwti880xqi4eAMN8AyR4a0ByT90zoYdLlevfrvU43vb0YZwZVfxOgxWrLXXXpyugL0hNZc9G6BiB5B3nUug==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/assign-symbols": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/assign-symbols/-/assign-symbols-1.0.0.tgz",
+ "integrity": "sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c=",
+ "dev": true,
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/astral-regex": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-1.0.0.tgz",
+ "integrity": "sha512-+Ryf6g3BKoRc7jfp7ad8tM4TtMiaWvbF/1/sQcZPkkS7ag3D5nMBCe2UfOTONtAkaG0tO0ij3C5Lwmf1EiyjHg==",
+ "dev": true,
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/atob": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/atob/-/atob-2.1.2.tgz",
+ "integrity": "sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==",
+ "dev": true,
+ "bin": {
+ "atob": "bin/atob.js"
+ },
+ "engines": {
+ "node": ">= 4.5.0"
+ }
+ },
+ "node_modules/babel-loader": {
+ "version": "8.3.0",
+ "resolved": "https://registry.npmjs.org/babel-loader/-/babel-loader-8.3.0.tgz",
+ "integrity": "sha512-H8SvsMF+m9t15HNLMipppzkC+Y2Yq+v3SonZyU70RBL/h1gxPkH08Ot8pEE9Z4Kd+czyWJClmFS8qzIP9OZ04Q==",
+ "dev": true,
+ "dependencies": {
+ "find-cache-dir": "^3.3.1",
+ "loader-utils": "^2.0.0",
+ "make-dir": "^3.1.0",
+ "schema-utils": "^2.6.5"
+ },
+ "engines": {
+ "node": ">= 8.9"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0",
+ "webpack": ">=2"
+ }
+ },
+ "node_modules/babel-plugin-dynamic-import-node": {
+ "version": "2.3.3",
+ "resolved": "https://registry.npmjs.org/babel-plugin-dynamic-import-node/-/babel-plugin-dynamic-import-node-2.3.3.tgz",
+ "integrity": "sha512-jZVI+s9Zg3IqA/kdi0i6UDCybUI3aSBLnglhYbSSjKlV7yF1F/5LWv8MakQmvYpnbJDS6fcBL2KzHSxNCMtWSQ==",
+ "dev": true,
+ "dependencies": {
+ "object.assign": "^4.1.0"
+ }
+ },
+ "node_modules/balanced-match": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz",
+ "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c="
+ },
+ "node_modules/base": {
+ "version": "0.11.2",
+ "resolved": "https://registry.npmjs.org/base/-/base-0.11.2.tgz",
+ "integrity": "sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg==",
+ "dev": true,
+ "dependencies": {
+ "cache-base": "^1.0.1",
+ "class-utils": "^0.3.5",
+ "component-emitter": "^1.2.1",
+ "define-property": "^1.0.0",
+ "isobject": "^3.0.1",
+ "mixin-deep": "^1.2.0",
+ "pascalcase": "^0.1.1"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/base/node_modules/define-property": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz",
+ "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=",
+ "dev": true,
+ "dependencies": {
+ "is-descriptor": "^1.0.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/base/node_modules/is-accessor-descriptor": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz",
+ "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==",
+ "deprecated": "Please upgrade to v1.0.1",
+ "dev": true,
+ "dependencies": {
+ "kind-of": "^6.0.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/base/node_modules/is-data-descriptor": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz",
+ "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==",
+ "deprecated": "Please upgrade to v1.0.1",
+ "dev": true,
+ "dependencies": {
+ "kind-of": "^6.0.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/base/node_modules/is-descriptor": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz",
+ "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==",
+ "dev": true,
+ "dependencies": {
+ "is-accessor-descriptor": "^1.0.0",
+ "is-data-descriptor": "^1.0.0",
+ "kind-of": "^6.0.2"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/big.js": {
+ "version": "5.2.2",
+ "resolved": "https://registry.npmjs.org/big.js/-/big.js-5.2.2.tgz",
+ "integrity": "sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==",
+ "dev": true,
+ "engines": {
+ "node": "*"
+ }
+ },
+ "node_modules/binary-extensions": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.1.0.tgz",
+ "integrity": "sha512-1Yj8h9Q+QDF5FzhMs/c9+6UntbD5MkRfRwac8DoEm9ZfUBZ7tZ55YcGVAzEe4bXsdQHEk+s9S5wsOKVdZrw0tQ==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/boxen": {
+ "version": "4.2.0",
+ "resolved": "https://registry.npmjs.org/boxen/-/boxen-4.2.0.tgz",
+ "integrity": "sha512-eB4uT9RGzg2odpER62bBwSLvUeGC+WbRjjyyFhGsKnc8wp/m0+hQsMUvUe3H2V0D5vw0nBdO1hCJoZo5mKeuIQ==",
+ "dev": true,
+ "dependencies": {
+ "ansi-align": "^3.0.0",
+ "camelcase": "^5.3.1",
+ "chalk": "^3.0.0",
+ "cli-boxes": "^2.2.0",
+ "string-width": "^4.1.0",
+ "term-size": "^2.1.0",
+ "type-fest": "^0.8.1",
+ "widest-line": "^3.1.0"
+ },
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/boxen/node_modules/ansi-styles": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
+ "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
+ "dev": true,
+ "dependencies": {
+ "color-convert": "^2.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/ansi-styles?sponsor=1"
+ }
+ },
+ "node_modules/boxen/node_modules/chalk": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz",
+ "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==",
+ "dev": true,
+ "dependencies": {
+ "ansi-styles": "^4.1.0",
+ "supports-color": "^7.1.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/boxen/node_modules/color-convert": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
+ "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
+ "dev": true,
+ "dependencies": {
+ "color-name": "~1.1.4"
+ },
+ "engines": {
+ "node": ">=7.0.0"
+ }
+ },
+ "node_modules/boxen/node_modules/color-name": {
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
+ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
+ "dev": true
+ },
+ "node_modules/boxen/node_modules/has-flag": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
+ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/boxen/node_modules/supports-color": {
+ "version": "7.2.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
+ "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
+ "dev": true,
+ "dependencies": {
+ "has-flag": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/brace-expansion": {
+ "version": "1.1.12",
+ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz",
+ "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==",
+ "dependencies": {
+ "balanced-match": "^1.0.0",
+ "concat-map": "0.0.1"
+ }
+ },
+ "node_modules/braces": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz",
+ "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==",
+ "dev": true,
+ "dependencies": {
+ "fill-range": "^7.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/browser-stdout": {
+ "version": "1.3.1",
+ "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz",
+ "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==",
+ "dev": true
+ },
+ "node_modules/browserslist": {
+ "version": "4.20.4",
+ "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.20.4.tgz",
+ "integrity": "sha512-ok1d+1WpnU24XYN7oC3QWgTyMhY/avPJ/r9T00xxvUOIparA/gc+UPUMaod3i+G6s+nI2nUb9xZ5k794uIwShw==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/browserslist"
+ },
+ {
+ "type": "tidelift",
+ "url": "https://tidelift.com/funding/github/npm/browserslist"
+ }
+ ],
+ "dependencies": {
+ "caniuse-lite": "^1.0.30001349",
+ "electron-to-chromium": "^1.4.147",
+ "escalade": "^3.1.1",
+ "node-releases": "^2.0.5",
+ "picocolors": "^1.0.0"
+ },
+ "bin": {
+ "browserslist": "cli.js"
+ },
+ "engines": {
+ "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7"
+ }
+ },
+ "node_modules/browserslist/node_modules/electron-to-chromium": {
+ "version": "1.4.158",
+ "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.158.tgz",
+ "integrity": "sha512-gppO3/+Y6sP432HtvwvuU8S+YYYLH4PmAYvQwqUtt9HDOmEsBwQfLnK9T8+1NIKwAS1BEygIjTaATC4H5EzvxQ==",
+ "dev": true
+ },
+ "node_modules/browserslist/node_modules/node-releases": {
+ "version": "2.0.5",
+ "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.5.tgz",
+ "integrity": "sha512-U9h1NLROZTq9uE1SNffn6WuPDg8icmi3ns4rEl/oTfIle4iLjTliCzgTsbaIFMq/Xn078/lfY/BL0GWZ+psK4Q==",
+ "dev": true
+ },
+ "node_modules/buf-compare": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/buf-compare/-/buf-compare-1.0.1.tgz",
+ "integrity": "sha1-/vKNqLgROgoNtEMLC2Rntpcws0o=",
+ "dev": true,
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/buffer-from": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz",
+ "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==",
+ "dev": true
+ },
+ "node_modules/cache-base": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/cache-base/-/cache-base-1.0.1.tgz",
+ "integrity": "sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ==",
+ "dev": true,
+ "dependencies": {
+ "collection-visit": "^1.0.0",
+ "component-emitter": "^1.2.1",
+ "get-value": "^2.0.6",
+ "has-value": "^1.0.0",
+ "isobject": "^3.0.1",
+ "set-value": "^2.0.0",
+ "to-object-path": "^0.3.0",
+ "union-value": "^1.0.0",
+ "unset-value": "^1.0.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/cacheable-request": {
+ "version": "6.1.0",
+ "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-6.1.0.tgz",
+ "integrity": "sha512-Oj3cAGPCqOZX7Rz64Uny2GYAZNliQSqfbePrgAQ1wKAihYmCUnraBtJtKcGR4xz7wF+LoJC+ssFZvv5BgF9Igg==",
+ "dev": true,
+ "dependencies": {
+ "clone-response": "^1.0.2",
+ "get-stream": "^5.1.0",
+ "http-cache-semantics": "^4.0.0",
+ "keyv": "^3.0.0",
+ "lowercase-keys": "^2.0.0",
+ "normalize-url": "^4.1.0",
+ "responselike": "^1.0.2"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/cacheable-request/node_modules/get-stream": {
+ "version": "5.2.0",
+ "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz",
+ "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==",
+ "dev": true,
+ "dependencies": {
+ "pump": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/cacheable-request/node_modules/lowercase-keys": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-2.0.0.tgz",
+ "integrity": "sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/call-bind": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.0.tgz",
+ "integrity": "sha512-AEXsYIyyDY3MCzbwdhzG3Jx1R0J2wetQyUynn6dYHAO+bg8l1k7jwZtRv4ryryFs7EP+NDlikJlVe59jr0cM2w==",
+ "dev": true,
+ "dependencies": {
+ "function-bind": "^1.1.1",
+ "get-intrinsic": "^1.0.0"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/call-me-maybe": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/call-me-maybe/-/call-me-maybe-1.0.1.tgz",
+ "integrity": "sha1-JtII6onje1y95gJQoV8DHBak1ms=",
+ "dev": true
+ },
+ "node_modules/callsites": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz",
+ "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==",
+ "dev": true,
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/camelcase": {
+ "version": "5.3.1",
+ "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz",
+ "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==",
+ "dev": true,
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/camelcase-keys": {
+ "version": "4.2.0",
+ "resolved": "https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-4.2.0.tgz",
+ "integrity": "sha1-oqpfsa9oh1glnDLBQUJteJI7m3c=",
+ "dev": true,
+ "dependencies": {
+ "camelcase": "^4.1.0",
+ "map-obj": "^2.0.0",
+ "quick-lru": "^1.0.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/camelcase-keys/node_modules/camelcase": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-4.1.0.tgz",
+ "integrity": "sha1-1UVjW+HjPFQmScaRc+Xeas+uNN0=",
+ "dev": true,
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/caniuse-lite": {
+ "version": "1.0.30001441",
+ "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001441.tgz",
+ "integrity": "sha512-OyxRR4Vof59I3yGWXws6i908EtGbMzVUi3ganaZQHmydk1iwDhRnvaPG2WaR0KcqrDFKrxVZHULT396LEPhXfg==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/browserslist"
+ },
+ {
+ "type": "tidelift",
+ "url": "https://tidelift.com/funding/github/npm/caniuse-lite"
+ }
+ ]
+ },
+ "node_modules/chalk": {
+ "version": "2.4.2",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
+ "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
+ "dev": true,
+ "dependencies": {
+ "ansi-styles": "^3.2.1",
+ "escape-string-regexp": "^1.0.5",
+ "supports-color": "^5.3.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/chardet": {
+ "version": "0.7.0",
+ "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.7.0.tgz",
+ "integrity": "sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==",
+ "dev": true
+ },
+ "node_modules/chokidar": {
+ "version": "3.5.3",
+ "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz",
+ "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "individual",
+ "url": "https://paulmillr.com/funding/"
+ }
+ ],
+ "dependencies": {
+ "anymatch": "~3.1.2",
+ "braces": "~3.0.2",
+ "glob-parent": "~5.1.2",
+ "is-binary-path": "~2.1.0",
+ "is-glob": "~4.0.1",
+ "normalize-path": "~3.0.0",
+ "readdirp": "~3.6.0"
+ },
+ "engines": {
+ "node": ">= 8.10.0"
+ },
+ "optionalDependencies": {
+ "fsevents": "~2.3.2"
+ }
+ },
+ "node_modules/chrome-trace-event": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.2.tgz",
+ "integrity": "sha512-9e/zx1jw7B4CO+c/RXoCsfg/x1AfUBioy4owYH0bJprEYAx5hRFLRhWBqHAG57D0ZM4H7vxbP7bPe0VwhQRYDQ==",
+ "dev": true,
+ "dependencies": {
+ "tslib": "^1.9.0"
+ },
+ "engines": {
+ "node": ">=6.0"
+ }
+ },
+ "node_modules/ci-info": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-2.0.0.tgz",
+ "integrity": "sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ==",
+ "dev": true
+ },
+ "node_modules/class-utils": {
+ "version": "0.3.6",
+ "resolved": "https://registry.npmjs.org/class-utils/-/class-utils-0.3.6.tgz",
+ "integrity": "sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg==",
+ "dev": true,
+ "dependencies": {
+ "arr-union": "^3.1.0",
+ "define-property": "^0.2.5",
+ "isobject": "^3.0.0",
+ "static-extend": "^0.1.1"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/class-utils/node_modules/define-property": {
+ "version": "0.2.5",
+ "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz",
+ "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=",
+ "dev": true,
+ "dependencies": {
+ "is-descriptor": "^0.1.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/clean-regexp": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/clean-regexp/-/clean-regexp-1.0.0.tgz",
+ "integrity": "sha1-jffHquUf02h06PjQW5GAvBGj/tc=",
+ "dev": true,
+ "dependencies": {
+ "escape-string-regexp": "^1.0.5"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/cli-boxes": {
+ "version": "2.2.1",
+ "resolved": "https://registry.npmjs.org/cli-boxes/-/cli-boxes-2.2.1.tgz",
+ "integrity": "sha512-y4coMcylgSCdVinjiDBuR8PCC2bLjyGTwEmPb9NHR/QaNU6EUOXcTY/s6VjGMD6ENSEaeQYHCY0GNGS5jfMwPw==",
+ "dev": true,
+ "engines": {
+ "node": ">=6"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/cli-cursor": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz",
+ "integrity": "sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==",
+ "dev": true,
+ "dependencies": {
+ "restore-cursor": "^3.1.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/cli-width": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-3.0.0.tgz",
+ "integrity": "sha512-FxqpkPPwu1HjuN93Omfm4h8uIanXofW0RxVEW3k5RKx+mJJYSthzNhp32Kzxxy3YAEZ/Dc/EWN1vZRY0+kOhbw==",
+ "dev": true,
+ "engines": {
+ "node": ">= 10"
+ }
+ },
+ "node_modules/clone-deep": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/clone-deep/-/clone-deep-4.0.1.tgz",
+ "integrity": "sha512-neHB9xuzh/wk0dIHweyAXv2aPGZIVk3pLMe+/RNzINf17fe0OG96QroktYAUm7SM1PBnzTabaLboqqxDyMU+SQ==",
+ "dev": true,
+ "dependencies": {
+ "is-plain-object": "^2.0.4",
+ "kind-of": "^6.0.2",
+ "shallow-clone": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/clone-response": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/clone-response/-/clone-response-1.0.2.tgz",
+ "integrity": "sha1-0dyXOSAxTfZ/vrlCI7TuNQI56Ws=",
+ "dev": true,
+ "dependencies": {
+ "mimic-response": "^1.0.0"
+ }
+ },
+ "node_modules/collection-visit": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/collection-visit/-/collection-visit-1.0.0.tgz",
+ "integrity": "sha1-S8A3PBZLwykbTTaMgpzxqApZ3KA=",
+ "dev": true,
+ "dependencies": {
+ "map-visit": "^1.0.0",
+ "object-visit": "^1.0.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/color-convert": {
+ "version": "1.9.3",
+ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz",
+ "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==",
+ "dev": true,
+ "dependencies": {
+ "color-name": "1.1.3"
+ }
+ },
+ "node_modules/color-name": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
+ "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=",
+ "dev": true
+ },
+ "node_modules/colorette": {
+ "version": "2.0.19",
+ "resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.19.tgz",
+ "integrity": "sha512-3tlv/dIP7FWvj3BsbHrGLJ6l/oKh1O3TcgBqMn+yyCagOxc23fyzDS6HypQbgxWbkpDnf52p1LuR4eWDQ/K9WQ==",
+ "dev": true
+ },
+ "node_modules/commander": {
+ "version": "2.20.3",
+ "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz",
+ "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==",
+ "dev": true
+ },
+ "node_modules/commondir": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz",
+ "integrity": "sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs=",
+ "dev": true
+ },
+ "node_modules/component-emitter": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.0.tgz",
+ "integrity": "sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg==",
+ "dev": true
+ },
+ "node_modules/concat-map": {
+ "version": "0.0.1",
+ "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
+ "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s="
+ },
+ "node_modules/configstore": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/configstore/-/configstore-5.0.1.tgz",
+ "integrity": "sha512-aMKprgk5YhBNyH25hj8wGt2+D52Sw1DRRIzqBwLp2Ya9mFmY8KPvvtvmna8SxVR9JMZ4kzMD68N22vlaRpkeFA==",
+ "dev": true,
+ "dependencies": {
+ "dot-prop": "^5.2.0",
+ "graceful-fs": "^4.1.2",
+ "make-dir": "^3.0.0",
+ "unique-string": "^2.0.0",
+ "write-file-atomic": "^3.0.0",
+ "xdg-basedir": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/confusing-browser-globals": {
+ "version": "1.0.9",
+ "resolved": "https://registry.npmjs.org/confusing-browser-globals/-/confusing-browser-globals-1.0.9.tgz",
+ "integrity": "sha512-KbS1Y0jMtyPgIxjO7ZzMAuUpAKMt1SzCL9fsrKsX6b0zJPTaT0SiSPmewwVZg9UAO83HVIlEhZF84LIjZ0lmAw==",
+ "dev": true
+ },
+ "node_modules/contains-path": {
+ "version": "0.1.0",
+ "resolved": "https://registry.npmjs.org/contains-path/-/contains-path-0.1.0.tgz",
+ "integrity": "sha1-/ozxhP9mcLa67wGp1IYaXL7EEgo=",
+ "dev": true,
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/convert-source-map": {
+ "version": "1.7.0",
+ "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.7.0.tgz",
+ "integrity": "sha512-4FJkXzKXEDB1snCFZlLP4gpC3JILicCpGbzG9f9G7tGqGCzETQ2hWPrcinA9oU4wtf2biUaEH5065UnMeR33oA==",
+ "dev": true,
+ "dependencies": {
+ "safe-buffer": "~5.1.1"
+ }
+ },
+ "node_modules/copy-descriptor": {
+ "version": "0.1.1",
+ "resolved": "https://registry.npmjs.org/copy-descriptor/-/copy-descriptor-0.1.1.tgz",
+ "integrity": "sha1-Z29us8OZl8LuGsOpJP1hJHSPV40=",
+ "dev": true,
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/core-assert": {
+ "version": "0.2.1",
+ "resolved": "https://registry.npmjs.org/core-assert/-/core-assert-0.2.1.tgz",
+ "integrity": "sha1-+F4s+b/tKPdzzIs/pcW2m9wC/j8=",
+ "dev": true,
+ "dependencies": {
+ "buf-compare": "^1.0.0",
+ "is-error": "^2.2.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/core-js-compat": {
+ "version": "3.6.5",
+ "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.6.5.tgz",
+ "integrity": "sha512-7ItTKOhOZbznhXAQ2g/slGg1PJV5zDO/WdkTwi7UEOJmkvsE32PWvx6mKtDjiMpjnR2CNf6BAD6sSxIlv7ptng==",
+ "dev": true,
+ "dependencies": {
+ "browserslist": "^4.8.5",
+ "semver": "7.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/core-js"
+ }
+ },
+ "node_modules/core-js-compat/node_modules/semver": {
+ "version": "7.0.0",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-7.0.0.tgz",
+ "integrity": "sha512-+GB6zVA9LWh6zovYQLALHwv5rb2PHGlJi3lfiqIHxR0uuwCgefcOJc59v9fv1w8GbStwxuuqqAjI9NMAOOgq1A==",
+ "dev": true,
+ "bin": {
+ "semver": "bin/semver.js"
+ }
+ },
+ "node_modules/core-util-is": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz",
+ "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=",
+ "dev": true
+ },
+ "node_modules/cross-spawn": {
+ "version": "6.0.5",
+ "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz",
+ "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==",
+ "dev": true,
+ "dependencies": {
+ "nice-try": "^1.0.4",
+ "path-key": "^2.0.1",
+ "semver": "^5.5.0",
+ "shebang-command": "^1.2.0",
+ "which": "^1.2.9"
+ },
+ "engines": {
+ "node": ">=4.8"
+ }
+ },
+ "node_modules/crypto-random-string": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/crypto-random-string/-/crypto-random-string-2.0.0.tgz",
+ "integrity": "sha512-v1plID3y9r/lPhviJ1wrXpLeyUIGAZ2SHNYTEapm7/8A9nLPoyvVp3RK/EPFqn5kEznyWgYZNsRtYYIWbuG8KA==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/currently-unhandled": {
+ "version": "0.4.1",
+ "resolved": "https://registry.npmjs.org/currently-unhandled/-/currently-unhandled-0.4.1.tgz",
+ "integrity": "sha1-mI3zP+qxke95mmE2nddsF635V+o=",
+ "dev": true,
+ "dependencies": {
+ "array-find-index": "^1.0.1"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/debug": {
+ "version": "4.3.4",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz",
+ "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==",
+ "dev": true,
+ "dependencies": {
+ "ms": "2.1.2"
+ },
+ "engines": {
+ "node": ">=6.0"
+ },
+ "peerDependenciesMeta": {
+ "supports-color": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/decamelize": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz",
+ "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=",
+ "dev": true,
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/decamelize-keys": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/decamelize-keys/-/decamelize-keys-1.1.0.tgz",
+ "integrity": "sha1-0XGoeTMlKAfrPLYdwcFEXQeN8tk=",
+ "dev": true,
+ "dependencies": {
+ "decamelize": "^1.1.0",
+ "map-obj": "^1.0.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/decamelize-keys/node_modules/map-obj": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-1.0.1.tgz",
+ "integrity": "sha1-2TPOuSBdgr3PSIb2dCvcK03qFG0=",
+ "dev": true,
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/decode-uri-component": {
+ "version": "0.2.2",
+ "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.2.tgz",
+ "integrity": "sha512-FqUYQ+8o158GyGTrMFJms9qh3CqTKvAqgqsTnkLI8sKu0028orqBhxNMFkFen0zGyg6epACD32pjVk58ngIErQ==",
+ "dev": true,
+ "engines": {
+ "node": ">=0.10"
+ }
+ },
+ "node_modules/decompress-response": {
+ "version": "3.3.0",
+ "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-3.3.0.tgz",
+ "integrity": "sha1-gKTdMjdIOEv6JICDYirt7Jgq3/M=",
+ "dev": true,
+ "dependencies": {
+ "mimic-response": "^1.0.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/deep-extend": {
+ "version": "0.6.0",
+ "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz",
+ "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==",
+ "dev": true,
+ "engines": {
+ "node": ">=4.0.0"
+ }
+ },
+ "node_modules/deep-is": {
+ "version": "0.1.3",
+ "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz",
+ "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=",
+ "dev": true
+ },
+ "node_modules/deep-strict-equal": {
+ "version": "0.2.0",
+ "resolved": "https://registry.npmjs.org/deep-strict-equal/-/deep-strict-equal-0.2.0.tgz",
+ "integrity": "sha1-SgeBR6irV/ag1PVUckPNIvROtOQ=",
+ "dev": true,
+ "dependencies": {
+ "core-assert": "^0.2.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/defer-to-connect": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/defer-to-connect/-/defer-to-connect-1.1.3.tgz",
+ "integrity": "sha512-0ISdNousHvZT2EiFlZeZAHBUvSxmKswVCEf8hW7KWgG4a8MVEu/3Vb6uWYozkjylyCxe0JBIiRB1jV45S70WVQ==",
+ "dev": true
+ },
+ "node_modules/define-properties": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz",
+ "integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==",
+ "dev": true,
+ "dependencies": {
+ "object-keys": "^1.0.12"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/define-property": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz",
+ "integrity": "sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==",
+ "dev": true,
+ "dependencies": {
+ "is-descriptor": "^1.0.2",
+ "isobject": "^3.0.1"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/define-property/node_modules/is-accessor-descriptor": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz",
+ "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==",
+ "deprecated": "Please upgrade to v1.0.1",
+ "dev": true,
+ "dependencies": {
+ "kind-of": "^6.0.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/define-property/node_modules/is-data-descriptor": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz",
+ "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==",
+ "deprecated": "Please upgrade to v1.0.1",
+ "dev": true,
+ "dependencies": {
+ "kind-of": "^6.0.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/define-property/node_modules/is-descriptor": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz",
+ "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==",
+ "dev": true,
+ "dependencies": {
+ "is-accessor-descriptor": "^1.0.0",
+ "is-data-descriptor": "^1.0.0",
+ "kind-of": "^6.0.2"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/diff": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/diff/-/diff-5.0.0.tgz",
+ "integrity": "sha512-/VTCrvm5Z0JGty/BWHljh+BAiw3IK+2j87NGMu8Nwc/f48WoDAC395uomO9ZD117ZOBaHmkX1oyLvkVM/aIT3w==",
+ "dev": true,
+ "engines": {
+ "node": ">=0.3.1"
+ }
+ },
+ "node_modules/dir-glob": {
+ "version": "2.2.2",
+ "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-2.2.2.tgz",
+ "integrity": "sha512-f9LBi5QWzIW3I6e//uxZoLBlUt9kcp66qo0sSCxL6YZKc75R1c4MFCoe/LaZiBGmgujvQdxc5Bn3QhfyvK5Hsw==",
+ "dev": true,
+ "dependencies": {
+ "path-type": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/dir-glob/node_modules/path-type": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/path-type/-/path-type-3.0.0.tgz",
+ "integrity": "sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg==",
+ "dev": true,
+ "dependencies": {
+ "pify": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/dir-glob/node_modules/pify": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz",
+ "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=",
+ "dev": true,
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/doctrine": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz",
+ "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==",
+ "dev": true,
+ "dependencies": {
+ "esutils": "^2.0.2"
+ },
+ "engines": {
+ "node": ">=6.0.0"
+ }
+ },
+ "node_modules/dot-prop": {
+ "version": "5.3.0",
+ "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-5.3.0.tgz",
+ "integrity": "sha512-QM8q3zDe58hqUqjraQOmzZ1LIH9SWQJTlEKCH4kJ2oQvLZk7RbQXvtDM2XEq3fwkV9CCvvH4LA0AV+ogFsBM2Q==",
+ "dev": true,
+ "dependencies": {
+ "is-obj": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/duplexer3": {
+ "version": "0.1.4",
+ "resolved": "https://registry.npmjs.org/duplexer3/-/duplexer3-0.1.4.tgz",
+ "integrity": "sha1-7gHdHKwO08vH/b6jfcCo8c4ALOI=",
+ "dev": true
+ },
+ "node_modules/emoji-regex": {
+ "version": "7.0.3",
+ "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz",
+ "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==",
+ "dev": true
+ },
+ "node_modules/emojis-list": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-3.0.0.tgz",
+ "integrity": "sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q==",
+ "dev": true,
+ "engines": {
+ "node": ">= 4"
+ }
+ },
+ "node_modules/end-of-stream": {
+ "version": "1.4.4",
+ "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz",
+ "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==",
+ "dev": true,
+ "dependencies": {
+ "once": "^1.4.0"
+ }
+ },
+ "node_modules/enhance-visitors": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/enhance-visitors/-/enhance-visitors-1.0.0.tgz",
+ "integrity": "sha1-qpRdBdpGVnKh69OP7i7T2oUY6Vo=",
+ "dev": true,
+ "dependencies": {
+ "lodash": "^4.13.1"
+ },
+ "engines": {
+ "node": ">=4.0.0"
+ }
+ },
+ "node_modules/enhanced-resolve": {
+ "version": "5.12.0",
+ "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.12.0.tgz",
+ "integrity": "sha512-QHTXI/sZQmko1cbDoNAa3mJ5qhWUUNAq3vR0/YiD379fWQrcfuoX1+HW2S0MTt7XmoPLapdaDKUtelUSPic7hQ==",
+ "dev": true,
+ "dependencies": {
+ "graceful-fs": "^4.2.4",
+ "tapable": "^2.2.0"
+ },
+ "engines": {
+ "node": ">=10.13.0"
+ }
+ },
+ "node_modules/env-editor": {
+ "version": "0.4.1",
+ "resolved": "https://registry.npmjs.org/env-editor/-/env-editor-0.4.1.tgz",
+ "integrity": "sha512-suh+Vm00GnPQgXpmONTkcUT9LgBSL6sJrRnJxbykT0j+ONjzmIS+1U3ne467ArdZN/42/npp+GnhtwkLQ+vUjw==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/envinfo": {
+ "version": "7.8.1",
+ "resolved": "https://registry.npmjs.org/envinfo/-/envinfo-7.8.1.tgz",
+ "integrity": "sha512-/o+BXHmB7ocbHEAs6F2EnG0ogybVVUdkRunTT2glZU9XAaGmhqskrvKwqXuDfNjEO0LZKWdejEEpnq8aM0tOaw==",
+ "dev": true,
+ "bin": {
+ "envinfo": "dist/cli.js"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/error-ex": {
+ "version": "1.3.2",
+ "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz",
+ "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==",
+ "dev": true,
+ "dependencies": {
+ "is-arrayish": "^0.2.1"
+ }
+ },
+ "node_modules/es-abstract": {
+ "version": "1.17.7",
+ "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.17.7.tgz",
+ "integrity": "sha512-VBl/gnfcJ7OercKA9MVaegWsBHFjV492syMudcnQZvt/Dw8ezpcOHYZXa/J96O8vx+g4x65YKhxOwDUh63aS5g==",
+ "dev": true,
+ "dependencies": {
+ "es-to-primitive": "^1.2.1",
+ "function-bind": "^1.1.1",
+ "has": "^1.0.3",
+ "has-symbols": "^1.0.1",
+ "is-callable": "^1.2.2",
+ "is-regex": "^1.1.1",
+ "object-inspect": "^1.8.0",
+ "object-keys": "^1.1.1",
+ "object.assign": "^4.1.1",
+ "string.prototype.trimend": "^1.0.1",
+ "string.prototype.trimstart": "^1.0.1"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/es-module-lexer": {
+ "version": "0.9.3",
+ "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-0.9.3.tgz",
+ "integrity": "sha512-1HQ2M2sPtxwnvOvT1ZClHyQDiggdNjURWpY2we6aMKCQiUVxTmVs2UYPLIrD84sS+kMdUwfBSylbJPwNnBrnHQ==",
+ "dev": true
+ },
+ "node_modules/es-to-primitive": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz",
+ "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==",
+ "dev": true,
+ "dependencies": {
+ "is-callable": "^1.1.4",
+ "is-date-object": "^1.0.1",
+ "is-symbol": "^1.0.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/escalade": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz",
+ "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==",
+ "dev": true,
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/escape-goat": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/escape-goat/-/escape-goat-2.1.1.tgz",
+ "integrity": "sha512-8/uIhbG12Csjy2JEW7D9pHbreaVaS/OpN3ycnyvElTdwM5n6GY6W6e2IPemfvGZeUMqZ9A/3GqIZMgKnBhAw/Q==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/escape-string-regexp": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
+ "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=",
+ "dev": true,
+ "engines": {
+ "node": ">=0.8.0"
+ }
+ },
+ "node_modules/eslint": {
+ "version": "6.8.0",
+ "resolved": "https://registry.npmjs.org/eslint/-/eslint-6.8.0.tgz",
+ "integrity": "sha512-K+Iayyo2LtyYhDSYwz5D5QdWw0hCacNzyq1Y821Xna2xSJj7cijoLLYmLxTQgcgZ9mC61nryMy9S7GRbYpI5Ig==",
+ "deprecated": "This version is no longer supported. Please see https://eslint.org/version-support for other options.",
+ "dev": true,
+ "dependencies": {
+ "@babel/code-frame": "^7.0.0",
+ "ajv": "^6.10.0",
+ "chalk": "^2.1.0",
+ "cross-spawn": "^6.0.5",
+ "debug": "^4.0.1",
+ "doctrine": "^3.0.0",
+ "eslint-scope": "^5.0.0",
+ "eslint-utils": "^1.4.3",
+ "eslint-visitor-keys": "^1.1.0",
+ "espree": "^6.1.2",
+ "esquery": "^1.0.1",
+ "esutils": "^2.0.2",
+ "file-entry-cache": "^5.0.1",
+ "functional-red-black-tree": "^1.0.1",
+ "glob-parent": "^5.0.0",
+ "globals": "^12.1.0",
+ "ignore": "^4.0.6",
+ "import-fresh": "^3.0.0",
+ "imurmurhash": "^0.1.4",
+ "inquirer": "^7.0.0",
+ "is-glob": "^4.0.0",
+ "js-yaml": "^3.13.1",
+ "json-stable-stringify-without-jsonify": "^1.0.1",
+ "levn": "^0.3.0",
+ "lodash": "^4.17.14",
+ "minimatch": "^3.0.4",
+ "mkdirp": "^0.5.1",
+ "natural-compare": "^1.4.0",
+ "optionator": "^0.8.3",
+ "progress": "^2.0.0",
+ "regexpp": "^2.0.1",
+ "semver": "^6.1.2",
+ "strip-ansi": "^5.2.0",
+ "strip-json-comments": "^3.0.1",
+ "table": "^5.2.3",
+ "text-table": "^0.2.0",
+ "v8-compile-cache": "^2.0.3"
+ },
+ "bin": {
+ "eslint": "bin/eslint.js"
+ },
+ "engines": {
+ "node": "^8.10.0 || ^10.13.0 || >=11.10.1"
+ },
+ "funding": {
+ "url": "https://opencollective.com/eslint"
+ }
+ },
+ "node_modules/eslint-ast-utils": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/eslint-ast-utils/-/eslint-ast-utils-1.1.0.tgz",
+ "integrity": "sha512-otzzTim2/1+lVrlH19EfQQJEhVJSu0zOb9ygb3iapN6UlyaDtyRq4b5U1FuW0v1lRa9Fp/GJyHkSwm6NqABgCA==",
+ "dev": true,
+ "dependencies": {
+ "lodash.get": "^4.4.2",
+ "lodash.zip": "^4.2.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/eslint-config-prettier": {
+ "version": "6.15.0",
+ "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-6.15.0.tgz",
+ "integrity": "sha512-a1+kOYLR8wMGustcgAjdydMsQ2A/2ipRPwRKUmfYaSxc9ZPcrku080Ctl6zrZzZNs/U82MjSv+qKREkoq3bJaw==",
+ "dev": true,
+ "dependencies": {
+ "get-stdin": "^6.0.0"
+ },
+ "bin": {
+ "eslint-config-prettier-check": "bin/cli.js"
+ },
+ "peerDependencies": {
+ "eslint": ">=3.14.1"
+ }
+ },
+ "node_modules/eslint-config-prettier/node_modules/get-stdin": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-6.0.0.tgz",
+ "integrity": "sha512-jp4tHawyV7+fkkSKyvjuLZswblUtz+SQKzSWnBbii16BuZksJlU1wuBYXY75r+duh/llF1ur6oNwi+2ZzjKZ7g==",
+ "dev": true,
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/eslint-config-xo": {
+ "version": "0.29.1",
+ "resolved": "https://registry.npmjs.org/eslint-config-xo/-/eslint-config-xo-0.29.1.tgz",
+ "integrity": "sha512-RDjeKh8CV0/EH4utW/6uOkwJJOOU+rX3uE5eUBOamcLNe4lNjyo8kSt3B6DzAm1L/1tWGikI7LFNVY9gG7PDQw==",
+ "dev": true,
+ "dependencies": {
+ "confusing-browser-globals": "1.0.9"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ },
+ "peerDependencies": {
+ "eslint": ">=6.8.0"
+ }
+ },
+ "node_modules/eslint-formatter-pretty": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/eslint-formatter-pretty/-/eslint-formatter-pretty-3.0.1.tgz",
+ "integrity": "sha512-hhQ/ASD4i6BAEalcEfUxesFtJFftT8xFsimCzUpPbTzygJ4J17yCGcJ3XKCB2g7XTJTv0pi7rVTadfHVmtfSRA==",
+ "dev": true,
+ "dependencies": {
+ "ansi-escapes": "^4.2.1",
+ "chalk": "^3.0.0",
+ "eslint-rule-docs": "^1.1.5",
+ "log-symbols": "^3.0.0",
+ "plur": "^3.0.1",
+ "string-width": "^4.2.0",
+ "supports-hyperlinks": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/eslint-formatter-pretty/node_modules/ansi-styles": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
+ "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
+ "dev": true,
+ "dependencies": {
+ "color-convert": "^2.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/ansi-styles?sponsor=1"
+ }
+ },
+ "node_modules/eslint-formatter-pretty/node_modules/chalk": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz",
+ "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==",
+ "dev": true,
+ "dependencies": {
+ "ansi-styles": "^4.1.0",
+ "supports-color": "^7.1.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/eslint-formatter-pretty/node_modules/color-convert": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
+ "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
+ "dev": true,
+ "dependencies": {
+ "color-name": "~1.1.4"
+ },
+ "engines": {
+ "node": ">=7.0.0"
+ }
+ },
+ "node_modules/eslint-formatter-pretty/node_modules/color-name": {
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
+ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
+ "dev": true
+ },
+ "node_modules/eslint-formatter-pretty/node_modules/has-flag": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
+ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/eslint-formatter-pretty/node_modules/supports-color": {
+ "version": "7.2.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
+ "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
+ "dev": true,
+ "dependencies": {
+ "has-flag": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/eslint-import-resolver-node": {
+ "version": "0.3.4",
+ "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.4.tgz",
+ "integrity": "sha512-ogtf+5AB/O+nM6DIeBUNr2fuT7ot9Qg/1harBfBtaP13ekEWFQEEMP94BCB7zaNW3gyY+8SHYF00rnqYwXKWOA==",
+ "dev": true,
+ "dependencies": {
+ "debug": "^2.6.9",
+ "resolve": "^1.13.1"
+ }
+ },
+ "node_modules/eslint-import-resolver-node/node_modules/debug": {
+ "version": "2.6.9",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
+ "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
+ "dev": true,
+ "dependencies": {
+ "ms": "2.0.0"
+ }
+ },
+ "node_modules/eslint-import-resolver-node/node_modules/ms": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
+ "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=",
+ "dev": true
+ },
+ "node_modules/eslint-module-utils": {
+ "version": "2.6.0",
+ "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.6.0.tgz",
+ "integrity": "sha512-6j9xxegbqe8/kZY8cYpcp0xhbK0EgJlg3g9mib3/miLaExuuwc3n5UEfSnU6hWMbT0FAYVvDbL9RrRgpUeQIvA==",
+ "dev": true,
+ "dependencies": {
+ "debug": "^2.6.9",
+ "pkg-dir": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/eslint-module-utils/node_modules/debug": {
+ "version": "2.6.9",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
+ "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
+ "dev": true,
+ "dependencies": {
+ "ms": "2.0.0"
+ }
+ },
+ "node_modules/eslint-module-utils/node_modules/find-up": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz",
+ "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=",
+ "dev": true,
+ "dependencies": {
+ "locate-path": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/eslint-module-utils/node_modules/locate-path": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz",
+ "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=",
+ "dev": true,
+ "dependencies": {
+ "p-locate": "^2.0.0",
+ "path-exists": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/eslint-module-utils/node_modules/ms": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
+ "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=",
+ "dev": true
+ },
+ "node_modules/eslint-module-utils/node_modules/p-limit": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz",
+ "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==",
+ "dev": true,
+ "dependencies": {
+ "p-try": "^1.0.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/eslint-module-utils/node_modules/p-locate": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz",
+ "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=",
+ "dev": true,
+ "dependencies": {
+ "p-limit": "^1.1.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/eslint-module-utils/node_modules/p-try": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz",
+ "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=",
+ "dev": true,
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/eslint-module-utils/node_modules/pkg-dir": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-2.0.0.tgz",
+ "integrity": "sha1-9tXREJ4Z1j7fQo4L1X4Sd3YVM0s=",
+ "dev": true,
+ "dependencies": {
+ "find-up": "^2.1.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/eslint-plugin-ava": {
+ "version": "10.5.0",
+ "resolved": "https://registry.npmjs.org/eslint-plugin-ava/-/eslint-plugin-ava-10.5.0.tgz",
+ "integrity": "sha512-2I0Ze8ZtwbSlLdnzms4bsa6PxxOxGMIJ9d4yy7aRy3yc5zEO2wHJLic8l3Lrct73hb5ML+PLt5VRqvdV87xWdQ==",
+ "dev": true,
+ "dependencies": {
+ "deep-strict-equal": "^0.2.0",
+ "enhance-visitors": "^1.0.0",
+ "espree": "^7.1.0",
+ "espurify": "^2.0.1",
+ "import-modules": "^2.0.0",
+ "micro-spelling-correcter": "^1.1.1",
+ "pkg-dir": "^4.2.0",
+ "resolve-from": "^5.0.0"
+ },
+ "engines": {
+ "node": ">=10.18.0 <11 || >=12.14.0 <13 || >=14"
+ },
+ "peerDependencies": {
+ "eslint": ">=6.2.0"
+ }
+ },
+ "node_modules/eslint-plugin-ava/node_modules/acorn": {
+ "version": "7.4.1",
+ "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz",
+ "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==",
+ "dev": true,
+ "bin": {
+ "acorn": "bin/acorn"
+ },
+ "engines": {
+ "node": ">=0.4.0"
+ }
+ },
+ "node_modules/eslint-plugin-ava/node_modules/espree": {
+ "version": "7.3.0",
+ "resolved": "https://registry.npmjs.org/espree/-/espree-7.3.0.tgz",
+ "integrity": "sha512-dksIWsvKCixn1yrEXO8UosNSxaDoSYpq9reEjZSbHLpT5hpaCAKTLBwq0RHtLrIr+c0ByiYzWT8KTMRzoRCNlw==",
+ "dev": true,
+ "dependencies": {
+ "acorn": "^7.4.0",
+ "acorn-jsx": "^5.2.0",
+ "eslint-visitor-keys": "^1.3.0"
+ },
+ "engines": {
+ "node": "^10.12.0 || >=12.0.0"
+ }
+ },
+ "node_modules/eslint-plugin-es": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/eslint-plugin-es/-/eslint-plugin-es-3.0.1.tgz",
+ "integrity": "sha512-GUmAsJaN4Fc7Gbtl8uOBlayo2DqhwWvEzykMHSCZHU3XdJ+NSzzZcVhXh3VxX5icqQ+oQdIEawXX8xkR3mIFmQ==",
+ "dev": true,
+ "dependencies": {
+ "eslint-utils": "^2.0.0",
+ "regexpp": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=8.10.0"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/mysticatea"
+ },
+ "peerDependencies": {
+ "eslint": ">=4.19.1"
+ }
+ },
+ "node_modules/eslint-plugin-es/node_modules/regexpp": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.1.0.tgz",
+ "integrity": "sha512-ZOIzd8yVsQQA7j8GCSlPGXwg5PfmA1mrq0JP4nGhh54LaKN3xdai/vHUDu74pKwV8OxseMS65u2NImosQcSD0Q==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/mysticatea"
+ }
+ },
+ "node_modules/eslint-plugin-eslint-comments": {
+ "version": "3.2.0",
+ "resolved": "https://registry.npmjs.org/eslint-plugin-eslint-comments/-/eslint-plugin-eslint-comments-3.2.0.tgz",
+ "integrity": "sha512-0jkOl0hfojIHHmEHgmNdqv4fmh7300NdpA9FFpF7zaoLvB/QeXOGNLIo86oAveJFrfB1p05kC8hpEMHM8DwWVQ==",
+ "dev": true,
+ "dependencies": {
+ "escape-string-regexp": "^1.0.5",
+ "ignore": "^5.0.5"
+ },
+ "engines": {
+ "node": ">=6.5.0"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/mysticatea"
+ },
+ "peerDependencies": {
+ "eslint": ">=4.19.1"
+ }
+ },
+ "node_modules/eslint-plugin-eslint-comments/node_modules/ignore": {
+ "version": "5.1.8",
+ "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.1.8.tgz",
+ "integrity": "sha512-BMpfD7PpiETpBl/A6S498BaIJ6Y/ABT93ETbby2fP00v4EbvPBXWEoaR1UBPKs3iR53pJY7EtZk5KACI57i1Uw==",
+ "dev": true,
+ "engines": {
+ "node": ">= 4"
+ }
+ },
+ "node_modules/eslint-plugin-import": {
+ "version": "2.22.1",
+ "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.22.1.tgz",
+ "integrity": "sha512-8K7JjINHOpH64ozkAhpT3sd+FswIZTfMZTjdx052pnWrgRCVfp8op9tbjpAk3DdUeI/Ba4C8OjdC0r90erHEOw==",
+ "dev": true,
+ "dependencies": {
+ "array-includes": "^3.1.1",
+ "array.prototype.flat": "^1.2.3",
+ "contains-path": "^0.1.0",
+ "debug": "^2.6.9",
+ "doctrine": "1.5.0",
+ "eslint-import-resolver-node": "^0.3.4",
+ "eslint-module-utils": "^2.6.0",
+ "has": "^1.0.3",
+ "minimatch": "^3.0.4",
+ "object.values": "^1.1.1",
+ "read-pkg-up": "^2.0.0",
+ "resolve": "^1.17.0",
+ "tsconfig-paths": "^3.9.0"
+ },
+ "engines": {
+ "node": ">=4"
+ },
+ "peerDependencies": {
+ "eslint": "^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0"
+ }
+ },
+ "node_modules/eslint-plugin-import/node_modules/debug": {
+ "version": "2.6.9",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
+ "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
+ "dev": true,
+ "dependencies": {
+ "ms": "2.0.0"
+ }
+ },
+ "node_modules/eslint-plugin-import/node_modules/doctrine": {
+ "version": "1.5.0",
+ "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-1.5.0.tgz",
+ "integrity": "sha1-N53Ocw9hZvds76TmcHoVmwLFpvo=",
+ "dev": true,
+ "dependencies": {
+ "esutils": "^2.0.2",
+ "isarray": "^1.0.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/eslint-plugin-import/node_modules/isarray": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
+ "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=",
+ "dev": true
+ },
+ "node_modules/eslint-plugin-import/node_modules/ms": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
+ "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=",
+ "dev": true
+ },
+ "node_modules/eslint-plugin-mocha": {
+ "version": "6.3.0",
+ "resolved": "https://registry.npmjs.org/eslint-plugin-mocha/-/eslint-plugin-mocha-6.3.0.tgz",
+ "integrity": "sha512-Cd2roo8caAyG21oKaaNTj7cqeYRWW1I2B5SfpKRp0Ip1gkfwoR1Ow0IGlPWnNjzywdF4n+kHL8/9vM6zCJUxdg==",
+ "dev": true,
+ "dependencies": {
+ "eslint-utils": "^2.0.0",
+ "ramda": "^0.27.0"
+ },
+ "engines": {
+ "node": ">=8.0.0"
+ },
+ "peerDependencies": {
+ "eslint": ">= 4.0.0"
+ }
+ },
+ "node_modules/eslint-plugin-no-use-extend-native": {
+ "version": "0.4.1",
+ "resolved": "https://registry.npmjs.org/eslint-plugin-no-use-extend-native/-/eslint-plugin-no-use-extend-native-0.4.1.tgz",
+ "integrity": "sha512-tDkHM0kvxU0M2TpLRKGfFrpWXctFdTDY7VkiDTLYDaX90hMSJKkr/FiWThEXvKV0Dvffut2Z0B9Y7+h/k6suiA==",
+ "dev": true,
+ "dependencies": {
+ "is-get-set-prop": "^1.0.0",
+ "is-js-type": "^2.0.0",
+ "is-obj-prop": "^1.0.0",
+ "is-proto-prop": "^2.0.0"
+ }
+ },
+ "node_modules/eslint-plugin-node": {
+ "version": "11.1.0",
+ "resolved": "https://registry.npmjs.org/eslint-plugin-node/-/eslint-plugin-node-11.1.0.tgz",
+ "integrity": "sha512-oUwtPJ1W0SKD0Tr+wqu92c5xuCeQqB3hSCHasn/ZgjFdA9iDGNkNf2Zi9ztY7X+hNuMib23LNGRm6+uN+KLE3g==",
+ "dev": true,
+ "dependencies": {
+ "eslint-plugin-es": "^3.0.0",
+ "eslint-utils": "^2.0.0",
+ "ignore": "^5.1.1",
+ "minimatch": "^3.0.4",
+ "resolve": "^1.10.1",
+ "semver": "^6.1.0"
+ },
+ "engines": {
+ "node": ">=8.10.0"
+ },
+ "peerDependencies": {
+ "eslint": ">=5.16.0"
+ }
+ },
+ "node_modules/eslint-plugin-node/node_modules/ignore": {
+ "version": "5.1.8",
+ "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.1.8.tgz",
+ "integrity": "sha512-BMpfD7PpiETpBl/A6S498BaIJ6Y/ABT93ETbby2fP00v4EbvPBXWEoaR1UBPKs3iR53pJY7EtZk5KACI57i1Uw==",
+ "dev": true,
+ "engines": {
+ "node": ">= 4"
+ }
+ },
+ "node_modules/eslint-plugin-node/node_modules/semver": {
+ "version": "6.3.0",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
+ "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
+ "dev": true,
+ "bin": {
+ "semver": "bin/semver.js"
+ }
+ },
+ "node_modules/eslint-plugin-prettier": {
+ "version": "3.1.4",
+ "resolved": "https://registry.npmjs.org/eslint-plugin-prettier/-/eslint-plugin-prettier-3.1.4.tgz",
+ "integrity": "sha512-jZDa8z76klRqo+TdGDTFJSavwbnWK2ZpqGKNZ+VvweMW516pDUMmQ2koXvxEE4JhzNvTv+radye/bWGBmA6jmg==",
+ "dev": true,
+ "dependencies": {
+ "prettier-linter-helpers": "^1.0.0"
+ },
+ "engines": {
+ "node": ">=6.0.0"
+ },
+ "peerDependencies": {
+ "eslint": ">=5.0.0",
+ "prettier": ">=1.13.0"
+ }
+ },
+ "node_modules/eslint-plugin-promise": {
+ "version": "4.2.1",
+ "resolved": "https://registry.npmjs.org/eslint-plugin-promise/-/eslint-plugin-promise-4.2.1.tgz",
+ "integrity": "sha512-VoM09vT7bfA7D+upt+FjeBO5eHIJQBUWki1aPvB+vbNiHS3+oGIJGIeyBtKQTME6UPXXy3vV07OL1tHd3ANuDw==",
+ "dev": true,
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/eslint-plugin-unicorn": {
+ "version": "16.1.1",
+ "resolved": "https://registry.npmjs.org/eslint-plugin-unicorn/-/eslint-plugin-unicorn-16.1.1.tgz",
+ "integrity": "sha512-IMxCsntb0T8s660Irc40gtzXtxuXHcOn36G9G8OYKfiseBD/kNrA1cNJhsJ0xQteDASGrFwqdzBsYEkUvczhOA==",
+ "dev": true,
+ "dependencies": {
+ "ci-info": "^2.0.0",
+ "clean-regexp": "^1.0.0",
+ "eslint-ast-utils": "^1.1.0",
+ "eslint-template-visitor": "^1.1.0",
+ "import-modules": "^2.0.0",
+ "lodash.camelcase": "^4.3.0",
+ "lodash.defaultsdeep": "^4.6.1",
+ "lodash.kebabcase": "^4.1.1",
+ "lodash.snakecase": "^4.1.1",
+ "lodash.upperfirst": "^4.3.1",
+ "read-pkg-up": "^7.0.1",
+ "regexp-tree": "^0.1.17",
+ "regexpp": "^3.0.0",
+ "reserved-words": "^0.1.2",
+ "safe-regex": "^2.1.1",
+ "semver": "^7.1.2"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sindresorhus/eslint-plugin-unicorn?sponsor=1"
+ },
+ "peerDependencies": {
+ "eslint": ">=6.7.1"
+ }
+ },
+ "node_modules/eslint-plugin-unicorn/node_modules/find-up": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz",
+ "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==",
+ "dev": true,
+ "dependencies": {
+ "locate-path": "^5.0.0",
+ "path-exists": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/eslint-plugin-unicorn/node_modules/locate-path": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz",
+ "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==",
+ "dev": true,
+ "dependencies": {
+ "p-locate": "^4.1.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/eslint-plugin-unicorn/node_modules/p-locate": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz",
+ "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==",
+ "dev": true,
+ "dependencies": {
+ "p-limit": "^2.2.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/eslint-plugin-unicorn/node_modules/parse-json": {
+ "version": "5.1.0",
+ "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.1.0.tgz",
+ "integrity": "sha512-+mi/lmVVNKFNVyLXV31ERiy2CY5E1/F6QtJFEzoChPRwwngMNXRDQ9GJ5WdE2Z2P4AujsOi0/+2qHID68KwfIQ==",
+ "dev": true,
+ "dependencies": {
+ "@babel/code-frame": "^7.0.0",
+ "error-ex": "^1.3.1",
+ "json-parse-even-better-errors": "^2.3.0",
+ "lines-and-columns": "^1.1.6"
+ },
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/eslint-plugin-unicorn/node_modules/path-exists": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz",
+ "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/eslint-plugin-unicorn/node_modules/read-pkg": {
+ "version": "5.2.0",
+ "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-5.2.0.tgz",
+ "integrity": "sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg==",
+ "dev": true,
+ "dependencies": {
+ "@types/normalize-package-data": "^2.4.0",
+ "normalize-package-data": "^2.5.0",
+ "parse-json": "^5.0.0",
+ "type-fest": "^0.6.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/eslint-plugin-unicorn/node_modules/read-pkg-up": {
+ "version": "7.0.1",
+ "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-7.0.1.tgz",
+ "integrity": "sha512-zK0TB7Xd6JpCLmlLmufqykGE+/TlOePD6qKClNW7hHDKFh/J7/7gCWGR7joEQEW1bKq3a3yUZSObOoWLFQ4ohg==",
+ "dev": true,
+ "dependencies": {
+ "find-up": "^4.1.0",
+ "read-pkg": "^5.2.0",
+ "type-fest": "^0.8.1"
+ },
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/eslint-plugin-unicorn/node_modules/read-pkg/node_modules/type-fest": {
+ "version": "0.6.0",
+ "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.6.0.tgz",
+ "integrity": "sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/eslint-plugin-unicorn/node_modules/regexpp": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.1.0.tgz",
+ "integrity": "sha512-ZOIzd8yVsQQA7j8GCSlPGXwg5PfmA1mrq0JP4nGhh54LaKN3xdai/vHUDu74pKwV8OxseMS65u2NImosQcSD0Q==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/mysticatea"
+ }
+ },
+ "node_modules/eslint-plugin-unicorn/node_modules/safe-regex": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/safe-regex/-/safe-regex-2.1.1.tgz",
+ "integrity": "sha512-rx+x8AMzKb5Q5lQ95Zoi6ZbJqwCLkqi3XuJXp5P3rT8OEc6sZCJG5AE5dU3lsgRr/F4Bs31jSlVN+j5KrsGu9A==",
+ "dev": true,
+ "dependencies": {
+ "regexp-tree": "~0.1.1"
+ }
+ },
+ "node_modules/eslint-plugin-unicorn/node_modules/semver": {
+ "version": "7.3.2",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.2.tgz",
+ "integrity": "sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ==",
+ "dev": true,
+ "bin": {
+ "semver": "bin/semver.js"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/eslint-rule-docs": {
+ "version": "1.1.213",
+ "resolved": "https://registry.npmjs.org/eslint-rule-docs/-/eslint-rule-docs-1.1.213.tgz",
+ "integrity": "sha512-oKJ88HkMlWcsznM4HQIPiMnUMGbkPjO8LLsTikxLbrfP2znUGa90FSQiVHazRZsX72e650g++uDNRWtb4qzDgw==",
+ "dev": true
+ },
+ "node_modules/eslint-scope": {
+ "version": "5.1.1",
+ "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz",
+ "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==",
+ "dev": true,
+ "dependencies": {
+ "esrecurse": "^4.3.0",
+ "estraverse": "^4.1.1"
+ },
+ "engines": {
+ "node": ">=8.0.0"
+ }
+ },
+ "node_modules/eslint-template-visitor": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/eslint-template-visitor/-/eslint-template-visitor-1.1.0.tgz",
+ "integrity": "sha512-Lmy6QVlmFiIGl5fPi+8ACnov3sare+0Ouf7deJAGGhmUfeWJ5fVarELUxZRpsZ9sHejiJUq8626d0dn9uvcZTw==",
+ "dev": true,
+ "dependencies": {
+ "eslint-visitor-keys": "^1.1.0",
+ "espree": "^6.1.1",
+ "multimap": "^1.0.2"
+ },
+ "peerDependencies": {
+ "eslint": "^6.4.0"
+ }
+ },
+ "node_modules/eslint-utils": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-2.1.0.tgz",
+ "integrity": "sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg==",
+ "dev": true,
+ "dependencies": {
+ "eslint-visitor-keys": "^1.1.0"
+ },
+ "engines": {
+ "node": ">=6"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/mysticatea"
+ }
+ },
+ "node_modules/eslint-visitor-keys": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz",
+ "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==",
+ "dev": true,
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/eslint/node_modules/ansi-regex": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.1.tgz",
+ "integrity": "sha512-ILlv4k/3f6vfQ4OoP2AGvirOktlQ98ZEL1k9FaQjxa3L1abBgbuTDAdPOpvbGncC0BTVQrl+OM8xZGK6tWXt7g==",
+ "dev": true,
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/eslint/node_modules/eslint-utils": {
+ "version": "1.4.3",
+ "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-1.4.3.tgz",
+ "integrity": "sha512-fbBN5W2xdY45KulGXmLHZ3c3FHfVYmKg0IrAKGOkT/464PQsx2UeIzfz1RmEci+KLm1bBaAzZAh8+/E+XAeZ8Q==",
+ "dev": true,
+ "dependencies": {
+ "eslint-visitor-keys": "^1.1.0"
+ },
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/eslint/node_modules/globals": {
+ "version": "12.4.0",
+ "resolved": "https://registry.npmjs.org/globals/-/globals-12.4.0.tgz",
+ "integrity": "sha512-BWICuzzDvDoH54NHKCseDanAhE3CeDorgDL5MT6LMXXj2WCnd9UC2szdk4AWLfjdgNBCXLUanXYcpBBKOSWGwg==",
+ "dev": true,
+ "dependencies": {
+ "type-fest": "^0.8.1"
+ },
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/eslint/node_modules/semver": {
+ "version": "6.3.0",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
+ "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
+ "dev": true,
+ "bin": {
+ "semver": "bin/semver.js"
+ }
+ },
+ "node_modules/eslint/node_modules/strip-ansi": {
+ "version": "5.2.0",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz",
+ "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==",
+ "dev": true,
+ "dependencies": {
+ "ansi-regex": "^4.1.0"
+ },
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/eslint/node_modules/strip-json-comments": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz",
+ "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/espree": {
+ "version": "6.2.1",
+ "resolved": "https://registry.npmjs.org/espree/-/espree-6.2.1.tgz",
+ "integrity": "sha512-ysCxRQY3WaXJz9tdbWOwuWr5Y/XrPTGX9Kiz3yoUXwW0VZ4w30HTkQLaGx/+ttFjF8i+ACbArnB4ce68a9m5hw==",
+ "dev": true,
+ "dependencies": {
+ "acorn": "^7.1.1",
+ "acorn-jsx": "^5.2.0",
+ "eslint-visitor-keys": "^1.1.0"
+ },
+ "engines": {
+ "node": ">=6.0.0"
+ }
+ },
+ "node_modules/espree/node_modules/acorn": {
+ "version": "7.4.1",
+ "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz",
+ "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==",
+ "dev": true,
+ "bin": {
+ "acorn": "bin/acorn"
+ },
+ "engines": {
+ "node": ">=0.4.0"
+ }
+ },
+ "node_modules/esprima": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz",
+ "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==",
+ "dev": true,
+ "bin": {
+ "esparse": "bin/esparse.js",
+ "esvalidate": "bin/esvalidate.js"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/espurify": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/espurify/-/espurify-2.0.1.tgz",
+ "integrity": "sha512-7w/dUrReI/QbJFHRwfomTlkQOXaB1NuCrBRn5Y26HXn5gvh18/19AgLbayVrNxXQfkckvgrJloWyvZDuJ7dhEA==",
+ "dev": true
+ },
+ "node_modules/esquery": {
+ "version": "1.3.1",
+ "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.3.1.tgz",
+ "integrity": "sha512-olpvt9QG0vniUBZspVRN6lwB7hOZoTRtT+jzR+tS4ffYx2mzbw+z0XCOk44aaLYKApNX5nMm+E+P6o25ip/DHQ==",
+ "dev": true,
+ "dependencies": {
+ "estraverse": "^5.1.0"
+ },
+ "engines": {
+ "node": ">=0.10"
+ }
+ },
+ "node_modules/esquery/node_modules/estraverse": {
+ "version": "5.2.0",
+ "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.2.0.tgz",
+ "integrity": "sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ==",
+ "dev": true,
+ "engines": {
+ "node": ">=4.0"
+ }
+ },
+ "node_modules/esrecurse": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz",
+ "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==",
+ "dev": true,
+ "dependencies": {
+ "estraverse": "^5.2.0"
+ },
+ "engines": {
+ "node": ">=4.0"
+ }
+ },
+ "node_modules/esrecurse/node_modules/estraverse": {
+ "version": "5.2.0",
+ "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.2.0.tgz",
+ "integrity": "sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ==",
+ "dev": true,
+ "engines": {
+ "node": ">=4.0"
+ }
+ },
+ "node_modules/estraverse": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz",
+ "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==",
+ "dev": true,
+ "engines": {
+ "node": ">=4.0"
+ }
+ },
+ "node_modules/esutils": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz",
+ "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==",
+ "dev": true,
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/events": {
+ "version": "3.3.0",
+ "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz",
+ "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==",
+ "dev": true,
+ "engines": {
+ "node": ">=0.8.x"
+ }
+ },
+ "node_modules/expand-brackets": {
+ "version": "2.1.4",
+ "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz",
+ "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=",
+ "dev": true,
+ "dependencies": {
+ "debug": "^2.3.3",
+ "define-property": "^0.2.5",
+ "extend-shallow": "^2.0.1",
+ "posix-character-classes": "^0.1.0",
+ "regex-not": "^1.0.0",
+ "snapdragon": "^0.8.1",
+ "to-regex": "^3.0.1"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/expand-brackets/node_modules/debug": {
+ "version": "2.6.9",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
+ "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
+ "dev": true,
+ "dependencies": {
+ "ms": "2.0.0"
+ }
+ },
+ "node_modules/expand-brackets/node_modules/define-property": {
+ "version": "0.2.5",
+ "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz",
+ "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=",
+ "dev": true,
+ "dependencies": {
+ "is-descriptor": "^0.1.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/expand-brackets/node_modules/extend-shallow": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
+ "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
+ "dev": true,
+ "dependencies": {
+ "is-extendable": "^0.1.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/expand-brackets/node_modules/ms": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
+ "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=",
+ "dev": true
+ },
+ "node_modules/extend-shallow": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz",
+ "integrity": "sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg=",
+ "dev": true,
+ "dependencies": {
+ "assign-symbols": "^1.0.0",
+ "is-extendable": "^1.0.1"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/extend-shallow/node_modules/is-extendable": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz",
+ "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==",
+ "dev": true,
+ "dependencies": {
+ "is-plain-object": "^2.0.4"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/external-editor": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-3.1.0.tgz",
+ "integrity": "sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew==",
+ "dev": true,
+ "dependencies": {
+ "chardet": "^0.7.0",
+ "iconv-lite": "^0.4.24",
+ "tmp": "^0.0.33"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/extglob": {
+ "version": "2.0.4",
+ "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz",
+ "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==",
+ "dev": true,
+ "dependencies": {
+ "array-unique": "^0.3.2",
+ "define-property": "^1.0.0",
+ "expand-brackets": "^2.1.4",
+ "extend-shallow": "^2.0.1",
+ "fragment-cache": "^0.2.1",
+ "regex-not": "^1.0.0",
+ "snapdragon": "^0.8.1",
+ "to-regex": "^3.0.1"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/extglob/node_modules/define-property": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz",
+ "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=",
+ "dev": true,
+ "dependencies": {
+ "is-descriptor": "^1.0.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/extglob/node_modules/extend-shallow": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
+ "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
+ "dev": true,
+ "dependencies": {
+ "is-extendable": "^0.1.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/extglob/node_modules/is-accessor-descriptor": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz",
+ "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==",
+ "deprecated": "Please upgrade to v1.0.1",
+ "dev": true,
+ "dependencies": {
+ "kind-of": "^6.0.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/extglob/node_modules/is-data-descriptor": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz",
+ "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==",
+ "deprecated": "Please upgrade to v1.0.1",
+ "dev": true,
+ "dependencies": {
+ "kind-of": "^6.0.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/extglob/node_modules/is-descriptor": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz",
+ "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==",
+ "dev": true,
+ "dependencies": {
+ "is-accessor-descriptor": "^1.0.0",
+ "is-data-descriptor": "^1.0.0",
+ "kind-of": "^6.0.2"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/fast-deep-equal": {
+ "version": "3.1.3",
+ "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz",
+ "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==",
+ "dev": true
+ },
+ "node_modules/fast-diff": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/fast-diff/-/fast-diff-1.2.0.tgz",
+ "integrity": "sha512-xJuoT5+L99XlZ8twedaRf6Ax2TgQVxvgZOYoPKqZufmJib0tL2tegPBOZb1pVNgIhlqDlA0eO0c3wBvQcmzx4w==",
+ "dev": true
+ },
+ "node_modules/fast-glob": {
+ "version": "2.2.7",
+ "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-2.2.7.tgz",
+ "integrity": "sha512-g1KuQwHOZAmOZMuBtHdxDtju+T2RT8jgCC9aANsbpdiDDTSnjgfuVsIBNKbUeJI3oKMRExcfNDtJl4OhbffMsw==",
+ "dev": true,
+ "dependencies": {
+ "@mrmlnc/readdir-enhanced": "^2.2.1",
+ "@nodelib/fs.stat": "^1.1.2",
+ "glob-parent": "^3.1.0",
+ "is-glob": "^4.0.0",
+ "merge2": "^1.2.3",
+ "micromatch": "^3.1.10"
+ },
+ "engines": {
+ "node": ">=4.0.0"
+ }
+ },
+ "node_modules/fast-glob/node_modules/glob-parent": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz",
+ "integrity": "sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4=",
+ "dev": true,
+ "dependencies": {
+ "is-glob": "^3.1.0",
+ "path-dirname": "^1.0.0"
+ }
+ },
+ "node_modules/fast-glob/node_modules/glob-parent/node_modules/is-glob": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz",
+ "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=",
+ "dev": true,
+ "dependencies": {
+ "is-extglob": "^2.1.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/fast-json-stable-stringify": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz",
+ "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==",
+ "dev": true
+ },
+ "node_modules/fast-levenshtein": {
+ "version": "2.0.6",
+ "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz",
+ "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=",
+ "dev": true
+ },
+ "node_modules/fastest-levenshtein": {
+ "version": "1.0.16",
+ "resolved": "https://registry.npmjs.org/fastest-levenshtein/-/fastest-levenshtein-1.0.16.tgz",
+ "integrity": "sha512-eRnCtTTtGZFpQCwhJiUOuxPQWRXVKYDn0b2PeHfXL6/Zi53SLAzAHfVhVWK2AryC/WH05kGfxhFIPvTF0SXQzg==",
+ "dev": true,
+ "engines": {
+ "node": ">= 4.9.1"
+ }
+ },
+ "node_modules/figures": {
+ "version": "3.2.0",
+ "resolved": "https://registry.npmjs.org/figures/-/figures-3.2.0.tgz",
+ "integrity": "sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg==",
+ "dev": true,
+ "dependencies": {
+ "escape-string-regexp": "^1.0.5"
+ },
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/file-entry-cache": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-5.0.1.tgz",
+ "integrity": "sha512-bCg29ictuBaKUwwArK4ouCaqDgLZcysCFLmM/Yn/FDoqndh/9vNuQfXRDvTuXKLxfD/JtZQGKFT8MGcJBK644g==",
+ "dev": true,
+ "dependencies": {
+ "flat-cache": "^2.0.1"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/fill-range": {
+ "version": "7.0.1",
+ "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz",
+ "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==",
+ "dev": true,
+ "dependencies": {
+ "to-regex-range": "^5.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/find-cache-dir": {
+ "version": "3.3.2",
+ "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-3.3.2.tgz",
+ "integrity": "sha512-wXZV5emFEjrridIgED11OoUKLxiYjAcqot/NJdAkOhlJ+vGzwhOAfcG5OX1jP+S0PcjEn8bdMJv+g2jwQ3Onig==",
+ "dev": true,
+ "dependencies": {
+ "commondir": "^1.0.1",
+ "make-dir": "^3.0.2",
+ "pkg-dir": "^4.1.0"
+ },
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/avajs/find-cache-dir?sponsor=1"
+ }
+ },
+ "node_modules/find-up": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz",
+ "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==",
+ "dev": true,
+ "dependencies": {
+ "locate-path": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/flat": {
+ "version": "5.0.2",
+ "resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz",
+ "integrity": "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==",
+ "dev": true,
+ "bin": {
+ "flat": "cli.js"
+ }
+ },
+ "node_modules/flat-cache": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-2.0.1.tgz",
+ "integrity": "sha512-LoQe6yDuUMDzQAEH8sgmh4Md6oZnc/7PjtwjNFSzveXqSHt6ka9fPBuso7IGf9Rz4uqnSnWiFH2B/zj24a5ReA==",
+ "dev": true,
+ "dependencies": {
+ "flatted": "^2.0.0",
+ "rimraf": "2.6.3",
+ "write": "1.0.3"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/flat-cache/node_modules/rimraf": {
+ "version": "2.6.3",
+ "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.3.tgz",
+ "integrity": "sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA==",
+ "deprecated": "Rimraf versions prior to v4 are no longer supported",
+ "dev": true,
+ "dependencies": {
+ "glob": "^7.1.3"
+ },
+ "bin": {
+ "rimraf": "bin.js"
+ }
+ },
+ "node_modules/flatted": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/flatted/-/flatted-2.0.2.tgz",
+ "integrity": "sha512-r5wGx7YeOwNWNlCA0wQ86zKyDLMQr+/RB8xy74M4hTphfmjlijTSSXGuH8rnvKZnfT9i+75zmd8jcKdMR4O6jA==",
+ "dev": true
+ },
+ "node_modules/for-in": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz",
+ "integrity": "sha1-gQaNKVqBQuwKxybG4iAMMPttXoA=",
+ "dev": true,
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/foreachasync": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/foreachasync/-/foreachasync-3.0.0.tgz",
+ "integrity": "sha1-VQKYfchxS+M5IJfzLgBxyd7gfPY="
+ },
+ "node_modules/fragment-cache": {
+ "version": "0.2.1",
+ "resolved": "https://registry.npmjs.org/fragment-cache/-/fragment-cache-0.2.1.tgz",
+ "integrity": "sha1-QpD60n8T6Jvn8zeZxrxaCr//DRk=",
+ "dev": true,
+ "dependencies": {
+ "map-cache": "^0.2.2"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/fs.realpath": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
+ "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=",
+ "dev": true
+ },
+ "node_modules/fsevents": {
+ "version": "2.3.2",
+ "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz",
+ "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==",
+ "dev": true,
+ "hasInstallScript": true,
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": "^8.16.0 || ^10.6.0 || >=11.0.0"
+ }
+ },
+ "node_modules/function-bind": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz",
+ "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==",
+ "dev": true
+ },
+ "node_modules/functional-red-black-tree": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz",
+ "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=",
+ "dev": true
+ },
+ "node_modules/gensync": {
+ "version": "1.0.0-beta.2",
+ "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz",
+ "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==",
+ "dev": true,
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/get-caller-file": {
+ "version": "2.0.5",
+ "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz",
+ "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==",
+ "dev": true,
+ "engines": {
+ "node": "6.* || 8.* || >= 10.*"
+ }
+ },
+ "node_modules/get-intrinsic": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.0.1.tgz",
+ "integrity": "sha512-ZnWP+AmS1VUaLgTRy47+zKtjTxz+0xMpx3I52i+aalBK1QP19ggLF3Db89KJX7kjfOfP2eoa01qc++GwPgufPg==",
+ "dev": true,
+ "dependencies": {
+ "function-bind": "^1.1.1",
+ "has": "^1.0.3",
+ "has-symbols": "^1.0.1"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/get-set-props": {
+ "version": "0.1.0",
+ "resolved": "https://registry.npmjs.org/get-set-props/-/get-set-props-0.1.0.tgz",
+ "integrity": "sha1-mYR1wXhEVobQsyJG2l3428++jqM=",
+ "dev": true,
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/get-stdin": {
+ "version": "7.0.0",
+ "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-7.0.0.tgz",
+ "integrity": "sha512-zRKcywvrXlXsA0v0i9Io4KDRaAw7+a1ZpjRwl9Wox8PFlVCCHra7E9c4kqXCoCM9nR5tBkaTTZRBoCm60bFqTQ==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/get-stream": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz",
+ "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==",
+ "dev": true,
+ "dependencies": {
+ "pump": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/get-value": {
+ "version": "2.0.6",
+ "resolved": "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz",
+ "integrity": "sha1-3BXKHGcjh8p2vTesCjlbogQqLCg=",
+ "dev": true,
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/glob": {
+ "version": "7.2.0",
+ "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz",
+ "integrity": "sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==",
+ "deprecated": "Glob versions prior to v9 are no longer supported",
+ "dev": true,
+ "dependencies": {
+ "fs.realpath": "^1.0.0",
+ "inflight": "^1.0.4",
+ "inherits": "2",
+ "minimatch": "^3.0.4",
+ "once": "^1.3.0",
+ "path-is-absolute": "^1.0.0"
+ },
+ "engines": {
+ "node": "*"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
+ "node_modules/glob-parent": {
+ "version": "5.1.2",
+ "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz",
+ "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==",
+ "dev": true,
+ "dependencies": {
+ "is-glob": "^4.0.1"
+ },
+ "engines": {
+ "node": ">= 6"
+ }
+ },
+ "node_modules/glob-to-regexp": {
+ "version": "0.3.0",
+ "resolved": "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.3.0.tgz",
+ "integrity": "sha1-jFoUlNIGbFcMw7/kSWF1rMTVAqs=",
+ "dev": true
+ },
+ "node_modules/global-dirs": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/global-dirs/-/global-dirs-2.0.1.tgz",
+ "integrity": "sha512-5HqUqdhkEovj2Of/ms3IeS/EekcO54ytHRLV4PEY2rhRwrHXLQjeVEES0Lhka0xwNDtGYn58wyC4s5+MHsOO6A==",
+ "dev": true,
+ "dependencies": {
+ "ini": "^1.3.5"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/globals": {
+ "version": "11.12.0",
+ "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz",
+ "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==",
+ "dev": true,
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/globby": {
+ "version": "9.2.0",
+ "resolved": "https://registry.npmjs.org/globby/-/globby-9.2.0.tgz",
+ "integrity": "sha512-ollPHROa5mcxDEkwg6bPt3QbEf4pDQSNtd6JPL1YvOvAo/7/0VAm9TccUeoTmarjPw4pfUthSCqcyfNB1I3ZSg==",
+ "dev": true,
+ "dependencies": {
+ "@types/glob": "^7.1.1",
+ "array-union": "^1.0.2",
+ "dir-glob": "^2.2.2",
+ "fast-glob": "^2.2.6",
+ "glob": "^7.1.3",
+ "ignore": "^4.0.3",
+ "pify": "^4.0.1",
+ "slash": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/globby/node_modules/slash": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/slash/-/slash-2.0.0.tgz",
+ "integrity": "sha512-ZYKh3Wh2z1PpEXWr0MpSBZ0V6mZHAQfYevttO11c51CaWjGTaadiKZ+wVt1PbMlDV5qhMFslpZCemhwOK7C89A==",
+ "dev": true,
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/got": {
+ "version": "9.6.0",
+ "resolved": "https://registry.npmjs.org/got/-/got-9.6.0.tgz",
+ "integrity": "sha512-R7eWptXuGYxwijs0eV+v3o6+XH1IqVK8dJOEecQfTmkncw9AV4dcw/Dhxi8MdlqPthxxpZyizMzyg8RTmEsG+Q==",
+ "dev": true,
+ "dependencies": {
+ "@sindresorhus/is": "^0.14.0",
+ "@szmarczak/http-timer": "^1.1.2",
+ "cacheable-request": "^6.0.0",
+ "decompress-response": "^3.3.0",
+ "duplexer3": "^0.1.4",
+ "get-stream": "^4.1.0",
+ "lowercase-keys": "^1.0.1",
+ "mimic-response": "^1.0.1",
+ "p-cancelable": "^1.0.0",
+ "to-readable-stream": "^1.0.0",
+ "url-parse-lax": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=8.6"
+ }
+ },
+ "node_modules/graceful-fs": {
+ "version": "4.2.10",
+ "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.10.tgz",
+ "integrity": "sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==",
+ "dev": true
+ },
+ "node_modules/growl": {
+ "version": "1.10.5",
+ "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.5.tgz",
+ "integrity": "sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA==",
+ "dev": true,
+ "engines": {
+ "node": ">=4.x"
+ }
+ },
+ "node_modules/has": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz",
+ "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==",
+ "dev": true,
+ "dependencies": {
+ "function-bind": "^1.1.1"
+ },
+ "engines": {
+ "node": ">= 0.4.0"
+ }
+ },
+ "node_modules/has-flag": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
+ "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=",
+ "dev": true,
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/has-symbols": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.1.tgz",
+ "integrity": "sha512-PLcsoqu++dmEIZB+6totNFKq/7Do+Z0u4oT0zKOJNl3lYK6vGwwu2hjHs+68OEZbTjiUE9bgOABXbP/GvrS0Kg==",
+ "dev": true,
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/has-value": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/has-value/-/has-value-1.0.0.tgz",
+ "integrity": "sha1-GLKB2lhbHFxR3vJMkw7SmgvmsXc=",
+ "dev": true,
+ "dependencies": {
+ "get-value": "^2.0.6",
+ "has-values": "^1.0.0",
+ "isobject": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/has-values": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/has-values/-/has-values-1.0.0.tgz",
+ "integrity": "sha1-lbC2P+whRmGab+V/51Yo1aOe/k8=",
+ "dev": true,
+ "dependencies": {
+ "is-number": "^3.0.0",
+ "kind-of": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/has-values/node_modules/is-buffer": {
+ "version": "1.1.6",
+ "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz",
+ "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==",
+ "dev": true
+ },
+ "node_modules/has-values/node_modules/is-number": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz",
+ "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=",
+ "dev": true,
+ "dependencies": {
+ "kind-of": "^3.0.2"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/has-values/node_modules/is-number/node_modules/kind-of": {
+ "version": "3.2.2",
+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
+ "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
+ "dev": true,
+ "dependencies": {
+ "is-buffer": "^1.1.5"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/has-values/node_modules/kind-of": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz",
+ "integrity": "sha1-IIE989cSkosgc3hpGkUGb65y3Vc=",
+ "dev": true,
+ "dependencies": {
+ "is-buffer": "^1.1.5"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/has-yarn": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/has-yarn/-/has-yarn-2.1.0.tgz",
+ "integrity": "sha512-UqBRqi4ju7T+TqGNdqAO0PaSVGsDGJUBQvk9eUWNGRY1CFGDzYhLWoM7JQEemnlvVcv/YEmc2wNW8BC24EnUsw==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/he": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz",
+ "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==",
+ "dev": true,
+ "bin": {
+ "he": "bin/he"
+ }
+ },
+ "node_modules/hosted-git-info": {
+ "version": "2.8.9",
+ "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz",
+ "integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==",
+ "dev": true
+ },
+ "node_modules/http-cache-semantics": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.1.tgz",
+ "integrity": "sha512-er295DKPVsV82j5kw1Gjt+ADA/XYHsajl82cGNQG2eyoPkvgUhX+nDIyelzhIWbbsXP39EHcI6l5tYs2FYqYXQ==",
+ "dev": true
+ },
+ "node_modules/iconv-lite": {
+ "version": "0.4.24",
+ "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz",
+ "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==",
+ "dev": true,
+ "dependencies": {
+ "safer-buffer": ">= 2.1.2 < 3"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/ignore": {
+ "version": "4.0.6",
+ "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz",
+ "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==",
+ "dev": true,
+ "engines": {
+ "node": ">= 4"
+ }
+ },
+ "node_modules/import-fresh": {
+ "version": "3.2.2",
+ "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.2.2.tgz",
+ "integrity": "sha512-cTPNrlvJT6twpYy+YmKUKrTSjWFs3bjYjAhCwm+z4EOCubZxAuO+hHpRN64TqjEaYSHs7tJAE0w1CKMGmsG/lw==",
+ "dev": true,
+ "dependencies": {
+ "parent-module": "^1.0.0",
+ "resolve-from": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/import-fresh/node_modules/resolve-from": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz",
+ "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==",
+ "dev": true,
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/import-lazy": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/import-lazy/-/import-lazy-2.1.0.tgz",
+ "integrity": "sha1-BWmOPUXIjo1+nZLLBYTnfwlvPkM=",
+ "dev": true,
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/import-local": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.1.0.tgz",
+ "integrity": "sha512-ASB07uLtnDs1o6EHjKpX34BKYDSqnFerfTOJL2HvMqF70LnxpjkzDB8J44oT9pu4AMPkQwf8jl6szgvNd2tRIg==",
+ "dev": true,
+ "dependencies": {
+ "pkg-dir": "^4.2.0",
+ "resolve-cwd": "^3.0.0"
+ },
+ "bin": {
+ "import-local-fixture": "fixtures/cli.js"
+ },
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/import-modules": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/import-modules/-/import-modules-2.0.0.tgz",
+ "integrity": "sha512-iczM/v9drffdNnABOKwj0f9G3cFDon99VcG1mxeBsdqnbd+vnQ5c2uAiCHNQITqFTOPaEvwg3VjoWCur0uHLEw==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/imurmurhash": {
+ "version": "0.1.4",
+ "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz",
+ "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=",
+ "dev": true,
+ "engines": {
+ "node": ">=0.8.19"
+ }
+ },
+ "node_modules/inflight": {
+ "version": "1.0.6",
+ "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
+ "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=",
+ "deprecated": "This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.",
+ "dev": true,
+ "dependencies": {
+ "once": "^1.3.0",
+ "wrappy": "1"
+ }
+ },
+ "node_modules/inherits": {
+ "version": "2.0.4",
+ "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
+ "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==",
+ "dev": true
+ },
+ "node_modules/ini": {
+ "version": "1.3.8",
+ "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz",
+ "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==",
+ "dev": true
+ },
+ "node_modules/inquirer": {
+ "version": "7.3.3",
+ "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-7.3.3.tgz",
+ "integrity": "sha512-JG3eIAj5V9CwcGvuOmoo6LB9kbAYT8HXffUl6memuszlwDC/qvFAJw49XJ5NROSFNPxp3iQg1GqkFhaY/CR0IA==",
+ "dev": true,
+ "dependencies": {
+ "ansi-escapes": "^4.2.1",
+ "chalk": "^4.1.0",
+ "cli-cursor": "^3.1.0",
+ "cli-width": "^3.0.0",
+ "external-editor": "^3.0.3",
+ "figures": "^3.0.0",
+ "lodash": "^4.17.19",
+ "mute-stream": "0.0.8",
+ "run-async": "^2.4.0",
+ "rxjs": "^6.6.0",
+ "string-width": "^4.1.0",
+ "strip-ansi": "^6.0.0",
+ "through": "^2.3.6"
+ },
+ "engines": {
+ "node": ">=8.0.0"
+ }
+ },
+ "node_modules/inquirer/node_modules/ansi-styles": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
+ "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
+ "dev": true,
+ "dependencies": {
+ "color-convert": "^2.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/ansi-styles?sponsor=1"
+ }
+ },
+ "node_modules/inquirer/node_modules/chalk": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz",
+ "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==",
+ "dev": true,
+ "dependencies": {
+ "ansi-styles": "^4.1.0",
+ "supports-color": "^7.1.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/chalk?sponsor=1"
+ }
+ },
+ "node_modules/inquirer/node_modules/color-convert": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
+ "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
+ "dev": true,
+ "dependencies": {
+ "color-name": "~1.1.4"
+ },
+ "engines": {
+ "node": ">=7.0.0"
+ }
+ },
+ "node_modules/inquirer/node_modules/color-name": {
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
+ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
+ "dev": true
+ },
+ "node_modules/inquirer/node_modules/has-flag": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
+ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/inquirer/node_modules/supports-color": {
+ "version": "7.2.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
+ "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
+ "dev": true,
+ "dependencies": {
+ "has-flag": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/interpret": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/interpret/-/interpret-3.1.1.tgz",
+ "integrity": "sha512-6xwYfHbajpoF0xLW+iwLkhwgvLoZDfjYfoFNu8ftMoXINzwuymNLd9u/KmwtdT2GbR+/Cz66otEGEVVUHX9QLQ==",
+ "dev": true,
+ "engines": {
+ "node": ">=10.13.0"
+ }
+ },
+ "node_modules/irregular-plurals": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/irregular-plurals/-/irregular-plurals-2.0.0.tgz",
+ "integrity": "sha512-Y75zBYLkh0lJ9qxeHlMjQ7bSbyiSqNW/UOPWDmzC7cXskL1hekSITh1Oc6JV0XCWWZ9DE8VYSB71xocLk3gmGw==",
+ "dev": true,
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/is-accessor-descriptor": {
+ "version": "0.1.6",
+ "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz",
+ "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=",
+ "deprecated": "Please upgrade to v0.1.7",
+ "dev": true,
+ "dependencies": {
+ "kind-of": "^3.0.2"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/is-accessor-descriptor/node_modules/is-buffer": {
+ "version": "1.1.6",
+ "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz",
+ "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==",
+ "dev": true
+ },
+ "node_modules/is-accessor-descriptor/node_modules/kind-of": {
+ "version": "3.2.2",
+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
+ "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
+ "dev": true,
+ "dependencies": {
+ "is-buffer": "^1.1.5"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/is-arrayish": {
+ "version": "0.2.1",
+ "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz",
+ "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=",
+ "dev": true
+ },
+ "node_modules/is-binary-path": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz",
+ "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==",
+ "dev": true,
+ "dependencies": {
+ "binary-extensions": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/is-callable": {
+ "version": "1.2.2",
+ "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.2.tgz",
+ "integrity": "sha512-dnMqspv5nU3LoewK2N/y7KLtxtakvTuaCsU9FU50/QDmdbHNy/4/JuRtMHqRU22o3q+W89YQndQEeCVwK+3qrA==",
+ "dev": true,
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-ci": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-2.0.0.tgz",
+ "integrity": "sha512-YfJT7rkpQB0updsdHLGWrvhBJfcfzNNawYDNIyQXJz0IViGf75O8EBPKSdvw2rF+LGCsX4FZ8tcr3b19LcZq4w==",
+ "dev": true,
+ "dependencies": {
+ "ci-info": "^2.0.0"
+ },
+ "bin": {
+ "is-ci": "bin.js"
+ }
+ },
+ "node_modules/is-core-module": {
+ "version": "2.11.0",
+ "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.11.0.tgz",
+ "integrity": "sha512-RRjxlvLDkD1YJwDbroBHMb+cukurkDWNyHx7D3oNB5x9rb5ogcksMC5wHCadcXoo67gVr/+3GFySh3134zi6rw==",
+ "dev": true,
+ "dependencies": {
+ "has": "^1.0.3"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-data-descriptor": {
+ "version": "0.1.4",
+ "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz",
+ "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=",
+ "deprecated": "Please upgrade to v0.1.5",
+ "dev": true,
+ "dependencies": {
+ "kind-of": "^3.0.2"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/is-data-descriptor/node_modules/is-buffer": {
+ "version": "1.1.6",
+ "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz",
+ "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==",
+ "dev": true
+ },
+ "node_modules/is-data-descriptor/node_modules/kind-of": {
+ "version": "3.2.2",
+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
+ "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
+ "dev": true,
+ "dependencies": {
+ "is-buffer": "^1.1.5"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/is-date-object": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.2.tgz",
+ "integrity": "sha512-USlDT524woQ08aoZFzh3/Z6ch9Y/EWXEHQ/AaRN0SkKq4t2Jw2R2339tSXmwuVoY7LLlBCbOIlx2myP/L5zk0g==",
+ "dev": true,
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-descriptor": {
+ "version": "0.1.6",
+ "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz",
+ "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==",
+ "dev": true,
+ "dependencies": {
+ "is-accessor-descriptor": "^0.1.6",
+ "is-data-descriptor": "^0.1.4",
+ "kind-of": "^5.0.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/is-descriptor/node_modules/kind-of": {
+ "version": "5.1.0",
+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz",
+ "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==",
+ "dev": true,
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/is-error": {
+ "version": "2.2.2",
+ "resolved": "https://registry.npmjs.org/is-error/-/is-error-2.2.2.tgz",
+ "integrity": "sha512-IOQqts/aHWbiisY5DuPJQ0gcbvaLFCa7fBa9xoLfxBZvQ+ZI/Zh9xoI7Gk+G64N0FdK4AbibytHht2tWgpJWLg==",
+ "dev": true
+ },
+ "node_modules/is-extendable": {
+ "version": "0.1.1",
+ "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz",
+ "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=",
+ "dev": true,
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/is-extglob": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
+ "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=",
+ "dev": true,
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/is-fullwidth-code-point": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz",
+ "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=",
+ "dev": true,
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/is-get-set-prop": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/is-get-set-prop/-/is-get-set-prop-1.0.0.tgz",
+ "integrity": "sha1-JzGHfk14pqae3M5rudaLB3nnYxI=",
+ "dev": true,
+ "dependencies": {
+ "get-set-props": "^0.1.0",
+ "lowercase-keys": "^1.0.0"
+ }
+ },
+ "node_modules/is-glob": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz",
+ "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==",
+ "dev": true,
+ "dependencies": {
+ "is-extglob": "^2.1.1"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/is-installed-globally": {
+ "version": "0.3.2",
+ "resolved": "https://registry.npmjs.org/is-installed-globally/-/is-installed-globally-0.3.2.tgz",
+ "integrity": "sha512-wZ8x1js7Ia0kecP/CHM/3ABkAmujX7WPvQk6uu3Fly/Mk44pySulQpnHG46OMjHGXApINnV4QhY3SWnECO2z5g==",
+ "dev": true,
+ "dependencies": {
+ "global-dirs": "^2.0.1",
+ "is-path-inside": "^3.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/is-js-type": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/is-js-type/-/is-js-type-2.0.0.tgz",
+ "integrity": "sha1-c2FwBtZZtOtHKbunR9KHgt8PfiI=",
+ "dev": true,
+ "dependencies": {
+ "js-types": "^1.0.0"
+ }
+ },
+ "node_modules/is-negative-zero": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.0.tgz",
+ "integrity": "sha1-lVOxIbD6wohp2p7UWeIMdUN4hGE=",
+ "dev": true,
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/is-npm": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/is-npm/-/is-npm-4.0.0.tgz",
+ "integrity": "sha512-96ECIfh9xtDDlPylNPXhzjsykHsMJZ18ASpaWzQyBr4YRTcVjUvzaHayDAES2oU/3KpljhHUjtSRNiDwi0F0ig==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/is-number": {
+ "version": "7.0.0",
+ "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz",
+ "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==",
+ "dev": true,
+ "engines": {
+ "node": ">=0.12.0"
+ }
+ },
+ "node_modules/is-obj": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-2.0.0.tgz",
+ "integrity": "sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/is-obj-prop": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/is-obj-prop/-/is-obj-prop-1.0.0.tgz",
+ "integrity": "sha1-s03nnEULjXxzqyzfZ9yHWtuF+A4=",
+ "dev": true,
+ "dependencies": {
+ "lowercase-keys": "^1.0.0",
+ "obj-props": "^1.0.0"
+ }
+ },
+ "node_modules/is-path-inside": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.2.tgz",
+ "integrity": "sha512-/2UGPSgmtqwo1ktx8NDHjuPwZWmHhO+gj0f93EkhLB5RgW9RZevWYYlIkS6zePc6U2WpOdQYIwHe9YC4DWEBVg==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/is-plain-obj": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-1.1.0.tgz",
+ "integrity": "sha1-caUMhCnfync8kqOQpKA7OfzVHT4=",
+ "dev": true,
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/is-plain-object": {
+ "version": "2.0.4",
+ "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz",
+ "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==",
+ "dev": true,
+ "dependencies": {
+ "isobject": "^3.0.1"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/is-proto-prop": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/is-proto-prop/-/is-proto-prop-2.0.0.tgz",
+ "integrity": "sha512-jl3NbQ/fGLv5Jhan4uX+Ge9ohnemqyblWVVCpAvtTQzNFvV2xhJq+esnkIbYQ9F1nITXoLfDDQLp7LBw/zzncg==",
+ "dev": true,
+ "dependencies": {
+ "lowercase-keys": "^1.0.0",
+ "proto-props": "^2.0.0"
+ }
+ },
+ "node_modules/is-regex": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.1.tgz",
+ "integrity": "sha512-1+QkEcxiLlB7VEyFtyBg94e08OAsvq7FUBgApTq/w2ymCLyKJgDPsybBENVtA7XCQEgEXxKPonG+mvYRxh/LIg==",
+ "dev": true,
+ "dependencies": {
+ "has-symbols": "^1.0.1"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-string": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.5.tgz",
+ "integrity": "sha512-buY6VNRjhQMiF1qWDouloZlQbRhDPCebwxSjxMjxgemYT46YMd2NR0/H+fBhEfWX4A/w9TBJ+ol+okqJKFE6vQ==",
+ "dev": true,
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-symbol": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.3.tgz",
+ "integrity": "sha512-OwijhaRSgqvhm/0ZdAcXNZt9lYdKFpcRDT5ULUuYXPoT794UNOdU+gpT6Rzo7b4V2HUl/op6GqY894AZwv9faQ==",
+ "dev": true,
+ "dependencies": {
+ "has-symbols": "^1.0.1"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-typedarray": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz",
+ "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=",
+ "dev": true
+ },
+ "node_modules/is-unicode-supported": {
+ "version": "0.1.0",
+ "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz",
+ "integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==",
+ "dev": true,
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/is-windows": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz",
+ "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==",
+ "dev": true,
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/is-wsl": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-1.1.0.tgz",
+ "integrity": "sha1-HxbkqiKwTRM2tmGIpmrzxgDDpm0=",
+ "dev": true,
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/is-yarn-global": {
+ "version": "0.3.0",
+ "resolved": "https://registry.npmjs.org/is-yarn-global/-/is-yarn-global-0.3.0.tgz",
+ "integrity": "sha512-VjSeb/lHmkoyd8ryPVIKvOCn4D1koMqY+vqyjjUfc3xyKtP4dYOxM44sZrnqQSzSds3xyOrUTLTC9LVCVgLngw==",
+ "dev": true
+ },
+ "node_modules/isarray": {
+ "version": "0.0.1",
+ "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz",
+ "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=",
+ "dev": true
+ },
+ "node_modules/isexe": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
+ "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=",
+ "dev": true
+ },
+ "node_modules/isobject": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz",
+ "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=",
+ "dev": true,
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/jest-worker": {
+ "version": "27.5.1",
+ "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-27.5.1.tgz",
+ "integrity": "sha512-7vuh85V5cdDofPyxn58nrPjBktZo0u9x1g8WtjQol+jZDaE+fhN+cIvTj11GndBnMnyfrUOG1sZQxCdjKh+DKg==",
+ "dev": true,
+ "dependencies": {
+ "@types/node": "*",
+ "merge-stream": "^2.0.0",
+ "supports-color": "^8.0.0"
+ },
+ "engines": {
+ "node": ">= 10.13.0"
+ }
+ },
+ "node_modules/jest-worker/node_modules/has-flag": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
+ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/jest-worker/node_modules/supports-color": {
+ "version": "8.1.1",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz",
+ "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==",
+ "dev": true,
+ "dependencies": {
+ "has-flag": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/supports-color?sponsor=1"
+ }
+ },
+ "node_modules/js-tokens": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
+ "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==",
+ "dev": true
+ },
+ "node_modules/js-types": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/js-types/-/js-types-1.0.0.tgz",
+ "integrity": "sha1-0kLmSU7Vcq08koCfyL7X92h8vwM=",
+ "dev": true,
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/js-yaml": {
+ "version": "3.13.1",
+ "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz",
+ "integrity": "sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==",
+ "dev": true,
+ "dependencies": {
+ "argparse": "^1.0.7",
+ "esprima": "^4.0.0"
+ },
+ "bin": {
+ "js-yaml": "bin/js-yaml.js"
+ }
+ },
+ "node_modules/jsesc": {
+ "version": "2.5.2",
+ "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz",
+ "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==",
+ "dev": true,
+ "bin": {
+ "jsesc": "bin/jsesc"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/json-buffer": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.0.tgz",
+ "integrity": "sha1-Wx85evx11ne96Lz8Dkfh+aPZqJg=",
+ "dev": true
+ },
+ "node_modules/json-parse-better-errors": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz",
+ "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==",
+ "dev": true
+ },
+ "node_modules/json-parse-even-better-errors": {
+ "version": "2.3.1",
+ "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz",
+ "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==",
+ "dev": true
+ },
+ "node_modules/json-schema-traverse": {
+ "version": "0.4.1",
+ "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz",
+ "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==",
+ "dev": true
+ },
+ "node_modules/json-stable-stringify-without-jsonify": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz",
+ "integrity": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=",
+ "dev": true
+ },
+ "node_modules/json5": {
+ "version": "2.2.3",
+ "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz",
+ "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==",
+ "dev": true,
+ "bin": {
+ "json5": "lib/cli.js"
+ },
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/just-extend": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/just-extend/-/just-extend-4.1.1.tgz",
+ "integrity": "sha512-aWgeGFW67BP3e5181Ep1Fv2v8z//iBJfrvyTnq8wG86vEESwmonn1zPBJ0VfmT9CJq2FIT0VsETtrNFm2a+SHA==",
+ "dev": true
+ },
+ "node_modules/keyv": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/keyv/-/keyv-3.1.0.tgz",
+ "integrity": "sha512-9ykJ/46SN/9KPM/sichzQ7OvXyGDYKGTaDlKMGCAlg2UK8KRy4jb0d8sFc+0Tt0YYnThq8X2RZgCg74RPxgcVA==",
+ "dev": true,
+ "dependencies": {
+ "json-buffer": "3.0.0"
+ }
+ },
+ "node_modules/kind-of": {
+ "version": "6.0.3",
+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz",
+ "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==",
+ "dev": true,
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/latest-version": {
+ "version": "5.1.0",
+ "resolved": "https://registry.npmjs.org/latest-version/-/latest-version-5.1.0.tgz",
+ "integrity": "sha512-weT+r0kTkRQdCdYCNtkMwWXQTMEswKrFBkm4ckQOMVhhqhIMI1UT2hMj+1iigIhgSZm5gTmrRXBNoGUgaTY1xA==",
+ "dev": true,
+ "dependencies": {
+ "package-json": "^6.3.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/levn": {
+ "version": "0.3.0",
+ "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz",
+ "integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=",
+ "dev": true,
+ "dependencies": {
+ "prelude-ls": "~1.1.2",
+ "type-check": "~0.3.2"
+ },
+ "engines": {
+ "node": ">= 0.8.0"
+ }
+ },
+ "node_modules/line-column-path": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/line-column-path/-/line-column-path-2.0.0.tgz",
+ "integrity": "sha512-nz3A+vi4bElhwd62E9+Qk/f9BDYLSzD/4Hy1rir0I4GnMxSTezSymzANyph5N1PgRZ3sSbA+yR5hOuXxc71a0Q==",
+ "dev": true,
+ "dependencies": {
+ "type-fest": "^0.4.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/line-column-path/node_modules/type-fest": {
+ "version": "0.4.1",
+ "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.4.1.tgz",
+ "integrity": "sha512-IwzA/LSfD2vC1/YDYMv/zHP4rDF1usCwllsDpbolT3D4fUepIO7f9K70jjmUewU/LmGUKJcwcVtDCpnKk4BPMw==",
+ "dev": true,
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/lines-and-columns": {
+ "version": "1.1.6",
+ "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.1.6.tgz",
+ "integrity": "sha1-HADHQ7QzzQpOgHWPe2SldEDZ/wA=",
+ "dev": true
+ },
+ "node_modules/load-json-file": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-2.0.0.tgz",
+ "integrity": "sha1-eUfkIUmvgNaWy/eXvKq8/h/inKg=",
+ "dev": true,
+ "dependencies": {
+ "graceful-fs": "^4.1.2",
+ "parse-json": "^2.2.0",
+ "pify": "^2.0.0",
+ "strip-bom": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/load-json-file/node_modules/pify": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz",
+ "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=",
+ "dev": true,
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/loader-runner": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-4.3.0.tgz",
+ "integrity": "sha512-3R/1M+yS3j5ou80Me59j7F9IMs4PXs3VqRrm0TU3AbKPxlmpoY1TNscJV/oGJXo8qCatFGTfDbY6W6ipGOYXfg==",
+ "dev": true,
+ "engines": {
+ "node": ">=6.11.5"
+ }
+ },
+ "node_modules/loader-utils": {
+ "version": "2.0.4",
+ "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.4.tgz",
+ "integrity": "sha512-xXqpXoINfFhgua9xiqD8fPFHgkoq1mmmpE92WlDbm9rNRd/EbRb+Gqf908T2DMfuHjjJlksiK2RbHVOdD/MqSw==",
+ "dev": true,
+ "dependencies": {
+ "big.js": "^5.2.2",
+ "emojis-list": "^3.0.0",
+ "json5": "^2.1.2"
+ },
+ "engines": {
+ "node": ">=8.9.0"
+ }
+ },
+ "node_modules/locate-path": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz",
+ "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==",
+ "dev": true,
+ "dependencies": {
+ "p-locate": "^3.0.0",
+ "path-exists": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/locutus": {
+ "version": "2.0.15",
+ "resolved": "https://registry.npmjs.org/locutus/-/locutus-2.0.15.tgz",
+ "integrity": "sha512-2xWC4RkoAoCVXEb/stzEgG1TNgd+mrkLBj6TuEDNyUoKeQ2XzDTyJUC23sMiqbL6zJmJSP3w59OZo+zc4IBOmA==",
+ "engines": {
+ "node": ">= 10"
+ }
+ },
+ "node_modules/lodash": {
+ "version": "4.17.21",
+ "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz",
+ "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==",
+ "dev": true
+ },
+ "node_modules/lodash.camelcase": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz",
+ "integrity": "sha1-soqmKIorn8ZRA1x3EfZathkDMaY=",
+ "dev": true
+ },
+ "node_modules/lodash.defaultsdeep": {
+ "version": "4.6.1",
+ "resolved": "https://registry.npmjs.org/lodash.defaultsdeep/-/lodash.defaultsdeep-4.6.1.tgz",
+ "integrity": "sha512-3j8wdDzYuWO3lM3Reg03MuQR957t287Rpcxp1njpEa8oDrikb+FwGdW3n+FELh/A6qib6yPit0j/pv9G/yeAqA==",
+ "dev": true
+ },
+ "node_modules/lodash.get": {
+ "version": "4.4.2",
+ "resolved": "https://registry.npmjs.org/lodash.get/-/lodash.get-4.4.2.tgz",
+ "integrity": "sha1-LRd/ZS+jHpObRDjVNBSZ36OCXpk=",
+ "deprecated": "This package is deprecated. Use the optional chaining (?.) operator instead.",
+ "dev": true
+ },
+ "node_modules/lodash.kebabcase": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/lodash.kebabcase/-/lodash.kebabcase-4.1.1.tgz",
+ "integrity": "sha1-hImxyw0p/4gZXM7KRI/21swpXDY=",
+ "dev": true
+ },
+ "node_modules/lodash.snakecase": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/lodash.snakecase/-/lodash.snakecase-4.1.1.tgz",
+ "integrity": "sha1-OdcUo1NXFHg3rv1ktdy7Fr7Nj40=",
+ "dev": true
+ },
+ "node_modules/lodash.upperfirst": {
+ "version": "4.3.1",
+ "resolved": "https://registry.npmjs.org/lodash.upperfirst/-/lodash.upperfirst-4.3.1.tgz",
+ "integrity": "sha1-E2Xt9DFIBIHvDRxolXpe2Z1J984=",
+ "dev": true
+ },
+ "node_modules/lodash.zip": {
+ "version": "4.2.0",
+ "resolved": "https://registry.npmjs.org/lodash.zip/-/lodash.zip-4.2.0.tgz",
+ "integrity": "sha1-7GZi5IlkCO1KtsVCo5kLcswIACA=",
+ "dev": true
+ },
+ "node_modules/log-symbols": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-3.0.0.tgz",
+ "integrity": "sha512-dSkNGuI7iG3mfvDzUuYZyvk5dD9ocYCYzNU6CYDE6+Xqd+gwme6Z00NS3dUh8mq/73HaEtT7m6W+yUPtU6BZnQ==",
+ "dev": true,
+ "dependencies": {
+ "chalk": "^2.4.2"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/loud-rejection": {
+ "version": "1.6.0",
+ "resolved": "https://registry.npmjs.org/loud-rejection/-/loud-rejection-1.6.0.tgz",
+ "integrity": "sha1-W0b4AUft7leIcPCG0Eghz5mOVR8=",
+ "dev": true,
+ "dependencies": {
+ "currently-unhandled": "^0.4.1",
+ "signal-exit": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/lowercase-keys": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-1.0.1.tgz",
+ "integrity": "sha512-G2Lj61tXDnVFFOi8VZds+SoQjtQC3dgokKdDG2mTm1tx4m50NUHBOZSBwQQHyy0V12A0JTG4icfZQH+xPyh8VA==",
+ "dev": true,
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/make-dir": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz",
+ "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==",
+ "dev": true,
+ "dependencies": {
+ "semver": "^6.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/make-dir/node_modules/semver": {
+ "version": "6.3.0",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
+ "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
+ "dev": true,
+ "bin": {
+ "semver": "bin/semver.js"
+ }
+ },
+ "node_modules/map-cache": {
+ "version": "0.2.2",
+ "resolved": "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz",
+ "integrity": "sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8=",
+ "dev": true,
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/map-obj": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-2.0.0.tgz",
+ "integrity": "sha1-plzSkIepJZi4eRJXpSPgISIqwfk=",
+ "dev": true,
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/map-visit": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/map-visit/-/map-visit-1.0.0.tgz",
+ "integrity": "sha1-7Nyo8TFE5mDxtb1B8S80edmN+48=",
+ "dev": true,
+ "dependencies": {
+ "object-visit": "^1.0.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/meow": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/meow/-/meow-5.0.0.tgz",
+ "integrity": "sha512-CbTqYU17ABaLefO8vCU153ZZlprKYWDljcndKKDCFcYQITzWCXZAVk4QMFZPgvzrnUQ3uItnIE/LoUOwrT15Ig==",
+ "dev": true,
+ "dependencies": {
+ "camelcase-keys": "^4.0.0",
+ "decamelize-keys": "^1.0.0",
+ "loud-rejection": "^1.0.0",
+ "minimist-options": "^3.0.1",
+ "normalize-package-data": "^2.3.4",
+ "read-pkg-up": "^3.0.0",
+ "redent": "^2.0.0",
+ "trim-newlines": "^2.0.0",
+ "yargs-parser": "^10.0.0"
+ },
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/meow/node_modules/camelcase": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-4.1.0.tgz",
+ "integrity": "sha1-1UVjW+HjPFQmScaRc+Xeas+uNN0=",
+ "dev": true,
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/meow/node_modules/find-up": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz",
+ "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=",
+ "dev": true,
+ "dependencies": {
+ "locate-path": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/meow/node_modules/load-json-file": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-4.0.0.tgz",
+ "integrity": "sha1-L19Fq5HjMhYjT9U62rZo607AmTs=",
+ "dev": true,
+ "dependencies": {
+ "graceful-fs": "^4.1.2",
+ "parse-json": "^4.0.0",
+ "pify": "^3.0.0",
+ "strip-bom": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/meow/node_modules/locate-path": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz",
+ "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=",
+ "dev": true,
+ "dependencies": {
+ "p-locate": "^2.0.0",
+ "path-exists": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/meow/node_modules/p-limit": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz",
+ "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==",
+ "dev": true,
+ "dependencies": {
+ "p-try": "^1.0.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/meow/node_modules/p-locate": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz",
+ "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=",
+ "dev": true,
+ "dependencies": {
+ "p-limit": "^1.1.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/meow/node_modules/p-try": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz",
+ "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=",
+ "dev": true,
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/meow/node_modules/parse-json": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz",
+ "integrity": "sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA=",
+ "dev": true,
+ "dependencies": {
+ "error-ex": "^1.3.1",
+ "json-parse-better-errors": "^1.0.1"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/meow/node_modules/path-type": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/path-type/-/path-type-3.0.0.tgz",
+ "integrity": "sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg==",
+ "dev": true,
+ "dependencies": {
+ "pify": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/meow/node_modules/pify": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz",
+ "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=",
+ "dev": true,
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/meow/node_modules/read-pkg": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-3.0.0.tgz",
+ "integrity": "sha1-nLxoaXj+5l0WwA4rGcI3/Pbjg4k=",
+ "dev": true,
+ "dependencies": {
+ "load-json-file": "^4.0.0",
+ "normalize-package-data": "^2.3.2",
+ "path-type": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/meow/node_modules/read-pkg-up": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-3.0.0.tgz",
+ "integrity": "sha1-PtSWaF26D4/hGNBpHcUfSh/5bwc=",
+ "dev": true,
+ "dependencies": {
+ "find-up": "^2.0.0",
+ "read-pkg": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/meow/node_modules/yargs-parser": {
+ "version": "10.1.0",
+ "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-10.1.0.tgz",
+ "integrity": "sha512-VCIyR1wJoEBZUqk5PA+oOBF6ypbwh5aNB3I50guxAL/quggdfs4TtNHQrSazFA3fYZ+tEqfs0zIGlv0c/rgjbQ==",
+ "dev": true,
+ "dependencies": {
+ "camelcase": "^4.1.0"
+ }
+ },
+ "node_modules/merge-stream": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz",
+ "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==",
+ "dev": true
+ },
+ "node_modules/merge2": {
+ "version": "1.4.1",
+ "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz",
+ "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==",
+ "dev": true,
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/micro-spelling-correcter": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/micro-spelling-correcter/-/micro-spelling-correcter-1.1.1.tgz",
+ "integrity": "sha512-lkJ3Rj/mtjlRcHk6YyCbvZhyWTOzdBvTHsxMmZSk5jxN1YyVSQ+JETAom55mdzfcyDrY/49Z7UCW760BK30crg==",
+ "dev": true
+ },
+ "node_modules/micromatch": {
+ "version": "3.1.10",
+ "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz",
+ "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==",
+ "dev": true,
+ "dependencies": {
+ "arr-diff": "^4.0.0",
+ "array-unique": "^0.3.2",
+ "braces": "^2.3.1",
+ "define-property": "^2.0.2",
+ "extend-shallow": "^3.0.2",
+ "extglob": "^2.0.4",
+ "fragment-cache": "^0.2.1",
+ "kind-of": "^6.0.2",
+ "nanomatch": "^1.2.9",
+ "object.pick": "^1.3.0",
+ "regex-not": "^1.0.0",
+ "snapdragon": "^0.8.1",
+ "to-regex": "^3.0.2"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/micromatch/node_modules/braces": {
+ "version": "2.3.2",
+ "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz",
+ "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==",
+ "dev": true,
+ "dependencies": {
+ "arr-flatten": "^1.1.0",
+ "array-unique": "^0.3.2",
+ "extend-shallow": "^2.0.1",
+ "fill-range": "^4.0.0",
+ "isobject": "^3.0.1",
+ "repeat-element": "^1.1.2",
+ "snapdragon": "^0.8.1",
+ "snapdragon-node": "^2.0.1",
+ "split-string": "^3.0.2",
+ "to-regex": "^3.0.1"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/micromatch/node_modules/braces/node_modules/extend-shallow": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
+ "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
+ "dev": true,
+ "dependencies": {
+ "is-extendable": "^0.1.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/micromatch/node_modules/fill-range": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz",
+ "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=",
+ "dev": true,
+ "dependencies": {
+ "extend-shallow": "^2.0.1",
+ "is-number": "^3.0.0",
+ "repeat-string": "^1.6.1",
+ "to-regex-range": "^2.1.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/micromatch/node_modules/fill-range/node_modules/extend-shallow": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
+ "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
+ "dev": true,
+ "dependencies": {
+ "is-extendable": "^0.1.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/micromatch/node_modules/is-buffer": {
+ "version": "1.1.6",
+ "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz",
+ "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==",
+ "dev": true
+ },
+ "node_modules/micromatch/node_modules/is-number": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz",
+ "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=",
+ "dev": true,
+ "dependencies": {
+ "kind-of": "^3.0.2"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/micromatch/node_modules/is-number/node_modules/kind-of": {
+ "version": "3.2.2",
+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
+ "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
+ "dev": true,
+ "dependencies": {
+ "is-buffer": "^1.1.5"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/micromatch/node_modules/to-regex-range": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz",
+ "integrity": "sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg=",
+ "dev": true,
+ "dependencies": {
+ "is-number": "^3.0.0",
+ "repeat-string": "^1.6.1"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/mime-db": {
+ "version": "1.52.0",
+ "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz",
+ "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==",
+ "dev": true,
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/mime-types": {
+ "version": "2.1.35",
+ "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz",
+ "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==",
+ "dev": true,
+ "dependencies": {
+ "mime-db": "1.52.0"
+ },
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/mimic-fn": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz",
+ "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==",
+ "dev": true,
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/mimic-response": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-1.0.1.tgz",
+ "integrity": "sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ==",
+ "dev": true,
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/minimatch": {
+ "version": "3.0.5",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.5.tgz",
+ "integrity": "sha512-tUpxzX0VAzJHjLu0xUfFv1gwVp9ba3IOuRAVH2EGuRW8a5emA2FlACLqiT/lDVtS1W+TGNwqz3sWaNyLgDJWuw==",
+ "dependencies": {
+ "brace-expansion": "^1.1.7"
+ },
+ "engines": {
+ "node": "*"
+ }
+ },
+ "node_modules/minimist": {
+ "version": "1.2.6",
+ "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.6.tgz",
+ "integrity": "sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q==",
+ "dev": true
+ },
+ "node_modules/minimist-options": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/minimist-options/-/minimist-options-3.0.2.tgz",
+ "integrity": "sha512-FyBrT/d0d4+uiZRbqznPXqw3IpZZG3gl3wKWiX784FycUKVwBt0uLBFkQrtE4tZOrgo78nZp2jnKz3L65T5LdQ==",
+ "dev": true,
+ "dependencies": {
+ "arrify": "^1.0.1",
+ "is-plain-obj": "^1.1.0"
+ },
+ "engines": {
+ "node": ">= 4"
+ }
+ },
+ "node_modules/minimist-options/node_modules/arrify": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz",
+ "integrity": "sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0=",
+ "dev": true,
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/mixin-deep": {
+ "version": "1.3.2",
+ "resolved": "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.2.tgz",
+ "integrity": "sha512-WRoDn//mXBiJ1H40rqa3vH0toePwSsGb45iInWlTySa+Uu4k3tYUSxa2v1KqAiLtvlrSzaExqS1gtk96A9zvEA==",
+ "dev": true,
+ "dependencies": {
+ "for-in": "^1.0.2",
+ "is-extendable": "^1.0.1"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/mixin-deep/node_modules/is-extendable": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz",
+ "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==",
+ "dev": true,
+ "dependencies": {
+ "is-plain-object": "^2.0.4"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/mkdirp": {
+ "version": "0.5.5",
+ "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz",
+ "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==",
+ "dev": true,
+ "dependencies": {
+ "minimist": "^1.2.5"
+ },
+ "bin": {
+ "mkdirp": "bin/cmd.js"
+ }
+ },
+ "node_modules/mocha": {
+ "version": "9.2.2",
+ "resolved": "https://registry.npmjs.org/mocha/-/mocha-9.2.2.tgz",
+ "integrity": "sha512-L6XC3EdwT6YrIk0yXpavvLkn8h+EU+Y5UcCHKECyMbdUIxyMuZj4bX4U9e1nvnvUUvQVsV2VHQr5zLdcUkhW/g==",
+ "dev": true,
+ "dependencies": {
+ "@ungap/promise-all-settled": "1.1.2",
+ "ansi-colors": "4.1.1",
+ "browser-stdout": "1.3.1",
+ "chokidar": "3.5.3",
+ "debug": "4.3.3",
+ "diff": "5.0.0",
+ "escape-string-regexp": "4.0.0",
+ "find-up": "5.0.0",
+ "glob": "7.2.0",
+ "growl": "1.10.5",
+ "he": "1.2.0",
+ "js-yaml": "4.1.0",
+ "log-symbols": "4.1.0",
+ "minimatch": "4.2.1",
+ "ms": "2.1.3",
+ "nanoid": "3.3.1",
+ "serialize-javascript": "6.0.0",
+ "strip-json-comments": "3.1.1",
+ "supports-color": "8.1.1",
+ "which": "2.0.2",
+ "workerpool": "6.2.0",
+ "yargs": "16.2.0",
+ "yargs-parser": "20.2.4",
+ "yargs-unparser": "2.0.0"
+ },
+ "bin": {
+ "_mocha": "bin/_mocha",
+ "mocha": "bin/mocha"
+ },
+ "engines": {
+ "node": ">= 12.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/mochajs"
+ }
+ },
+ "node_modules/mocha/node_modules/ansi-styles": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
+ "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
+ "dev": true,
+ "dependencies": {
+ "color-convert": "^2.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/ansi-styles?sponsor=1"
+ }
+ },
+ "node_modules/mocha/node_modules/argparse": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz",
+ "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==",
+ "dev": true
+ },
+ "node_modules/mocha/node_modules/chalk": {
+ "version": "4.1.2",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
+ "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
+ "dev": true,
+ "dependencies": {
+ "ansi-styles": "^4.1.0",
+ "supports-color": "^7.1.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/chalk?sponsor=1"
+ }
+ },
+ "node_modules/mocha/node_modules/chalk/node_modules/supports-color": {
+ "version": "7.2.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
+ "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
+ "dev": true,
+ "dependencies": {
+ "has-flag": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/mocha/node_modules/cliui": {
+ "version": "7.0.4",
+ "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz",
+ "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==",
+ "dev": true,
+ "dependencies": {
+ "string-width": "^4.2.0",
+ "strip-ansi": "^6.0.0",
+ "wrap-ansi": "^7.0.0"
+ }
+ },
+ "node_modules/mocha/node_modules/color-convert": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
+ "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
+ "dev": true,
+ "dependencies": {
+ "color-name": "~1.1.4"
+ },
+ "engines": {
+ "node": ">=7.0.0"
+ }
+ },
+ "node_modules/mocha/node_modules/color-name": {
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
+ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
+ "dev": true
+ },
+ "node_modules/mocha/node_modules/debug": {
+ "version": "4.3.3",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.3.tgz",
+ "integrity": "sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q==",
+ "dev": true,
+ "dependencies": {
+ "ms": "2.1.2"
+ },
+ "engines": {
+ "node": ">=6.0"
+ },
+ "peerDependenciesMeta": {
+ "supports-color": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/mocha/node_modules/debug/node_modules/ms": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
+ "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
+ "dev": true
+ },
+ "node_modules/mocha/node_modules/escape-string-regexp": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz",
+ "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==",
+ "dev": true,
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/mocha/node_modules/find-up": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz",
+ "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==",
+ "dev": true,
+ "dependencies": {
+ "locate-path": "^6.0.0",
+ "path-exists": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/mocha/node_modules/has-flag": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
+ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/mocha/node_modules/js-yaml": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz",
+ "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==",
+ "dev": true,
+ "dependencies": {
+ "argparse": "^2.0.1"
+ },
+ "bin": {
+ "js-yaml": "bin/js-yaml.js"
+ }
+ },
+ "node_modules/mocha/node_modules/locate-path": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz",
+ "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==",
+ "dev": true,
+ "dependencies": {
+ "p-locate": "^5.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/mocha/node_modules/log-symbols": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz",
+ "integrity": "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==",
+ "dev": true,
+ "dependencies": {
+ "chalk": "^4.1.0",
+ "is-unicode-supported": "^0.1.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/mocha/node_modules/minimatch": {
+ "version": "4.2.1",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-4.2.1.tgz",
+ "integrity": "sha512-9Uq1ChtSZO+Mxa/CL1eGizn2vRn3MlLgzhT0Iz8zaY8NdvxvB0d5QdPFmCKf7JKA9Lerx5vRrnwO03jsSfGG9g==",
+ "dev": true,
+ "dependencies": {
+ "brace-expansion": "^1.1.7"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/mocha/node_modules/ms": {
+ "version": "2.1.3",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
+ "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
+ "dev": true
+ },
+ "node_modules/mocha/node_modules/p-limit": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz",
+ "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==",
+ "dev": true,
+ "dependencies": {
+ "yocto-queue": "^0.1.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/mocha/node_modules/p-locate": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz",
+ "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==",
+ "dev": true,
+ "dependencies": {
+ "p-limit": "^3.0.2"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/mocha/node_modules/path-exists": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz",
+ "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/mocha/node_modules/strip-json-comments": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz",
+ "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/mocha/node_modules/supports-color": {
+ "version": "8.1.1",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz",
+ "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==",
+ "dev": true,
+ "dependencies": {
+ "has-flag": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/supports-color?sponsor=1"
+ }
+ },
+ "node_modules/mocha/node_modules/which": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
+ "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==",
+ "dev": true,
+ "dependencies": {
+ "isexe": "^2.0.0"
+ },
+ "bin": {
+ "node-which": "bin/node-which"
+ },
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/mocha/node_modules/wrap-ansi": {
+ "version": "7.0.0",
+ "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz",
+ "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==",
+ "dev": true,
+ "dependencies": {
+ "ansi-styles": "^4.0.0",
+ "string-width": "^4.1.0",
+ "strip-ansi": "^6.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/wrap-ansi?sponsor=1"
+ }
+ },
+ "node_modules/mocha/node_modules/y18n": {
+ "version": "5.0.8",
+ "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz",
+ "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==",
+ "dev": true,
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/mocha/node_modules/yargs": {
+ "version": "16.2.0",
+ "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz",
+ "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==",
+ "dev": true,
+ "dependencies": {
+ "cliui": "^7.0.2",
+ "escalade": "^3.1.1",
+ "get-caller-file": "^2.0.5",
+ "require-directory": "^2.1.1",
+ "string-width": "^4.2.0",
+ "y18n": "^5.0.5",
+ "yargs-parser": "^20.2.2"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/mocha/node_modules/yargs-parser": {
+ "version": "20.2.4",
+ "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.4.tgz",
+ "integrity": "sha512-WOkpgNhPTlE73h4VFAFsOnomJVaovO8VqLDzy5saChRBFQFBoMYirowyW+Q9HB4HFF4Z7VZTiG3iSzJJA29yRA==",
+ "dev": true,
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/ms": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
+ "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
+ "dev": true
+ },
+ "node_modules/multimap": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/multimap/-/multimap-1.1.0.tgz",
+ "integrity": "sha512-0ZIR9PasPxGXmRsEF8jsDzndzHDj7tIav+JUmvIFB/WHswliFnquxECT/De7GR4yg99ky/NlRKJT82G1y271bw==",
+ "dev": true
+ },
+ "node_modules/multimatch": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/multimatch/-/multimatch-4.0.0.tgz",
+ "integrity": "sha512-lDmx79y1z6i7RNx0ZGCPq1bzJ6ZoDDKbvh7jxr9SJcWLkShMzXrHbYVpTdnhNM5MXpDUxCQ4DgqVttVXlBgiBQ==",
+ "dev": true,
+ "dependencies": {
+ "@types/minimatch": "^3.0.3",
+ "array-differ": "^3.0.0",
+ "array-union": "^2.1.0",
+ "arrify": "^2.0.1",
+ "minimatch": "^3.0.4"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/multimatch/node_modules/array-union": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz",
+ "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/mute-stream": {
+ "version": "0.0.8",
+ "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.8.tgz",
+ "integrity": "sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==",
+ "dev": true
+ },
+ "node_modules/nanoid": {
+ "version": "3.3.1",
+ "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.1.tgz",
+ "integrity": "sha512-n6Vs/3KGyxPQd6uO0eH4Bv0ojGSUvuLlIHtC3Y0kEO23YRge8H9x1GCzLn28YX0H66pMkxuaeESFq4tKISKwdw==",
+ "dev": true,
+ "bin": {
+ "nanoid": "bin/nanoid.cjs"
+ },
+ "engines": {
+ "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1"
+ }
+ },
+ "node_modules/nanomatch": {
+ "version": "1.2.13",
+ "resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.13.tgz",
+ "integrity": "sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA==",
+ "dev": true,
+ "dependencies": {
+ "arr-diff": "^4.0.0",
+ "array-unique": "^0.3.2",
+ "define-property": "^2.0.2",
+ "extend-shallow": "^3.0.2",
+ "fragment-cache": "^0.2.1",
+ "is-windows": "^1.0.2",
+ "kind-of": "^6.0.2",
+ "object.pick": "^1.3.0",
+ "regex-not": "^1.0.0",
+ "snapdragon": "^0.8.1",
+ "to-regex": "^3.0.1"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/natural-compare": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz",
+ "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=",
+ "dev": true
+ },
+ "node_modules/neo-async": {
+ "version": "2.6.2",
+ "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz",
+ "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==",
+ "dev": true
+ },
+ "node_modules/nice-try": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz",
+ "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==",
+ "dev": true
+ },
+ "node_modules/nise": {
+ "version": "4.0.4",
+ "resolved": "https://registry.npmjs.org/nise/-/nise-4.0.4.tgz",
+ "integrity": "sha512-bTTRUNlemx6deJa+ZyoCUTRvH3liK5+N6VQZ4NIw90AgDXY6iPnsqplNFf6STcj+ePk0H/xqxnP75Lr0J0Fq3A==",
+ "dev": true,
+ "dependencies": {
+ "@sinonjs/commons": "^1.7.0",
+ "@sinonjs/fake-timers": "^6.0.0",
+ "@sinonjs/text-encoding": "^0.7.1",
+ "just-extend": "^4.0.2",
+ "path-to-regexp": "^1.7.0"
+ }
+ },
+ "node_modules/normalize-package-data": {
+ "version": "2.5.0",
+ "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz",
+ "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==",
+ "dev": true,
+ "dependencies": {
+ "hosted-git-info": "^2.1.4",
+ "resolve": "^1.10.0",
+ "semver": "2 || 3 || 4 || 5",
+ "validate-npm-package-license": "^3.0.1"
+ }
+ },
+ "node_modules/normalize-path": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz",
+ "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==",
+ "dev": true,
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/normalize-url": {
+ "version": "4.5.1",
+ "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-4.5.1.tgz",
+ "integrity": "sha512-9UZCFRHQdNrfTpGg8+1INIg93B6zE0aXMVFkw1WFwvO4SlZywU6aLg5Of0Ap/PgcbSw4LNxvMWXMeugwMCX0AA==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/obj-props": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/obj-props/-/obj-props-1.3.0.tgz",
+ "integrity": "sha512-k2Xkjx5wn6eC3537SWAXHzB6lkI81kS+icMKMkh4nG3w7shWG6MaWOBrNvhWVOszrtL5uxdfymQQfPUxwY+2eg==",
+ "dev": true,
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/object-copy": {
+ "version": "0.1.0",
+ "resolved": "https://registry.npmjs.org/object-copy/-/object-copy-0.1.0.tgz",
+ "integrity": "sha1-fn2Fi3gb18mRpBupde04EnVOmYw=",
+ "dev": true,
+ "dependencies": {
+ "copy-descriptor": "^0.1.0",
+ "define-property": "^0.2.5",
+ "kind-of": "^3.0.3"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/object-copy/node_modules/define-property": {
+ "version": "0.2.5",
+ "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz",
+ "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=",
+ "dev": true,
+ "dependencies": {
+ "is-descriptor": "^0.1.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/object-copy/node_modules/is-buffer": {
+ "version": "1.1.6",
+ "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz",
+ "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==",
+ "dev": true
+ },
+ "node_modules/object-copy/node_modules/kind-of": {
+ "version": "3.2.2",
+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
+ "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
+ "dev": true,
+ "dependencies": {
+ "is-buffer": "^1.1.5"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/object-inspect": {
+ "version": "1.8.0",
+ "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.8.0.tgz",
+ "integrity": "sha512-jLdtEOB112fORuypAyl/50VRVIBIdVQOSUUGQHzJ4xBSbit81zRarz7GThkEFZy1RceYrWYcPcBFPQwHyAc1gA==",
+ "dev": true,
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/object-keys": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz",
+ "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==",
+ "dev": true,
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/object-visit": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/object-visit/-/object-visit-1.0.1.tgz",
+ "integrity": "sha1-95xEk68MU3e1n+OdOV5BBC3QRbs=",
+ "dev": true,
+ "dependencies": {
+ "isobject": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/object.assign": {
+ "version": "4.1.2",
+ "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.2.tgz",
+ "integrity": "sha512-ixT2L5THXsApyiUPYKmW+2EHpXXe5Ii3M+f4e+aJFAHao5amFRW6J0OO6c/LU8Be47utCx2GL89hxGB6XSmKuQ==",
+ "dev": true,
+ "dependencies": {
+ "call-bind": "^1.0.0",
+ "define-properties": "^1.1.3",
+ "has-symbols": "^1.0.1",
+ "object-keys": "^1.1.1"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/object.pick": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/object.pick/-/object.pick-1.3.0.tgz",
+ "integrity": "sha1-h6EKxMFpS9Lhy/U1kaZhQftd10c=",
+ "dev": true,
+ "dependencies": {
+ "isobject": "^3.0.1"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/object.values": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.1.1.tgz",
+ "integrity": "sha512-WTa54g2K8iu0kmS/us18jEmdv1a4Wi//BZ/DTVYEcH0XhLM5NYdpDHja3gt57VrZLcNAO2WGA+KpWsDBaHt6eA==",
+ "dev": true,
+ "dependencies": {
+ "define-properties": "^1.1.3",
+ "es-abstract": "^1.17.0-next.1",
+ "function-bind": "^1.1.1",
+ "has": "^1.0.3"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/once": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
+ "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=",
+ "dev": true,
+ "dependencies": {
+ "wrappy": "1"
+ }
+ },
+ "node_modules/onetime": {
+ "version": "5.1.2",
+ "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz",
+ "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==",
+ "dev": true,
+ "dependencies": {
+ "mimic-fn": "^2.1.0"
+ },
+ "engines": {
+ "node": ">=6"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/open": {
+ "version": "6.4.0",
+ "resolved": "https://registry.npmjs.org/open/-/open-6.4.0.tgz",
+ "integrity": "sha512-IFenVPgF70fSm1keSd2iDBIDIBZkroLeuffXq+wKTzTJlBpesFWojV9lb8mzOfaAzM1sr7HQHuO0vtV0zYekGg==",
+ "dev": true,
+ "dependencies": {
+ "is-wsl": "^1.1.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/open-editor": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/open-editor/-/open-editor-2.0.1.tgz",
+ "integrity": "sha512-B3KdD7Pl8jYdpBSBBbdYaqVUI3whQjLl1G1+CvhNc8+d7GzKRUq+VuCIx1thxGiqD2oBGRvsZz7QWrBsFP2yVA==",
+ "dev": true,
+ "dependencies": {
+ "env-editor": "^0.4.0",
+ "line-column-path": "^2.0.0",
+ "open": "^6.2.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/optionator": {
+ "version": "0.8.3",
+ "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.3.tgz",
+ "integrity": "sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA==",
+ "dev": true,
+ "dependencies": {
+ "deep-is": "~0.1.3",
+ "fast-levenshtein": "~2.0.6",
+ "levn": "~0.3.0",
+ "prelude-ls": "~1.1.2",
+ "type-check": "~0.3.2",
+ "word-wrap": "~1.2.3"
+ },
+ "engines": {
+ "node": ">= 0.8.0"
+ }
+ },
+ "node_modules/os-tmpdir": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz",
+ "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=",
+ "dev": true,
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/p-cancelable": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-1.1.0.tgz",
+ "integrity": "sha512-s73XxOZ4zpt1edZYZzvhqFa6uvQc1vwUa0K0BdtIZgQMAJj9IbebH+JkgKZc9h+B05PKHLOTl4ajG1BmNrVZlw==",
+ "dev": true,
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/p-limit": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz",
+ "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==",
+ "dev": true,
+ "dependencies": {
+ "p-try": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=6"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/p-locate": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz",
+ "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==",
+ "dev": true,
+ "dependencies": {
+ "p-limit": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/p-try": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz",
+ "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==",
+ "dev": true,
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/package-json": {
+ "version": "6.5.0",
+ "resolved": "https://registry.npmjs.org/package-json/-/package-json-6.5.0.tgz",
+ "integrity": "sha512-k3bdm2n25tkyxcjSKzB5x8kfVxlMdgsbPr0GkZcwHsLpba6cBjqCt1KlcChKEvxHIcTB1FVMuwoijZ26xex5MQ==",
+ "dev": true,
+ "dependencies": {
+ "got": "^9.6.0",
+ "registry-auth-token": "^4.0.0",
+ "registry-url": "^5.0.0",
+ "semver": "^6.2.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/package-json/node_modules/semver": {
+ "version": "6.3.0",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
+ "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
+ "dev": true,
+ "bin": {
+ "semver": "bin/semver.js"
+ }
+ },
+ "node_modules/parent-module": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz",
+ "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==",
+ "dev": true,
+ "dependencies": {
+ "callsites": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/parse-json": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz",
+ "integrity": "sha1-9ID0BDTvgHQfhGkJn43qGPVaTck=",
+ "dev": true,
+ "dependencies": {
+ "error-ex": "^1.2.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/pascalcase": {
+ "version": "0.1.1",
+ "resolved": "https://registry.npmjs.org/pascalcase/-/pascalcase-0.1.1.tgz",
+ "integrity": "sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ=",
+ "dev": true,
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/path-browserify": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-1.0.1.tgz",
+ "integrity": "sha512-b7uo2UCUOYZcnF/3ID0lulOJi/bafxa1xPe7ZPsammBSpjSWQkjNxlt635YGS2MiR9GjvuXCtz2emr3jbsz98g==",
+ "dev": true
+ },
+ "node_modules/path-dirname": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/path-dirname/-/path-dirname-1.0.2.tgz",
+ "integrity": "sha1-zDPSTVJeCZpTiMAzbG4yuRYGCeA=",
+ "dev": true
+ },
+ "node_modules/path-exists": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz",
+ "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=",
+ "dev": true,
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/path-is-absolute": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
+ "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=",
+ "dev": true,
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/path-key": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz",
+ "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=",
+ "dev": true,
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/path-parse": {
+ "version": "1.0.7",
+ "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz",
+ "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==",
+ "dev": true
+ },
+ "node_modules/path-to-regexp": {
+ "version": "1.8.0",
+ "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-1.8.0.tgz",
+ "integrity": "sha512-n43JRhlUKUAlibEJhPeir1ncUID16QnEjNpwzNdO3Lm4ywrBpBZ5oLD0I6br9evr1Y9JTqwRtAh7JLoOzAQdVA==",
+ "dev": true,
+ "dependencies": {
+ "isarray": "0.0.1"
+ }
+ },
+ "node_modules/path-type": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/path-type/-/path-type-2.0.0.tgz",
+ "integrity": "sha1-8BLMuEFbcJb8LaoQVMPXI4lZTHM=",
+ "dev": true,
+ "dependencies": {
+ "pify": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/path-type/node_modules/pify": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz",
+ "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=",
+ "dev": true,
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/picocolors": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz",
+ "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==",
+ "dev": true
+ },
+ "node_modules/picomatch": {
+ "version": "2.3.1",
+ "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz",
+ "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==",
+ "dev": true,
+ "engines": {
+ "node": ">=8.6"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/jonschlinkert"
+ }
+ },
+ "node_modules/pify": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz",
+ "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==",
+ "dev": true,
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/pkg-conf": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/pkg-conf/-/pkg-conf-3.1.0.tgz",
+ "integrity": "sha512-m0OTbR/5VPNPqO1ph6Fqbj7Hv6QU7gR/tQW40ZqrL1rjgCU85W6C1bJn0BItuJqnR98PWzw7Z8hHeChD1WrgdQ==",
+ "dev": true,
+ "dependencies": {
+ "find-up": "^3.0.0",
+ "load-json-file": "^5.2.0"
+ },
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/pkg-conf/node_modules/load-json-file": {
+ "version": "5.3.0",
+ "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-5.3.0.tgz",
+ "integrity": "sha512-cJGP40Jc/VXUsp8/OrnyKyTZ1y6v/dphm3bioS+RrKXjK2BB6wHUd6JptZEFDGgGahMT+InnZO5i1Ei9mpC8Bw==",
+ "dev": true,
+ "dependencies": {
+ "graceful-fs": "^4.1.15",
+ "parse-json": "^4.0.0",
+ "pify": "^4.0.1",
+ "strip-bom": "^3.0.0",
+ "type-fest": "^0.3.0"
+ },
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/pkg-conf/node_modules/parse-json": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz",
+ "integrity": "sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA=",
+ "dev": true,
+ "dependencies": {
+ "error-ex": "^1.3.1",
+ "json-parse-better-errors": "^1.0.1"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/pkg-conf/node_modules/type-fest": {
+ "version": "0.3.1",
+ "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.3.1.tgz",
+ "integrity": "sha512-cUGJnCdr4STbePCgqNFbpVNCepa+kAVohJs1sLhxzdH+gnEoOd8VhbYa7pD3zZYGiURWM2xzEII3fQcRizDkYQ==",
+ "dev": true,
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/pkg-dir": {
+ "version": "4.2.0",
+ "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz",
+ "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==",
+ "dev": true,
+ "dependencies": {
+ "find-up": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/pkg-dir/node_modules/find-up": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz",
+ "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==",
+ "dev": true,
+ "dependencies": {
+ "locate-path": "^5.0.0",
+ "path-exists": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/pkg-dir/node_modules/locate-path": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz",
+ "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==",
+ "dev": true,
+ "dependencies": {
+ "p-locate": "^4.1.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/pkg-dir/node_modules/p-locate": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz",
+ "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==",
+ "dev": true,
+ "dependencies": {
+ "p-limit": "^2.2.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/pkg-dir/node_modules/path-exists": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz",
+ "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/plur": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/plur/-/plur-3.1.1.tgz",
+ "integrity": "sha512-t1Ax8KUvV3FFII8ltczPn2tJdjqbd1sIzu6t4JL7nQ3EyeL/lTrj5PWKb06ic5/6XYDr65rQ4uzQEGN70/6X5w==",
+ "dev": true,
+ "dependencies": {
+ "irregular-plurals": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/posix-character-classes": {
+ "version": "0.1.1",
+ "resolved": "https://registry.npmjs.org/posix-character-classes/-/posix-character-classes-0.1.1.tgz",
+ "integrity": "sha1-AerA/jta9xoqbAL+q7jB/vfgDqs=",
+ "dev": true,
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/prelude-ls": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz",
+ "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=",
+ "dev": true,
+ "engines": {
+ "node": ">= 0.8.0"
+ }
+ },
+ "node_modules/prepend-http": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/prepend-http/-/prepend-http-2.0.0.tgz",
+ "integrity": "sha1-6SQ0v6XqjBn0HN/UAddBo8gZ2Jc=",
+ "dev": true,
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/prettier": {
+ "version": "1.19.1",
+ "resolved": "https://registry.npmjs.org/prettier/-/prettier-1.19.1.tgz",
+ "integrity": "sha512-s7PoyDv/II1ObgQunCbB9PdLmUcBZcnWOcxDh7O0N/UwDEsHyqkW+Qh28jW+mVuCdx7gLB0BotYI1Y6uI9iyew==",
+ "dev": true,
+ "bin": {
+ "prettier": "bin-prettier.js"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/prettier-linter-helpers": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/prettier-linter-helpers/-/prettier-linter-helpers-1.0.0.tgz",
+ "integrity": "sha512-GbK2cP9nraSSUF9N2XwUwqfzlAFlMNYYl+ShE/V+H8a9uNl/oUqB1w2EL54Jh0OlyRSd8RfWYJ3coVS4TROP2w==",
+ "dev": true,
+ "dependencies": {
+ "fast-diff": "^1.1.2"
+ },
+ "engines": {
+ "node": ">=6.0.0"
+ }
+ },
+ "node_modules/process-nextick-args": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz",
+ "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==",
+ "dev": true
+ },
+ "node_modules/progress": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz",
+ "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==",
+ "dev": true,
+ "engines": {
+ "node": ">=0.4.0"
+ }
+ },
+ "node_modules/proto-props": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/proto-props/-/proto-props-2.0.0.tgz",
+ "integrity": "sha512-2yma2tog9VaRZY2mn3Wq51uiSW4NcPYT1cQdBagwyrznrilKSZwIZ0UG3ZPL/mx+axEns0hE35T5ufOYZXEnBQ==",
+ "dev": true,
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/pump": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz",
+ "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==",
+ "dev": true,
+ "dependencies": {
+ "end-of-stream": "^1.1.0",
+ "once": "^1.3.1"
+ }
+ },
+ "node_modules/punycode": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz",
+ "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==",
+ "dev": true,
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/pupa": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/pupa/-/pupa-2.1.1.tgz",
+ "integrity": "sha512-l1jNAspIBSFqbT+y+5FosojNpVpF94nlI+wDUpqP9enwOTfHx9f0gh5nB96vl+6yTpsJsypeNrwfzPrKuHB41A==",
+ "dev": true,
+ "dependencies": {
+ "escape-goat": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/quick-lru": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-1.1.0.tgz",
+ "integrity": "sha1-Q2CxfGETatOAeDl/8RQW4Ybc+7g=",
+ "dev": true,
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/ramda": {
+ "version": "0.27.1",
+ "resolved": "https://registry.npmjs.org/ramda/-/ramda-0.27.1.tgz",
+ "integrity": "sha512-PgIdVpn5y5Yns8vqb8FzBUEYn98V3xcPgawAkkgj0YJ0qDsnHCiNmZYfOGMgOvoB0eWFLpYbhxUR3mxfDIMvpw==",
+ "dev": true
+ },
+ "node_modules/randombytes": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz",
+ "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==",
+ "dev": true,
+ "dependencies": {
+ "safe-buffer": "^5.1.0"
+ }
+ },
+ "node_modules/rc": {
+ "version": "1.2.8",
+ "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz",
+ "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==",
+ "dev": true,
+ "dependencies": {
+ "deep-extend": "^0.6.0",
+ "ini": "~1.3.0",
+ "minimist": "^1.2.0",
+ "strip-json-comments": "~2.0.1"
+ },
+ "bin": {
+ "rc": "cli.js"
+ }
+ },
+ "node_modules/read-pkg": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-2.0.0.tgz",
+ "integrity": "sha1-jvHAYjxqbbDcZxPEv6xGMysjaPg=",
+ "dev": true,
+ "dependencies": {
+ "load-json-file": "^2.0.0",
+ "normalize-package-data": "^2.3.2",
+ "path-type": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/read-pkg-up": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-2.0.0.tgz",
+ "integrity": "sha1-a3KoBImE4MQeeVEP1en6mbO1Sb4=",
+ "dev": true,
+ "dependencies": {
+ "find-up": "^2.0.0",
+ "read-pkg": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/read-pkg-up/node_modules/find-up": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz",
+ "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=",
+ "dev": true,
+ "dependencies": {
+ "locate-path": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/read-pkg-up/node_modules/locate-path": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz",
+ "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=",
+ "dev": true,
+ "dependencies": {
+ "p-locate": "^2.0.0",
+ "path-exists": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/read-pkg-up/node_modules/p-limit": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz",
+ "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==",
+ "dev": true,
+ "dependencies": {
+ "p-try": "^1.0.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/read-pkg-up/node_modules/p-locate": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz",
+ "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=",
+ "dev": true,
+ "dependencies": {
+ "p-limit": "^1.1.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/read-pkg-up/node_modules/p-try": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz",
+ "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=",
+ "dev": true,
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/readable-stream": {
+ "version": "2.3.7",
+ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz",
+ "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==",
+ "dev": true,
+ "dependencies": {
+ "core-util-is": "~1.0.0",
+ "inherits": "~2.0.3",
+ "isarray": "~1.0.0",
+ "process-nextick-args": "~2.0.0",
+ "safe-buffer": "~5.1.1",
+ "string_decoder": "~1.1.1",
+ "util-deprecate": "~1.0.1"
+ }
+ },
+ "node_modules/readable-stream/node_modules/isarray": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
+ "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=",
+ "dev": true
+ },
+ "node_modules/readdirp": {
+ "version": "3.6.0",
+ "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz",
+ "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==",
+ "dev": true,
+ "dependencies": {
+ "picomatch": "^2.2.1"
+ },
+ "engines": {
+ "node": ">=8.10.0"
+ }
+ },
+ "node_modules/rechoir": {
+ "version": "0.8.0",
+ "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.8.0.tgz",
+ "integrity": "sha512-/vxpCXddiX8NGfGO/mTafwjq4aFa/71pvamip0++IQk3zG8cbCj0fifNPrjjF1XMXUne91jL9OoxmdykoEtifQ==",
+ "dev": true,
+ "dependencies": {
+ "resolve": "^1.20.0"
+ },
+ "engines": {
+ "node": ">= 10.13.0"
+ }
+ },
+ "node_modules/redent": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/redent/-/redent-2.0.0.tgz",
+ "integrity": "sha1-wbIAe0LVfrE4kHmzyDM2OdXhzKo=",
+ "dev": true,
+ "dependencies": {
+ "indent-string": "^3.0.0",
+ "strip-indent": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/redent/node_modules/indent-string": {
+ "version": "3.2.0",
+ "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-3.2.0.tgz",
+ "integrity": "sha1-Sl/W0nzDMvN+VBmlBNu4NxBckok=",
+ "dev": true,
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/regenerate": {
+ "version": "1.4.2",
+ "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.2.tgz",
+ "integrity": "sha512-zrceR/XhGYU/d/opr2EKO7aRHUeiBI8qjtfHqADTwZd6Szfy16la6kqD0MIUs5z5hx6AaKa+PixpPrR289+I0A==",
+ "dev": true
+ },
+ "node_modules/regenerate-unicode-properties": {
+ "version": "8.2.0",
+ "resolved": "https://registry.npmjs.org/regenerate-unicode-properties/-/regenerate-unicode-properties-8.2.0.tgz",
+ "integrity": "sha512-F9DjY1vKLo/tPePDycuH3dn9H1OTPIkVD9Kz4LODu+F2C75mgjAJ7x/gwy6ZcSNRAAkhNlJSOHRe8k3p+K9WhA==",
+ "dev": true,
+ "dependencies": {
+ "regenerate": "^1.4.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/regenerator-runtime": {
+ "version": "0.13.7",
+ "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.7.tgz",
+ "integrity": "sha512-a54FxoJDIr27pgf7IgeQGxmqUNYrcV338lf/6gH456HZ/PhX+5BcwHXG9ajESmwe6WRO0tAzRUrRmNONWgkrew=="
+ },
+ "node_modules/regenerator-transform": {
+ "version": "0.14.5",
+ "resolved": "https://registry.npmjs.org/regenerator-transform/-/regenerator-transform-0.14.5.tgz",
+ "integrity": "sha512-eOf6vka5IO151Jfsw2NO9WpGX58W6wWmefK3I1zEGr0lOD0u8rwPaNqQL1aRxUaxLeKO3ArNh3VYg1KbaD+FFw==",
+ "dev": true,
+ "dependencies": {
+ "@babel/runtime": "^7.8.4"
+ }
+ },
+ "node_modules/regex-not": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/regex-not/-/regex-not-1.0.2.tgz",
+ "integrity": "sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A==",
+ "dev": true,
+ "dependencies": {
+ "extend-shallow": "^3.0.2",
+ "safe-regex": "^1.1.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/regexp-tree": {
+ "version": "0.1.21",
+ "resolved": "https://registry.npmjs.org/regexp-tree/-/regexp-tree-0.1.21.tgz",
+ "integrity": "sha512-kUUXjX4AnqnR8KRTCrayAo9PzYMRKmVoGgaz2tBuz0MF3g1ZbGebmtW0yFHfFK9CmBjQKeYIgoL22pFLBJY7sw==",
+ "dev": true,
+ "bin": {
+ "regexp-tree": "bin/regexp-tree"
+ }
+ },
+ "node_modules/regexpp": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-2.0.1.tgz",
+ "integrity": "sha512-lv0M6+TkDVniA3aD1Eg0DVpfU/booSu7Eev3TDO/mZKHBfVjgCGTV4t4buppESEYDtkArYFOxTJWv6S5C+iaNw==",
+ "dev": true,
+ "engines": {
+ "node": ">=6.5.0"
+ }
+ },
+ "node_modules/regexpu-core": {
+ "version": "4.7.1",
+ "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-4.7.1.tgz",
+ "integrity": "sha512-ywH2VUraA44DZQuRKzARmw6S66mr48pQVva4LBeRhcOltJ6hExvWly5ZjFLYo67xbIxb6W1q4bAGtgfEl20zfQ==",
+ "dev": true,
+ "dependencies": {
+ "regenerate": "^1.4.0",
+ "regenerate-unicode-properties": "^8.2.0",
+ "regjsgen": "^0.5.1",
+ "regjsparser": "^0.6.4",
+ "unicode-match-property-ecmascript": "^1.0.4",
+ "unicode-match-property-value-ecmascript": "^1.2.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/registry-auth-token": {
+ "version": "4.2.0",
+ "resolved": "https://registry.npmjs.org/registry-auth-token/-/registry-auth-token-4.2.0.tgz",
+ "integrity": "sha512-P+lWzPrsgfN+UEpDS3U8AQKg/UjZX6mQSJueZj3EK+vNESoqBSpBUD3gmu4sF9lOsjXWjF11dQKUqemf3veq1w==",
+ "dev": true,
+ "dependencies": {
+ "rc": "^1.2.8"
+ },
+ "engines": {
+ "node": ">=6.0.0"
+ }
+ },
+ "node_modules/registry-url": {
+ "version": "5.1.0",
+ "resolved": "https://registry.npmjs.org/registry-url/-/registry-url-5.1.0.tgz",
+ "integrity": "sha512-8acYXXTI0AkQv6RAOjE3vOaIXZkT9wo4LOFbBKYQEEnnMNBpKqdUrI6S4NT0KPIo/WVvJ5tE/X5LF/TQUf0ekw==",
+ "dev": true,
+ "dependencies": {
+ "rc": "^1.2.8"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/regjsgen": {
+ "version": "0.5.2",
+ "resolved": "https://registry.npmjs.org/regjsgen/-/regjsgen-0.5.2.tgz",
+ "integrity": "sha512-OFFT3MfrH90xIW8OOSyUrk6QHD5E9JOTeGodiJeBS3J6IwlgzJMNE/1bZklWz5oTg+9dCMyEetclvCVXOPoN3A==",
+ "dev": true
+ },
+ "node_modules/regjsparser": {
+ "version": "0.6.4",
+ "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.6.4.tgz",
+ "integrity": "sha512-64O87/dPDgfk8/RQqC4gkZoGyyWFIEUTTh80CU6CWuK5vkCGyekIx+oKcEIYtP/RAxSQltCZHCNu/mdd7fqlJw==",
+ "dev": true,
+ "dependencies": {
+ "jsesc": "~0.5.0"
+ },
+ "bin": {
+ "regjsparser": "bin/parser"
+ }
+ },
+ "node_modules/regjsparser/node_modules/jsesc": {
+ "version": "0.5.0",
+ "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-0.5.0.tgz",
+ "integrity": "sha1-597mbjXW/Bb3EP6R1c9p9w8IkR0=",
+ "dev": true,
+ "bin": {
+ "jsesc": "bin/jsesc"
+ }
+ },
+ "node_modules/repeat-element": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.3.tgz",
+ "integrity": "sha512-ahGq0ZnV5m5XtZLMb+vP76kcAM5nkLqk0lpqAuojSKGgQtn4eRi4ZZGm2olo2zKFH+sMsWaqOCW1dqAnOru72g==",
+ "dev": true,
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/repeat-string": {
+ "version": "1.6.1",
+ "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz",
+ "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=",
+ "dev": true,
+ "engines": {
+ "node": ">=0.10"
+ }
+ },
+ "node_modules/require-directory": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz",
+ "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=",
+ "dev": true,
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/reserved-words": {
+ "version": "0.1.2",
+ "resolved": "https://registry.npmjs.org/reserved-words/-/reserved-words-0.1.2.tgz",
+ "integrity": "sha1-AKCUD5jNUBrqqsMWQR2a3FKzGrE=",
+ "dev": true
+ },
+ "node_modules/resolve": {
+ "version": "1.22.1",
+ "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.1.tgz",
+ "integrity": "sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw==",
+ "dev": true,
+ "dependencies": {
+ "is-core-module": "^2.9.0",
+ "path-parse": "^1.0.7",
+ "supports-preserve-symlinks-flag": "^1.0.0"
+ },
+ "bin": {
+ "resolve": "bin/resolve"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/resolve-cwd": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-3.0.0.tgz",
+ "integrity": "sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==",
+ "dev": true,
+ "dependencies": {
+ "resolve-from": "^5.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/resolve-from": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz",
+ "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/resolve-url": {
+ "version": "0.2.1",
+ "resolved": "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz",
+ "integrity": "sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo=",
+ "deprecated": "https://github.com/lydell/resolve-url#deprecated",
+ "dev": true
+ },
+ "node_modules/responselike": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/responselike/-/responselike-1.0.2.tgz",
+ "integrity": "sha1-kYcg7ztjHFZCvgaPFa3lpG9Loec=",
+ "dev": true,
+ "dependencies": {
+ "lowercase-keys": "^1.0.0"
+ }
+ },
+ "node_modules/restore-cursor": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz",
+ "integrity": "sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==",
+ "dev": true,
+ "dependencies": {
+ "onetime": "^5.1.0",
+ "signal-exit": "^3.0.2"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/ret": {
+ "version": "0.1.15",
+ "resolved": "https://registry.npmjs.org/ret/-/ret-0.1.15.tgz",
+ "integrity": "sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==",
+ "dev": true,
+ "engines": {
+ "node": ">=0.12"
+ }
+ },
+ "node_modules/run-async": {
+ "version": "2.4.1",
+ "resolved": "https://registry.npmjs.org/run-async/-/run-async-2.4.1.tgz",
+ "integrity": "sha512-tvVnVv01b8c1RrA6Ep7JkStj85Guv/YrMcwqYQnwjsAS2cTmmPGBBjAjpCW7RrSodNSoE2/qg9O4bceNvUuDgQ==",
+ "dev": true,
+ "engines": {
+ "node": ">=0.12.0"
+ }
+ },
+ "node_modules/rxjs": {
+ "version": "6.6.3",
+ "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.6.3.tgz",
+ "integrity": "sha512-trsQc+xYYXZ3urjOiJOuCOa5N3jAZ3eiSpQB5hIT8zGlL2QfnHLJ2r7GMkBGuIausdJN1OneaI6gQlsqNHHmZQ==",
+ "dev": true,
+ "dependencies": {
+ "tslib": "^1.9.0"
+ },
+ "engines": {
+ "npm": ">=2.0.0"
+ }
+ },
+ "node_modules/safe-buffer": {
+ "version": "5.1.2",
+ "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
+ "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==",
+ "dev": true
+ },
+ "node_modules/safe-regex": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz",
+ "integrity": "sha1-QKNmnzsHfR6UPURinhV91IAjvy4=",
+ "dev": true,
+ "dependencies": {
+ "ret": "~0.1.10"
+ }
+ },
+ "node_modules/safer-buffer": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
+ "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==",
+ "dev": true
+ },
+ "node_modules/schema-utils": {
+ "version": "2.7.1",
+ "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-2.7.1.tgz",
+ "integrity": "sha512-SHiNtMOUGWBQJwzISiVYKu82GiV4QYGePp3odlY1tuKO7gPtphAT5R/py0fA6xtbgLL/RvtJZnU9b8s0F1q0Xg==",
+ "dev": true,
+ "dependencies": {
+ "@types/json-schema": "^7.0.5",
+ "ajv": "^6.12.4",
+ "ajv-keywords": "^3.5.2"
+ },
+ "engines": {
+ "node": ">= 8.9.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/webpack"
+ }
+ },
+ "node_modules/semver": {
+ "version": "5.7.1",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz",
+ "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==",
+ "dev": true,
+ "bin": {
+ "semver": "bin/semver"
+ }
+ },
+ "node_modules/semver-diff": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/semver-diff/-/semver-diff-3.1.1.tgz",
+ "integrity": "sha512-GX0Ix/CJcHyB8c4ykpHGIAvLyOwOobtM/8d+TQkAd81/bEjgPHrfba41Vpesr7jX/t8Uh+R3EX9eAS5be+jQYg==",
+ "dev": true,
+ "dependencies": {
+ "semver": "^6.3.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/semver-diff/node_modules/semver": {
+ "version": "6.3.0",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
+ "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
+ "dev": true,
+ "bin": {
+ "semver": "bin/semver.js"
+ }
+ },
+ "node_modules/serialize-javascript": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.0.tgz",
+ "integrity": "sha512-Qr3TosvguFt8ePWqsvRfrKyQXIiW+nGbYpy8XK24NQHE83caxWt+mIymTT19DGFbNWNLfEwsrkSmN64lVWB9ag==",
+ "dev": true,
+ "dependencies": {
+ "randombytes": "^2.1.0"
+ }
+ },
+ "node_modules/set-value": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.1.tgz",
+ "integrity": "sha512-JxHc1weCN68wRY0fhCoXpyK55m/XPHafOmK4UWD7m2CI14GMcFypt4w/0+NV5f/ZMby2F6S2wwA7fgynh9gWSw==",
+ "dev": true,
+ "dependencies": {
+ "extend-shallow": "^2.0.1",
+ "is-extendable": "^0.1.1",
+ "is-plain-object": "^2.0.3",
+ "split-string": "^3.0.1"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/set-value/node_modules/extend-shallow": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
+ "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
+ "dev": true,
+ "dependencies": {
+ "is-extendable": "^0.1.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/shallow-clone": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/shallow-clone/-/shallow-clone-3.0.1.tgz",
+ "integrity": "sha512-/6KqX+GVUdqPuPPd2LxDDxzX6CAbjJehAAOKlNpqqUpAqPM6HeL8f+o3a+JsyGjn2lv0WY8UsTgUJjU9Ok55NA==",
+ "dev": true,
+ "dependencies": {
+ "kind-of": "^6.0.2"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/shebang-command": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz",
+ "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=",
+ "dev": true,
+ "dependencies": {
+ "shebang-regex": "^1.0.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/shebang-regex": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz",
+ "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=",
+ "dev": true,
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/should": {
+ "version": "13.2.3",
+ "resolved": "https://registry.npmjs.org/should/-/should-13.2.3.tgz",
+ "integrity": "sha512-ggLesLtu2xp+ZxI+ysJTmNjh2U0TsC+rQ/pfED9bUZZ4DKefP27D+7YJVVTvKsmjLpIi9jAa7itwDGkDDmt1GQ==",
+ "dev": true,
+ "dependencies": {
+ "should-equal": "^2.0.0",
+ "should-format": "^3.0.3",
+ "should-type": "^1.4.0",
+ "should-type-adaptors": "^1.0.1",
+ "should-util": "^1.0.0"
+ }
+ },
+ "node_modules/should-equal": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/should-equal/-/should-equal-2.0.0.tgz",
+ "integrity": "sha512-ZP36TMrK9euEuWQYBig9W55WPC7uo37qzAEmbjHz4gfyuXrEUgF8cUvQVO+w+d3OMfPvSRQJ22lSm8MQJ43LTA==",
+ "dev": true,
+ "dependencies": {
+ "should-type": "^1.4.0"
+ }
+ },
+ "node_modules/should-format": {
+ "version": "3.0.3",
+ "resolved": "https://registry.npmjs.org/should-format/-/should-format-3.0.3.tgz",
+ "integrity": "sha1-m/yPdPo5IFxT04w01xcwPidxJPE=",
+ "dev": true,
+ "dependencies": {
+ "should-type": "^1.3.0",
+ "should-type-adaptors": "^1.0.1"
+ }
+ },
+ "node_modules/should-sinon": {
+ "version": "0.0.6",
+ "resolved": "https://registry.npmjs.org/should-sinon/-/should-sinon-0.0.6.tgz",
+ "integrity": "sha512-ScBOH5uW5QVFaONmUnIXANSR6z5B8IKzEmBP3HE5sPOCDuZ88oTMdUdnKoCVQdLcCIrRrhRLPS5YT+7H40a04g==",
+ "dev": true,
+ "peerDependencies": {
+ "should": ">= 8.x"
+ }
+ },
+ "node_modules/should-type": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/should-type/-/should-type-1.4.0.tgz",
+ "integrity": "sha1-B1bYzoRt/QmEOmlHcZ36DUz/XPM=",
+ "dev": true
+ },
+ "node_modules/should-type-adaptors": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/should-type-adaptors/-/should-type-adaptors-1.1.0.tgz",
+ "integrity": "sha512-JA4hdoLnN+kebEp2Vs8eBe9g7uy0zbRo+RMcU0EsNy+R+k049Ki+N5tT5Jagst2g7EAja+euFuoXFCa8vIklfA==",
+ "dev": true,
+ "dependencies": {
+ "should-type": "^1.3.0",
+ "should-util": "^1.0.0"
+ }
+ },
+ "node_modules/should-util": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/should-util/-/should-util-1.0.1.tgz",
+ "integrity": "sha512-oXF8tfxx5cDk8r2kYqlkUJzZpDBqVY/II2WhvU0n9Y3XYvAYRmeaf1PvvIvTgPnv4KJ+ES5M0PyDq5Jp+Ygy2g==",
+ "dev": true
+ },
+ "node_modules/signal-exit": {
+ "version": "3.0.3",
+ "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.3.tgz",
+ "integrity": "sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA==",
+ "dev": true
+ },
+ "node_modules/sinon": {
+ "version": "9.2.1",
+ "resolved": "https://registry.npmjs.org/sinon/-/sinon-9.2.1.tgz",
+ "integrity": "sha512-naPfsamB5KEE1aiioaoqJ6MEhdUs/2vtI5w1hPAXX/UwvoPjXcwh1m5HiKx0HGgKR8lQSoFIgY5jM6KK8VrS9w==",
+ "deprecated": "16.1.1",
+ "dev": true,
+ "dependencies": {
+ "@sinonjs/commons": "^1.8.1",
+ "@sinonjs/fake-timers": "^6.0.1",
+ "@sinonjs/formatio": "^5.0.1",
+ "@sinonjs/samsam": "^5.2.0",
+ "diff": "^4.0.2",
+ "nise": "^4.0.4",
+ "supports-color": "^7.1.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/sinon"
+ }
+ },
+ "node_modules/sinon/node_modules/diff": {
+ "version": "4.0.2",
+ "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz",
+ "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==",
+ "dev": true,
+ "engines": {
+ "node": ">=0.3.1"
+ }
+ },
+ "node_modules/sinon/node_modules/has-flag": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
+ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/sinon/node_modules/supports-color": {
+ "version": "7.2.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
+ "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
+ "dev": true,
+ "dependencies": {
+ "has-flag": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/slash": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz",
+ "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/slice-ansi": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-2.1.0.tgz",
+ "integrity": "sha512-Qu+VC3EwYLldKa1fCxuuvULvSJOKEgk9pi8dZeCVK7TqBfUNTH4sFkk4joj8afVSfAYgJoSOetjx9QWOJ5mYoQ==",
+ "dev": true,
+ "dependencies": {
+ "ansi-styles": "^3.2.0",
+ "astral-regex": "^1.0.0",
+ "is-fullwidth-code-point": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/snapdragon": {
+ "version": "0.8.2",
+ "resolved": "https://registry.npmjs.org/snapdragon/-/snapdragon-0.8.2.tgz",
+ "integrity": "sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg==",
+ "dev": true,
+ "dependencies": {
+ "base": "^0.11.1",
+ "debug": "^2.2.0",
+ "define-property": "^0.2.5",
+ "extend-shallow": "^2.0.1",
+ "map-cache": "^0.2.2",
+ "source-map": "^0.5.6",
+ "source-map-resolve": "^0.5.0",
+ "use": "^3.1.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/snapdragon-node": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/snapdragon-node/-/snapdragon-node-2.1.1.tgz",
+ "integrity": "sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw==",
+ "dev": true,
+ "dependencies": {
+ "define-property": "^1.0.0",
+ "isobject": "^3.0.0",
+ "snapdragon-util": "^3.0.1"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/snapdragon-node/node_modules/define-property": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz",
+ "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=",
+ "dev": true,
+ "dependencies": {
+ "is-descriptor": "^1.0.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/snapdragon-node/node_modules/is-accessor-descriptor": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz",
+ "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==",
+ "deprecated": "Please upgrade to v1.0.1",
+ "dev": true,
+ "dependencies": {
+ "kind-of": "^6.0.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/snapdragon-node/node_modules/is-data-descriptor": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz",
+ "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==",
+ "deprecated": "Please upgrade to v1.0.1",
+ "dev": true,
+ "dependencies": {
+ "kind-of": "^6.0.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/snapdragon-node/node_modules/is-descriptor": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz",
+ "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==",
+ "dev": true,
+ "dependencies": {
+ "is-accessor-descriptor": "^1.0.0",
+ "is-data-descriptor": "^1.0.0",
+ "kind-of": "^6.0.2"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/snapdragon-util": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/snapdragon-util/-/snapdragon-util-3.0.1.tgz",
+ "integrity": "sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ==",
+ "dev": true,
+ "dependencies": {
+ "kind-of": "^3.2.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/snapdragon-util/node_modules/is-buffer": {
+ "version": "1.1.6",
+ "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz",
+ "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==",
+ "dev": true
+ },
+ "node_modules/snapdragon-util/node_modules/kind-of": {
+ "version": "3.2.2",
+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
+ "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
+ "dev": true,
+ "dependencies": {
+ "is-buffer": "^1.1.5"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/snapdragon/node_modules/debug": {
+ "version": "2.6.9",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
+ "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
+ "dev": true,
+ "dependencies": {
+ "ms": "2.0.0"
+ }
+ },
+ "node_modules/snapdragon/node_modules/define-property": {
+ "version": "0.2.5",
+ "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz",
+ "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=",
+ "dev": true,
+ "dependencies": {
+ "is-descriptor": "^0.1.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/snapdragon/node_modules/extend-shallow": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
+ "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
+ "dev": true,
+ "dependencies": {
+ "is-extendable": "^0.1.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/snapdragon/node_modules/ms": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
+ "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=",
+ "dev": true
+ },
+ "node_modules/source-map": {
+ "version": "0.5.7",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz",
+ "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=",
+ "dev": true,
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/source-map-resolve": {
+ "version": "0.5.3",
+ "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.5.3.tgz",
+ "integrity": "sha512-Htz+RnsXWk5+P2slx5Jh3Q66vhQj1Cllm0zvnaY98+NFx+Dv2CF/f5O/t8x+KaNdrdIAsruNzoh/KpialbqAnw==",
+ "deprecated": "See https://github.com/lydell/source-map-resolve#deprecated",
+ "dev": true,
+ "dependencies": {
+ "atob": "^2.1.2",
+ "decode-uri-component": "^0.2.0",
+ "resolve-url": "^0.2.1",
+ "source-map-url": "^0.4.0",
+ "urix": "^0.1.0"
+ }
+ },
+ "node_modules/source-map-support": {
+ "version": "0.5.21",
+ "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz",
+ "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==",
+ "dev": true,
+ "dependencies": {
+ "buffer-from": "^1.0.0",
+ "source-map": "^0.6.0"
+ }
+ },
+ "node_modules/source-map-support/node_modules/source-map": {
+ "version": "0.6.1",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
+ "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
+ "dev": true,
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/source-map-url": {
+ "version": "0.4.0",
+ "resolved": "https://registry.npmjs.org/source-map-url/-/source-map-url-0.4.0.tgz",
+ "integrity": "sha1-PpNdfd1zYxuXZZlW1VEo6HtQhKM=",
+ "deprecated": "See https://github.com/lydell/source-map-url#deprecated",
+ "dev": true
+ },
+ "node_modules/spdx-correct": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.1.1.tgz",
+ "integrity": "sha512-cOYcUWwhCuHCXi49RhFRCyJEK3iPj1Ziz9DpViV3tbZOwXD49QzIN3MpOLJNxh2qwq2lJJZaKMVw9qNi4jTC0w==",
+ "dev": true,
+ "dependencies": {
+ "spdx-expression-parse": "^3.0.0",
+ "spdx-license-ids": "^3.0.0"
+ }
+ },
+ "node_modules/spdx-exceptions": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.3.0.tgz",
+ "integrity": "sha512-/tTrYOC7PPI1nUAgx34hUpqXuyJG+DTHJTnIULG4rDygi4xu/tfgmq1e1cIRwRzwZgo4NLySi+ricLkZkw4i5A==",
+ "dev": true
+ },
+ "node_modules/spdx-expression-parse": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz",
+ "integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==",
+ "dev": true,
+ "dependencies": {
+ "spdx-exceptions": "^2.1.0",
+ "spdx-license-ids": "^3.0.0"
+ }
+ },
+ "node_modules/spdx-license-ids": {
+ "version": "3.0.6",
+ "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.6.tgz",
+ "integrity": "sha512-+orQK83kyMva3WyPf59k1+Y525csj5JejicWut55zeTWANuN17qSiSLUXWtzHeNWORSvT7GLDJ/E/XiIWoXBTw==",
+ "dev": true
+ },
+ "node_modules/split-string": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/split-string/-/split-string-3.1.0.tgz",
+ "integrity": "sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw==",
+ "dev": true,
+ "dependencies": {
+ "extend-shallow": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/sprintf-js": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz",
+ "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=",
+ "dev": true
+ },
+ "node_modules/static-extend": {
+ "version": "0.1.2",
+ "resolved": "https://registry.npmjs.org/static-extend/-/static-extend-0.1.2.tgz",
+ "integrity": "sha1-YICcOcv/VTNyJv1eC1IPNB8ftcY=",
+ "dev": true,
+ "dependencies": {
+ "define-property": "^0.2.5",
+ "object-copy": "^0.1.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/static-extend/node_modules/define-property": {
+ "version": "0.2.5",
+ "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz",
+ "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=",
+ "dev": true,
+ "dependencies": {
+ "is-descriptor": "^0.1.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/string_decoder": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
+ "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
+ "dev": true,
+ "dependencies": {
+ "safe-buffer": "~5.1.0"
+ }
+ },
+ "node_modules/string-width": {
+ "version": "4.2.3",
+ "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
+ "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
+ "dev": true,
+ "dependencies": {
+ "emoji-regex": "^8.0.0",
+ "is-fullwidth-code-point": "^3.0.0",
+ "strip-ansi": "^6.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/string-width/node_modules/emoji-regex": {
+ "version": "8.0.0",
+ "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
+ "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==",
+ "dev": true
+ },
+ "node_modules/string-width/node_modules/is-fullwidth-code-point": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
+ "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/string.prototype.trimend": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.2.tgz",
+ "integrity": "sha512-8oAG/hi14Z4nOVP0z6mdiVZ/wqjDtWSLygMigTzAb+7aPEDTleeFf+WrF+alzecxIRkckkJVn+dTlwzJXORATw==",
+ "dev": true,
+ "dependencies": {
+ "define-properties": "^1.1.3",
+ "es-abstract": "^1.18.0-next.1"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/string.prototype.trimend/node_modules/es-abstract": {
+ "version": "1.18.0-next.1",
+ "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.18.0-next.1.tgz",
+ "integrity": "sha512-I4UGspA0wpZXWENrdA0uHbnhte683t3qT/1VFH9aX2dA5PPSf6QW5HHXf5HImaqPmjXaVeVk4RGWnaylmV7uAA==",
+ "dev": true,
+ "dependencies": {
+ "es-to-primitive": "^1.2.1",
+ "function-bind": "^1.1.1",
+ "has": "^1.0.3",
+ "has-symbols": "^1.0.1",
+ "is-callable": "^1.2.2",
+ "is-negative-zero": "^2.0.0",
+ "is-regex": "^1.1.1",
+ "object-inspect": "^1.8.0",
+ "object-keys": "^1.1.1",
+ "object.assign": "^4.1.1",
+ "string.prototype.trimend": "^1.0.1",
+ "string.prototype.trimstart": "^1.0.1"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/string.prototype.trimstart": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.2.tgz",
+ "integrity": "sha512-7F6CdBTl5zyu30BJFdzSTlSlLPwODC23Od+iLoVH8X6+3fvDPPuBVVj9iaB1GOsSTSIgVfsfm27R2FGrAPznWg==",
+ "dev": true,
+ "dependencies": {
+ "define-properties": "^1.1.3",
+ "es-abstract": "^1.18.0-next.1"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/string.prototype.trimstart/node_modules/es-abstract": {
+ "version": "1.18.0-next.1",
+ "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.18.0-next.1.tgz",
+ "integrity": "sha512-I4UGspA0wpZXWENrdA0uHbnhte683t3qT/1VFH9aX2dA5PPSf6QW5HHXf5HImaqPmjXaVeVk4RGWnaylmV7uAA==",
+ "dev": true,
+ "dependencies": {
+ "es-to-primitive": "^1.2.1",
+ "function-bind": "^1.1.1",
+ "has": "^1.0.3",
+ "has-symbols": "^1.0.1",
+ "is-callable": "^1.2.2",
+ "is-negative-zero": "^2.0.0",
+ "is-regex": "^1.1.1",
+ "object-inspect": "^1.8.0",
+ "object-keys": "^1.1.1",
+ "object.assign": "^4.1.1",
+ "string.prototype.trimend": "^1.0.1",
+ "string.prototype.trimstart": "^1.0.1"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/strip-ansi": {
+ "version": "6.0.1",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
+ "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
+ "dev": true,
+ "dependencies": {
+ "ansi-regex": "^5.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/strip-bom": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz",
+ "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=",
+ "dev": true,
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/strip-indent": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-2.0.0.tgz",
+ "integrity": "sha1-XvjbKV0B5u1sv3qrlpmNeCJSe2g=",
+ "dev": true,
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/strip-json-comments": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz",
+ "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=",
+ "dev": true,
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/supports-color": {
+ "version": "5.5.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
+ "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
+ "dev": true,
+ "dependencies": {
+ "has-flag": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/supports-hyperlinks": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/supports-hyperlinks/-/supports-hyperlinks-2.1.0.tgz",
+ "integrity": "sha512-zoE5/e+dnEijk6ASB6/qrK+oYdm2do1hjoLWrqUC/8WEIW1gbxFcKuBof7sW8ArN6e+AYvsE8HBGiVRWL/F5CA==",
+ "dev": true,
+ "dependencies": {
+ "has-flag": "^4.0.0",
+ "supports-color": "^7.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/supports-hyperlinks/node_modules/has-flag": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
+ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/supports-hyperlinks/node_modules/supports-color": {
+ "version": "7.2.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
+ "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
+ "dev": true,
+ "dependencies": {
+ "has-flag": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/supports-preserve-symlinks-flag": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz",
+ "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==",
+ "dev": true,
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/table": {
+ "version": "5.4.6",
+ "resolved": "https://registry.npmjs.org/table/-/table-5.4.6.tgz",
+ "integrity": "sha512-wmEc8m4fjnob4gt5riFRtTu/6+4rSe12TpAELNSqHMfF3IqnA+CH37USM6/YR3qRZv7e56kAEAtd6nKZaxe0Ug==",
+ "dev": true,
+ "dependencies": {
+ "ajv": "^6.10.2",
+ "lodash": "^4.17.14",
+ "slice-ansi": "^2.1.0",
+ "string-width": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=6.0.0"
+ }
+ },
+ "node_modules/table/node_modules/ansi-regex": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.1.tgz",
+ "integrity": "sha512-ILlv4k/3f6vfQ4OoP2AGvirOktlQ98ZEL1k9FaQjxa3L1abBgbuTDAdPOpvbGncC0BTVQrl+OM8xZGK6tWXt7g==",
+ "dev": true,
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/table/node_modules/string-width": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz",
+ "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==",
+ "dev": true,
+ "dependencies": {
+ "emoji-regex": "^7.0.1",
+ "is-fullwidth-code-point": "^2.0.0",
+ "strip-ansi": "^5.1.0"
+ },
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/table/node_modules/strip-ansi": {
+ "version": "5.2.0",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz",
+ "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==",
+ "dev": true,
+ "dependencies": {
+ "ansi-regex": "^4.1.0"
+ },
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/tapable": {
+ "version": "2.2.1",
+ "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.1.tgz",
+ "integrity": "sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==",
+ "dev": true,
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/term-size": {
+ "version": "2.2.1",
+ "resolved": "https://registry.npmjs.org/term-size/-/term-size-2.2.1.tgz",
+ "integrity": "sha512-wK0Ri4fOGjv/XPy8SBHZChl8CM7uMc5VML7SqiQ0zG7+J5Vr+RMQDoHa2CNT6KHUnTGIXH34UDMkPzAUyapBZg==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/terser": {
+ "version": "5.16.1",
+ "resolved": "https://registry.npmjs.org/terser/-/terser-5.16.1.tgz",
+ "integrity": "sha512-xvQfyfA1ayT0qdK47zskQgRZeWLoOQ8JQ6mIgRGVNwZKdQMU+5FkCBjmv4QjcrTzyZquRw2FVtlJSRUmMKQslw==",
+ "dev": true,
+ "dependencies": {
+ "@jridgewell/source-map": "^0.3.2",
+ "acorn": "^8.5.0",
+ "commander": "^2.20.0",
+ "source-map-support": "~0.5.20"
+ },
+ "bin": {
+ "terser": "bin/terser"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/terser-webpack-plugin": {
+ "version": "5.3.6",
+ "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.3.6.tgz",
+ "integrity": "sha512-kfLFk+PoLUQIbLmB1+PZDMRSZS99Mp+/MHqDNmMA6tOItzRt+Npe3E+fsMs5mfcM0wCtrrdU387UnV+vnSffXQ==",
+ "dev": true,
+ "dependencies": {
+ "@jridgewell/trace-mapping": "^0.3.14",
+ "jest-worker": "^27.4.5",
+ "schema-utils": "^3.1.1",
+ "serialize-javascript": "^6.0.0",
+ "terser": "^5.14.1"
+ },
+ "engines": {
+ "node": ">= 10.13.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/webpack"
+ },
+ "peerDependencies": {
+ "webpack": "^5.1.0"
+ },
+ "peerDependenciesMeta": {
+ "@swc/core": {
+ "optional": true
+ },
+ "esbuild": {
+ "optional": true
+ },
+ "uglify-js": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/terser-webpack-plugin/node_modules/schema-utils": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.1.1.tgz",
+ "integrity": "sha512-Y5PQxS4ITlC+EahLuXaY86TXfR7Dc5lw294alXOq86JAHCihAIZfqv8nNCWvaEJvaC51uN9hbLGeV0cFBdH+Fw==",
+ "dev": true,
+ "dependencies": {
+ "@types/json-schema": "^7.0.8",
+ "ajv": "^6.12.5",
+ "ajv-keywords": "^3.5.2"
+ },
+ "engines": {
+ "node": ">= 10.13.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/webpack"
+ }
+ },
+ "node_modules/text-table": {
+ "version": "0.2.0",
+ "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz",
+ "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=",
+ "dev": true
+ },
+ "node_modules/through": {
+ "version": "2.3.8",
+ "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz",
+ "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=",
+ "dev": true
+ },
+ "node_modules/through2": {
+ "version": "2.0.5",
+ "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz",
+ "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==",
+ "dev": true,
+ "dependencies": {
+ "readable-stream": "~2.3.6",
+ "xtend": "~4.0.1"
+ }
+ },
+ "node_modules/tmp": {
+ "version": "0.0.33",
+ "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz",
+ "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==",
+ "dev": true,
+ "dependencies": {
+ "os-tmpdir": "~1.0.2"
+ },
+ "engines": {
+ "node": ">=0.6.0"
+ }
+ },
+ "node_modules/to-fast-properties": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz",
+ "integrity": "sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=",
+ "dev": true,
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/to-object-path": {
+ "version": "0.3.0",
+ "resolved": "https://registry.npmjs.org/to-object-path/-/to-object-path-0.3.0.tgz",
+ "integrity": "sha1-KXWIt7Dn4KwI4E5nL4XB9JmeF68=",
+ "dev": true,
+ "dependencies": {
+ "kind-of": "^3.0.2"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/to-object-path/node_modules/is-buffer": {
+ "version": "1.1.6",
+ "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz",
+ "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==",
+ "dev": true
+ },
+ "node_modules/to-object-path/node_modules/kind-of": {
+ "version": "3.2.2",
+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
+ "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
+ "dev": true,
+ "dependencies": {
+ "is-buffer": "^1.1.5"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/to-readable-stream": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/to-readable-stream/-/to-readable-stream-1.0.0.tgz",
+ "integrity": "sha512-Iq25XBt6zD5npPhlLVXGFN3/gyR2/qODcKNNyTMd4vbm39HUaOiAM4PMq0eMVC/Tkxz+Zjdsc55g9yyz+Yq00Q==",
+ "dev": true,
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/to-regex": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/to-regex/-/to-regex-3.0.2.tgz",
+ "integrity": "sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw==",
+ "dev": true,
+ "dependencies": {
+ "define-property": "^2.0.2",
+ "extend-shallow": "^3.0.2",
+ "regex-not": "^1.0.2",
+ "safe-regex": "^1.1.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/to-regex-range": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
+ "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==",
+ "dev": true,
+ "dependencies": {
+ "is-number": "^7.0.0"
+ },
+ "engines": {
+ "node": ">=8.0"
+ }
+ },
+ "node_modules/tokenizer2": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/tokenizer2/-/tokenizer2-2.0.1.tgz",
+ "integrity": "sha512-WAUyv8sbJuFMq4OgQAcXVYrJj1YALGz2Ah4yMyMxRD5DrMnogbtQV3r2RDZ69/Zxh3yYc/olp8rURZ0t3mLevQ==",
+ "deprecated": "This package is no longer maintained.",
+ "dev": true,
+ "dependencies": {
+ "through2": "^2.0.0"
+ }
+ },
+ "node_modules/trim-newlines": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/trim-newlines/-/trim-newlines-2.0.0.tgz",
+ "integrity": "sha1-tAPQuRvlDDMd/EuC7s6yLD3hbSA=",
+ "dev": true,
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/tsconfig-paths": {
+ "version": "3.14.1",
+ "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.14.1.tgz",
+ "integrity": "sha512-fxDhWnFSLt3VuTwtvJt5fpwxBHg5AdKWMsgcPOOIilyjymcYVZoCQF8fvFRezCNfblEXmi+PcM1eYHeOAgXCOQ==",
+ "dev": true,
+ "dependencies": {
+ "@types/json5": "^0.0.29",
+ "json5": "^1.0.1",
+ "minimist": "^1.2.6",
+ "strip-bom": "^3.0.0"
+ }
+ },
+ "node_modules/tsconfig-paths/node_modules/json5": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.2.tgz",
+ "integrity": "sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==",
+ "dev": true,
+ "dependencies": {
+ "minimist": "^1.2.0"
+ },
+ "bin": {
+ "json5": "lib/cli.js"
+ }
+ },
+ "node_modules/tslib": {
+ "version": "1.14.1",
+ "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz",
+ "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==",
+ "dev": true
+ },
+ "node_modules/type-check": {
+ "version": "0.3.2",
+ "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz",
+ "integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=",
+ "dev": true,
+ "dependencies": {
+ "prelude-ls": "~1.1.2"
+ },
+ "engines": {
+ "node": ">= 0.8.0"
+ }
+ },
+ "node_modules/type-detect": {
+ "version": "4.0.8",
+ "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz",
+ "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==",
+ "dev": true,
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/type-fest": {
+ "version": "0.8.1",
+ "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz",
+ "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/typedarray-to-buffer": {
+ "version": "3.1.5",
+ "resolved": "https://registry.npmjs.org/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz",
+ "integrity": "sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q==",
+ "dev": true,
+ "dependencies": {
+ "is-typedarray": "^1.0.0"
+ }
+ },
+ "node_modules/unicode-canonical-property-names-ecmascript": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-1.0.4.tgz",
+ "integrity": "sha512-jDrNnXWHd4oHiTZnx/ZG7gtUTVp+gCcTTKr8L0HjlwphROEW3+Him+IpvC+xcJEFegapiMZyZe02CyuOnRmbnQ==",
+ "dev": true,
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/unicode-match-property-ecmascript": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/unicode-match-property-ecmascript/-/unicode-match-property-ecmascript-1.0.4.tgz",
+ "integrity": "sha512-L4Qoh15vTfntsn4P1zqnHulG0LdXgjSO035fEpdtp6YxXhMT51Q6vgM5lYdG/5X3MjS+k/Y9Xw4SFCY9IkR0rg==",
+ "dev": true,
+ "dependencies": {
+ "unicode-canonical-property-names-ecmascript": "^1.0.4",
+ "unicode-property-aliases-ecmascript": "^1.0.4"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/unicode-match-property-value-ecmascript": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-1.2.0.tgz",
+ "integrity": "sha512-wjuQHGQVofmSJv1uVISKLE5zO2rNGzM/KCYZch/QQvez7C1hUhBIuZ701fYXExuufJFMPhv2SyL8CyoIfMLbIQ==",
+ "dev": true,
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/unicode-property-aliases-ecmascript": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-1.1.0.tgz",
+ "integrity": "sha512-PqSoPh/pWetQ2phoj5RLiaqIk4kCNwoV3CI+LfGmWLKI3rE3kl1h59XpX2BjgDrmbxD9ARtQobPGU1SguCYuQg==",
+ "dev": true,
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/union-value": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/union-value/-/union-value-1.0.1.tgz",
+ "integrity": "sha512-tJfXmxMeWYnczCVs7XAEvIV7ieppALdyepWMkHkwciRpZraG/xwT+s2JN8+pr1+8jCRf80FFzvr+MpQeeoF4Xg==",
+ "dev": true,
+ "dependencies": {
+ "arr-union": "^3.1.0",
+ "get-value": "^2.0.6",
+ "is-extendable": "^0.1.1",
+ "set-value": "^2.0.1"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/unique-string": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/unique-string/-/unique-string-2.0.0.tgz",
+ "integrity": "sha512-uNaeirEPvpZWSgzwsPGtU2zVSTrn/8L5q/IexZmH0eH6SA73CmAA5U4GwORTxQAZs95TAXLNqeLoPPNO5gZfWg==",
+ "dev": true,
+ "dependencies": {
+ "crypto-random-string": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/unset-value": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/unset-value/-/unset-value-1.0.0.tgz",
+ "integrity": "sha1-g3aHP30jNRef+x5vw6jtDfyKtVk=",
+ "dev": true,
+ "dependencies": {
+ "has-value": "^0.3.1",
+ "isobject": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/unset-value/node_modules/has-value": {
+ "version": "0.3.1",
+ "resolved": "https://registry.npmjs.org/has-value/-/has-value-0.3.1.tgz",
+ "integrity": "sha1-ex9YutpiyoJ+wKIHgCVlSEWZXh8=",
+ "dev": true,
+ "dependencies": {
+ "get-value": "^2.0.3",
+ "has-values": "^0.1.4",
+ "isobject": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/unset-value/node_modules/has-value/node_modules/isobject": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz",
+ "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=",
+ "dev": true,
+ "dependencies": {
+ "isarray": "1.0.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/unset-value/node_modules/has-values": {
+ "version": "0.1.4",
+ "resolved": "https://registry.npmjs.org/has-values/-/has-values-0.1.4.tgz",
+ "integrity": "sha1-bWHeldkd/Km5oCCJrThL/49it3E=",
+ "dev": true,
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/unset-value/node_modules/isarray": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
+ "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=",
+ "dev": true
+ },
+ "node_modules/update-notifier": {
+ "version": "4.1.3",
+ "resolved": "https://registry.npmjs.org/update-notifier/-/update-notifier-4.1.3.tgz",
+ "integrity": "sha512-Yld6Z0RyCYGB6ckIjffGOSOmHXj1gMeE7aROz4MG+XMkmixBX4jUngrGXNYz7wPKBmtoD4MnBa2Anu7RSKht/A==",
+ "dev": true,
+ "dependencies": {
+ "boxen": "^4.2.0",
+ "chalk": "^3.0.0",
+ "configstore": "^5.0.1",
+ "has-yarn": "^2.1.0",
+ "import-lazy": "^2.1.0",
+ "is-ci": "^2.0.0",
+ "is-installed-globally": "^0.3.1",
+ "is-npm": "^4.0.0",
+ "is-yarn-global": "^0.3.0",
+ "latest-version": "^5.0.0",
+ "pupa": "^2.0.1",
+ "semver-diff": "^3.1.1",
+ "xdg-basedir": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/yeoman/update-notifier?sponsor=1"
+ }
+ },
+ "node_modules/update-notifier/node_modules/ansi-styles": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
+ "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
+ "dev": true,
+ "dependencies": {
+ "color-convert": "^2.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/ansi-styles?sponsor=1"
+ }
+ },
+ "node_modules/update-notifier/node_modules/chalk": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz",
+ "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==",
+ "dev": true,
+ "dependencies": {
+ "ansi-styles": "^4.1.0",
+ "supports-color": "^7.1.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/update-notifier/node_modules/color-convert": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
+ "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
+ "dev": true,
+ "dependencies": {
+ "color-name": "~1.1.4"
+ },
+ "engines": {
+ "node": ">=7.0.0"
+ }
+ },
+ "node_modules/update-notifier/node_modules/color-name": {
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
+ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
+ "dev": true
+ },
+ "node_modules/update-notifier/node_modules/has-flag": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
+ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/update-notifier/node_modules/supports-color": {
+ "version": "7.2.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
+ "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
+ "dev": true,
+ "dependencies": {
+ "has-flag": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/uri-js": {
+ "version": "4.4.0",
+ "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.0.tgz",
+ "integrity": "sha512-B0yRTzYdUCCn9n+F4+Gh4yIDtMQcaJsmYBDsTSG8g/OejKBodLQ2IHfN3bM7jUsRXndopT7OIXWdYqc1fjmV6g==",
+ "dev": true,
+ "dependencies": {
+ "punycode": "^2.1.0"
+ }
+ },
+ "node_modules/urix": {
+ "version": "0.1.0",
+ "resolved": "https://registry.npmjs.org/urix/-/urix-0.1.0.tgz",
+ "integrity": "sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI=",
+ "deprecated": "Please see https://github.com/lydell/urix#deprecated",
+ "dev": true
+ },
+ "node_modules/url-parse-lax": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/url-parse-lax/-/url-parse-lax-3.0.0.tgz",
+ "integrity": "sha1-FrXK/Afb42dsGxmZF3gj1lA6yww=",
+ "dev": true,
+ "dependencies": {
+ "prepend-http": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/use": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/use/-/use-3.1.1.tgz",
+ "integrity": "sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ==",
+ "dev": true,
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/util-deprecate": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
+ "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=",
+ "dev": true
+ },
+ "node_modules/v8-compile-cache": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.2.0.tgz",
+ "integrity": "sha512-gTpR5XQNKFwOd4clxfnhaqvfqMpqEwr4tOtCyz4MtYZX2JYhfr1JvBFKdS+7K/9rfpZR3VLX+YWBbKoxCgS43Q==",
+ "dev": true
+ },
+ "node_modules/validate-npm-package-license": {
+ "version": "3.0.4",
+ "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz",
+ "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==",
+ "dev": true,
+ "dependencies": {
+ "spdx-correct": "^3.0.0",
+ "spdx-expression-parse": "^3.0.0"
+ }
+ },
+ "node_modules/walk": {
+ "version": "2.3.14",
+ "resolved": "https://registry.npmjs.org/walk/-/walk-2.3.14.tgz",
+ "integrity": "sha512-5skcWAUmySj6hkBdH6B6+3ddMjVQYH5Qy9QGbPmN8kVmLteXk+yVXg+yfk1nbX30EYakahLrr8iPcCxJQSCBeg==",
+ "dependencies": {
+ "foreachasync": "^3.0.0"
+ }
+ },
+ "node_modules/watchpack": {
+ "version": "2.4.0",
+ "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.4.0.tgz",
+ "integrity": "sha512-Lcvm7MGST/4fup+ifyKi2hjyIAwcdI4HRgtvTpIUxBRhB+RFtUh8XtDOxUfctVCnhVi+QQj49i91OyvzkJl6cg==",
+ "dev": true,
+ "dependencies": {
+ "glob-to-regexp": "^0.4.1",
+ "graceful-fs": "^4.1.2"
+ },
+ "engines": {
+ "node": ">=10.13.0"
+ }
+ },
+ "node_modules/watchpack/node_modules/glob-to-regexp": {
+ "version": "0.4.1",
+ "resolved": "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz",
+ "integrity": "sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==",
+ "dev": true
+ },
+ "node_modules/webpack": {
+ "version": "5.75.0",
+ "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.75.0.tgz",
+ "integrity": "sha512-piaIaoVJlqMsPtX/+3KTTO6jfvrSYgauFVdt8cr9LTHKmcq/AMd4mhzsiP7ZF/PGRNPGA8336jldh9l2Kt2ogQ==",
+ "dev": true,
+ "dependencies": {
+ "@types/eslint-scope": "^3.7.3",
+ "@types/estree": "^0.0.51",
+ "@webassemblyjs/ast": "1.11.1",
+ "@webassemblyjs/wasm-edit": "1.11.1",
+ "@webassemblyjs/wasm-parser": "1.11.1",
+ "acorn": "^8.7.1",
+ "acorn-import-assertions": "^1.7.6",
+ "browserslist": "^4.14.5",
+ "chrome-trace-event": "^1.0.2",
+ "enhanced-resolve": "^5.10.0",
+ "es-module-lexer": "^0.9.0",
+ "eslint-scope": "5.1.1",
+ "events": "^3.2.0",
+ "glob-to-regexp": "^0.4.1",
+ "graceful-fs": "^4.2.9",
+ "json-parse-even-better-errors": "^2.3.1",
+ "loader-runner": "^4.2.0",
+ "mime-types": "^2.1.27",
+ "neo-async": "^2.6.2",
+ "schema-utils": "^3.1.0",
+ "tapable": "^2.1.1",
+ "terser-webpack-plugin": "^5.1.3",
+ "watchpack": "^2.4.0",
+ "webpack-sources": "^3.2.3"
+ },
+ "bin": {
+ "webpack": "bin/webpack.js"
+ },
+ "engines": {
+ "node": ">=10.13.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/webpack"
+ },
+ "peerDependenciesMeta": {
+ "webpack-cli": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/webpack-cli": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/webpack-cli/-/webpack-cli-5.0.1.tgz",
+ "integrity": "sha512-S3KVAyfwUqr0Mo/ur3NzIp6jnerNpo7GUO6so51mxLi1spqsA17YcMXy0WOIJtBSnj748lthxC6XLbNKh/ZC+A==",
+ "dev": true,
+ "dependencies": {
+ "@discoveryjs/json-ext": "^0.5.0",
+ "@webpack-cli/configtest": "^2.0.1",
+ "@webpack-cli/info": "^2.0.1",
+ "@webpack-cli/serve": "^2.0.1",
+ "colorette": "^2.0.14",
+ "commander": "^9.4.1",
+ "cross-spawn": "^7.0.3",
+ "envinfo": "^7.7.3",
+ "fastest-levenshtein": "^1.0.12",
+ "import-local": "^3.0.2",
+ "interpret": "^3.1.1",
+ "rechoir": "^0.8.0",
+ "webpack-merge": "^5.7.3"
+ },
+ "bin": {
+ "webpack-cli": "bin/cli.js"
+ },
+ "engines": {
+ "node": ">=14.15.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/webpack"
+ },
+ "peerDependencies": {
+ "webpack": "5.x.x"
+ },
+ "peerDependenciesMeta": {
+ "@webpack-cli/generators": {
+ "optional": true
+ },
+ "webpack-bundle-analyzer": {
+ "optional": true
+ },
+ "webpack-dev-server": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/webpack-cli/node_modules/commander": {
+ "version": "9.4.1",
+ "resolved": "https://registry.npmjs.org/commander/-/commander-9.4.1.tgz",
+ "integrity": "sha512-5EEkTNyHNGFPD2H+c/dXXfQZYa/scCKasxWcXJaWnNJ99pnQN9Vnmqow+p+PlFPE63Q6mThaZws1T+HxfpgtPw==",
+ "dev": true,
+ "engines": {
+ "node": "^12.20.0 || >=14"
+ }
+ },
+ "node_modules/webpack-cli/node_modules/cross-spawn": {
+ "version": "7.0.3",
+ "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz",
+ "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==",
+ "dev": true,
+ "dependencies": {
+ "path-key": "^3.1.0",
+ "shebang-command": "^2.0.0",
+ "which": "^2.0.1"
+ },
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/webpack-cli/node_modules/path-key": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz",
+ "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/webpack-cli/node_modules/shebang-command": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz",
+ "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==",
+ "dev": true,
+ "dependencies": {
+ "shebang-regex": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/webpack-cli/node_modules/shebang-regex": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz",
+ "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/webpack-cli/node_modules/which": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
+ "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==",
+ "dev": true,
+ "dependencies": {
+ "isexe": "^2.0.0"
+ },
+ "bin": {
+ "node-which": "bin/node-which"
+ },
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/webpack-merge": {
+ "version": "5.8.0",
+ "resolved": "https://registry.npmjs.org/webpack-merge/-/webpack-merge-5.8.0.tgz",
+ "integrity": "sha512-/SaI7xY0831XwP6kzuwhKWVKDP9t1QY1h65lAFLbZqMPIuYcD9QAW4u9STIbU9kaJbPBB/geU/gLr1wDjOhQ+Q==",
+ "dev": true,
+ "dependencies": {
+ "clone-deep": "^4.0.1",
+ "wildcard": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=10.0.0"
+ }
+ },
+ "node_modules/webpack/node_modules/glob-to-regexp": {
+ "version": "0.4.1",
+ "resolved": "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz",
+ "integrity": "sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==",
+ "dev": true
+ },
+ "node_modules/webpack/node_modules/schema-utils": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.1.1.tgz",
+ "integrity": "sha512-Y5PQxS4ITlC+EahLuXaY86TXfR7Dc5lw294alXOq86JAHCihAIZfqv8nNCWvaEJvaC51uN9hbLGeV0cFBdH+Fw==",
+ "dev": true,
+ "dependencies": {
+ "@types/json-schema": "^7.0.8",
+ "ajv": "^6.12.5",
+ "ajv-keywords": "^3.5.2"
+ },
+ "engines": {
+ "node": ">= 10.13.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/webpack"
+ }
+ },
+ "node_modules/webpack/node_modules/webpack-sources": {
+ "version": "3.2.3",
+ "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-3.2.3.tgz",
+ "integrity": "sha512-/DyMEOrDgLKKIG0fmvtz+4dUX/3Ghozwgm6iPp8KRhvn+eQf9+Q7GWxVNMk3+uCPWfdXYC4ExGBckIXdFEfH1w==",
+ "dev": true,
+ "engines": {
+ "node": ">=10.13.0"
+ }
+ },
+ "node_modules/which": {
+ "version": "1.3.1",
+ "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz",
+ "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==",
+ "dev": true,
+ "dependencies": {
+ "isexe": "^2.0.0"
+ },
+ "bin": {
+ "which": "bin/which"
+ }
+ },
+ "node_modules/widest-line": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/widest-line/-/widest-line-3.1.0.tgz",
+ "integrity": "sha512-NsmoXalsWVDMGupxZ5R08ka9flZjjiLvHVAWYOKtiKM8ujtZWr9cRffak+uSE48+Ob8ObalXpwyeUiyDD6QFgg==",
+ "dev": true,
+ "dependencies": {
+ "string-width": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/wildcard": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/wildcard/-/wildcard-2.0.0.tgz",
+ "integrity": "sha512-JcKqAHLPxcdb9KM49dufGXn2x3ssnfjbcaQdLlfZsL9rH9wgDQjUtDxbo8NE0F6SFvydeu1VhZe7hZuHsB2/pw==",
+ "dev": true
+ },
+ "node_modules/word-wrap": {
+ "version": "1.2.3",
+ "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz",
+ "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==",
+ "dev": true,
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/workerpool": {
+ "version": "6.2.0",
+ "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-6.2.0.tgz",
+ "integrity": "sha512-Rsk5qQHJ9eowMH28Jwhe8HEbmdYDX4lwoMWshiCXugjtHqMD9ZbiqSDLxcsfdqsETPzVUtX5s1Z5kStiIM6l4A==",
+ "dev": true
+ },
+ "node_modules/wrappy": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
+ "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=",
+ "dev": true
+ },
+ "node_modules/write": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/write/-/write-1.0.3.tgz",
+ "integrity": "sha512-/lg70HAjtkUgWPVZhZcm+T4hkL8Zbtp1nFNOn3lRrxnlv50SRBv7cR7RqR+GMsd3hUXy9hWBo4CHTbFTcOYwig==",
+ "dev": true,
+ "dependencies": {
+ "mkdirp": "^0.5.1"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/write-file-atomic": {
+ "version": "3.0.3",
+ "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-3.0.3.tgz",
+ "integrity": "sha512-AvHcyZ5JnSfq3ioSyjrBkH9yW4m7Ayk8/9My/DD9onKeu/94fwrMocemO2QAJFAlnnDN+ZDS+ZjAR5ua1/PV/Q==",
+ "dev": true,
+ "dependencies": {
+ "imurmurhash": "^0.1.4",
+ "is-typedarray": "^1.0.0",
+ "signal-exit": "^3.0.2",
+ "typedarray-to-buffer": "^3.1.5"
+ }
+ },
+ "node_modules/xdg-basedir": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/xdg-basedir/-/xdg-basedir-4.0.0.tgz",
+ "integrity": "sha512-PSNhEJDejZYV7h50BohL09Er9VaIefr2LMAf3OEmpCkjOi34eYyQYAXUTjEQtZJTKcF0E2UKTh+osDLsgNim9Q==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/xo": {
+ "version": "0.26.1",
+ "resolved": "https://registry.npmjs.org/xo/-/xo-0.26.1.tgz",
+ "integrity": "sha512-m2h2NrFoprrB8jsCvZFx5Wn3uLwd9k4mTo4bA+ZzXOv3fCOMMW8sA2C+qCCNTuEdRarYRtO068+cerM8ZnBiCQ==",
+ "dev": true,
+ "dependencies": {
+ "arrify": "^2.0.1",
+ "debug": "^4.1.0",
+ "eslint": "^6.8.0",
+ "eslint-config-prettier": "^6.10.0",
+ "eslint-config-xo": "^0.29.0",
+ "eslint-formatter-pretty": "^3.0.1",
+ "eslint-plugin-ava": "^10.0.1",
+ "eslint-plugin-eslint-comments": "^3.1.2",
+ "eslint-plugin-import": "^2.20.1",
+ "eslint-plugin-no-use-extend-native": "^0.4.1",
+ "eslint-plugin-node": "^11.0.0",
+ "eslint-plugin-prettier": "^3.1.2",
+ "eslint-plugin-promise": "^4.2.1",
+ "eslint-plugin-unicorn": "^16.1.1",
+ "find-cache-dir": "^3.0.0",
+ "get-stdin": "^7.0.0",
+ "globby": "^9.0.0",
+ "has-flag": "^4.0.0",
+ "lodash": "^4.17.15",
+ "meow": "^5.0.0",
+ "multimatch": "^4.0.0",
+ "open-editor": "^2.0.1",
+ "path-exists": "^4.0.0",
+ "pkg-conf": "^3.1.0",
+ "prettier": "^1.15.2",
+ "resolve-cwd": "^3.0.0",
+ "resolve-from": "^5.0.0",
+ "semver": "^7.1.3",
+ "slash": "^3.0.0",
+ "update-notifier": "^4.0.0"
+ },
+ "bin": {
+ "xo": "cli.js"
+ },
+ "engines": {
+ "node": ">=10.18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/xo/node_modules/has-flag": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
+ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/xo/node_modules/path-exists": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz",
+ "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/xo/node_modules/semver": {
+ "version": "7.3.2",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.2.tgz",
+ "integrity": "sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ==",
+ "dev": true,
+ "bin": {
+ "semver": "bin/semver.js"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/xtend": {
+ "version": "4.0.2",
+ "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz",
+ "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==",
+ "dev": true,
+ "engines": {
+ "node": ">=0.4"
+ }
+ },
+ "node_modules/yargs-unparser": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-2.0.0.tgz",
+ "integrity": "sha512-7pRTIA9Qc1caZ0bZ6RYRGbHJthJWuakf+WmHK0rVeLkNrrGhfoabBNdue6kdINI6r4if7ocq9aD/n7xwKOdzOA==",
+ "dev": true,
+ "dependencies": {
+ "camelcase": "^6.0.0",
+ "decamelize": "^4.0.0",
+ "flat": "^5.0.2",
+ "is-plain-obj": "^2.1.0"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/yargs-unparser/node_modules/camelcase": {
+ "version": "6.3.0",
+ "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz",
+ "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==",
+ "dev": true,
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/yargs-unparser/node_modules/decamelize": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-4.0.0.tgz",
+ "integrity": "sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ==",
+ "dev": true,
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/yargs-unparser/node_modules/is-plain-obj": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-2.1.0.tgz",
+ "integrity": "sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/yocto-queue": {
+ "version": "0.1.0",
+ "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz",
+ "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==",
+ "dev": true,
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ }
+ },
+ "dependencies": {
+ "@babel/code-frame": {
+ "version": "7.10.4",
+ "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.10.4.tgz",
+ "integrity": "sha512-vG6SvB6oYEhvgisZNFRmRCUkLz11c7rp+tbNTynGqc6mS1d5ATd/sGyV6W0KZZnXRKMTzZDRgQT3Ou9jhpAfUg==",
+ "dev": true,
+ "requires": {
+ "@babel/highlight": "^7.10.4"
+ }
+ },
+ "@babel/compat-data": {
+ "version": "7.12.5",
+ "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.12.5.tgz",
+ "integrity": "sha512-DTsS7cxrsH3by8nqQSpFSyjSfSYl57D6Cf4q8dW3LK83tBKBDCkfcay1nYkXq1nIHXnpX8WMMb/O25HOy3h1zg==",
+ "dev": true
+ },
+ "@babel/core": {
+ "version": "7.12.3",
+ "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.12.3.tgz",
+ "integrity": "sha512-0qXcZYKZp3/6N2jKYVxZv0aNCsxTSVCiK72DTiTYZAu7sjg73W0/aynWjMbiGd87EQL4WyA8reiJVh92AVla9g==",
+ "dev": true,
+ "requires": {
+ "@babel/code-frame": "^7.10.4",
+ "@babel/generator": "^7.12.1",
+ "@babel/helper-module-transforms": "^7.12.1",
+ "@babel/helpers": "^7.12.1",
+ "@babel/parser": "^7.12.3",
+ "@babel/template": "^7.10.4",
+ "@babel/traverse": "^7.12.1",
+ "@babel/types": "^7.12.1",
+ "convert-source-map": "^1.7.0",
+ "debug": "^4.1.0",
+ "gensync": "^1.0.0-beta.1",
+ "json5": "^2.1.2",
+ "lodash": "^4.17.19",
+ "resolve": "^1.3.2",
+ "semver": "^5.4.1",
+ "source-map": "^0.5.0"
+ }
+ },
+ "@babel/generator": {
+ "version": "7.12.5",
+ "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.12.5.tgz",
+ "integrity": "sha512-m16TQQJ8hPt7E+OS/XVQg/7U184MLXtvuGbCdA7na61vha+ImkyyNM/9DDA0unYCVZn3ZOhng+qz48/KBOT96A==",
+ "dev": true,
+ "requires": {
+ "@babel/types": "^7.12.5",
+ "jsesc": "^2.5.1",
+ "source-map": "^0.5.0"
+ }
+ },
+ "@babel/helper-annotate-as-pure": {
+ "version": "7.10.4",
+ "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.10.4.tgz",
+ "integrity": "sha512-XQlqKQP4vXFB7BN8fEEerrmYvHp3fK/rBkRFz9jaJbzK0B1DSfej9Kc7ZzE8Z/OnId1jpJdNAZ3BFQjWG68rcA==",
+ "dev": true,
+ "requires": {
+ "@babel/types": "^7.10.4"
+ }
+ },
+ "@babel/helper-builder-binary-assignment-operator-visitor": {
+ "version": "7.10.4",
+ "resolved": "https://registry.npmjs.org/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.10.4.tgz",
+ "integrity": "sha512-L0zGlFrGWZK4PbT8AszSfLTM5sDU1+Az/En9VrdT8/LmEiJt4zXt+Jve9DCAnQcbqDhCI+29y/L93mrDzddCcg==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-explode-assignable-expression": "^7.10.4",
+ "@babel/types": "^7.10.4"
+ }
+ },
+ "@babel/helper-compilation-targets": {
+ "version": "7.12.5",
+ "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.12.5.tgz",
+ "integrity": "sha512-+qH6NrscMolUlzOYngSBMIOQpKUGPPsc61Bu5W10mg84LxZ7cmvnBHzARKbDoFxVvqqAbj6Tg6N7bSrWSPXMyw==",
+ "dev": true,
+ "requires": {
+ "@babel/compat-data": "^7.12.5",
+ "@babel/helper-validator-option": "^7.12.1",
+ "browserslist": "^4.14.5",
+ "semver": "^5.5.0"
+ }
+ },
+ "@babel/helper-create-class-features-plugin": {
+ "version": "7.12.1",
+ "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.12.1.tgz",
+ "integrity": "sha512-hkL++rWeta/OVOBTRJc9a5Azh5mt5WgZUGAKMD8JM141YsE08K//bp1unBBieO6rUKkIPyUE0USQ30jAy3Sk1w==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-function-name": "^7.10.4",
+ "@babel/helper-member-expression-to-functions": "^7.12.1",
+ "@babel/helper-optimise-call-expression": "^7.10.4",
+ "@babel/helper-replace-supers": "^7.12.1",
+ "@babel/helper-split-export-declaration": "^7.10.4"
+ }
+ },
+ "@babel/helper-create-regexp-features-plugin": {
+ "version": "7.12.1",
+ "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.12.1.tgz",
+ "integrity": "sha512-rsZ4LGvFTZnzdNZR5HZdmJVuXK8834R5QkF3WvcnBhrlVtF0HSIUC6zbreL9MgjTywhKokn8RIYRiq99+DLAxA==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-annotate-as-pure": "^7.10.4",
+ "@babel/helper-regex": "^7.10.4",
+ "regexpu-core": "^4.7.1"
+ }
+ },
+ "@babel/helper-define-map": {
+ "version": "7.10.5",
+ "resolved": "https://registry.npmjs.org/@babel/helper-define-map/-/helper-define-map-7.10.5.tgz",
+ "integrity": "sha512-fMw4kgFB720aQFXSVaXr79pjjcW5puTCM16+rECJ/plGS+zByelE8l9nCpV1GibxTnFVmUuYG9U8wYfQHdzOEQ==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-function-name": "^7.10.4",
+ "@babel/types": "^7.10.5",
+ "lodash": "^4.17.19"
+ }
+ },
+ "@babel/helper-environment-visitor": {
+ "version": "7.22.20",
+ "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.22.20.tgz",
+ "integrity": "sha512-zfedSIzFhat/gFhWfHtgWvlec0nqB9YEIVrpuwjruLlXfUSnA8cJB0miHKwqDnQ7d32aKo2xt88/xZptwxbfhA==",
+ "dev": true
+ },
+ "@babel/helper-explode-assignable-expression": {
+ "version": "7.12.1",
+ "resolved": "https://registry.npmjs.org/@babel/helper-explode-assignable-expression/-/helper-explode-assignable-expression-7.12.1.tgz",
+ "integrity": "sha512-dmUwH8XmlrUpVqgtZ737tK88v07l840z9j3OEhCLwKTkjlvKpfqXVIZ0wpK3aeOxspwGrf/5AP5qLx4rO3w5rA==",
+ "dev": true,
+ "requires": {
+ "@babel/types": "^7.12.1"
+ }
+ },
+ "@babel/helper-function-name": {
+ "version": "7.10.4",
+ "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.10.4.tgz",
+ "integrity": "sha512-YdaSyz1n8gY44EmN7x44zBn9zQ1Ry2Y+3GTA+3vH6Mizke1Vw0aWDM66FOYEPw8//qKkmqOckrGgTYa+6sceqQ==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-get-function-arity": "^7.10.4",
+ "@babel/template": "^7.10.4",
+ "@babel/types": "^7.10.4"
+ }
+ },
+ "@babel/helper-get-function-arity": {
+ "version": "7.10.4",
+ "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.10.4.tgz",
+ "integrity": "sha512-EkN3YDB+SRDgiIUnNgcmiD361ti+AVbL3f3Henf6dqqUyr5dMsorno0lJWJuLhDhkI5sYEpgj6y9kB8AOU1I2A==",
+ "dev": true,
+ "requires": {
+ "@babel/types": "^7.10.4"
+ }
+ },
+ "@babel/helper-hoist-variables": {
+ "version": "7.10.4",
+ "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.10.4.tgz",
+ "integrity": "sha512-wljroF5PgCk2juF69kanHVs6vrLwIPNp6DLD+Lrl3hoQ3PpPPikaDRNFA+0t81NOoMt2DL6WW/mdU8k4k6ZzuA==",
+ "dev": true,
+ "requires": {
+ "@babel/types": "^7.10.4"
+ }
+ },
+ "@babel/helper-member-expression-to-functions": {
+ "version": "7.12.1",
+ "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.12.1.tgz",
+ "integrity": "sha512-k0CIe3tXUKTRSoEx1LQEPFU9vRQfqHtl+kf8eNnDqb4AUJEy5pz6aIiog+YWtVm2jpggjS1laH68bPsR+KWWPQ==",
+ "dev": true,
+ "requires": {
+ "@babel/types": "^7.12.1"
+ }
+ },
+ "@babel/helper-module-imports": {
+ "version": "7.12.5",
+ "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.12.5.tgz",
+ "integrity": "sha512-SR713Ogqg6++uexFRORf/+nPXMmWIn80TALu0uaFb+iQIUoR7bOC7zBWyzBs5b3tBBJXuyD0cRu1F15GyzjOWA==",
+ "dev": true,
+ "requires": {
+ "@babel/types": "^7.12.5"
+ }
+ },
+ "@babel/helper-module-transforms": {
+ "version": "7.12.1",
+ "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.12.1.tgz",
+ "integrity": "sha512-QQzehgFAZ2bbISiCpmVGfiGux8YVFXQ0abBic2Envhej22DVXV9nCFaS5hIQbkyo1AdGb+gNME2TSh3hYJVV/w==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-module-imports": "^7.12.1",
+ "@babel/helper-replace-supers": "^7.12.1",
+ "@babel/helper-simple-access": "^7.12.1",
+ "@babel/helper-split-export-declaration": "^7.11.0",
+ "@babel/helper-validator-identifier": "^7.10.4",
+ "@babel/template": "^7.10.4",
+ "@babel/traverse": "^7.12.1",
+ "@babel/types": "^7.12.1",
+ "lodash": "^4.17.19"
+ }
+ },
+ "@babel/helper-optimise-call-expression": {
+ "version": "7.10.4",
+ "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.10.4.tgz",
+ "integrity": "sha512-n3UGKY4VXwXThEiKrgRAoVPBMqeoPgHVqiHZOanAJCG9nQUL2pLRQirUzl0ioKclHGpGqRgIOkgcIJaIWLpygg==",
+ "dev": true,
+ "requires": {
+ "@babel/types": "^7.10.4"
+ }
+ },
+ "@babel/helper-plugin-utils": {
+ "version": "7.10.4",
+ "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.10.4.tgz",
+ "integrity": "sha512-O4KCvQA6lLiMU9l2eawBPMf1xPP8xPfB3iEQw150hOVTqj/rfXz0ThTb4HEzqQfs2Bmo5Ay8BzxfzVtBrr9dVg==",
+ "dev": true
+ },
+ "@babel/helper-regex": {
+ "version": "7.10.5",
+ "resolved": "https://registry.npmjs.org/@babel/helper-regex/-/helper-regex-7.10.5.tgz",
+ "integrity": "sha512-68kdUAzDrljqBrio7DYAEgCoJHxppJOERHOgOrDN7WjOzP0ZQ1LsSDRXcemzVZaLvjaJsJEESb6qt+znNuENDg==",
+ "dev": true,
+ "requires": {
+ "lodash": "^4.17.19"
+ }
+ },
+ "@babel/helper-remap-async-to-generator": {
+ "version": "7.12.1",
+ "resolved": "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.12.1.tgz",
+ "integrity": "sha512-9d0KQCRM8clMPcDwo8SevNs+/9a8yWVVmaE80FGJcEP8N1qToREmWEGnBn8BUlJhYRFz6fqxeRL1sl5Ogsed7A==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-annotate-as-pure": "^7.10.4",
+ "@babel/helper-wrap-function": "^7.10.4",
+ "@babel/types": "^7.12.1"
+ }
+ },
+ "@babel/helper-replace-supers": {
+ "version": "7.12.5",
+ "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.12.5.tgz",
+ "integrity": "sha512-5YILoed0ZyIpF4gKcpZitEnXEJ9UoDRki1Ey6xz46rxOzfNMAhVIJMoune1hmPVxh40LRv1+oafz7UsWX+vyWA==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-member-expression-to-functions": "^7.12.1",
+ "@babel/helper-optimise-call-expression": "^7.10.4",
+ "@babel/traverse": "^7.12.5",
+ "@babel/types": "^7.12.5"
+ }
+ },
+ "@babel/helper-simple-access": {
+ "version": "7.12.1",
+ "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.12.1.tgz",
+ "integrity": "sha512-OxBp7pMrjVewSSC8fXDFrHrBcJATOOFssZwv16F3/6Xtc138GHybBfPbm9kfiqQHKhYQrlamWILwlDCeyMFEaA==",
+ "dev": true,
+ "requires": {
+ "@babel/types": "^7.12.1"
+ }
+ },
+ "@babel/helper-skip-transparent-expression-wrappers": {
+ "version": "7.12.1",
+ "resolved": "https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.12.1.tgz",
+ "integrity": "sha512-Mf5AUuhG1/OCChOJ/HcADmvcHM42WJockombn8ATJG3OnyiSxBK/Mm5x78BQWvmtXZKHgbjdGL2kin/HOLlZGA==",
+ "dev": true,
+ "requires": {
+ "@babel/types": "^7.12.1"
+ }
+ },
+ "@babel/helper-split-export-declaration": {
+ "version": "7.11.0",
+ "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.11.0.tgz",
+ "integrity": "sha512-74Vejvp6mHkGE+m+k5vHY93FX2cAtrw1zXrZXRlG4l410Nm9PxfEiVTn1PjDPV5SnmieiueY4AFg2xqhNFuuZg==",
+ "dev": true,
+ "requires": {
+ "@babel/types": "^7.11.0"
+ }
+ },
+ "@babel/helper-string-parser": {
+ "version": "7.22.5",
+ "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.22.5.tgz",
+ "integrity": "sha512-mM4COjgZox8U+JcXQwPijIZLElkgEpO5rsERVDJTc2qfCDfERyob6k5WegS14SX18IIjv+XD+GrqNumY5JRCDw==",
+ "dev": true
+ },
+ "@babel/helper-validator-identifier": {
+ "version": "7.10.4",
+ "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.10.4.tgz",
+ "integrity": "sha512-3U9y+43hz7ZM+rzG24Qe2mufW5KhvFg/NhnNph+i9mgCtdTCtMJuI1TMkrIUiK7Ix4PYlRF9I5dhqaLYA/ADXw==",
+ "dev": true
+ },
+ "@babel/helper-validator-option": {
+ "version": "7.12.1",
+ "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.12.1.tgz",
+ "integrity": "sha512-YpJabsXlJVWP0USHjnC/AQDTLlZERbON577YUVO/wLpqyj6HAtVYnWaQaN0iUN+1/tWn3c+uKKXjRut5115Y2A==",
+ "dev": true
+ },
+ "@babel/helper-wrap-function": {
+ "version": "7.12.3",
+ "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.12.3.tgz",
+ "integrity": "sha512-Cvb8IuJDln3rs6tzjW3Y8UeelAOdnpB8xtQ4sme2MSZ9wOxrbThporC0y/EtE16VAtoyEfLM404Xr1e0OOp+ow==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-function-name": "^7.10.4",
+ "@babel/template": "^7.10.4",
+ "@babel/traverse": "^7.10.4",
+ "@babel/types": "^7.10.4"
+ }
+ },
+ "@babel/helpers": {
+ "version": "7.12.5",
+ "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.12.5.tgz",
+ "integrity": "sha512-lgKGMQlKqA8meJqKsW6rUnc4MdUk35Ln0ATDqdM1a/UpARODdI4j5Y5lVfUScnSNkJcdCRAaWkspykNoFg9sJA==",
+ "dev": true,
+ "requires": {
+ "@babel/template": "^7.10.4",
+ "@babel/traverse": "^7.12.5",
+ "@babel/types": "^7.12.5"
+ }
+ },
+ "@babel/highlight": {
+ "version": "7.10.4",
+ "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.10.4.tgz",
+ "integrity": "sha512-i6rgnR/YgPEQzZZnbTHHuZdlE8qyoBNalD6F+q4vAFlcMEcqmkoG+mPqJYJCo63qPf74+Y1UZsl3l6f7/RIkmA==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-validator-identifier": "^7.10.4",
+ "chalk": "^2.0.0",
+ "js-tokens": "^4.0.0"
+ }
+ },
+ "@babel/parser": {
+ "version": "7.12.5",
+ "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.12.5.tgz",
+ "integrity": "sha512-FVM6RZQ0mn2KCf1VUED7KepYeUWoVShczewOCfm3nzoBybaih51h+sYVVGthW9M6lPByEPTQf+xm27PBdlpwmQ==",
+ "dev": true
+ },
+ "@babel/plugin-proposal-async-generator-functions": {
+ "version": "7.12.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.12.1.tgz",
+ "integrity": "sha512-d+/o30tJxFxrA1lhzJqiUcEJdI6jKlNregCv5bASeGf2Q4MXmnwH7viDo7nhx1/ohf09oaH8j1GVYG/e3Yqk6A==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-plugin-utils": "^7.10.4",
+ "@babel/helper-remap-async-to-generator": "^7.12.1",
+ "@babel/plugin-syntax-async-generators": "^7.8.0"
+ }
+ },
+ "@babel/plugin-proposal-class-properties": {
+ "version": "7.12.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.12.1.tgz",
+ "integrity": "sha512-cKp3dlQsFsEs5CWKnN7BnSHOd0EOW8EKpEjkoz1pO2E5KzIDNV9Ros1b0CnmbVgAGXJubOYVBOGCT1OmJwOI7w==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-create-class-features-plugin": "^7.12.1",
+ "@babel/helper-plugin-utils": "^7.10.4"
+ }
+ },
+ "@babel/plugin-proposal-dynamic-import": {
+ "version": "7.12.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-dynamic-import/-/plugin-proposal-dynamic-import-7.12.1.tgz",
+ "integrity": "sha512-a4rhUSZFuq5W8/OO8H7BL5zspjnc1FLd9hlOxIK/f7qG4a0qsqk8uvF/ywgBA8/OmjsapjpvaEOYItfGG1qIvQ==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-plugin-utils": "^7.10.4",
+ "@babel/plugin-syntax-dynamic-import": "^7.8.0"
+ }
+ },
+ "@babel/plugin-proposal-export-namespace-from": {
+ "version": "7.12.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-export-namespace-from/-/plugin-proposal-export-namespace-from-7.12.1.tgz",
+ "integrity": "sha512-6CThGf0irEkzujYS5LQcjBx8j/4aQGiVv7J9+2f7pGfxqyKh3WnmVJYW3hdrQjyksErMGBPQrCnHfOtna+WLbw==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-plugin-utils": "^7.10.4",
+ "@babel/plugin-syntax-export-namespace-from": "^7.8.3"
+ }
+ },
+ "@babel/plugin-proposal-json-strings": {
+ "version": "7.12.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-json-strings/-/plugin-proposal-json-strings-7.12.1.tgz",
+ "integrity": "sha512-GoLDUi6U9ZLzlSda2Df++VSqDJg3CG+dR0+iWsv6XRw1rEq+zwt4DirM9yrxW6XWaTpmai1cWJLMfM8qQJf+yw==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-plugin-utils": "^7.10.4",
+ "@babel/plugin-syntax-json-strings": "^7.8.0"
+ }
+ },
+ "@babel/plugin-proposal-logical-assignment-operators": {
+ "version": "7.12.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-logical-assignment-operators/-/plugin-proposal-logical-assignment-operators-7.12.1.tgz",
+ "integrity": "sha512-k8ZmVv0JU+4gcUGeCDZOGd0lCIamU/sMtIiX3UWnUc5yzgq6YUGyEolNYD+MLYKfSzgECPcqetVcJP9Afe/aCA==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-plugin-utils": "^7.10.4",
+ "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4"
+ }
+ },
+ "@babel/plugin-proposal-nullish-coalescing-operator": {
+ "version": "7.12.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-nullish-coalescing-operator/-/plugin-proposal-nullish-coalescing-operator-7.12.1.tgz",
+ "integrity": "sha512-nZY0ESiaQDI1y96+jk6VxMOaL4LPo/QDHBqL+SF3/vl6dHkTwHlOI8L4ZwuRBHgakRBw5zsVylel7QPbbGuYgg==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-plugin-utils": "^7.10.4",
+ "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.0"
+ }
+ },
+ "@babel/plugin-proposal-numeric-separator": {
+ "version": "7.12.5",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-numeric-separator/-/plugin-proposal-numeric-separator-7.12.5.tgz",
+ "integrity": "sha512-UiAnkKuOrCyjZ3sYNHlRlfuZJbBHknMQ9VMwVeX97Ofwx7RpD6gS2HfqTCh8KNUQgcOm8IKt103oR4KIjh7Q8g==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-plugin-utils": "^7.10.4",
+ "@babel/plugin-syntax-numeric-separator": "^7.10.4"
+ }
+ },
+ "@babel/plugin-proposal-object-rest-spread": {
+ "version": "7.12.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.12.1.tgz",
+ "integrity": "sha512-s6SowJIjzlhx8o7lsFx5zmY4At6CTtDvgNQDdPzkBQucle58A6b/TTeEBYtyDgmcXjUTM+vE8YOGHZzzbc/ioA==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-plugin-utils": "^7.10.4",
+ "@babel/plugin-syntax-object-rest-spread": "^7.8.0",
+ "@babel/plugin-transform-parameters": "^7.12.1"
+ }
+ },
+ "@babel/plugin-proposal-optional-catch-binding": {
+ "version": "7.12.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-catch-binding/-/plugin-proposal-optional-catch-binding-7.12.1.tgz",
+ "integrity": "sha512-hFvIjgprh9mMw5v42sJWLI1lzU5L2sznP805zeT6rySVRA0Y18StRhDqhSxlap0oVgItRsB6WSROp4YnJTJz0g==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-plugin-utils": "^7.10.4",
+ "@babel/plugin-syntax-optional-catch-binding": "^7.8.0"
+ }
+ },
+ "@babel/plugin-proposal-optional-chaining": {
+ "version": "7.12.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.12.1.tgz",
+ "integrity": "sha512-c2uRpY6WzaVDzynVY9liyykS+kVU+WRZPMPYpkelXH8KBt1oXoI89kPbZKKG/jDT5UK92FTW2fZkZaJhdiBabw==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-plugin-utils": "^7.10.4",
+ "@babel/helper-skip-transparent-expression-wrappers": "^7.12.1",
+ "@babel/plugin-syntax-optional-chaining": "^7.8.0"
+ }
+ },
+ "@babel/plugin-proposal-private-methods": {
+ "version": "7.12.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-methods/-/plugin-proposal-private-methods-7.12.1.tgz",
+ "integrity": "sha512-mwZ1phvH7/NHK6Kf8LP7MYDogGV+DKB1mryFOEwx5EBNQrosvIczzZFTUmWaeujd5xT6G1ELYWUz3CutMhjE1w==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-create-class-features-plugin": "^7.12.1",
+ "@babel/helper-plugin-utils": "^7.10.4"
+ }
+ },
+ "@babel/plugin-proposal-unicode-property-regex": {
+ "version": "7.12.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-unicode-property-regex/-/plugin-proposal-unicode-property-regex-7.12.1.tgz",
+ "integrity": "sha512-MYq+l+PvHuw/rKUz1at/vb6nCnQ2gmJBNaM62z0OgH7B2W1D9pvkpYtlti9bGtizNIU1K3zm4bZF9F91efVY0w==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-create-regexp-features-plugin": "^7.12.1",
+ "@babel/helper-plugin-utils": "^7.10.4"
+ }
+ },
+ "@babel/plugin-syntax-async-generators": {
+ "version": "7.8.4",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz",
+ "integrity": "sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-plugin-utils": "^7.8.0"
+ }
+ },
+ "@babel/plugin-syntax-class-properties": {
+ "version": "7.12.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.1.tgz",
+ "integrity": "sha512-U40A76x5gTwmESz+qiqssqmeEsKvcSyvtgktrm0uzcARAmM9I1jR221f6Oq+GmHrcD+LvZDag1UTOTe2fL3TeA==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-plugin-utils": "^7.10.4"
+ }
+ },
+ "@babel/plugin-syntax-dynamic-import": {
+ "version": "7.8.3",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-dynamic-import/-/plugin-syntax-dynamic-import-7.8.3.tgz",
+ "integrity": "sha512-5gdGbFon+PszYzqs83S3E5mpi7/y/8M9eC90MRTZfduQOYW76ig6SOSPNe41IG5LoP3FGBn2N0RjVDSQiS94kQ==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-plugin-utils": "^7.8.0"
+ }
+ },
+ "@babel/plugin-syntax-export-namespace-from": {
+ "version": "7.8.3",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-export-namespace-from/-/plugin-syntax-export-namespace-from-7.8.3.tgz",
+ "integrity": "sha512-MXf5laXo6c1IbEbegDmzGPwGNTsHZmEy6QGznu5Sh2UCWvueywb2ee+CCE4zQiZstxU9BMoQO9i6zUFSY0Kj0Q==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-plugin-utils": "^7.8.3"
+ }
+ },
+ "@babel/plugin-syntax-json-strings": {
+ "version": "7.8.3",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz",
+ "integrity": "sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-plugin-utils": "^7.8.0"
+ }
+ },
+ "@babel/plugin-syntax-logical-assignment-operators": {
+ "version": "7.10.4",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz",
+ "integrity": "sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-plugin-utils": "^7.10.4"
+ }
+ },
+ "@babel/plugin-syntax-nullish-coalescing-operator": {
+ "version": "7.8.3",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz",
+ "integrity": "sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-plugin-utils": "^7.8.0"
+ }
+ },
+ "@babel/plugin-syntax-numeric-separator": {
+ "version": "7.10.4",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.10.4.tgz",
+ "integrity": "sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-plugin-utils": "^7.10.4"
+ }
+ },
+ "@babel/plugin-syntax-object-rest-spread": {
+ "version": "7.8.3",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz",
+ "integrity": "sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-plugin-utils": "^7.8.0"
+ }
+ },
+ "@babel/plugin-syntax-optional-catch-binding": {
+ "version": "7.8.3",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz",
+ "integrity": "sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-plugin-utils": "^7.8.0"
+ }
+ },
+ "@babel/plugin-syntax-optional-chaining": {
+ "version": "7.8.3",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.8.3.tgz",
+ "integrity": "sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-plugin-utils": "^7.8.0"
+ }
+ },
+ "@babel/plugin-syntax-top-level-await": {
+ "version": "7.12.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.12.1.tgz",
+ "integrity": "sha512-i7ooMZFS+a/Om0crxZodrTzNEPJHZrlMVGMTEpFAj6rYY/bKCddB0Dk/YxfPuYXOopuhKk/e1jV6h+WUU9XN3A==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-plugin-utils": "^7.10.4"
+ }
+ },
+ "@babel/plugin-transform-arrow-functions": {
+ "version": "7.12.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.12.1.tgz",
+ "integrity": "sha512-5QB50qyN44fzzz4/qxDPQMBCTHgxg3n0xRBLJUmBlLoU/sFvxVWGZF/ZUfMVDQuJUKXaBhbupxIzIfZ6Fwk/0A==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-plugin-utils": "^7.10.4"
+ }
+ },
+ "@babel/plugin-transform-async-to-generator": {
+ "version": "7.12.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.12.1.tgz",
+ "integrity": "sha512-SDtqoEcarK1DFlRJ1hHRY5HvJUj5kX4qmtpMAm2QnhOlyuMC4TMdCRgW6WXpv93rZeYNeLP22y8Aq2dbcDRM1A==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-module-imports": "^7.12.1",
+ "@babel/helper-plugin-utils": "^7.10.4",
+ "@babel/helper-remap-async-to-generator": "^7.12.1"
+ }
+ },
+ "@babel/plugin-transform-block-scoped-functions": {
+ "version": "7.12.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.12.1.tgz",
+ "integrity": "sha512-5OpxfuYnSgPalRpo8EWGPzIYf0lHBWORCkj5M0oLBwHdlux9Ri36QqGW3/LR13RSVOAoUUMzoPI/jpE4ABcHoA==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-plugin-utils": "^7.10.4"
+ }
+ },
+ "@babel/plugin-transform-block-scoping": {
+ "version": "7.12.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.12.1.tgz",
+ "integrity": "sha512-zJyAC9sZdE60r1nVQHblcfCj29Dh2Y0DOvlMkcqSo0ckqjiCwNiUezUKw+RjOCwGfpLRwnAeQ2XlLpsnGkvv9w==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-plugin-utils": "^7.10.4"
+ }
+ },
+ "@babel/plugin-transform-classes": {
+ "version": "7.12.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.12.1.tgz",
+ "integrity": "sha512-/74xkA7bVdzQTBeSUhLLJgYIcxw/dpEpCdRDiHgPJ3Mv6uC11UhjpOhl72CgqbBCmt1qtssCyB2xnJm1+PFjog==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-annotate-as-pure": "^7.10.4",
+ "@babel/helper-define-map": "^7.10.4",
+ "@babel/helper-function-name": "^7.10.4",
+ "@babel/helper-optimise-call-expression": "^7.10.4",
+ "@babel/helper-plugin-utils": "^7.10.4",
+ "@babel/helper-replace-supers": "^7.12.1",
+ "@babel/helper-split-export-declaration": "^7.10.4",
+ "globals": "^11.1.0"
+ }
+ },
+ "@babel/plugin-transform-computed-properties": {
+ "version": "7.12.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.12.1.tgz",
+ "integrity": "sha512-vVUOYpPWB7BkgUWPo4C44mUQHpTZXakEqFjbv8rQMg7TC6S6ZhGZ3otQcRH6u7+adSlE5i0sp63eMC/XGffrzg==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-plugin-utils": "^7.10.4"
+ }
+ },
+ "@babel/plugin-transform-destructuring": {
+ "version": "7.12.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.12.1.tgz",
+ "integrity": "sha512-fRMYFKuzi/rSiYb2uRLiUENJOKq4Gnl+6qOv5f8z0TZXg3llUwUhsNNwrwaT/6dUhJTzNpBr+CUvEWBtfNY1cw==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-plugin-utils": "^7.10.4"
+ }
+ },
+ "@babel/plugin-transform-dotall-regex": {
+ "version": "7.12.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.12.1.tgz",
+ "integrity": "sha512-B2pXeRKoLszfEW7J4Hg9LoFaWEbr/kzo3teWHmtFCszjRNa/b40f9mfeqZsIDLLt/FjwQ6pz/Gdlwy85xNckBA==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-create-regexp-features-plugin": "^7.12.1",
+ "@babel/helper-plugin-utils": "^7.10.4"
+ }
+ },
+ "@babel/plugin-transform-duplicate-keys": {
+ "version": "7.12.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.12.1.tgz",
+ "integrity": "sha512-iRght0T0HztAb/CazveUpUQrZY+aGKKaWXMJ4uf9YJtqxSUe09j3wteztCUDRHs+SRAL7yMuFqUsLoAKKzgXjw==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-plugin-utils": "^7.10.4"
+ }
+ },
+ "@babel/plugin-transform-exponentiation-operator": {
+ "version": "7.12.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.12.1.tgz",
+ "integrity": "sha512-7tqwy2bv48q+c1EHbXK0Zx3KXd2RVQp6OC7PbwFNt/dPTAV3Lu5sWtWuAj8owr5wqtWnqHfl2/mJlUmqkChKug==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-builder-binary-assignment-operator-visitor": "^7.10.4",
+ "@babel/helper-plugin-utils": "^7.10.4"
+ }
+ },
+ "@babel/plugin-transform-for-of": {
+ "version": "7.12.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.12.1.tgz",
+ "integrity": "sha512-Zaeq10naAsuHo7heQvyV0ptj4dlZJwZgNAtBYBnu5nNKJoW62m0zKcIEyVECrUKErkUkg6ajMy4ZfnVZciSBhg==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-plugin-utils": "^7.10.4"
+ }
+ },
+ "@babel/plugin-transform-function-name": {
+ "version": "7.12.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.12.1.tgz",
+ "integrity": "sha512-JF3UgJUILoFrFMEnOJLJkRHSk6LUSXLmEFsA23aR2O5CSLUxbeUX1IZ1YQ7Sn0aXb601Ncwjx73a+FVqgcljVw==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-function-name": "^7.10.4",
+ "@babel/helper-plugin-utils": "^7.10.4"
+ }
+ },
+ "@babel/plugin-transform-literals": {
+ "version": "7.12.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.12.1.tgz",
+ "integrity": "sha512-+PxVGA+2Ag6uGgL0A5f+9rklOnnMccwEBzwYFL3EUaKuiyVnUipyXncFcfjSkbimLrODoqki1U9XxZzTvfN7IQ==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-plugin-utils": "^7.10.4"
+ }
+ },
+ "@babel/plugin-transform-member-expression-literals": {
+ "version": "7.12.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.12.1.tgz",
+ "integrity": "sha512-1sxePl6z9ad0gFMB9KqmYofk34flq62aqMt9NqliS/7hPEpURUCMbyHXrMPlo282iY7nAvUB1aQd5mg79UD9Jg==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-plugin-utils": "^7.10.4"
+ }
+ },
+ "@babel/plugin-transform-modules-amd": {
+ "version": "7.12.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.12.1.tgz",
+ "integrity": "sha512-tDW8hMkzad5oDtzsB70HIQQRBiTKrhfgwC/KkJeGsaNFTdWhKNt/BiE8c5yj19XiGyrxpbkOfH87qkNg1YGlOQ==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-module-transforms": "^7.12.1",
+ "@babel/helper-plugin-utils": "^7.10.4",
+ "babel-plugin-dynamic-import-node": "^2.3.3"
+ }
+ },
+ "@babel/plugin-transform-modules-commonjs": {
+ "version": "7.12.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.12.1.tgz",
+ "integrity": "sha512-dY789wq6l0uLY8py9c1B48V8mVL5gZh/+PQ5ZPrylPYsnAvnEMjqsUXkuoDVPeVK+0VyGar+D08107LzDQ6pag==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-module-transforms": "^7.12.1",
+ "@babel/helper-plugin-utils": "^7.10.4",
+ "@babel/helper-simple-access": "^7.12.1",
+ "babel-plugin-dynamic-import-node": "^2.3.3"
+ }
+ },
+ "@babel/plugin-transform-modules-systemjs": {
+ "version": "7.12.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.12.1.tgz",
+ "integrity": "sha512-Hn7cVvOavVh8yvW6fLwveFqSnd7rbQN3zJvoPNyNaQSvgfKmDBO9U1YL9+PCXGRlZD9tNdWTy5ACKqMuzyn32Q==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-hoist-variables": "^7.10.4",
+ "@babel/helper-module-transforms": "^7.12.1",
+ "@babel/helper-plugin-utils": "^7.10.4",
+ "@babel/helper-validator-identifier": "^7.10.4",
+ "babel-plugin-dynamic-import-node": "^2.3.3"
+ }
+ },
+ "@babel/plugin-transform-modules-umd": {
+ "version": "7.12.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.12.1.tgz",
+ "integrity": "sha512-aEIubCS0KHKM0zUos5fIoQm+AZUMt1ZvMpqz0/H5qAQ7vWylr9+PLYurT+Ic7ID/bKLd4q8hDovaG3Zch2uz5Q==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-module-transforms": "^7.12.1",
+ "@babel/helper-plugin-utils": "^7.10.4"
+ }
+ },
+ "@babel/plugin-transform-named-capturing-groups-regex": {
+ "version": "7.12.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.12.1.tgz",
+ "integrity": "sha512-tB43uQ62RHcoDp9v2Nsf+dSM8sbNodbEicbQNA53zHz8pWUhsgHSJCGpt7daXxRydjb0KnfmB+ChXOv3oADp1Q==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-create-regexp-features-plugin": "^7.12.1"
+ }
+ },
+ "@babel/plugin-transform-new-target": {
+ "version": "7.12.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.12.1.tgz",
+ "integrity": "sha512-+eW/VLcUL5L9IvJH7rT1sT0CzkdUTvPrXC2PXTn/7z7tXLBuKvezYbGdxD5WMRoyvyaujOq2fWoKl869heKjhw==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-plugin-utils": "^7.10.4"
+ }
+ },
+ "@babel/plugin-transform-object-super": {
+ "version": "7.12.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.12.1.tgz",
+ "integrity": "sha512-AvypiGJH9hsquNUn+RXVcBdeE3KHPZexWRdimhuV59cSoOt5kFBmqlByorAeUlGG2CJWd0U+4ZtNKga/TB0cAw==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-plugin-utils": "^7.10.4",
+ "@babel/helper-replace-supers": "^7.12.1"
+ }
+ },
+ "@babel/plugin-transform-parameters": {
+ "version": "7.12.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.12.1.tgz",
+ "integrity": "sha512-xq9C5EQhdPK23ZeCdMxl8bbRnAgHFrw5EOC3KJUsSylZqdkCaFEXxGSBuTSObOpiiHHNyb82es8M1QYgfQGfNg==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-plugin-utils": "^7.10.4"
+ }
+ },
+ "@babel/plugin-transform-property-literals": {
+ "version": "7.12.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.12.1.tgz",
+ "integrity": "sha512-6MTCR/mZ1MQS+AwZLplX4cEySjCpnIF26ToWo942nqn8hXSm7McaHQNeGx/pt7suI1TWOWMfa/NgBhiqSnX0cQ==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-plugin-utils": "^7.10.4"
+ }
+ },
+ "@babel/plugin-transform-regenerator": {
+ "version": "7.12.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.12.1.tgz",
+ "integrity": "sha512-gYrHqs5itw6i4PflFX3OdBPMQdPbF4bj2REIUxlMRUFk0/ZOAIpDFuViuxPjUL7YC8UPnf+XG7/utJvqXdPKng==",
+ "dev": true,
+ "requires": {
+ "regenerator-transform": "^0.14.2"
+ }
+ },
+ "@babel/plugin-transform-reserved-words": {
+ "version": "7.12.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.12.1.tgz",
+ "integrity": "sha512-pOnUfhyPKvZpVyBHhSBoX8vfA09b7r00Pmm1sH+29ae2hMTKVmSp4Ztsr8KBKjLjx17H0eJqaRC3bR2iThM54A==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-plugin-utils": "^7.10.4"
+ }
+ },
+ "@babel/plugin-transform-runtime": {
+ "version": "7.12.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.12.1.tgz",
+ "integrity": "sha512-Ac/H6G9FEIkS2tXsZjL4RAdS3L3WHxci0usAnz7laPWUmFiGtj7tIASChqKZMHTSQTQY6xDbOq+V1/vIq3QrWg==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-module-imports": "^7.12.1",
+ "@babel/helper-plugin-utils": "^7.10.4",
+ "resolve": "^1.8.1",
+ "semver": "^5.5.1"
+ }
+ },
+ "@babel/plugin-transform-shorthand-properties": {
+ "version": "7.12.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.12.1.tgz",
+ "integrity": "sha512-GFZS3c/MhX1OusqB1MZ1ct2xRzX5ppQh2JU1h2Pnfk88HtFTM+TWQqJNfwkmxtPQtb/s1tk87oENfXJlx7rSDw==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-plugin-utils": "^7.10.4"
+ }
+ },
+ "@babel/plugin-transform-spread": {
+ "version": "7.12.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.12.1.tgz",
+ "integrity": "sha512-vuLp8CP0BE18zVYjsEBZ5xoCecMK6LBMMxYzJnh01rxQRvhNhH1csMMmBfNo5tGpGO+NhdSNW2mzIvBu3K1fng==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-plugin-utils": "^7.10.4",
+ "@babel/helper-skip-transparent-expression-wrappers": "^7.12.1"
+ }
+ },
+ "@babel/plugin-transform-sticky-regex": {
+ "version": "7.12.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.12.1.tgz",
+ "integrity": "sha512-CiUgKQ3AGVk7kveIaPEET1jNDhZZEl1RPMWdTBE1799bdz++SwqDHStmxfCtDfBhQgCl38YRiSnrMuUMZIWSUQ==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-plugin-utils": "^7.10.4",
+ "@babel/helper-regex": "^7.10.4"
+ }
+ },
+ "@babel/plugin-transform-template-literals": {
+ "version": "7.12.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.12.1.tgz",
+ "integrity": "sha512-b4Zx3KHi+taXB1dVRBhVJtEPi9h1THCeKmae2qP0YdUHIFhVjtpqqNfxeVAa1xeHVhAy4SbHxEwx5cltAu5apw==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-plugin-utils": "^7.10.4"
+ }
+ },
+ "@babel/plugin-transform-typeof-symbol": {
+ "version": "7.12.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.12.1.tgz",
+ "integrity": "sha512-EPGgpGy+O5Kg5pJFNDKuxt9RdmTgj5sgrus2XVeMp/ZIbOESadgILUbm50SNpghOh3/6yrbsH+NB5+WJTmsA7Q==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-plugin-utils": "^7.10.4"
+ }
+ },
+ "@babel/plugin-transform-unicode-escapes": {
+ "version": "7.12.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.12.1.tgz",
+ "integrity": "sha512-I8gNHJLIc7GdApm7wkVnStWssPNbSRMPtgHdmH3sRM1zopz09UWPS4x5V4n1yz/MIWTVnJ9sp6IkuXdWM4w+2Q==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-plugin-utils": "^7.10.4"
+ }
+ },
+ "@babel/plugin-transform-unicode-regex": {
+ "version": "7.12.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.12.1.tgz",
+ "integrity": "sha512-SqH4ClNngh/zGwHZOOQMTD+e8FGWexILV+ePMyiDJttAWRh5dhDL8rcl5lSgU3Huiq6Zn6pWTMvdPAb21Dwdyg==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-create-regexp-features-plugin": "^7.12.1",
+ "@babel/helper-plugin-utils": "^7.10.4"
+ }
+ },
+ "@babel/preset-env": {
+ "version": "7.12.1",
+ "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.12.1.tgz",
+ "integrity": "sha512-H8kxXmtPaAGT7TyBvSSkoSTUK6RHh61So05SyEbpmr0MCZrsNYn7mGMzzeYoOUCdHzww61k8XBft2TaES+xPLg==",
+ "dev": true,
+ "requires": {
+ "@babel/compat-data": "^7.12.1",
+ "@babel/helper-compilation-targets": "^7.12.1",
+ "@babel/helper-module-imports": "^7.12.1",
+ "@babel/helper-plugin-utils": "^7.10.4",
+ "@babel/helper-validator-option": "^7.12.1",
+ "@babel/plugin-proposal-async-generator-functions": "^7.12.1",
+ "@babel/plugin-proposal-class-properties": "^7.12.1",
+ "@babel/plugin-proposal-dynamic-import": "^7.12.1",
+ "@babel/plugin-proposal-export-namespace-from": "^7.12.1",
+ "@babel/plugin-proposal-json-strings": "^7.12.1",
+ "@babel/plugin-proposal-logical-assignment-operators": "^7.12.1",
+ "@babel/plugin-proposal-nullish-coalescing-operator": "^7.12.1",
+ "@babel/plugin-proposal-numeric-separator": "^7.12.1",
+ "@babel/plugin-proposal-object-rest-spread": "^7.12.1",
+ "@babel/plugin-proposal-optional-catch-binding": "^7.12.1",
+ "@babel/plugin-proposal-optional-chaining": "^7.12.1",
+ "@babel/plugin-proposal-private-methods": "^7.12.1",
+ "@babel/plugin-proposal-unicode-property-regex": "^7.12.1",
+ "@babel/plugin-syntax-async-generators": "^7.8.0",
+ "@babel/plugin-syntax-class-properties": "^7.12.1",
+ "@babel/plugin-syntax-dynamic-import": "^7.8.0",
+ "@babel/plugin-syntax-export-namespace-from": "^7.8.3",
+ "@babel/plugin-syntax-json-strings": "^7.8.0",
+ "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4",
+ "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.0",
+ "@babel/plugin-syntax-numeric-separator": "^7.10.4",
+ "@babel/plugin-syntax-object-rest-spread": "^7.8.0",
+ "@babel/plugin-syntax-optional-catch-binding": "^7.8.0",
+ "@babel/plugin-syntax-optional-chaining": "^7.8.0",
+ "@babel/plugin-syntax-top-level-await": "^7.12.1",
+ "@babel/plugin-transform-arrow-functions": "^7.12.1",
+ "@babel/plugin-transform-async-to-generator": "^7.12.1",
+ "@babel/plugin-transform-block-scoped-functions": "^7.12.1",
+ "@babel/plugin-transform-block-scoping": "^7.12.1",
+ "@babel/plugin-transform-classes": "^7.12.1",
+ "@babel/plugin-transform-computed-properties": "^7.12.1",
+ "@babel/plugin-transform-destructuring": "^7.12.1",
+ "@babel/plugin-transform-dotall-regex": "^7.12.1",
+ "@babel/plugin-transform-duplicate-keys": "^7.12.1",
+ "@babel/plugin-transform-exponentiation-operator": "^7.12.1",
+ "@babel/plugin-transform-for-of": "^7.12.1",
+ "@babel/plugin-transform-function-name": "^7.12.1",
+ "@babel/plugin-transform-literals": "^7.12.1",
+ "@babel/plugin-transform-member-expression-literals": "^7.12.1",
+ "@babel/plugin-transform-modules-amd": "^7.12.1",
+ "@babel/plugin-transform-modules-commonjs": "^7.12.1",
+ "@babel/plugin-transform-modules-systemjs": "^7.12.1",
+ "@babel/plugin-transform-modules-umd": "^7.12.1",
+ "@babel/plugin-transform-named-capturing-groups-regex": "^7.12.1",
+ "@babel/plugin-transform-new-target": "^7.12.1",
+ "@babel/plugin-transform-object-super": "^7.12.1",
+ "@babel/plugin-transform-parameters": "^7.12.1",
+ "@babel/plugin-transform-property-literals": "^7.12.1",
+ "@babel/plugin-transform-regenerator": "^7.12.1",
+ "@babel/plugin-transform-reserved-words": "^7.12.1",
+ "@babel/plugin-transform-shorthand-properties": "^7.12.1",
+ "@babel/plugin-transform-spread": "^7.12.1",
+ "@babel/plugin-transform-sticky-regex": "^7.12.1",
+ "@babel/plugin-transform-template-literals": "^7.12.1",
+ "@babel/plugin-transform-typeof-symbol": "^7.12.1",
+ "@babel/plugin-transform-unicode-escapes": "^7.12.1",
+ "@babel/plugin-transform-unicode-regex": "^7.12.1",
+ "@babel/preset-modules": "^0.1.3",
+ "@babel/types": "^7.12.1",
+ "core-js-compat": "^3.6.2",
+ "semver": "^5.5.0"
+ }
+ },
+ "@babel/preset-modules": {
+ "version": "0.1.4",
+ "resolved": "https://registry.npmjs.org/@babel/preset-modules/-/preset-modules-0.1.4.tgz",
+ "integrity": "sha512-J36NhwnfdzpmH41M1DrnkkgAqhZaqr/NBdPfQ677mLzlaXo+oDiv1deyCDtgAhz8p328otdob0Du7+xgHGZbKg==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-plugin-utils": "^7.0.0",
+ "@babel/plugin-proposal-unicode-property-regex": "^7.4.4",
+ "@babel/plugin-transform-dotall-regex": "^7.4.4",
+ "@babel/types": "^7.4.4",
+ "esutils": "^2.0.2"
+ }
+ },
+ "@babel/runtime": {
+ "version": "7.12.5",
+ "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.12.5.tgz",
+ "integrity": "sha512-plcc+hbExy3McchJCEQG3knOsuh3HH+Prx1P6cLIkET/0dLuQDEnrT+s27Axgc9bqfsmNUNHfscgMUdBpC9xfg==",
+ "requires": {
+ "regenerator-runtime": "^0.13.4"
+ }
+ },
+ "@babel/template": {
+ "version": "7.10.4",
+ "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.10.4.tgz",
+ "integrity": "sha512-ZCjD27cGJFUB6nmCB1Enki3r+L5kJveX9pq1SvAUKoICy6CZ9yD8xO086YXdYhvNjBdnekm4ZnaP5yC8Cs/1tA==",
+ "dev": true,
+ "requires": {
+ "@babel/code-frame": "^7.10.4",
+ "@babel/parser": "^7.10.4",
+ "@babel/types": "^7.10.4"
+ }
+ },
+ "@babel/traverse": {
+ "version": "7.23.2",
+ "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.23.2.tgz",
+ "integrity": "sha512-azpe59SQ48qG6nu2CzcMLbxUudtN+dOM9kDbUqGq3HXUJRlo7i8fvPoxQUzYgLZ4cMVmuZgm8vvBpNeRhd6XSw==",
+ "dev": true,
+ "requires": {
+ "@babel/code-frame": "^7.22.13",
+ "@babel/generator": "^7.23.0",
+ "@babel/helper-environment-visitor": "^7.22.20",
+ "@babel/helper-function-name": "^7.23.0",
+ "@babel/helper-hoist-variables": "^7.22.5",
+ "@babel/helper-split-export-declaration": "^7.22.6",
+ "@babel/parser": "^7.23.0",
+ "@babel/types": "^7.23.0",
+ "debug": "^4.1.0",
+ "globals": "^11.1.0"
+ },
+ "dependencies": {
+ "@babel/code-frame": {
+ "version": "7.22.13",
+ "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.22.13.tgz",
+ "integrity": "sha512-XktuhWlJ5g+3TJXc5upd9Ks1HutSArik6jf2eAjYFyIOf4ej3RN+184cZbzDvbPnuTJIUhPKKJE3cIsYTiAT3w==",
+ "dev": true,
+ "requires": {
+ "@babel/highlight": "^7.22.13",
+ "chalk": "^2.4.2"
+ }
+ },
+ "@babel/generator": {
+ "version": "7.23.0",
+ "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.23.0.tgz",
+ "integrity": "sha512-lN85QRR+5IbYrMWM6Y4pE/noaQtg4pNiqeNGX60eqOfo6gtEj6uw/JagelB8vVztSd7R6M5n1+PQkDbHbBRU4g==",
+ "dev": true,
+ "requires": {
+ "@babel/types": "^7.23.0",
+ "@jridgewell/gen-mapping": "^0.3.2",
+ "@jridgewell/trace-mapping": "^0.3.17",
+ "jsesc": "^2.5.1"
+ }
+ },
+ "@babel/helper-function-name": {
+ "version": "7.23.0",
+ "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.23.0.tgz",
+ "integrity": "sha512-OErEqsrxjZTJciZ4Oo+eoZqeW9UIiOcuYKRJA4ZAgV9myA+pOXhhmpfNCKjEH/auVfEYVFJ6y1Tc4r0eIApqiw==",
+ "dev": true,
+ "requires": {
+ "@babel/template": "^7.22.15",
+ "@babel/types": "^7.23.0"
+ }
+ },
+ "@babel/helper-hoist-variables": {
+ "version": "7.22.5",
+ "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.22.5.tgz",
+ "integrity": "sha512-wGjk9QZVzvknA6yKIUURb8zY3grXCcOZt+/7Wcy8O2uctxhplmUPkOdlgoNhmdVee2c92JXbf1xpMtVNbfoxRw==",
+ "dev": true,
+ "requires": {
+ "@babel/types": "^7.22.5"
+ }
+ },
+ "@babel/helper-split-export-declaration": {
+ "version": "7.22.6",
+ "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.22.6.tgz",
+ "integrity": "sha512-AsUnxuLhRYsisFiaJwvp1QF+I3KjD5FOxut14q/GzovUe6orHLesW2C7d754kRm53h5gqrz6sFl6sxc4BVtE/g==",
+ "dev": true,
+ "requires": {
+ "@babel/types": "^7.22.5"
+ }
+ },
+ "@babel/helper-validator-identifier": {
+ "version": "7.22.20",
+ "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.20.tgz",
+ "integrity": "sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A==",
+ "dev": true
+ },
+ "@babel/highlight": {
+ "version": "7.22.20",
+ "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.22.20.tgz",
+ "integrity": "sha512-dkdMCN3py0+ksCgYmGG8jKeGA/8Tk+gJwSYYlFGxG5lmhfKNoAy004YpLxpS1W2J8m/EK2Ew+yOs9pVRwO89mg==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-validator-identifier": "^7.22.20",
+ "chalk": "^2.4.2",
+ "js-tokens": "^4.0.0"
+ }
+ },
+ "@babel/parser": {
+ "version": "7.23.0",
+ "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.23.0.tgz",
+ "integrity": "sha512-vvPKKdMemU85V9WE/l5wZEmImpCtLqbnTvqDS2U1fJ96KrxoW7KrXhNsNCblQlg8Ck4b85yxdTyelsMUgFUXiw==",
+ "dev": true
+ },
+ "@babel/template": {
+ "version": "7.22.15",
+ "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.22.15.tgz",
+ "integrity": "sha512-QPErUVm4uyJa60rkI73qneDacvdvzxshT3kksGqlGWYdOTIUOwJ7RDUL8sGqslY1uXWSL6xMFKEXDS3ox2uF0w==",
+ "dev": true,
+ "requires": {
+ "@babel/code-frame": "^7.22.13",
+ "@babel/parser": "^7.22.15",
+ "@babel/types": "^7.22.15"
+ }
+ },
+ "@babel/types": {
+ "version": "7.23.0",
+ "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.23.0.tgz",
+ "integrity": "sha512-0oIyUfKoI3mSqMvsxBdclDwxXKXAUA8v/apZbc+iSyARYou1o8ZGDxbUYyLFoW2arqS2jDGqJuZvv1d/io1axg==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-string-parser": "^7.22.5",
+ "@babel/helper-validator-identifier": "^7.22.20",
+ "to-fast-properties": "^2.0.0"
+ }
+ }
+ }
+ },
+ "@babel/types": {
+ "version": "7.12.6",
+ "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.12.6.tgz",
+ "integrity": "sha512-hwyjw6GvjBLiyy3W0YQf0Z5Zf4NpYejUnKFcfcUhZCSffoBBp30w6wP2Wn6pk31jMYZvcOrB/1b7cGXvEoKogA==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-validator-identifier": "^7.10.4",
+ "lodash": "^4.17.19",
+ "to-fast-properties": "^2.0.0"
+ }
+ },
+ "@discoveryjs/json-ext": {
+ "version": "0.5.7",
+ "resolved": "https://registry.npmjs.org/@discoveryjs/json-ext/-/json-ext-0.5.7.tgz",
+ "integrity": "sha512-dBVuXR082gk3jsFp7Rd/JI4kytwGHecnCoTtXFb7DB6CNHp4rg5k1bhg0nWdLGLnOV71lmDzGQaLMy8iPLY0pw==",
+ "dev": true
+ },
+ "@jridgewell/gen-mapping": {
+ "version": "0.3.2",
+ "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.2.tgz",
+ "integrity": "sha512-mh65xKQAzI6iBcFzwv28KVWSmCkdRBWoOh+bYQGW3+6OZvbbN3TqMGo5hqYxQniRcH9F2VZIoJCm4pa3BPDK/A==",
+ "dev": true,
+ "requires": {
+ "@jridgewell/set-array": "^1.0.1",
+ "@jridgewell/sourcemap-codec": "^1.4.10",
+ "@jridgewell/trace-mapping": "^0.3.9"
+ }
+ },
+ "@jridgewell/resolve-uri": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz",
+ "integrity": "sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w==",
+ "dev": true
+ },
+ "@jridgewell/set-array": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.1.2.tgz",
+ "integrity": "sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==",
+ "dev": true
+ },
+ "@jridgewell/source-map": {
+ "version": "0.3.2",
+ "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.2.tgz",
+ "integrity": "sha512-m7O9o2uR8k2ObDysZYzdfhb08VuEml5oWGiosa1VdaPZ/A6QyPkAJuwN0Q1lhULOf6B7MtQmHENS743hWtCrgw==",
+ "dev": true,
+ "requires": {
+ "@jridgewell/gen-mapping": "^0.3.0",
+ "@jridgewell/trace-mapping": "^0.3.9"
+ }
+ },
+ "@jridgewell/sourcemap-codec": {
+ "version": "1.4.14",
+ "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz",
+ "integrity": "sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==",
+ "dev": true
+ },
+ "@jridgewell/trace-mapping": {
+ "version": "0.3.17",
+ "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.17.tgz",
+ "integrity": "sha512-MCNzAp77qzKca9+W/+I0+sEpaUnZoeasnghNeVc41VZCEKaCH73Vq3BZZ/SzWIgrqE4H4ceI+p+b6C0mHf9T4g==",
+ "dev": true,
+ "requires": {
+ "@jridgewell/resolve-uri": "3.1.0",
+ "@jridgewell/sourcemap-codec": "1.4.14"
+ }
+ },
+ "@mrmlnc/readdir-enhanced": {
+ "version": "2.2.1",
+ "resolved": "https://registry.npmjs.org/@mrmlnc/readdir-enhanced/-/readdir-enhanced-2.2.1.tgz",
+ "integrity": "sha512-bPHp6Ji8b41szTOcaP63VlnbbO5Ny6dwAATtY6JTjh5N2OLrb5Qk/Th5cRkRQhkWCt+EJsYrNB0MiL+Gpn6e3g==",
+ "dev": true,
+ "requires": {
+ "call-me-maybe": "^1.0.1",
+ "glob-to-regexp": "^0.3.0"
+ }
+ },
+ "@nodelib/fs.stat": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-1.1.3.tgz",
+ "integrity": "sha512-shAmDyaQC4H92APFoIaVDHCx5bStIocgvbwQyxPRrbUY20V1EYTbSDchWbuwlMG3V17cprZhA6+78JfB+3DTPw==",
+ "dev": true
+ },
+ "@sindresorhus/is": {
+ "version": "0.14.0",
+ "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-0.14.0.tgz",
+ "integrity": "sha512-9NET910DNaIPngYnLLPeg+Ogzqsi9uM4mSboU5y6p8S5DzMTVEsJZrawi+BoDNUVBa2DhJqQYUFvMDfgU062LQ==",
+ "dev": true
+ },
+ "@sinonjs/commons": {
+ "version": "1.8.1",
+ "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.8.1.tgz",
+ "integrity": "sha512-892K+kWUUi3cl+LlqEWIDrhvLgdL79tECi8JZUyq6IviKy/DNhuzCRlbHUjxK89f4ypPMMaFnFuR9Ie6DoIMsw==",
+ "dev": true,
+ "requires": {
+ "type-detect": "4.0.8"
+ }
+ },
+ "@sinonjs/fake-timers": {
+ "version": "6.0.1",
+ "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-6.0.1.tgz",
+ "integrity": "sha512-MZPUxrmFubI36XS1DI3qmI0YdN1gks62JtFZvxR67ljjSNCeK6U08Zx4msEWOXuofgqUt6zPHSi1H9fbjR/NRA==",
+ "dev": true,
+ "requires": {
+ "@sinonjs/commons": "^1.7.0"
+ }
+ },
+ "@sinonjs/formatio": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/@sinonjs/formatio/-/formatio-5.0.1.tgz",
+ "integrity": "sha512-KaiQ5pBf1MpS09MuA0kp6KBQt2JUOQycqVG1NZXvzeaXe5LGFqAKueIS0bw4w0P9r7KuBSVdUk5QjXsUdu2CxQ==",
+ "dev": true,
+ "requires": {
+ "@sinonjs/commons": "^1",
+ "@sinonjs/samsam": "^5.0.2"
+ }
+ },
+ "@sinonjs/samsam": {
+ "version": "5.2.0",
+ "resolved": "https://registry.npmjs.org/@sinonjs/samsam/-/samsam-5.2.0.tgz",
+ "integrity": "sha512-CaIcyX5cDsjcW/ab7HposFWzV1kC++4HNsfnEdFJa7cP1QIuILAKV+BgfeqRXhcnSAc76r/Rh/O5C+300BwUIw==",
+ "dev": true,
+ "requires": {
+ "@sinonjs/commons": "^1.6.0",
+ "lodash.get": "^4.4.2",
+ "type-detect": "^4.0.8"
+ }
+ },
+ "@sinonjs/text-encoding": {
+ "version": "0.7.1",
+ "resolved": "https://registry.npmjs.org/@sinonjs/text-encoding/-/text-encoding-0.7.1.tgz",
+ "integrity": "sha512-+iTbntw2IZPb/anVDbypzfQa+ay64MW0Zo8aJ8gZPWMMK6/OubMVb6lUPMagqjOPnmtauXnFCACVl3O7ogjeqQ==",
+ "dev": true
+ },
+ "@szmarczak/http-timer": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-1.1.2.tgz",
+ "integrity": "sha512-XIB2XbzHTN6ieIjfIMV9hlVcfPU26s2vafYWQcZHWXHOxiaRZYEDKEwdl129Zyg50+foYV2jCgtrqSA6qNuNSA==",
+ "dev": true,
+ "requires": {
+ "defer-to-connect": "^1.0.1"
+ }
+ },
+ "@types/eslint": {
+ "version": "8.4.10",
+ "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-8.4.10.tgz",
+ "integrity": "sha512-Sl/HOqN8NKPmhWo2VBEPm0nvHnu2LL3v9vKo8MEq0EtbJ4eVzGPl41VNPvn5E1i5poMk4/XD8UriLHpJvEP/Nw==",
+ "dev": true,
+ "requires": {
+ "@types/estree": "*",
+ "@types/json-schema": "*"
+ }
+ },
+ "@types/eslint-scope": {
+ "version": "3.7.4",
+ "resolved": "https://registry.npmjs.org/@types/eslint-scope/-/eslint-scope-3.7.4.tgz",
+ "integrity": "sha512-9K4zoImiZc3HlIp6AVUDE4CWYx22a+lhSZMYNpbjW04+YF0KWj4pJXnEMjdnFTiQibFFmElcsasJXDbdI/EPhA==",
+ "dev": true,
+ "requires": {
+ "@types/eslint": "*",
+ "@types/estree": "*"
+ }
+ },
+ "@types/estree": {
+ "version": "0.0.51",
+ "resolved": "https://registry.npmjs.org/@types/estree/-/estree-0.0.51.tgz",
+ "integrity": "sha512-CuPgU6f3eT/XgKKPqKd/gLZV1Xmvf1a2R5POBOGQa6uv82xpls89HU5zKeVoyR8XzHd1RGNOlQlvUe3CFkjWNQ==",
+ "dev": true
+ },
+ "@types/glob": {
+ "version": "7.1.3",
+ "resolved": "https://registry.npmjs.org/@types/glob/-/glob-7.1.3.tgz",
+ "integrity": "sha512-SEYeGAIQIQX8NN6LDKprLjbrd5dARM5EXsd8GI/A5l0apYI1fGMWgPHSe4ZKL4eozlAyI+doUE9XbYS4xCkQ1w==",
+ "dev": true,
+ "requires": {
+ "@types/minimatch": "*",
+ "@types/node": "*"
+ }
+ },
+ "@types/json-schema": {
+ "version": "7.0.11",
+ "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.11.tgz",
+ "integrity": "sha512-wOuvG1SN4Us4rez+tylwwwCV1psiNVOkJeM3AUWUNWg/jDQY2+HE/444y5gc+jBmRqASOm2Oeh5c1axHobwRKQ==",
+ "dev": true
+ },
+ "@types/json5": {
+ "version": "0.0.29",
+ "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz",
+ "integrity": "sha1-7ihweulOEdK4J7y+UnC86n8+ce4=",
+ "dev": true
+ },
+ "@types/minimatch": {
+ "version": "3.0.3",
+ "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.3.tgz",
+ "integrity": "sha512-tHq6qdbT9U1IRSGf14CL0pUlULksvY9OZ+5eEgl1N7t+OA3tGvNpxJCzuKQlsNgCVwbAs670L1vcVQi8j9HjnA==",
+ "dev": true
+ },
+ "@types/node": {
+ "version": "14.14.6",
+ "resolved": "https://registry.npmjs.org/@types/node/-/node-14.14.6.tgz",
+ "integrity": "sha512-6QlRuqsQ/Ox/aJEQWBEJG7A9+u7oSYl3mem/K8IzxXG/kAGbV1YPD9Bg9Zw3vyxC/YP+zONKwy8hGkSt1jxFMw==",
+ "dev": true
+ },
+ "@types/normalize-package-data": {
+ "version": "2.4.0",
+ "resolved": "https://registry.npmjs.org/@types/normalize-package-data/-/normalize-package-data-2.4.0.tgz",
+ "integrity": "sha512-f5j5b/Gf71L+dbqxIpQ4Z2WlmI/mPJ0fOkGGmFgtb6sAu97EPczzbS3/tJKxmcYDj55OX6ssqwDAWOHIYDRDGA==",
+ "dev": true
+ },
+ "@ungap/promise-all-settled": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/@ungap/promise-all-settled/-/promise-all-settled-1.1.2.tgz",
+ "integrity": "sha512-sL/cEvJWAnClXw0wHk85/2L0G6Sj8UB0Ctc1TEMbKSsmpRosqhwj9gWgFRZSrBr2f9tiXISwNhCPmlfqUqyb9Q==",
+ "dev": true
+ },
+ "@webassemblyjs/ast": {
+ "version": "1.11.1",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.11.1.tgz",
+ "integrity": "sha512-ukBh14qFLjxTQNTXocdyksN5QdM28S1CxHt2rdskFyL+xFV7VremuBLVbmCePj+URalXBENx/9Lm7lnhihtCSw==",
+ "dev": true,
+ "requires": {
+ "@webassemblyjs/helper-numbers": "1.11.1",
+ "@webassemblyjs/helper-wasm-bytecode": "1.11.1"
+ }
+ },
+ "@webassemblyjs/floating-point-hex-parser": {
+ "version": "1.11.1",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.11.1.tgz",
+ "integrity": "sha512-iGRfyc5Bq+NnNuX8b5hwBrRjzf0ocrJPI6GWFodBFzmFnyvrQ83SHKhmilCU/8Jv67i4GJZBMhEzltxzcNagtQ==",
+ "dev": true
+ },
+ "@webassemblyjs/helper-api-error": {
+ "version": "1.11.1",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.11.1.tgz",
+ "integrity": "sha512-RlhS8CBCXfRUR/cwo2ho9bkheSXG0+NwooXcc3PAILALf2QLdFyj7KGsKRbVc95hZnhnERon4kW/D3SZpp6Tcg==",
+ "dev": true
+ },
+ "@webassemblyjs/helper-buffer": {
+ "version": "1.11.1",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.11.1.tgz",
+ "integrity": "sha512-gwikF65aDNeeXa8JxXa2BAk+REjSyhrNC9ZwdT0f8jc4dQQeDQ7G4m0f2QCLPJiMTTO6wfDmRmj/pW0PsUvIcA==",
+ "dev": true
+ },
+ "@webassemblyjs/helper-numbers": {
+ "version": "1.11.1",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-numbers/-/helper-numbers-1.11.1.tgz",
+ "integrity": "sha512-vDkbxiB8zfnPdNK9Rajcey5C0w+QJugEglN0of+kmO8l7lDb77AnlKYQF7aarZuCrv+l0UvqL+68gSDr3k9LPQ==",
+ "dev": true,
+ "requires": {
+ "@webassemblyjs/floating-point-hex-parser": "1.11.1",
+ "@webassemblyjs/helper-api-error": "1.11.1",
+ "@xtuc/long": "4.2.2"
+ }
+ },
+ "@webassemblyjs/helper-wasm-bytecode": {
+ "version": "1.11.1",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.11.1.tgz",
+ "integrity": "sha512-PvpoOGiJwXeTrSf/qfudJhwlvDQxFgelbMqtq52WWiXC6Xgg1IREdngmPN3bs4RoO83PnL/nFrxucXj1+BX62Q==",
+ "dev": true
+ },
+ "@webassemblyjs/helper-wasm-section": {
+ "version": "1.11.1",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.11.1.tgz",
+ "integrity": "sha512-10P9No29rYX1j7F3EVPX3JvGPQPae+AomuSTPiF9eBQeChHI6iqjMIwR9JmOJXwpnn/oVGDk7I5IlskuMwU/pg==",
+ "dev": true,
+ "requires": {
+ "@webassemblyjs/ast": "1.11.1",
+ "@webassemblyjs/helper-buffer": "1.11.1",
+ "@webassemblyjs/helper-wasm-bytecode": "1.11.1",
+ "@webassemblyjs/wasm-gen": "1.11.1"
+ }
+ },
+ "@webassemblyjs/ieee754": {
+ "version": "1.11.1",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.11.1.tgz",
+ "integrity": "sha512-hJ87QIPtAMKbFq6CGTkZYJivEwZDbQUgYd3qKSadTNOhVY7p+gfP6Sr0lLRVTaG1JjFj+r3YchoqRYxNH3M0GQ==",
+ "dev": true,
+ "requires": {
+ "@xtuc/ieee754": "^1.2.0"
+ }
+ },
+ "@webassemblyjs/leb128": {
+ "version": "1.11.1",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.11.1.tgz",
+ "integrity": "sha512-BJ2P0hNZ0u+Th1YZXJpzW6miwqQUGcIHT1G/sf72gLVD9DZ5AdYTqPNbHZh6K1M5VmKvFXwGSWZADz+qBWxeRw==",
+ "dev": true,
+ "requires": {
+ "@xtuc/long": "4.2.2"
+ }
+ },
+ "@webassemblyjs/utf8": {
+ "version": "1.11.1",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.11.1.tgz",
+ "integrity": "sha512-9kqcxAEdMhiwQkHpkNiorZzqpGrodQQ2IGrHHxCy+Ozng0ofyMA0lTqiLkVs1uzTRejX+/O0EOT7KxqVPuXosQ==",
+ "dev": true
+ },
+ "@webassemblyjs/wasm-edit": {
+ "version": "1.11.1",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.11.1.tgz",
+ "integrity": "sha512-g+RsupUC1aTHfR8CDgnsVRVZFJqdkFHpsHMfJuWQzWU3tvnLC07UqHICfP+4XyL2tnr1amvl1Sdp06TnYCmVkA==",
+ "dev": true,
+ "requires": {
+ "@webassemblyjs/ast": "1.11.1",
+ "@webassemblyjs/helper-buffer": "1.11.1",
+ "@webassemblyjs/helper-wasm-bytecode": "1.11.1",
+ "@webassemblyjs/helper-wasm-section": "1.11.1",
+ "@webassemblyjs/wasm-gen": "1.11.1",
+ "@webassemblyjs/wasm-opt": "1.11.1",
+ "@webassemblyjs/wasm-parser": "1.11.1",
+ "@webassemblyjs/wast-printer": "1.11.1"
+ }
+ },
+ "@webassemblyjs/wasm-gen": {
+ "version": "1.11.1",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.11.1.tgz",
+ "integrity": "sha512-F7QqKXwwNlMmsulj6+O7r4mmtAlCWfO/0HdgOxSklZfQcDu0TpLiD1mRt/zF25Bk59FIjEuGAIyn5ei4yMfLhA==",
+ "dev": true,
+ "requires": {
+ "@webassemblyjs/ast": "1.11.1",
+ "@webassemblyjs/helper-wasm-bytecode": "1.11.1",
+ "@webassemblyjs/ieee754": "1.11.1",
+ "@webassemblyjs/leb128": "1.11.1",
+ "@webassemblyjs/utf8": "1.11.1"
+ }
+ },
+ "@webassemblyjs/wasm-opt": {
+ "version": "1.11.1",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.11.1.tgz",
+ "integrity": "sha512-VqnkNqnZlU5EB64pp1l7hdm3hmQw7Vgqa0KF/KCNO9sIpI6Fk6brDEiX+iCOYrvMuBWDws0NkTOxYEb85XQHHw==",
+ "dev": true,
+ "requires": {
+ "@webassemblyjs/ast": "1.11.1",
+ "@webassemblyjs/helper-buffer": "1.11.1",
+ "@webassemblyjs/wasm-gen": "1.11.1",
+ "@webassemblyjs/wasm-parser": "1.11.1"
+ }
+ },
+ "@webassemblyjs/wasm-parser": {
+ "version": "1.11.1",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.11.1.tgz",
+ "integrity": "sha512-rrBujw+dJu32gYB7/Lup6UhdkPx9S9SnobZzRVL7VcBH9Bt9bCBLEuX/YXOOtBsOZ4NQrRykKhffRWHvigQvOA==",
+ "dev": true,
+ "requires": {
+ "@webassemblyjs/ast": "1.11.1",
+ "@webassemblyjs/helper-api-error": "1.11.1",
+ "@webassemblyjs/helper-wasm-bytecode": "1.11.1",
+ "@webassemblyjs/ieee754": "1.11.1",
+ "@webassemblyjs/leb128": "1.11.1",
+ "@webassemblyjs/utf8": "1.11.1"
+ }
+ },
+ "@webassemblyjs/wast-printer": {
+ "version": "1.11.1",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.11.1.tgz",
+ "integrity": "sha512-IQboUWM4eKzWW+N/jij2sRatKMh99QEelo3Eb2q0qXkvPRISAj8Qxtmw5itwqK+TTkBuUIE45AxYPToqPtL5gg==",
+ "dev": true,
+ "requires": {
+ "@webassemblyjs/ast": "1.11.1",
+ "@xtuc/long": "4.2.2"
+ }
+ },
+ "@webpack-cli/configtest": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/@webpack-cli/configtest/-/configtest-2.0.1.tgz",
+ "integrity": "sha512-njsdJXJSiS2iNbQVS0eT8A/KPnmyH4pv1APj2K0d1wrZcBLw+yppxOy4CGqa0OxDJkzfL/XELDhD8rocnIwB5A==",
+ "dev": true,
+ "requires": {}
+ },
+ "@webpack-cli/info": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/@webpack-cli/info/-/info-2.0.1.tgz",
+ "integrity": "sha512-fE1UEWTwsAxRhrJNikE7v4EotYflkEhBL7EbajfkPlf6E37/2QshOy/D48Mw8G5XMFlQtS6YV42vtbG9zBpIQA==",
+ "dev": true,
+ "requires": {}
+ },
+ "@webpack-cli/serve": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/@webpack-cli/serve/-/serve-2.0.1.tgz",
+ "integrity": "sha512-0G7tNyS+yW8TdgHwZKlDWYXFA6OJQnoLCQvYKkQP0Q2X205PSQ6RNUj0M+1OB/9gRQaUZ/ccYfaxd0nhaWKfjw==",
+ "dev": true,
+ "requires": {}
+ },
+ "@xtuc/ieee754": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz",
+ "integrity": "sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==",
+ "dev": true
+ },
+ "@xtuc/long": {
+ "version": "4.2.2",
+ "resolved": "https://registry.npmjs.org/@xtuc/long/-/long-4.2.2.tgz",
+ "integrity": "sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==",
+ "dev": true
+ },
+ "acorn": {
+ "version": "8.8.1",
+ "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.1.tgz",
+ "integrity": "sha512-7zFpHzhnqYKrkYdUjF1HI1bzd0VygEGX8lFk4k5zVMqHEoES+P+7TKI+EvLO9WVMJ8eekdO0aDEK044xTXwPPA==",
+ "dev": true
+ },
+ "acorn-import-assertions": {
+ "version": "1.8.0",
+ "resolved": "https://registry.npmjs.org/acorn-import-assertions/-/acorn-import-assertions-1.8.0.tgz",
+ "integrity": "sha512-m7VZ3jwz4eK6A4Vtt8Ew1/mNbP24u0FhdyfA7fSvnJR6LMdfOYnmuIrrJAgrYfYJ10F/otaHTtrtrtmHdMNzEw==",
+ "dev": true,
+ "requires": {}
+ },
+ "acorn-jsx": {
+ "version": "5.3.1",
+ "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.1.tgz",
+ "integrity": "sha512-K0Ptm/47OKfQRpNQ2J/oIN/3QYiK6FwW+eJbILhsdxh2WTLdl+30o8aGdTbm5JbffpFFAg/g+zi1E+jvJha5ng==",
+ "dev": true,
+ "requires": {}
+ },
+ "ajv": {
+ "version": "6.12.6",
+ "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz",
+ "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==",
+ "dev": true,
+ "requires": {
+ "fast-deep-equal": "^3.1.1",
+ "fast-json-stable-stringify": "^2.0.0",
+ "json-schema-traverse": "^0.4.1",
+ "uri-js": "^4.2.2"
+ }
+ },
+ "ajv-keywords": {
+ "version": "3.5.2",
+ "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz",
+ "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==",
+ "dev": true,
+ "requires": {}
+ },
+ "ansi-align": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/ansi-align/-/ansi-align-3.0.0.tgz",
+ "integrity": "sha512-ZpClVKqXN3RGBmKibdfWzqCY4lnjEuoNzU5T0oEFpfd/z5qJHVarukridD4juLO2FXMiwUQxr9WqQtaYa8XRYw==",
+ "dev": true,
+ "requires": {
+ "string-width": "^3.0.0"
+ },
+ "dependencies": {
+ "ansi-regex": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.1.tgz",
+ "integrity": "sha512-ILlv4k/3f6vfQ4OoP2AGvirOktlQ98ZEL1k9FaQjxa3L1abBgbuTDAdPOpvbGncC0BTVQrl+OM8xZGK6tWXt7g==",
+ "dev": true
+ },
+ "string-width": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz",
+ "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==",
+ "dev": true,
+ "requires": {
+ "emoji-regex": "^7.0.1",
+ "is-fullwidth-code-point": "^2.0.0",
+ "strip-ansi": "^5.1.0"
+ }
+ },
+ "strip-ansi": {
+ "version": "5.2.0",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz",
+ "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==",
+ "dev": true,
+ "requires": {
+ "ansi-regex": "^4.1.0"
+ }
+ }
+ }
+ },
+ "ansi-colors": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz",
+ "integrity": "sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==",
+ "dev": true
+ },
+ "ansi-escapes": {
+ "version": "4.3.1",
+ "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.1.tgz",
+ "integrity": "sha512-JWF7ocqNrp8u9oqpgV+wH5ftbt+cfvv+PTjOvKLT3AdYly/LmORARfEVT1iyjwN+4MqE5UmVKoAdIBqeoCHgLA==",
+ "dev": true,
+ "requires": {
+ "type-fest": "^0.11.0"
+ },
+ "dependencies": {
+ "type-fest": {
+ "version": "0.11.0",
+ "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.11.0.tgz",
+ "integrity": "sha512-OdjXJxnCN1AvyLSzeKIgXTXxV+99ZuXl3Hpo9XpJAv9MBcHrrJOQ5kV7ypXOuQie+AmWG25hLbiKdwYTifzcfQ==",
+ "dev": true
+ }
+ }
+ },
+ "ansi-regex": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
+ "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
+ "dev": true
+ },
+ "ansi-styles": {
+ "version": "3.2.1",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
+ "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
+ "dev": true,
+ "requires": {
+ "color-convert": "^1.9.0"
+ }
+ },
+ "anymatch": {
+ "version": "3.1.2",
+ "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz",
+ "integrity": "sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==",
+ "dev": true,
+ "requires": {
+ "normalize-path": "^3.0.0",
+ "picomatch": "^2.0.4"
+ }
+ },
+ "argparse": {
+ "version": "1.0.10",
+ "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz",
+ "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==",
+ "dev": true,
+ "requires": {
+ "sprintf-js": "~1.0.2"
+ }
+ },
+ "arr-diff": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz",
+ "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=",
+ "dev": true
+ },
+ "arr-flatten": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/arr-flatten/-/arr-flatten-1.1.0.tgz",
+ "integrity": "sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg==",
+ "dev": true
+ },
+ "arr-union": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/arr-union/-/arr-union-3.1.0.tgz",
+ "integrity": "sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ=",
+ "dev": true
+ },
+ "array-differ": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/array-differ/-/array-differ-3.0.0.tgz",
+ "integrity": "sha512-THtfYS6KtME/yIAhKjZ2ul7XI96lQGHRputJQHO80LAWQnuGP4iCIN8vdMRboGbIEYBwU33q8Tch1os2+X0kMg==",
+ "dev": true
+ },
+ "array-find-index": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/array-find-index/-/array-find-index-1.0.2.tgz",
+ "integrity": "sha1-3wEKoSh+Fku9pvlyOwqWoexBh6E=",
+ "dev": true
+ },
+ "array-includes": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.1.tgz",
+ "integrity": "sha512-c2VXaCHl7zPsvpkFsw4nxvFie4fh1ur9bpcgsVkIjqn0H/Xwdg+7fv3n2r/isyS8EBj5b06M9kHyZuIr4El6WQ==",
+ "dev": true,
+ "requires": {
+ "define-properties": "^1.1.3",
+ "es-abstract": "^1.17.0",
+ "is-string": "^1.0.5"
+ }
+ },
+ "array-union": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/array-union/-/array-union-1.0.2.tgz",
+ "integrity": "sha1-mjRBDk9OPaI96jdb5b5w8kd47Dk=",
+ "dev": true,
+ "requires": {
+ "array-uniq": "^1.0.1"
+ }
+ },
+ "array-uniq": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/array-uniq/-/array-uniq-1.0.3.tgz",
+ "integrity": "sha1-r2rId6Jcx/dOBYiUdThY39sk/bY=",
+ "dev": true
+ },
+ "array-unique": {
+ "version": "0.3.2",
+ "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz",
+ "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=",
+ "dev": true
+ },
+ "array.prototype.flat": {
+ "version": "1.2.3",
+ "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.2.3.tgz",
+ "integrity": "sha512-gBlRZV0VSmfPIeWfuuy56XZMvbVfbEUnOXUvt3F/eUUUSyzlgLxhEX4YAEpxNAogRGehPSnfXyPtYyKAhkzQhQ==",
+ "dev": true,
+ "requires": {
+ "define-properties": "^1.1.3",
+ "es-abstract": "^1.17.0-next.1"
+ }
+ },
+ "arrify": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/arrify/-/arrify-2.0.1.tgz",
+ "integrity": "sha512-3duEwti880xqi4eAMN8AyR4a0ByT90zoYdLlevfrvU43vb0YZwZVfxOgxWrLXXXpyugL0hNZc9G6BiB5B3nUug==",
+ "dev": true
+ },
+ "assign-symbols": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/assign-symbols/-/assign-symbols-1.0.0.tgz",
+ "integrity": "sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c=",
+ "dev": true
+ },
+ "astral-regex": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-1.0.0.tgz",
+ "integrity": "sha512-+Ryf6g3BKoRc7jfp7ad8tM4TtMiaWvbF/1/sQcZPkkS7ag3D5nMBCe2UfOTONtAkaG0tO0ij3C5Lwmf1EiyjHg==",
+ "dev": true
+ },
+ "atob": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/atob/-/atob-2.1.2.tgz",
+ "integrity": "sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==",
+ "dev": true
+ },
+ "babel-loader": {
+ "version": "8.3.0",
+ "resolved": "https://registry.npmjs.org/babel-loader/-/babel-loader-8.3.0.tgz",
+ "integrity": "sha512-H8SvsMF+m9t15HNLMipppzkC+Y2Yq+v3SonZyU70RBL/h1gxPkH08Ot8pEE9Z4Kd+czyWJClmFS8qzIP9OZ04Q==",
+ "dev": true,
+ "requires": {
+ "find-cache-dir": "^3.3.1",
+ "loader-utils": "^2.0.0",
+ "make-dir": "^3.1.0",
+ "schema-utils": "^2.6.5"
+ }
+ },
+ "babel-plugin-dynamic-import-node": {
+ "version": "2.3.3",
+ "resolved": "https://registry.npmjs.org/babel-plugin-dynamic-import-node/-/babel-plugin-dynamic-import-node-2.3.3.tgz",
+ "integrity": "sha512-jZVI+s9Zg3IqA/kdi0i6UDCybUI3aSBLnglhYbSSjKlV7yF1F/5LWv8MakQmvYpnbJDS6fcBL2KzHSxNCMtWSQ==",
+ "dev": true,
+ "requires": {
+ "object.assign": "^4.1.0"
+ }
+ },
+ "balanced-match": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz",
+ "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c="
+ },
+ "base": {
+ "version": "0.11.2",
+ "resolved": "https://registry.npmjs.org/base/-/base-0.11.2.tgz",
+ "integrity": "sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg==",
+ "dev": true,
+ "requires": {
+ "cache-base": "^1.0.1",
+ "class-utils": "^0.3.5",
+ "component-emitter": "^1.2.1",
+ "define-property": "^1.0.0",
+ "isobject": "^3.0.1",
+ "mixin-deep": "^1.2.0",
+ "pascalcase": "^0.1.1"
+ },
+ "dependencies": {
+ "define-property": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz",
+ "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=",
+ "dev": true,
+ "requires": {
+ "is-descriptor": "^1.0.0"
+ }
+ },
+ "is-accessor-descriptor": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz",
+ "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==",
+ "dev": true,
+ "requires": {
+ "kind-of": "^6.0.0"
+ }
+ },
+ "is-data-descriptor": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz",
+ "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==",
+ "dev": true,
+ "requires": {
+ "kind-of": "^6.0.0"
+ }
+ },
+ "is-descriptor": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz",
+ "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==",
+ "dev": true,
+ "requires": {
+ "is-accessor-descriptor": "^1.0.0",
+ "is-data-descriptor": "^1.0.0",
+ "kind-of": "^6.0.2"
+ }
+ }
+ }
+ },
+ "big.js": {
+ "version": "5.2.2",
+ "resolved": "https://registry.npmjs.org/big.js/-/big.js-5.2.2.tgz",
+ "integrity": "sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==",
+ "dev": true
+ },
+ "binary-extensions": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.1.0.tgz",
+ "integrity": "sha512-1Yj8h9Q+QDF5FzhMs/c9+6UntbD5MkRfRwac8DoEm9ZfUBZ7tZ55YcGVAzEe4bXsdQHEk+s9S5wsOKVdZrw0tQ==",
+ "dev": true
+ },
+ "boxen": {
+ "version": "4.2.0",
+ "resolved": "https://registry.npmjs.org/boxen/-/boxen-4.2.0.tgz",
+ "integrity": "sha512-eB4uT9RGzg2odpER62bBwSLvUeGC+WbRjjyyFhGsKnc8wp/m0+hQsMUvUe3H2V0D5vw0nBdO1hCJoZo5mKeuIQ==",
+ "dev": true,
+ "requires": {
+ "ansi-align": "^3.0.0",
+ "camelcase": "^5.3.1",
+ "chalk": "^3.0.0",
+ "cli-boxes": "^2.2.0",
+ "string-width": "^4.1.0",
+ "term-size": "^2.1.0",
+ "type-fest": "^0.8.1",
+ "widest-line": "^3.1.0"
+ },
+ "dependencies": {
+ "ansi-styles": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
+ "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
+ "dev": true,
+ "requires": {
+ "color-convert": "^2.0.1"
+ }
+ },
+ "chalk": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz",
+ "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==",
+ "dev": true,
+ "requires": {
+ "ansi-styles": "^4.1.0",
+ "supports-color": "^7.1.0"
+ }
+ },
+ "color-convert": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
+ "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
+ "dev": true,
+ "requires": {
+ "color-name": "~1.1.4"
+ }
+ },
+ "color-name": {
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
+ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
+ "dev": true
+ },
+ "has-flag": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
+ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
+ "dev": true
+ },
+ "supports-color": {
+ "version": "7.2.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
+ "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
+ "dev": true,
+ "requires": {
+ "has-flag": "^4.0.0"
+ }
+ }
+ }
+ },
+ "brace-expansion": {
+ "version": "1.1.12",
+ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz",
+ "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==",
+ "requires": {
+ "balanced-match": "^1.0.0",
+ "concat-map": "0.0.1"
+ }
+ },
+ "braces": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz",
+ "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==",
+ "dev": true,
+ "requires": {
+ "fill-range": "^7.0.1"
+ }
+ },
+ "browser-stdout": {
+ "version": "1.3.1",
+ "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz",
+ "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==",
+ "dev": true
+ },
+ "browserslist": {
+ "version": "4.20.4",
+ "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.20.4.tgz",
+ "integrity": "sha512-ok1d+1WpnU24XYN7oC3QWgTyMhY/avPJ/r9T00xxvUOIparA/gc+UPUMaod3i+G6s+nI2nUb9xZ5k794uIwShw==",
+ "dev": true,
+ "requires": {
+ "caniuse-lite": "^1.0.30001349",
+ "electron-to-chromium": "^1.4.147",
+ "escalade": "^3.1.1",
+ "node-releases": "^2.0.5",
+ "picocolors": "^1.0.0"
+ },
+ "dependencies": {
+ "electron-to-chromium": {
+ "version": "1.4.158",
+ "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.158.tgz",
+ "integrity": "sha512-gppO3/+Y6sP432HtvwvuU8S+YYYLH4PmAYvQwqUtt9HDOmEsBwQfLnK9T8+1NIKwAS1BEygIjTaATC4H5EzvxQ==",
+ "dev": true
+ },
+ "node-releases": {
+ "version": "2.0.5",
+ "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.5.tgz",
+ "integrity": "sha512-U9h1NLROZTq9uE1SNffn6WuPDg8icmi3ns4rEl/oTfIle4iLjTliCzgTsbaIFMq/Xn078/lfY/BL0GWZ+psK4Q==",
+ "dev": true
+ }
+ }
+ },
+ "buf-compare": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/buf-compare/-/buf-compare-1.0.1.tgz",
+ "integrity": "sha1-/vKNqLgROgoNtEMLC2Rntpcws0o=",
+ "dev": true
+ },
+ "buffer-from": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz",
+ "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==",
+ "dev": true
+ },
+ "cache-base": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/cache-base/-/cache-base-1.0.1.tgz",
+ "integrity": "sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ==",
+ "dev": true,
+ "requires": {
+ "collection-visit": "^1.0.0",
+ "component-emitter": "^1.2.1",
+ "get-value": "^2.0.6",
+ "has-value": "^1.0.0",
+ "isobject": "^3.0.1",
+ "set-value": "^2.0.0",
+ "to-object-path": "^0.3.0",
+ "union-value": "^1.0.0",
+ "unset-value": "^1.0.0"
+ }
+ },
+ "cacheable-request": {
+ "version": "6.1.0",
+ "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-6.1.0.tgz",
+ "integrity": "sha512-Oj3cAGPCqOZX7Rz64Uny2GYAZNliQSqfbePrgAQ1wKAihYmCUnraBtJtKcGR4xz7wF+LoJC+ssFZvv5BgF9Igg==",
+ "dev": true,
+ "requires": {
+ "clone-response": "^1.0.2",
+ "get-stream": "^5.1.0",
+ "http-cache-semantics": "^4.0.0",
+ "keyv": "^3.0.0",
+ "lowercase-keys": "^2.0.0",
+ "normalize-url": "^4.1.0",
+ "responselike": "^1.0.2"
+ },
+ "dependencies": {
+ "get-stream": {
+ "version": "5.2.0",
+ "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz",
+ "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==",
+ "dev": true,
+ "requires": {
+ "pump": "^3.0.0"
+ }
+ },
+ "lowercase-keys": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-2.0.0.tgz",
+ "integrity": "sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA==",
+ "dev": true
+ }
+ }
+ },
+ "call-bind": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.0.tgz",
+ "integrity": "sha512-AEXsYIyyDY3MCzbwdhzG3Jx1R0J2wetQyUynn6dYHAO+bg8l1k7jwZtRv4ryryFs7EP+NDlikJlVe59jr0cM2w==",
+ "dev": true,
+ "requires": {
+ "function-bind": "^1.1.1",
+ "get-intrinsic": "^1.0.0"
+ }
+ },
+ "call-me-maybe": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/call-me-maybe/-/call-me-maybe-1.0.1.tgz",
+ "integrity": "sha1-JtII6onje1y95gJQoV8DHBak1ms=",
+ "dev": true
+ },
+ "callsites": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz",
+ "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==",
+ "dev": true
+ },
+ "camelcase": {
+ "version": "5.3.1",
+ "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz",
+ "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==",
+ "dev": true
+ },
+ "camelcase-keys": {
+ "version": "4.2.0",
+ "resolved": "https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-4.2.0.tgz",
+ "integrity": "sha1-oqpfsa9oh1glnDLBQUJteJI7m3c=",
+ "dev": true,
+ "requires": {
+ "camelcase": "^4.1.0",
+ "map-obj": "^2.0.0",
+ "quick-lru": "^1.0.0"
+ },
+ "dependencies": {
+ "camelcase": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-4.1.0.tgz",
+ "integrity": "sha1-1UVjW+HjPFQmScaRc+Xeas+uNN0=",
+ "dev": true
+ }
+ }
+ },
+ "caniuse-lite": {
+ "version": "1.0.30001441",
+ "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001441.tgz",
+ "integrity": "sha512-OyxRR4Vof59I3yGWXws6i908EtGbMzVUi3ganaZQHmydk1iwDhRnvaPG2WaR0KcqrDFKrxVZHULT396LEPhXfg==",
+ "dev": true
+ },
+ "chalk": {
+ "version": "2.4.2",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
+ "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
+ "dev": true,
+ "requires": {
+ "ansi-styles": "^3.2.1",
+ "escape-string-regexp": "^1.0.5",
+ "supports-color": "^5.3.0"
+ }
+ },
+ "chardet": {
+ "version": "0.7.0",
+ "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.7.0.tgz",
+ "integrity": "sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==",
+ "dev": true
+ },
+ "chokidar": {
+ "version": "3.5.3",
+ "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz",
+ "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==",
+ "dev": true,
+ "requires": {
+ "anymatch": "~3.1.2",
+ "braces": "~3.0.2",
+ "fsevents": "~2.3.2",
+ "glob-parent": "~5.1.2",
+ "is-binary-path": "~2.1.0",
+ "is-glob": "~4.0.1",
+ "normalize-path": "~3.0.0",
+ "readdirp": "~3.6.0"
+ }
+ },
+ "chrome-trace-event": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.2.tgz",
+ "integrity": "sha512-9e/zx1jw7B4CO+c/RXoCsfg/x1AfUBioy4owYH0bJprEYAx5hRFLRhWBqHAG57D0ZM4H7vxbP7bPe0VwhQRYDQ==",
+ "dev": true,
+ "requires": {
+ "tslib": "^1.9.0"
+ }
+ },
+ "ci-info": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-2.0.0.tgz",
+ "integrity": "sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ==",
+ "dev": true
+ },
+ "class-utils": {
+ "version": "0.3.6",
+ "resolved": "https://registry.npmjs.org/class-utils/-/class-utils-0.3.6.tgz",
+ "integrity": "sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg==",
+ "dev": true,
+ "requires": {
+ "arr-union": "^3.1.0",
+ "define-property": "^0.2.5",
+ "isobject": "^3.0.0",
+ "static-extend": "^0.1.1"
+ },
+ "dependencies": {
+ "define-property": {
+ "version": "0.2.5",
+ "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz",
+ "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=",
+ "dev": true,
+ "requires": {
+ "is-descriptor": "^0.1.0"
+ }
+ }
+ }
+ },
+ "clean-regexp": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/clean-regexp/-/clean-regexp-1.0.0.tgz",
+ "integrity": "sha1-jffHquUf02h06PjQW5GAvBGj/tc=",
+ "dev": true,
+ "requires": {
+ "escape-string-regexp": "^1.0.5"
+ }
+ },
+ "cli-boxes": {
+ "version": "2.2.1",
+ "resolved": "https://registry.npmjs.org/cli-boxes/-/cli-boxes-2.2.1.tgz",
+ "integrity": "sha512-y4coMcylgSCdVinjiDBuR8PCC2bLjyGTwEmPb9NHR/QaNU6EUOXcTY/s6VjGMD6ENSEaeQYHCY0GNGS5jfMwPw==",
+ "dev": true
+ },
+ "cli-cursor": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz",
+ "integrity": "sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==",
+ "dev": true,
+ "requires": {
+ "restore-cursor": "^3.1.0"
+ }
+ },
+ "cli-width": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-3.0.0.tgz",
+ "integrity": "sha512-FxqpkPPwu1HjuN93Omfm4h8uIanXofW0RxVEW3k5RKx+mJJYSthzNhp32Kzxxy3YAEZ/Dc/EWN1vZRY0+kOhbw==",
+ "dev": true
+ },
+ "clone-deep": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/clone-deep/-/clone-deep-4.0.1.tgz",
+ "integrity": "sha512-neHB9xuzh/wk0dIHweyAXv2aPGZIVk3pLMe+/RNzINf17fe0OG96QroktYAUm7SM1PBnzTabaLboqqxDyMU+SQ==",
+ "dev": true,
+ "requires": {
+ "is-plain-object": "^2.0.4",
+ "kind-of": "^6.0.2",
+ "shallow-clone": "^3.0.0"
+ }
+ },
+ "clone-response": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/clone-response/-/clone-response-1.0.2.tgz",
+ "integrity": "sha1-0dyXOSAxTfZ/vrlCI7TuNQI56Ws=",
+ "dev": true,
+ "requires": {
+ "mimic-response": "^1.0.0"
+ }
+ },
+ "collection-visit": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/collection-visit/-/collection-visit-1.0.0.tgz",
+ "integrity": "sha1-S8A3PBZLwykbTTaMgpzxqApZ3KA=",
+ "dev": true,
+ "requires": {
+ "map-visit": "^1.0.0",
+ "object-visit": "^1.0.0"
+ }
+ },
+ "color-convert": {
+ "version": "1.9.3",
+ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz",
+ "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==",
+ "dev": true,
+ "requires": {
+ "color-name": "1.1.3"
+ }
+ },
+ "color-name": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
+ "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=",
+ "dev": true
+ },
+ "colorette": {
+ "version": "2.0.19",
+ "resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.19.tgz",
+ "integrity": "sha512-3tlv/dIP7FWvj3BsbHrGLJ6l/oKh1O3TcgBqMn+yyCagOxc23fyzDS6HypQbgxWbkpDnf52p1LuR4eWDQ/K9WQ==",
+ "dev": true
+ },
+ "commander": {
+ "version": "2.20.3",
+ "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz",
+ "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==",
+ "dev": true
+ },
+ "commondir": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz",
+ "integrity": "sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs=",
+ "dev": true
+ },
+ "component-emitter": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.0.tgz",
+ "integrity": "sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg==",
+ "dev": true
+ },
+ "concat-map": {
+ "version": "0.0.1",
+ "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
+ "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s="
+ },
+ "configstore": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/configstore/-/configstore-5.0.1.tgz",
+ "integrity": "sha512-aMKprgk5YhBNyH25hj8wGt2+D52Sw1DRRIzqBwLp2Ya9mFmY8KPvvtvmna8SxVR9JMZ4kzMD68N22vlaRpkeFA==",
+ "dev": true,
+ "requires": {
+ "dot-prop": "^5.2.0",
+ "graceful-fs": "^4.1.2",
+ "make-dir": "^3.0.0",
+ "unique-string": "^2.0.0",
+ "write-file-atomic": "^3.0.0",
+ "xdg-basedir": "^4.0.0"
+ }
+ },
+ "confusing-browser-globals": {
+ "version": "1.0.9",
+ "resolved": "https://registry.npmjs.org/confusing-browser-globals/-/confusing-browser-globals-1.0.9.tgz",
+ "integrity": "sha512-KbS1Y0jMtyPgIxjO7ZzMAuUpAKMt1SzCL9fsrKsX6b0zJPTaT0SiSPmewwVZg9UAO83HVIlEhZF84LIjZ0lmAw==",
+ "dev": true
+ },
+ "contains-path": {
+ "version": "0.1.0",
+ "resolved": "https://registry.npmjs.org/contains-path/-/contains-path-0.1.0.tgz",
+ "integrity": "sha1-/ozxhP9mcLa67wGp1IYaXL7EEgo=",
+ "dev": true
+ },
+ "convert-source-map": {
+ "version": "1.7.0",
+ "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.7.0.tgz",
+ "integrity": "sha512-4FJkXzKXEDB1snCFZlLP4gpC3JILicCpGbzG9f9G7tGqGCzETQ2hWPrcinA9oU4wtf2biUaEH5065UnMeR33oA==",
+ "dev": true,
+ "requires": {
+ "safe-buffer": "~5.1.1"
+ }
+ },
+ "copy-descriptor": {
+ "version": "0.1.1",
+ "resolved": "https://registry.npmjs.org/copy-descriptor/-/copy-descriptor-0.1.1.tgz",
+ "integrity": "sha1-Z29us8OZl8LuGsOpJP1hJHSPV40=",
+ "dev": true
+ },
+ "core-assert": {
+ "version": "0.2.1",
+ "resolved": "https://registry.npmjs.org/core-assert/-/core-assert-0.2.1.tgz",
+ "integrity": "sha1-+F4s+b/tKPdzzIs/pcW2m9wC/j8=",
+ "dev": true,
+ "requires": {
+ "buf-compare": "^1.0.0",
+ "is-error": "^2.2.0"
+ }
+ },
+ "core-js-compat": {
+ "version": "3.6.5",
+ "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.6.5.tgz",
+ "integrity": "sha512-7ItTKOhOZbznhXAQ2g/slGg1PJV5zDO/WdkTwi7UEOJmkvsE32PWvx6mKtDjiMpjnR2CNf6BAD6sSxIlv7ptng==",
+ "dev": true,
+ "requires": {
+ "browserslist": "^4.8.5",
+ "semver": "7.0.0"
+ },
+ "dependencies": {
+ "semver": {
+ "version": "7.0.0",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-7.0.0.tgz",
+ "integrity": "sha512-+GB6zVA9LWh6zovYQLALHwv5rb2PHGlJi3lfiqIHxR0uuwCgefcOJc59v9fv1w8GbStwxuuqqAjI9NMAOOgq1A==",
+ "dev": true
+ }
+ }
+ },
+ "core-util-is": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz",
+ "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=",
+ "dev": true
+ },
+ "cross-spawn": {
+ "version": "6.0.5",
+ "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz",
+ "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==",
+ "dev": true,
+ "requires": {
+ "nice-try": "^1.0.4",
+ "path-key": "^2.0.1",
+ "semver": "^5.5.0",
+ "shebang-command": "^1.2.0",
+ "which": "^1.2.9"
+ }
+ },
+ "crypto-random-string": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/crypto-random-string/-/crypto-random-string-2.0.0.tgz",
+ "integrity": "sha512-v1plID3y9r/lPhviJ1wrXpLeyUIGAZ2SHNYTEapm7/8A9nLPoyvVp3RK/EPFqn5kEznyWgYZNsRtYYIWbuG8KA==",
+ "dev": true
+ },
+ "currently-unhandled": {
+ "version": "0.4.1",
+ "resolved": "https://registry.npmjs.org/currently-unhandled/-/currently-unhandled-0.4.1.tgz",
+ "integrity": "sha1-mI3zP+qxke95mmE2nddsF635V+o=",
+ "dev": true,
+ "requires": {
+ "array-find-index": "^1.0.1"
+ }
+ },
+ "debug": {
+ "version": "4.3.4",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz",
+ "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==",
+ "dev": true,
+ "requires": {
+ "ms": "2.1.2"
+ }
+ },
+ "decamelize": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz",
+ "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=",
+ "dev": true
+ },
+ "decamelize-keys": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/decamelize-keys/-/decamelize-keys-1.1.0.tgz",
+ "integrity": "sha1-0XGoeTMlKAfrPLYdwcFEXQeN8tk=",
+ "dev": true,
+ "requires": {
+ "decamelize": "^1.1.0",
+ "map-obj": "^1.0.0"
+ },
+ "dependencies": {
+ "map-obj": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-1.0.1.tgz",
+ "integrity": "sha1-2TPOuSBdgr3PSIb2dCvcK03qFG0=",
+ "dev": true
+ }
+ }
+ },
+ "decode-uri-component": {
+ "version": "0.2.2",
+ "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.2.tgz",
+ "integrity": "sha512-FqUYQ+8o158GyGTrMFJms9qh3CqTKvAqgqsTnkLI8sKu0028orqBhxNMFkFen0zGyg6epACD32pjVk58ngIErQ==",
+ "dev": true
+ },
+ "decompress-response": {
+ "version": "3.3.0",
+ "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-3.3.0.tgz",
+ "integrity": "sha1-gKTdMjdIOEv6JICDYirt7Jgq3/M=",
+ "dev": true,
+ "requires": {
+ "mimic-response": "^1.0.0"
+ }
+ },
+ "deep-extend": {
+ "version": "0.6.0",
+ "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz",
+ "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==",
+ "dev": true
+ },
+ "deep-is": {
+ "version": "0.1.3",
+ "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz",
+ "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=",
+ "dev": true
+ },
+ "deep-strict-equal": {
+ "version": "0.2.0",
+ "resolved": "https://registry.npmjs.org/deep-strict-equal/-/deep-strict-equal-0.2.0.tgz",
+ "integrity": "sha1-SgeBR6irV/ag1PVUckPNIvROtOQ=",
+ "dev": true,
+ "requires": {
+ "core-assert": "^0.2.0"
+ }
+ },
+ "defer-to-connect": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/defer-to-connect/-/defer-to-connect-1.1.3.tgz",
+ "integrity": "sha512-0ISdNousHvZT2EiFlZeZAHBUvSxmKswVCEf8hW7KWgG4a8MVEu/3Vb6uWYozkjylyCxe0JBIiRB1jV45S70WVQ==",
+ "dev": true
+ },
+ "define-properties": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz",
+ "integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==",
+ "dev": true,
+ "requires": {
+ "object-keys": "^1.0.12"
+ }
+ },
+ "define-property": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz",
+ "integrity": "sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==",
+ "dev": true,
+ "requires": {
+ "is-descriptor": "^1.0.2",
+ "isobject": "^3.0.1"
+ },
+ "dependencies": {
+ "is-accessor-descriptor": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz",
+ "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==",
+ "dev": true,
+ "requires": {
+ "kind-of": "^6.0.0"
+ }
+ },
+ "is-data-descriptor": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz",
+ "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==",
+ "dev": true,
+ "requires": {
+ "kind-of": "^6.0.0"
+ }
+ },
+ "is-descriptor": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz",
+ "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==",
+ "dev": true,
+ "requires": {
+ "is-accessor-descriptor": "^1.0.0",
+ "is-data-descriptor": "^1.0.0",
+ "kind-of": "^6.0.2"
+ }
+ }
+ }
+ },
+ "diff": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/diff/-/diff-5.0.0.tgz",
+ "integrity": "sha512-/VTCrvm5Z0JGty/BWHljh+BAiw3IK+2j87NGMu8Nwc/f48WoDAC395uomO9ZD117ZOBaHmkX1oyLvkVM/aIT3w==",
+ "dev": true
+ },
+ "dir-glob": {
+ "version": "2.2.2",
+ "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-2.2.2.tgz",
+ "integrity": "sha512-f9LBi5QWzIW3I6e//uxZoLBlUt9kcp66qo0sSCxL6YZKc75R1c4MFCoe/LaZiBGmgujvQdxc5Bn3QhfyvK5Hsw==",
+ "dev": true,
+ "requires": {
+ "path-type": "^3.0.0"
+ },
+ "dependencies": {
+ "path-type": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/path-type/-/path-type-3.0.0.tgz",
+ "integrity": "sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg==",
+ "dev": true,
+ "requires": {
+ "pify": "^3.0.0"
+ }
+ },
+ "pify": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz",
+ "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=",
+ "dev": true
+ }
+ }
+ },
+ "doctrine": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz",
+ "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==",
+ "dev": true,
+ "requires": {
+ "esutils": "^2.0.2"
+ }
+ },
+ "dot-prop": {
+ "version": "5.3.0",
+ "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-5.3.0.tgz",
+ "integrity": "sha512-QM8q3zDe58hqUqjraQOmzZ1LIH9SWQJTlEKCH4kJ2oQvLZk7RbQXvtDM2XEq3fwkV9CCvvH4LA0AV+ogFsBM2Q==",
+ "dev": true,
+ "requires": {
+ "is-obj": "^2.0.0"
+ }
+ },
+ "duplexer3": {
+ "version": "0.1.4",
+ "resolved": "https://registry.npmjs.org/duplexer3/-/duplexer3-0.1.4.tgz",
+ "integrity": "sha1-7gHdHKwO08vH/b6jfcCo8c4ALOI=",
+ "dev": true
+ },
+ "emoji-regex": {
+ "version": "7.0.3",
+ "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz",
+ "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==",
+ "dev": true
+ },
+ "emojis-list": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-3.0.0.tgz",
+ "integrity": "sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q==",
+ "dev": true
+ },
+ "end-of-stream": {
+ "version": "1.4.4",
+ "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz",
+ "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==",
+ "dev": true,
+ "requires": {
+ "once": "^1.4.0"
+ }
+ },
+ "enhance-visitors": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/enhance-visitors/-/enhance-visitors-1.0.0.tgz",
+ "integrity": "sha1-qpRdBdpGVnKh69OP7i7T2oUY6Vo=",
+ "dev": true,
+ "requires": {
+ "lodash": "^4.13.1"
+ }
+ },
+ "enhanced-resolve": {
+ "version": "5.12.0",
+ "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.12.0.tgz",
+ "integrity": "sha512-QHTXI/sZQmko1cbDoNAa3mJ5qhWUUNAq3vR0/YiD379fWQrcfuoX1+HW2S0MTt7XmoPLapdaDKUtelUSPic7hQ==",
+ "dev": true,
+ "requires": {
+ "graceful-fs": "^4.2.4",
+ "tapable": "^2.2.0"
+ }
+ },
+ "env-editor": {
+ "version": "0.4.1",
+ "resolved": "https://registry.npmjs.org/env-editor/-/env-editor-0.4.1.tgz",
+ "integrity": "sha512-suh+Vm00GnPQgXpmONTkcUT9LgBSL6sJrRnJxbykT0j+ONjzmIS+1U3ne467ArdZN/42/npp+GnhtwkLQ+vUjw==",
+ "dev": true
+ },
+ "envinfo": {
+ "version": "7.8.1",
+ "resolved": "https://registry.npmjs.org/envinfo/-/envinfo-7.8.1.tgz",
+ "integrity": "sha512-/o+BXHmB7ocbHEAs6F2EnG0ogybVVUdkRunTT2glZU9XAaGmhqskrvKwqXuDfNjEO0LZKWdejEEpnq8aM0tOaw==",
+ "dev": true
+ },
+ "error-ex": {
+ "version": "1.3.2",
+ "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz",
+ "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==",
+ "dev": true,
+ "requires": {
+ "is-arrayish": "^0.2.1"
+ }
+ },
+ "es-abstract": {
+ "version": "1.17.7",
+ "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.17.7.tgz",
+ "integrity": "sha512-VBl/gnfcJ7OercKA9MVaegWsBHFjV492syMudcnQZvt/Dw8ezpcOHYZXa/J96O8vx+g4x65YKhxOwDUh63aS5g==",
+ "dev": true,
+ "requires": {
+ "es-to-primitive": "^1.2.1",
+ "function-bind": "^1.1.1",
+ "has": "^1.0.3",
+ "has-symbols": "^1.0.1",
+ "is-callable": "^1.2.2",
+ "is-regex": "^1.1.1",
+ "object-inspect": "^1.8.0",
+ "object-keys": "^1.1.1",
+ "object.assign": "^4.1.1",
+ "string.prototype.trimend": "^1.0.1",
+ "string.prototype.trimstart": "^1.0.1"
+ }
+ },
+ "es-module-lexer": {
+ "version": "0.9.3",
+ "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-0.9.3.tgz",
+ "integrity": "sha512-1HQ2M2sPtxwnvOvT1ZClHyQDiggdNjURWpY2we6aMKCQiUVxTmVs2UYPLIrD84sS+kMdUwfBSylbJPwNnBrnHQ==",
+ "dev": true
+ },
+ "es-to-primitive": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz",
+ "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==",
+ "dev": true,
+ "requires": {
+ "is-callable": "^1.1.4",
+ "is-date-object": "^1.0.1",
+ "is-symbol": "^1.0.2"
+ }
+ },
+ "escalade": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz",
+ "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==",
+ "dev": true
+ },
+ "escape-goat": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/escape-goat/-/escape-goat-2.1.1.tgz",
+ "integrity": "sha512-8/uIhbG12Csjy2JEW7D9pHbreaVaS/OpN3ycnyvElTdwM5n6GY6W6e2IPemfvGZeUMqZ9A/3GqIZMgKnBhAw/Q==",
+ "dev": true
+ },
+ "escape-string-regexp": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
+ "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=",
+ "dev": true
+ },
+ "eslint": {
+ "version": "6.8.0",
+ "resolved": "https://registry.npmjs.org/eslint/-/eslint-6.8.0.tgz",
+ "integrity": "sha512-K+Iayyo2LtyYhDSYwz5D5QdWw0hCacNzyq1Y821Xna2xSJj7cijoLLYmLxTQgcgZ9mC61nryMy9S7GRbYpI5Ig==",
+ "dev": true,
+ "requires": {
+ "@babel/code-frame": "^7.0.0",
+ "ajv": "^6.10.0",
+ "chalk": "^2.1.0",
+ "cross-spawn": "^6.0.5",
+ "debug": "^4.0.1",
+ "doctrine": "^3.0.0",
+ "eslint-scope": "^5.0.0",
+ "eslint-utils": "^1.4.3",
+ "eslint-visitor-keys": "^1.1.0",
+ "espree": "^6.1.2",
+ "esquery": "^1.0.1",
+ "esutils": "^2.0.2",
+ "file-entry-cache": "^5.0.1",
+ "functional-red-black-tree": "^1.0.1",
+ "glob-parent": "^5.0.0",
+ "globals": "^12.1.0",
+ "ignore": "^4.0.6",
+ "import-fresh": "^3.0.0",
+ "imurmurhash": "^0.1.4",
+ "inquirer": "^7.0.0",
+ "is-glob": "^4.0.0",
+ "js-yaml": "^3.13.1",
+ "json-stable-stringify-without-jsonify": "^1.0.1",
+ "levn": "^0.3.0",
+ "lodash": "^4.17.14",
+ "minimatch": "^3.0.4",
+ "mkdirp": "^0.5.1",
+ "natural-compare": "^1.4.0",
+ "optionator": "^0.8.3",
+ "progress": "^2.0.0",
+ "regexpp": "^2.0.1",
+ "semver": "^6.1.2",
+ "strip-ansi": "^5.2.0",
+ "strip-json-comments": "^3.0.1",
+ "table": "^5.2.3",
+ "text-table": "^0.2.0",
+ "v8-compile-cache": "^2.0.3"
+ },
+ "dependencies": {
+ "ansi-regex": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.1.tgz",
+ "integrity": "sha512-ILlv4k/3f6vfQ4OoP2AGvirOktlQ98ZEL1k9FaQjxa3L1abBgbuTDAdPOpvbGncC0BTVQrl+OM8xZGK6tWXt7g==",
+ "dev": true
+ },
+ "eslint-utils": {
+ "version": "1.4.3",
+ "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-1.4.3.tgz",
+ "integrity": "sha512-fbBN5W2xdY45KulGXmLHZ3c3FHfVYmKg0IrAKGOkT/464PQsx2UeIzfz1RmEci+KLm1bBaAzZAh8+/E+XAeZ8Q==",
+ "dev": true,
+ "requires": {
+ "eslint-visitor-keys": "^1.1.0"
+ }
+ },
+ "globals": {
+ "version": "12.4.0",
+ "resolved": "https://registry.npmjs.org/globals/-/globals-12.4.0.tgz",
+ "integrity": "sha512-BWICuzzDvDoH54NHKCseDanAhE3CeDorgDL5MT6LMXXj2WCnd9UC2szdk4AWLfjdgNBCXLUanXYcpBBKOSWGwg==",
+ "dev": true,
+ "requires": {
+ "type-fest": "^0.8.1"
+ }
+ },
+ "semver": {
+ "version": "6.3.0",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
+ "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
+ "dev": true
+ },
+ "strip-ansi": {
+ "version": "5.2.0",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz",
+ "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==",
+ "dev": true,
+ "requires": {
+ "ansi-regex": "^4.1.0"
+ }
+ },
+ "strip-json-comments": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz",
+ "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==",
+ "dev": true
+ }
+ }
+ },
+ "eslint-ast-utils": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/eslint-ast-utils/-/eslint-ast-utils-1.1.0.tgz",
+ "integrity": "sha512-otzzTim2/1+lVrlH19EfQQJEhVJSu0zOb9ygb3iapN6UlyaDtyRq4b5U1FuW0v1lRa9Fp/GJyHkSwm6NqABgCA==",
+ "dev": true,
+ "requires": {
+ "lodash.get": "^4.4.2",
+ "lodash.zip": "^4.2.0"
+ }
+ },
+ "eslint-config-prettier": {
+ "version": "6.15.0",
+ "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-6.15.0.tgz",
+ "integrity": "sha512-a1+kOYLR8wMGustcgAjdydMsQ2A/2ipRPwRKUmfYaSxc9ZPcrku080Ctl6zrZzZNs/U82MjSv+qKREkoq3bJaw==",
+ "dev": true,
+ "requires": {
+ "get-stdin": "^6.0.0"
+ },
+ "dependencies": {
+ "get-stdin": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-6.0.0.tgz",
+ "integrity": "sha512-jp4tHawyV7+fkkSKyvjuLZswblUtz+SQKzSWnBbii16BuZksJlU1wuBYXY75r+duh/llF1ur6oNwi+2ZzjKZ7g==",
+ "dev": true
+ }
+ }
+ },
+ "eslint-config-xo": {
+ "version": "0.29.1",
+ "resolved": "https://registry.npmjs.org/eslint-config-xo/-/eslint-config-xo-0.29.1.tgz",
+ "integrity": "sha512-RDjeKh8CV0/EH4utW/6uOkwJJOOU+rX3uE5eUBOamcLNe4lNjyo8kSt3B6DzAm1L/1tWGikI7LFNVY9gG7PDQw==",
+ "dev": true,
+ "requires": {
+ "confusing-browser-globals": "1.0.9"
+ }
+ },
+ "eslint-formatter-pretty": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/eslint-formatter-pretty/-/eslint-formatter-pretty-3.0.1.tgz",
+ "integrity": "sha512-hhQ/ASD4i6BAEalcEfUxesFtJFftT8xFsimCzUpPbTzygJ4J17yCGcJ3XKCB2g7XTJTv0pi7rVTadfHVmtfSRA==",
+ "dev": true,
+ "requires": {
+ "ansi-escapes": "^4.2.1",
+ "chalk": "^3.0.0",
+ "eslint-rule-docs": "^1.1.5",
+ "log-symbols": "^3.0.0",
+ "plur": "^3.0.1",
+ "string-width": "^4.2.0",
+ "supports-hyperlinks": "^2.0.0"
+ },
+ "dependencies": {
+ "ansi-styles": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
+ "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
+ "dev": true,
+ "requires": {
+ "color-convert": "^2.0.1"
+ }
+ },
+ "chalk": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz",
+ "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==",
+ "dev": true,
+ "requires": {
+ "ansi-styles": "^4.1.0",
+ "supports-color": "^7.1.0"
+ }
+ },
+ "color-convert": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
+ "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
+ "dev": true,
+ "requires": {
+ "color-name": "~1.1.4"
+ }
+ },
+ "color-name": {
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
+ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
+ "dev": true
+ },
+ "has-flag": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
+ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
+ "dev": true
+ },
+ "supports-color": {
+ "version": "7.2.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
+ "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
+ "dev": true,
+ "requires": {
+ "has-flag": "^4.0.0"
+ }
+ }
+ }
+ },
+ "eslint-import-resolver-node": {
+ "version": "0.3.4",
+ "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.4.tgz",
+ "integrity": "sha512-ogtf+5AB/O+nM6DIeBUNr2fuT7ot9Qg/1harBfBtaP13ekEWFQEEMP94BCB7zaNW3gyY+8SHYF00rnqYwXKWOA==",
+ "dev": true,
+ "requires": {
+ "debug": "^2.6.9",
+ "resolve": "^1.13.1"
+ },
+ "dependencies": {
+ "debug": {
+ "version": "2.6.9",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
+ "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
+ "dev": true,
+ "requires": {
+ "ms": "2.0.0"
+ }
+ },
+ "ms": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
+ "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=",
+ "dev": true
+ }
+ }
+ },
+ "eslint-module-utils": {
+ "version": "2.6.0",
+ "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.6.0.tgz",
+ "integrity": "sha512-6j9xxegbqe8/kZY8cYpcp0xhbK0EgJlg3g9mib3/miLaExuuwc3n5UEfSnU6hWMbT0FAYVvDbL9RrRgpUeQIvA==",
+ "dev": true,
+ "requires": {
+ "debug": "^2.6.9",
+ "pkg-dir": "^2.0.0"
+ },
+ "dependencies": {
+ "debug": {
+ "version": "2.6.9",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
+ "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
+ "dev": true,
+ "requires": {
+ "ms": "2.0.0"
+ }
+ },
+ "find-up": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz",
+ "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=",
+ "dev": true,
+ "requires": {
+ "locate-path": "^2.0.0"
+ }
+ },
+ "locate-path": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz",
+ "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=",
+ "dev": true,
+ "requires": {
+ "p-locate": "^2.0.0",
+ "path-exists": "^3.0.0"
+ }
+ },
+ "ms": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
+ "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=",
+ "dev": true
+ },
+ "p-limit": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz",
+ "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==",
+ "dev": true,
+ "requires": {
+ "p-try": "^1.0.0"
+ }
+ },
+ "p-locate": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz",
+ "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=",
+ "dev": true,
+ "requires": {
+ "p-limit": "^1.1.0"
+ }
+ },
+ "p-try": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz",
+ "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=",
+ "dev": true
+ },
+ "pkg-dir": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-2.0.0.tgz",
+ "integrity": "sha1-9tXREJ4Z1j7fQo4L1X4Sd3YVM0s=",
+ "dev": true,
+ "requires": {
+ "find-up": "^2.1.0"
+ }
+ }
+ }
+ },
+ "eslint-plugin-ava": {
+ "version": "10.5.0",
+ "resolved": "https://registry.npmjs.org/eslint-plugin-ava/-/eslint-plugin-ava-10.5.0.tgz",
+ "integrity": "sha512-2I0Ze8ZtwbSlLdnzms4bsa6PxxOxGMIJ9d4yy7aRy3yc5zEO2wHJLic8l3Lrct73hb5ML+PLt5VRqvdV87xWdQ==",
+ "dev": true,
+ "requires": {
+ "deep-strict-equal": "^0.2.0",
+ "enhance-visitors": "^1.0.0",
+ "espree": "^7.1.0",
+ "espurify": "^2.0.1",
+ "import-modules": "^2.0.0",
+ "micro-spelling-correcter": "^1.1.1",
+ "pkg-dir": "^4.2.0",
+ "resolve-from": "^5.0.0"
+ },
+ "dependencies": {
+ "acorn": {
+ "version": "7.4.1",
+ "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz",
+ "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==",
+ "dev": true
+ },
+ "espree": {
+ "version": "7.3.0",
+ "resolved": "https://registry.npmjs.org/espree/-/espree-7.3.0.tgz",
+ "integrity": "sha512-dksIWsvKCixn1yrEXO8UosNSxaDoSYpq9reEjZSbHLpT5hpaCAKTLBwq0RHtLrIr+c0ByiYzWT8KTMRzoRCNlw==",
+ "dev": true,
+ "requires": {
+ "acorn": "^7.4.0",
+ "acorn-jsx": "^5.2.0",
+ "eslint-visitor-keys": "^1.3.0"
+ }
+ }
+ }
+ },
+ "eslint-plugin-es": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/eslint-plugin-es/-/eslint-plugin-es-3.0.1.tgz",
+ "integrity": "sha512-GUmAsJaN4Fc7Gbtl8uOBlayo2DqhwWvEzykMHSCZHU3XdJ+NSzzZcVhXh3VxX5icqQ+oQdIEawXX8xkR3mIFmQ==",
+ "dev": true,
+ "requires": {
+ "eslint-utils": "^2.0.0",
+ "regexpp": "^3.0.0"
+ },
+ "dependencies": {
+ "regexpp": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.1.0.tgz",
+ "integrity": "sha512-ZOIzd8yVsQQA7j8GCSlPGXwg5PfmA1mrq0JP4nGhh54LaKN3xdai/vHUDu74pKwV8OxseMS65u2NImosQcSD0Q==",
+ "dev": true
+ }
+ }
+ },
+ "eslint-plugin-eslint-comments": {
+ "version": "3.2.0",
+ "resolved": "https://registry.npmjs.org/eslint-plugin-eslint-comments/-/eslint-plugin-eslint-comments-3.2.0.tgz",
+ "integrity": "sha512-0jkOl0hfojIHHmEHgmNdqv4fmh7300NdpA9FFpF7zaoLvB/QeXOGNLIo86oAveJFrfB1p05kC8hpEMHM8DwWVQ==",
+ "dev": true,
+ "requires": {
+ "escape-string-regexp": "^1.0.5",
+ "ignore": "^5.0.5"
+ },
+ "dependencies": {
+ "ignore": {
+ "version": "5.1.8",
+ "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.1.8.tgz",
+ "integrity": "sha512-BMpfD7PpiETpBl/A6S498BaIJ6Y/ABT93ETbby2fP00v4EbvPBXWEoaR1UBPKs3iR53pJY7EtZk5KACI57i1Uw==",
+ "dev": true
+ }
+ }
+ },
+ "eslint-plugin-import": {
+ "version": "2.22.1",
+ "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.22.1.tgz",
+ "integrity": "sha512-8K7JjINHOpH64ozkAhpT3sd+FswIZTfMZTjdx052pnWrgRCVfp8op9tbjpAk3DdUeI/Ba4C8OjdC0r90erHEOw==",
+ "dev": true,
+ "requires": {
+ "array-includes": "^3.1.1",
+ "array.prototype.flat": "^1.2.3",
+ "contains-path": "^0.1.0",
+ "debug": "^2.6.9",
+ "doctrine": "1.5.0",
+ "eslint-import-resolver-node": "^0.3.4",
+ "eslint-module-utils": "^2.6.0",
+ "has": "^1.0.3",
+ "minimatch": "^3.0.4",
+ "object.values": "^1.1.1",
+ "read-pkg-up": "^2.0.0",
+ "resolve": "^1.17.0",
+ "tsconfig-paths": "^3.9.0"
+ },
+ "dependencies": {
+ "debug": {
+ "version": "2.6.9",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
+ "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
+ "dev": true,
+ "requires": {
+ "ms": "2.0.0"
+ }
+ },
+ "doctrine": {
+ "version": "1.5.0",
+ "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-1.5.0.tgz",
+ "integrity": "sha1-N53Ocw9hZvds76TmcHoVmwLFpvo=",
+ "dev": true,
+ "requires": {
+ "esutils": "^2.0.2",
+ "isarray": "^1.0.0"
+ }
+ },
+ "isarray": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
+ "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=",
+ "dev": true
+ },
+ "ms": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
+ "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=",
+ "dev": true
+ }
+ }
+ },
+ "eslint-plugin-mocha": {
+ "version": "6.3.0",
+ "resolved": "https://registry.npmjs.org/eslint-plugin-mocha/-/eslint-plugin-mocha-6.3.0.tgz",
+ "integrity": "sha512-Cd2roo8caAyG21oKaaNTj7cqeYRWW1I2B5SfpKRp0Ip1gkfwoR1Ow0IGlPWnNjzywdF4n+kHL8/9vM6zCJUxdg==",
+ "dev": true,
+ "requires": {
+ "eslint-utils": "^2.0.0",
+ "ramda": "^0.27.0"
+ }
+ },
+ "eslint-plugin-no-use-extend-native": {
+ "version": "0.4.1",
+ "resolved": "https://registry.npmjs.org/eslint-plugin-no-use-extend-native/-/eslint-plugin-no-use-extend-native-0.4.1.tgz",
+ "integrity": "sha512-tDkHM0kvxU0M2TpLRKGfFrpWXctFdTDY7VkiDTLYDaX90hMSJKkr/FiWThEXvKV0Dvffut2Z0B9Y7+h/k6suiA==",
+ "dev": true,
+ "requires": {
+ "is-get-set-prop": "^1.0.0",
+ "is-js-type": "^2.0.0",
+ "is-obj-prop": "^1.0.0",
+ "is-proto-prop": "^2.0.0"
+ }
+ },
+ "eslint-plugin-node": {
+ "version": "11.1.0",
+ "resolved": "https://registry.npmjs.org/eslint-plugin-node/-/eslint-plugin-node-11.1.0.tgz",
+ "integrity": "sha512-oUwtPJ1W0SKD0Tr+wqu92c5xuCeQqB3hSCHasn/ZgjFdA9iDGNkNf2Zi9ztY7X+hNuMib23LNGRm6+uN+KLE3g==",
+ "dev": true,
+ "requires": {
+ "eslint-plugin-es": "^3.0.0",
+ "eslint-utils": "^2.0.0",
+ "ignore": "^5.1.1",
+ "minimatch": "^3.0.4",
+ "resolve": "^1.10.1",
+ "semver": "^6.1.0"
+ },
+ "dependencies": {
+ "ignore": {
+ "version": "5.1.8",
+ "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.1.8.tgz",
+ "integrity": "sha512-BMpfD7PpiETpBl/A6S498BaIJ6Y/ABT93ETbby2fP00v4EbvPBXWEoaR1UBPKs3iR53pJY7EtZk5KACI57i1Uw==",
+ "dev": true
+ },
+ "semver": {
+ "version": "6.3.0",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
+ "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
+ "dev": true
+ }
+ }
+ },
+ "eslint-plugin-prettier": {
+ "version": "3.1.4",
+ "resolved": "https://registry.npmjs.org/eslint-plugin-prettier/-/eslint-plugin-prettier-3.1.4.tgz",
+ "integrity": "sha512-jZDa8z76klRqo+TdGDTFJSavwbnWK2ZpqGKNZ+VvweMW516pDUMmQ2koXvxEE4JhzNvTv+radye/bWGBmA6jmg==",
+ "dev": true,
+ "requires": {
+ "prettier-linter-helpers": "^1.0.0"
+ }
+ },
+ "eslint-plugin-promise": {
+ "version": "4.2.1",
+ "resolved": "https://registry.npmjs.org/eslint-plugin-promise/-/eslint-plugin-promise-4.2.1.tgz",
+ "integrity": "sha512-VoM09vT7bfA7D+upt+FjeBO5eHIJQBUWki1aPvB+vbNiHS3+oGIJGIeyBtKQTME6UPXXy3vV07OL1tHd3ANuDw==",
+ "dev": true
+ },
+ "eslint-plugin-unicorn": {
+ "version": "16.1.1",
+ "resolved": "https://registry.npmjs.org/eslint-plugin-unicorn/-/eslint-plugin-unicorn-16.1.1.tgz",
+ "integrity": "sha512-IMxCsntb0T8s660Irc40gtzXtxuXHcOn36G9G8OYKfiseBD/kNrA1cNJhsJ0xQteDASGrFwqdzBsYEkUvczhOA==",
+ "dev": true,
+ "requires": {
+ "ci-info": "^2.0.0",
+ "clean-regexp": "^1.0.0",
+ "eslint-ast-utils": "^1.1.0",
+ "eslint-template-visitor": "^1.1.0",
+ "import-modules": "^2.0.0",
+ "lodash.camelcase": "^4.3.0",
+ "lodash.defaultsdeep": "^4.6.1",
+ "lodash.kebabcase": "^4.1.1",
+ "lodash.snakecase": "^4.1.1",
+ "lodash.upperfirst": "^4.3.1",
+ "read-pkg-up": "^7.0.1",
+ "regexp-tree": "^0.1.17",
+ "regexpp": "^3.0.0",
+ "reserved-words": "^0.1.2",
+ "safe-regex": "^2.1.1",
+ "semver": "^7.1.2"
+ },
+ "dependencies": {
+ "find-up": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz",
+ "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==",
+ "dev": true,
+ "requires": {
+ "locate-path": "^5.0.0",
+ "path-exists": "^4.0.0"
+ }
+ },
+ "locate-path": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz",
+ "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==",
+ "dev": true,
+ "requires": {
+ "p-locate": "^4.1.0"
+ }
+ },
+ "p-locate": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz",
+ "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==",
+ "dev": true,
+ "requires": {
+ "p-limit": "^2.2.0"
+ }
+ },
+ "parse-json": {
+ "version": "5.1.0",
+ "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.1.0.tgz",
+ "integrity": "sha512-+mi/lmVVNKFNVyLXV31ERiy2CY5E1/F6QtJFEzoChPRwwngMNXRDQ9GJ5WdE2Z2P4AujsOi0/+2qHID68KwfIQ==",
+ "dev": true,
+ "requires": {
+ "@babel/code-frame": "^7.0.0",
+ "error-ex": "^1.3.1",
+ "json-parse-even-better-errors": "^2.3.0",
+ "lines-and-columns": "^1.1.6"
+ }
+ },
+ "path-exists": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz",
+ "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==",
+ "dev": true
+ },
+ "read-pkg": {
+ "version": "5.2.0",
+ "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-5.2.0.tgz",
+ "integrity": "sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg==",
+ "dev": true,
+ "requires": {
+ "@types/normalize-package-data": "^2.4.0",
+ "normalize-package-data": "^2.5.0",
+ "parse-json": "^5.0.0",
+ "type-fest": "^0.6.0"
+ },
+ "dependencies": {
+ "type-fest": {
+ "version": "0.6.0",
+ "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.6.0.tgz",
+ "integrity": "sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg==",
+ "dev": true
+ }
+ }
+ },
+ "read-pkg-up": {
+ "version": "7.0.1",
+ "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-7.0.1.tgz",
+ "integrity": "sha512-zK0TB7Xd6JpCLmlLmufqykGE+/TlOePD6qKClNW7hHDKFh/J7/7gCWGR7joEQEW1bKq3a3yUZSObOoWLFQ4ohg==",
+ "dev": true,
+ "requires": {
+ "find-up": "^4.1.0",
+ "read-pkg": "^5.2.0",
+ "type-fest": "^0.8.1"
+ }
+ },
+ "regexpp": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.1.0.tgz",
+ "integrity": "sha512-ZOIzd8yVsQQA7j8GCSlPGXwg5PfmA1mrq0JP4nGhh54LaKN3xdai/vHUDu74pKwV8OxseMS65u2NImosQcSD0Q==",
+ "dev": true
+ },
+ "safe-regex": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/safe-regex/-/safe-regex-2.1.1.tgz",
+ "integrity": "sha512-rx+x8AMzKb5Q5lQ95Zoi6ZbJqwCLkqi3XuJXp5P3rT8OEc6sZCJG5AE5dU3lsgRr/F4Bs31jSlVN+j5KrsGu9A==",
+ "dev": true,
+ "requires": {
+ "regexp-tree": "~0.1.1"
+ }
+ },
+ "semver": {
+ "version": "7.3.2",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.2.tgz",
+ "integrity": "sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ==",
+ "dev": true
+ }
+ }
+ },
+ "eslint-rule-docs": {
+ "version": "1.1.213",
+ "resolved": "https://registry.npmjs.org/eslint-rule-docs/-/eslint-rule-docs-1.1.213.tgz",
+ "integrity": "sha512-oKJ88HkMlWcsznM4HQIPiMnUMGbkPjO8LLsTikxLbrfP2znUGa90FSQiVHazRZsX72e650g++uDNRWtb4qzDgw==",
+ "dev": true
+ },
+ "eslint-scope": {
+ "version": "5.1.1",
+ "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz",
+ "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==",
+ "dev": true,
+ "requires": {
+ "esrecurse": "^4.3.0",
+ "estraverse": "^4.1.1"
+ }
+ },
+ "eslint-template-visitor": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/eslint-template-visitor/-/eslint-template-visitor-1.1.0.tgz",
+ "integrity": "sha512-Lmy6QVlmFiIGl5fPi+8ACnov3sare+0Ouf7deJAGGhmUfeWJ5fVarELUxZRpsZ9sHejiJUq8626d0dn9uvcZTw==",
+ "dev": true,
+ "requires": {
+ "eslint-visitor-keys": "^1.1.0",
+ "espree": "^6.1.1",
+ "multimap": "^1.0.2"
+ }
+ },
+ "eslint-utils": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-2.1.0.tgz",
+ "integrity": "sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg==",
+ "dev": true,
+ "requires": {
+ "eslint-visitor-keys": "^1.1.0"
+ }
+ },
+ "eslint-visitor-keys": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz",
+ "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==",
+ "dev": true
+ },
+ "espree": {
+ "version": "6.2.1",
+ "resolved": "https://registry.npmjs.org/espree/-/espree-6.2.1.tgz",
+ "integrity": "sha512-ysCxRQY3WaXJz9tdbWOwuWr5Y/XrPTGX9Kiz3yoUXwW0VZ4w30HTkQLaGx/+ttFjF8i+ACbArnB4ce68a9m5hw==",
+ "dev": true,
+ "requires": {
+ "acorn": "^7.1.1",
+ "acorn-jsx": "^5.2.0",
+ "eslint-visitor-keys": "^1.1.0"
+ },
+ "dependencies": {
+ "acorn": {
+ "version": "7.4.1",
+ "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz",
+ "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==",
+ "dev": true
+ }
+ }
+ },
+ "esprima": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz",
+ "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==",
+ "dev": true
+ },
+ "espurify": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/espurify/-/espurify-2.0.1.tgz",
+ "integrity": "sha512-7w/dUrReI/QbJFHRwfomTlkQOXaB1NuCrBRn5Y26HXn5gvh18/19AgLbayVrNxXQfkckvgrJloWyvZDuJ7dhEA==",
+ "dev": true
+ },
+ "esquery": {
+ "version": "1.3.1",
+ "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.3.1.tgz",
+ "integrity": "sha512-olpvt9QG0vniUBZspVRN6lwB7hOZoTRtT+jzR+tS4ffYx2mzbw+z0XCOk44aaLYKApNX5nMm+E+P6o25ip/DHQ==",
+ "dev": true,
+ "requires": {
+ "estraverse": "^5.1.0"
+ },
+ "dependencies": {
+ "estraverse": {
+ "version": "5.2.0",
+ "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.2.0.tgz",
+ "integrity": "sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ==",
+ "dev": true
+ }
+ }
+ },
+ "esrecurse": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz",
+ "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==",
+ "dev": true,
+ "requires": {
+ "estraverse": "^5.2.0"
+ },
+ "dependencies": {
+ "estraverse": {
+ "version": "5.2.0",
+ "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.2.0.tgz",
+ "integrity": "sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ==",
+ "dev": true
+ }
+ }
+ },
+ "estraverse": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz",
+ "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==",
+ "dev": true
+ },
+ "esutils": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz",
+ "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==",
+ "dev": true
+ },
+ "events": {
+ "version": "3.3.0",
+ "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz",
+ "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==",
+ "dev": true
+ },
+ "expand-brackets": {
+ "version": "2.1.4",
+ "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz",
+ "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=",
+ "dev": true,
+ "requires": {
+ "debug": "^2.3.3",
+ "define-property": "^0.2.5",
+ "extend-shallow": "^2.0.1",
+ "posix-character-classes": "^0.1.0",
+ "regex-not": "^1.0.0",
+ "snapdragon": "^0.8.1",
+ "to-regex": "^3.0.1"
+ },
+ "dependencies": {
+ "debug": {
+ "version": "2.6.9",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
+ "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
+ "dev": true,
+ "requires": {
+ "ms": "2.0.0"
+ }
+ },
+ "define-property": {
+ "version": "0.2.5",
+ "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz",
+ "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=",
+ "dev": true,
+ "requires": {
+ "is-descriptor": "^0.1.0"
+ }
+ },
+ "extend-shallow": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
+ "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
+ "dev": true,
+ "requires": {
+ "is-extendable": "^0.1.0"
+ }
+ },
+ "ms": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
+ "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=",
+ "dev": true
+ }
+ }
+ },
+ "extend-shallow": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz",
+ "integrity": "sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg=",
+ "dev": true,
+ "requires": {
+ "assign-symbols": "^1.0.0",
+ "is-extendable": "^1.0.1"
+ },
+ "dependencies": {
+ "is-extendable": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz",
+ "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==",
+ "dev": true,
+ "requires": {
+ "is-plain-object": "^2.0.4"
+ }
+ }
+ }
+ },
+ "external-editor": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-3.1.0.tgz",
+ "integrity": "sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew==",
+ "dev": true,
+ "requires": {
+ "chardet": "^0.7.0",
+ "iconv-lite": "^0.4.24",
+ "tmp": "^0.0.33"
+ }
+ },
+ "extglob": {
+ "version": "2.0.4",
+ "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz",
+ "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==",
+ "dev": true,
+ "requires": {
+ "array-unique": "^0.3.2",
+ "define-property": "^1.0.0",
+ "expand-brackets": "^2.1.4",
+ "extend-shallow": "^2.0.1",
+ "fragment-cache": "^0.2.1",
+ "regex-not": "^1.0.0",
+ "snapdragon": "^0.8.1",
+ "to-regex": "^3.0.1"
+ },
+ "dependencies": {
+ "define-property": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz",
+ "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=",
+ "dev": true,
+ "requires": {
+ "is-descriptor": "^1.0.0"
+ }
+ },
+ "extend-shallow": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
+ "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
+ "dev": true,
+ "requires": {
+ "is-extendable": "^0.1.0"
+ }
+ },
+ "is-accessor-descriptor": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz",
+ "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==",
+ "dev": true,
+ "requires": {
+ "kind-of": "^6.0.0"
+ }
+ },
+ "is-data-descriptor": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz",
+ "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==",
+ "dev": true,
+ "requires": {
+ "kind-of": "^6.0.0"
+ }
+ },
+ "is-descriptor": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz",
+ "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==",
+ "dev": true,
+ "requires": {
+ "is-accessor-descriptor": "^1.0.0",
+ "is-data-descriptor": "^1.0.0",
+ "kind-of": "^6.0.2"
+ }
+ }
+ }
+ },
+ "fast-deep-equal": {
+ "version": "3.1.3",
+ "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz",
+ "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==",
+ "dev": true
+ },
+ "fast-diff": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/fast-diff/-/fast-diff-1.2.0.tgz",
+ "integrity": "sha512-xJuoT5+L99XlZ8twedaRf6Ax2TgQVxvgZOYoPKqZufmJib0tL2tegPBOZb1pVNgIhlqDlA0eO0c3wBvQcmzx4w==",
+ "dev": true
+ },
+ "fast-glob": {
+ "version": "2.2.7",
+ "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-2.2.7.tgz",
+ "integrity": "sha512-g1KuQwHOZAmOZMuBtHdxDtju+T2RT8jgCC9aANsbpdiDDTSnjgfuVsIBNKbUeJI3oKMRExcfNDtJl4OhbffMsw==",
+ "dev": true,
+ "requires": {
+ "@mrmlnc/readdir-enhanced": "^2.2.1",
+ "@nodelib/fs.stat": "^1.1.2",
+ "glob-parent": "^3.1.0",
+ "is-glob": "^4.0.0",
+ "merge2": "^1.2.3",
+ "micromatch": "^3.1.10"
+ },
+ "dependencies": {
+ "glob-parent": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz",
+ "integrity": "sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4=",
+ "dev": true,
+ "requires": {
+ "is-glob": "^3.1.0",
+ "path-dirname": "^1.0.0"
+ },
+ "dependencies": {
+ "is-glob": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz",
+ "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=",
+ "dev": true,
+ "requires": {
+ "is-extglob": "^2.1.0"
+ }
+ }
+ }
+ }
+ }
+ },
+ "fast-json-stable-stringify": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz",
+ "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==",
+ "dev": true
+ },
+ "fast-levenshtein": {
+ "version": "2.0.6",
+ "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz",
+ "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=",
+ "dev": true
+ },
+ "fastest-levenshtein": {
+ "version": "1.0.16",
+ "resolved": "https://registry.npmjs.org/fastest-levenshtein/-/fastest-levenshtein-1.0.16.tgz",
+ "integrity": "sha512-eRnCtTTtGZFpQCwhJiUOuxPQWRXVKYDn0b2PeHfXL6/Zi53SLAzAHfVhVWK2AryC/WH05kGfxhFIPvTF0SXQzg==",
+ "dev": true
+ },
+ "figures": {
+ "version": "3.2.0",
+ "resolved": "https://registry.npmjs.org/figures/-/figures-3.2.0.tgz",
+ "integrity": "sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg==",
+ "dev": true,
+ "requires": {
+ "escape-string-regexp": "^1.0.5"
+ }
+ },
+ "file-entry-cache": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-5.0.1.tgz",
+ "integrity": "sha512-bCg29ictuBaKUwwArK4ouCaqDgLZcysCFLmM/Yn/FDoqndh/9vNuQfXRDvTuXKLxfD/JtZQGKFT8MGcJBK644g==",
+ "dev": true,
+ "requires": {
+ "flat-cache": "^2.0.1"
+ }
+ },
+ "fill-range": {
+ "version": "7.0.1",
+ "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz",
+ "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==",
+ "dev": true,
+ "requires": {
+ "to-regex-range": "^5.0.1"
+ }
+ },
+ "find-cache-dir": {
+ "version": "3.3.2",
+ "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-3.3.2.tgz",
+ "integrity": "sha512-wXZV5emFEjrridIgED11OoUKLxiYjAcqot/NJdAkOhlJ+vGzwhOAfcG5OX1jP+S0PcjEn8bdMJv+g2jwQ3Onig==",
+ "dev": true,
+ "requires": {
+ "commondir": "^1.0.1",
+ "make-dir": "^3.0.2",
+ "pkg-dir": "^4.1.0"
+ }
+ },
+ "find-up": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz",
+ "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==",
+ "dev": true,
+ "requires": {
+ "locate-path": "^3.0.0"
+ }
+ },
+ "flat": {
+ "version": "5.0.2",
+ "resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz",
+ "integrity": "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==",
+ "dev": true
+ },
+ "flat-cache": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-2.0.1.tgz",
+ "integrity": "sha512-LoQe6yDuUMDzQAEH8sgmh4Md6oZnc/7PjtwjNFSzveXqSHt6ka9fPBuso7IGf9Rz4uqnSnWiFH2B/zj24a5ReA==",
+ "dev": true,
+ "requires": {
+ "flatted": "^2.0.0",
+ "rimraf": "2.6.3",
+ "write": "1.0.3"
+ },
+ "dependencies": {
+ "rimraf": {
+ "version": "2.6.3",
+ "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.3.tgz",
+ "integrity": "sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA==",
+ "dev": true,
+ "requires": {
+ "glob": "^7.1.3"
+ }
+ }
+ }
+ },
+ "flatted": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/flatted/-/flatted-2.0.2.tgz",
+ "integrity": "sha512-r5wGx7YeOwNWNlCA0wQ86zKyDLMQr+/RB8xy74M4hTphfmjlijTSSXGuH8rnvKZnfT9i+75zmd8jcKdMR4O6jA==",
+ "dev": true
+ },
+ "for-in": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz",
+ "integrity": "sha1-gQaNKVqBQuwKxybG4iAMMPttXoA=",
+ "dev": true
+ },
+ "foreachasync": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/foreachasync/-/foreachasync-3.0.0.tgz",
+ "integrity": "sha1-VQKYfchxS+M5IJfzLgBxyd7gfPY="
+ },
+ "fragment-cache": {
+ "version": "0.2.1",
+ "resolved": "https://registry.npmjs.org/fragment-cache/-/fragment-cache-0.2.1.tgz",
+ "integrity": "sha1-QpD60n8T6Jvn8zeZxrxaCr//DRk=",
+ "dev": true,
+ "requires": {
+ "map-cache": "^0.2.2"
+ }
+ },
+ "fs.realpath": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
+ "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=",
+ "dev": true
+ },
+ "fsevents": {
+ "version": "2.3.2",
+ "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz",
+ "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==",
+ "dev": true,
+ "optional": true
+ },
+ "function-bind": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz",
+ "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==",
+ "dev": true
+ },
+ "functional-red-black-tree": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz",
+ "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=",
+ "dev": true
+ },
+ "gensync": {
+ "version": "1.0.0-beta.2",
+ "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz",
+ "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==",
+ "dev": true
+ },
+ "get-caller-file": {
+ "version": "2.0.5",
+ "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz",
+ "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==",
+ "dev": true
+ },
+ "get-intrinsic": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.0.1.tgz",
+ "integrity": "sha512-ZnWP+AmS1VUaLgTRy47+zKtjTxz+0xMpx3I52i+aalBK1QP19ggLF3Db89KJX7kjfOfP2eoa01qc++GwPgufPg==",
+ "dev": true,
+ "requires": {
+ "function-bind": "^1.1.1",
+ "has": "^1.0.3",
+ "has-symbols": "^1.0.1"
+ }
+ },
+ "get-set-props": {
+ "version": "0.1.0",
+ "resolved": "https://registry.npmjs.org/get-set-props/-/get-set-props-0.1.0.tgz",
+ "integrity": "sha1-mYR1wXhEVobQsyJG2l3428++jqM=",
+ "dev": true
+ },
+ "get-stdin": {
+ "version": "7.0.0",
+ "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-7.0.0.tgz",
+ "integrity": "sha512-zRKcywvrXlXsA0v0i9Io4KDRaAw7+a1ZpjRwl9Wox8PFlVCCHra7E9c4kqXCoCM9nR5tBkaTTZRBoCm60bFqTQ==",
+ "dev": true
+ },
+ "get-stream": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz",
+ "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==",
+ "dev": true,
+ "requires": {
+ "pump": "^3.0.0"
+ }
+ },
+ "get-value": {
+ "version": "2.0.6",
+ "resolved": "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz",
+ "integrity": "sha1-3BXKHGcjh8p2vTesCjlbogQqLCg=",
+ "dev": true
+ },
+ "glob": {
+ "version": "7.2.0",
+ "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz",
+ "integrity": "sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==",
+ "dev": true,
+ "requires": {
+ "fs.realpath": "^1.0.0",
+ "inflight": "^1.0.4",
+ "inherits": "2",
+ "minimatch": "^3.0.4",
+ "once": "^1.3.0",
+ "path-is-absolute": "^1.0.0"
+ }
+ },
+ "glob-parent": {
+ "version": "5.1.2",
+ "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz",
+ "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==",
+ "dev": true,
+ "requires": {
+ "is-glob": "^4.0.1"
+ }
+ },
+ "glob-to-regexp": {
+ "version": "0.3.0",
+ "resolved": "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.3.0.tgz",
+ "integrity": "sha1-jFoUlNIGbFcMw7/kSWF1rMTVAqs=",
+ "dev": true
+ },
+ "global-dirs": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/global-dirs/-/global-dirs-2.0.1.tgz",
+ "integrity": "sha512-5HqUqdhkEovj2Of/ms3IeS/EekcO54ytHRLV4PEY2rhRwrHXLQjeVEES0Lhka0xwNDtGYn58wyC4s5+MHsOO6A==",
+ "dev": true,
+ "requires": {
+ "ini": "^1.3.5"
+ }
+ },
+ "globals": {
+ "version": "11.12.0",
+ "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz",
+ "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==",
+ "dev": true
+ },
+ "globby": {
+ "version": "9.2.0",
+ "resolved": "https://registry.npmjs.org/globby/-/globby-9.2.0.tgz",
+ "integrity": "sha512-ollPHROa5mcxDEkwg6bPt3QbEf4pDQSNtd6JPL1YvOvAo/7/0VAm9TccUeoTmarjPw4pfUthSCqcyfNB1I3ZSg==",
+ "dev": true,
+ "requires": {
+ "@types/glob": "^7.1.1",
+ "array-union": "^1.0.2",
+ "dir-glob": "^2.2.2",
+ "fast-glob": "^2.2.6",
+ "glob": "^7.1.3",
+ "ignore": "^4.0.3",
+ "pify": "^4.0.1",
+ "slash": "^2.0.0"
+ },
+ "dependencies": {
+ "slash": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/slash/-/slash-2.0.0.tgz",
+ "integrity": "sha512-ZYKh3Wh2z1PpEXWr0MpSBZ0V6mZHAQfYevttO11c51CaWjGTaadiKZ+wVt1PbMlDV5qhMFslpZCemhwOK7C89A==",
+ "dev": true
+ }
+ }
+ },
+ "got": {
+ "version": "9.6.0",
+ "resolved": "https://registry.npmjs.org/got/-/got-9.6.0.tgz",
+ "integrity": "sha512-R7eWptXuGYxwijs0eV+v3o6+XH1IqVK8dJOEecQfTmkncw9AV4dcw/Dhxi8MdlqPthxxpZyizMzyg8RTmEsG+Q==",
+ "dev": true,
+ "requires": {
+ "@sindresorhus/is": "^0.14.0",
+ "@szmarczak/http-timer": "^1.1.2",
+ "cacheable-request": "^6.0.0",
+ "decompress-response": "^3.3.0",
+ "duplexer3": "^0.1.4",
+ "get-stream": "^4.1.0",
+ "lowercase-keys": "^1.0.1",
+ "mimic-response": "^1.0.1",
+ "p-cancelable": "^1.0.0",
+ "to-readable-stream": "^1.0.0",
+ "url-parse-lax": "^3.0.0"
+ }
+ },
+ "graceful-fs": {
+ "version": "4.2.10",
+ "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.10.tgz",
+ "integrity": "sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==",
+ "dev": true
+ },
+ "growl": {
+ "version": "1.10.5",
+ "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.5.tgz",
+ "integrity": "sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA==",
+ "dev": true
+ },
+ "has": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz",
+ "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==",
+ "dev": true,
+ "requires": {
+ "function-bind": "^1.1.1"
+ }
+ },
+ "has-flag": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
+ "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=",
+ "dev": true
+ },
+ "has-symbols": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.1.tgz",
+ "integrity": "sha512-PLcsoqu++dmEIZB+6totNFKq/7Do+Z0u4oT0zKOJNl3lYK6vGwwu2hjHs+68OEZbTjiUE9bgOABXbP/GvrS0Kg==",
+ "dev": true
+ },
+ "has-value": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/has-value/-/has-value-1.0.0.tgz",
+ "integrity": "sha1-GLKB2lhbHFxR3vJMkw7SmgvmsXc=",
+ "dev": true,
+ "requires": {
+ "get-value": "^2.0.6",
+ "has-values": "^1.0.0",
+ "isobject": "^3.0.0"
+ }
+ },
+ "has-values": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/has-values/-/has-values-1.0.0.tgz",
+ "integrity": "sha1-lbC2P+whRmGab+V/51Yo1aOe/k8=",
+ "dev": true,
+ "requires": {
+ "is-number": "^3.0.0",
+ "kind-of": "^4.0.0"
+ },
+ "dependencies": {
+ "is-buffer": {
+ "version": "1.1.6",
+ "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz",
+ "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==",
+ "dev": true
+ },
+ "is-number": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz",
+ "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=",
+ "dev": true,
+ "requires": {
+ "kind-of": "^3.0.2"
+ },
+ "dependencies": {
+ "kind-of": {
+ "version": "3.2.2",
+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
+ "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
+ "dev": true,
+ "requires": {
+ "is-buffer": "^1.1.5"
+ }
+ }
+ }
+ },
+ "kind-of": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz",
+ "integrity": "sha1-IIE989cSkosgc3hpGkUGb65y3Vc=",
+ "dev": true,
+ "requires": {
+ "is-buffer": "^1.1.5"
+ }
+ }
+ }
+ },
+ "has-yarn": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/has-yarn/-/has-yarn-2.1.0.tgz",
+ "integrity": "sha512-UqBRqi4ju7T+TqGNdqAO0PaSVGsDGJUBQvk9eUWNGRY1CFGDzYhLWoM7JQEemnlvVcv/YEmc2wNW8BC24EnUsw==",
+ "dev": true
+ },
+ "he": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz",
+ "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==",
+ "dev": true
+ },
+ "hosted-git-info": {
+ "version": "2.8.9",
+ "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz",
+ "integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==",
+ "dev": true
+ },
+ "http-cache-semantics": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.1.tgz",
+ "integrity": "sha512-er295DKPVsV82j5kw1Gjt+ADA/XYHsajl82cGNQG2eyoPkvgUhX+nDIyelzhIWbbsXP39EHcI6l5tYs2FYqYXQ==",
+ "dev": true
+ },
+ "iconv-lite": {
+ "version": "0.4.24",
+ "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz",
+ "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==",
+ "dev": true,
+ "requires": {
+ "safer-buffer": ">= 2.1.2 < 3"
+ }
+ },
+ "ignore": {
+ "version": "4.0.6",
+ "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz",
+ "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==",
+ "dev": true
+ },
+ "import-fresh": {
+ "version": "3.2.2",
+ "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.2.2.tgz",
+ "integrity": "sha512-cTPNrlvJT6twpYy+YmKUKrTSjWFs3bjYjAhCwm+z4EOCubZxAuO+hHpRN64TqjEaYSHs7tJAE0w1CKMGmsG/lw==",
+ "dev": true,
+ "requires": {
+ "parent-module": "^1.0.0",
+ "resolve-from": "^4.0.0"
+ },
+ "dependencies": {
+ "resolve-from": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz",
+ "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==",
+ "dev": true
+ }
+ }
+ },
+ "import-lazy": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/import-lazy/-/import-lazy-2.1.0.tgz",
+ "integrity": "sha1-BWmOPUXIjo1+nZLLBYTnfwlvPkM=",
+ "dev": true
+ },
+ "import-local": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.1.0.tgz",
+ "integrity": "sha512-ASB07uLtnDs1o6EHjKpX34BKYDSqnFerfTOJL2HvMqF70LnxpjkzDB8J44oT9pu4AMPkQwf8jl6szgvNd2tRIg==",
+ "dev": true,
+ "requires": {
+ "pkg-dir": "^4.2.0",
+ "resolve-cwd": "^3.0.0"
+ }
+ },
+ "import-modules": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/import-modules/-/import-modules-2.0.0.tgz",
+ "integrity": "sha512-iczM/v9drffdNnABOKwj0f9G3cFDon99VcG1mxeBsdqnbd+vnQ5c2uAiCHNQITqFTOPaEvwg3VjoWCur0uHLEw==",
+ "dev": true
+ },
+ "imurmurhash": {
+ "version": "0.1.4",
+ "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz",
+ "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=",
+ "dev": true
+ },
+ "inflight": {
+ "version": "1.0.6",
+ "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
+ "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=",
+ "dev": true,
+ "requires": {
+ "once": "^1.3.0",
+ "wrappy": "1"
+ }
+ },
+ "inherits": {
+ "version": "2.0.4",
+ "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
+ "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==",
+ "dev": true
+ },
+ "ini": {
+ "version": "1.3.8",
+ "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz",
+ "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==",
+ "dev": true
+ },
+ "inquirer": {
+ "version": "7.3.3",
+ "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-7.3.3.tgz",
+ "integrity": "sha512-JG3eIAj5V9CwcGvuOmoo6LB9kbAYT8HXffUl6memuszlwDC/qvFAJw49XJ5NROSFNPxp3iQg1GqkFhaY/CR0IA==",
+ "dev": true,
+ "requires": {
+ "ansi-escapes": "^4.2.1",
+ "chalk": "^4.1.0",
+ "cli-cursor": "^3.1.0",
+ "cli-width": "^3.0.0",
+ "external-editor": "^3.0.3",
+ "figures": "^3.0.0",
+ "lodash": "^4.17.19",
+ "mute-stream": "0.0.8",
+ "run-async": "^2.4.0",
+ "rxjs": "^6.6.0",
+ "string-width": "^4.1.0",
+ "strip-ansi": "^6.0.0",
+ "through": "^2.3.6"
+ },
+ "dependencies": {
+ "ansi-styles": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
+ "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
+ "dev": true,
+ "requires": {
+ "color-convert": "^2.0.1"
+ }
+ },
+ "chalk": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz",
+ "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==",
+ "dev": true,
+ "requires": {
+ "ansi-styles": "^4.1.0",
+ "supports-color": "^7.1.0"
+ }
+ },
+ "color-convert": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
+ "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
+ "dev": true,
+ "requires": {
+ "color-name": "~1.1.4"
+ }
+ },
+ "color-name": {
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
+ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
+ "dev": true
+ },
+ "has-flag": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
+ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
+ "dev": true
+ },
+ "supports-color": {
+ "version": "7.2.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
+ "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
+ "dev": true,
+ "requires": {
+ "has-flag": "^4.0.0"
+ }
+ }
+ }
+ },
+ "interpret": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/interpret/-/interpret-3.1.1.tgz",
+ "integrity": "sha512-6xwYfHbajpoF0xLW+iwLkhwgvLoZDfjYfoFNu8ftMoXINzwuymNLd9u/KmwtdT2GbR+/Cz66otEGEVVUHX9QLQ==",
+ "dev": true
+ },
+ "irregular-plurals": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/irregular-plurals/-/irregular-plurals-2.0.0.tgz",
+ "integrity": "sha512-Y75zBYLkh0lJ9qxeHlMjQ7bSbyiSqNW/UOPWDmzC7cXskL1hekSITh1Oc6JV0XCWWZ9DE8VYSB71xocLk3gmGw==",
+ "dev": true
+ },
+ "is-accessor-descriptor": {
+ "version": "0.1.6",
+ "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz",
+ "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=",
+ "dev": true,
+ "requires": {
+ "kind-of": "^3.0.2"
+ },
+ "dependencies": {
+ "is-buffer": {
+ "version": "1.1.6",
+ "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz",
+ "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==",
+ "dev": true
+ },
+ "kind-of": {
+ "version": "3.2.2",
+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
+ "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
+ "dev": true,
+ "requires": {
+ "is-buffer": "^1.1.5"
+ }
+ }
+ }
+ },
+ "is-arrayish": {
+ "version": "0.2.1",
+ "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz",
+ "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=",
+ "dev": true
+ },
+ "is-binary-path": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz",
+ "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==",
+ "dev": true,
+ "requires": {
+ "binary-extensions": "^2.0.0"
+ }
+ },
+ "is-callable": {
+ "version": "1.2.2",
+ "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.2.tgz",
+ "integrity": "sha512-dnMqspv5nU3LoewK2N/y7KLtxtakvTuaCsU9FU50/QDmdbHNy/4/JuRtMHqRU22o3q+W89YQndQEeCVwK+3qrA==",
+ "dev": true
+ },
+ "is-ci": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-2.0.0.tgz",
+ "integrity": "sha512-YfJT7rkpQB0updsdHLGWrvhBJfcfzNNawYDNIyQXJz0IViGf75O8EBPKSdvw2rF+LGCsX4FZ8tcr3b19LcZq4w==",
+ "dev": true,
+ "requires": {
+ "ci-info": "^2.0.0"
+ }
+ },
+ "is-core-module": {
+ "version": "2.11.0",
+ "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.11.0.tgz",
+ "integrity": "sha512-RRjxlvLDkD1YJwDbroBHMb+cukurkDWNyHx7D3oNB5x9rb5ogcksMC5wHCadcXoo67gVr/+3GFySh3134zi6rw==",
+ "dev": true,
+ "requires": {
+ "has": "^1.0.3"
+ }
+ },
+ "is-data-descriptor": {
+ "version": "0.1.4",
+ "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz",
+ "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=",
+ "dev": true,
+ "requires": {
+ "kind-of": "^3.0.2"
+ },
+ "dependencies": {
+ "is-buffer": {
+ "version": "1.1.6",
+ "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz",
+ "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==",
+ "dev": true
+ },
+ "kind-of": {
+ "version": "3.2.2",
+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
+ "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
+ "dev": true,
+ "requires": {
+ "is-buffer": "^1.1.5"
+ }
+ }
+ }
+ },
+ "is-date-object": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.2.tgz",
+ "integrity": "sha512-USlDT524woQ08aoZFzh3/Z6ch9Y/EWXEHQ/AaRN0SkKq4t2Jw2R2339tSXmwuVoY7LLlBCbOIlx2myP/L5zk0g==",
+ "dev": true
+ },
+ "is-descriptor": {
+ "version": "0.1.6",
+ "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz",
+ "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==",
+ "dev": true,
+ "requires": {
+ "is-accessor-descriptor": "^0.1.6",
+ "is-data-descriptor": "^0.1.4",
+ "kind-of": "^5.0.0"
+ },
+ "dependencies": {
+ "kind-of": {
+ "version": "5.1.0",
+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz",
+ "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==",
+ "dev": true
+ }
+ }
+ },
+ "is-error": {
+ "version": "2.2.2",
+ "resolved": "https://registry.npmjs.org/is-error/-/is-error-2.2.2.tgz",
+ "integrity": "sha512-IOQqts/aHWbiisY5DuPJQ0gcbvaLFCa7fBa9xoLfxBZvQ+ZI/Zh9xoI7Gk+G64N0FdK4AbibytHht2tWgpJWLg==",
+ "dev": true
+ },
+ "is-extendable": {
+ "version": "0.1.1",
+ "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz",
+ "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=",
+ "dev": true
+ },
+ "is-extglob": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
+ "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=",
+ "dev": true
+ },
+ "is-fullwidth-code-point": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz",
+ "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=",
+ "dev": true
+ },
+ "is-get-set-prop": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/is-get-set-prop/-/is-get-set-prop-1.0.0.tgz",
+ "integrity": "sha1-JzGHfk14pqae3M5rudaLB3nnYxI=",
+ "dev": true,
+ "requires": {
+ "get-set-props": "^0.1.0",
+ "lowercase-keys": "^1.0.0"
+ }
+ },
+ "is-glob": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz",
+ "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==",
+ "dev": true,
+ "requires": {
+ "is-extglob": "^2.1.1"
+ }
+ },
+ "is-installed-globally": {
+ "version": "0.3.2",
+ "resolved": "https://registry.npmjs.org/is-installed-globally/-/is-installed-globally-0.3.2.tgz",
+ "integrity": "sha512-wZ8x1js7Ia0kecP/CHM/3ABkAmujX7WPvQk6uu3Fly/Mk44pySulQpnHG46OMjHGXApINnV4QhY3SWnECO2z5g==",
+ "dev": true,
+ "requires": {
+ "global-dirs": "^2.0.1",
+ "is-path-inside": "^3.0.1"
+ }
+ },
+ "is-js-type": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/is-js-type/-/is-js-type-2.0.0.tgz",
+ "integrity": "sha1-c2FwBtZZtOtHKbunR9KHgt8PfiI=",
+ "dev": true,
+ "requires": {
+ "js-types": "^1.0.0"
+ }
+ },
+ "is-negative-zero": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.0.tgz",
+ "integrity": "sha1-lVOxIbD6wohp2p7UWeIMdUN4hGE=",
+ "dev": true
+ },
+ "is-npm": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/is-npm/-/is-npm-4.0.0.tgz",
+ "integrity": "sha512-96ECIfh9xtDDlPylNPXhzjsykHsMJZ18ASpaWzQyBr4YRTcVjUvzaHayDAES2oU/3KpljhHUjtSRNiDwi0F0ig==",
+ "dev": true
+ },
+ "is-number": {
+ "version": "7.0.0",
+ "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz",
+ "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==",
+ "dev": true
+ },
+ "is-obj": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-2.0.0.tgz",
+ "integrity": "sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w==",
+ "dev": true
+ },
+ "is-obj-prop": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/is-obj-prop/-/is-obj-prop-1.0.0.tgz",
+ "integrity": "sha1-s03nnEULjXxzqyzfZ9yHWtuF+A4=",
+ "dev": true,
+ "requires": {
+ "lowercase-keys": "^1.0.0",
+ "obj-props": "^1.0.0"
+ }
+ },
+ "is-path-inside": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.2.tgz",
+ "integrity": "sha512-/2UGPSgmtqwo1ktx8NDHjuPwZWmHhO+gj0f93EkhLB5RgW9RZevWYYlIkS6zePc6U2WpOdQYIwHe9YC4DWEBVg==",
+ "dev": true
+ },
+ "is-plain-obj": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-1.1.0.tgz",
+ "integrity": "sha1-caUMhCnfync8kqOQpKA7OfzVHT4=",
+ "dev": true
+ },
+ "is-plain-object": {
+ "version": "2.0.4",
+ "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz",
+ "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==",
+ "dev": true,
+ "requires": {
+ "isobject": "^3.0.1"
+ }
+ },
+ "is-proto-prop": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/is-proto-prop/-/is-proto-prop-2.0.0.tgz",
+ "integrity": "sha512-jl3NbQ/fGLv5Jhan4uX+Ge9ohnemqyblWVVCpAvtTQzNFvV2xhJq+esnkIbYQ9F1nITXoLfDDQLp7LBw/zzncg==",
+ "dev": true,
+ "requires": {
+ "lowercase-keys": "^1.0.0",
+ "proto-props": "^2.0.0"
+ }
+ },
+ "is-regex": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.1.tgz",
+ "integrity": "sha512-1+QkEcxiLlB7VEyFtyBg94e08OAsvq7FUBgApTq/w2ymCLyKJgDPsybBENVtA7XCQEgEXxKPonG+mvYRxh/LIg==",
+ "dev": true,
+ "requires": {
+ "has-symbols": "^1.0.1"
+ }
+ },
+ "is-string": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.5.tgz",
+ "integrity": "sha512-buY6VNRjhQMiF1qWDouloZlQbRhDPCebwxSjxMjxgemYT46YMd2NR0/H+fBhEfWX4A/w9TBJ+ol+okqJKFE6vQ==",
+ "dev": true
+ },
+ "is-symbol": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.3.tgz",
+ "integrity": "sha512-OwijhaRSgqvhm/0ZdAcXNZt9lYdKFpcRDT5ULUuYXPoT794UNOdU+gpT6Rzo7b4V2HUl/op6GqY894AZwv9faQ==",
+ "dev": true,
+ "requires": {
+ "has-symbols": "^1.0.1"
+ }
+ },
+ "is-typedarray": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz",
+ "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=",
+ "dev": true
+ },
+ "is-unicode-supported": {
+ "version": "0.1.0",
+ "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz",
+ "integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==",
+ "dev": true
+ },
+ "is-windows": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz",
+ "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==",
+ "dev": true
+ },
+ "is-wsl": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-1.1.0.tgz",
+ "integrity": "sha1-HxbkqiKwTRM2tmGIpmrzxgDDpm0=",
+ "dev": true
+ },
+ "is-yarn-global": {
+ "version": "0.3.0",
+ "resolved": "https://registry.npmjs.org/is-yarn-global/-/is-yarn-global-0.3.0.tgz",
+ "integrity": "sha512-VjSeb/lHmkoyd8ryPVIKvOCn4D1koMqY+vqyjjUfc3xyKtP4dYOxM44sZrnqQSzSds3xyOrUTLTC9LVCVgLngw==",
+ "dev": true
+ },
+ "isarray": {
+ "version": "0.0.1",
+ "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz",
+ "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=",
+ "dev": true
+ },
+ "isexe": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
+ "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=",
+ "dev": true
+ },
+ "isobject": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz",
+ "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=",
+ "dev": true
+ },
+ "jest-worker": {
+ "version": "27.5.1",
+ "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-27.5.1.tgz",
+ "integrity": "sha512-7vuh85V5cdDofPyxn58nrPjBktZo0u9x1g8WtjQol+jZDaE+fhN+cIvTj11GndBnMnyfrUOG1sZQxCdjKh+DKg==",
+ "dev": true,
+ "requires": {
+ "@types/node": "*",
+ "merge-stream": "^2.0.0",
+ "supports-color": "^8.0.0"
+ },
+ "dependencies": {
+ "has-flag": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
+ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
+ "dev": true
+ },
+ "supports-color": {
+ "version": "8.1.1",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz",
+ "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==",
+ "dev": true,
+ "requires": {
+ "has-flag": "^4.0.0"
+ }
+ }
+ }
+ },
+ "js-tokens": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
+ "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==",
+ "dev": true
+ },
+ "js-types": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/js-types/-/js-types-1.0.0.tgz",
+ "integrity": "sha1-0kLmSU7Vcq08koCfyL7X92h8vwM=",
+ "dev": true
+ },
+ "js-yaml": {
+ "version": "3.13.1",
+ "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz",
+ "integrity": "sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==",
+ "dev": true,
+ "requires": {
+ "argparse": "^1.0.7",
+ "esprima": "^4.0.0"
+ }
+ },
+ "jsesc": {
+ "version": "2.5.2",
+ "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz",
+ "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==",
+ "dev": true
+ },
+ "json-buffer": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.0.tgz",
+ "integrity": "sha1-Wx85evx11ne96Lz8Dkfh+aPZqJg=",
+ "dev": true
+ },
+ "json-parse-better-errors": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz",
+ "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==",
+ "dev": true
+ },
+ "json-parse-even-better-errors": {
+ "version": "2.3.1",
+ "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz",
+ "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==",
+ "dev": true
+ },
+ "json-schema-traverse": {
+ "version": "0.4.1",
+ "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz",
+ "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==",
+ "dev": true
+ },
+ "json-stable-stringify-without-jsonify": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz",
+ "integrity": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=",
+ "dev": true
+ },
+ "json5": {
+ "version": "2.2.3",
+ "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz",
+ "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==",
+ "dev": true
+ },
+ "just-extend": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/just-extend/-/just-extend-4.1.1.tgz",
+ "integrity": "sha512-aWgeGFW67BP3e5181Ep1Fv2v8z//iBJfrvyTnq8wG86vEESwmonn1zPBJ0VfmT9CJq2FIT0VsETtrNFm2a+SHA==",
+ "dev": true
+ },
+ "keyv": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/keyv/-/keyv-3.1.0.tgz",
+ "integrity": "sha512-9ykJ/46SN/9KPM/sichzQ7OvXyGDYKGTaDlKMGCAlg2UK8KRy4jb0d8sFc+0Tt0YYnThq8X2RZgCg74RPxgcVA==",
+ "dev": true,
+ "requires": {
+ "json-buffer": "3.0.0"
+ }
+ },
+ "kind-of": {
+ "version": "6.0.3",
+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz",
+ "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==",
+ "dev": true
+ },
+ "latest-version": {
+ "version": "5.1.0",
+ "resolved": "https://registry.npmjs.org/latest-version/-/latest-version-5.1.0.tgz",
+ "integrity": "sha512-weT+r0kTkRQdCdYCNtkMwWXQTMEswKrFBkm4ckQOMVhhqhIMI1UT2hMj+1iigIhgSZm5gTmrRXBNoGUgaTY1xA==",
+ "dev": true,
+ "requires": {
+ "package-json": "^6.3.0"
+ }
+ },
+ "levn": {
+ "version": "0.3.0",
+ "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz",
+ "integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=",
+ "dev": true,
+ "requires": {
+ "prelude-ls": "~1.1.2",
+ "type-check": "~0.3.2"
+ }
+ },
+ "line-column-path": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/line-column-path/-/line-column-path-2.0.0.tgz",
+ "integrity": "sha512-nz3A+vi4bElhwd62E9+Qk/f9BDYLSzD/4Hy1rir0I4GnMxSTezSymzANyph5N1PgRZ3sSbA+yR5hOuXxc71a0Q==",
+ "dev": true,
+ "requires": {
+ "type-fest": "^0.4.1"
+ },
+ "dependencies": {
+ "type-fest": {
+ "version": "0.4.1",
+ "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.4.1.tgz",
+ "integrity": "sha512-IwzA/LSfD2vC1/YDYMv/zHP4rDF1usCwllsDpbolT3D4fUepIO7f9K70jjmUewU/LmGUKJcwcVtDCpnKk4BPMw==",
+ "dev": true
+ }
+ }
+ },
+ "lines-and-columns": {
+ "version": "1.1.6",
+ "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.1.6.tgz",
+ "integrity": "sha1-HADHQ7QzzQpOgHWPe2SldEDZ/wA=",
+ "dev": true
+ },
+ "load-json-file": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-2.0.0.tgz",
+ "integrity": "sha1-eUfkIUmvgNaWy/eXvKq8/h/inKg=",
+ "dev": true,
+ "requires": {
+ "graceful-fs": "^4.1.2",
+ "parse-json": "^2.2.0",
+ "pify": "^2.0.0",
+ "strip-bom": "^3.0.0"
+ },
+ "dependencies": {
+ "pify": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz",
+ "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=",
+ "dev": true
+ }
+ }
+ },
+ "loader-runner": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-4.3.0.tgz",
+ "integrity": "sha512-3R/1M+yS3j5ou80Me59j7F9IMs4PXs3VqRrm0TU3AbKPxlmpoY1TNscJV/oGJXo8qCatFGTfDbY6W6ipGOYXfg==",
+ "dev": true
+ },
+ "loader-utils": {
+ "version": "2.0.4",
+ "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.4.tgz",
+ "integrity": "sha512-xXqpXoINfFhgua9xiqD8fPFHgkoq1mmmpE92WlDbm9rNRd/EbRb+Gqf908T2DMfuHjjJlksiK2RbHVOdD/MqSw==",
+ "dev": true,
+ "requires": {
+ "big.js": "^5.2.2",
+ "emojis-list": "^3.0.0",
+ "json5": "^2.1.2"
+ }
+ },
+ "locate-path": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz",
+ "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==",
+ "dev": true,
+ "requires": {
+ "p-locate": "^3.0.0",
+ "path-exists": "^3.0.0"
+ }
+ },
+ "locutus": {
+ "version": "2.0.15",
+ "resolved": "https://registry.npmjs.org/locutus/-/locutus-2.0.15.tgz",
+ "integrity": "sha512-2xWC4RkoAoCVXEb/stzEgG1TNgd+mrkLBj6TuEDNyUoKeQ2XzDTyJUC23sMiqbL6zJmJSP3w59OZo+zc4IBOmA=="
+ },
+ "lodash": {
+ "version": "4.17.21",
+ "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz",
+ "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==",
+ "dev": true
+ },
+ "lodash.camelcase": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz",
+ "integrity": "sha1-soqmKIorn8ZRA1x3EfZathkDMaY=",
+ "dev": true
+ },
+ "lodash.defaultsdeep": {
+ "version": "4.6.1",
+ "resolved": "https://registry.npmjs.org/lodash.defaultsdeep/-/lodash.defaultsdeep-4.6.1.tgz",
+ "integrity": "sha512-3j8wdDzYuWO3lM3Reg03MuQR957t287Rpcxp1njpEa8oDrikb+FwGdW3n+FELh/A6qib6yPit0j/pv9G/yeAqA==",
+ "dev": true
+ },
+ "lodash.get": {
+ "version": "4.4.2",
+ "resolved": "https://registry.npmjs.org/lodash.get/-/lodash.get-4.4.2.tgz",
+ "integrity": "sha1-LRd/ZS+jHpObRDjVNBSZ36OCXpk=",
+ "dev": true
+ },
+ "lodash.kebabcase": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/lodash.kebabcase/-/lodash.kebabcase-4.1.1.tgz",
+ "integrity": "sha1-hImxyw0p/4gZXM7KRI/21swpXDY=",
+ "dev": true
+ },
+ "lodash.snakecase": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/lodash.snakecase/-/lodash.snakecase-4.1.1.tgz",
+ "integrity": "sha1-OdcUo1NXFHg3rv1ktdy7Fr7Nj40=",
+ "dev": true
+ },
+ "lodash.upperfirst": {
+ "version": "4.3.1",
+ "resolved": "https://registry.npmjs.org/lodash.upperfirst/-/lodash.upperfirst-4.3.1.tgz",
+ "integrity": "sha1-E2Xt9DFIBIHvDRxolXpe2Z1J984=",
+ "dev": true
+ },
+ "lodash.zip": {
+ "version": "4.2.0",
+ "resolved": "https://registry.npmjs.org/lodash.zip/-/lodash.zip-4.2.0.tgz",
+ "integrity": "sha1-7GZi5IlkCO1KtsVCo5kLcswIACA=",
+ "dev": true
+ },
+ "log-symbols": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-3.0.0.tgz",
+ "integrity": "sha512-dSkNGuI7iG3mfvDzUuYZyvk5dD9ocYCYzNU6CYDE6+Xqd+gwme6Z00NS3dUh8mq/73HaEtT7m6W+yUPtU6BZnQ==",
+ "dev": true,
+ "requires": {
+ "chalk": "^2.4.2"
+ }
+ },
+ "loud-rejection": {
+ "version": "1.6.0",
+ "resolved": "https://registry.npmjs.org/loud-rejection/-/loud-rejection-1.6.0.tgz",
+ "integrity": "sha1-W0b4AUft7leIcPCG0Eghz5mOVR8=",
+ "dev": true,
+ "requires": {
+ "currently-unhandled": "^0.4.1",
+ "signal-exit": "^3.0.0"
+ }
+ },
+ "lowercase-keys": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-1.0.1.tgz",
+ "integrity": "sha512-G2Lj61tXDnVFFOi8VZds+SoQjtQC3dgokKdDG2mTm1tx4m50NUHBOZSBwQQHyy0V12A0JTG4icfZQH+xPyh8VA==",
+ "dev": true
+ },
+ "make-dir": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz",
+ "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==",
+ "dev": true,
+ "requires": {
+ "semver": "^6.0.0"
+ },
+ "dependencies": {
+ "semver": {
+ "version": "6.3.0",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
+ "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
+ "dev": true
+ }
+ }
+ },
+ "map-cache": {
+ "version": "0.2.2",
+ "resolved": "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz",
+ "integrity": "sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8=",
+ "dev": true
+ },
+ "map-obj": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-2.0.0.tgz",
+ "integrity": "sha1-plzSkIepJZi4eRJXpSPgISIqwfk=",
+ "dev": true
+ },
+ "map-visit": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/map-visit/-/map-visit-1.0.0.tgz",
+ "integrity": "sha1-7Nyo8TFE5mDxtb1B8S80edmN+48=",
+ "dev": true,
+ "requires": {
+ "object-visit": "^1.0.0"
+ }
+ },
+ "meow": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/meow/-/meow-5.0.0.tgz",
+ "integrity": "sha512-CbTqYU17ABaLefO8vCU153ZZlprKYWDljcndKKDCFcYQITzWCXZAVk4QMFZPgvzrnUQ3uItnIE/LoUOwrT15Ig==",
+ "dev": true,
+ "requires": {
+ "camelcase-keys": "^4.0.0",
+ "decamelize-keys": "^1.0.0",
+ "loud-rejection": "^1.0.0",
+ "minimist-options": "^3.0.1",
+ "normalize-package-data": "^2.3.4",
+ "read-pkg-up": "^3.0.0",
+ "redent": "^2.0.0",
+ "trim-newlines": "^2.0.0",
+ "yargs-parser": "^10.0.0"
+ },
+ "dependencies": {
+ "camelcase": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-4.1.0.tgz",
+ "integrity": "sha1-1UVjW+HjPFQmScaRc+Xeas+uNN0=",
+ "dev": true
+ },
+ "find-up": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz",
+ "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=",
+ "dev": true,
+ "requires": {
+ "locate-path": "^2.0.0"
+ }
+ },
+ "load-json-file": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-4.0.0.tgz",
+ "integrity": "sha1-L19Fq5HjMhYjT9U62rZo607AmTs=",
+ "dev": true,
+ "requires": {
+ "graceful-fs": "^4.1.2",
+ "parse-json": "^4.0.0",
+ "pify": "^3.0.0",
+ "strip-bom": "^3.0.0"
+ }
+ },
+ "locate-path": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz",
+ "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=",
+ "dev": true,
+ "requires": {
+ "p-locate": "^2.0.0",
+ "path-exists": "^3.0.0"
+ }
+ },
+ "p-limit": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz",
+ "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==",
+ "dev": true,
+ "requires": {
+ "p-try": "^1.0.0"
+ }
+ },
+ "p-locate": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz",
+ "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=",
+ "dev": true,
+ "requires": {
+ "p-limit": "^1.1.0"
+ }
+ },
+ "p-try": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz",
+ "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=",
+ "dev": true
+ },
+ "parse-json": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz",
+ "integrity": "sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA=",
+ "dev": true,
+ "requires": {
+ "error-ex": "^1.3.1",
+ "json-parse-better-errors": "^1.0.1"
+ }
+ },
+ "path-type": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/path-type/-/path-type-3.0.0.tgz",
+ "integrity": "sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg==",
+ "dev": true,
+ "requires": {
+ "pify": "^3.0.0"
+ }
+ },
+ "pify": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz",
+ "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=",
+ "dev": true
+ },
+ "read-pkg": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-3.0.0.tgz",
+ "integrity": "sha1-nLxoaXj+5l0WwA4rGcI3/Pbjg4k=",
+ "dev": true,
+ "requires": {
+ "load-json-file": "^4.0.0",
+ "normalize-package-data": "^2.3.2",
+ "path-type": "^3.0.0"
+ }
+ },
+ "read-pkg-up": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-3.0.0.tgz",
+ "integrity": "sha1-PtSWaF26D4/hGNBpHcUfSh/5bwc=",
+ "dev": true,
+ "requires": {
+ "find-up": "^2.0.0",
+ "read-pkg": "^3.0.0"
+ }
+ },
+ "yargs-parser": {
+ "version": "10.1.0",
+ "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-10.1.0.tgz",
+ "integrity": "sha512-VCIyR1wJoEBZUqk5PA+oOBF6ypbwh5aNB3I50guxAL/quggdfs4TtNHQrSazFA3fYZ+tEqfs0zIGlv0c/rgjbQ==",
+ "dev": true,
+ "requires": {
+ "camelcase": "^4.1.0"
+ }
+ }
+ }
+ },
+ "merge-stream": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz",
+ "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==",
+ "dev": true
+ },
+ "merge2": {
+ "version": "1.4.1",
+ "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz",
+ "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==",
+ "dev": true
+ },
+ "micro-spelling-correcter": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/micro-spelling-correcter/-/micro-spelling-correcter-1.1.1.tgz",
+ "integrity": "sha512-lkJ3Rj/mtjlRcHk6YyCbvZhyWTOzdBvTHsxMmZSk5jxN1YyVSQ+JETAom55mdzfcyDrY/49Z7UCW760BK30crg==",
+ "dev": true
+ },
+ "micromatch": {
+ "version": "3.1.10",
+ "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz",
+ "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==",
+ "dev": true,
+ "requires": {
+ "arr-diff": "^4.0.0",
+ "array-unique": "^0.3.2",
+ "braces": "^2.3.1",
+ "define-property": "^2.0.2",
+ "extend-shallow": "^3.0.2",
+ "extglob": "^2.0.4",
+ "fragment-cache": "^0.2.1",
+ "kind-of": "^6.0.2",
+ "nanomatch": "^1.2.9",
+ "object.pick": "^1.3.0",
+ "regex-not": "^1.0.0",
+ "snapdragon": "^0.8.1",
+ "to-regex": "^3.0.2"
+ },
+ "dependencies": {
+ "braces": {
+ "version": "2.3.2",
+ "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz",
+ "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==",
+ "dev": true,
+ "requires": {
+ "arr-flatten": "^1.1.0",
+ "array-unique": "^0.3.2",
+ "extend-shallow": "^2.0.1",
+ "fill-range": "^4.0.0",
+ "isobject": "^3.0.1",
+ "repeat-element": "^1.1.2",
+ "snapdragon": "^0.8.1",
+ "snapdragon-node": "^2.0.1",
+ "split-string": "^3.0.2",
+ "to-regex": "^3.0.1"
+ },
+ "dependencies": {
+ "extend-shallow": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
+ "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
+ "dev": true,
+ "requires": {
+ "is-extendable": "^0.1.0"
+ }
+ }
+ }
+ },
+ "fill-range": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz",
+ "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=",
+ "dev": true,
+ "requires": {
+ "extend-shallow": "^2.0.1",
+ "is-number": "^3.0.0",
+ "repeat-string": "^1.6.1",
+ "to-regex-range": "^2.1.0"
+ },
+ "dependencies": {
+ "extend-shallow": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
+ "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
+ "dev": true,
+ "requires": {
+ "is-extendable": "^0.1.0"
+ }
+ }
+ }
+ },
+ "is-buffer": {
+ "version": "1.1.6",
+ "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz",
+ "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==",
+ "dev": true
+ },
+ "is-number": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz",
+ "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=",
+ "dev": true,
+ "requires": {
+ "kind-of": "^3.0.2"
+ },
+ "dependencies": {
+ "kind-of": {
+ "version": "3.2.2",
+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
+ "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
+ "dev": true,
+ "requires": {
+ "is-buffer": "^1.1.5"
+ }
+ }
+ }
+ },
+ "to-regex-range": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz",
+ "integrity": "sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg=",
+ "dev": true,
+ "requires": {
+ "is-number": "^3.0.0",
+ "repeat-string": "^1.6.1"
+ }
+ }
+ }
+ },
+ "mime-db": {
+ "version": "1.52.0",
+ "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz",
+ "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==",
+ "dev": true
+ },
+ "mime-types": {
+ "version": "2.1.35",
+ "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz",
+ "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==",
+ "dev": true,
+ "requires": {
+ "mime-db": "1.52.0"
+ }
+ },
+ "mimic-fn": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz",
+ "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==",
+ "dev": true
+ },
+ "mimic-response": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-1.0.1.tgz",
+ "integrity": "sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ==",
+ "dev": true
+ },
+ "minimatch": {
+ "version": "3.0.5",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.5.tgz",
+ "integrity": "sha512-tUpxzX0VAzJHjLu0xUfFv1gwVp9ba3IOuRAVH2EGuRW8a5emA2FlACLqiT/lDVtS1W+TGNwqz3sWaNyLgDJWuw==",
+ "requires": {
+ "brace-expansion": "^1.1.7"
+ }
+ },
+ "minimist": {
+ "version": "1.2.6",
+ "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.6.tgz",
+ "integrity": "sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q==",
+ "dev": true
+ },
+ "minimist-options": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/minimist-options/-/minimist-options-3.0.2.tgz",
+ "integrity": "sha512-FyBrT/d0d4+uiZRbqznPXqw3IpZZG3gl3wKWiX784FycUKVwBt0uLBFkQrtE4tZOrgo78nZp2jnKz3L65T5LdQ==",
+ "dev": true,
+ "requires": {
+ "arrify": "^1.0.1",
+ "is-plain-obj": "^1.1.0"
+ },
+ "dependencies": {
+ "arrify": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz",
+ "integrity": "sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0=",
+ "dev": true
+ }
+ }
+ },
+ "mixin-deep": {
+ "version": "1.3.2",
+ "resolved": "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.2.tgz",
+ "integrity": "sha512-WRoDn//mXBiJ1H40rqa3vH0toePwSsGb45iInWlTySa+Uu4k3tYUSxa2v1KqAiLtvlrSzaExqS1gtk96A9zvEA==",
+ "dev": true,
+ "requires": {
+ "for-in": "^1.0.2",
+ "is-extendable": "^1.0.1"
+ },
+ "dependencies": {
+ "is-extendable": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz",
+ "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==",
+ "dev": true,
+ "requires": {
+ "is-plain-object": "^2.0.4"
+ }
+ }
+ }
+ },
+ "mkdirp": {
+ "version": "0.5.5",
+ "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz",
+ "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==",
+ "dev": true,
+ "requires": {
+ "minimist": "^1.2.5"
+ }
+ },
+ "mocha": {
+ "version": "9.2.2",
+ "resolved": "https://registry.npmjs.org/mocha/-/mocha-9.2.2.tgz",
+ "integrity": "sha512-L6XC3EdwT6YrIk0yXpavvLkn8h+EU+Y5UcCHKECyMbdUIxyMuZj4bX4U9e1nvnvUUvQVsV2VHQr5zLdcUkhW/g==",
+ "dev": true,
+ "requires": {
+ "@ungap/promise-all-settled": "1.1.2",
+ "ansi-colors": "4.1.1",
+ "browser-stdout": "1.3.1",
+ "chokidar": "3.5.3",
+ "debug": "4.3.3",
+ "diff": "5.0.0",
+ "escape-string-regexp": "4.0.0",
+ "find-up": "5.0.0",
+ "glob": "7.2.0",
+ "growl": "1.10.5",
+ "he": "1.2.0",
+ "js-yaml": "4.1.0",
+ "log-symbols": "4.1.0",
+ "minimatch": "4.2.1",
+ "ms": "2.1.3",
+ "nanoid": "3.3.1",
+ "serialize-javascript": "6.0.0",
+ "strip-json-comments": "3.1.1",
+ "supports-color": "8.1.1",
+ "which": "2.0.2",
+ "workerpool": "6.2.0",
+ "yargs": "16.2.0",
+ "yargs-parser": "20.2.4",
+ "yargs-unparser": "2.0.0"
+ },
+ "dependencies": {
+ "ansi-styles": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
+ "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
+ "dev": true,
+ "requires": {
+ "color-convert": "^2.0.1"
+ }
+ },
+ "argparse": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz",
+ "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==",
+ "dev": true
+ },
+ "chalk": {
+ "version": "4.1.2",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
+ "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
+ "dev": true,
+ "requires": {
+ "ansi-styles": "^4.1.0",
+ "supports-color": "^7.1.0"
+ },
+ "dependencies": {
+ "supports-color": {
+ "version": "7.2.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
+ "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
+ "dev": true,
+ "requires": {
+ "has-flag": "^4.0.0"
+ }
+ }
+ }
+ },
+ "cliui": {
+ "version": "7.0.4",
+ "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz",
+ "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==",
+ "dev": true,
+ "requires": {
+ "string-width": "^4.2.0",
+ "strip-ansi": "^6.0.0",
+ "wrap-ansi": "^7.0.0"
+ }
+ },
+ "color-convert": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
+ "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
+ "dev": true,
+ "requires": {
+ "color-name": "~1.1.4"
+ }
+ },
+ "color-name": {
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
+ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
+ "dev": true
+ },
+ "debug": {
+ "version": "4.3.3",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.3.tgz",
+ "integrity": "sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q==",
+ "dev": true,
+ "requires": {
+ "ms": "2.1.2"
+ },
+ "dependencies": {
+ "ms": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
+ "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
+ "dev": true
+ }
+ }
+ },
+ "escape-string-regexp": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz",
+ "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==",
+ "dev": true
+ },
+ "find-up": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz",
+ "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==",
+ "dev": true,
+ "requires": {
+ "locate-path": "^6.0.0",
+ "path-exists": "^4.0.0"
+ }
+ },
+ "has-flag": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
+ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
+ "dev": true
+ },
+ "js-yaml": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz",
+ "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==",
+ "dev": true,
+ "requires": {
+ "argparse": "^2.0.1"
+ }
+ },
+ "locate-path": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz",
+ "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==",
+ "dev": true,
+ "requires": {
+ "p-locate": "^5.0.0"
+ }
+ },
+ "log-symbols": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz",
+ "integrity": "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==",
+ "dev": true,
+ "requires": {
+ "chalk": "^4.1.0",
+ "is-unicode-supported": "^0.1.0"
+ }
+ },
+ "minimatch": {
+ "version": "4.2.1",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-4.2.1.tgz",
+ "integrity": "sha512-9Uq1ChtSZO+Mxa/CL1eGizn2vRn3MlLgzhT0Iz8zaY8NdvxvB0d5QdPFmCKf7JKA9Lerx5vRrnwO03jsSfGG9g==",
+ "dev": true,
+ "requires": {
+ "brace-expansion": "^1.1.7"
+ }
+ },
+ "ms": {
+ "version": "2.1.3",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
+ "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
+ "dev": true
+ },
+ "p-limit": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz",
+ "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==",
+ "dev": true,
+ "requires": {
+ "yocto-queue": "^0.1.0"
+ }
+ },
+ "p-locate": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz",
+ "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==",
+ "dev": true,
+ "requires": {
+ "p-limit": "^3.0.2"
+ }
+ },
+ "path-exists": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz",
+ "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==",
+ "dev": true
+ },
+ "strip-json-comments": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz",
+ "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==",
+ "dev": true
+ },
+ "supports-color": {
+ "version": "8.1.1",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz",
+ "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==",
+ "dev": true,
+ "requires": {
+ "has-flag": "^4.0.0"
+ }
+ },
+ "which": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
+ "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==",
+ "dev": true,
+ "requires": {
+ "isexe": "^2.0.0"
+ }
+ },
+ "wrap-ansi": {
+ "version": "7.0.0",
+ "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz",
+ "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==",
+ "dev": true,
+ "requires": {
+ "ansi-styles": "^4.0.0",
+ "string-width": "^4.1.0",
+ "strip-ansi": "^6.0.0"
+ }
+ },
+ "y18n": {
+ "version": "5.0.8",
+ "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz",
+ "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==",
+ "dev": true
+ },
+ "yargs": {
+ "version": "16.2.0",
+ "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz",
+ "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==",
+ "dev": true,
+ "requires": {
+ "cliui": "^7.0.2",
+ "escalade": "^3.1.1",
+ "get-caller-file": "^2.0.5",
+ "require-directory": "^2.1.1",
+ "string-width": "^4.2.0",
+ "y18n": "^5.0.5",
+ "yargs-parser": "^20.2.2"
+ }
+ },
+ "yargs-parser": {
+ "version": "20.2.4",
+ "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.4.tgz",
+ "integrity": "sha512-WOkpgNhPTlE73h4VFAFsOnomJVaovO8VqLDzy5saChRBFQFBoMYirowyW+Q9HB4HFF4Z7VZTiG3iSzJJA29yRA==",
+ "dev": true
+ }
+ }
+ },
+ "ms": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
+ "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
+ "dev": true
+ },
+ "multimap": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/multimap/-/multimap-1.1.0.tgz",
+ "integrity": "sha512-0ZIR9PasPxGXmRsEF8jsDzndzHDj7tIav+JUmvIFB/WHswliFnquxECT/De7GR4yg99ky/NlRKJT82G1y271bw==",
+ "dev": true
+ },
+ "multimatch": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/multimatch/-/multimatch-4.0.0.tgz",
+ "integrity": "sha512-lDmx79y1z6i7RNx0ZGCPq1bzJ6ZoDDKbvh7jxr9SJcWLkShMzXrHbYVpTdnhNM5MXpDUxCQ4DgqVttVXlBgiBQ==",
+ "dev": true,
+ "requires": {
+ "@types/minimatch": "^3.0.3",
+ "array-differ": "^3.0.0",
+ "array-union": "^2.1.0",
+ "arrify": "^2.0.1",
+ "minimatch": "^3.0.4"
+ },
+ "dependencies": {
+ "array-union": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz",
+ "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==",
+ "dev": true
+ }
+ }
+ },
+ "mute-stream": {
+ "version": "0.0.8",
+ "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.8.tgz",
+ "integrity": "sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==",
+ "dev": true
+ },
+ "nanoid": {
+ "version": "3.3.1",
+ "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.1.tgz",
+ "integrity": "sha512-n6Vs/3KGyxPQd6uO0eH4Bv0ojGSUvuLlIHtC3Y0kEO23YRge8H9x1GCzLn28YX0H66pMkxuaeESFq4tKISKwdw==",
+ "dev": true
+ },
+ "nanomatch": {
+ "version": "1.2.13",
+ "resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.13.tgz",
+ "integrity": "sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA==",
+ "dev": true,
+ "requires": {
+ "arr-diff": "^4.0.0",
+ "array-unique": "^0.3.2",
+ "define-property": "^2.0.2",
+ "extend-shallow": "^3.0.2",
+ "fragment-cache": "^0.2.1",
+ "is-windows": "^1.0.2",
+ "kind-of": "^6.0.2",
+ "object.pick": "^1.3.0",
+ "regex-not": "^1.0.0",
+ "snapdragon": "^0.8.1",
+ "to-regex": "^3.0.1"
+ }
+ },
+ "natural-compare": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz",
+ "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=",
+ "dev": true
+ },
+ "neo-async": {
+ "version": "2.6.2",
+ "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz",
+ "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==",
+ "dev": true
+ },
+ "nice-try": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz",
+ "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==",
+ "dev": true
+ },
+ "nise": {
+ "version": "4.0.4",
+ "resolved": "https://registry.npmjs.org/nise/-/nise-4.0.4.tgz",
+ "integrity": "sha512-bTTRUNlemx6deJa+ZyoCUTRvH3liK5+N6VQZ4NIw90AgDXY6iPnsqplNFf6STcj+ePk0H/xqxnP75Lr0J0Fq3A==",
+ "dev": true,
+ "requires": {
+ "@sinonjs/commons": "^1.7.0",
+ "@sinonjs/fake-timers": "^6.0.0",
+ "@sinonjs/text-encoding": "^0.7.1",
+ "just-extend": "^4.0.2",
+ "path-to-regexp": "^1.7.0"
+ }
+ },
+ "normalize-package-data": {
+ "version": "2.5.0",
+ "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz",
+ "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==",
+ "dev": true,
+ "requires": {
+ "hosted-git-info": "^2.1.4",
+ "resolve": "^1.10.0",
+ "semver": "2 || 3 || 4 || 5",
+ "validate-npm-package-license": "^3.0.1"
+ }
+ },
+ "normalize-path": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz",
+ "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==",
+ "dev": true
+ },
+ "normalize-url": {
+ "version": "4.5.1",
+ "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-4.5.1.tgz",
+ "integrity": "sha512-9UZCFRHQdNrfTpGg8+1INIg93B6zE0aXMVFkw1WFwvO4SlZywU6aLg5Of0Ap/PgcbSw4LNxvMWXMeugwMCX0AA==",
+ "dev": true
+ },
+ "obj-props": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/obj-props/-/obj-props-1.3.0.tgz",
+ "integrity": "sha512-k2Xkjx5wn6eC3537SWAXHzB6lkI81kS+icMKMkh4nG3w7shWG6MaWOBrNvhWVOszrtL5uxdfymQQfPUxwY+2eg==",
+ "dev": true
+ },
+ "object-copy": {
+ "version": "0.1.0",
+ "resolved": "https://registry.npmjs.org/object-copy/-/object-copy-0.1.0.tgz",
+ "integrity": "sha1-fn2Fi3gb18mRpBupde04EnVOmYw=",
+ "dev": true,
+ "requires": {
+ "copy-descriptor": "^0.1.0",
+ "define-property": "^0.2.5",
+ "kind-of": "^3.0.3"
+ },
+ "dependencies": {
+ "define-property": {
+ "version": "0.2.5",
+ "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz",
+ "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=",
+ "dev": true,
+ "requires": {
+ "is-descriptor": "^0.1.0"
+ }
+ },
+ "is-buffer": {
+ "version": "1.1.6",
+ "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz",
+ "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==",
+ "dev": true
+ },
+ "kind-of": {
+ "version": "3.2.2",
+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
+ "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
+ "dev": true,
+ "requires": {
+ "is-buffer": "^1.1.5"
+ }
+ }
+ }
+ },
+ "object-inspect": {
+ "version": "1.8.0",
+ "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.8.0.tgz",
+ "integrity": "sha512-jLdtEOB112fORuypAyl/50VRVIBIdVQOSUUGQHzJ4xBSbit81zRarz7GThkEFZy1RceYrWYcPcBFPQwHyAc1gA==",
+ "dev": true
+ },
+ "object-keys": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz",
+ "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==",
+ "dev": true
+ },
+ "object-visit": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/object-visit/-/object-visit-1.0.1.tgz",
+ "integrity": "sha1-95xEk68MU3e1n+OdOV5BBC3QRbs=",
+ "dev": true,
+ "requires": {
+ "isobject": "^3.0.0"
+ }
+ },
+ "object.assign": {
+ "version": "4.1.2",
+ "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.2.tgz",
+ "integrity": "sha512-ixT2L5THXsApyiUPYKmW+2EHpXXe5Ii3M+f4e+aJFAHao5amFRW6J0OO6c/LU8Be47utCx2GL89hxGB6XSmKuQ==",
+ "dev": true,
+ "requires": {
+ "call-bind": "^1.0.0",
+ "define-properties": "^1.1.3",
+ "has-symbols": "^1.0.1",
+ "object-keys": "^1.1.1"
+ }
+ },
+ "object.pick": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/object.pick/-/object.pick-1.3.0.tgz",
+ "integrity": "sha1-h6EKxMFpS9Lhy/U1kaZhQftd10c=",
+ "dev": true,
+ "requires": {
+ "isobject": "^3.0.1"
+ }
+ },
+ "object.values": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.1.1.tgz",
+ "integrity": "sha512-WTa54g2K8iu0kmS/us18jEmdv1a4Wi//BZ/DTVYEcH0XhLM5NYdpDHja3gt57VrZLcNAO2WGA+KpWsDBaHt6eA==",
+ "dev": true,
+ "requires": {
+ "define-properties": "^1.1.3",
+ "es-abstract": "^1.17.0-next.1",
+ "function-bind": "^1.1.1",
+ "has": "^1.0.3"
+ }
+ },
+ "once": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
+ "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=",
+ "dev": true,
+ "requires": {
+ "wrappy": "1"
+ }
+ },
+ "onetime": {
+ "version": "5.1.2",
+ "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz",
+ "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==",
+ "dev": true,
+ "requires": {
+ "mimic-fn": "^2.1.0"
+ }
+ },
+ "open": {
+ "version": "6.4.0",
+ "resolved": "https://registry.npmjs.org/open/-/open-6.4.0.tgz",
+ "integrity": "sha512-IFenVPgF70fSm1keSd2iDBIDIBZkroLeuffXq+wKTzTJlBpesFWojV9lb8mzOfaAzM1sr7HQHuO0vtV0zYekGg==",
+ "dev": true,
+ "requires": {
+ "is-wsl": "^1.1.0"
+ }
+ },
+ "open-editor": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/open-editor/-/open-editor-2.0.1.tgz",
+ "integrity": "sha512-B3KdD7Pl8jYdpBSBBbdYaqVUI3whQjLl1G1+CvhNc8+d7GzKRUq+VuCIx1thxGiqD2oBGRvsZz7QWrBsFP2yVA==",
+ "dev": true,
+ "requires": {
+ "env-editor": "^0.4.0",
+ "line-column-path": "^2.0.0",
+ "open": "^6.2.0"
+ }
+ },
+ "optionator": {
+ "version": "0.8.3",
+ "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.3.tgz",
+ "integrity": "sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA==",
+ "dev": true,
+ "requires": {
+ "deep-is": "~0.1.3",
+ "fast-levenshtein": "~2.0.6",
+ "levn": "~0.3.0",
+ "prelude-ls": "~1.1.2",
+ "type-check": "~0.3.2",
+ "word-wrap": "~1.2.3"
+ }
+ },
+ "os-tmpdir": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz",
+ "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=",
+ "dev": true
+ },
+ "p-cancelable": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-1.1.0.tgz",
+ "integrity": "sha512-s73XxOZ4zpt1edZYZzvhqFa6uvQc1vwUa0K0BdtIZgQMAJj9IbebH+JkgKZc9h+B05PKHLOTl4ajG1BmNrVZlw==",
+ "dev": true
+ },
+ "p-limit": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz",
+ "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==",
+ "dev": true,
+ "requires": {
+ "p-try": "^2.0.0"
+ }
+ },
+ "p-locate": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz",
+ "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==",
+ "dev": true,
+ "requires": {
+ "p-limit": "^2.0.0"
+ }
+ },
+ "p-try": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz",
+ "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==",
+ "dev": true
+ },
+ "package-json": {
+ "version": "6.5.0",
+ "resolved": "https://registry.npmjs.org/package-json/-/package-json-6.5.0.tgz",
+ "integrity": "sha512-k3bdm2n25tkyxcjSKzB5x8kfVxlMdgsbPr0GkZcwHsLpba6cBjqCt1KlcChKEvxHIcTB1FVMuwoijZ26xex5MQ==",
+ "dev": true,
+ "requires": {
+ "got": "^9.6.0",
+ "registry-auth-token": "^4.0.0",
+ "registry-url": "^5.0.0",
+ "semver": "^6.2.0"
+ },
+ "dependencies": {
+ "semver": {
+ "version": "6.3.0",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
+ "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
+ "dev": true
+ }
+ }
+ },
+ "parent-module": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz",
+ "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==",
+ "dev": true,
+ "requires": {
+ "callsites": "^3.0.0"
+ }
+ },
+ "parse-json": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz",
+ "integrity": "sha1-9ID0BDTvgHQfhGkJn43qGPVaTck=",
+ "dev": true,
+ "requires": {
+ "error-ex": "^1.2.0"
+ }
+ },
+ "pascalcase": {
+ "version": "0.1.1",
+ "resolved": "https://registry.npmjs.org/pascalcase/-/pascalcase-0.1.1.tgz",
+ "integrity": "sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ=",
+ "dev": true
+ },
+ "path-browserify": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-1.0.1.tgz",
+ "integrity": "sha512-b7uo2UCUOYZcnF/3ID0lulOJi/bafxa1xPe7ZPsammBSpjSWQkjNxlt635YGS2MiR9GjvuXCtz2emr3jbsz98g==",
+ "dev": true
+ },
+ "path-dirname": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/path-dirname/-/path-dirname-1.0.2.tgz",
+ "integrity": "sha1-zDPSTVJeCZpTiMAzbG4yuRYGCeA=",
+ "dev": true
+ },
+ "path-exists": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz",
+ "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=",
+ "dev": true
+ },
+ "path-is-absolute": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
+ "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=",
+ "dev": true
+ },
+ "path-key": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz",
+ "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=",
+ "dev": true
+ },
+ "path-parse": {
+ "version": "1.0.7",
+ "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz",
+ "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==",
+ "dev": true
+ },
+ "path-to-regexp": {
+ "version": "1.8.0",
+ "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-1.8.0.tgz",
+ "integrity": "sha512-n43JRhlUKUAlibEJhPeir1ncUID16QnEjNpwzNdO3Lm4ywrBpBZ5oLD0I6br9evr1Y9JTqwRtAh7JLoOzAQdVA==",
+ "dev": true,
+ "requires": {
+ "isarray": "0.0.1"
+ }
+ },
+ "path-type": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/path-type/-/path-type-2.0.0.tgz",
+ "integrity": "sha1-8BLMuEFbcJb8LaoQVMPXI4lZTHM=",
+ "dev": true,
+ "requires": {
+ "pify": "^2.0.0"
+ },
+ "dependencies": {
+ "pify": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz",
+ "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=",
+ "dev": true
+ }
+ }
+ },
+ "picocolors": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz",
+ "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==",
+ "dev": true
+ },
+ "picomatch": {
+ "version": "2.3.1",
+ "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz",
+ "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==",
+ "dev": true
+ },
+ "pify": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz",
+ "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==",
+ "dev": true
+ },
+ "pkg-conf": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/pkg-conf/-/pkg-conf-3.1.0.tgz",
+ "integrity": "sha512-m0OTbR/5VPNPqO1ph6Fqbj7Hv6QU7gR/tQW40ZqrL1rjgCU85W6C1bJn0BItuJqnR98PWzw7Z8hHeChD1WrgdQ==",
+ "dev": true,
+ "requires": {
+ "find-up": "^3.0.0",
+ "load-json-file": "^5.2.0"
+ },
+ "dependencies": {
+ "load-json-file": {
+ "version": "5.3.0",
+ "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-5.3.0.tgz",
+ "integrity": "sha512-cJGP40Jc/VXUsp8/OrnyKyTZ1y6v/dphm3bioS+RrKXjK2BB6wHUd6JptZEFDGgGahMT+InnZO5i1Ei9mpC8Bw==",
+ "dev": true,
+ "requires": {
+ "graceful-fs": "^4.1.15",
+ "parse-json": "^4.0.0",
+ "pify": "^4.0.1",
+ "strip-bom": "^3.0.0",
+ "type-fest": "^0.3.0"
+ }
+ },
+ "parse-json": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz",
+ "integrity": "sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA=",
+ "dev": true,
+ "requires": {
+ "error-ex": "^1.3.1",
+ "json-parse-better-errors": "^1.0.1"
+ }
+ },
+ "type-fest": {
+ "version": "0.3.1",
+ "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.3.1.tgz",
+ "integrity": "sha512-cUGJnCdr4STbePCgqNFbpVNCepa+kAVohJs1sLhxzdH+gnEoOd8VhbYa7pD3zZYGiURWM2xzEII3fQcRizDkYQ==",
+ "dev": true
+ }
+ }
+ },
+ "pkg-dir": {
+ "version": "4.2.0",
+ "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz",
+ "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==",
+ "dev": true,
+ "requires": {
+ "find-up": "^4.0.0"
+ },
+ "dependencies": {
+ "find-up": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz",
+ "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==",
+ "dev": true,
+ "requires": {
+ "locate-path": "^5.0.0",
+ "path-exists": "^4.0.0"
+ }
+ },
+ "locate-path": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz",
+ "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==",
+ "dev": true,
+ "requires": {
+ "p-locate": "^4.1.0"
+ }
+ },
+ "p-locate": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz",
+ "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==",
+ "dev": true,
+ "requires": {
+ "p-limit": "^2.2.0"
+ }
+ },
+ "path-exists": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz",
+ "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==",
+ "dev": true
+ }
+ }
+ },
+ "plur": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/plur/-/plur-3.1.1.tgz",
+ "integrity": "sha512-t1Ax8KUvV3FFII8ltczPn2tJdjqbd1sIzu6t4JL7nQ3EyeL/lTrj5PWKb06ic5/6XYDr65rQ4uzQEGN70/6X5w==",
+ "dev": true,
+ "requires": {
+ "irregular-plurals": "^2.0.0"
+ }
+ },
+ "posix-character-classes": {
+ "version": "0.1.1",
+ "resolved": "https://registry.npmjs.org/posix-character-classes/-/posix-character-classes-0.1.1.tgz",
+ "integrity": "sha1-AerA/jta9xoqbAL+q7jB/vfgDqs=",
+ "dev": true
+ },
+ "prelude-ls": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz",
+ "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=",
+ "dev": true
+ },
+ "prepend-http": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/prepend-http/-/prepend-http-2.0.0.tgz",
+ "integrity": "sha1-6SQ0v6XqjBn0HN/UAddBo8gZ2Jc=",
+ "dev": true
+ },
+ "prettier": {
+ "version": "1.19.1",
+ "resolved": "https://registry.npmjs.org/prettier/-/prettier-1.19.1.tgz",
+ "integrity": "sha512-s7PoyDv/II1ObgQunCbB9PdLmUcBZcnWOcxDh7O0N/UwDEsHyqkW+Qh28jW+mVuCdx7gLB0BotYI1Y6uI9iyew==",
+ "dev": true
+ },
+ "prettier-linter-helpers": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/prettier-linter-helpers/-/prettier-linter-helpers-1.0.0.tgz",
+ "integrity": "sha512-GbK2cP9nraSSUF9N2XwUwqfzlAFlMNYYl+ShE/V+H8a9uNl/oUqB1w2EL54Jh0OlyRSd8RfWYJ3coVS4TROP2w==",
+ "dev": true,
+ "requires": {
+ "fast-diff": "^1.1.2"
+ }
+ },
+ "process-nextick-args": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz",
+ "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==",
+ "dev": true
+ },
+ "progress": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz",
+ "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==",
+ "dev": true
+ },
+ "proto-props": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/proto-props/-/proto-props-2.0.0.tgz",
+ "integrity": "sha512-2yma2tog9VaRZY2mn3Wq51uiSW4NcPYT1cQdBagwyrznrilKSZwIZ0UG3ZPL/mx+axEns0hE35T5ufOYZXEnBQ==",
+ "dev": true
+ },
+ "pump": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz",
+ "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==",
+ "dev": true,
+ "requires": {
+ "end-of-stream": "^1.1.0",
+ "once": "^1.3.1"
+ }
+ },
+ "punycode": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz",
+ "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==",
+ "dev": true
+ },
+ "pupa": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/pupa/-/pupa-2.1.1.tgz",
+ "integrity": "sha512-l1jNAspIBSFqbT+y+5FosojNpVpF94nlI+wDUpqP9enwOTfHx9f0gh5nB96vl+6yTpsJsypeNrwfzPrKuHB41A==",
+ "dev": true,
+ "requires": {
+ "escape-goat": "^2.0.0"
+ }
+ },
+ "quick-lru": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-1.1.0.tgz",
+ "integrity": "sha1-Q2CxfGETatOAeDl/8RQW4Ybc+7g=",
+ "dev": true
+ },
+ "ramda": {
+ "version": "0.27.1",
+ "resolved": "https://registry.npmjs.org/ramda/-/ramda-0.27.1.tgz",
+ "integrity": "sha512-PgIdVpn5y5Yns8vqb8FzBUEYn98V3xcPgawAkkgj0YJ0qDsnHCiNmZYfOGMgOvoB0eWFLpYbhxUR3mxfDIMvpw==",
+ "dev": true
+ },
+ "randombytes": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz",
+ "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==",
+ "dev": true,
+ "requires": {
+ "safe-buffer": "^5.1.0"
+ }
+ },
+ "rc": {
+ "version": "1.2.8",
+ "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz",
+ "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==",
+ "dev": true,
+ "requires": {
+ "deep-extend": "^0.6.0",
+ "ini": "~1.3.0",
+ "minimist": "^1.2.0",
+ "strip-json-comments": "~2.0.1"
+ }
+ },
+ "read-pkg": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-2.0.0.tgz",
+ "integrity": "sha1-jvHAYjxqbbDcZxPEv6xGMysjaPg=",
+ "dev": true,
+ "requires": {
+ "load-json-file": "^2.0.0",
+ "normalize-package-data": "^2.3.2",
+ "path-type": "^2.0.0"
+ }
+ },
+ "read-pkg-up": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-2.0.0.tgz",
+ "integrity": "sha1-a3KoBImE4MQeeVEP1en6mbO1Sb4=",
+ "dev": true,
+ "requires": {
+ "find-up": "^2.0.0",
+ "read-pkg": "^2.0.0"
+ },
+ "dependencies": {
+ "find-up": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz",
+ "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=",
+ "dev": true,
+ "requires": {
+ "locate-path": "^2.0.0"
+ }
+ },
+ "locate-path": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz",
+ "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=",
+ "dev": true,
+ "requires": {
+ "p-locate": "^2.0.0",
+ "path-exists": "^3.0.0"
+ }
+ },
+ "p-limit": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz",
+ "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==",
+ "dev": true,
+ "requires": {
+ "p-try": "^1.0.0"
+ }
+ },
+ "p-locate": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz",
+ "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=",
+ "dev": true,
+ "requires": {
+ "p-limit": "^1.1.0"
+ }
+ },
+ "p-try": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz",
+ "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=",
+ "dev": true
+ }
+ }
+ },
+ "readable-stream": {
+ "version": "2.3.7",
+ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz",
+ "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==",
+ "dev": true,
+ "requires": {
+ "core-util-is": "~1.0.0",
+ "inherits": "~2.0.3",
+ "isarray": "~1.0.0",
+ "process-nextick-args": "~2.0.0",
+ "safe-buffer": "~5.1.1",
+ "string_decoder": "~1.1.1",
+ "util-deprecate": "~1.0.1"
+ },
+ "dependencies": {
+ "isarray": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
+ "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=",
+ "dev": true
+ }
+ }
+ },
+ "readdirp": {
+ "version": "3.6.0",
+ "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz",
+ "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==",
+ "dev": true,
+ "requires": {
+ "picomatch": "^2.2.1"
+ }
+ },
+ "rechoir": {
+ "version": "0.8.0",
+ "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.8.0.tgz",
+ "integrity": "sha512-/vxpCXddiX8NGfGO/mTafwjq4aFa/71pvamip0++IQk3zG8cbCj0fifNPrjjF1XMXUne91jL9OoxmdykoEtifQ==",
+ "dev": true,
+ "requires": {
+ "resolve": "^1.20.0"
+ }
+ },
+ "redent": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/redent/-/redent-2.0.0.tgz",
+ "integrity": "sha1-wbIAe0LVfrE4kHmzyDM2OdXhzKo=",
+ "dev": true,
+ "requires": {
+ "indent-string": "^3.0.0",
+ "strip-indent": "^2.0.0"
+ },
+ "dependencies": {
+ "indent-string": {
+ "version": "3.2.0",
+ "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-3.2.0.tgz",
+ "integrity": "sha1-Sl/W0nzDMvN+VBmlBNu4NxBckok=",
+ "dev": true
+ }
+ }
+ },
+ "regenerate": {
+ "version": "1.4.2",
+ "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.2.tgz",
+ "integrity": "sha512-zrceR/XhGYU/d/opr2EKO7aRHUeiBI8qjtfHqADTwZd6Szfy16la6kqD0MIUs5z5hx6AaKa+PixpPrR289+I0A==",
+ "dev": true
+ },
+ "regenerate-unicode-properties": {
+ "version": "8.2.0",
+ "resolved": "https://registry.npmjs.org/regenerate-unicode-properties/-/regenerate-unicode-properties-8.2.0.tgz",
+ "integrity": "sha512-F9DjY1vKLo/tPePDycuH3dn9H1OTPIkVD9Kz4LODu+F2C75mgjAJ7x/gwy6ZcSNRAAkhNlJSOHRe8k3p+K9WhA==",
+ "dev": true,
+ "requires": {
+ "regenerate": "^1.4.0"
+ }
+ },
+ "regenerator-runtime": {
+ "version": "0.13.7",
+ "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.7.tgz",
+ "integrity": "sha512-a54FxoJDIr27pgf7IgeQGxmqUNYrcV338lf/6gH456HZ/PhX+5BcwHXG9ajESmwe6WRO0tAzRUrRmNONWgkrew=="
+ },
+ "regenerator-transform": {
+ "version": "0.14.5",
+ "resolved": "https://registry.npmjs.org/regenerator-transform/-/regenerator-transform-0.14.5.tgz",
+ "integrity": "sha512-eOf6vka5IO151Jfsw2NO9WpGX58W6wWmefK3I1zEGr0lOD0u8rwPaNqQL1aRxUaxLeKO3ArNh3VYg1KbaD+FFw==",
+ "dev": true,
+ "requires": {
+ "@babel/runtime": "^7.8.4"
+ }
+ },
+ "regex-not": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/regex-not/-/regex-not-1.0.2.tgz",
+ "integrity": "sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A==",
+ "dev": true,
+ "requires": {
+ "extend-shallow": "^3.0.2",
+ "safe-regex": "^1.1.0"
+ }
+ },
+ "regexp-tree": {
+ "version": "0.1.21",
+ "resolved": "https://registry.npmjs.org/regexp-tree/-/regexp-tree-0.1.21.tgz",
+ "integrity": "sha512-kUUXjX4AnqnR8KRTCrayAo9PzYMRKmVoGgaz2tBuz0MF3g1ZbGebmtW0yFHfFK9CmBjQKeYIgoL22pFLBJY7sw==",
+ "dev": true
+ },
+ "regexpp": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-2.0.1.tgz",
+ "integrity": "sha512-lv0M6+TkDVniA3aD1Eg0DVpfU/booSu7Eev3TDO/mZKHBfVjgCGTV4t4buppESEYDtkArYFOxTJWv6S5C+iaNw==",
+ "dev": true
+ },
+ "regexpu-core": {
+ "version": "4.7.1",
+ "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-4.7.1.tgz",
+ "integrity": "sha512-ywH2VUraA44DZQuRKzARmw6S66mr48pQVva4LBeRhcOltJ6hExvWly5ZjFLYo67xbIxb6W1q4bAGtgfEl20zfQ==",
+ "dev": true,
+ "requires": {
+ "regenerate": "^1.4.0",
+ "regenerate-unicode-properties": "^8.2.0",
+ "regjsgen": "^0.5.1",
+ "regjsparser": "^0.6.4",
+ "unicode-match-property-ecmascript": "^1.0.4",
+ "unicode-match-property-value-ecmascript": "^1.2.0"
+ }
+ },
+ "registry-auth-token": {
+ "version": "4.2.0",
+ "resolved": "https://registry.npmjs.org/registry-auth-token/-/registry-auth-token-4.2.0.tgz",
+ "integrity": "sha512-P+lWzPrsgfN+UEpDS3U8AQKg/UjZX6mQSJueZj3EK+vNESoqBSpBUD3gmu4sF9lOsjXWjF11dQKUqemf3veq1w==",
+ "dev": true,
+ "requires": {
+ "rc": "^1.2.8"
+ }
+ },
+ "registry-url": {
+ "version": "5.1.0",
+ "resolved": "https://registry.npmjs.org/registry-url/-/registry-url-5.1.0.tgz",
+ "integrity": "sha512-8acYXXTI0AkQv6RAOjE3vOaIXZkT9wo4LOFbBKYQEEnnMNBpKqdUrI6S4NT0KPIo/WVvJ5tE/X5LF/TQUf0ekw==",
+ "dev": true,
+ "requires": {
+ "rc": "^1.2.8"
+ }
+ },
+ "regjsgen": {
+ "version": "0.5.2",
+ "resolved": "https://registry.npmjs.org/regjsgen/-/regjsgen-0.5.2.tgz",
+ "integrity": "sha512-OFFT3MfrH90xIW8OOSyUrk6QHD5E9JOTeGodiJeBS3J6IwlgzJMNE/1bZklWz5oTg+9dCMyEetclvCVXOPoN3A==",
+ "dev": true
+ },
+ "regjsparser": {
+ "version": "0.6.4",
+ "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.6.4.tgz",
+ "integrity": "sha512-64O87/dPDgfk8/RQqC4gkZoGyyWFIEUTTh80CU6CWuK5vkCGyekIx+oKcEIYtP/RAxSQltCZHCNu/mdd7fqlJw==",
+ "dev": true,
+ "requires": {
+ "jsesc": "~0.5.0"
+ },
+ "dependencies": {
+ "jsesc": {
+ "version": "0.5.0",
+ "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-0.5.0.tgz",
+ "integrity": "sha1-597mbjXW/Bb3EP6R1c9p9w8IkR0=",
+ "dev": true
+ }
+ }
+ },
+ "repeat-element": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.3.tgz",
+ "integrity": "sha512-ahGq0ZnV5m5XtZLMb+vP76kcAM5nkLqk0lpqAuojSKGgQtn4eRi4ZZGm2olo2zKFH+sMsWaqOCW1dqAnOru72g==",
+ "dev": true
+ },
+ "repeat-string": {
+ "version": "1.6.1",
+ "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz",
+ "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=",
+ "dev": true
+ },
+ "require-directory": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz",
+ "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=",
+ "dev": true
+ },
+ "reserved-words": {
+ "version": "0.1.2",
+ "resolved": "https://registry.npmjs.org/reserved-words/-/reserved-words-0.1.2.tgz",
+ "integrity": "sha1-AKCUD5jNUBrqqsMWQR2a3FKzGrE=",
+ "dev": true
+ },
+ "resolve": {
+ "version": "1.22.1",
+ "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.1.tgz",
+ "integrity": "sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw==",
+ "dev": true,
+ "requires": {
+ "is-core-module": "^2.9.0",
+ "path-parse": "^1.0.7",
+ "supports-preserve-symlinks-flag": "^1.0.0"
+ }
+ },
+ "resolve-cwd": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-3.0.0.tgz",
+ "integrity": "sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==",
+ "dev": true,
+ "requires": {
+ "resolve-from": "^5.0.0"
+ }
+ },
+ "resolve-from": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz",
+ "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==",
+ "dev": true
+ },
+ "resolve-url": {
+ "version": "0.2.1",
+ "resolved": "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz",
+ "integrity": "sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo=",
+ "dev": true
+ },
+ "responselike": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/responselike/-/responselike-1.0.2.tgz",
+ "integrity": "sha1-kYcg7ztjHFZCvgaPFa3lpG9Loec=",
+ "dev": true,
+ "requires": {
+ "lowercase-keys": "^1.0.0"
+ }
+ },
+ "restore-cursor": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz",
+ "integrity": "sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==",
+ "dev": true,
+ "requires": {
+ "onetime": "^5.1.0",
+ "signal-exit": "^3.0.2"
+ }
+ },
+ "ret": {
+ "version": "0.1.15",
+ "resolved": "https://registry.npmjs.org/ret/-/ret-0.1.15.tgz",
+ "integrity": "sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==",
+ "dev": true
+ },
+ "run-async": {
+ "version": "2.4.1",
+ "resolved": "https://registry.npmjs.org/run-async/-/run-async-2.4.1.tgz",
+ "integrity": "sha512-tvVnVv01b8c1RrA6Ep7JkStj85Guv/YrMcwqYQnwjsAS2cTmmPGBBjAjpCW7RrSodNSoE2/qg9O4bceNvUuDgQ==",
+ "dev": true
+ },
+ "rxjs": {
+ "version": "6.6.3",
+ "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.6.3.tgz",
+ "integrity": "sha512-trsQc+xYYXZ3urjOiJOuCOa5N3jAZ3eiSpQB5hIT8zGlL2QfnHLJ2r7GMkBGuIausdJN1OneaI6gQlsqNHHmZQ==",
+ "dev": true,
+ "requires": {
+ "tslib": "^1.9.0"
+ }
+ },
+ "safe-buffer": {
+ "version": "5.1.2",
+ "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
+ "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==",
+ "dev": true
+ },
+ "safe-regex": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz",
+ "integrity": "sha1-QKNmnzsHfR6UPURinhV91IAjvy4=",
+ "dev": true,
+ "requires": {
+ "ret": "~0.1.10"
+ }
+ },
+ "safer-buffer": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
+ "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==",
+ "dev": true
+ },
+ "schema-utils": {
+ "version": "2.7.1",
+ "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-2.7.1.tgz",
+ "integrity": "sha512-SHiNtMOUGWBQJwzISiVYKu82GiV4QYGePp3odlY1tuKO7gPtphAT5R/py0fA6xtbgLL/RvtJZnU9b8s0F1q0Xg==",
+ "dev": true,
+ "requires": {
+ "@types/json-schema": "^7.0.5",
+ "ajv": "^6.12.4",
+ "ajv-keywords": "^3.5.2"
+ }
+ },
+ "semver": {
+ "version": "5.7.1",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz",
+ "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==",
+ "dev": true
+ },
+ "semver-diff": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/semver-diff/-/semver-diff-3.1.1.tgz",
+ "integrity": "sha512-GX0Ix/CJcHyB8c4ykpHGIAvLyOwOobtM/8d+TQkAd81/bEjgPHrfba41Vpesr7jX/t8Uh+R3EX9eAS5be+jQYg==",
+ "dev": true,
+ "requires": {
+ "semver": "^6.3.0"
+ },
+ "dependencies": {
+ "semver": {
+ "version": "6.3.0",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
+ "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
+ "dev": true
+ }
+ }
+ },
+ "serialize-javascript": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.0.tgz",
+ "integrity": "sha512-Qr3TosvguFt8ePWqsvRfrKyQXIiW+nGbYpy8XK24NQHE83caxWt+mIymTT19DGFbNWNLfEwsrkSmN64lVWB9ag==",
+ "dev": true,
+ "requires": {
+ "randombytes": "^2.1.0"
+ }
+ },
+ "set-value": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.1.tgz",
+ "integrity": "sha512-JxHc1weCN68wRY0fhCoXpyK55m/XPHafOmK4UWD7m2CI14GMcFypt4w/0+NV5f/ZMby2F6S2wwA7fgynh9gWSw==",
+ "dev": true,
+ "requires": {
+ "extend-shallow": "^2.0.1",
+ "is-extendable": "^0.1.1",
+ "is-plain-object": "^2.0.3",
+ "split-string": "^3.0.1"
+ },
+ "dependencies": {
+ "extend-shallow": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
+ "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
+ "dev": true,
+ "requires": {
+ "is-extendable": "^0.1.0"
+ }
+ }
+ }
+ },
+ "shallow-clone": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/shallow-clone/-/shallow-clone-3.0.1.tgz",
+ "integrity": "sha512-/6KqX+GVUdqPuPPd2LxDDxzX6CAbjJehAAOKlNpqqUpAqPM6HeL8f+o3a+JsyGjn2lv0WY8UsTgUJjU9Ok55NA==",
+ "dev": true,
+ "requires": {
+ "kind-of": "^6.0.2"
+ }
+ },
+ "shebang-command": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz",
+ "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=",
+ "dev": true,
+ "requires": {
+ "shebang-regex": "^1.0.0"
+ }
+ },
+ "shebang-regex": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz",
+ "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=",
+ "dev": true
+ },
+ "should": {
+ "version": "13.2.3",
+ "resolved": "https://registry.npmjs.org/should/-/should-13.2.3.tgz",
+ "integrity": "sha512-ggLesLtu2xp+ZxI+ysJTmNjh2U0TsC+rQ/pfED9bUZZ4DKefP27D+7YJVVTvKsmjLpIi9jAa7itwDGkDDmt1GQ==",
+ "dev": true,
+ "requires": {
+ "should-equal": "^2.0.0",
+ "should-format": "^3.0.3",
+ "should-type": "^1.4.0",
+ "should-type-adaptors": "^1.0.1",
+ "should-util": "^1.0.0"
+ }
+ },
+ "should-equal": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/should-equal/-/should-equal-2.0.0.tgz",
+ "integrity": "sha512-ZP36TMrK9euEuWQYBig9W55WPC7uo37qzAEmbjHz4gfyuXrEUgF8cUvQVO+w+d3OMfPvSRQJ22lSm8MQJ43LTA==",
+ "dev": true,
+ "requires": {
+ "should-type": "^1.4.0"
+ }
+ },
+ "should-format": {
+ "version": "3.0.3",
+ "resolved": "https://registry.npmjs.org/should-format/-/should-format-3.0.3.tgz",
+ "integrity": "sha1-m/yPdPo5IFxT04w01xcwPidxJPE=",
+ "dev": true,
+ "requires": {
+ "should-type": "^1.3.0",
+ "should-type-adaptors": "^1.0.1"
+ }
+ },
+ "should-sinon": {
+ "version": "0.0.6",
+ "resolved": "https://registry.npmjs.org/should-sinon/-/should-sinon-0.0.6.tgz",
+ "integrity": "sha512-ScBOH5uW5QVFaONmUnIXANSR6z5B8IKzEmBP3HE5sPOCDuZ88oTMdUdnKoCVQdLcCIrRrhRLPS5YT+7H40a04g==",
+ "dev": true,
+ "requires": {}
+ },
+ "should-type": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/should-type/-/should-type-1.4.0.tgz",
+ "integrity": "sha1-B1bYzoRt/QmEOmlHcZ36DUz/XPM=",
+ "dev": true
+ },
+ "should-type-adaptors": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/should-type-adaptors/-/should-type-adaptors-1.1.0.tgz",
+ "integrity": "sha512-JA4hdoLnN+kebEp2Vs8eBe9g7uy0zbRo+RMcU0EsNy+R+k049Ki+N5tT5Jagst2g7EAja+euFuoXFCa8vIklfA==",
+ "dev": true,
+ "requires": {
+ "should-type": "^1.3.0",
+ "should-util": "^1.0.0"
+ }
+ },
+ "should-util": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/should-util/-/should-util-1.0.1.tgz",
+ "integrity": "sha512-oXF8tfxx5cDk8r2kYqlkUJzZpDBqVY/II2WhvU0n9Y3XYvAYRmeaf1PvvIvTgPnv4KJ+ES5M0PyDq5Jp+Ygy2g==",
+ "dev": true
+ },
+ "signal-exit": {
+ "version": "3.0.3",
+ "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.3.tgz",
+ "integrity": "sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA==",
+ "dev": true
+ },
+ "sinon": {
+ "version": "9.2.1",
+ "resolved": "https://registry.npmjs.org/sinon/-/sinon-9.2.1.tgz",
+ "integrity": "sha512-naPfsamB5KEE1aiioaoqJ6MEhdUs/2vtI5w1hPAXX/UwvoPjXcwh1m5HiKx0HGgKR8lQSoFIgY5jM6KK8VrS9w==",
+ "dev": true,
+ "requires": {
+ "@sinonjs/commons": "^1.8.1",
+ "@sinonjs/fake-timers": "^6.0.1",
+ "@sinonjs/formatio": "^5.0.1",
+ "@sinonjs/samsam": "^5.2.0",
+ "diff": "^4.0.2",
+ "nise": "^4.0.4",
+ "supports-color": "^7.1.0"
+ },
+ "dependencies": {
+ "diff": {
+ "version": "4.0.2",
+ "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz",
+ "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==",
+ "dev": true
+ },
+ "has-flag": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
+ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
+ "dev": true
+ },
+ "supports-color": {
+ "version": "7.2.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
+ "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
+ "dev": true,
+ "requires": {
+ "has-flag": "^4.0.0"
+ }
+ }
+ }
+ },
+ "slash": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz",
+ "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==",
+ "dev": true
+ },
+ "slice-ansi": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-2.1.0.tgz",
+ "integrity": "sha512-Qu+VC3EwYLldKa1fCxuuvULvSJOKEgk9pi8dZeCVK7TqBfUNTH4sFkk4joj8afVSfAYgJoSOetjx9QWOJ5mYoQ==",
+ "dev": true,
+ "requires": {
+ "ansi-styles": "^3.2.0",
+ "astral-regex": "^1.0.0",
+ "is-fullwidth-code-point": "^2.0.0"
+ }
+ },
+ "snapdragon": {
+ "version": "0.8.2",
+ "resolved": "https://registry.npmjs.org/snapdragon/-/snapdragon-0.8.2.tgz",
+ "integrity": "sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg==",
+ "dev": true,
+ "requires": {
+ "base": "^0.11.1",
+ "debug": "^2.2.0",
+ "define-property": "^0.2.5",
+ "extend-shallow": "^2.0.1",
+ "map-cache": "^0.2.2",
+ "source-map": "^0.5.6",
+ "source-map-resolve": "^0.5.0",
+ "use": "^3.1.0"
+ },
+ "dependencies": {
+ "debug": {
+ "version": "2.6.9",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
+ "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
+ "dev": true,
+ "requires": {
+ "ms": "2.0.0"
+ }
+ },
+ "define-property": {
+ "version": "0.2.5",
+ "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz",
+ "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=",
+ "dev": true,
+ "requires": {
+ "is-descriptor": "^0.1.0"
+ }
+ },
+ "extend-shallow": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
+ "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
+ "dev": true,
+ "requires": {
+ "is-extendable": "^0.1.0"
+ }
+ },
+ "ms": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
+ "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=",
+ "dev": true
+ }
+ }
+ },
+ "snapdragon-node": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/snapdragon-node/-/snapdragon-node-2.1.1.tgz",
+ "integrity": "sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw==",
+ "dev": true,
+ "requires": {
+ "define-property": "^1.0.0",
+ "isobject": "^3.0.0",
+ "snapdragon-util": "^3.0.1"
+ },
+ "dependencies": {
+ "define-property": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz",
+ "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=",
+ "dev": true,
+ "requires": {
+ "is-descriptor": "^1.0.0"
+ }
+ },
+ "is-accessor-descriptor": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz",
+ "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==",
+ "dev": true,
+ "requires": {
+ "kind-of": "^6.0.0"
+ }
+ },
+ "is-data-descriptor": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz",
+ "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==",
+ "dev": true,
+ "requires": {
+ "kind-of": "^6.0.0"
+ }
+ },
+ "is-descriptor": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz",
+ "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==",
+ "dev": true,
+ "requires": {
+ "is-accessor-descriptor": "^1.0.0",
+ "is-data-descriptor": "^1.0.0",
+ "kind-of": "^6.0.2"
+ }
+ }
+ }
+ },
+ "snapdragon-util": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/snapdragon-util/-/snapdragon-util-3.0.1.tgz",
+ "integrity": "sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ==",
+ "dev": true,
+ "requires": {
+ "kind-of": "^3.2.0"
+ },
+ "dependencies": {
+ "is-buffer": {
+ "version": "1.1.6",
+ "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz",
+ "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==",
+ "dev": true
+ },
+ "kind-of": {
+ "version": "3.2.2",
+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
+ "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
+ "dev": true,
+ "requires": {
+ "is-buffer": "^1.1.5"
+ }
+ }
+ }
+ },
+ "source-map": {
+ "version": "0.5.7",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz",
+ "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=",
+ "dev": true
+ },
+ "source-map-resolve": {
+ "version": "0.5.3",
+ "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.5.3.tgz",
+ "integrity": "sha512-Htz+RnsXWk5+P2slx5Jh3Q66vhQj1Cllm0zvnaY98+NFx+Dv2CF/f5O/t8x+KaNdrdIAsruNzoh/KpialbqAnw==",
+ "dev": true,
+ "requires": {
+ "atob": "^2.1.2",
+ "decode-uri-component": "^0.2.0",
+ "resolve-url": "^0.2.1",
+ "source-map-url": "^0.4.0",
+ "urix": "^0.1.0"
+ }
+ },
+ "source-map-support": {
+ "version": "0.5.21",
+ "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz",
+ "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==",
+ "dev": true,
+ "requires": {
+ "buffer-from": "^1.0.0",
+ "source-map": "^0.6.0"
+ },
+ "dependencies": {
+ "source-map": {
+ "version": "0.6.1",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
+ "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
+ "dev": true
+ }
+ }
+ },
+ "source-map-url": {
+ "version": "0.4.0",
+ "resolved": "https://registry.npmjs.org/source-map-url/-/source-map-url-0.4.0.tgz",
+ "integrity": "sha1-PpNdfd1zYxuXZZlW1VEo6HtQhKM=",
+ "dev": true
+ },
+ "spdx-correct": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.1.1.tgz",
+ "integrity": "sha512-cOYcUWwhCuHCXi49RhFRCyJEK3iPj1Ziz9DpViV3tbZOwXD49QzIN3MpOLJNxh2qwq2lJJZaKMVw9qNi4jTC0w==",
+ "dev": true,
+ "requires": {
+ "spdx-expression-parse": "^3.0.0",
+ "spdx-license-ids": "^3.0.0"
+ }
+ },
+ "spdx-exceptions": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.3.0.tgz",
+ "integrity": "sha512-/tTrYOC7PPI1nUAgx34hUpqXuyJG+DTHJTnIULG4rDygi4xu/tfgmq1e1cIRwRzwZgo4NLySi+ricLkZkw4i5A==",
+ "dev": true
+ },
+ "spdx-expression-parse": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz",
+ "integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==",
+ "dev": true,
+ "requires": {
+ "spdx-exceptions": "^2.1.0",
+ "spdx-license-ids": "^3.0.0"
+ }
+ },
+ "spdx-license-ids": {
+ "version": "3.0.6",
+ "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.6.tgz",
+ "integrity": "sha512-+orQK83kyMva3WyPf59k1+Y525csj5JejicWut55zeTWANuN17qSiSLUXWtzHeNWORSvT7GLDJ/E/XiIWoXBTw==",
+ "dev": true
+ },
+ "split-string": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/split-string/-/split-string-3.1.0.tgz",
+ "integrity": "sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw==",
+ "dev": true,
+ "requires": {
+ "extend-shallow": "^3.0.0"
+ }
+ },
+ "sprintf-js": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz",
+ "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=",
+ "dev": true
+ },
+ "static-extend": {
+ "version": "0.1.2",
+ "resolved": "https://registry.npmjs.org/static-extend/-/static-extend-0.1.2.tgz",
+ "integrity": "sha1-YICcOcv/VTNyJv1eC1IPNB8ftcY=",
+ "dev": true,
+ "requires": {
+ "define-property": "^0.2.5",
+ "object-copy": "^0.1.0"
+ },
+ "dependencies": {
+ "define-property": {
+ "version": "0.2.5",
+ "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz",
+ "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=",
+ "dev": true,
+ "requires": {
+ "is-descriptor": "^0.1.0"
+ }
+ }
+ }
+ },
+ "string_decoder": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
+ "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
+ "dev": true,
+ "requires": {
+ "safe-buffer": "~5.1.0"
+ }
+ },
+ "string-width": {
+ "version": "4.2.3",
+ "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
+ "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
+ "dev": true,
+ "requires": {
+ "emoji-regex": "^8.0.0",
+ "is-fullwidth-code-point": "^3.0.0",
+ "strip-ansi": "^6.0.1"
+ },
+ "dependencies": {
+ "emoji-regex": {
+ "version": "8.0.0",
+ "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
+ "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==",
+ "dev": true
+ },
+ "is-fullwidth-code-point": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
+ "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==",
+ "dev": true
+ }
+ }
+ },
+ "string.prototype.trimend": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.2.tgz",
+ "integrity": "sha512-8oAG/hi14Z4nOVP0z6mdiVZ/wqjDtWSLygMigTzAb+7aPEDTleeFf+WrF+alzecxIRkckkJVn+dTlwzJXORATw==",
+ "dev": true,
+ "requires": {
+ "define-properties": "^1.1.3",
+ "es-abstract": "^1.18.0-next.1"
+ },
+ "dependencies": {
+ "es-abstract": {
+ "version": "1.18.0-next.1",
+ "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.18.0-next.1.tgz",
+ "integrity": "sha512-I4UGspA0wpZXWENrdA0uHbnhte683t3qT/1VFH9aX2dA5PPSf6QW5HHXf5HImaqPmjXaVeVk4RGWnaylmV7uAA==",
+ "dev": true,
+ "requires": {
+ "es-to-primitive": "^1.2.1",
+ "function-bind": "^1.1.1",
+ "has": "^1.0.3",
+ "has-symbols": "^1.0.1",
+ "is-callable": "^1.2.2",
+ "is-negative-zero": "^2.0.0",
+ "is-regex": "^1.1.1",
+ "object-inspect": "^1.8.0",
+ "object-keys": "^1.1.1",
+ "object.assign": "^4.1.1",
+ "string.prototype.trimend": "^1.0.1",
+ "string.prototype.trimstart": "^1.0.1"
+ }
+ }
+ }
+ },
+ "string.prototype.trimstart": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.2.tgz",
+ "integrity": "sha512-7F6CdBTl5zyu30BJFdzSTlSlLPwODC23Od+iLoVH8X6+3fvDPPuBVVj9iaB1GOsSTSIgVfsfm27R2FGrAPznWg==",
+ "dev": true,
+ "requires": {
+ "define-properties": "^1.1.3",
+ "es-abstract": "^1.18.0-next.1"
+ },
+ "dependencies": {
+ "es-abstract": {
+ "version": "1.18.0-next.1",
+ "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.18.0-next.1.tgz",
+ "integrity": "sha512-I4UGspA0wpZXWENrdA0uHbnhte683t3qT/1VFH9aX2dA5PPSf6QW5HHXf5HImaqPmjXaVeVk4RGWnaylmV7uAA==",
+ "dev": true,
+ "requires": {
+ "es-to-primitive": "^1.2.1",
+ "function-bind": "^1.1.1",
+ "has": "^1.0.3",
+ "has-symbols": "^1.0.1",
+ "is-callable": "^1.2.2",
+ "is-negative-zero": "^2.0.0",
+ "is-regex": "^1.1.1",
+ "object-inspect": "^1.8.0",
+ "object-keys": "^1.1.1",
+ "object.assign": "^4.1.1",
+ "string.prototype.trimend": "^1.0.1",
+ "string.prototype.trimstart": "^1.0.1"
+ }
+ }
+ }
+ },
+ "strip-ansi": {
+ "version": "6.0.1",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
+ "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
+ "dev": true,
+ "requires": {
+ "ansi-regex": "^5.0.1"
+ }
+ },
+ "strip-bom": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz",
+ "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=",
+ "dev": true
+ },
+ "strip-indent": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-2.0.0.tgz",
+ "integrity": "sha1-XvjbKV0B5u1sv3qrlpmNeCJSe2g=",
+ "dev": true
+ },
+ "strip-json-comments": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz",
+ "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=",
+ "dev": true
+ },
+ "supports-color": {
+ "version": "5.5.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
+ "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
+ "dev": true,
+ "requires": {
+ "has-flag": "^3.0.0"
+ }
+ },
+ "supports-hyperlinks": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/supports-hyperlinks/-/supports-hyperlinks-2.1.0.tgz",
+ "integrity": "sha512-zoE5/e+dnEijk6ASB6/qrK+oYdm2do1hjoLWrqUC/8WEIW1gbxFcKuBof7sW8ArN6e+AYvsE8HBGiVRWL/F5CA==",
+ "dev": true,
+ "requires": {
+ "has-flag": "^4.0.0",
+ "supports-color": "^7.0.0"
+ },
+ "dependencies": {
+ "has-flag": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
+ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
+ "dev": true
+ },
+ "supports-color": {
+ "version": "7.2.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
+ "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
+ "dev": true,
+ "requires": {
+ "has-flag": "^4.0.0"
+ }
+ }
+ }
+ },
+ "supports-preserve-symlinks-flag": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz",
+ "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==",
+ "dev": true
+ },
+ "table": {
+ "version": "5.4.6",
+ "resolved": "https://registry.npmjs.org/table/-/table-5.4.6.tgz",
+ "integrity": "sha512-wmEc8m4fjnob4gt5riFRtTu/6+4rSe12TpAELNSqHMfF3IqnA+CH37USM6/YR3qRZv7e56kAEAtd6nKZaxe0Ug==",
+ "dev": true,
+ "requires": {
+ "ajv": "^6.10.2",
+ "lodash": "^4.17.14",
+ "slice-ansi": "^2.1.0",
+ "string-width": "^3.0.0"
+ },
+ "dependencies": {
+ "ansi-regex": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.1.tgz",
+ "integrity": "sha512-ILlv4k/3f6vfQ4OoP2AGvirOktlQ98ZEL1k9FaQjxa3L1abBgbuTDAdPOpvbGncC0BTVQrl+OM8xZGK6tWXt7g==",
+ "dev": true
+ },
+ "string-width": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz",
+ "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==",
+ "dev": true,
+ "requires": {
+ "emoji-regex": "^7.0.1",
+ "is-fullwidth-code-point": "^2.0.0",
+ "strip-ansi": "^5.1.0"
+ }
+ },
+ "strip-ansi": {
+ "version": "5.2.0",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz",
+ "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==",
+ "dev": true,
+ "requires": {
+ "ansi-regex": "^4.1.0"
+ }
+ }
+ }
+ },
+ "tapable": {
+ "version": "2.2.1",
+ "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.1.tgz",
+ "integrity": "sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==",
+ "dev": true
+ },
+ "term-size": {
+ "version": "2.2.1",
+ "resolved": "https://registry.npmjs.org/term-size/-/term-size-2.2.1.tgz",
+ "integrity": "sha512-wK0Ri4fOGjv/XPy8SBHZChl8CM7uMc5VML7SqiQ0zG7+J5Vr+RMQDoHa2CNT6KHUnTGIXH34UDMkPzAUyapBZg==",
+ "dev": true
+ },
+ "terser": {
+ "version": "5.16.1",
+ "resolved": "https://registry.npmjs.org/terser/-/terser-5.16.1.tgz",
+ "integrity": "sha512-xvQfyfA1ayT0qdK47zskQgRZeWLoOQ8JQ6mIgRGVNwZKdQMU+5FkCBjmv4QjcrTzyZquRw2FVtlJSRUmMKQslw==",
+ "dev": true,
+ "requires": {
+ "@jridgewell/source-map": "^0.3.2",
+ "acorn": "^8.5.0",
+ "commander": "^2.20.0",
+ "source-map-support": "~0.5.20"
+ }
+ },
+ "terser-webpack-plugin": {
+ "version": "5.3.6",
+ "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.3.6.tgz",
+ "integrity": "sha512-kfLFk+PoLUQIbLmB1+PZDMRSZS99Mp+/MHqDNmMA6tOItzRt+Npe3E+fsMs5mfcM0wCtrrdU387UnV+vnSffXQ==",
+ "dev": true,
+ "requires": {
+ "@jridgewell/trace-mapping": "^0.3.14",
+ "jest-worker": "^27.4.5",
+ "schema-utils": "^3.1.1",
+ "serialize-javascript": "^6.0.0",
+ "terser": "^5.14.1"
+ },
+ "dependencies": {
+ "schema-utils": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.1.1.tgz",
+ "integrity": "sha512-Y5PQxS4ITlC+EahLuXaY86TXfR7Dc5lw294alXOq86JAHCihAIZfqv8nNCWvaEJvaC51uN9hbLGeV0cFBdH+Fw==",
+ "dev": true,
+ "requires": {
+ "@types/json-schema": "^7.0.8",
+ "ajv": "^6.12.5",
+ "ajv-keywords": "^3.5.2"
+ }
+ }
+ }
+ },
+ "text-table": {
+ "version": "0.2.0",
+ "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz",
+ "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=",
+ "dev": true
+ },
+ "through": {
+ "version": "2.3.8",
+ "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz",
+ "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=",
+ "dev": true
+ },
+ "through2": {
+ "version": "2.0.5",
+ "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz",
+ "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==",
+ "dev": true,
+ "requires": {
+ "readable-stream": "~2.3.6",
+ "xtend": "~4.0.1"
+ }
+ },
+ "tmp": {
+ "version": "0.0.33",
+ "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz",
+ "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==",
+ "dev": true,
+ "requires": {
+ "os-tmpdir": "~1.0.2"
+ }
+ },
+ "to-fast-properties": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz",
+ "integrity": "sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=",
+ "dev": true
+ },
+ "to-object-path": {
+ "version": "0.3.0",
+ "resolved": "https://registry.npmjs.org/to-object-path/-/to-object-path-0.3.0.tgz",
+ "integrity": "sha1-KXWIt7Dn4KwI4E5nL4XB9JmeF68=",
+ "dev": true,
+ "requires": {
+ "kind-of": "^3.0.2"
+ },
+ "dependencies": {
+ "is-buffer": {
+ "version": "1.1.6",
+ "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz",
+ "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==",
+ "dev": true
+ },
+ "kind-of": {
+ "version": "3.2.2",
+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
+ "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
+ "dev": true,
+ "requires": {
+ "is-buffer": "^1.1.5"
+ }
+ }
+ }
+ },
+ "to-readable-stream": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/to-readable-stream/-/to-readable-stream-1.0.0.tgz",
+ "integrity": "sha512-Iq25XBt6zD5npPhlLVXGFN3/gyR2/qODcKNNyTMd4vbm39HUaOiAM4PMq0eMVC/Tkxz+Zjdsc55g9yyz+Yq00Q==",
+ "dev": true
+ },
+ "to-regex": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/to-regex/-/to-regex-3.0.2.tgz",
+ "integrity": "sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw==",
+ "dev": true,
+ "requires": {
+ "define-property": "^2.0.2",
+ "extend-shallow": "^3.0.2",
+ "regex-not": "^1.0.2",
+ "safe-regex": "^1.1.0"
+ }
+ },
+ "to-regex-range": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
+ "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==",
+ "dev": true,
+ "requires": {
+ "is-number": "^7.0.0"
+ }
+ },
+ "tokenizer2": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/tokenizer2/-/tokenizer2-2.0.1.tgz",
+ "integrity": "sha512-WAUyv8sbJuFMq4OgQAcXVYrJj1YALGz2Ah4yMyMxRD5DrMnogbtQV3r2RDZ69/Zxh3yYc/olp8rURZ0t3mLevQ==",
+ "dev": true,
+ "requires": {
+ "through2": "^2.0.0"
+ }
+ },
+ "trim-newlines": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/trim-newlines/-/trim-newlines-2.0.0.tgz",
+ "integrity": "sha1-tAPQuRvlDDMd/EuC7s6yLD3hbSA=",
+ "dev": true
+ },
+ "tsconfig-paths": {
+ "version": "3.14.1",
+ "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.14.1.tgz",
+ "integrity": "sha512-fxDhWnFSLt3VuTwtvJt5fpwxBHg5AdKWMsgcPOOIilyjymcYVZoCQF8fvFRezCNfblEXmi+PcM1eYHeOAgXCOQ==",
+ "dev": true,
+ "requires": {
+ "@types/json5": "^0.0.29",
+ "json5": "^1.0.1",
+ "minimist": "^1.2.6",
+ "strip-bom": "^3.0.0"
+ },
+ "dependencies": {
+ "json5": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.2.tgz",
+ "integrity": "sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==",
+ "dev": true,
+ "requires": {
+ "minimist": "^1.2.0"
+ }
+ }
+ }
+ },
+ "tslib": {
+ "version": "1.14.1",
+ "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz",
+ "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==",
+ "dev": true
+ },
+ "type-check": {
+ "version": "0.3.2",
+ "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz",
+ "integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=",
+ "dev": true,
+ "requires": {
+ "prelude-ls": "~1.1.2"
+ }
+ },
+ "type-detect": {
+ "version": "4.0.8",
+ "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz",
+ "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==",
+ "dev": true
+ },
+ "type-fest": {
+ "version": "0.8.1",
+ "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz",
+ "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==",
+ "dev": true
+ },
+ "typedarray-to-buffer": {
+ "version": "3.1.5",
+ "resolved": "https://registry.npmjs.org/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz",
+ "integrity": "sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q==",
+ "dev": true,
+ "requires": {
+ "is-typedarray": "^1.0.0"
+ }
+ },
+ "unicode-canonical-property-names-ecmascript": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-1.0.4.tgz",
+ "integrity": "sha512-jDrNnXWHd4oHiTZnx/ZG7gtUTVp+gCcTTKr8L0HjlwphROEW3+Him+IpvC+xcJEFegapiMZyZe02CyuOnRmbnQ==",
+ "dev": true
+ },
+ "unicode-match-property-ecmascript": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/unicode-match-property-ecmascript/-/unicode-match-property-ecmascript-1.0.4.tgz",
+ "integrity": "sha512-L4Qoh15vTfntsn4P1zqnHulG0LdXgjSO035fEpdtp6YxXhMT51Q6vgM5lYdG/5X3MjS+k/Y9Xw4SFCY9IkR0rg==",
+ "dev": true,
+ "requires": {
+ "unicode-canonical-property-names-ecmascript": "^1.0.4",
+ "unicode-property-aliases-ecmascript": "^1.0.4"
+ }
+ },
+ "unicode-match-property-value-ecmascript": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-1.2.0.tgz",
+ "integrity": "sha512-wjuQHGQVofmSJv1uVISKLE5zO2rNGzM/KCYZch/QQvez7C1hUhBIuZ701fYXExuufJFMPhv2SyL8CyoIfMLbIQ==",
+ "dev": true
+ },
+ "unicode-property-aliases-ecmascript": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-1.1.0.tgz",
+ "integrity": "sha512-PqSoPh/pWetQ2phoj5RLiaqIk4kCNwoV3CI+LfGmWLKI3rE3kl1h59XpX2BjgDrmbxD9ARtQobPGU1SguCYuQg==",
+ "dev": true
+ },
+ "union-value": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/union-value/-/union-value-1.0.1.tgz",
+ "integrity": "sha512-tJfXmxMeWYnczCVs7XAEvIV7ieppALdyepWMkHkwciRpZraG/xwT+s2JN8+pr1+8jCRf80FFzvr+MpQeeoF4Xg==",
+ "dev": true,
+ "requires": {
+ "arr-union": "^3.1.0",
+ "get-value": "^2.0.6",
+ "is-extendable": "^0.1.1",
+ "set-value": "^2.0.1"
+ }
+ },
+ "unique-string": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/unique-string/-/unique-string-2.0.0.tgz",
+ "integrity": "sha512-uNaeirEPvpZWSgzwsPGtU2zVSTrn/8L5q/IexZmH0eH6SA73CmAA5U4GwORTxQAZs95TAXLNqeLoPPNO5gZfWg==",
+ "dev": true,
+ "requires": {
+ "crypto-random-string": "^2.0.0"
+ }
+ },
+ "unset-value": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/unset-value/-/unset-value-1.0.0.tgz",
+ "integrity": "sha1-g3aHP30jNRef+x5vw6jtDfyKtVk=",
+ "dev": true,
+ "requires": {
+ "has-value": "^0.3.1",
+ "isobject": "^3.0.0"
+ },
+ "dependencies": {
+ "has-value": {
+ "version": "0.3.1",
+ "resolved": "https://registry.npmjs.org/has-value/-/has-value-0.3.1.tgz",
+ "integrity": "sha1-ex9YutpiyoJ+wKIHgCVlSEWZXh8=",
+ "dev": true,
+ "requires": {
+ "get-value": "^2.0.3",
+ "has-values": "^0.1.4",
+ "isobject": "^2.0.0"
+ },
+ "dependencies": {
+ "isobject": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz",
+ "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=",
+ "dev": true,
+ "requires": {
+ "isarray": "1.0.0"
+ }
+ }
+ }
+ },
+ "has-values": {
+ "version": "0.1.4",
+ "resolved": "https://registry.npmjs.org/has-values/-/has-values-0.1.4.tgz",
+ "integrity": "sha1-bWHeldkd/Km5oCCJrThL/49it3E=",
+ "dev": true
+ },
+ "isarray": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
+ "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=",
+ "dev": true
+ }
+ }
+ },
+ "update-notifier": {
+ "version": "4.1.3",
+ "resolved": "https://registry.npmjs.org/update-notifier/-/update-notifier-4.1.3.tgz",
+ "integrity": "sha512-Yld6Z0RyCYGB6ckIjffGOSOmHXj1gMeE7aROz4MG+XMkmixBX4jUngrGXNYz7wPKBmtoD4MnBa2Anu7RSKht/A==",
+ "dev": true,
+ "requires": {
+ "boxen": "^4.2.0",
+ "chalk": "^3.0.0",
+ "configstore": "^5.0.1",
+ "has-yarn": "^2.1.0",
+ "import-lazy": "^2.1.0",
+ "is-ci": "^2.0.0",
+ "is-installed-globally": "^0.3.1",
+ "is-npm": "^4.0.0",
+ "is-yarn-global": "^0.3.0",
+ "latest-version": "^5.0.0",
+ "pupa": "^2.0.1",
+ "semver-diff": "^3.1.1",
+ "xdg-basedir": "^4.0.0"
+ },
+ "dependencies": {
+ "ansi-styles": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
+ "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
+ "dev": true,
+ "requires": {
+ "color-convert": "^2.0.1"
+ }
+ },
+ "chalk": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz",
+ "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==",
+ "dev": true,
+ "requires": {
+ "ansi-styles": "^4.1.0",
+ "supports-color": "^7.1.0"
+ }
+ },
+ "color-convert": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
+ "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
+ "dev": true,
+ "requires": {
+ "color-name": "~1.1.4"
+ }
+ },
+ "color-name": {
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
+ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
+ "dev": true
+ },
+ "has-flag": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
+ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
+ "dev": true
+ },
+ "supports-color": {
+ "version": "7.2.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
+ "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
+ "dev": true,
+ "requires": {
+ "has-flag": "^4.0.0"
+ }
+ }
+ }
+ },
+ "uri-js": {
+ "version": "4.4.0",
+ "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.0.tgz",
+ "integrity": "sha512-B0yRTzYdUCCn9n+F4+Gh4yIDtMQcaJsmYBDsTSG8g/OejKBodLQ2IHfN3bM7jUsRXndopT7OIXWdYqc1fjmV6g==",
+ "dev": true,
+ "requires": {
+ "punycode": "^2.1.0"
+ }
+ },
+ "urix": {
+ "version": "0.1.0",
+ "resolved": "https://registry.npmjs.org/urix/-/urix-0.1.0.tgz",
+ "integrity": "sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI=",
+ "dev": true
+ },
+ "url-parse-lax": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/url-parse-lax/-/url-parse-lax-3.0.0.tgz",
+ "integrity": "sha1-FrXK/Afb42dsGxmZF3gj1lA6yww=",
+ "dev": true,
+ "requires": {
+ "prepend-http": "^2.0.0"
+ }
+ },
+ "use": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/use/-/use-3.1.1.tgz",
+ "integrity": "sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ==",
+ "dev": true
+ },
+ "util-deprecate": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
+ "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=",
+ "dev": true
+ },
+ "v8-compile-cache": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.2.0.tgz",
+ "integrity": "sha512-gTpR5XQNKFwOd4clxfnhaqvfqMpqEwr4tOtCyz4MtYZX2JYhfr1JvBFKdS+7K/9rfpZR3VLX+YWBbKoxCgS43Q==",
+ "dev": true
+ },
+ "validate-npm-package-license": {
+ "version": "3.0.4",
+ "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz",
+ "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==",
+ "dev": true,
+ "requires": {
+ "spdx-correct": "^3.0.0",
+ "spdx-expression-parse": "^3.0.0"
+ }
+ },
+ "walk": {
+ "version": "2.3.14",
+ "resolved": "https://registry.npmjs.org/walk/-/walk-2.3.14.tgz",
+ "integrity": "sha512-5skcWAUmySj6hkBdH6B6+3ddMjVQYH5Qy9QGbPmN8kVmLteXk+yVXg+yfk1nbX30EYakahLrr8iPcCxJQSCBeg==",
+ "requires": {
+ "foreachasync": "^3.0.0"
+ }
+ },
+ "watchpack": {
+ "version": "2.4.0",
+ "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.4.0.tgz",
+ "integrity": "sha512-Lcvm7MGST/4fup+ifyKi2hjyIAwcdI4HRgtvTpIUxBRhB+RFtUh8XtDOxUfctVCnhVi+QQj49i91OyvzkJl6cg==",
+ "dev": true,
+ "requires": {
+ "glob-to-regexp": "^0.4.1",
+ "graceful-fs": "^4.1.2"
+ },
+ "dependencies": {
+ "glob-to-regexp": {
+ "version": "0.4.1",
+ "resolved": "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz",
+ "integrity": "sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==",
+ "dev": true
+ }
+ }
+ },
+ "webpack": {
+ "version": "5.75.0",
+ "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.75.0.tgz",
+ "integrity": "sha512-piaIaoVJlqMsPtX/+3KTTO6jfvrSYgauFVdt8cr9LTHKmcq/AMd4mhzsiP7ZF/PGRNPGA8336jldh9l2Kt2ogQ==",
+ "dev": true,
+ "requires": {
+ "@types/eslint-scope": "^3.7.3",
+ "@types/estree": "^0.0.51",
+ "@webassemblyjs/ast": "1.11.1",
+ "@webassemblyjs/wasm-edit": "1.11.1",
+ "@webassemblyjs/wasm-parser": "1.11.1",
+ "acorn": "^8.7.1",
+ "acorn-import-assertions": "^1.7.6",
+ "browserslist": "^4.14.5",
+ "chrome-trace-event": "^1.0.2",
+ "enhanced-resolve": "^5.10.0",
+ "es-module-lexer": "^0.9.0",
+ "eslint-scope": "5.1.1",
+ "events": "^3.2.0",
+ "glob-to-regexp": "^0.4.1",
+ "graceful-fs": "^4.2.9",
+ "json-parse-even-better-errors": "^2.3.1",
+ "loader-runner": "^4.2.0",
+ "mime-types": "^2.1.27",
+ "neo-async": "^2.6.2",
+ "schema-utils": "^3.1.0",
+ "tapable": "^2.1.1",
+ "terser-webpack-plugin": "^5.1.3",
+ "watchpack": "^2.4.0",
+ "webpack-sources": "^3.2.3"
+ },
+ "dependencies": {
+ "glob-to-regexp": {
+ "version": "0.4.1",
+ "resolved": "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz",
+ "integrity": "sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==",
+ "dev": true
+ },
+ "schema-utils": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.1.1.tgz",
+ "integrity": "sha512-Y5PQxS4ITlC+EahLuXaY86TXfR7Dc5lw294alXOq86JAHCihAIZfqv8nNCWvaEJvaC51uN9hbLGeV0cFBdH+Fw==",
+ "dev": true,
+ "requires": {
+ "@types/json-schema": "^7.0.8",
+ "ajv": "^6.12.5",
+ "ajv-keywords": "^3.5.2"
+ }
+ },
+ "webpack-sources": {
+ "version": "3.2.3",
+ "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-3.2.3.tgz",
+ "integrity": "sha512-/DyMEOrDgLKKIG0fmvtz+4dUX/3Ghozwgm6iPp8KRhvn+eQf9+Q7GWxVNMk3+uCPWfdXYC4ExGBckIXdFEfH1w==",
+ "dev": true
+ }
+ }
+ },
+ "webpack-cli": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/webpack-cli/-/webpack-cli-5.0.1.tgz",
+ "integrity": "sha512-S3KVAyfwUqr0Mo/ur3NzIp6jnerNpo7GUO6so51mxLi1spqsA17YcMXy0WOIJtBSnj748lthxC6XLbNKh/ZC+A==",
+ "dev": true,
+ "requires": {
+ "@discoveryjs/json-ext": "^0.5.0",
+ "@webpack-cli/configtest": "^2.0.1",
+ "@webpack-cli/info": "^2.0.1",
+ "@webpack-cli/serve": "^2.0.1",
+ "colorette": "^2.0.14",
+ "commander": "^9.4.1",
+ "cross-spawn": "^7.0.3",
+ "envinfo": "^7.7.3",
+ "fastest-levenshtein": "^1.0.12",
+ "import-local": "^3.0.2",
+ "interpret": "^3.1.1",
+ "rechoir": "^0.8.0",
+ "webpack-merge": "^5.7.3"
+ },
+ "dependencies": {
+ "commander": {
+ "version": "9.4.1",
+ "resolved": "https://registry.npmjs.org/commander/-/commander-9.4.1.tgz",
+ "integrity": "sha512-5EEkTNyHNGFPD2H+c/dXXfQZYa/scCKasxWcXJaWnNJ99pnQN9Vnmqow+p+PlFPE63Q6mThaZws1T+HxfpgtPw==",
+ "dev": true
+ },
+ "cross-spawn": {
+ "version": "7.0.3",
+ "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz",
+ "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==",
+ "dev": true,
+ "requires": {
+ "path-key": "^3.1.0",
+ "shebang-command": "^2.0.0",
+ "which": "^2.0.1"
+ }
+ },
+ "path-key": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz",
+ "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==",
+ "dev": true
+ },
+ "shebang-command": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz",
+ "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==",
+ "dev": true,
+ "requires": {
+ "shebang-regex": "^3.0.0"
+ }
+ },
+ "shebang-regex": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz",
+ "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==",
+ "dev": true
+ },
+ "which": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
+ "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==",
+ "dev": true,
+ "requires": {
+ "isexe": "^2.0.0"
+ }
+ }
+ }
+ },
+ "webpack-merge": {
+ "version": "5.8.0",
+ "resolved": "https://registry.npmjs.org/webpack-merge/-/webpack-merge-5.8.0.tgz",
+ "integrity": "sha512-/SaI7xY0831XwP6kzuwhKWVKDP9t1QY1h65lAFLbZqMPIuYcD9QAW4u9STIbU9kaJbPBB/geU/gLr1wDjOhQ+Q==",
+ "dev": true,
+ "requires": {
+ "clone-deep": "^4.0.1",
+ "wildcard": "^2.0.0"
+ }
+ },
+ "which": {
+ "version": "1.3.1",
+ "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz",
+ "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==",
+ "dev": true,
+ "requires": {
+ "isexe": "^2.0.0"
+ }
+ },
+ "widest-line": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/widest-line/-/widest-line-3.1.0.tgz",
+ "integrity": "sha512-NsmoXalsWVDMGupxZ5R08ka9flZjjiLvHVAWYOKtiKM8ujtZWr9cRffak+uSE48+Ob8ObalXpwyeUiyDD6QFgg==",
+ "dev": true,
+ "requires": {
+ "string-width": "^4.0.0"
+ }
+ },
+ "wildcard": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/wildcard/-/wildcard-2.0.0.tgz",
+ "integrity": "sha512-JcKqAHLPxcdb9KM49dufGXn2x3ssnfjbcaQdLlfZsL9rH9wgDQjUtDxbo8NE0F6SFvydeu1VhZe7hZuHsB2/pw==",
+ "dev": true
+ },
+ "word-wrap": {
+ "version": "1.2.3",
+ "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz",
+ "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==",
+ "dev": true
+ },
+ "workerpool": {
+ "version": "6.2.0",
+ "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-6.2.0.tgz",
+ "integrity": "sha512-Rsk5qQHJ9eowMH28Jwhe8HEbmdYDX4lwoMWshiCXugjtHqMD9ZbiqSDLxcsfdqsETPzVUtX5s1Z5kStiIM6l4A==",
+ "dev": true
+ },
+ "wrappy": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
+ "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=",
+ "dev": true
+ },
+ "write": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/write/-/write-1.0.3.tgz",
+ "integrity": "sha512-/lg70HAjtkUgWPVZhZcm+T4hkL8Zbtp1nFNOn3lRrxnlv50SRBv7cR7RqR+GMsd3hUXy9hWBo4CHTbFTcOYwig==",
+ "dev": true,
+ "requires": {
+ "mkdirp": "^0.5.1"
+ }
+ },
+ "write-file-atomic": {
+ "version": "3.0.3",
+ "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-3.0.3.tgz",
+ "integrity": "sha512-AvHcyZ5JnSfq3ioSyjrBkH9yW4m7Ayk8/9My/DD9onKeu/94fwrMocemO2QAJFAlnnDN+ZDS+ZjAR5ua1/PV/Q==",
+ "dev": true,
+ "requires": {
+ "imurmurhash": "^0.1.4",
+ "is-typedarray": "^1.0.0",
+ "signal-exit": "^3.0.2",
+ "typedarray-to-buffer": "^3.1.5"
+ }
+ },
+ "xdg-basedir": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/xdg-basedir/-/xdg-basedir-4.0.0.tgz",
+ "integrity": "sha512-PSNhEJDejZYV7h50BohL09Er9VaIefr2LMAf3OEmpCkjOi34eYyQYAXUTjEQtZJTKcF0E2UKTh+osDLsgNim9Q==",
+ "dev": true
+ },
+ "xo": {
+ "version": "0.26.1",
+ "resolved": "https://registry.npmjs.org/xo/-/xo-0.26.1.tgz",
+ "integrity": "sha512-m2h2NrFoprrB8jsCvZFx5Wn3uLwd9k4mTo4bA+ZzXOv3fCOMMW8sA2C+qCCNTuEdRarYRtO068+cerM8ZnBiCQ==",
+ "dev": true,
+ "requires": {
+ "arrify": "^2.0.1",
+ "debug": "^4.1.0",
+ "eslint": "^6.8.0",
+ "eslint-config-prettier": "^6.10.0",
+ "eslint-config-xo": "^0.29.0",
+ "eslint-formatter-pretty": "^3.0.1",
+ "eslint-plugin-ava": "^10.0.1",
+ "eslint-plugin-eslint-comments": "^3.1.2",
+ "eslint-plugin-import": "^2.20.1",
+ "eslint-plugin-no-use-extend-native": "^0.4.1",
+ "eslint-plugin-node": "^11.0.0",
+ "eslint-plugin-prettier": "^3.1.2",
+ "eslint-plugin-promise": "^4.2.1",
+ "eslint-plugin-unicorn": "^16.1.1",
+ "find-cache-dir": "^3.0.0",
+ "get-stdin": "^7.0.0",
+ "globby": "^9.0.0",
+ "has-flag": "^4.0.0",
+ "lodash": "^4.17.15",
+ "meow": "^5.0.0",
+ "multimatch": "^4.0.0",
+ "open-editor": "^2.0.1",
+ "path-exists": "^4.0.0",
+ "pkg-conf": "^3.1.0",
+ "prettier": "^1.15.2",
+ "resolve-cwd": "^3.0.0",
+ "resolve-from": "^5.0.0",
+ "semver": "^7.1.3",
+ "slash": "^3.0.0",
+ "update-notifier": "^4.0.0"
+ },
+ "dependencies": {
+ "has-flag": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
+ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
+ "dev": true
+ },
+ "path-exists": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz",
+ "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==",
+ "dev": true
+ },
+ "semver": {
+ "version": "7.3.2",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.2.tgz",
+ "integrity": "sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ==",
+ "dev": true
+ }
+ }
+ },
+ "xtend": {
+ "version": "4.0.2",
+ "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz",
+ "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==",
+ "dev": true
+ },
+ "yargs-unparser": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-2.0.0.tgz",
+ "integrity": "sha512-7pRTIA9Qc1caZ0bZ6RYRGbHJthJWuakf+WmHK0rVeLkNrrGhfoabBNdue6kdINI6r4if7ocq9aD/n7xwKOdzOA==",
+ "dev": true,
+ "requires": {
+ "camelcase": "^6.0.0",
+ "decamelize": "^4.0.0",
+ "flat": "^5.0.2",
+ "is-plain-obj": "^2.1.0"
+ },
+ "dependencies": {
+ "camelcase": {
+ "version": "6.3.0",
+ "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz",
+ "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==",
+ "dev": true
+ },
+ "decamelize": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-4.0.0.tgz",
+ "integrity": "sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ==",
+ "dev": true
+ },
+ "is-plain-obj": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-2.1.0.tgz",
+ "integrity": "sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==",
+ "dev": true
+ }
+ }
+ },
+ "yocto-queue": {
+ "version": "0.1.0",
+ "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz",
+ "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==",
+ "dev": true
+ }
+ }
+}
diff --git a/package.json b/package.json
index 53495143..ea41fa8e 100644
--- a/package.json
+++ b/package.json
@@ -2,35 +2,74 @@
"author": "John Roepke (http://john.sh/)",
"name": "twig",
"description": "JS port of the Twig templating language.",
- "version": "0.7.2",
- "homepage": "https://github.com/justjohn/twig.js",
+ "version": "1.17.1",
+ "homepage": "https://github.com/twigjs/twig.js",
+ "license": "BSD-2-Clause",
"licenses": [
- { "type": "BSD-2-Clause",
- "url": "https://raw.github.com/justjohn/twig.js/master/LICENSE" }
+ {
+ "type": "BSD-2-Clause",
+ "url": "https://raw.github.com/twigjs/twig.js/master/LICENSE"
+ }
],
"repository": {
"type": "git",
- "url": "git://github.com/justjohn/twig.js.git"
+ "url": "git://github.com/twigjs/twig.js.git"
},
- "main": "twig.min.js",
+ "main": "src/twig.js",
"engines": {
- "node": "*"
+ "node": ">=10"
},
"bin": {
"twigjs": "./bin/twigjs"
},
"scripts": {
- "test": "make test"
+ "preversion": "npm test && git diff --exit-code --quiet",
+ "postversion": "git push origin master && git push origin master --tags",
+ "pretest": "npm run build",
+ "test": "mocha -r should",
+ "build": "node node/build.js",
+ "posttest": "xo src lib bin"
},
"dependencies": {
- "walk": "2.3.x",
- "minimatch": "0.2.x"
+ "@babel/runtime": "^7.8.4",
+ "locutus": "^2.0.11",
+ "minimatch": "3.0.x",
+ "walk": "2.3.x"
},
"devDependencies": {
- "tokenizer": "1.1.x",
- "should": "3.3.x",
- "mocha": "1.18.x",
- "docco": "0.6.x",
- "uglify-js": "2.4.x"
+ "@babel/core": "^7.8.4",
+ "@babel/plugin-transform-runtime": "^7.8.3",
+ "@babel/preset-env": "^7.8.4",
+ "babel-loader": "^8.0.6",
+ "eslint-plugin-mocha": "^6.3.0",
+ "mocha": "^9.0.0",
+ "path-browserify": "^1.0.1",
+ "should": "^13.2.3",
+ "should-sinon": "0.0.6",
+ "sinon": "^9.0.0",
+ "terser-webpack-plugin": "^5.3.6",
+ "tokenizer2": "^2.0.1",
+ "webpack": "^5.75.0",
+ "webpack-cli": "^5.0.1",
+ "xo": "^0.26.1"
+ },
+ "browser": {
+ "fs": false
+ },
+ "xo": {
+ "space": 4,
+ "envs": [
+ "browser",
+ "node",
+ "mocha"
+ ],
+ "plugins": [
+ "mocha"
+ ],
+ "rules": {
+ "promise/prefer-await-to-then": 0,
+ "prefer-arrow-callback": 0,
+ "mocha/prefer-arrow-callback": 2
+ }
}
}
diff --git a/src/.gitignore b/src/.gitignore
new file mode 100644
index 00000000..b90ae812
--- /dev/null
+++ b/src/.gitignore
@@ -0,0 +1 @@
+!twig.js
diff --git a/src/twig.async.js b/src/twig.async.js
new file mode 100644
index 00000000..62a50da3
--- /dev/null
+++ b/src/twig.async.js
@@ -0,0 +1,377 @@
+// ## twig.async.js
+//
+// This file handles asynchronous tasks within twig.
+module.exports = function (Twig) {
+ 'use strict';
+
+ const STATE_UNKNOWN = 0;
+ const STATE_RESOLVED = 1;
+ const STATE_REJECTED = 2;
+
+ Twig.ParseState.prototype.parseAsync = function (tokens, context) {
+ return this.parse(tokens, context, true);
+ };
+
+ Twig.expression.parseAsync = function (tokens, context, tokensAreParameters) {
+ const state = this;
+
+ return Twig.expression.parse.call(state, tokens, context, tokensAreParameters, true);
+ };
+
+ Twig.logic.parseAsync = function (token, context, chain) {
+ const state = this;
+
+ return Twig.logic.parse.call(state, token, context, chain, true);
+ };
+
+ Twig.Template.prototype.renderAsync = function (context, params) {
+ return this.render(context, params, true);
+ };
+
+ Twig.async = {};
+
+ /**
+ * Checks for `thenable` objects
+ */
+ Twig.isPromise = function (obj) {
+ return obj && obj.then && (typeof obj.then === 'function');
+ };
+
+ /**
+ * Handling of code paths that might either return a promise
+ * or a value depending on whether async code is used.
+ *
+ * @see https://github.com/twigjs/twig.js/blob/master/ASYNC.md#detecting-asynchronous-behaviour
+ */
+ function potentiallyAsyncSlow(that, allowAsync, action) {
+ let result = action.call(that);
+ let err = null;
+ let isAsync = true;
+
+ if (!Twig.isPromise(result)) {
+ return result;
+ }
+
+ result.then(res => {
+ result = res;
+ isAsync = false;
+ }).catch(error => {
+ err = error;
+ });
+
+ if (err !== null) {
+ throw err;
+ }
+
+ if (isAsync) {
+ throw new Twig.Error('You are using Twig.js in sync mode in combination with async extensions.');
+ }
+
+ return result;
+ }
+
+ Twig.async.potentiallyAsync = function (that, allowAsync, action) {
+ if (allowAsync) {
+ return Twig.Promise.resolve(action.call(that));
+ }
+
+ return potentiallyAsyncSlow(that, allowAsync, action);
+ };
+
+ function run(fn, resolve, reject) {
+ try {
+ fn(resolve, reject);
+ } catch (error) {
+ reject(error);
+ }
+ }
+
+ function pending(handlers, onResolved, onRejected) {
+ const h = [onResolved, onRejected, -2];
+
+ // The promise has yet to be rejected or resolved.
+ if (!handlers) {
+ handlers = h;
+ } else if (handlers[2] === -2) {
+ // Only allocate an array when there are multiple handlers
+ handlers = [handlers, h];
+ } else {
+ handlers.push(h);
+ }
+
+ return handlers;
+ }
+
+ /**
+ * Really small thenable to represent promises that resolve immediately.
+ *
+ */
+ Twig.Thenable = function (then, value, state) {
+ this.then = then;
+ this._value = state ? value : null;
+ this._state = state || STATE_UNKNOWN;
+ };
+
+ Twig.Thenable.prototype.catch = function (onRejected) {
+ // THe promise will not throw, it has already resolved.
+ if (this._state === STATE_RESOLVED) {
+ return this;
+ }
+
+ return this.then(null, onRejected);
+ };
+
+ /**
+ * The `then` method attached to a Thenable when it has resolved.
+ *
+ */
+ Twig.Thenable.resolvedThen = function (onResolved) {
+ try {
+ return Twig.Promise.resolve(onResolved(this._value));
+ } catch (error) {
+ return Twig.Promise.reject(error);
+ }
+ };
+
+ /**
+ * The `then` method attached to a Thenable when it has rejected.
+ *
+ */
+ Twig.Thenable.rejectedThen = function (onResolved, onRejected) {
+ // Shortcut for rejected twig promises
+ if (!onRejected || typeof onRejected !== 'function') {
+ return this;
+ }
+
+ const value = this._value;
+
+ let result;
+ try {
+ result = onRejected(value);
+ } catch (error) {
+ result = Twig.Promise.reject(error);
+ }
+
+ return Twig.Promise.resolve(result);
+ };
+
+ /**
+ * An alternate implementation of a Promise that does not fully follow
+ * the spec, but instead works fully synchronous while still being
+ * thenable.
+ *
+ * These promises can be mixed with regular promises at which point
+ * the synchronous behaviour is lost.
+ */
+ Twig.Promise = function (executor) {
+ let state = STATE_UNKNOWN;
+ let value = null;
+
+ let changeState = function (nextState, nextValue) {
+ state = nextState;
+ value = nextValue;
+ };
+
+ function onReady(v) {
+ changeState(STATE_RESOLVED, v);
+ }
+
+ function onReject(e) {
+ changeState(STATE_REJECTED, e);
+ }
+
+ run(executor, onReady, onReject);
+
+ // If the promise settles right after running the executor we can
+ // return a Promise with it's state already set.
+ //
+ // Twig.Promise.resolve and Twig.Promise.reject both use the more
+ // efficient `Twig.Thenable` for this purpose.
+ if (state === STATE_RESOLVED) {
+ return Twig.Promise.resolve(value);
+ }
+
+ if (state === STATE_REJECTED) {
+ return Twig.Promise.reject(value);
+ }
+ // If we managed to get here our promise is going to resolve asynchronous.
+
+ changeState = new Twig.FullPromise();
+
+ return changeState.promise;
+ };
+
+ /**
+ * Promise implementation that can handle being resolved at any later time.
+ *
+ */
+ Twig.FullPromise = function () {
+ let handlers = null;
+
+ // The state has been changed to either resolve, or reject
+ // which means we should call the handler.
+ function resolved(onResolved) {
+ onResolved(p._value);
+ }
+
+ function rejected(onResolved, onRejected) {
+ onRejected(p._value);
+ }
+
+ let append = function (onResolved, onRejected) {
+ handlers = pending(handlers, onResolved, onRejected);
+ };
+
+ function changeState(newState, v) {
+ if (p._state) {
+ return;
+ }
+
+ p._value = v;
+ p._state = newState;
+
+ append = newState === STATE_RESOLVED ? resolved : rejected;
+
+ if (!handlers) {
+ return;
+ }
+
+ if (handlers[2] === -2) {
+ append(handlers[0], handlers[1]);
+ handlers = null;
+ return;
+ }
+
+ handlers.forEach(h => {
+ append(h[0], h[1]);
+ });
+ handlers = null;
+ }
+
+ const p = new Twig.Thenable((onResolved, onRejected) => {
+ const hasResolved = typeof onResolved === 'function';
+
+ // Shortcut for resolved twig promises
+ if (p._state === STATE_RESOLVED && !hasResolved) {
+ return Twig.Promise.resolve(p._value);
+ }
+
+ if (p._state === STATE_RESOLVED) {
+ try {
+ return Twig.Promise.resolve(onResolved(p._value));
+ } catch (error) {
+ return Twig.Promise.reject(error);
+ }
+ }
+
+ const hasRejected = typeof onRejected === 'function';
+
+ return new Twig.Promise((resolve, reject) => {
+ append(
+ hasResolved ? result => {
+ try {
+ resolve(onResolved(result));
+ } catch (error) {
+ reject(error);
+ }
+ } : resolve,
+ hasRejected ? err => {
+ try {
+ resolve(onRejected(err));
+ } catch (error) {
+ reject(error);
+ }
+ } : reject
+ );
+ });
+ });
+
+ changeState.promise = p;
+
+ return changeState;
+ };
+
+ Twig.Promise.defaultResolved = new Twig.Thenable(Twig.Thenable.resolvedThen, undefined, STATE_RESOLVED);
+ Twig.Promise.emptyStringResolved = new Twig.Thenable(Twig.Thenable.resolvedThen, '', STATE_RESOLVED);
+
+ Twig.Promise.resolve = function (value) {
+ if (arguments.length === 0 || typeof value === 'undefined') {
+ return Twig.Promise.defaultResolved;
+ }
+
+ if (Twig.isPromise(value)) {
+ return value;
+ }
+
+ // Twig often resolves with an empty string, we optimize for this
+ // scenario by returning a fixed promise. This reduces the load on
+ // garbage collection.
+ if (value === '') {
+ return Twig.Promise.emptyStringResolved;
+ }
+
+ return new Twig.Thenable(Twig.Thenable.resolvedThen, value, STATE_RESOLVED);
+ };
+
+ Twig.Promise.reject = function (e) {
+ // `e` should never be a promise.
+ return new Twig.Thenable(Twig.Thenable.rejectedThen, e, STATE_REJECTED);
+ };
+
+ Twig.Promise.all = function (promises) {
+ const results = new Array(promises.length);
+
+ return Twig.async.forEach(promises, (p, index) => {
+ if (!Twig.isPromise(p)) {
+ results[index] = p;
+ return;
+ }
+
+ if (p._state === STATE_RESOLVED) {
+ results[index] = p._value;
+ return;
+ }
+
+ return p.then(v => {
+ results[index] = v;
+ });
+ }).then(() => {
+ return results;
+ });
+ };
+
+ /**
+ * Go over each item in a fashion compatible with Twig.forEach,
+ * allow the function to return a promise or call the third argument
+ * to signal it is finished.
+ *
+ * Each item in the array will be called sequentially.
+ */
+ Twig.async.forEach = function (arr, callback) {
+ const len = arr ? arr.length : 0;
+ let index = 0;
+
+ function next() {
+ let resp = null;
+
+ do {
+ if (index === len) {
+ return Twig.Promise.resolve();
+ }
+
+ resp = callback(arr[index], index);
+ index++;
+
+ // While the result of the callback is not a promise or it is
+ // a promise that has settled we can use a regular loop which
+ // is much faster.
+ } while (!resp || !Twig.isPromise(resp) || resp._state === STATE_RESOLVED);
+
+ return resp.then(next);
+ }
+
+ return next();
+ };
+
+ return Twig;
+};
diff --git a/src/twig.compiler.js b/src/twig.compiler.js
index e0e88488..32425c12 100644
--- a/src/twig.compiler.js
+++ b/src/twig.compiler.js
@@ -1,12 +1,7 @@
-// Twig.js
-// Copyright (c) 2011-2013 John Roepke
-// Available under the BSD 2-Clause License
-// https://github.com/justjohn/twig.js
-
// ## twig.compiler.js
//
// This file handles compiling templates into JS
-var Twig = (function (Twig) {
+module.exports = function (Twig) {
/**
* Namespace for compilation.
*/
@@ -15,42 +10,40 @@ var Twig = (function (Twig) {
};
// Compile a Twig Template to output.
- Twig.compiler.compile = function(template, options) {
+ Twig.compiler.compile = function (template, options) {
// Get tokens
- var tokens = JSON.stringify(template.tokens)
- , id = template.id
- , output;
+ const tokens = JSON.stringify(template.tokens);
+ const {id} = template;
+ let output = null;
if (options.module) {
if (Twig.compiler.module[options.module] === undefined) {
- throw new Twig.Error("Unable to find module type " + options.module);
+ throw new Twig.Error('Unable to find module type ' + options.module);
}
+
output = Twig.compiler.module[options.module](id, tokens, options.twig);
} else {
output = Twig.compiler.wrap(id, tokens);
}
+
return output;
};
Twig.compiler.module = {
- amd: function(id, tokens, pathToTwig) {
+ amd(id, tokens, pathToTwig) {
return 'define(["' + pathToTwig + '"], function (Twig) {\n\tvar twig, templates;\ntwig = Twig.twig;\ntemplates = ' + Twig.compiler.wrap(id, tokens) + '\n\treturn templates;\n});';
- }
- , node: function(id, tokens) {
- return 'var twig = require("twig").twig;\n'
- + 'exports.template = ' + Twig.compiler.wrap(id, tokens)
- }
- , cjs2: function(id, tokens, pathToTwig) {
- return 'module.declare([{ twig: "' + pathToTwig + '" }], function (require, exports, module) {\n'
- + '\tvar twig = require("twig").twig;\n'
- + '\texports.template = ' + Twig.compiler.wrap(id, tokens)
- + '\n});'
+ },
+ node(id, tokens) {
+ return 'var twig = require("twig").twig;\nexports.template = ' + Twig.compiler.wrap(id, tokens);
+ },
+ cjs2(id, tokens, pathToTwig) {
+ return 'module.declare([{ twig: "' + pathToTwig + '" }], function (require, exports, module) {\n\tvar twig = require("twig").twig;\n\texports.template = ' + Twig.compiler.wrap(id, tokens) + '\n});';
}
};
- Twig.compiler.wrap = function(id, tokens) {
- return 'twig({id:"'+id.replace('"', '\\"')+'", data:'+tokens+', precompiled: true});\n';
+ Twig.compiler.wrap = function (id, tokens) {
+ return 'twig({id:"' + id.replace('"', '\\"') + '", data:' + tokens + ', precompiled: true});\n';
};
return Twig;
-})(Twig || {});
+};
diff --git a/src/twig.core.js b/src/twig.core.js
index 05985a2c..d896d5c3 100644
--- a/src/twig.core.js
+++ b/src/twig.core.js
@@ -1,13 +1,8 @@
-// Twig.js
-// Copyright (c) 2011-2013 John Roepke
-// Available under the BSD 2-Clause License
-// https://github.com/justjohn/twig.js
-
-var Twig = (function (Twig) {
- "use strict";
- // ## twig.core.js
- //
- // This file handles template level tokenizing, compiling and parsing.
+// ## twig.core.js
+//
+// This file handles template level tokenizing, compiling and parsing.
+module.exports = function (Twig) {
+ 'use strict';
Twig.trace = false;
Twig.debug = false;
@@ -15,123 +10,35 @@ var Twig = (function (Twig) {
// Default caching to true for the improved performance it offers
Twig.cache = true;
- Twig.placeholders = {
- parent: "{{|PARENT|}}"
- };
+ Twig.noop = function () {};
- /**
- * Fallback for Array.indexOf for IE8 et al
- */
- Twig.indexOf = function (arr, searchElement /*, fromIndex */ ) {
- if (Array.prototype.hasOwnProperty("indexOf")) {
- return arr.indexOf(searchElement);
- }
- if (arr === void 0 || arr === null) {
- throw new TypeError();
- }
- var t = Object(arr);
- var len = t.length >>> 0;
- if (len === 0) {
- return -1;
- }
- var n = 0;
- if (arguments.length > 0) {
- n = Number(arguments[1]);
- if (n !== n) { // shortcut for verifying if it's NaN
- n = 0;
- } else if (n !== 0 && n !== Infinity && n !== -Infinity) {
- n = (n > 0 || -1) * Math.floor(Math.abs(n));
+ Twig.merge = function (target, source, onlyChanged) {
+ Object.keys(source).forEach(key => {
+ if (onlyChanged && !(key in target)) {
+ return;
}
- }
- if (n >= len) {
- // console.log("indexOf not found1 ", JSON.stringify(searchElement), JSON.stringify(arr));
- return -1;
- }
- var k = n >= 0 ? n : Math.max(len - Math.abs(n), 0);
- for (; k < len; k++) {
- if (k in t && t[k] === searchElement) {
- return k;
- }
- }
- if (arr == searchElement) {
- return 0;
- }
- // console.log("indexOf not found2 ", JSON.stringify(searchElement), JSON.stringify(arr));
-
- return -1;
- }
-
- Twig.forEach = function (arr, callback, thisArg) {
- if (Array.prototype.forEach ) {
- return arr.forEach(callback, thisArg);
- }
-
- var T, k;
-
- if ( arr == null ) {
- throw new TypeError( " this is null or not defined" );
- }
-
- // 1. Let O be the result of calling ToObject passing the |this| value as the argument.
- var O = Object(arr);
-
- // 2. Let lenValue be the result of calling the Get internal method of O with the argument "length".
- // 3. Let len be ToUint32(lenValue).
- var len = O.length >>> 0; // Hack to convert O.length to a UInt32
-
- // 4. If IsCallable(callback) is false, throw a TypeError exception.
- // See: http://es5.github.com/#x9.11
- if ( {}.toString.call(callback) != "[object Function]" ) {
- throw new TypeError( callback + " is not a function" );
- }
-
- // 5. If thisArg was supplied, let T be thisArg; else let T be undefined.
- if ( thisArg ) {
- T = thisArg;
- }
-
- // 6. Let k be 0
- k = 0;
-
- // 7. Repeat, while k < len
- while( k < len ) {
-
- var kValue;
-
- // a. Let Pk be ToString(k).
- // This is implicit for LHS operands of the in operator
- // b. Let kPresent be the result of calling the HasProperty internal method of O with argument Pk.
- // This step can be combined with c
- // c. If kPresent is true, then
- if ( k in O ) {
- // i. Let kValue be the result of calling the Get internal method of O with argument Pk.
- kValue = O[ k ];
+ target[key] = source[key];
+ });
- // ii. Call the Call internal method of callback with T as the this value and
- // argument list containing kValue, k, and O.
- callback.call( T, kValue, k, O );
- }
- // d. Increase k by 1.
- k++;
- }
- // 8. return undefined
+ return target;
};
/**
* Exception thrown by twig.js.
*/
- Twig.Error = function(message) {
- this.message = message;
- this.name = "TwigException";
- this.type = "TwigException";
+ Twig.Error = function (message, file) {
+ this.message = message;
+ this.name = 'TwigException';
+ this.type = 'TwigException';
+ this.file = file;
};
/**
* Get the string representation of a Twig error.
*/
- Twig.Error.prototype.toString = function() {
- var output = this.name + ": " + this.message;
+ Twig.Error.prototype.toString = function () {
+ const output = this.name + ': ' + this.message;
return output;
};
@@ -140,17 +47,28 @@ var Twig = (function (Twig) {
* Wrapper for logging to the console.
*/
Twig.log = {
- trace: function() {if (Twig.trace && console) {console.log(Array.prototype.slice.call(arguments));}},
- debug: function() {if (Twig.debug && console) {console.log(Array.prototype.slice.call(arguments));}},
+ trace(...args) {
+ if (Twig.trace && console) {
+ console.log(Array.prototype.slice.call(args));
+ }
+ },
+ debug(...args) {
+ if (Twig.debug && console) {
+ console.log(Array.prototype.slice.call(args));
+ }
+ }
};
- if (typeof console !== "undefined" &&
- typeof console.log !== "undefined") {
- Twig.log.error = function() {
- console.log.apply(console, arguments);
- }
- } else {
- Twig.log.error = function(){};
+ if (typeof console === 'undefined') {
+ Twig.log.error = function () {};
+ } else if (typeof console.error !== 'undefined') {
+ Twig.log.error = function (...args) {
+ console.error(...args);
+ };
+ } else if (typeof console.log !== 'undefined') {
+ Twig.log.error = function (...args) {
+ console.log(...args);
+ };
}
/**
@@ -163,10 +81,16 @@ var Twig = (function (Twig) {
* Token types.
*/
Twig.token.type = {
- output: 'output',
- logic: 'logic',
+ output: 'output',
+ logic: 'logic',
comment: 'comment',
- raw: 'raw'
+ raw: 'raw',
+ outputWhitespacePre: 'output_whitespace_pre',
+ outputWhitespacePost: 'output_whitespace_post',
+ outputWhitespaceBoth: 'output_whitespace_both',
+ logicWhitespacePre: 'logic_whitespace_pre',
+ logicWhitespacePost: 'logic_whitespace_post',
+ logicWhitespaceBoth: 'logic_whitespace_both'
};
/**
@@ -178,6 +102,44 @@ var Twig = (function (Twig) {
open: '{% raw %}',
close: '{% endraw %}'
},
+ {
+ type: Twig.token.type.raw,
+ open: '{% verbatim %}',
+ close: '{% endverbatim %}'
+ },
+ // *Whitespace type tokens*
+ //
+ // These typically take the form `{{- expression -}}` or `{{- expression }}` or `{{ expression -}}`.
+ {
+ type: Twig.token.type.outputWhitespacePre,
+ open: '{{-',
+ close: '}}'
+ },
+ {
+ type: Twig.token.type.outputWhitespacePost,
+ open: '{{',
+ close: '-}}'
+ },
+ {
+ type: Twig.token.type.outputWhitespaceBoth,
+ open: '{{-',
+ close: '-}}'
+ },
+ {
+ type: Twig.token.type.logicWhitespacePre,
+ open: '{%-',
+ close: '%}'
+ },
+ {
+ type: Twig.token.type.logicWhitespacePost,
+ open: '{%',
+ close: '-%}'
+ },
+ {
+ type: Twig.token.type.logicWhitespaceBoth,
+ open: '{%-',
+ close: '-%}'
+ },
// *Output type tokens*
//
// These typically take the form `{{ expression }}`.
@@ -204,106 +166,157 @@ var Twig = (function (Twig) {
}
];
-
/**
* What characters start "strings" in token definitions. We need this to ignore token close
* strings inside an expression.
*/
- Twig.token.strings = ['"', "'"];
+ Twig.token.strings = ['"', '\''];
Twig.token.findStart = function (template) {
- var output = {
- position: null,
- def: null
- },
- i,
- token_template,
- first_key_position;
-
- for (i=0;i= 0) {
+ // This token matches the template
+ if (tokenTemplate.open.length !== tokenTemplate.close.length) {
+ // This token has mismatched closing and opening tags
+ if (closeKeyPosition < 0) {
+ // This token's closing tag does not match the template
+ continue;
+ }
+ }
+ }
// Does this token occur before any other types?
- if (first_key_position >= 0 && (output.position === null || first_key_position < output.position)) {
- output.position = first_key_position;
- output.def = token_template;
+
+ if (firstKeyPosition >= 0 && (output.position === null || firstKeyPosition < output.position)) {
+ output.position = firstKeyPosition;
+ output.def = tokenTemplate;
+ closePosition = closeKeyPosition;
+ } else if (firstKeyPosition >= 0 && output.position !== null && firstKeyPosition === output.position) {
+ /* This token exactly matches another token,
+ greedily match to check if this token has a greater specificity */
+ if (tokenTemplate.open.length > output.def.open.length) {
+ // This token's opening tag is more specific than the previous match
+ output.position = firstKeyPosition;
+ output.def = tokenTemplate;
+ closePosition = closeKeyPosition;
+ } else if (tokenTemplate.open.length === output.def.open.length) {
+ if (tokenTemplate.close.length > output.def.close.length) {
+ // This token's opening tag is as specific as the previous match,
+ // but the closing tag has greater specificity
+ if (closeKeyPosition >= 0 && closeKeyPosition < closePosition) {
+ // This token's closing tag exists in the template,
+ // and it occurs sooner than the previous match
+ output.position = firstKeyPosition;
+ output.def = tokenTemplate;
+ closePosition = closeKeyPosition;
+ }
+ } else if (closeKeyPosition >= 0 && closeKeyPosition < closePosition) {
+ // This token's closing tag is not more specific than the previous match,
+ // but it occurs sooner than the previous match
+ output.position = firstKeyPosition;
+ output.def = tokenTemplate;
+ closePosition = closeKeyPosition;
+ }
+ }
}
}
return output;
};
- Twig.token.findEnd = function (template, token_def, start) {
- var end = null,
- found = false,
- offset = 0,
+ Twig.token.findEnd = function (template, tokenDef, start) {
+ let end = null;
+ let found = false;
+ let offset = 0;
- // String position variables
- str_pos = null,
- str_found = null,
- pos = null,
- end_offset = null,
- this_str_pos = null,
- end_str_pos = null,
+ // String position variables
+ let strPos = null;
+ let strFound = null;
+ let pos = null;
+ let endOffset = null;
+ let thisStrPos = null;
+ let endStrPos = null;
- // For loop variables
- i,
- l;
+ // For loop variables
+ let i;
+ let l;
while (!found) {
- str_pos = null;
- str_found = null;
- pos = template.indexOf(token_def.close, offset);
+ strPos = null;
+ strFound = null;
+ pos = template.indexOf(tokenDef.close, offset);
if (pos >= 0) {
end = pos;
found = true;
} else {
- // throw an exception
- throw new Twig.Error("Unable to find closing bracket '" + token_def.close +
- "'" + " opened near template position " + start);
+ // Throw an exception
+ throw new Twig.Error('Unable to find closing bracket \'' + tokenDef.close +
+ '\' opened near template position ' + start);
}
// Ignore quotes within comments; just look for the next comment close sequence,
// regardless of what comes before it. https://github.com/justjohn/twig.js/issues/95
- if (token_def.type === Twig.token.type.comment) {
- break;
+ if (tokenDef.type === Twig.token.type.comment) {
+ break;
+ }
+ // Ignore quotes within raw tag
+ // Fixes #283
+
+ if (tokenDef.type === Twig.token.type.raw) {
+ break;
}
l = Twig.token.strings.length;
for (i = 0; i < l; i += 1) {
- this_str_pos = template.indexOf(Twig.token.strings[i], offset);
+ thisStrPos = template.indexOf(Twig.token.strings[i], offset);
- if (this_str_pos > 0 && this_str_pos < pos &&
- (str_pos === null || this_str_pos < str_pos)) {
- str_pos = this_str_pos;
- str_found = Twig.token.strings[i];
+ if (thisStrPos > 0 && thisStrPos < pos &&
+ (strPos === null || thisStrPos < strPos)) {
+ strPos = thisStrPos;
+ strFound = Twig.token.strings[i];
}
}
// We found a string before the end of the token, now find the string's end and set the search offset to it
- if (str_pos !== null) {
- end_offset = str_pos + 1;
+ if (strPos !== null) {
+ endOffset = strPos + 1;
end = null;
found = false;
- while (true) {
- end_str_pos = template.indexOf(str_found, end_offset);
- if (end_str_pos < 0) {
- throw "Unclosed string in template";
+ for (;;) {
+ endStrPos = template.indexOf(strFound, endOffset);
+ if (endStrPos < 0) {
+ throw Twig.Error('Unclosed string in template');
}
// Ignore escaped quotes
- if (template.substr(end_str_pos - 1, 1) !== "\\") {
- offset = end_str_pos + 1;
- break;
+
+ if (template.slice(endStrPos - 1, endStrPos) === '\\') {
+ endOffset = endStrPos + 1;
} else {
- end_offset = end_str_pos + 1;
+ offset = endStrPos + 1;
+ break;
}
}
}
}
+
return end;
};
@@ -311,276 +324,346 @@ var Twig = (function (Twig) {
* Convert a template into high-level tokens.
*/
Twig.tokenize = function (template) {
- var tokens = [],
- // An offset for reporting errors locations in the template.
- error_offset = 0,
-
- // The start and type of the first token found in the template.
- found_token = null,
- // The end position of the matched token.
- end = null;
+ const tokens = [];
+ // An offset for reporting errors locations and the position of the nodes in the template.
+ let currentPosition = 0;
+ // The start and type of the first token found in the template.
+ let foundToken = null;
+ // The end position of the matched token.
+ let end = null;
while (template.length > 0) {
// Find the first occurance of any token type in the template
- found_token = Twig.token.findStart(template);
+ foundToken = Twig.token.findStart(template);
- Twig.log.trace("Twig.tokenize: ", "Found token: ", found_token);
+ Twig.log.trace('Twig.tokenize: ', 'Found token: ', foundToken);
- if (found_token.position !== null) {
+ if (foundToken.position === null) {
+ // No more tokens -> add the rest of the template as a raw-type token
+ tokens.push({
+ type: Twig.token.type.raw,
+ value: template,
+ position: {
+ start: currentPosition,
+ end: currentPosition + foundToken.position
+ }
+ });
+ template = '';
+ } else {
// Add a raw type token for anything before the start of the token
- if (found_token.position > 0) {
+ if (foundToken.position > 0) {
tokens.push({
type: Twig.token.type.raw,
- value: template.substring(0, found_token.position)
+ value: template.slice(0, Math.max(0, foundToken.position)),
+ position: {
+ start: currentPosition,
+ end: currentPosition + Math.max(0, foundToken.position)
+ }
});
}
- template = template.substr(found_token.position + found_token.def.open.length);
- error_offset += found_token.position + found_token.def.open.length;
+
+ template = template.slice(foundToken.position + foundToken.def.open.length);
+ currentPosition += foundToken.position + foundToken.def.open.length;
// Find the end of the token
- end = Twig.token.findEnd(template, found_token.def, error_offset);
+ end = Twig.token.findEnd(template, foundToken.def, currentPosition);
- Twig.log.trace("Twig.tokenize: ", "Token ends at ", end);
+ Twig.log.trace('Twig.tokenize: ', 'Token ends at ', end);
tokens.push({
- type: found_token.def.type,
- value: template.substring(0, end).trim()
+ type: foundToken.def.type,
+ value: template.slice(0, Math.max(0, end)).trim(),
+ position: {
+ start: currentPosition - foundToken.def.open.length,
+ end: currentPosition + end + foundToken.def.close.length
+ }
});
- if ( found_token.def.type === "logic" && template.substr( end + found_token.def.close.length, 1 ) === "\n" ) {
- // Newlines directly after logic tokens are ignored
- end += 1;
+ if (template.slice(end + foundToken.def.close.length, end + foundToken.def.close.length + 1) === '\n') {
+ switch (foundToken.def.type) {
+ case 'logic_whitespace_pre':
+ case 'logic_whitespace_post':
+ case 'logic_whitespace_both':
+ case 'logic':
+ // Newlines directly after logic tokens are ignored
+ end += 1;
+ break;
+ default:
+ break;
+ }
}
- template = template.substr(end + found_token.def.close.length);
+ template = template.slice(end + foundToken.def.close.length);
// Increment the position in the template
- error_offset += end + found_token.def.close.length;
-
- } else {
- // No more tokens -> add the rest of the template as a raw-type token
- tokens.push({
- type: Twig.token.type.raw,
- value: template
- });
- template = '';
+ currentPosition += end + foundToken.def.close.length;
}
}
return tokens;
};
-
Twig.compile = function (tokens) {
+ const self = this;
try {
-
// Output and intermediate stacks
- var output = [],
- stack = [],
- // The tokens between open and close tags
- intermediate_output = [],
-
- token = null,
- logic_token = null,
- unclosed_token = null,
- // Temporary previous token.
- prev_token = null,
- // The previous token's template
- prev_template = null,
- // The output token
- tok_output = null,
-
- // Logic Token values
- type = null,
- open = null,
- next = null;
+ const output = [];
+ const stack = [];
+ // The tokens between open and close tags
+ let intermediateOutput = [];
+
+ let token = null;
+ let logicToken = null;
+ let unclosedToken = null;
+ // Temporary previous token.
+ let prevToken = null;
+ // Temporary previous output.
+ let prevOutput = null;
+ // Temporary previous intermediate output.
+ let prevIntermediateOutput = null;
+ // The previous token's template
+ let prevTemplate = null;
+ // Token lookahead
+ let nextToken = null;
+ // The output token
+ let tokOutput = null;
+
+ // Logic Token values
+ let type = null;
+ let open = null;
+ let next = null;
+
+ const compileOutput = function (token) {
+ Twig.expression.compile.call(self, token);
+ if (stack.length > 0) {
+ intermediateOutput.push(token);
+ } else {
+ output.push(token);
+ }
+ };
+
+ const compileLogic = function (token) {
+ // Compile the logic token
+ logicToken = Twig.logic.compile.call(self, token);
+ logicToken.position = token.position;
+
+ type = logicToken.type;
+ open = Twig.logic.handler[type].open;
+ next = Twig.logic.handler[type].next;
+
+ Twig.log.trace('Twig.compile: ', 'Compiled logic token to ', logicToken,
+ ' next is: ', next, ' open is : ', open);
+
+ // Not a standalone token, check logic stack to see if this is expected
+ if (open !== undefined && !open) {
+ prevToken = stack.pop();
+ prevTemplate = Twig.logic.handler[prevToken.type];
+
+ if (!prevTemplate.next.includes(type)) {
+ throw new Error(type + ' not expected after a ' + prevToken.type);
+ }
+
+ prevToken.output = prevToken.output || [];
+
+ prevToken.output = prevToken.output.concat(intermediateOutput);
+ intermediateOutput = [];
+
+ tokOutput = {
+ type: Twig.token.type.logic,
+ token: prevToken,
+ position: {
+ open: prevToken.position,
+ close: token.position
+ }
+ };
+
+ if (stack.length > 0) {
+ intermediateOutput.push(tokOutput);
+ } else {
+ output.push(tokOutput);
+ }
+ }
+
+ // This token requires additional tokens to complete the logic structure.
+ if (next !== undefined && next.length > 0) {
+ Twig.log.trace('Twig.compile: ', 'Pushing ', logicToken, ' to logic stack.');
+
+ if (stack.length > 0) {
+ // Put any currently held output into the output list of the logic operator
+ // currently at the head of the stack before we push a new one on.
+ prevToken = stack.pop();
+ prevToken.output = prevToken.output || [];
+ prevToken.output = prevToken.output.concat(intermediateOutput);
+ stack.push(prevToken);
+ intermediateOutput = [];
+ }
+
+ // Push the new logic token onto the logic stack
+ stack.push(logicToken);
+ } else if (open !== undefined && open) {
+ tokOutput = {
+ type: Twig.token.type.logic,
+ token: logicToken,
+ position: logicToken.position
+ };
+ // Standalone token (like {% set ... %}
+ if (stack.length > 0) {
+ intermediateOutput.push(tokOutput);
+ } else {
+ output.push(tokOutput);
+ }
+ }
+ };
while (tokens.length > 0) {
token = tokens.shift();
- Twig.log.trace("Compiling token ", token);
+ prevOutput = output[output.length - 1];
+ prevIntermediateOutput = intermediateOutput[intermediateOutput.length - 1];
+ nextToken = tokens[0];
+ Twig.log.trace('Compiling token ', token);
switch (token.type) {
case Twig.token.type.raw:
if (stack.length > 0) {
- intermediate_output.push(token);
+ intermediateOutput.push(token);
} else {
output.push(token);
}
+
break;
case Twig.token.type.logic:
- // Compile the logic token
- logic_token = Twig.logic.compile.apply(this, [token]);
-
- type = logic_token.type;
- open = Twig.logic.handler[type].open;
- next = Twig.logic.handler[type].next;
+ compileLogic.call(self, token);
+ break;
- Twig.log.trace("Twig.compile: ", "Compiled logic token to ", logic_token,
- " next is: ", next, " open is : ", open);
+ // Do nothing, comments should be ignored
+ case Twig.token.type.comment:
+ break;
- // Not a standalone token, check logic stack to see if this is expected
- if (open !== undefined && !open) {
- prev_token = stack.pop();
- prev_template = Twig.logic.handler[prev_token.type];
+ case Twig.token.type.output:
+ compileOutput.call(self, token);
+ break;
- if (Twig.indexOf(prev_template.next, type) < 0) {
- throw new Error(type + " not expected after a " + prev_token.type);
+ // Kill whitespace ahead and behind this token
+ case Twig.token.type.logicWhitespacePre:
+ case Twig.token.type.logicWhitespacePost:
+ case Twig.token.type.logicWhitespaceBoth:
+ case Twig.token.type.outputWhitespacePre:
+ case Twig.token.type.outputWhitespacePost:
+ case Twig.token.type.outputWhitespaceBoth:
+ if (token.type !== Twig.token.type.outputWhitespacePost && token.type !== Twig.token.type.logicWhitespacePost) {
+ if (prevOutput) {
+ // If the previous output is raw, pop it off
+ if (prevOutput.type === Twig.token.type.raw) {
+ output.pop();
+
+ prevOutput.value = prevOutput.value.trimEnd();
+ // Repush the previous output
+ output.push(prevOutput);
+ }
}
- prev_token.output = prev_token.output || [];
+ if (prevIntermediateOutput) {
+ // If the previous intermediate output is raw, pop it off
+ if (prevIntermediateOutput.type === Twig.token.type.raw) {
+ intermediateOutput.pop();
- prev_token.output = prev_token.output.concat(intermediate_output);
- intermediate_output = [];
-
- tok_output = {
- type: Twig.token.type.logic,
- token: prev_token
- };
- if (stack.length > 0) {
- intermediate_output.push(tok_output);
- } else {
- output.push(tok_output);
+ prevIntermediateOutput.value = prevIntermediateOutput.value.trimEnd();
+ // Repush the previous intermediate output
+ intermediateOutput.push(prevIntermediateOutput);
+ }
}
}
- // This token requires additional tokens to complete the logic structure.
- if (next !== undefined && next.length > 0) {
- Twig.log.trace("Twig.compile: ", "Pushing ", logic_token, " to logic stack.");
-
- if (stack.length > 0) {
- // Put any currently held output into the output list of the logic operator
- // currently at the head of the stack before we push a new one on.
- prev_token = stack.pop();
- prev_token.output = prev_token.output || [];
- prev_token.output = prev_token.output.concat(intermediate_output);
- stack.push(prev_token);
- intermediate_output = [];
- }
+ // Compile this token
+ switch (token.type) {
+ case Twig.token.type.outputWhitespacePre:
+ case Twig.token.type.outputWhitespacePost:
+ case Twig.token.type.outputWhitespaceBoth:
+ compileOutput.call(self, token);
+ break;
+ case Twig.token.type.logicWhitespacePre:
+ case Twig.token.type.logicWhitespacePost:
+ case Twig.token.type.logicWhitespaceBoth:
+ compileLogic.call(self, token);
+ break;
+ default:
+ break;
+ }
- // Push the new logic token onto the logic stack
- stack.push(logic_token);
-
- } else if (open !== undefined && open) {
- tok_output = {
- type: Twig.token.type.logic,
- token: logic_token
- };
- // Standalone token (like {% set ... %}
- if (stack.length > 0) {
- intermediate_output.push(tok_output);
- } else {
- output.push(tok_output);
+ if (token.type !== Twig.token.type.outputWhitespacePre && token.type !== Twig.token.type.logicWhitespacePre) {
+ if (nextToken) {
+ // If the next token is raw, shift it out
+ if (nextToken.type === Twig.token.type.raw) {
+ tokens.shift();
+
+ nextToken.value = nextToken.value.trimStart();
+ // Unshift the next token
+ tokens.unshift(nextToken);
+ }
}
}
- break;
- // Do nothing, comments should be ignored
- case Twig.token.type.comment:
break;
-
- case Twig.token.type.output:
- Twig.expression.compile.apply(this, [token]);
- if (stack.length > 0) {
- intermediate_output.push(token);
- } else {
- output.push(token);
- }
+ default:
break;
}
- Twig.log.trace("Twig.compile: ", " Output: ", output,
- " Logic Stack: ", stack,
- " Pending Output: ", intermediate_output );
+ Twig.log.trace('Twig.compile: ', ' Output: ', output,
+ ' Logic Stack: ', stack,
+ ' Pending Output: ', intermediateOutput
+ );
}
// Verify that there are no logic tokens left in the stack.
if (stack.length > 0) {
- unclosed_token = stack.pop();
- throw new Error("Unable to find an end tag for " + unclosed_token.type +
- ", expecting one of " + unclosed_token.next);
+ unclosedToken = stack.pop();
+ throw new Error('Unable to find an end tag for ' + unclosedToken.type +
+ ', expecting one of ' + unclosedToken.next);
}
+
return output;
- } catch (ex) {
- Twig.log.error("Error compiling twig template " + this.id + ": ");
- if (ex.stack) {
- Twig.log.error(ex.stack);
+ } catch (error) {
+ if (self.options.rethrow) {
+ if (error.type === 'TwigException' && !error.file) {
+ error.file = self.id;
+ }
+
+ throw error;
} else {
- Twig.log.error(ex.toString());
+ Twig.log.error('Error compiling twig template ' + self.id + ': ');
+ if (error.stack) {
+ Twig.log.error(error.stack);
+ } else {
+ Twig.log.error(error.toString());
+ }
}
-
- if (this.options.rethrow) throw ex;
}
};
- /**
- * Parse a compiled template.
- *
- * @param {Array} tokens The compiled tokens.
- * @param {Object} context The render context.
- *
- * @return {string} The parsed template.
- */
- Twig.parse = function (tokens, context) {
- try {
- var output = [],
- // Track logic chains
- chain = true,
- that = this;
-
- // Default to an empty object if none provided
- context = context || { };
-
-
- Twig.forEach(tokens, function parseToken(token) {
- Twig.log.debug("Twig.parse: ", "Parsing token: ", token);
-
- switch (token.type) {
- case Twig.token.type.raw:
- output.push(token.value);
- break;
-
- case Twig.token.type.logic:
- var logic_token = token.token,
- logic = Twig.logic.parse.apply(that, [logic_token, context, chain]);
-
- if (logic.chain !== undefined) {
- chain = logic.chain;
- }
- if (logic.context !== undefined) {
- context = logic.context;
- }
- if (logic.output !== undefined) {
- output.push(logic.output);
- }
- break;
+ function handleException(state, ex) {
+ if (state.template.options.rethrow) {
+ if (typeof ex === 'string') {
+ ex = new Twig.Error(ex);
+ }
- case Twig.token.type.comment:
- // Do nothing, comments should be ignored
- break;
+ if (ex.type === 'TwigException' && !ex.file) {
+ ex.file = state.template.id;
+ }
- case Twig.token.type.output:
- Twig.log.debug("Twig.parse: ", "Output token: ", token.stack);
- // Parse the given expression in the given context
- output.push(Twig.expression.parse.apply(that, [token.stack, context]));
- break;
- }
- });
- return output.join("");
- } catch (ex) {
- Twig.log.error("Error parsing twig template " + this.id + ": ");
+ throw ex;
+ } else {
+ Twig.log.error('Error parsing twig template ' + state.template.id + ': ');
if (ex.stack) {
Twig.log.error(ex.stack);
} else {
Twig.log.error(ex.toString());
}
- if (this.options.rethrow) throw ex;
-
if (Twig.debug) {
return ex.toString();
}
}
- };
+ }
/**
* Tokenize and compile a string template.
@@ -589,24 +672,78 @@ var Twig = (function (Twig) {
*
* @return {Array} The compiled tokens.
*/
- Twig.prepare = function(data) {
- var tokens, raw_tokens;
-
+ Twig.prepare = function (data) {
// Tokenize
- Twig.log.debug("Twig.prepare: ", "Tokenizing ", data);
- raw_tokens = Twig.tokenize.apply(this, [data]);
+ Twig.log.debug('Twig.prepare: ', 'Tokenizing ', data);
+ const rawTokens = Twig.tokenize.call(this, data);
// Compile
- Twig.log.debug("Twig.prepare: ", "Compiling ", raw_tokens);
- tokens = Twig.compile.apply(this, [raw_tokens]);
+ Twig.log.debug('Twig.prepare: ', 'Compiling ', rawTokens);
+ const tokens = Twig.compile.call(this, rawTokens);
- Twig.log.debug("Twig.prepare: ", "Compiled ", tokens);
+ Twig.log.debug('Twig.prepare: ', 'Compiled ', tokens);
return tokens;
};
+ /**
+ * Join the output token's stack and escape it if needed
+ *
+ * @param {Array} Output token's stack
+ *
+ * @return {string|String} Autoescaped output
+ */
+ Twig.output = function (output) {
+ const {autoescape} = this.options;
+
+ if (!autoescape) {
+ return output.join('');
+ }
+
+ const strategy = (typeof autoescape === 'string') ? autoescape : 'html';
+
+ const escapedOutput = output.map(str => {
+ if (
+ str &&
+ (str.twigMarkup !== true && str.twigMarkup !== strategy) &&
+ !(strategy === 'html' && str.twigMarkup === 'html_attr')
+ ) {
+ str = Twig.filters.escape(str, [strategy]);
+ }
+
+ return str;
+ });
+
+ if (escapedOutput.length === 0) {
+ return '';
+ }
+
+ const joinedOutput = escapedOutput.join('');
+ if (joinedOutput.length === 0) {
+ return '';
+ }
+
+ return new Twig.Markup(joinedOutput, true);
+ };
+
// Namespace for template storage and retrieval
Twig.Templates = {
+ /**
+ * Registered template loaders - use Twig.Templates.registerLoader to add supported loaders
+ * @type {Object}
+ */
+ loaders: {},
+
+ /**
+ * Registered template parsers - use Twig.Templates.registerParser to add supported parsers
+ * @type {Object}
+ */
+ parsers: {},
+
+ /**
+ * Cached / loaded templates
+ * @type {Object}
+ */
registry: {}
};
@@ -618,24 +755,147 @@ var Twig = (function (Twig) {
* @throws {Twig.Error} If the ID is invalid or used.
* @return {boolean} True if the ID is valid.
*/
- Twig.validateId = function(id) {
- if (id === "prototype") {
- throw new Twig.Error(id + " is not a valid twig identifier");
- } else if (Twig.Templates.registry.hasOwnProperty(id)) {
- throw new Twig.Error("There is already a template with the ID " + id);
+ Twig.validateId = function (id) {
+ if (id === 'prototype') {
+ throw new Twig.Error(id + ' is not a valid twig identifier');
+ } else if (Twig.cache && Object.hasOwnProperty.call(Twig.Templates.registry, id)) {
+ throw new Twig.Error('There is already a template with the ID ' + id);
}
+
return true;
- }
+ };
+
+ /**
+ * Register a template loader
+ *
+ * @example
+ * Twig.extend(function (Twig) {
+ * Twig.Templates.registerLoader('custom_loader', function (location, params, callback, errorCallback) {
+ * // ... load the template ...
+ * params.data = loadedTemplateData;
+ * // create and return the template
+ * var template = new Twig.Template(params);
+ * if (typeof callback === 'function') {
+ * callback(template);
+ * }
+ * return template;
+ * });
+ * });
+ *
+ * @param {String} methodName The method this loader is intended for (ajax, fs)
+ * @param {Function} func The function to execute when loading the template
+ * @param {Object|undefined} scope Optional scope parameter to bind func to
+ *
+ * @throws Twig.Error
+ *
+ * @return {void}
+ */
+ Twig.Templates.registerLoader = function (methodName, func, scope) {
+ if (typeof func !== 'function') {
+ throw new Twig.Error('Unable to add loader for ' + methodName + ': Invalid function reference given.');
+ }
+
+ if (scope) {
+ func = func.bind(scope);
+ }
+
+ this.loaders[methodName] = func;
+ };
+
+ /**
+ * Remove a registered loader
+ *
+ * @param {String} methodName The method name for the loader you wish to remove
+ *
+ * @return {void}
+ */
+ Twig.Templates.unRegisterLoader = function (methodName) {
+ if (this.isRegisteredLoader(methodName)) {
+ delete this.loaders[methodName];
+ }
+ };
+
+ /**
+ * See if a loader is registered by its method name
+ *
+ * @param {String} methodName The name of the loader you are looking for
+ *
+ * @return {boolean}
+ */
+ Twig.Templates.isRegisteredLoader = function (methodName) {
+ return Object.hasOwnProperty.call(this.loaders, methodName);
+ };
+
+ /**
+ * Register a template parser
+ *
+ * @example
+ * Twig.extend(function (Twig) {
+ * Twig.Templates.registerParser('custom_parser', function (params) {
+ * // this template source can be accessed in params.data
+ * var template = params.data
+ *
+ * // ... custom process that modifies the template
+ *
+ * // return the parsed template
+ * return template;
+ * });
+ * });
+ *
+ * @param {String} methodName The method this parser is intended for (twig, source)
+ * @param {Function} func The function to execute when parsing the template
+ * @param {Object|undefined} scope Optional scope parameter to bind func to
+ *
+ * @throws Twig.Error
+ *
+ * @return {void}
+ */
+ Twig.Templates.registerParser = function (methodName, func, scope) {
+ if (typeof func !== 'function') {
+ throw new Twig.Error('Unable to add parser for ' + methodName + ': Invalid function regerence given.');
+ }
+
+ if (scope) {
+ func = func.bind(scope);
+ }
+
+ this.parsers[methodName] = func;
+ };
+
+ /**
+ * Remove a registered parser
+ *
+ * @param {String} methodName The method name for the parser you wish to remove
+ *
+ * @return {void}
+ */
+ Twig.Templates.unRegisterParser = function (methodName) {
+ if (this.isRegisteredParser(methodName)) {
+ delete this.parsers[methodName];
+ }
+ };
+
+ /**
+ * See if a parser is registered by its method name
+ *
+ * @param {String} methodName The name of the parser you are looking for
+ *
+ * @return {boolean}
+ */
+ Twig.Templates.isRegisteredParser = function (methodName) {
+ return Object.hasOwnProperty.call(this.parsers, methodName);
+ };
/**
* Save a template object to the store.
*
* @param {Twig.Template} template The twig.js template to store.
*/
- Twig.Templates.save = function(template) {
+ Twig.Templates.save = function (template) {
if (template.id === undefined) {
- throw new Twig.Error("Unable to save template with no id");
+ throw new Twig.Error('Unable to save template with no id');
}
+
Twig.Templates.registry[template.id] = template;
};
@@ -646,10 +906,11 @@ var Twig = (function (Twig) {
*
* @return {Twig.Template} A twig.js template stored with the provided ID.
*/
- Twig.Templates.load = function(id) {
- if (!Twig.Templates.registry.hasOwnProperty(id)) {
+ Twig.Templates.load = function (id) {
+ if (!Object.hasOwnProperty.call(Twig.Templates.registry, id)) {
return null;
}
+
return Twig.Templates.registry[id];
};
@@ -662,136 +923,311 @@ var Twig = (function (Twig) {
* Defaults to true.
* method: What method should be used to load the template
* (fs or ajax)
+ * parser: What method should be used to parse the template
+ * (twig or source)
* precompiled: Has the template already been compiled.
*
* @param {string} location The remote URL to load as a template.
* @param {Object} params The template parameters.
* @param {function} callback A callback triggered when the template finishes loading.
- * @param {function} error_callback A callback triggered if an error occurs loading the template.
+ * @param {function} errorCallback A callback triggered if an error occurs loading the template.
*
*
*/
- Twig.Templates.loadRemote = function(location, params, callback, error_callback) {
- var id = params.id,
- method = params.method,
- async = params.async,
- precompiled = params.precompiled,
- template = null;
-
- // Default to async
- if (async === undefined) async = true;
-
+ Twig.Templates.loadRemote = function (location, params, callback, errorCallback) {
// Default to the URL so the template is cached.
- if (id === undefined) {
- id = location;
- }
- params.id = id;
+ const id = typeof params.id === 'undefined' ? location : params.id;
+ const cached = Twig.Templates.registry[id];
// Check for existing template
- if (Twig.cache && Twig.Templates.registry.hasOwnProperty(id)) {
+ if (Twig.cache && typeof cached !== 'undefined') {
// A template is already saved with the given id.
- if (callback) {
- callback(Twig.Templates.registry[id]);
+ if (typeof callback === 'function') {
+ callback(cached);
}
- return Twig.Templates.registry[id];
+ // TODO: if async, return deferred promise
+
+ return cached;
}
- if (method == 'ajax') {
- if (typeof XMLHttpRequest == "undefined") {
- throw new Twig.Error("Unsupported platform: Unable to do remote requests " +
- "because there is no XMLHTTPRequest implementation");
- }
+ // If the parser name hasn't been set, default it to twig
+ params.parser = params.parser || 'twig';
+ params.id = id;
- var xmlhttp = new XMLHttpRequest();
- xmlhttp.onreadystatechange = function() {
- var data = null;
+ // Default to async
+ if (typeof params.async === 'undefined') {
+ params.async = true;
+ }
- if(xmlhttp.readyState == 4) {
- if (xmlhttp.status == 200) {
- Twig.log.debug("Got template ", xmlhttp.responseText);
+ // Assume 'fs' if the loader is not defined
+ const loader = this.loaders[params.method] || this.loaders.fs;
+ return loader.call(this, location, params, callback, errorCallback);
+ };
- if (precompiled === true) {
- data = JSON.parse(xmlhttp.responseText);
- } else {
- data = xmlhttp.responseText;
- }
+ // Determine object type
+ function is(type, obj) {
+ const clas = Object.prototype.toString.call(obj).slice(8, -1);
+ return obj !== undefined && obj !== null && clas === type;
+ }
- params.url = location;
- params.data = data;
+ /**
+ * A wrapper for template blocks.
+ *
+ * @param {Twig.Template} The template that the block was originally defined in.
+ * @param {Object} The compiled block token.
+ */
+ Twig.Block = function (template, token) {
+ this.template = template;
+ this.token = token;
+ };
- template = new Twig.Template(params);
+ /**
+ * Render the block using a specific parse state and context.
+ *
+ * @param {Twig.ParseState} parseState
+ * @param {Object} context
+ *
+ * @return {Promise}
+ */
+ Twig.Block.prototype.render = function (parseState, context) {
+ const originalTemplate = parseState.template;
+ let promise;
- if (callback) {
- callback(template);
- }
- } else {
- if (error_callback) {
- error_callback(xmlhttp);
- }
- }
- }
- };
- xmlhttp.open("GET", location, async);
- xmlhttp.send();
-
- } else { // if method = 'fs'
- // Create local scope
- (function() {
- var fs = require('fs'),
- path = require('path'),
- data = null,
- loadTemplateFn = function(err, data) {
- if (err) {
- if (error_callback) {
- error_callback(err);
- }
- return;
- }
+ parseState.template = this.template;
- if (precompiled === true) {
- data = JSON.parse(data);
- }
+ if (this.token.expression) {
+ promise = Twig.expression.parseAsync.call(parseState, this.token.output, context);
+ } else {
+ promise = parseState.parseAsync(this.token.output, context);
+ }
- params.data = data;
- params.path = location;
+ return promise
+ .then(value => {
+ return Twig.expression.parseAsync.call(
+ parseState,
+ {
+ type: Twig.expression.type.string,
+ value
+ },
+ context
+ );
+ })
+ .then(output => {
+ parseState.template = originalTemplate;
+
+ return output;
+ });
+ };
- // template is in data
- template = new Twig.Template(params);
+ /**
+ * Holds the state needed to parse a template.
+ *
+ * @param {Twig.Template} template The template that the tokens being parsed are associated with.
+ * @param {Object} blockOverrides Any blocks that should override those defined in the associated template.
+ */
+ Twig.ParseState = function (template, blockOverrides, context) {
+ this.renderedBlocks = {};
+ this.overrideBlocks = blockOverrides === undefined ? {} : blockOverrides;
+ this.context = context === undefined ? {} : context;
+ this.macros = {};
+ this.nestingStack = [];
+ this.template = template;
+ };
- if (callback) {
- callback(template);
- }
- };
+ /**
+ * Get a block by its name, resolving in the following order:
+ * - override blocks specified when initialized (except when excluded)
+ * - blocks resolved from the associated template
+ * - blocks resolved from the parent template when extending
+ *
+ * @param {String} name The name of the block to return.
+ * @param {Boolean} checkOnlyInheritedBlocks Whether to skip checking the overrides and associated template, will not skip by default.
+ *
+ * @return {Twig.Block|undefined}
+ */
+ Twig.ParseState.prototype.getBlock = function (name, checkOnlyInheritedBlocks) {
+ let block;
- if (async === true) {
- fs.stat(location, function (err, stats) {
- if (err || !stats.isFile())
- throw new Twig.Error("Unable to find template file " + location);
+ if (checkOnlyInheritedBlocks !== true) {
+ // Blocks specified when initialized
+ block = this.overrideBlocks[name];
+ }
- fs.readFile(location, 'utf8', loadTemplateFn);
- });
- } else {
- if (!fs.statSync(location).isFile())
- throw new Twig.Error("Unable to find template file " + location);
+ if (block === undefined) {
+ // Block defined by the associated template
+ block = this.template.getBlock(name, checkOnlyInheritedBlocks);
+ }
- data = fs.readFileSync(location, 'utf8');
- loadTemplateFn(undefined, data);
- }
- })();
+ if (block === undefined && this.template.parentTemplate !== null) {
+ // Block defined in the parent template when extending
+ block = this.template.parentTemplate.getBlock(name);
}
- if (async === false) {
- return template;
- } else {
- // placeholder for now, should eventually return a deferred object.
- return true;
+
+ return block;
+ };
+
+ /**
+ * Get all the available blocks, resolving in the following order:
+ * - override blocks specified when initialized
+ * - blocks resolved from the associated template
+ * - blocks resolved from the parent template when extending (except when excluded)
+ *
+ * @param {Boolean} includeParentBlocks Whether to get blocks from the parent template when extending, will always do so by default.
+ *
+ * @return {Object}
+ */
+ Twig.ParseState.prototype.getBlocks = function (includeParentBlocks) {
+ let blocks = {};
+
+ if (includeParentBlocks !== false &&
+ this.template.parentTemplate !== null &&
+ // Prevent infinite loop
+ this.template.parentTemplate !== this.template
+ ) {
+ // Blocks from the parent template when extending
+ blocks = this.template.parentTemplate.getBlocks();
}
+
+ blocks = {
+ ...blocks,
+ // Override with any blocks defined within the associated template
+ ...this.template.getBlocks(),
+ // Override with any blocks specified when initialized
+ ...this.overrideBlocks
+ };
+
+ return blocks;
};
- // Determine object type
- function is(type, obj) {
- var clas = Object.prototype.toString.call(obj).slice(8, -1);
- return obj !== undefined && obj !== null && clas === type;
- }
+ /**
+ * Get the closest token of a specific type to the current nest level.
+ *
+ * @param {String} type The logic token type
+ *
+ * @return {Object}
+ */
+ Twig.ParseState.prototype.getNestingStackToken = function (type) {
+ let matchingToken;
+
+ this.nestingStack.forEach(token => {
+ if (matchingToken === undefined && token.type === type) {
+ matchingToken = token;
+ }
+ });
+
+ return matchingToken;
+ };
+
+ /**
+ * Parse a set of tokens using the current state.
+ *
+ * @param {Array} tokens The compiled tokens.
+ * @param {Object} context The context to set the state to while parsing.
+ * @param {Boolean} allowAsync Whether to parse asynchronously.
+ * @param {Object} blocks Blocks that should override any defined while parsing.
+ *
+ * @return {String} The rendered tokens.
+ *
+ */
+ Twig.ParseState.prototype.parse = function (tokens, context, allowAsync) {
+ const state = this;
+ let output = [];
+
+ // Store any error that might be thrown by the promise chain.
+ let err = null;
+
+ // This will be set to isAsync if template renders synchronously
+ let isAsync = true;
+ let promise = null;
+ // Track logic chains
+ let chain = true;
+
+ if (context) {
+ state.context = context;
+ }
+
+ /*
+ * Extracted into it's own function such that the function
+ * does not get recreated over and over again in the `forEach`
+ * loop below. This method can be compiled and optimized
+ * a single time instead of being recreated on each iteration.
+ */
+ function outputPush(o) {
+ output.push(o);
+ }
+
+ function parseTokenLogic(logic) {
+ if (typeof logic.chain !== 'undefined') {
+ chain = logic.chain;
+ }
+
+ if (typeof logic.context !== 'undefined') {
+ state.context = logic.context;
+ }
+
+ if (typeof logic.output !== 'undefined') {
+ output.push(logic.output);
+ }
+ }
+
+ promise = Twig.async.forEach(tokens, token => {
+ Twig.log.debug('Twig.ParseState.parse: ', 'Parsing token: ', token);
+
+ switch (token.type) {
+ case Twig.token.type.raw:
+ output.push(Twig.filters.raw(token.value));
+ break;
+
+ case Twig.token.type.logic:
+ return Twig.logic.parseAsync.call(state, token.token /* logicToken */, state.context, chain)
+ .then(parseTokenLogic);
+ case Twig.token.type.comment:
+ // Do nothing, comments should be ignored
+ break;
+
+ // Fall through whitespace to output
+ case Twig.token.type.outputWhitespacePre:
+ case Twig.token.type.outputWhitespacePost:
+ case Twig.token.type.outputWhitespaceBoth:
+ case Twig.token.type.output:
+ Twig.log.debug('Twig.ParseState.parse: ', 'Output token: ', token.stack);
+ // Parse the given expression in the given context
+ return Twig.expression.parseAsync.call(state, token.stack, state.context)
+ .then(outputPush);
+ default:
+ break;
+ }
+ }).then(() => {
+ output = Twig.output.call(state.template, output);
+ isAsync = false;
+ return output;
+ }).catch(error => {
+ if (allowAsync) {
+ handleException(state, error);
+ }
+
+ err = error;
+ });
+
+ // If `allowAsync` we will always return a promise since we do not
+ // know in advance if we are going to run asynchronously or not.
+ if (allowAsync) {
+ return promise;
+ }
+
+ // Handle errors here if we fail synchronously.
+ if (err !== null) {
+ return handleException(state, err);
+ }
+
+ // If `allowAsync` is not true we should not allow the user
+ // to use asynchronous functions or filters.
+ if (isAsync) {
+ throw new Twig.Error('You are using Twig.js in sync mode in combination with async extensions.');
+ }
+
+ return output;
+ };
/**
* Create a new twig.js template.
@@ -799,21 +1235,12 @@ var Twig = (function (Twig) {
* Parameters: {
* data: The template, either pre-compiled tokens or a string template
* id: The name of this template
- * blocks: Any pre-existing block from a child template
* }
*
* @param {Object} params The template parameters.
*/
- Twig.Template = function ( params ) {
- var data = params.data,
- id = params.id,
- blocks = params.blocks,
- macros = params.macros || {},
- base = params.base,
- path = params.path,
- url = params.url,
- // parser options
- options = params.options;
+ Twig.Template = function (params) {
+ const {data, id, base, path, url, name, method, options} = params;
// # What is stored in a Twig.Template
//
@@ -822,7 +1249,6 @@ var Twig = (function (Twig) {
// {
// id: The token ID (if any)
// tokens: The list of tokens that makes up this template.
- // blocks: The list of block this template contains.
// base: The base template (if any)
// options: {
// Compiler/parser options
@@ -833,17 +1259,21 @@ var Twig = (function (Twig) {
// }
//
- this.id = id;
- this.base = base;
- this.path = path;
- this.url = url;
- this.macros = macros;
+ this.base = base;
+ this.blocks = {
+ defined: {},
+ imported: {}
+ };
+ this.id = id;
+ this.method = method;
+ this.name = name;
this.options = options;
-
- this.reset(blocks);
+ this.parentTemplate = null;
+ this.path = path;
+ this.url = url;
if (is('String', data)) {
- this.tokens = Twig.prepare.apply(this, [data]);
+ this.tokens = Twig.prepare.call(this, data);
} else {
this.tokens = data;
}
@@ -853,199 +1283,195 @@ var Twig = (function (Twig) {
}
};
- Twig.Template.prototype.reset = function(blocks) {
- Twig.log.debug("Twig.Template.reset", "Reseting template " + this.id);
- this.blocks = {};
- this.child = {
- blocks: blocks || {}
+ /**
+ * Get a block by its name, resolving in the following order:
+ * - blocks defined in the template itself
+ * - blocks imported from another template
+ *
+ * @param {String} name The name of the block to return.
+ * @param {Boolean} checkOnlyInheritedBlocks Whether to skip checking the blocks defined in the template itself, will not skip by default.
+ *
+ * @return {Twig.Block|undefined}
+ */
+ Twig.Template.prototype.getBlock = function (name, checkOnlyInheritedBlocks, checkImports = true) {
+ let block;
+
+ if (checkOnlyInheritedBlocks !== true) {
+ block = this.blocks.defined[name];
+ }
+
+ if (checkImports && block === undefined) {
+ block = this.blocks.imported[name];
+ }
+
+ if (block === undefined && this.parentTemplate !== null) {
+ /**
+ * Block defined in the parent template when extending.
+ * This recursion is useful to inherit from ascendants.
+ * But take care of not considering ascendants' {% use %}
+ */
+ block = this.parentTemplate.getBlock(name, checkOnlyInheritedBlocks, checkImports = false);
+ }
+
+ return block;
+ };
+
+ /**
+ * Get all the available blocks, resolving in the following order:
+ * - blocks defined in the template itself
+ * - blocks imported from other templates
+ *
+ * @return {Object}
+ */
+ Twig.Template.prototype.getBlocks = function () {
+ let blocks = {};
+
+ blocks = {
+ ...blocks,
+ // Get any blocks imported from other templates
+ ...this.blocks.imported,
+ // Override with any blocks defined within the template itself
+ ...this.blocks.defined
};
- this.extend = null;
+
+ return blocks;
};
- Twig.Template.prototype.render = function (context, params) {
+ Twig.Template.prototype.render = function (context, params, allowAsync) {
+ const template = this;
+
params = params || {};
- var output,
- url;
+ return Twig.async.potentiallyAsync(template, allowAsync, () => {
+ const state = new Twig.ParseState(template, params.blocks, context);
- this.context = context || {};
+ return state.parseAsync(template.tokens)
+ .then(output => {
+ let parentTemplate;
+ let url;
- // Clear any previous state
- this.reset();
- if (params.blocks) {
- this.blocks = params.blocks;
- }
- if (params.macros) {
- this.macros = params.macros;
- }
-
- output = Twig.parse.apply(this, [this.tokens, this.context]);
+ if (template.parentTemplate !== null) {
+ // This template extends another template
- // Does this template extend another
- if (this.extend) {
- var ext_template;
+ if (template.options.allowInlineIncludes) {
+ // The template is provided inline
+ parentTemplate = Twig.Templates.load(template.parentTemplate);
- // check if the template is provided inline
- if ( this.options.allowInlineIncludes ) {
- ext_template = Twig.Templates.load(this.extend);
- if ( ext_template ) {
- ext_template.options = this.options;
- }
- }
+ if (parentTemplate) {
+ parentTemplate.options = template.options;
+ }
+ }
- // check for the template file via include
- if (!ext_template) {
- url = relativePath(this, this.extend);
+ // Check for the template file via include
+ if (!parentTemplate) {
+ url = Twig.path.parsePath(template, template.parentTemplate);
+
+ parentTemplate = Twig.Templates.loadRemote(url, {
+ method: template.getLoaderMethod(),
+ base: template.base,
+ async: false,
+ id: url,
+ options: template.options
+ });
+ }
- ext_template = Twig.Templates.loadRemote(url, {
- method: this.url?'ajax':'fs',
- base: this.base,
- async: false,
- id: url,
- options: this.options
- });
- }
+ template.parentTemplate = parentTemplate;
- this.parent = ext_template;
+ return template.parentTemplate.renderAsync(
+ state.context,
+ {
+ blocks: state.getBlocks(false),
+ isInclude: true
+ }
+ );
+ }
- return this.parent.render(this.context, {
- blocks: this.blocks
- });
- }
+ if (params.isInclude === true) {
+ return output;
+ }
- if (params.output == 'blocks') {
- return this.blocks;
- } else if (params.output == 'macros') {
- return this.macros;
- } else {
- return output;
- }
+ return output.valueOf();
+ });
+ });
};
- Twig.Template.prototype.importFile = function(file) {
- var url, sub_template;
- if ( !this.url && !this.path && this.options.allowInlineIncludes ) {
- sub_template = Twig.Templates.load(file);
- sub_template.options = this.options;
- if ( sub_template ) {
- return sub_template;
+ Twig.Template.prototype.importFile = function (file) {
+ let url = null;
+ let subTemplate;
+ if (!this.url && this.options.allowInlineIncludes) {
+ file = this.path ? Twig.path.parsePath(this, file) : file;
+ subTemplate = Twig.Templates.load(file);
+
+ if (!subTemplate) {
+ subTemplate = Twig.Templates.loadRemote(url, {
+ id: file,
+ method: this.getLoaderMethod(),
+ async: false,
+ path: file,
+ options: this.options
+ });
+
+ if (!subTemplate) {
+ throw new Twig.Error('Unable to find the template ' + file);
+ }
}
- throw new Twig.Error("Didn't find the inline template by id");
+ subTemplate.options = this.options;
+
+ return subTemplate;
}
- url = relativePath(this, file);
+ url = Twig.path.parsePath(this, file);
// Load blocks from an external file
- sub_template = Twig.Templates.loadRemote(url, {
- method: this.url?'ajax':'fs',
+ subTemplate = Twig.Templates.loadRemote(url, {
+ method: this.getLoaderMethod(),
base: this.base,
async: false,
options: this.options,
id: url
});
- return sub_template;
- };
-
- Twig.Template.prototype.importBlocks = function(file, override) {
- var sub_template = this.importFile(file),
- context = this.context,
- that = this,
- key;
-
- override = override || false;
-
- sub_template.render(context);
-
- // Mixin blocks
- Twig.forEach(Object.keys(sub_template.blocks), function(key) {
- if (override || that.blocks[key] === undefined) {
- that.blocks[key] = sub_template.blocks[key];
- }
- });
+ return subTemplate;
};
- Twig.Template.prototype.importMacros = function(file) {
- var url = relativePath(this, file);
+ Twig.Template.prototype.getLoaderMethod = function () {
+ if (this.path) {
+ return 'fs';
+ }
- // load remote template
- var remoteTemplate = Twig.Templates.loadRemote(url, {
- method: this.url?'ajax':'fs',
- async: false,
- id: url
- });
+ if (this.url) {
+ return 'ajax';
+ }
- return remoteTemplate;
+ return this.method || 'fs';
};
- Twig.Template.prototype.compile = function(options) {
- // compile the template into raw JS
+ Twig.Template.prototype.compile = function (options) {
+ // Compile the template into raw JS
return Twig.compiler.compile(this, options);
};
/**
- * Generate the relative canonical version of a url based on the given base path and file path.
+ * Create safe output
*
- * @param {string} template The Twig.Template.
- * @param {string} file The file path, relative to the base path.
+ * @param {string} Content safe to output
*
- * @return {string} The canonical version of the path.
+ * @return {String} Content wrapped into a String
*/
- function relativePath(template, file) {
- var base,
- base_path,
- sep_chr = "/",
- new_path = [],
- val;
-
- if (template.url) {
- if (typeof template.base !== 'undefined') {
- base = template.base + ((template.base.charAt(template.base.length-1) === '/') ? '' : '/');
- } else {
- base = template.url;
- }
- } else if (template.path) {
- // Get the system-specific path separator
- var path = require("path"),
- sep = path.sep || sep_chr,
- relative = new RegExp("^\\.{1,2}" + sep.replace("\\", "\\\\"));
- file = file.replace(/\//g, sep);
-
- if (template.base !== undefined && file.match(relative) == null) {
- file = file.replace(template.base, '');
- base = template.base + sep;
- } else {
- base = template.path;
- }
- base = base.replace(sep+sep, sep);
- sep_chr = sep;
- } else {
- throw new Twig.Error("Cannot extend an inline template.");
+ Twig.Markup = function (content, strategy) {
+ if (typeof content !== 'string') {
+ return content;
}
- base_path = base.split(sep_chr);
-
- // Remove file from url
- base_path.pop();
- base_path = base_path.concat(file.split(sep_chr));
-
- while (base_path.length > 0) {
- val = base_path.shift();
- if (val == ".") {
- // Ignore
- } else if (val == ".." && new_path.length > 0 && new_path[new_path.length-1] != "..") {
- new_path.pop();
- } else {
- new_path.push(val);
- }
- }
+ /* eslint-disable no-new-wrappers, unicorn/new-for-builtins */
+ const output = new String(content);
+ /* eslint-enable */
+ output.twigMarkup = (typeof strategy === 'undefined') ? true : strategy;
- return new_path.join(sep_chr);
- }
+ return output;
+ };
return Twig;
-
-}) (Twig || { });
-
+};
diff --git a/src/twig.exports.js b/src/twig.exports.js
index 1392f612..e95b33b6 100644
--- a/src/twig.exports.js
+++ b/src/twig.exports.js
@@ -1,14 +1,9 @@
-// Twig.js
-// Copyright (c) 2011-2013 John Roepke
-// Available under the BSD 2-Clause License
-// https://github.com/justjohn/twig.js
-
// ## twig.exports.js
//
// This file provides extension points and other hooks into the twig functionality.
-var Twig = (function (Twig) {
- "use strict";
+module.exports = function (Twig) {
+ 'use strict';
Twig.exports = {
VERSION: Twig.VERSION
};
@@ -20,93 +15,120 @@ var Twig = (function (Twig) {
*
* @return {Twig.Template} A Twig template ready for rendering.
*/
- Twig.exports.twig = function twig(params) {
+ Twig.exports.twig = function (params) {
'use strict';
- var id = params.id,
- options = {
- strict_variables: params.strict_variables || false,
- allowInlineIncludes: params.allowInlineIncludes || false,
- rethrow: params.rethrow || false
- };
-
- if (id) {
+ const {id} = params;
+ const options = {
+ strictVariables: params.strict_variables || false,
+ // TODO: turn autoscape on in the next major version
+ autoescape: (params.autoescape !== null && params.autoescape) || false,
+ allowInlineIncludes: params.allowInlineIncludes || false,
+ rethrow: params.rethrow || false,
+ namespaces: params.namespaces
+ };
+
+ if (Twig.cache && id) {
Twig.validateId(id);
}
if (params.debug !== undefined) {
Twig.debug = params.debug;
}
+
if (params.trace !== undefined) {
Twig.trace = params.trace;
}
if (params.data !== undefined) {
- return new Twig.Template({
+ return Twig.Templates.parsers.twig({
data: params.data,
+ path: Object.hasOwnProperty.call(params, 'path') ? params.path : undefined,
module: params.module,
- id: id,
- options: options
+ id,
+ options
});
+ }
- } else if (params.ref !== undefined) {
+ if (params.ref !== undefined) {
if (params.id !== undefined) {
- throw new Twig.Error("Both ref and id cannot be set on a twig.js template.");
+ throw new Twig.Error('Both ref and id cannot be set on a twig.js template.');
}
+
return Twig.Templates.load(params.ref);
+ }
+
+ if (params.method !== undefined) {
+ if (!Twig.Templates.isRegisteredLoader(params.method)) {
+ throw new Twig.Error('Loader for "' + params.method + '" is not defined.');
+ }
+
+ return Twig.Templates.loadRemote(params.name || params.href || params.path || id || undefined, {
+ id,
+ method: params.method,
+ parser: params.parser || 'twig',
+ base: params.base,
+ module: params.module,
+ precompiled: params.precompiled,
+ async: params.async,
+ options
+
+ }, params.load, params.error);
+ }
- } else if (params.href !== undefined) {
+ if (params.href !== undefined) {
return Twig.Templates.loadRemote(params.href, {
- id: id,
+ id,
method: 'ajax',
+ parser: params.parser || 'twig',
base: params.base,
module: params.module,
precompiled: params.precompiled,
async: params.async,
- options: options
+ options
}, params.load, params.error);
+ }
- } else if (params.path !== undefined) {
+ if (params.path !== undefined) {
return Twig.Templates.loadRemote(params.path, {
- id: id,
+ id,
method: 'fs',
+ parser: params.parser || 'twig',
base: params.base,
module: params.module,
precompiled: params.precompiled,
async: params.async,
- options: options
-
+ options
}, params.load, params.error);
}
};
// Extend Twig with a new filter.
- Twig.exports.extendFilter = function(filter, definition) {
+ Twig.exports.extendFilter = function (filter, definition) {
Twig.filter.extend(filter, definition);
};
// Extend Twig with a new function.
- Twig.exports.extendFunction = function(fn, definition) {
+ Twig.exports.extendFunction = function (fn, definition) {
Twig._function.extend(fn, definition);
};
// Extend Twig with a new test.
- Twig.exports.extendTest = function(test, definition) {
+ Twig.exports.extendTest = function (test, definition) {
Twig.test.extend(test, definition);
};
// Extend Twig with a new definition.
- Twig.exports.extendTag = function(definition) {
+ Twig.exports.extendTag = function (definition) {
Twig.logic.extend(definition);
};
// Provide an environment for extending Twig core.
// Calls fn with the internal Twig object.
- Twig.exports.extend = function(fn) {
+ Twig.exports.extend = function (fn) {
fn(Twig);
};
-
/**
* Provide an extension for use with express 2.
*
@@ -115,20 +137,19 @@ var Twig = (function (Twig) {
*
* @return {string} The rendered template.
*/
- Twig.exports.compile = function(markup, options) {
- var id = options.filename,
- path = options.filename,
- template;
+ Twig.exports.compile = function (markup, options) {
+ const id = options.filename;
+ const path = options.filename;
// Try to load the template from the cache
- template = new Twig.Template({
+ const template = new Twig.Template({
data: markup,
- path: path,
- id: id,
+ path,
+ id,
options: options.settings['twig options']
}); // Twig.Templates.load(id) ||
- return function(context) {
+ return function (context) {
return template.render(context);
};
};
@@ -139,32 +160,46 @@ var Twig = (function (Twig) {
* @param {string} path The location of the template file on disk.
* @param {Object|Function} The options or callback.
* @param {Function} fn callback.
+ *
+ * @throws Twig.Error
*/
-
- Twig.exports.renderFile = function(path, options, fn) {
- // handle callback in options
- if ('function' == typeof options) {
+ Twig.exports.renderFile = function (path, options, fn) {
+ // Handle callback in options
+ if (typeof options === 'function') {
fn = options;
options = {};
}
options = options || {};
- var params = {
- path: path,
- base: options.settings['views'],
- load: function(template) {
- // render and return template
- fn(null, template.render(options));
+ const settings = options.settings || {};
+
+ // Mixin any options provided to the express app.
+ const viewOptions = settings['twig options'];
+
+ const params = {
+ path,
+ base: settings.views,
+ load(template) {
+ // Render and return template as a simple string, see https://github.com/twigjs/twig.js/pull/348 for more information
+ if (!viewOptions || !viewOptions.allowAsync) {
+ fn(null, String(template.render(options)));
+ return;
}
- };
- // mixin any options provided to the express app.
- var view_options = options.settings['twig options'];
+ template.renderAsync(options)
+ .then(out => fn(null, out), fn);
+ },
+ error(err) {
+ fn(err);
+ }
+ };
- if (view_options) {
- for (var option in view_options) if (view_options.hasOwnProperty(option)) {
- params[option] = view_options[option];
+ if (viewOptions) {
+ for (const option in viewOptions) {
+ if (Object.hasOwnProperty.call(viewOptions, option)) {
+ params[option] = viewOptions[option];
+ }
}
}
@@ -181,10 +216,24 @@ var Twig = (function (Twig) {
*
* @param {boolean} cache
*/
- Twig.exports.cache = function(cache) {
+ Twig.exports.cache = function (cache) {
Twig.cache = cache;
- }
+ };
- return Twig;
-}) (Twig || { });
+ // We need to export the path module so we can effectively test it
+ Twig.exports.path = Twig.path;
+
+ // Export our filters.
+ // Resolves #307
+ Twig.exports.filters = Twig.filters;
+ // Export our tests.
+ Twig.exports.tests = Twig.tests;
+
+ // Export our functions.
+ Twig.exports.functions = Twig.functions;
+
+ Twig.exports.Promise = Twig.Promise;
+
+ return Twig;
+};
diff --git a/src/twig.expression.js b/src/twig.expression.js
index 54c190a2..50f85d67 100644
--- a/src/twig.expression.js
+++ b/src/twig.expression.js
@@ -1,60 +1,70 @@
-// Twig.js
-// Copyright (c) 2011-2013 John Roepke
-// Available under the BSD 2-Clause License
-// https://github.com/justjohn/twig.js
-
// ## twig.expression.js
//
// This file handles tokenizing, compiling and parsing expressions.
-var Twig = (function (Twig) {
- "use strict";
+module.exports = function (Twig) {
+ 'use strict';
+
+ function parseParams(state, params, context) {
+ if (params) {
+ return Twig.expression.parseAsync.call(state, params, context);
+ }
+
+ return Twig.Promise.resolve(false);
+ }
/**
* Namespace for expression handling.
*/
Twig.expression = { };
+ require('./twig.expression.operator')(Twig);
+
/**
* Reserved word that can't be used as variable names.
*/
Twig.expression.reservedWords = [
- "true", "false", "null", "_context"
+ 'true', 'false', 'null', 'TRUE', 'FALSE', 'NULL', '_context', 'and', 'b-and', 'or', 'b-or', 'b-xor', 'in', 'not in', 'if', 'matches', 'starts', 'ends', 'with'
];
/**
* The type of tokens used in expressions.
*/
Twig.expression.type = {
- comma: 'Twig.expression.type.comma',
+ comma: 'Twig.expression.type.comma',
operator: {
- unary: 'Twig.expression.type.operator.unary',
+ unary: 'Twig.expression.type.operator.unary',
binary: 'Twig.expression.type.operator.binary'
},
- string: 'Twig.expression.type.string',
- bool: 'Twig.expression.type.bool',
+ string: 'Twig.expression.type.string',
+ bool: 'Twig.expression.type.bool',
+ slice: 'Twig.expression.type.slice',
array: {
- start: 'Twig.expression.type.array.start',
- end: 'Twig.expression.type.array.end'
+ start: 'Twig.expression.type.array.start',
+ end: 'Twig.expression.type.array.end'
},
object: {
- start: 'Twig.expression.type.object.start',
- end: 'Twig.expression.type.object.end'
+ start: 'Twig.expression.type.object.start',
+ end: 'Twig.expression.type.object.end'
},
parameter: {
- start: 'Twig.expression.type.parameter.start',
- end: 'Twig.expression.type.parameter.end'
+ start: 'Twig.expression.type.parameter.start',
+ end: 'Twig.expression.type.parameter.end'
+ },
+ subexpression: {
+ start: 'Twig.expression.type.subexpression.start',
+ end: 'Twig.expression.type.subexpression.end'
},
key: {
- period: 'Twig.expression.type.key.period',
+ period: 'Twig.expression.type.key.period',
brackets: 'Twig.expression.type.key.brackets'
},
- filter: 'Twig.expression.type.filter',
- _function: 'Twig.expression.type._function',
- variable: 'Twig.expression.type.variable',
- number: 'Twig.expression.type.number',
- _null: 'Twig.expression.type.null',
- context: 'Twig.expression.type.context',
- test: 'Twig.expression.type.test'
+ filter: 'Twig.expression.type.filter',
+ _function: 'Twig.expression.type._function',
+ variable: 'Twig.expression.type.variable',
+ number: 'Twig.expression.type.number',
+ _null: 'Twig.expression.type.null',
+ context: 'Twig.expression.type.context',
+ test: 'Twig.expression.type.test'
};
Twig.expression.set = {
@@ -66,6 +76,7 @@ var Twig = (function (Twig) {
Twig.expression.type.array.end,
Twig.expression.type.object.end,
Twig.expression.type.parameter.end,
+ Twig.expression.type.subexpression.end,
Twig.expression.type.comma,
Twig.expression.type.test
],
@@ -79,31 +90,35 @@ var Twig = (function (Twig) {
Twig.expression.type.context,
Twig.expression.type.parameter.start,
Twig.expression.type.array.start,
- Twig.expression.type.object.start
+ Twig.expression.type.object.start,
+ Twig.expression.type.subexpression.start,
+ Twig.expression.type.operator.unary
]
};
// Most expressions allow a '.' or '[' after them, so we provide a convenience set
- Twig.expression.set.operations_extended = Twig.expression.set.operations.concat([
- Twig.expression.type.key.period,
- Twig.expression.type.key.brackets]);
+ Twig.expression.set.operationsExtended = Twig.expression.set.operations.concat([
+ Twig.expression.type.key.period,
+ Twig.expression.type.key.brackets,
+ Twig.expression.type.slice
+ ]);
// Some commonly used compile and parse functions.
Twig.expression.fn = {
compile: {
- push: function(token, stack, output) {
+ push(token, stack, output) {
output.push(token);
},
- push_both: function(token, stack, output) {
+ pushBoth(token, stack, output) {
output.push(token);
stack.push(token);
}
},
parse: {
- push: function(token, stack, context) {
+ push(token, stack) {
stack.push(token);
},
- push_value: function(token, stack, context) {
+ pushValue(token, stack) {
stack.push(token.value);
}
}
@@ -128,25 +143,29 @@ var Twig = (function (Twig) {
Twig.expression.definitions = [
{
type: Twig.expression.type.test,
- regex: /^is\s+(not)?\s*([a-zA-Z_][a-zA-Z0-9_]*)/,
+ regex: /^is\s+(not)?\s*([a-zA-Z_]\w*(\s?(?:as|by))?)/,
next: Twig.expression.set.operations.concat([Twig.expression.type.parameter.start]),
- compile: function(token, stack, output) {
- token.filter = token.match[2];
+ compile(token, stack, output) {
+ token.filter = token.match[2];
token.modifier = token.match[1];
delete token.match;
delete token.value;
output.push(token);
},
- parse: function(token, stack, context) {
- var value = stack.pop(),
- params = token.params && Twig.expression.parse.apply(this, [token.params, context]),
- result = Twig.test(token.filter, value, params);
+ parse(token, stack, context) {
+ const value = stack.pop();
+ const state = this;
- if (token.modifier == 'not') {
- stack.push(!result);
- } else {
- stack.push(result);
- }
+ return parseParams(state, token.params, context)
+ .then(params => {
+ const result = Twig.test(token.filter, value, params);
+
+ if (token.modifier === 'not') {
+ stack.push(!result);
+ } else {
+ stack.push(result);
+ }
+ });
}
},
{
@@ -154,85 +173,136 @@ var Twig = (function (Twig) {
// Match a comma
regex: /^,/,
next: Twig.expression.set.expressions.concat([Twig.expression.type.array.end, Twig.expression.type.object.end]),
- compile: function(token, stack, output) {
- var i = stack.length - 1,
- stack_token;
+ compile(token, stack, output) {
+ let i = stack.length - 1;
+ let stackToken;
delete token.match;
delete token.value;
- // pop tokens off the stack until the start of the object
- for(;i >= 0; i--) {
- stack_token = stack.pop();
- if (stack_token.type === Twig.expression.type.object.start
- || stack_token.type === Twig.expression.type.parameter.start
- || stack_token.type === Twig.expression.type.array.start) {
- stack.push(stack_token);
+ // Pop tokens off the stack until the start of the object
+ for (;i >= 0; i--) {
+ stackToken = stack.pop();
+ if (stackToken.type === Twig.expression.type.object.start ||
+ stackToken.type === Twig.expression.type.parameter.start ||
+ stackToken.type === Twig.expression.type.array.start) {
+ stack.push(stackToken);
break;
}
- output.push(stack_token);
+
+ output.push(stackToken);
}
+
output.push(token);
}
},
+ {
+ /**
+ * Match a number (integer or decimal)
+ */
+ type: Twig.expression.type.number,
+ // Match a number
+ regex: /^-?\d+(\.\d+)?/,
+ next: Twig.expression.set.operations,
+ compile(token, stack, output) {
+ token.value = Number(token.value);
+ output.push(token);
+ },
+ parse: Twig.expression.fn.parse.pushValue
+ },
{
type: Twig.expression.type.operator.binary,
- // Match any of +, *, /, -, %, ~, <, <=, >, >=, !=, ==, **, ?, :, and, or, not
- regex: /(^[\+\-~%\?\:]|^[!=]==?|^[!<>]=?|^\*\*?|^\/\/?|^and\s+|^or\s+|^in\s+|^not in\s+|^\.\.)/,
- next: Twig.expression.set.expressions.concat([Twig.expression.type.operator.unary]),
- compile: function(token, stack, output) {
+ // Match any of ??, ?:, +, *, /, -, %, ~, <=>, <, <=, >, >=, !=, ==, **, ?, :, and, b-and, or, b-or, b-xor, in, not in
+ // and, or, in, not in, matches, starts with, ends with can be followed by a space or parenthesis
+ regex: /(^\?\?|^\?\s*:|^(b-and)|^(b-or)|^(b-xor)|^[+\-~%?]|^(<=>)|^[:](?!\d\])|^[!=]==?|^[!<>]=?|^\*\*?|^\/\/?|^(and)[(|\s+]|^(or)[(|\s+]|^(in)[(|\s+]|^(not in)[(|\s+]|^(matches)|^(starts with)|^(ends with)|^\.\.)/,
+ next: Twig.expression.set.expressions,
+ transform(match, tokens) {
+ switch (match[0]) {
+ case 'and(':
+ case 'or(':
+ case 'in(':
+ case 'not in(':
+ // Strip off the ( if it exists
+ tokens[tokens.length - 1].value = match[2];
+ return match[0];
+ default:
+ return '';
+ }
+ },
+ compile(token, stack, output) {
delete token.match;
+ if (token.value.match(/^\?\s*:/)) {
+ token.value = '?:';
+ }
+
token.value = token.value.trim();
- var value = token.value,
- operator = Twig.expression.operator.lookup(value, token);
+ const {value} = token;
+ const operator = Twig.expression.operator.lookup(value, token);
- Twig.log.trace("Twig.expression.compile: ", "Operator: ", operator, " from ", value);
+ Twig.log.trace('Twig.expression.compile: ', 'Operator: ', operator, ' from ', value);
while (stack.length > 0 &&
- (stack[stack.length-1].type == Twig.expression.type.operator.unary || stack[stack.length-1].type == Twig.expression.type.operator.binary) &&
+ (stack[stack.length - 1].type === Twig.expression.type.operator.unary || stack[stack.length - 1].type === Twig.expression.type.operator.binary) &&
(
(operator.associativity === Twig.expression.operator.leftToRight &&
- operator.precidence >= stack[stack.length-1].precidence) ||
+ operator.precidence >= stack[stack.length - 1].precidence) ||
(operator.associativity === Twig.expression.operator.rightToLeft &&
- operator.precidence > stack[stack.length-1].precidence)
+ operator.precidence > stack[stack.length - 1].precidence)
)
- ) {
- var temp = stack.pop();
- output.push(temp);
+ ) {
+ const temp = stack.pop();
+ output.push(temp);
}
- if (value === ":") {
+ if (value === ':') {
// Check if this is a ternary or object key being set
- if (stack[stack.length - 1] && stack[stack.length-1].value === "?") {
+ if (stack[stack.length - 1] && stack[stack.length - 1].value === '?') {
// Continue as normal for a ternary
} else {
// This is not a ternary so we push the token to the output where it can be handled
// when the assocated object is closed.
- var key_token = output.pop();
+ const keyToken = output.pop();
- if (key_token.type === Twig.expression.type.string ||
- key_token.type === Twig.expression.type.variable) {
- token.key = key_token.value;
- } else if (key_token.type === Twig.expression.type.number) {
+ if (keyToken.type === Twig.expression.type.string ||
+ keyToken.type === Twig.expression.type.variable) {
+ token.key = keyToken.value;
+ } else if (keyToken.type === Twig.expression.type.number) {
// Convert integer keys into string keys
- token.key = key_token.value.toString();
+ token.key = keyToken.value.toString();
+ } else if (keyToken.expression &&
+ (keyToken.type === Twig.expression.type.parameter.end ||
+ keyToken.type === Twig.expression.type.subexpression.end)) {
+ token.params = keyToken.params;
} else {
- throw new Twig.Error("Unexpected value before ':' of " + key_token.type + " = " + key_token.value);
+ throw new Twig.Error('Unexpected value before \':\' of ' + keyToken.type + ' = ' + keyToken.value);
}
output.push(token);
- return;
}
} else {
stack.push(operator);
}
},
- parse: function(token, stack, context) {
+ parse(token, stack, context) {
+ const state = this;
+
if (token.key) {
- // handle ternary ':' operator
+ // Handle ternary ':' operator
stack.push(token);
+ } else if (token.params) {
+ // Handle "{(expression):value}"
+ return Twig.expression.parseAsync.call(state, token.params, context)
+ .then(key => {
+ token.key = key;
+ stack.push(token);
+
+ // If we're in a loop, we might need token.params later, especially in this form of "(expression):value"
+ if (!context.loop) {
+ delete (token.params);
+ }
+ });
} else {
Twig.expression.operator.parse(token.value, stack);
}
@@ -243,32 +313,32 @@ var Twig = (function (Twig) {
// Match any of not
regex: /(^not\s+)/,
next: Twig.expression.set.expressions,
- compile: function(token, stack, output) {
+ compile(token, stack, output) {
delete token.match;
token.value = token.value.trim();
- var value = token.value,
- operator = Twig.expression.operator.lookup(value, token);
+ const {value} = token;
+ const operator = Twig.expression.operator.lookup(value, token);
- Twig.log.trace("Twig.expression.compile: ", "Operator: ", operator, " from ", value);
+ Twig.log.trace('Twig.expression.compile: ', 'Operator: ', operator, ' from ', value);
while (stack.length > 0 &&
- (stack[stack.length-1].type == Twig.expression.type.operator.unary || stack[stack.length-1].type == Twig.expression.type.operator.binary) &&
+ (stack[stack.length - 1].type === Twig.expression.type.operator.unary || stack[stack.length - 1].type === Twig.expression.type.operator.binary) &&
(
(operator.associativity === Twig.expression.operator.leftToRight &&
- operator.precidence >= stack[stack.length-1].precidence) ||
+ operator.precidence >= stack[stack.length - 1].precidence) ||
(operator.associativity === Twig.expression.operator.rightToLeft &&
- operator.precidence > stack[stack.length-1].precidence)
+ operator.precidence > stack[stack.length - 1].precidence)
)
- ) {
- var temp = stack.pop();
- output.push(temp);
+ ) {
+ const temp = stack.pop();
+ output.push(temp);
}
stack.push(operator);
},
- parse: function(token, stack, context) {
+ parse(token, stack) {
Twig.expression.operator.parse(token.value, stack);
}
},
@@ -278,23 +348,140 @@ var Twig = (function (Twig) {
*/
type: Twig.expression.type.string,
// See: http://blog.stevenlevithan.com/archives/match-quoted-string
- regex: /^(["'])(?:(?=(\\?))\2.)*?\1/,
- next: Twig.expression.set.operations,
- compile: function(token, stack, output) {
- var value = token.value;
- delete token.match
+ regex: /^(["'])(?:(?=(\\?))\2[\s\S])*?\1/,
+ next: Twig.expression.set.operationsExtended,
+ compile(token, stack, output) {
+ let {value} = token;
+ delete token.match;
// Remove the quotes from the string
- if (value.substring(0, 1) === '"') {
+ if (value.slice(0, 1) === '"') {
value = value.replace('\\"', '"');
} else {
- value = value.replace("\\'", "'");
+ value = value.replace('\\\'', '\'');
}
- token.value = value.substring(1, value.length-1).replace( /\\n/g, "\n" ).replace( /\\r/g, "\r" );
- Twig.log.trace("Twig.expression.compile: ", "String value: ", token.value);
+
+ token.value = value.slice(1, -1).replace(/\\n/g, '\n').replace(/\\r/g, '\r');
+ Twig.log.trace('Twig.expression.compile: ', 'String value: ', token.value);
output.push(token);
},
- parse: Twig.expression.fn.parse.push_value
+ parse: Twig.expression.fn.parse.pushValue
+ },
+ {
+ /**
+ * Match a subexpression set start.
+ */
+ type: Twig.expression.type.subexpression.start,
+ regex: /^\(/,
+ next: Twig.expression.set.expressions.concat([Twig.expression.type.subexpression.end]),
+ compile(token, stack, output) {
+ token.value = '(';
+ output.push(token);
+ stack.push(token);
+ },
+ parse: Twig.expression.fn.parse.push
+ },
+ {
+ /**
+ * Match a subexpression set end.
+ */
+ type: Twig.expression.type.subexpression.end,
+ regex: /^\)/,
+ next: Twig.expression.set.operationsExtended,
+ validate(match, tokens) {
+ // Iterate back through previous tokens to ensure we follow a subexpression start
+ let i = tokens.length - 1;
+ let foundSubexpressionStart = false;
+ let nextSubexpressionStartInvalid = false;
+ let unclosedParameterCount = 0;
+
+ while (!foundSubexpressionStart && i >= 0) {
+ const token = tokens[i];
+
+ foundSubexpressionStart = token.type === Twig.expression.type.subexpression.start;
+
+ // If we have previously found a subexpression end, then this subexpression start is the start of
+ // that subexpression, not the subexpression we are searching for
+ if (foundSubexpressionStart && nextSubexpressionStartInvalid) {
+ nextSubexpressionStartInvalid = false;
+ foundSubexpressionStart = false;
+ }
+
+ // Count parameter tokens to ensure we dont return truthy for a parameter opener
+ if (token.type === Twig.expression.type.parameter.start) {
+ unclosedParameterCount++;
+ } else if (token.type === Twig.expression.type.parameter.end) {
+ unclosedParameterCount--;
+ } else if (token.type === Twig.expression.type.subexpression.end) {
+ nextSubexpressionStartInvalid = true;
+ }
+
+ i--;
+ }
+
+ // If we found unclosed parameters, return false
+ // If we didnt find subexpression start, return false
+ // Otherwise return true
+
+ return (foundSubexpressionStart && (unclosedParameterCount === 0));
+ },
+ compile(token, stack, output) {
+ // This is basically a copy of parameter end compilation
+ let stackToken;
+ const endToken = token;
+
+ stackToken = stack.pop();
+ while (stack.length > 0 && stackToken.type !== Twig.expression.type.subexpression.start) {
+ output.push(stackToken);
+ stackToken = stack.pop();
+ }
+
+ // Move contents of parens into preceding filter
+ const paramStack = [];
+ while (token.type !== Twig.expression.type.subexpression.start) {
+ // Add token to arguments stack
+ paramStack.unshift(token);
+ token = output.pop();
+ }
+
+ paramStack.unshift(token);
+
+ // If the token at the top of the *stack* is a function token, pop it onto the output queue.
+ // Get the token preceding the parameters
+ stackToken = stack[stack.length - 1];
+
+ if (stackToken === undefined ||
+ (stackToken.type !== Twig.expression.type._function &&
+ stackToken.type !== Twig.expression.type.filter &&
+ stackToken.type !== Twig.expression.type.test &&
+ stackToken.type !== Twig.expression.type.key.brackets)) {
+ endToken.expression = true;
+
+ // Remove start and end token from stack
+ paramStack.pop();
+ paramStack.shift();
+
+ endToken.params = paramStack;
+
+ output.push(endToken);
+ } else {
+ // This should never be hit
+ endToken.expression = false;
+ stackToken.params = paramStack;
+ }
+ },
+ parse(token, stack, context) {
+ const state = this;
+
+ if (token.expression) {
+ return Twig.expression.parseAsync.call(state, token.params, context)
+ .then(value => {
+ stack.push(value);
+ });
+ }
+
+ throw new Twig.Error('Unexpected subexpression end when token is not marked as an expression');
+ }
},
{
/**
@@ -303,7 +490,12 @@ var Twig = (function (Twig) {
type: Twig.expression.type.parameter.start,
regex: /^\(/,
next: Twig.expression.set.expressions.concat([Twig.expression.type.parameter.end]),
- compile: Twig.expression.fn.compile.push_both,
+ validate(match, tokens) {
+ const lastToken = tokens[tokens.length - 1];
+ // We can't use the regex to test if we follow a space because expression is trimmed
+ return lastToken && (!Twig.expression.reservedWords.includes(lastToken.value.trim()));
+ },
+ compile: Twig.expression.fn.compile.pushBoth,
parse: Twig.expression.fn.parse.push
},
{
@@ -312,80 +504,136 @@ var Twig = (function (Twig) {
*/
type: Twig.expression.type.parameter.end,
regex: /^\)/,
- next: Twig.expression.set.operations_extended,
- compile: function(token, stack, output) {
- var stack_token,
- end_token = token;
-
- stack_token = stack.pop();
- while(stack.length > 0 && stack_token.type != Twig.expression.type.parameter.start) {
- output.push(stack_token);
- stack_token = stack.pop();
+ next: Twig.expression.set.operationsExtended,
+ compile(token, stack, output) {
+ let stackToken;
+ const endToken = token;
+
+ stackToken = stack.pop();
+ while (stack.length > 0 && stackToken.type !== Twig.expression.type.parameter.start) {
+ output.push(stackToken);
+ stackToken = stack.pop();
}
// Move contents of parens into preceding filter
- var param_stack = [];
- while(token.type !== Twig.expression.type.parameter.start) {
+ const paramStack = [];
+ while (token.type !== Twig.expression.type.parameter.start) {
// Add token to arguments stack
- param_stack.unshift(token);
+ paramStack.unshift(token);
token = output.pop();
}
- param_stack.unshift(token);
- var is_expression = false;
+ paramStack.unshift(token);
// Get the token preceding the parameters
- token = output[output.length-1];
+ token = output[output.length - 1];
if (token === undefined ||
(token.type !== Twig.expression.type._function &&
token.type !== Twig.expression.type.filter &&
token.type !== Twig.expression.type.test &&
- token.type !== Twig.expression.type.key.brackets &&
- token.type !== Twig.expression.type.key.period)) {
-
- end_token.expression = true;
+ token.type !== Twig.expression.type.key.brackets)) {
+ endToken.expression = true;
- // remove start and end token from stack
- param_stack.pop();
- param_stack.shift();
+ // Remove start and end token from stack
+ paramStack.pop();
+ paramStack.shift();
- end_token.params = param_stack;
-
- output.push(end_token);
+ endToken.params = paramStack;
+ output.push(endToken);
} else {
- end_token.expression = false;
- token.params = param_stack;
+ endToken.expression = false;
+ token.params = paramStack;
}
},
- parse: function(token, stack, context) {
- var new_array = [],
- array_ended = false,
- value = null;
+ parse(token, stack, context) {
+ const newArray = [];
+ let arrayEnded = false;
+ let value = null;
+ const state = this;
if (token.expression) {
- value = Twig.expression.parse.apply(this, [token.params, context])
- stack.push(value);
+ return Twig.expression.parseAsync.call(state, token.params, context)
+ .then(value => {
+ stack.push(value);
+ });
+ }
+ while (stack.length > 0) {
+ value = stack.pop();
+ // Push values into the array until the start of the array
+ if (value && value.type && value.type === Twig.expression.type.parameter.start) {
+ arrayEnded = true;
+ break;
+ }
+
+ newArray.unshift(value);
+ }
+
+ if (!arrayEnded) {
+ throw new Twig.Error('Expected end of parameter set.');
+ }
+
+ stack.push(newArray);
+ }
+ },
+ {
+ type: Twig.expression.type.slice,
+ regex: /^\[(-?\w*:-?\w*)\]/,
+ next: Twig.expression.set.operationsExtended,
+ compile(token, stack, output) {
+ const sliceRange = token.match[1].split(':');
+
+ // SliceStart can be undefined when we pass parameters to the slice filter later
+ const sliceStart = sliceRange[0];
+ const sliceEnd = sliceRange[1];
+
+ token.value = 'slice';
+ token.params = [sliceStart, sliceEnd];
+
+ // SliceEnd can't be undefined as the slice filter doesn't check for this, but it does check the length
+ // of the params array, so just shorten it.
+ if (!sliceEnd) {
+ token.params = [sliceStart];
+ }
+
+ output.push(token);
+ },
+ parse(token, stack, context) {
+ const input = stack.pop();
+ let {params} = token;
+ const state = this;
+
+ if (parseInt(params[0], 10).toString() === params[0]) {
+ params[0] = parseInt(params[0], 10);
} else {
+ const value = context[params[0]];
+ if (state.template.options.strictVariables && value === undefined) {
+ throw new Twig.Error('Variable "' + params[0] + '" does not exist.');
+ }
+
+ params[0] = value;
+ }
- while (stack.length > 0) {
- value = stack.pop();
- // Push values into the array until the start of the array
- if (value && value.type && value.type == Twig.expression.type.parameter.start) {
- array_ended = true;
- break;
+ if (params[1]) {
+ if (parseInt(params[1], 10).toString() === params[1]) {
+ params[1] = parseInt(params[1], 10);
+ } else {
+ const value = context[params[1]];
+ if (state.template.options.strictVariables && value === undefined) {
+ throw new Twig.Error('Variable "' + params[1] + '" does not exist.');
}
- new_array.unshift(value);
- }
- if (!array_ended) {
- throw new Twig.Error("Expected end of parameter set.");
+ if (value === undefined) {
+ params = [params[0]];
+ } else {
+ params[1] = value;
+ }
}
-
- stack.push(new_array);
}
+
+ stack.push(Twig.filter.call(state, token.value, input, params));
}
},
{
@@ -395,7 +643,7 @@ var Twig = (function (Twig) {
type: Twig.expression.type.array.start,
regex: /^\[/,
next: Twig.expression.set.expressions.concat([Twig.expression.type.array.end]),
- compile: Twig.expression.fn.compile.push_both,
+ compile: Twig.expression.fn.compile.pushBoth,
parse: Twig.expression.fn.parse.push
},
{
@@ -404,39 +652,43 @@ var Twig = (function (Twig) {
*/
type: Twig.expression.type.array.end,
regex: /^\]/,
- next: Twig.expression.set.operations_extended,
- compile: function(token, stack, output) {
- var i = stack.length - 1,
- stack_token;
- // pop tokens off the stack until the start of the object
- for(;i >= 0; i--) {
- stack_token = stack.pop();
- if (stack_token.type === Twig.expression.type.array.start) {
+ next: Twig.expression.set.operationsExtended,
+ compile(token, stack, output) {
+ let i = stack.length - 1;
+ let stackToken;
+ // Pop tokens off the stack until the start of the object
+ for (;i >= 0; i--) {
+ stackToken = stack.pop();
+ if (stackToken.type === Twig.expression.type.array.start) {
break;
}
- output.push(stack_token);
+
+ output.push(stackToken);
}
+
output.push(token);
},
- parse: function(token, stack, context) {
- var new_array = [],
- array_ended = false,
- value = null;
+ parse(token, stack) {
+ const newArray = [];
+ let arrayEnded = false;
+ let value = null;
while (stack.length > 0) {
value = stack.pop();
// Push values into the array until the start of the array
- if (value.type && value.type == Twig.expression.type.array.start) {
- array_ended = true;
+ if (value && value.type && value.type === Twig.expression.type.array.start) {
+ arrayEnded = true;
break;
}
- new_array.unshift(value);
+
+ newArray.unshift(value);
}
- if (!array_ended) {
- throw new Twig.Error("Expected end of array.");
+
+ if (!arrayEnded) {
+ throw new Twig.Error('Expected end of array.');
}
- stack.push(new_array);
+ stack.push(newArray);
}
},
// Token that represents the start of a hash map '}'
@@ -449,7 +701,7 @@ var Twig = (function (Twig) {
type: Twig.expression.type.object.start,
regex: /^\{/,
next: Twig.expression.set.expressions.concat([Twig.expression.type.object.end]),
- compile: Twig.expression.fn.compile.push_both,
+ compile: Twig.expression.fn.compile.pushBoth,
parse: Twig.expression.fn.parse.push
},
@@ -460,62 +712,68 @@ var Twig = (function (Twig) {
{
type: Twig.expression.type.object.end,
regex: /^\}/,
- next: Twig.expression.set.operations_extended,
- compile: function(token, stack, output) {
- var i = stack.length-1,
- stack_token;
-
- // pop tokens off the stack until the start of the object
- for(;i >= 0; i--) {
- stack_token = stack.pop();
- if (stack_token && stack_token.type === Twig.expression.type.object.start) {
+ next: Twig.expression.set.operationsExtended,
+ compile(token, stack, output) {
+ let i = stack.length - 1;
+ let stackToken;
+
+ // Pop tokens off the stack until the start of the object
+ for (;i >= 0; i--) {
+ stackToken = stack.pop();
+ if (stackToken && stackToken.type === Twig.expression.type.object.start) {
break;
}
- output.push(stack_token);
+
+ output.push(stackToken);
}
+
output.push(token);
},
- parse: function(end_token, stack, context) {
- var new_object = {},
- object_ended = false,
- token = null,
- token_key = null,
- has_value = false,
- value = null;
+ parse(endToken, stack) {
+ const newObject = {};
+ let objectEnded = false;
+ let token = null;
+ let hasValue = false;
+ let value = null;
while (stack.length > 0) {
token = stack.pop();
// Push values into the array until the start of the object
if (token && token.type && token.type === Twig.expression.type.object.start) {
- object_ended = true;
+ objectEnded = true;
break;
}
+
if (token && token.type && (token.type === Twig.expression.type.operator.binary || token.type === Twig.expression.type.operator.unary) && token.key) {
- if (!has_value) {
- throw new Twig.Error("Missing value for key '" + token.key + "' in object definition.");
+ if (!hasValue) {
+ throw new Twig.Error('Missing value for key \'' + token.key + '\' in object definition.');
}
- new_object[token.key] = value;
+
+ newObject[token.key] = value;
// Preserve the order that elements are added to the map
// This is necessary since JavaScript objects don't
// guarantee the order of keys
- if (new_object._keys === undefined) new_object._keys = [];
- new_object._keys.unshift(token.key);
+ if (newObject._keys === undefined) {
+ newObject._keys = [];
+ }
- // reset value check
- value = null;
- has_value = false;
+ newObject._keys.unshift(token.key);
+ // Reset value check
+ value = null;
+ hasValue = false;
} else {
- has_value = true;
+ hasValue = true;
value = token;
}
}
- if (!object_ended) {
- throw new Twig.Error("Unexpected end of object.");
+
+ if (!objectEnded) {
+ throw new Twig.Error('Unexpected end of object.');
}
- stack.push(new_object);
+ stack.push(newObject);
}
},
@@ -527,56 +785,71 @@ var Twig = (function (Twig) {
// Filter parsing is done in the Twig.filters namespace.
{
type: Twig.expression.type.filter,
- // match a | then a letter or _, then any number of letters, numbers, _ or -
- regex: /^\|\s?([a-zA-Z_][a-zA-Z0-9_\-]*)/,
- next: Twig.expression.set.operations_extended.concat([
- Twig.expression.type.parameter.start]),
- compile: function(token, stack, output) {
+ // Match a | then a letter or _, then any number of letters, numbers, _ or -
+ regex: /^\|\s?([a-zA-Z_][a-zA-Z0-9_-]*)/,
+ next: Twig.expression.set.operationsExtended.concat([
+ Twig.expression.type.parameter.start
+ ]),
+ compile(token, stack, output) {
token.value = token.match[1];
output.push(token);
},
- parse: function(token, stack, context) {
- var input = stack.pop(),
- params = token.params && Twig.expression.parse.apply(this, [token.params, context]);
-
- stack.push(Twig.filter.apply(this, [token.value, input, params]));
+ parse(token, stack, context) {
+ const input = stack.pop();
+ const state = this;
+
+ return parseParams(state, token.params, context)
+ .then(params => {
+ return Twig.filter.call(state, token.value, input, params);
+ })
+ .then(value => {
+ stack.push(value);
+ });
}
},
{
type: Twig.expression.type._function,
- // match any letter or _, then any number of letters, numbers, _ or - followed by (
- regex: /^([a-zA-Z_][a-zA-Z0-9_]*)\s*\(/,
+ // Match any letter or _, then any number of letters, numbers, _ or - followed by (
+ regex: /^([a-zA-Z_]\w*)\s*\(/,
next: Twig.expression.type.parameter.start,
- transform: function(match, tokens) {
+ validate(match) {
+ // Make sure this function is not a reserved word
+ return match[1] && (!Twig.expression.reservedWords.includes(match[1]));
+ },
+ transform() {
return '(';
},
- compile: function(token, stack, output) {
- var fn = token.match[1];
+ compile(token, stack, output) {
+ const fn = token.match[1];
token.fn = fn;
- // cleanup token
+ // Cleanup token
delete token.match;
delete token.value;
output.push(token);
},
- parse: function(token, stack, context) {
- var params = token.params && Twig.expression.parse.apply(this, [token.params, context]),
- fn = token.fn,
- value;
-
- if (Twig.functions[fn]) {
- // Get the function from the built-in functions
- value = Twig.functions[fn].apply(this, params);
-
- } else if (typeof context[fn] == 'function') {
- // Get the function from the user/context defined functions
- value = context[fn].apply(context, params);
-
- } else {
- throw new Twig.Error(fn + ' function does not exist and is not defined in the context');
- }
+ parse(token, stack, context) {
+ const state = this;
+ const {fn} = token;
+ let value;
+
+ return parseParams(state, token.params, context)
+ .then(params => {
+ if (Twig.functions[fn]) {
+ // Get the function from the built-in functions
+ value = Twig.functions[fn].apply(state, params);
+ } else if (typeof context[fn] === 'function') {
+ // Get the function from the user/context defined functions
+ value = context[fn](...params);
+ } else {
+ throw new Twig.Error(fn + ' function does not exist and is not defined in the context');
+ }
- stack.push(value);
+ return value;
+ })
+ .then(result => {
+ stack.push(result);
+ });
}
},
@@ -590,68 +863,94 @@ var Twig = (function (Twig) {
// exist in the context.
{
type: Twig.expression.type.variable,
- // match any letter or _, then any number of letters, numbers, _ or -
- regex: /^[a-zA-Z_][a-zA-Z0-9_]*/,
- next: Twig.expression.set.operations_extended.concat([
- Twig.expression.type.parameter.start]),
+ // Match any letter or _, then any number of letters, numbers, _ or -
+ regex: /^[a-zA-Z_]\w*/,
+ next: Twig.expression.set.operationsExtended.concat([
+ Twig.expression.type.parameter.start
+ ]),
compile: Twig.expression.fn.compile.push,
- validate: function(match, tokens) {
- return (Twig.indexOf(Twig.expression.reservedWords, match[0]) < 0);
+ validate(match) {
+ return (!Twig.expression.reservedWords.includes(match[0]));
},
- parse: function(token, stack, context) {
+ parse(token, stack, context) {
+ const state = this;
+
// Get the variable from the context
- var value = Twig.expression.resolve(context[token.value], context);
- stack.push(value);
+ return Twig.expression.resolveAsync.call(state, context[token.value], context)
+ .then(value => {
+ if (state.template.options.strictVariables && value === undefined) {
+ throw new Twig.Error('Variable "' + token.value + '" does not exist.');
+ }
+
+ stack.push(value);
+ });
}
},
{
type: Twig.expression.type.key.period,
- regex: /^\.([a-zA-Z0-9_]+)/,
- next: Twig.expression.set.operations_extended.concat([
- Twig.expression.type.parameter.start]),
- compile: function(token, stack, output) {
+ regex: /^\.(\w+)/,
+ next: Twig.expression.set.operationsExtended.concat([
+ Twig.expression.type.parameter.start
+ ]),
+ compile(token, stack, output) {
token.key = token.match[1];
delete token.match;
delete token.value;
output.push(token);
},
- parse: function(token, stack, context) {
- var params = token.params && Twig.expression.parse.apply(this, [token.params, context]),
- key = token.key,
- object = stack.pop(),
- value;
-
- if (object === null || object === undefined) {
- if (this.options.strict_variables) {
- throw new Twig.Error("Can't access a key " + key + " on an null or undefined object.");
+ parse(token, stack, context, nextToken) {
+ const state = this;
+ const {key} = token;
+ const object = stack.pop();
+ let value;
+
+ if (object && !Object.prototype.hasOwnProperty.call(object, key) && state.template.options.strictVariables) {
+ const keys = Object.keys(object);
+ if (keys.length > 0) {
+ throw new Twig.Error('Key "' + key + '" for object with keys "' + Object.keys(object).join(', ') + '" does not exist.');
} else {
- return null;
+ throw new Twig.Error('Key "' + key + '" does not exist as the object is empty.');
}
}
- var capitalize = function(value) {return value.substr(0, 1).toUpperCase() + value.substr(1);};
+ return parseParams(state, token.params, context)
+ .then(params => {
+ if (object === null || object === undefined) {
+ value = undefined;
+ } else {
+ const capitalize = function (value) {
+ return value.slice(0, 1).toUpperCase() + value.slice(1);
+ };
+
+ // Get the variable from the context
+ if (typeof object === 'object' && key in object) {
+ value = object[key];
+ } else if (object['get' + capitalize(key)]) {
+ value = object['get' + capitalize(key)];
+ } else if (object['is' + capitalize(key)]) {
+ value = object['is' + capitalize(key)];
+ } else {
+ value = undefined;
+ }
+ }
- // Get the variable from the context
- if (typeof object === 'object' && key in object) {
- value = object[key];
- } else if (object["get"+capitalize(key)] !== undefined) {
- value = object["get"+capitalize(key)];
- } else if (object["is"+capitalize(key)] !== undefined) {
- value = object["is"+capitalize(key)];
- } else {
- value = null;
- }
- stack.push(Twig.expression.resolve(value, object, params));
+ // When resolving an expression we need to pass nextToken in case the expression is a function
+ return Twig.expression.resolveAsync.call(state, value, context, params, nextToken, object);
+ })
+ .then(result => {
+ stack.push(result);
+ });
}
},
{
type: Twig.expression.type.key.brackets,
regex: /^\[([^\]]*)\]/,
- next: Twig.expression.set.operations_extended.concat([
- Twig.expression.type.parameter.start]),
- compile: function(token, stack, output) {
- var match = token.match[1];
+ next: Twig.expression.set.operationsExtended.concat([
+ Twig.expression.type.parameter.start
+ ]),
+ compile(token, stack, output) {
+ const match = token.match[1];
delete token.value;
delete token.match;
@@ -662,28 +961,45 @@ var Twig = (function (Twig) {
output.push(token);
},
- parse: function(token, stack, context) {
+ parse(token, stack, context, nextToken) {
// Evaluate key
- var params = token.params && Twig.expression.parse.apply(this, [token.params, context]),
- key = Twig.expression.parse.apply(this, [token.stack, context]),
- object = stack.pop(),
- value;
-
- if (object === null || object === undefined) {
- if (this.options.strict_variables) {
- throw new Twig.Error("Can't access a key " + key + " on an null or undefined object.");
- } else {
- return null;
- }
- }
+ const state = this;
+ let params = null;
+ let object;
+ let value;
+
+ return parseParams(state, token.params, context)
+ .then(parameters => {
+ params = parameters;
+ return Twig.expression.parseAsync.call(state, token.stack, context);
+ })
+ .then(key => {
+ object = stack.pop();
+
+ if (object && !Object.prototype.hasOwnProperty.call(object, key) && state.template.options.strictVariables) {
+ const keys = Object.keys(object);
+ if (keys.length > 0) {
+ throw new Twig.Error('Key "' + key + '" for array with keys "' + keys.join(', ') + '" does not exist.');
+ } else {
+ throw new Twig.Error('Key "' + key + '" does not exist as the array is empty.');
+ }
+ } else if (object === null || object === undefined) {
+ return null;
+ }
- // Get the variable from the context
- if (typeof object === 'object' && key in object) {
- value = object[key];
- } else {
- value = null;
- }
- stack.push(Twig.expression.resolve(value, object, params));
+ // Get the variable from the context
+ if (typeof object === 'object' && key in object) {
+ value = object[key];
+ } else {
+ value = null;
+ }
+
+ // When resolving an expression we need to pass nextToken in case the expression is a function
+ return Twig.expression.resolveAsync.call(state, value, object, params, nextToken);
+ })
+ .then(result => {
+ stack.push(result);
+ });
}
},
{
@@ -691,15 +1007,15 @@ var Twig = (function (Twig) {
* Match a null value.
*/
type: Twig.expression.type._null,
- // match a number
- regex: /^null/,
+ // Match a number
+ regex: /^(null|NULL|none|NONE)/,
next: Twig.expression.set.operations,
- compile: function(token, stack, output) {
+ compile(token, stack, output) {
delete token.match;
token.value = null;
output.push(token);
},
- parse: Twig.expression.fn.parse.push_value
+ parse: Twig.expression.fn.parse.pushValue
},
{
/**
@@ -707,40 +1023,27 @@ var Twig = (function (Twig) {
*/
type: Twig.expression.type.context,
regex: /^_context/,
- next: Twig.expression.set.operations_extended.concat([
- Twig.expression.type.parameter.start]),
+ next: Twig.expression.set.operationsExtended.concat([
+ Twig.expression.type.parameter.start
+ ]),
compile: Twig.expression.fn.compile.push,
- parse: function(token, stack, context) {
+ parse(token, stack, context) {
stack.push(context);
}
},
- {
- /**
- * Match a number (integer or decimal)
- */
- type: Twig.expression.type.number,
- // match a number
- regex: /^\-?\d+(\.\d+)?/,
- next: Twig.expression.set.operations,
- compile: function(token, stack, output) {
- token.value = Number(token.value);
- output.push(token);
- },
- parse: Twig.expression.fn.parse.push_value
- },
{
/**
* Match a boolean
*/
type: Twig.expression.type.bool,
- regex: /^(true|false)/,
+ regex: /^(true|TRUE|false|FALSE)/,
next: Twig.expression.set.operations,
- compile: function(token, stack, output) {
- token.value = (token.match[0] == "true");
+ compile(token, stack, output) {
+ token.value = (token.match[0].toLowerCase() === 'true');
delete token.match;
output.push(token);
},
- parse: Twig.expression.fn.parse.push_value
+ parse: Twig.expression.fn.parse.pushValue
}
];
@@ -752,12 +1055,48 @@ var Twig = (function (Twig) {
* @param {string} key The context object key.
* @param {Object} context The render context.
*/
- Twig.expression.resolve = function(value, context, params) {
- if (typeof value == 'function') {
- return value.apply(context, params || []);
- } else {
- return value;
+ Twig.expression.resolveAsync = function (value, context, params, nextToken, object) {
+ const state = this;
+
+ if (typeof value !== 'function') {
+ return Twig.Promise.resolve(value);
}
+
+ let promise = Twig.Promise.resolve(params);
+
+ /*
+ If value is a function, it will have been impossible during the compile stage to determine that a following
+ set of parentheses were parameters for this function.
+
+ Those parentheses will have therefore been marked as an expression, with their own parameters, which really
+ belong to this function.
+
+ Those parameters will also need parsing in case they are actually an expression to pass as parameters.
+ */
+ if (nextToken && nextToken.type === Twig.expression.type.parameter.end) {
+ // When parsing these parameters, we need to get them all back, not just the last item on the stack.
+ const tokensAreParameters = true;
+
+ promise = promise.then(() => {
+ return nextToken.params && Twig.expression.parseAsync.call(state, nextToken.params, context, tokensAreParameters);
+ })
+ .then(p => {
+ // Clean up the parentheses tokens on the next loop
+ nextToken.cleanup = true;
+
+ return p;
+ });
+ }
+
+ return promise.then(params => {
+ return value.apply(object || context, params || []);
+ });
+ };
+
+ Twig.expression.resolve = function (value, context, params, nextToken, object) {
+ return Twig.async.potentiallyAsync(this, false, function () {
+ return Twig.expression.resolveAsync.call(this, value, context, params, nextToken, object);
+ });
};
/**
@@ -771,7 +1110,7 @@ var Twig = (function (Twig) {
* @param {string} type The name of the new type.
*/
Twig.expression.extendType = function (type) {
- Twig.expression.type[type] = "Twig.expression.type." + type;
+ Twig.expression.type[type] = 'Twig.expression.type.' + type;
};
/**
@@ -797,8 +1136,9 @@ var Twig = (function (Twig) {
*/
Twig.expression.extend = function (definition) {
if (!definition.type) {
- throw new Twig.Error("Unable to extend logic definition. No type provided for " + definition);
+ throw new Twig.Error('Unable to extend logic definition. No type provided for ' + definition);
}
+
Twig.expression.handler[definition.type] = definition;
};
@@ -810,155 +1150,172 @@ var Twig = (function (Twig) {
/**
* Break an expression into tokens defined in Twig.expression.definitions.
*
- * @param {string} expression The string to tokenize.
+ * @param {Object} rawToken The string to tokenize.
*
* @return {Array} An array of tokens.
*/
- Twig.expression.tokenize = function (expression) {
- var tokens = [],
- // Keep an offset of the location in the expression for error messages.
- exp_offset = 0,
- // The valid next tokens of the previous token
- next = null,
- // Match information
- type, regex, regex_array,
- // The possible next token for the match
- token_next,
- // Has a match been found from the definitions
- match_found, invalid_matches = [], match_function;
-
- match_function = function () {
- var match = Array.prototype.slice.apply(arguments),
- string = match.pop(),
- offset = match.pop();
-
- Twig.log.trace("Twig.expression.tokenize",
- "Matched a ", type, " regular expression of ", match);
-
- if (next && Twig.indexOf(next, type) < 0) {
- invalid_matches.push(
- type + " cannot follow a " + tokens[tokens.length - 1].type +
- " at template:" + exp_offset + " near '" + match[0].substring(0, 20) +
- "...'"
+ Twig.expression.tokenize = function (rawToken) {
+ let expression = rawToken.value;
+ const tokens = [];
+ // Keep an offset of the location in the expression for error messages.
+ let expOffset = 0;
+ // The valid next tokens of the previous token
+ let next = null;
+ // Match information
+ let type;
+ let regex;
+ let regexI;
+ // The possible next token for the match
+ let tokenNext;
+ // Has a match been found from the definitions
+ let matchFound;
+ let invalidMatches = [];
+
+ const matchFunction = function (...args) {
+ // Don't pass arguments to `Array.slice`, that is a performance killer
+ let matchI = arguments.length - 2;
+ const match = new Array(matchI);
+
+ while (matchI-- > 0) {
+ match[matchI] = args[matchI];
+ }
+
+ Twig.log.trace('Twig.expression.tokenize',
+ 'Matched a ', type, ' regular expression of ', match);
+
+ if (next && !next.includes(type)) {
+ invalidMatches.push(
+ type + ' cannot follow a ' + tokens[tokens.length - 1].type +
+ ' at template:' + expOffset + ' near \'' + match[0].slice(0, 20) +
+ '...\''
);
+
// Not a match, don't change the expression
return match[0];
}
+ const handler = Twig.expression.handler[type];
+
// Validate the token if a validation function is provided
- if (Twig.expression.handler[type].validate &&
- !Twig.expression.handler[type].validate(match, tokens)) {
+ if (handler.validate && !handler.validate(match, tokens)) {
return match[0];
}
- invalid_matches = [];
+ invalidMatches = [];
- tokens.push({
- type: type,
+ const token = {
+ type,
value: match[0],
- match: match
- });
+ match
+ };
+
+ if (rawToken.position) {
+ token.position = rawToken.position;
+ }
- match_found = true;
- next = token_next;
- exp_offset += match[0].length;
+ tokens.push(token);
+
+ matchFound = true;
+ next = tokenNext;
+ expOffset += match[0].length;
// Does the token need to return output back to the expression string
// e.g. a function match of cycle( might return the '(' back to the expression
// This allows look-ahead to differentiate between token types (e.g. functions and variable names)
- if (Twig.expression.handler[type].transform) {
- return Twig.expression.handler[type].transform(match, tokens);
+ if (handler.transform) {
+ return handler.transform(match, tokens);
}
+
return '';
};
- Twig.log.debug("Twig.expression.tokenize", "Tokenizing expression ", expression);
+ Twig.log.debug('Twig.expression.tokenize', 'Tokenizing expression ', expression);
while (expression.length > 0) {
expression = expression.trim();
for (type in Twig.expression.handler) {
- if (Twig.expression.handler.hasOwnProperty(type)) {
- token_next = Twig.expression.handler[type].next;
+ if (Object.hasOwnProperty.call(Twig.expression.handler, type)) {
+ tokenNext = Twig.expression.handler[type].next;
regex = Twig.expression.handler[type].regex;
- // Twig.log.trace("Checking type ", type, " on ", expression);
- if (regex instanceof Array) {
- regex_array = regex;
+ Twig.log.trace('Checking type ', type, ' on ', expression);
+
+ matchFound = false;
+
+ if (Array.isArray(regex)) {
+ regexI = regex.length;
+ while (regexI-- > 0) {
+ expression = expression.replace(regex[regexI], matchFunction);
+ }
} else {
- regex_array = [regex];
+ expression = expression.replace(regex, matchFunction);
}
- match_found = false;
- while (regex_array.length > 0) {
- regex = regex_array.pop();
- expression = expression.replace(regex, match_function);
- }
// An expression token has been matched. Break the for loop and start trying to
// match the next template (if expression isn't empty.)
- if (match_found) {
+ if (matchFound) {
break;
}
}
}
- if (!match_found) {
- if (invalid_matches.length > 0) {
- throw new Twig.Error(invalid_matches.join(" OR "));
+
+ if (!matchFound) {
+ if (invalidMatches.length > 0) {
+ throw new Twig.Error(invalidMatches.join(' OR '));
} else {
- throw new Twig.Error("Unable to parse '" + expression + "' at template position" + exp_offset);
+ throw new Twig.Error('Unable to parse \'' + expression + '\' at template position' + expOffset);
}
}
}
- Twig.log.trace("Twig.expression.tokenize", "Tokenized to ", tokens);
+ Twig.log.trace('Twig.expression.tokenize', 'Tokenized to ', tokens);
return tokens;
};
/**
* Compile an expression token.
*
- * @param {Object} raw_token The uncompiled token.
+ * @param {Object} rawToken The uncompiled token.
*
* @return {Object} The compiled token.
*/
- Twig.expression.compile = function (raw_token) {
- var expression = raw_token.value,
- // Tokenize expression
- tokens = Twig.expression.tokenize(expression),
- token = null,
- output = [],
- stack = [],
- token_template = null;
-
- Twig.log.trace("Twig.expression.compile: ", "Compiling ", expression);
-
- // Push tokens into RPN stack using the Sunting-yard algorithm
+ Twig.expression.compile = function (rawToken) {
+ // Tokenize expression
+ const tokens = Twig.expression.tokenize(rawToken);
+ let token = null;
+ const output = [];
+ const stack = [];
+ let tokenTemplate = null;
+
+ Twig.log.trace('Twig.expression.compile: ', 'Compiling ', rawToken.value);
+
+ // Push tokens into RPN stack using the Shunting-yard algorithm
// See http://en.wikipedia.org/wiki/Shunting_yard_algorithm
while (tokens.length > 0) {
token = tokens.shift();
- token_template = Twig.expression.handler[token.type];
+ tokenTemplate = Twig.expression.handler[token.type];
- Twig.log.trace("Twig.expression.compile: ", "Compiling ", token);
+ Twig.log.trace('Twig.expression.compile: ', 'Compiling ', token);
// Compile the template
- token_template.compile && token_template.compile(token, stack, output);
+ tokenTemplate.compile(token, stack, output);
- Twig.log.trace("Twig.expression.compile: ", "Stack is", stack);
- Twig.log.trace("Twig.expression.compile: ", "Output is", output);
+ Twig.log.trace('Twig.expression.compile: ', 'Stack is', stack);
+ Twig.log.trace('Twig.expression.compile: ', 'Output is', output);
}
- while(stack.length > 0) {
+ while (stack.length > 0) {
output.push(stack.pop());
}
- Twig.log.trace("Twig.expression.compile: ", "Final output is", output);
+ Twig.log.trace('Twig.expression.compile: ', 'Final output is', output);
- raw_token.stack = output;
- delete raw_token.value;
+ rawToken.stack = output;
+ delete rawToken.value;
- return raw_token;
+ return rawToken;
};
-
/**
* Parse an RPN expression stack within a context.
*
@@ -969,28 +1326,74 @@ var Twig = (function (Twig) {
* can be anything, String, Array, Object, etc... based on
* the given expression.
*/
- Twig.expression.parse = function (tokens, context) {
- var that = this;
+ Twig.expression.parse = function (tokens, context, tokensAreParameters, allowAsync) {
+ const state = this;
// If the token isn't an array, make it one.
- if (!(tokens instanceof Array)) {
+ if (!Array.isArray(tokens)) {
tokens = [tokens];
}
// The output stack
- var stack = [],
- token_template = null;
+ const stack = [];
+ const loopTokenFixups = [];
+ const binaryOperator = Twig.expression.type.operator.binary;
+
+ return Twig.async.potentiallyAsync(state, allowAsync, () => {
+ return Twig.async.forEach(tokens, (token, index) => {
+ let tokenTemplate = null;
+ let nextToken = null;
+ let result;
+
+ // If the token is marked for cleanup, we don't need to parse it
+ if (token.cleanup) {
+ return;
+ }
- Twig.forEach(tokens, function (token) {
- token_template = Twig.expression.handler[token.type];
+ // Determine the token that follows this one so that we can pass it to the parser
+ if (tokens.length > index + 1) {
+ nextToken = tokens[index + 1];
+ }
- token_template.parse && token_template.parse.apply(that, [token, stack, context]);
- });
+ tokenTemplate = Twig.expression.handler[token.type];
- // Pop the final value off the stack
- return stack.pop();
+ if (tokenTemplate.parse) {
+ result = tokenTemplate.parse.call(state, token, stack, context, nextToken);
+ }
+
+ // Store any binary tokens for later if we are in a loop.
+ if (token.type === binaryOperator && context.loop) {
+ loopTokenFixups.push(token);
+ }
+
+ return result;
+ })
+ .then(() => {
+ // Check every fixup and remove "key" as long as they still have "params". This covers the use case where
+ // a ":" operator is used in a loop with a "(expression):" statement. We need to be able to evaluate the expression
+ let len = loopTokenFixups.length;
+ let loopTokenFixup = null;
+
+ while (len-- > 0) {
+ loopTokenFixup = loopTokenFixups[len];
+ if (loopTokenFixup.params && loopTokenFixup.key) {
+ delete loopTokenFixup.key;
+ }
+ }
+
+ // If parse has been called with a set of tokens that are parameters, we need to return the whole stack,
+ // wrapped in an Array.
+ if (tokensAreParameters) {
+ const params = stack.splice(0);
+
+ stack.push(params);
+ }
+
+ // Pop the final value off the stack
+ return stack.pop();
+ });
+ });
};
return Twig;
-
-})( Twig || { } );
+};
diff --git a/src/twig.expression.operator.js b/src/twig.expression.operator.js
index dd4b51f3..027382e1 100644
--- a/src/twig.expression.operator.js
+++ b/src/twig.expression.operator.js
@@ -1,13 +1,8 @@
-// Twig.js
-// Copyright (c) 2011-2013 John Roepke
-// Available under the BSD 2-Clause License
-// https://github.com/justjohn/twig.js
-
// ## twig.expression.operator.js
//
// This file handles operator lookups and parsing.
-var Twig = (function (Twig) {
- "use strict";
+module.exports = function (Twig) {
+ 'use strict';
/**
* Operator associativity constants.
@@ -17,20 +12,24 @@ var Twig = (function (Twig) {
rightToLeft: 'rightToLeft'
};
- var containment = function(a, b) {
+ const containment = function (a, b) {
+ if (b === undefined || b === null) {
+ return null;
+ }
+
if (b.indexOf !== undefined) {
// String
- return a === b || a !== '' && b.indexOf(a) > -1;
+ return (a === b || a !== '') && b.includes(a);
+ }
- } else {
- var el;
- for (el in b) {
- if (b.hasOwnProperty(el) && b[el] === a) {
- return true;
- }
+ let el;
+ for (el in b) {
+ if (Object.hasOwnProperty.call(b, el) && b[el] === a) {
+ return true;
}
- return false;
}
+
+ return false;
};
/**
@@ -39,9 +38,7 @@ var Twig = (function (Twig) {
*/
Twig.expression.operator.lookup = function (operator, token) {
switch (operator) {
- case "..":
- case 'not in':
- case 'in':
+ case '..':
token.precidence = 20;
token.associativity = Twig.expression.operator.leftToRight;
break;
@@ -52,12 +49,19 @@ var Twig = (function (Twig) {
break;
// Ternary
+ case '?:':
case '?':
case ':':
token.precidence = 16;
token.associativity = Twig.expression.operator.rightToLeft;
break;
+ // Null-coalescing operator
+ case '??':
+ token.precidence = 15;
+ token.associativity = Twig.expression.operator.rightToLeft;
+ break;
+
case 'or':
token.precidence = 14;
token.associativity = Twig.expression.operator.leftToRight;
@@ -68,21 +72,42 @@ var Twig = (function (Twig) {
token.associativity = Twig.expression.operator.leftToRight;
break;
+ case 'b-or':
+ token.precidence = 12;
+ token.associativity = Twig.expression.operator.leftToRight;
+ break;
+
+ case 'b-xor':
+ token.precidence = 11;
+ token.associativity = Twig.expression.operator.leftToRight;
+ break;
+
+ case 'b-and':
+ token.precidence = 10;
+ token.associativity = Twig.expression.operator.leftToRight;
+ break;
+
case '==':
case '!=':
token.precidence = 9;
token.associativity = Twig.expression.operator.leftToRight;
break;
+ case '<=>':
+ token.precidence = 9;
+ token.associativity = Twig.expression.operator.leftToRight;
+ break;
+
case '<':
case '<=':
case '>':
case '>=':
+ case 'not in':
+ case 'in':
token.precidence = 8;
token.associativity = Twig.expression.operator.leftToRight;
break;
-
case '~': // String concatination
case '+':
case '-':
@@ -104,9 +129,25 @@ var Twig = (function (Twig) {
token.associativity = Twig.expression.operator.rightToLeft;
break;
+ case 'matches':
+ token.precidence = 8;
+ token.associativity = Twig.expression.operator.leftToRight;
+ break;
+
+ case 'starts with':
+ token.precidence = 8;
+ token.associativity = Twig.expression.operator.leftToRight;
+ break;
+
+ case 'ends with':
+ token.precidence = 8;
+ token.associativity = Twig.expression.operator.leftToRight;
+ break;
+
default:
- throw new Twig.Error(operator + " is an unknown operator.");
+ throw new Twig.Error('Failed to lookup operator: ' + operator + ' is an unknown operator.');
}
+
token.operator = operator;
return token;
};
@@ -117,162 +158,218 @@ var Twig = (function (Twig) {
* Returns the updated stack.
*/
Twig.expression.operator.parse = function (operator, stack) {
- Twig.log.trace("Twig.expression.operator.parse: ", "Handling ", operator);
- var a, b, c;
+ Twig.log.trace('Twig.expression.operator.parse: ', 'Handling ', operator);
+ let a;
+ let b;
+ let c;
+
+ if (operator === '?') {
+ c = stack.pop();
+ }
+
+ b = stack.pop();
+ if (operator !== 'not') {
+ a = stack.pop();
+ }
+
+ if (operator !== 'in' && operator !== 'not in' && operator !== '??') {
+ if (a && Array.isArray(a)) {
+ a = a.length;
+ }
+
+ if (operator !== '?' && (b && Array.isArray(b))) {
+ b = b.length;
+ }
+ }
+
+ if (operator === 'matches') {
+ if (b && typeof b === 'string') {
+ const reParts = b.match(/^\/(.*)\/([gims]?)$/);
+ const reBody = reParts[1];
+ const reFlags = reParts[2];
+ b = new RegExp(reBody, reFlags);
+ }
+ }
+
switch (operator) {
case ':':
// Ignore
break;
+ case '??':
+ if (a === undefined) {
+ a = b;
+ b = c;
+ c = undefined;
+ }
+
+ if (a !== undefined && a !== null) {
+ stack.push(a);
+ } else {
+ stack.push(b);
+ }
+
+ break;
+ case '?:':
+ if (Twig.lib.boolval(a)) {
+ stack.push(a);
+ } else {
+ stack.push(b);
+ }
+
+ break;
case '?':
- c = stack.pop(); // false expr
- b = stack.pop(); // true expr
- a = stack.pop(); // conditional
- if (a) {
+ if (a === undefined) {
+ // An extended ternary.
+ a = b;
+ b = c;
+ c = undefined;
+ }
+
+ if (Twig.lib.boolval(a)) {
stack.push(b);
} else {
stack.push(c);
}
+
break;
case '+':
- b = parseFloat(stack.pop());
- a = parseFloat(stack.pop());
+ b = parseFloat(b);
+ a = parseFloat(a);
stack.push(a + b);
break;
case '-':
- b = parseFloat(stack.pop());
- a = parseFloat(stack.pop());
+ b = parseFloat(b);
+ a = parseFloat(a);
stack.push(a - b);
break;
case '*':
- b = parseFloat(stack.pop());
- a = parseFloat(stack.pop());
+ b = parseFloat(b);
+ a = parseFloat(a);
stack.push(a * b);
break;
case '/':
- b = parseFloat(stack.pop());
- a = parseFloat(stack.pop());
+ b = parseFloat(b);
+ a = parseFloat(a);
stack.push(a / b);
break;
case '//':
- b = parseFloat(stack.pop());
- a = parseFloat(stack.pop());
- stack.push(parseInt(a / b));
+ b = parseFloat(b);
+ a = parseFloat(a);
+ stack.push(Math.floor(a / b));
break;
case '%':
- b = parseFloat(stack.pop());
- a = parseFloat(stack.pop());
+ b = parseFloat(b);
+ a = parseFloat(a);
stack.push(a % b);
break;
case '~':
- b = stack.pop();
- a = stack.pop();
- stack.push( (a != null ? a.toString() : "")
- + (b != null ? b.toString() : "") );
+ stack.push((typeof a !== 'undefined' && a !== null ? a.toString() : '') +
+ (typeof b !== 'undefined' && b !== null ? b.toString() : ''));
break;
case 'not':
case '!':
- stack.push(!stack.pop());
+ stack.push(!Twig.lib.boolval(b));
+ break;
+
+ case '<=>':
+ stack.push(a === b ? 0 : (a < b ? -1 : 1));
break;
case '<':
- b = stack.pop();
- a = stack.pop();
stack.push(a < b);
break;
case '<=':
- b = stack.pop();
- a = stack.pop();
stack.push(a <= b);
break;
case '>':
- b = stack.pop();
- a = stack.pop();
stack.push(a > b);
break;
case '>=':
- b = stack.pop();
- a = stack.pop();
stack.push(a >= b);
break;
case '===':
- b = stack.pop();
- a = stack.pop();
stack.push(a === b);
break;
case '==':
- b = stack.pop();
- a = stack.pop();
+ /* eslint-disable-next-line eqeqeq */
stack.push(a == b);
break;
case '!==':
- b = stack.pop();
- a = stack.pop();
stack.push(a !== b);
break;
case '!=':
- b = stack.pop();
- a = stack.pop();
+ /* eslint-disable-next-line eqeqeq */
stack.push(a != b);
break;
case 'or':
- b = stack.pop();
- a = stack.pop();
- stack.push(a || b);
+ stack.push(Twig.lib.boolval(a) || Twig.lib.boolval(b));
+ break;
+
+ case 'b-or':
+ stack.push(a | b);
+ break;
+
+ case 'b-xor':
+ stack.push(a ^ b);
break;
case 'and':
- b = stack.pop();
- a = stack.pop();
- stack.push(a && b);
+ stack.push(Twig.lib.boolval(a) && Twig.lib.boolval(b));
break;
- case '**':
- b = stack.pop();
- a = stack.pop();
- stack.push(Math.pow(a, b));
+ case 'b-and':
+ stack.push(a & b);
break;
+ case '**':
+ stack.push(a ** b);
+ break;
case 'not in':
- b = stack.pop();
- a = stack.pop();
- stack.push( !containment(a, b) );
+ stack.push(!containment(a, b));
break;
case 'in':
- b = stack.pop();
- a = stack.pop();
- stack.push( containment(a, b) );
+ stack.push(containment(a, b));
+ break;
+
+ case 'matches':
+ stack.push(b.test(a));
+ break;
+
+ case 'starts with':
+ stack.push(typeof a === 'string' && a.indexOf(b) === 0);
+ break;
+
+ case 'ends with':
+ stack.push(typeof a === 'string' && a.includes(b, a.length - b.length));
break;
case '..':
- b = stack.pop();
- a = stack.pop();
- stack.push( Twig.functions.range(a, b) );
+ stack.push(Twig.functions.range(a, b));
break;
default:
- throw new Twig.Error(operator + " is an unknown operator.");
+ throw new Twig.Error('Failed to parse operator: ' + operator + ' is an unknown operator.');
}
};
return Twig;
-
-})( Twig || { } );
+};
diff --git a/src/twig.factory.js b/src/twig.factory.js
new file mode 100644
index 00000000..b20735c2
--- /dev/null
+++ b/src/twig.factory.js
@@ -0,0 +1,28 @@
+// ## twig.factory.js
+//
+// This file handles creating the Twig library
+module.exports = function factory() {
+ const Twig = {
+ VERSION: '1.17.1'
+ };
+
+ require('./twig.core')(Twig);
+ require('./twig.compiler')(Twig);
+ require('./twig.expression')(Twig);
+ require('./twig.filters')(Twig);
+ require('./twig.functions')(Twig);
+ require('./twig.lib')(Twig);
+ require('./twig.loader.ajax')(Twig);
+ require('./twig.loader.fs')(Twig);
+ require('./twig.logic')(Twig);
+ require('./twig.parser.source')(Twig);
+ require('./twig.parser.twig')(Twig);
+ require('./twig.path')(Twig);
+ require('./twig.tests')(Twig);
+ require('./twig.async')(Twig);
+ require('./twig.exports')(Twig);
+
+ Twig.exports.factory = factory;
+
+ return Twig.exports;
+};
diff --git a/src/twig.fills.js b/src/twig.fills.js
deleted file mode 100644
index 2e3c62a7..00000000
--- a/src/twig.fills.js
+++ /dev/null
@@ -1,30 +0,0 @@
-// The following methods are from MDN and are available under a
-// [MIT License](http://www.opensource.org/licenses/mit-license.php) or are
-// [Public Domain](https://developer.mozilla.org/Project:Copyrights).
-//
-// See:
-// * [Object.keys - MDN](https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Object/keys)
-
-// ## twig.fills.js
-//
-// This file contains fills for backwards compatability.
-(function() {
- "use strict";
- // Handle methods that don't yet exist in every browser
-
- if (!String.prototype.trim) {
- String.prototype.trim = function() {
- return this.replace(/^\s+|\s+$/g,'');
- }
- };
-
- if(!Object.keys) Object.keys = function(o){
- if (o !== Object(o)) {
- throw new TypeError('Object.keys called on non-object');
- }
- var ret = [], p;
- for (p in o) if (Object.prototype.hasOwnProperty.call(o, p)) ret.push(p);
- return ret;
- }
-
-})();
diff --git a/src/twig.filters.js b/src/twig.filters.js
old mode 100755
new mode 100644
index 4ae9691a..30ad66a8
--- a/src/twig.filters.js
+++ b/src/twig.filters.js
@@ -1,191 +1,293 @@
-// Twig.js
-// Copyright (c) 2011-2013 John Roepke
-// Available under the BSD 2-Clause License
-// https://github.com/justjohn/twig.js
-
// ## twig.filters.js
//
// This file handles parsing filters.
-var Twig = (function (Twig) {
-
+module.exports = function (Twig) {
// Determine object type
function is(type, obj) {
- var clas = Object.prototype.toString.call(obj).slice(8, -1);
+ const clas = Object.prototype.toString.call(obj).slice(8, -1);
return obj !== undefined && obj !== null && clas === type;
}
Twig.filters = {
// String Filters
- upper: function(value) {
- if ( typeof value !== "string" ) {
- return value;
+ upper(value) {
+ if (typeof value !== 'string') {
+ return value;
}
return value.toUpperCase();
},
- lower: function(value) {
- if ( typeof value !== "string" ) {
- return value;
+ lower(value) {
+ if (typeof value !== 'string') {
+ return value;
}
return value.toLowerCase();
},
- capitalize: function(value) {
- if ( typeof value !== "string" ) {
- return value;
+ capitalize(value) {
+ if (typeof value !== 'string') {
+ return value;
}
- return value.substr(0, 1).toUpperCase() + value.toLowerCase().substr(1);
+ return value.slice(0, 1).toUpperCase() + value.toLowerCase().slice(1);
},
- title: function(value) {
- if ( typeof value !== "string" ) {
- return value;
+ title(value) {
+ if (typeof value !== 'string') {
+ return value;
}
- return value.toLowerCase().replace( /(^|\s)([a-z])/g , function(m, p1, p2){
+ return value.toLowerCase().replace(/(^|\s)([a-z])/g, (m, p1, p2) => {
return p1 + p2.toUpperCase();
});
},
- length: function(value) {
- if (Twig.lib.is("Array", value) || typeof value === "string") {
+ length(value) {
+ if (Twig.lib.is('Array', value) || typeof value === 'string') {
return value.length;
- } else if (Twig.lib.is("Object", value)) {
+ }
+
+ if (Twig.lib.is('Object', value)) {
if (value._keys === undefined) {
return Object.keys(value).length;
- } else {
- return value._keys.length;
}
- } else {
- return 0;
+
+ return value._keys.length;
}
+
+ return 0;
},
// Array/Object Filters
- reverse: function(value) {
- if (is("Array", value)) {
+ reverse(value) {
+ if (is('Array', value)) {
return value.reverse();
- } else if (is("String", value)) {
- return value.split("").reverse().join("");
- } else if (value instanceof Object) {
- var keys = value._keys || Object.keys(value).reverse();
+ }
+
+ if (is('String', value)) {
+ return value.split('').reverse().join('');
+ }
+
+ if (is('Object', value)) {
+ const keys = value._keys || Object.keys(value).reverse();
value._keys = keys;
return value;
}
},
- sort: function(value) {
- if (is("Array", value)) {
+ sort(value) {
+ if (is('Array', value)) {
return value.sort();
- } else if (value instanceof Object) {
+ }
+
+ if (is('Object', value)) {
// Sorting objects isn't obvious since the order of
- // returned keys isn't guaranteedin JavaScript.
+ // returned keys isn't guaranteed in JavaScript.
// Because of this we use a "hidden" key called _keys to
// store the keys in the order we want to return them.
delete value._keys;
- var keys = Object.keys(value),
- sorted_keys = keys.sort(function(a, b) {
- return value[a] > value[b];
- });
- value._keys = sorted_keys;
+ const keys = Object.keys(value);
+ const sortedKeys = keys.sort((a, b) => {
+ let a1;
+ let b1;
+
+ // If a and b are comparable, we're fine :-)
+ if ((value[a] > value[b]) === !(value[a] <= value[b])) {
+ return value[a] > value[b] ? 1 :
+ (value[a] < value[b] ? -1 : 0);
+ }
+
+ // If a and b can be parsed as numbers, we can compare
+ // their numeric value
+ if (!isNaN(a1 = parseFloat(value[a])) &&
+ !isNaN(b1 = parseFloat(value[b]))) {
+ return a1 > b1 ? 1 : (a1 < b1 ? -1 : 0);
+ }
+
+ // If one of the values is a string, we convert the
+ // other value to string as well
+ if (typeof value[a] === 'string') {
+ return value[a] > value[b].toString() ? 1 :
+ (value[a] < value[b].toString() ? -1 : 0);
+ }
+
+ if (typeof value[b] === 'string') {
+ return value[a].toString() > value[b] ? 1 :
+ (value[a].toString() < value[b] ? -1 : 0);
+ }
+ // Everything failed - return 'null' as sign, that
+ // the values are not comparable
+
+ return null;
+ });
+ value._keys = sortedKeys;
return value;
}
},
- keys: function(value) {
- if (value === undefined || value === null){
+ keys(value) {
+ if (value === undefined || value === null) {
return;
- }
+ }
+
+ const keyset = value._keys || Object.keys(value);
+ const output = [];
- var keyset = value._keys || Object.keys(value),
- output = [];
+ keyset.forEach(key => {
+ if (key === '_keys') {
+ return;
+ } // Ignore the _keys property
- Twig.forEach(keyset, function(key) {
- if (key === "_keys") return; // Ignore the _keys property
- if (value.hasOwnProperty(key)) {
+ if (Object.hasOwnProperty.call(value, key)) {
output.push(key);
}
});
return output;
},
- url_encode: function(value) {
- if (value === undefined || value === null){
+ /* eslint-disable-next-line camelcase */
+ url_encode(value) {
+ if (value === undefined || value === null) {
return;
}
- return encodeURIComponent(value);
+ if (Twig.lib.is('Object', value)) {
+ const serialize = function (obj, prefix) {
+ const result = [];
+ const keyset = obj._keys || Object.keys(obj);
+
+ keyset.forEach(key => {
+ if (!Object.prototype.hasOwnProperty.call(obj, key)) {
+ return;
+ }
+
+ const resultKey = prefix ? prefix + '[' + key + ']' : key;
+ const resultValue = obj[key];
+
+ result.push(
+ (Twig.lib.is('Object', resultValue) || Array.isArray(resultValue)) ?
+ serialize(resultValue, resultKey) :
+ encodeURIComponent(resultKey) + '=' + encodeURIComponent(resultValue)
+ );
+ });
+
+ return result.join('&');
+ };
+
+ return serialize(value);
+ }
+
+ let result = encodeURIComponent(value);
+ result = result.replace('\'', '%27');
+ return result;
},
- join: function(value, params) {
- if (value === undefined || value === null){
+ join(value, params) {
+ if (value === undefined || value === null) {
return;
}
- var join_str = "",
- output = [],
- keyset = null;
+ let joinStr = '';
+ let output = [];
+ let keyset = null;
if (params && params[0]) {
- join_str = params[0];
+ joinStr = params[0];
}
- if (value instanceof Array) {
+
+ if (is('Array', value)) {
output = value;
} else {
keyset = value._keys || Object.keys(value);
- Twig.forEach(keyset, function(key) {
- if (key === "_keys") return; // Ignore the _keys property
- if (value.hasOwnProperty(key)) {
+ keyset.forEach(key => {
+ if (key === '_keys') {
+ return;
+ } // Ignore the _keys property
+
+ if (Object.hasOwnProperty.call(value, key)) {
output.push(value[key]);
}
});
}
- return output.join(join_str);
+
+ return output.join(joinStr);
},
- "default": function(value, params) {
- if (params === undefined || params.length !== 1) {
- throw new Twig.Error("default filter expects one argument");
+ default(value, params) {
+ if (params !== undefined && params.length > 1) {
+ throw new Twig.Error('default filter expects one argument');
}
- if (value === undefined || value === null || value === '' ) {
+
+ if (value === undefined || value === null || value === '') {
+ if (params === undefined) {
+ return '';
+ }
+
return params[0];
- } else {
- return value;
}
+
+ return value;
},
- json_encode: function(value) {
- if (value && value.hasOwnProperty( "_keys" ) ) {
- delete value._keys;
+ /* eslint-disable-next-line camelcase */
+ json_encode(value) {
+ if (value === undefined || value === null) {
+ return 'null';
}
- if(value === undefined || value === null) {
- return "null";
+
+ if ((typeof value === 'object') && (is('Array', value))) {
+ const output = [];
+
+ value.forEach(v => {
+ output.push(Twig.filters.json_encode(v));
+ });
+
+ return '[' + output.join(',') + ']';
+ }
+
+ if ((typeof value === 'object') && (is('Date', value))) {
+ return '"' + value.toISOString() + '"';
+ }
+
+ if (typeof value === 'object') {
+ const keyset = value._keys || Object.keys(value);
+ const output = [];
+
+ keyset.forEach(key => {
+ output.push(JSON.stringify(key) + ':' + Twig.filters.json_encode(value[key]));
+ });
+
+ return '{' + output.join(',') + '}';
}
+
return JSON.stringify(value);
},
- merge: function(value, params) {
- var obj = [],
- arr_index = 0,
- keyset = [];
+ merge(value, params) {
+ let obj = [];
+ let arrIndex = 0;
+ let keyset = [];
// Check to see if all the objects being merged are arrays
- if (!(value instanceof Array)) {
- // Create obj as an Object
- obj = { };
- } else {
- Twig.forEach(params, function(param) {
- if (!(param instanceof Array)) {
+ if (is('Array', value)) {
+ params.forEach(param => {
+ if (!is('Array', param)) {
obj = { };
}
});
+ } else {
+ // Create obj as an Object
+ obj = { };
}
- if (!(obj instanceof Array)) {
+
+ if (!is('Array', obj)) {
obj._keys = [];
}
- if (value instanceof Array) {
- Twig.forEach(value, function(val) {
- if (obj._keys) obj._keys.push(arr_index);
- obj[arr_index] = val;
- arr_index++;
+ if (is('Array', value)) {
+ value.forEach(val => {
+ if (obj._keys) {
+ obj._keys.push(arrIndex);
+ }
+
+ obj[arrIndex] = val;
+ arrIndex++;
});
} else {
keyset = value._keys || Object.keys(value);
- Twig.forEach(keyset, function(key) {
+ keyset.forEach(key => {
obj[key] = value[key];
obj._keys.push(key);
@@ -196,219 +298,377 @@ var Twig = (function (Twig) {
// Example {{ ["a", "b"]|merge({"4":"value"}, ["c", "d"])
// Without this, d would have an index of "4" and overwrite the value
// of "value"
- var int_key = parseInt(key, 10);
- if (!isNaN(int_key) && int_key >= arr_index) {
- arr_index = int_key + 1;
+ const intKey = parseInt(key, 10);
+ if (!isNaN(intKey) && intKey >= arrIndex) {
+ arrIndex = intKey + 1;
}
});
}
- // mixin the merge arrays
- Twig.forEach(params, function(param) {
- if (param instanceof Array) {
- Twig.forEach(param, function(val) {
- if (obj._keys) obj._keys.push(arr_index);
- obj[arr_index] = val;
- arr_index++;
+ // Mixin the merge arrays
+ params.forEach(param => {
+ if (is('Array', param)) {
+ param.forEach(val => {
+ if (obj._keys) {
+ obj._keys.push(arrIndex);
+ }
+
+ obj[arrIndex] = val;
+ arrIndex++;
});
} else {
keyset = param._keys || Object.keys(param);
- Twig.forEach(keyset, function(key) {
- if (!obj[key]) obj._keys.push(key);
+ keyset.forEach(key => {
+ if (!obj[key]) {
+ obj._keys.push(key);
+ }
+
obj[key] = param[key];
- var int_key = parseInt(key, 10);
- if (!isNaN(int_key) && int_key >= arr_index) {
- arr_index = int_key + 1;
+ const intKey = parseInt(key, 10);
+ if (!isNaN(intKey) && intKey >= arrIndex) {
+ arrIndex = intKey + 1;
}
});
}
});
if (params.length === 0) {
- throw new Twig.Error("Filter merge expects at least one parameter");
+ throw new Twig.Error('Filter merge expects at least one parameter');
}
return obj;
},
- date: function(value, params) {
- if (value === undefined||value === null){
- return;
- }
- var date = Twig.functions.date(value);
- return Twig.lib.formatDate(date, params[0]);
+ date(value, params) {
+ const date = Twig.functions.date(value);
+ const format = params && Boolean(params.length) ? params[0] : 'F j, Y H:i';
+ return Twig.lib.date(format.replace(/\\\\/g, '\\'), date);
},
-
- date_modify: function(value, params) {
+ /* eslint-disable-next-line camelcase */
+ date_modify(value, params) {
if (value === undefined || value === null) {
return;
}
+
if (params === undefined || params.length !== 1) {
- throw new Twig.Error("date_modify filter expects 1 argument");
+ throw new Twig.Error('date_modify filter expects 1 argument');
}
- var modifyText = params[0], time;
+ const modifyText = params[0];
+ let time;
- if (Twig.lib.is("Date", value)) {
+ if (Twig.lib.is('Date', value)) {
time = Twig.lib.strtotime(modifyText, value.getTime() / 1000);
}
- if (Twig.lib.is("String", value)) {
+
+ if (Twig.lib.is('String', value)) {
time = Twig.lib.strtotime(modifyText, Twig.lib.strtotime(value));
}
- if (Twig.lib.is("Number", value)) {
+
+ if (Twig.lib.is('Number', value)) {
time = Twig.lib.strtotime(modifyText, value);
}
return new Date(time * 1000);
},
- replace: function(value, params) {
- if (value === undefined||value === null){
+ replace(value, params) {
+ if (value === undefined || value === null) {
return;
}
- var pairs = params[0],
- tag;
+ const pairs = params[0];
+ let tag;
for (tag in pairs) {
- if (pairs.hasOwnProperty(tag) && tag !== "_keys") {
+ if (Object.hasOwnProperty.call(pairs, tag) && tag !== '_keys') {
value = Twig.lib.replaceAll(value, tag, pairs[tag]);
}
}
+
return value;
},
- format: function(value, params) {
- if (value === undefined || value === null){
+ format(value, params) {
+ if (value === undefined || value === null) {
return;
}
return Twig.lib.vsprintf(value, params);
},
- striptags: function(value) {
- if (value === undefined || value === null){
+ striptags(value, allowed) {
+ if (value === undefined || value === null) {
return;
}
- return Twig.lib.strip_tags(value);
+ return Twig.lib.stripTags(value, allowed);
},
- escape: function(value) {
- if (value === undefined|| value === null){
+ escape(value, params) {
+ if (value === undefined || value === null || value === '') {
return;
}
- return value.toString().replace(/&/g, "&")
- .replace(//g, ">")
- .replace(/"/g, """)
- .replace(/'/g, "'");
+
+ let strategy = 'html';
+ if (params && Boolean(params.length) && params[0] !== true) {
+ strategy = params[0];
+ }
+
+ if (strategy === 'html') {
+ const rawValue = value.toString().replace(/&/g, '&')
+ .replace(//g, '>')
+ .replace(/"/g, '"')
+ .replace(/'/g, ''');
+ return new Twig.Markup(rawValue, 'html');
+ }
+
+ if (strategy === 'js') {
+ const rawValue = value.toString();
+ let result = '';
+
+ for (let i = 0; i < rawValue.length; i++) {
+ if (rawValue[i].match(/^[a-zA-Z0-9,._]$/)) {
+ result += rawValue[i];
+ } else {
+ const char = rawValue.charAt(i);
+ const charCode = rawValue.charCodeAt(i);
+
+ // A few characters have short escape sequences in JSON and JavaScript.
+ // Escape sequences supported only by JavaScript, not JSON, are ommitted.
+ // \" is also supported but omitted, because the resulting string is not HTML safe.
+ const shortMap = {
+ '\\': '\\\\',
+ '/': '\\/',
+ '\u0008': '\\b',
+ '\u000C': '\\f',
+ '\u000A': '\\n',
+ '\u000D': '\\r',
+ '\u0009': '\\t'
+ };
+
+ if (shortMap[char]) {
+ result += shortMap[char];
+ } else {
+ result += Twig.lib.sprintf('\\u%04s', charCode.toString(16).toUpperCase());
+ }
+ }
+ }
+
+ return new Twig.Markup(result, 'js');
+ }
+
+ if (strategy === 'css') {
+ const rawValue = value.toString();
+ let result = '';
+
+ for (let i = 0; i < rawValue.length; i++) {
+ if (rawValue[i].match(/^[a-zA-Z0-9]$/)) {
+ result += rawValue[i];
+ } else {
+ const charCode = rawValue.charCodeAt(i);
+ result += '\\' + charCode.toString(16).toUpperCase() + ' ';
+ }
+ }
+
+ return new Twig.Markup(result, 'css');
+ }
+
+ if (strategy === 'url') {
+ const result = Twig.filters.url_encode(value);
+ return new Twig.Markup(result, 'url');
+ }
+
+ if (strategy === 'html_attr') {
+ const rawValue = value.toString();
+ let result = '';
+
+ for (let i = 0; i < rawValue.length; i++) {
+ if (rawValue[i].match(/^[a-zA-Z0-9,.\-_]$/)) {
+ result += rawValue[i];
+ } else if (rawValue[i].match(/^[&<>"]$/)) {
+ result += rawValue[i].replace(/&/g, '&')
+ .replace(//g, '>')
+ .replace(/"/g, '"');
+ } else {
+ const charCode = rawValue.charCodeAt(i);
+
+ // The following replaces characters undefined in HTML with
+ // the hex entity for the Unicode replacement character.
+ if (charCode <= 0x1F && charCode !== 0x09 && charCode !== 0x0A && charCode !== 0x0D) {
+ result += '�';
+ } else if (charCode < 0x80) {
+ result += Twig.lib.sprintf('%02s;', charCode.toString(16).toUpperCase());
+ } else {
+ result += Twig.lib.sprintf('%04s;', charCode.toString(16).toUpperCase());
+ }
+ }
+ }
+
+ return new Twig.Markup(result, 'html_attr');
+ }
+
+ throw new Twig.Error('escape strategy unsupported');
},
/* Alias of escape */
- "e": function(value) {
- return Twig.filters.escape(value);
+ e(value, params) {
+ return Twig.filters.escape(value, params);
},
- nl2br: function(value) {
- if (value === undefined || value === null){
+ nl2br(value) {
+ if (value === undefined || value === null || value === '') {
return;
}
- var linebreak_tag = "BACKSLASH_n_replace",
- br = " " + linebreak_tag;
+
+ const linebreakTag = 'BACKSLASH_n_replace';
+ const br = ' ' + linebreakTag;
value = Twig.filters.escape(value)
- .replace(/\r\n/g, br)
- .replace(/\r/g, br)
- .replace(/\n/g, br);
+ .replace(/\r\n/g, br)
+ .replace(/\r/g, br)
+ .replace(/\n/g, br);
- return Twig.lib.replaceAll(value, linebreak_tag, "\n");
+ value = Twig.lib.replaceAll(value, linebreakTag, '\n');
+
+ return new Twig.Markup(value);
},
/**
* Adapted from: http://phpjs.org/functions/number_format:481
*/
- number_format: function(value, params) {
- var number = value,
- decimals = (params && params[0]) ? params[0] : undefined,
- dec = (params && params[1] !== undefined) ? params[1] : ".",
- sep = (params && params[2] !== undefined) ? params[2] : ",";
-
- number = (number + '').replace(/[^0-9+\-Ee.]/g, '');
- var n = !isFinite(+number) ? 0 : +number,
- prec = !isFinite(+decimals) ? 0 : Math.abs(decimals),
- s = '',
- toFixedFix = function (n, prec) {
- var k = Math.pow(10, prec);
- return '' + Math.round(n * k) / k;
- };
+ /* eslint-disable-next-line camelcase */
+ number_format(value, params) {
+ let number = value;
+ const decimals = (params && params[0]) ? params[0] : undefined;
+ const dec = (params && params[1] !== undefined) ? params[1] : '.';
+ const sep = (params && params[2] !== undefined) ? params[2] : ',';
+
+ number = (String(number)).replace(/[^0-9+\-Ee.]/g, '');
+ const n = isFinite(Number(number)) ? Number(number) : 0;
+ const prec = isFinite(Number(decimals)) ? Math.abs(decimals) : 0;
+ let s = '';
+ const toFixedFix = function (n, prec) {
+ const k = 10 ** prec;
+ return String(Math.round(n * k) / k);
+ };
+
// Fix for IE parseFloat(0.55).toFixed(0) = 0;
- s = (prec ? toFixedFix(n, prec) : '' + Math.round(n)).split('.');
+ s = (prec ? toFixedFix(n, prec) : String(Math.round(n))).split('.');
if (s[0].length > 3) {
s[0] = s[0].replace(/\B(?=(?:\d{3})+(?!\d))/g, sep);
}
+
if ((s[1] || '').length < prec) {
s[1] = s[1] || '';
s[1] += new Array(prec - s[1].length + 1).join('0');
}
+
return s.join(dec);
},
- trim: function(value, params) {
- if (value === undefined|| value === null){
+ trim(value, params) {
+ if (value === undefined || value === null) {
return;
}
- var str = Twig.filters.escape( '' + value ),
- whitespace;
- if ( params && params[0] ) {
- whitespace = '' + params[0];
+ let str = String(value);
+ let whitespace;
+ if (params && params[0]) {
+ whitespace = String(params[0]);
} else {
- whitespace = ' \n\r\t\f\x0b\xa0\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u200b\u2028\u2029\u3000';
+ whitespace = ' \n\r\t\f\u000B\u00A0\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u200b\u2028\u2029\u3000';
}
- for (var i = 0; i < str.length; i++) {
- if (whitespace.indexOf(str.charAt(i)) === -1) {
- str = str.substring(i);
+
+ for (let i = 0; i < str.length; i++) {
+ if (!whitespace.includes(str.charAt(i))) {
+ str = str.slice(Math.max(0, i));
break;
}
}
- for (i = str.length - 1; i >= 0; i--) {
- if (whitespace.indexOf(str.charAt(i)) === -1) {
- str = str.substring(0, i + 1);
+
+ for (let i = str.length - 1; i >= 0; i--) {
+ if (!whitespace.includes(str.charAt(i))) {
+ str = str.slice(0, Math.max(0, i + 1));
break;
}
}
- return whitespace.indexOf(str.charAt(0)) === -1 ? str : '';
+
+ return whitespace.includes(str.charAt(0)) ? '' : str;
+ },
+
+ truncate(value, params) {
+ let length = 30;
+ let preserve = false;
+ let separator = '...';
+
+ value = String(value);
+ if (params) {
+ if (params[0]) {
+ length = params[0];
+ }
+
+ if (params[1]) {
+ preserve = params[1];
+ }
+
+ if (params[2]) {
+ separator = params[2];
+ }
+ }
+
+ if (value.length > length) {
+ if (preserve) {
+ length = value.indexOf(' ', length);
+ if (length === -1) {
+ return value;
+ }
+ }
+
+ value = value.slice(0, length) + separator;
+ }
+
+ return value;
},
- slice: function(value, params) {
+ slice(value, params) {
if (value === undefined || value === null) {
return;
}
- if (params === undefined || params.length < 1) {
- throw new Twig.Error("slice filter expects at least 1 argument");
+
+ if (params === undefined || params.length === 0) {
+ throw new Twig.Error('slice filter expects at least 1 argument');
}
- // default to start of string
- var start = params[0] || 0;
- // default to length of string
- var length = params.length > 1 ? params[1] : value.length;
- // handle negative start values
- var startIndex = start >= 0 ? start : Math.max( value.length + start, 0 );
+ // Default to start of string
+ const start = params[0] || 0;
+ // Default to length of string
+ let length = params.length > 1 ? params[1] : value.length;
+ // Handle negative start values
+ const startIndex = start >= 0 ? start : Math.max(value.length + start, 0);
+ // Handle negative length values
+ if (length < 0) {
+ length = value.length - startIndex + length;
+ }
- if (Twig.lib.is("Array", value)) {
- var output = [];
- for (var i = startIndex; i < startIndex + length && i < value.length; i++) {
+ if (Twig.lib.is('Array', value)) {
+ const output = [];
+ for (let i = startIndex; i < startIndex + length && i < value.length; i++) {
output.push(value[i]);
}
+
return output;
- } else if (Twig.lib.is("String", value)) {
- return value.substr(startIndex, length);
- } else {
- throw new Twig.Error("slice filter expects value to be an array or string");
}
+
+ if (Twig.lib.is('String', value)) {
+ return value.slice(startIndex, startIndex + length);
+ }
+
+ throw new Twig.Error('slice filter expects value to be an array or string');
},
- abs: function(value) {
+ abs(value) {
if (value === undefined || value === null) {
return;
}
@@ -416,81 +676,79 @@ var Twig = (function (Twig) {
return Math.abs(value);
},
- first: function(value) {
- if (value instanceof Array) {
+ first(value) {
+ if (is('Array', value)) {
return value[0];
- } else if (value instanceof Object) {
+ }
+
+ if (is('Object', value)) {
if ('_keys' in value) {
return value[value._keys[0]];
}
- } else if ( typeof value === "string" ) {
- return value.substr(0, 1);
+ } else if (typeof value === 'string') {
+ return value.slice(0, 1);
}
-
- return;
},
- split: function(value, params) {
+ split(value, params) {
if (value === undefined || value === null) {
return;
}
- if (params === undefined || params.length < 1 || params.length > 2) {
- throw new Twig.Error("split filter expects 1 or 2 argument");
+
+ if (params === undefined || params.length === 0 || params.length > 2) {
+ throw new Twig.Error('split filter expects 1 or 2 argument');
}
- if (Twig.lib.is("String", value)) {
- var delimiter = params[0],
- limit = params[1],
- split = value.split(delimiter);
- if (limit === undefined) {
+ if (Twig.lib.is('String', value)) {
+ const delimiter = params[0];
+ const limit = params[1];
+ const split = value.split(delimiter);
+ if (limit === undefined) {
return split;
+ }
- } else if (limit < 0) {
-
+ if (limit < 0) {
return value.split(delimiter, split.length + limit);
+ }
- } else {
-
- var limitedSplit = [];
+ const limitedSplit = [];
- if (delimiter == '') {
- // empty delimiter
- // "aabbcc"|split('', 2)
- // -> ['aa', 'bb', 'cc']
+ if (delimiter === '') {
+ // Empty delimiter
+ // "aabbcc"|split('', 2)
+ // -> ['aa', 'bb', 'cc']
- while(split.length > 0) {
- var temp = "";
- for (var i=0; i 0; i++) {
- temp += split.shift();
- }
- limitedSplit.push(temp);
+ while (split.length > 0) {
+ let temp = '';
+ for (let i = 0; i < limit && split.length > 0; i++) {
+ temp += split.shift();
}
- } else {
- // non-empty delimiter
- // "one,two,three,four,five"|split(',', 3)
- // -> ['one', 'two', 'three,four,five']
-
- for (var i=0; i 0; i++) {
- limitedSplit.push(split.shift());
- }
+ limitedSplit.push(temp);
+ }
+ } else {
+ // Non-empty delimiter
+ // "one,two,three,four,five"|split(',', 3)
+ // -> ['one', 'two', 'three,four,five']
- if (split.length > 0) {
- limitedSplit.push(split.join(delimiter));
- }
+ for (let i = 0; i < limit - 1 && split.length > 0; i++) {
+ limitedSplit.push(split.shift());
}
- return limitedSplit;
+ if (split.length > 0) {
+ limitedSplit.push(split.join(delimiter));
+ }
}
- } else {
- throw new Twig.Error("split filter expects value to be a string");
+ return limitedSplit;
}
+
+ throw new Twig.Error('split filter expects value to be a string');
},
- last: function(value) {
+ last(value) {
if (Twig.lib.is('Object', value)) {
- var keys;
+ let keys;
if (value._keys === undefined) {
keys = Object.keys(value);
@@ -501,33 +759,35 @@ var Twig = (function (Twig) {
return value[keys[keys.length - 1]];
}
- // string|array
+ if (Twig.lib.is('Number', value)) {
+ return value.toString().slice(-1);
+ }
+
+ // String|array
return value[value.length - 1];
},
- raw: function(value) {
- //Raw filter shim
- return value;
+ raw(value) {
+ return new Twig.Markup(value || '');
},
- batch: function(items, params) {
- var size = params.shift(),
- fill = params.shift(),
- result,
- last,
- missing;
+ batch(items, params) {
+ let size = params.shift();
+ const fill = params.shift();
+ let last;
+ let missing;
- if (!Twig.lib.is("Array", items)) {
- throw new Twig.Error("batch filter expects items to be an array");
+ if (!Twig.lib.is('Array', items)) {
+ throw new Twig.Error('batch filter expects items to be an array');
}
- if (!Twig.lib.is("Number", size)) {
- throw new Twig.Error("batch filter expects size to be a number");
+ if (!Twig.lib.is('Number', size)) {
+ throw new Twig.Error('batch filter expects size to be a number');
}
size = Math.ceil(size);
- result = Twig.lib.chunkArray(items, size);
+ const result = Twig.lib.chunkArray(items, size);
- if (fill && items.length % size != 0) {
+ if (fill && items.length % size !== 0) {
last = result.pop();
missing = size - last.length;
@@ -540,41 +800,46 @@ var Twig = (function (Twig) {
return result;
},
- round: function(value, params) {
+ round(value, params) {
params = params || [];
- var precision = params.length > 0 ? params[0] : 0,
- method = params.length > 1 ? params[1] : "common";
+ const precision = params.length > 0 ? params[0] : 0;
+ const method = params.length > 1 ? params[1] : 'common';
value = parseFloat(value);
- if(precision && !Twig.lib.is("Number", precision)) {
- throw new Twig.Error("round filter expects precision to be a number");
+ if (precision && !Twig.lib.is('Number', precision)) {
+ throw new Twig.Error('round filter expects precision to be a number');
}
- if (method === "common") {
+ if (method === 'common') {
return Twig.lib.round(value, precision);
}
- if(!Twig.lib.is("Function", Math[method])) {
- throw new Twig.Error("round filter expects method to be 'floor', 'ceil', or 'common'");
+ if (!Twig.lib.is('Function', Math[method])) {
+ throw new Twig.Error('round filter expects method to be \'floor\', \'ceil\', or \'common\'');
}
- return Math[method](value * Math.pow(10, precision)) / Math.pow(10, precision);
+ return Math[method](value * (10 ** precision)) / (10 ** precision);
+ },
+ spaceless(value) {
+ return value.replace(/>\s+<').trim();
}
};
- Twig.filter = function(filter, value, params) {
+ Twig.filter = function (filter, value, params) {
+ const state = this;
+
if (!Twig.filters[filter]) {
- throw "Unable to find filter " + filter;
+ throw new Twig.Error('Unable to find filter ' + filter);
}
- return Twig.filters[filter].apply(this, [value, params]);
+
+ return Twig.filters[filter].call(state, value, params);
};
- Twig.filter.extend = function(filter, definition) {
+ Twig.filter.extend = function (filter, definition) {
Twig.filters[filter] = definition;
};
return Twig;
-
-})(Twig || { });
+};
diff --git a/src/twig.functions.js b/src/twig.functions.js
index 8cfa277f..aab5d7fe 100644
--- a/src/twig.functions.js
+++ b/src/twig.functions.js
@@ -1,26 +1,19 @@
-// Twig.js
-// Copyright (c) 2011-2013 John Roepke
-// 2012 Hadrien Lanneau
-// Available under the BSD 2-Clause License
-// https://github.com/justjohn/twig.js
-
// ## twig.functions.js
//
// This file handles parsing filters.
-var Twig = (function (Twig) {
-
- // Determine object type
- function is(type, obj) {
- var clas = Object.prototype.toString.call(obj).slice(8, -1);
- return obj !== undefined && obj !== null && clas === type;
- }
+module.exports = function (Twig) {
+ /**
+ * @constant
+ * @type {string}
+ */
+ const TEMPLATE_NOT_FOUND_MESSAGE = 'Template "{name}" is not defined.';
Twig.functions = {
- // attribute, block, constant, date, dump, parent, random,.
+ // Attribute, block, constant, date, dump, parent, random,.
// Range function from http://phpjs.org/functions/range:499
// Used under an MIT License
- range: function (low, high, step) {
+ range(low, high, step) {
// http://kevin.vanzonneveld.net
// + original by: Waldo Malqui Silva
// * example 1: range ( 0, 12 );
@@ -31,10 +24,11 @@ var Twig = (function (Twig) {
// * returns 3: ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i']
// * example 4: range( 'c', 'a' );
// * returns 4: ['c', 'b', 'a']
- var matrix = [];
- var inival, endval, plus;
- var walker = step || 1;
- var chars = false;
+ const matrix = [];
+ let inival;
+ let endval;
+ const walker = step || 1;
+ let chars = false;
if (!isNaN(low) && !isNaN(high)) {
inival = parseInt(low, 10);
@@ -48,7 +42,7 @@ var Twig = (function (Twig) {
endval = (isNaN(high) ? 0 : high);
}
- plus = ((inival > endval) ? false : true);
+ const plus = (!((inival > endval)));
if (plus) {
while (inival <= endval) {
matrix.push(((chars) ? String.fromCharCode(inival) : inival));
@@ -63,126 +57,281 @@ var Twig = (function (Twig) {
return matrix;
},
- cycle: function(arr, i) {
- var pos = i % arr.length;
+ cycle(arr, i) {
+ const pos = i % arr.length;
return arr[pos];
},
- dump: function() {
- var EOL = '\n',
- indentChar = ' ',
- indentTimes = 0,
- out = '',
- args = Array.prototype.slice.call(arguments),
- indent = function(times) {
- var ind = '';
- while (times > 0) {
- times--;
- ind += indentChar;
- }
- return ind;
- },
- displayVar = function(variable) {
- out += indent(indentTimes);
- if (typeof(variable) === 'object') {
- dumpVar(variable);
- } else if (typeof(variable) === 'function') {
- out += 'function()' + EOL;
- } else if (typeof(variable) === 'string') {
- out += 'string(' + variable.length + ') "' + variable + '"' + EOL;
- } else if (typeof(variable) === 'number') {
- out += 'number(' + variable + ')' + EOL;
- } else if (typeof(variable) === 'boolean') {
- out += 'bool(' + variable + ')' + EOL;
+ dump(...args) {
+ // Don't pass arguments to `Array.slice`, that is a performance killer
+
+ const argsCopy = [...args];
+ const state = this;
+
+ const EOL = '\n';
+ const indentChar = ' ';
+ let indentTimes = 0;
+ let out = '';
+ const indent = function (times) {
+ let ind = '';
+ while (times > 0) {
+ times--;
+ ind += indentChar;
+ }
+
+ return ind;
+ };
+
+ const displayVar = function (variable) {
+ out += indent(indentTimes);
+ if (typeof (variable) === 'object') {
+ dumpVar(variable);
+ } else if (typeof (variable) === 'function') {
+ out += 'function()' + EOL;
+ } else if (typeof (variable) === 'string') {
+ out += 'string(' + variable.length + ') "' + variable + '"' + EOL;
+ } else if (typeof (variable) === 'number') {
+ out += 'number(' + variable + ')' + EOL;
+ } else if (typeof (variable) === 'boolean') {
+ out += 'bool(' + variable + ')' + EOL;
+ }
+ };
+
+ const dumpVar = function (variable) {
+ let i;
+ if (variable === null) {
+ out += 'NULL' + EOL;
+ } else if (variable === undefined) {
+ out += 'undefined' + EOL;
+ } else if (typeof variable === 'object') {
+ out += indent(indentTimes) + typeof (variable);
+ indentTimes++;
+ out += '(' + (function (obj) {
+ let size = 0;
+ let key;
+ for (key in obj) {
+ if (Object.hasOwnProperty.call(obj, key)) {
+ size++;
+ }
+ }
+
+ return size;
+ })(variable) + ') {' + EOL;
+ for (i in variable) {
+ if (Object.hasOwnProperty.call(variable, i)) {
+ out += indent(indentTimes) + '[' + i + ']=> ' + EOL;
+ displayVar(variable[i]);
+ }
}
- },
- dumpVar = function(variable) {
- var i;
- if (variable === null) {
- out += 'NULL' + EOL;
- } else if (variable === undefined) {
- out += 'undefined' + EOL;
- } else if (typeof variable === 'object') {
- out += indent(indentTimes) + typeof(variable);
- indentTimes++;
- out += '(' + (function(obj) {
- var size = 0, key;
- for (key in obj) {
- if (obj.hasOwnProperty(key)) {
- size++;
- }
- }
- return size;
- })(variable) + ') {' + EOL;
- for (i in variable) {
- out += indent(indentTimes) + '[' + i + ']=> ' + EOL;
- displayVar(variable[i]);
- }
- indentTimes--;
- out += indent(indentTimes) + '}' + EOL;
- } else {
- displayVar(variable);
- }
- };
-
- // handle no argument case by dumping the entire render context
- if (args.length == 0) args.push(this.context);
-
- Twig.forEach(args, function(variable) {
- dumpVar(variable);
- });
+
+ indentTimes--;
+ out += indent(indentTimes) + '}' + EOL;
+ } else {
+ displayVar(variable);
+ }
+ };
+
+ // Handle no argument case by dumping the entire render context
+ if (argsCopy.length === 0) {
+ argsCopy.push(state.context);
+ }
+
+ argsCopy.forEach(variable => {
+ dumpVar(variable);
+ });
return out;
},
- date: function(date, time) {
- var dateObj;
- if (date === undefined) {
+ date(date) {
+ let dateObj;
+ if (date === undefined || date === null || date === '') {
dateObj = new Date();
- } else if (Twig.lib.is("Date", date)) {
+ } else if (Twig.lib.is('Date', date)) {
dateObj = date;
- } else if (Twig.lib.is("String", date)) {
- dateObj = new Date(Twig.lib.strtotime(date) * 1000);
- } else if (Twig.lib.is("Number", date)) {
- // timestamp
+ } else if (Twig.lib.is('String', date)) {
+ if (date.match(/^\d+$/)) {
+ dateObj = new Date(date * 1000);
+ } else {
+ dateObj = new Date(Twig.lib.strtotime(date) * 1000);
+ }
+ } else if (Twig.lib.is('Number', date)) {
+ // Timestamp
dateObj = new Date(date * 1000);
} else {
- throw new Twig.Error("Unable to parse date " + date);
+ throw new Twig.Error('Unable to parse date ' + date);
}
+
return dateObj;
},
- block: function(block) {
- return this.blocks[block];
+ block(blockName) {
+ const state = this;
+
+ const block = state.getBlock(blockName);
+
+ if (block !== undefined) {
+ return block.render(state, state.context);
+ }
},
- parent: function() {
- // Add a placeholder
- return Twig.placeholders.parent;
+ parent() {
+ const state = this;
+
+ return state.getBlock(state.getNestingStackToken(Twig.logic.type.block).blockName, true).render(state, state.context);
},
- attribute: function(object, method, params) {
- if (object instanceof Object) {
- if (object.hasOwnProperty(method)) {
- if (typeof object[method] === "function") {
+ attribute(object, method, params) {
+ if (Twig.lib.is('Object', object)) {
+ if (Object.hasOwnProperty.call(object, method)) {
+ if (typeof object[method] === 'function') {
return object[method].apply(undefined, params);
}
- else {
- return object[method];
- }
+
+ return object[method];
}
}
+
// Array will return element 0-index
- return object[method] || undefined;
+ return object ? (object[method] || undefined) : undefined;
+ },
+ max(values, ...args) {
+ if (Twig.lib.is('Object', values)) {
+ delete values._keys;
+ return Twig.lib.max(values);
+ }
+
+ return Reflect.apply(Twig.lib.max, null, [values, ...args]);
+ },
+ min(values, ...args) {
+ if (Twig.lib.is('Object', values)) {
+ delete values._keys;
+ return Twig.lib.min(values);
+ }
+
+ return Reflect.apply(Twig.lib.min, null, [values, ...args]);
+ },
+ /* eslint-disable-next-line camelcase */
+ template_from_string(template) {
+ const state = this;
+
+ if (template === undefined) {
+ template = '';
+ }
+
+ return Twig.Templates.parsers.twig({
+ options: state.template.options,
+ data: template
+ });
+ },
+ random(value) {
+ const LIMIT_INT31 = 0x80000000;
+
+ function getRandomNumber(n) {
+ const random = Math.floor(Math.random() * LIMIT_INT31);
+ const min = Math.min.call(null, 0, n);
+ const max = Math.max.call(null, 0, n);
+ return min + Math.floor((max - min + 1) * random / LIMIT_INT31);
+ }
+
+ if (Twig.lib.is('Number', value)) {
+ return getRandomNumber(value);
+ }
+
+ if (Twig.lib.is('String', value)) {
+ return value.charAt(getRandomNumber(value.length - 1));
+ }
+
+ if (Twig.lib.is('Array', value)) {
+ return value[getRandomNumber(value.length - 1)];
+ }
+
+ if (Twig.lib.is('Object', value)) {
+ const keys = Object.keys(value);
+ return value[keys[getRandomNumber(keys.length - 1)]];
+ }
+
+ return getRandomNumber(LIMIT_INT31 - 1);
+ },
+
+ /**
+ * Returns the content of a template without rendering it
+ * @param {string} name
+ * @param {boolean} [ignoreMissing=false]
+ * @returns {string}
+ */
+ source(name, ignoreMissing) {
+ const state = this;
+ const {namespaces} = state.template.options;
+ let templateSource;
+ let templateFound = false;
+ const isNodeEnvironment = typeof module !== 'undefined' && typeof module.exports !== 'undefined' && typeof window === 'undefined';
+ let loader;
+ let path = name;
+
+ if (namespaces && typeof namespaces === 'object') {
+ path = Twig.path.expandNamespace(namespaces, path);
+ }
+
+ // If we are running in a node.js environment, set the loader to 'fs'.
+ if (isNodeEnvironment) {
+ loader = 'fs';
+ } else {
+ loader = 'ajax';
+ }
+
+ // Build the params object
+ const params = {
+ id: name,
+ path,
+ method: loader,
+ parser: 'source',
+ async: false,
+ fetchTemplateSource: true
+ };
+
+ // Default ignoreMissing to false
+ if (typeof ignoreMissing === 'undefined') {
+ ignoreMissing = false;
+ }
+
+ // Try to load the remote template
+ //
+ // on exception, log it
+ try {
+ templateSource = Twig.Templates.loadRemote(name, params);
+
+ // If the template is undefined or null, set the template to an empty string and do NOT flip the
+ // boolean indicating we found the template
+ //
+ // else, all is good! flip the boolean indicating we found the template
+ if (typeof templateSource === 'undefined' || templateSource === null) {
+ templateSource = '';
+ } else {
+ templateFound = true;
+ }
+ } catch (error) {
+ Twig.log.debug('Twig.functions.source: ', 'Problem loading template ', error);
+ }
+
+ // If the template was NOT found AND we are not ignoring missing templates, return the same message
+ // that is returned by the PHP implementation of the twig source() function
+ //
+ // else, return the template source
+ if (!templateFound && !ignoreMissing) {
+ return TEMPLATE_NOT_FOUND_MESSAGE.replace('{name}', name);
+ }
+
+ return templateSource;
}
};
- Twig._function = function(_function, value, params) {
+ Twig._function = function (_function, value, params) {
if (!Twig.functions[_function]) {
- throw "Unable to find function " + _function;
+ throw new Twig.Error('Unable to find function ' + _function);
}
+
return Twig.functions[_function](value, params);
};
- Twig._function.extend = function(_function, definition) {
+ Twig._function.extend = function (_function, definition) {
Twig.functions[_function] = definition;
};
return Twig;
-
-})(Twig || { });
+};
diff --git a/src/twig.header.js b/src/twig.header.js
deleted file mode 100644
index 1f3a6949..00000000
--- a/src/twig.header.js
+++ /dev/null
@@ -1,14 +0,0 @@
-/**
- * Twig.js 0.7.2
- *
- * @copyright 2011-2013 John Roepke
- * @license Available under the BSD 2-Clause License
- * @link https://github.com/justjohn/twig.js
- */
-
-var Twig = (function (Twig) {
-
- Twig.VERSION = "0.7.2";
-
- return Twig;
-})(Twig || {});
diff --git a/src/twig.js b/src/twig.js
new file mode 100644
index 00000000..6db79670
--- /dev/null
+++ b/src/twig.js
@@ -0,0 +1,9 @@
+/**
+ * Twig.js
+ *
+ * @copyright 2011-2020 John Roepke and the Twig.js Contributors
+ * @license Available under the BSD 2-Clause License
+ * @link https://github.com/twigjs/twig.js
+ */
+
+module.exports = require('./twig.factory')();
diff --git a/src/twig.lib.js b/src/twig.lib.js
old mode 100755
new mode 100644
index 3921be51..41d93ee9
--- a/src/twig.lib.js
+++ b/src/twig.lib.js
@@ -6,619 +6,58 @@
// LICENSES.md file.
//
-var Twig = (function(Twig) {
-
+module.exports = function (Twig) {
// Namespace for libraries
Twig.lib = { };
- /**
- sprintf() for JavaScript 0.7-beta1
- http://www.diveintojavascript.com/projects/javascript-sprintf
- **/
- var sprintf = (function() {
- function get_type(variable) {
- return Object.prototype.toString.call(variable).slice(8, -1).toLowerCase();
- }
- function str_repeat(input, multiplier) {
- for (var output = []; multiplier > 0; output[--multiplier] = input) {/* do nothing */}
- return output.join('');
- }
-
- var str_format = function() {
- if (!str_format.cache.hasOwnProperty(arguments[0])) {
- str_format.cache[arguments[0]] = str_format.parse(arguments[0]);
- }
- return str_format.format.call(null, str_format.cache[arguments[0]], arguments);
- };
-
- str_format.format = function(parse_tree, argv) {
- var cursor = 1, tree_length = parse_tree.length, node_type = '', arg, output = [], i, k, match, pad, pad_character, pad_length;
- for (i = 0; i < tree_length; i++) {
- node_type = get_type(parse_tree[i]);
- if (node_type === 'string') {
- output.push(parse_tree[i]);
- }
- else if (node_type === 'array') {
- match = parse_tree[i]; // convenience purposes only
- if (match[2]) { // keyword argument
- arg = argv[cursor];
- for (k = 0; k < match[2].length; k++) {
- if (!arg.hasOwnProperty(match[2][k])) {
- throw(sprintf('[sprintf] property "%s" does not exist', match[2][k]));
- }
- arg = arg[match[2][k]];
- }
- }
- else if (match[1]) { // positional argument (explicit)
- arg = argv[match[1]];
- }
- else { // positional argument (implicit)
- arg = argv[cursor++];
- }
-
- if (/[^s]/.test(match[8]) && (get_type(arg) != 'number')) {
- throw(sprintf('[sprintf] expecting number but found %s', get_type(arg)));
- }
- switch (match[8]) {
- case 'b': arg = arg.toString(2); break;
- case 'c': arg = String.fromCharCode(arg); break;
- case 'd': arg = parseInt(arg, 10); break;
- case 'e': arg = match[7] ? arg.toExponential(match[7]) : arg.toExponential(); break;
- case 'f': arg = match[7] ? parseFloat(arg).toFixed(match[7]) : parseFloat(arg); break;
- case 'o': arg = arg.toString(8); break;
- case 's': arg = ((arg = String(arg)) && match[7] ? arg.substring(0, match[7]) : arg); break;
- case 'u': arg = Math.abs(arg); break;
- case 'x': arg = arg.toString(16); break;
- case 'X': arg = arg.toString(16).toUpperCase(); break;
- }
- arg = (/[def]/.test(match[8]) && match[3] && arg >= 0 ? '+'+ arg : arg);
- pad_character = match[4] ? match[4] == '0' ? '0' : match[4].charAt(1) : ' ';
- pad_length = match[6] - String(arg).length;
- pad = match[6] ? str_repeat(pad_character, pad_length) : '';
- output.push(match[5] ? arg + pad : pad + arg);
- }
- }
- return output.join('');
- };
-
- str_format.cache = {};
-
- str_format.parse = function(fmt) {
- var _fmt = fmt, match = [], parse_tree = [], arg_names = 0;
- while (_fmt) {
- if ((match = /^[^\x25]+/.exec(_fmt)) !== null) {
- parse_tree.push(match[0]);
- }
- else if ((match = /^\x25{2}/.exec(_fmt)) !== null) {
- parse_tree.push('%');
- }
- else if ((match = /^\x25(?:([1-9]\d*)\$|\(([^\)]+)\))?(\+)?(0|'[^$])?(-)?(\d+)?(?:\.(\d+))?([b-fosuxX])/.exec(_fmt)) !== null) {
- if (match[2]) {
- arg_names |= 1;
- var field_list = [], replacement_field = match[2], field_match = [];
- if ((field_match = /^([a-z_][a-z_\d]*)/i.exec(replacement_field)) !== null) {
- field_list.push(field_match[1]);
- while ((replacement_field = replacement_field.substring(field_match[0].length)) !== '') {
- if ((field_match = /^\.([a-z_][a-z_\d]*)/i.exec(replacement_field)) !== null) {
- field_list.push(field_match[1]);
- }
- else if ((field_match = /^\[(\d+)\]/.exec(replacement_field)) !== null) {
- field_list.push(field_match[1]);
- }
- else {
- throw('[sprintf] huh?');
- }
- }
- }
- else {
- throw('[sprintf] huh?');
- }
- match[2] = field_list;
- }
- else {
- arg_names |= 2;
- }
- if (arg_names === 3) {
- throw('[sprintf] mixing positional and named placeholders is not (yet) supported');
- }
- parse_tree.push(match);
- }
- else {
- throw('[sprintf] huh?');
- }
- _fmt = _fmt.substring(match[0].length);
- }
- return parse_tree;
- };
-
- return str_format;
- })();
-
- var vsprintf = function(fmt, argv) {
- argv.unshift(fmt);
- return sprintf.apply(null, argv);
- };
-
- // Expose to Twig
- Twig.lib.sprintf = sprintf;
- Twig.lib.vsprintf = vsprintf;
-
-
- /**
- * jPaq - A fully customizable JavaScript/JScript library
- * http://jpaq.org/
- *
- * Copyright (c) 2011 Christopher West
- * Licensed under the MIT license.
- * http://jpaq.org/license/
- *
- * Version: 1.0.6.0000W
- * Revised: April 6, 2011
- */
- ; (function() {
- var shortDays = "Sun,Mon,Tue,Wed,Thu,Fri,Sat".split(",");
- var fullDays = "Sunday,Monday,Tuesday,Wednesday,Thursday,Friday,Saturday".split(",");
- var shortMonths = "Jan,Feb,Mar,Apr,May,Jun,Jul,Aug,Sep,Oct,Nov,Dec".split(",");
- var fullMonths = "January,February,March,April,May,June,July,August,September,October,November,December".split(",");
- function getOrdinalFor(intNum) {
- return (((intNum = Math.abs(intNum) % 100) % 10 == 1 && intNum != 11) ? "st"
- : (intNum % 10 == 2 && intNum != 12) ? "nd" : (intNum % 10 == 3
- && intNum != 13) ? "rd" : "th");
- }
- function getISO8601Year(aDate) {
- var d = new Date(aDate.getFullYear() + 1, 0, 4);
- if((d - aDate) / 86400000 < 7 && (aDate.getDay() + 6) % 7 < (d.getDay() + 6) % 7)
- return d.getFullYear();
- if(aDate.getMonth() > 0 || aDate.getDate() >= 4)
- return aDate.getFullYear();
- return aDate.getFullYear() - (((aDate.getDay() + 6) % 7 - aDate.getDate() > 2) ? 1 : 0);
- }
- function getISO8601Week(aDate) {
- // Get a day during the first week of the year.
- var d = new Date(getISO8601Year(aDate), 0, 4);
- // Get the first monday of the year.
- d.setDate(d.getDate() - (d.getDay() + 6) % 7);
- return parseInt((aDate - d) / 604800000) + 1;
- }
- Twig.lib.formatDate = function(date, format) {
- ///
- /// Gets a string for this date, formatted according to the given format
- /// string.
- ///
- ///
- /// The format of the output date string. The format string works in a
- /// nearly identical way to the PHP date function which is highlighted here:
- /// http://php.net/manual/en/function.date.php.
- /// The only difference is the fact that "u" signifies milliseconds
- /// instead of microseconds. The following characters are recognized in
- /// the format parameter string:
- /// d - Day of the month, 2 digits with leading zeros
- /// D - A textual representation of a day, three letters
- /// j - Day of the month without leading zeros
- /// l (lowercase 'L') - A full textual representation of the day of the week
- /// N - ISO-8601 numeric representation of the day of the week (starting from 1)
- /// S - English ordinal suffix for the day of the month, 2 characters st,
- /// nd, rd or th. Works well with j.
- /// w - Numeric representation of the day of the week (starting from 0)
- /// z - The day of the year (starting from 0)
- /// W - ISO-8601 week number of year, weeks starting on Monday
- /// F - A full textual representation of a month, such as January or March
- /// m - Numeric representation of a month, with leading zeros
- /// M - A short textual representation of a month, three letters
- /// n - Numeric representation of a month, without leading zeros
- /// t - Number of days in the given month
- /// L - Whether it's a leap year
- /// o - ISO-8601 year number. This has the same value as Y, except that if
- /// the ISO week number (W) belongs to the previous or next year, that
- /// year is used instead.
- /// Y - A full numeric representation of a year, 4 digits
- /// y - A two digit representation of a year
- /// a - Lowercase Ante meridiem and Post meridiem
- /// A - Uppercase Ante meridiem and Post meridiem
- /// B - Swatch Internet time
- /// g - 12-hour format of an hour without leading zeros
- /// G - 24-hour format of an hour without leading zeros
- /// h - 12-hour format of an hour with leading zeros
- /// H - 24-hour format of an hour with leading zeros
- /// i - Minutes with leading zeros
- /// s - Seconds, with leading zeros
- /// u - Milliseconds
- /// U - Seconds since the Unix Epoch (January 1 1970 00:00:00 GMT)
- ///
- ///
- /// Returns the string for this date, formatted according to the given
- /// format string.
- ///
- // If the format was not passed, use the default toString method.
- if(typeof format !== "string" || /^\s*$/.test(format))
- return date + "";
- var jan1st = new Date(date.getFullYear(), 0, 1);
- var me = date;
- return format.replace(/[dDjlNSwzWFmMntLoYyaABgGhHisuU]/g, function(option) {
- switch(option) {
- // Day of the month, 2 digits with leading zeros
- case "d": return ("0" + me.getDate()).replace(/^.+(..)$/, "$1");
- // A textual representation of a day, three letters
- case "D": return shortDays[me.getDay()];
- // Day of the month without leading zeros
- case "j": return me.getDate();
- // A full textual representation of the day of the week
- case "l": return fullDays[me.getDay()];
- // ISO-8601 numeric representation of the day of the week
- case "N": return (me.getDay() + 6) % 7 + 1;
- // English ordinal suffix for the day of the month, 2 characters
- case "S": return getOrdinalFor(me.getDate());
- // Numeric representation of the day of the week
- case "w": return me.getDay();
- // The day of the year (starting from 0)
- case "z": return Math.ceil((jan1st - me) / 86400000);
- // ISO-8601 week number of year, weeks starting on Monday
- case "W": return ("0" + getISO8601Week(me)).replace(/^.(..)$/, "$1");
- // A full textual representation of a month, such as January or March
- case "F": return fullMonths[me.getMonth()];
- // Numeric representation of a month, with leading zeros
- case "m": return ("0" + (me.getMonth() + 1)).replace(/^.+(..)$/, "$1");
- // A short textual representation of a month, three letters
- case "M": return shortMonths[me.getMonth()];
- // Numeric representation of a month, without leading zeros
- case "n": return me.getMonth() + 1;
- // Number of days in the given month
- case "t": return new Date(me.getFullYear(), me.getMonth() + 1, -1).getDate();
- // Whether it's a leap year
- case "L": return new Date(me.getFullYear(), 1, 29).getDate() == 29 ? 1 : 0;
- // ISO-8601 year number. This has the same value as Y, except that if the
- // ISO week number (W) belongs to the previous or next year, that year is
- // used instead.
- case "o": return getISO8601Year(me);
- // A full numeric representation of a year, 4 digits
- case "Y": return me.getFullYear();
- // A two digit representation of a year
- case "y": return (me.getFullYear() + "").replace(/^.+(..)$/, "$1");
- // Lowercase Ante meridiem and Post meridiem
- case "a": return me.getHours() < 12 ? "am" : "pm";
- // Uppercase Ante meridiem and Post meridiem
- case "A": return me.getHours() < 12 ? "AM" : "PM";
- // Swatch Internet time
- case "B": return Math.floor((((me.getUTCHours() + 1) % 24) + me.getUTCMinutes() / 60 + me.getUTCSeconds() / 3600) * 1000 / 24);
- // 12-hour format of an hour without leading zeros
- case "g": return me.getHours() % 12 != 0 ? me.getHours() % 12 : 12;
- // 24-hour format of an hour without leading zeros
- case "G": return me.getHours();
- // 12-hour format of an hour with leading zeros
- case "h": return ("0" + (me.getHours() % 12 != 0 ? me.getHours() % 12 : 12)).replace(/^.+(..)$/, "$1");
- // 24-hour format of an hour with leading zeros
- case "H": return ("0" + me.getHours()).replace(/^.+(..)$/, "$1");
- // Minutes with leading zeros
- case "i": return ("0" + me.getMinutes()).replace(/^.+(..)$/, "$1");
- // Seconds, with leading zeros
- case "s": return ("0" + me.getSeconds()).replace(/^.+(..)$/, "$1");
- // Milliseconds
- case "u": return me.getMilliseconds();
- // Seconds since the Unix Epoch (January 1 1970 00:00:00 GMT)
- case "U": return me.getTime() / 1000;
- }
- });
- };
- })();
-
- Twig.lib.strip_tags = function(input, allowed) {
- // Strips HTML and PHP tags from a string
- //
- // version: 1109.2015
- // discuss at: http://phpjs.org/functions/strip_tags
- // + original by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
- // + improved by: Luke Godfrey
- // + input by: Pul
- // + bugfixed by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
- // + bugfixed by: Onno Marsman
- // + input by: Alex
- // + bugfixed by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
- // + input by: Marc Palau
- // + improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
- // + input by: Brett Zamir (http://brett-zamir.me)
- // + bugfixed by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
- // + bugfixed by: Eric Nagel
- // + input by: Bobby Drake
- // + bugfixed by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
- // + bugfixed by: Tomasz Wesolowski
- // + input by: Evertjan Garretsen
- // + revised by: Rafał Kukawski (http://blog.kukawski.pl/)
- // * example 1: strip_tags('Kevin
van Zonneveld ', '');
- // * returns 1: 'Kevin van Zonneveld '
- // * example 2: strip_tags(' Kevin van Zonneveld
', '');
- // * returns 2: '
Kevin van Zonneveld
'
- // * example 3: strip_tags("Kevin van Zonneveld ", "");
- // * returns 3: ' Kevin van Zonneveld '
- // * example 4: strip_tags('1 < 5 5 > 1');
- // * returns 4: '1 < 5 5 > 1'
- // * example 5: strip_tags('1 1');
- // * returns 5: '1 1'
- // * example 6: strip_tags('1 1', ' ');
- // * returns 6: '1 1'
- // * example 7: strip_tags('1 1', ' ');
- // * returns 7: '1 1'
- allowed = (((allowed || "") + "").toLowerCase().match(/<[a-z][a-z0-9]*>/g) || []).join(''); // making sure the allowed arg is a string containing only tags in lowercase ()
- var tags = /<\/?([a-z][a-z0-9]*)\b[^>]*>/gi,
- commentsAndPhpTags = /|<\?(?:php)?[\s\S]*?\?>/gi;
- return input.replace(commentsAndPhpTags, '').replace(tags, function ($0, $1) {
- return allowed.indexOf('<' + $1.toLowerCase() + '>') > -1 ? $0 : '';
- });
- }
-
- Twig.lib.parseISO8601Date = function (s){
- // Taken from http://n8v.enteuxis.org/2010/12/parsing-iso-8601-dates-in-javascript/
- // parenthese matches:
- // year month day hours minutes seconds
- // dotmilliseconds
- // tzstring plusminus hours minutes
- var re = /(\d{4})-(\d\d)-(\d\d)T(\d\d):(\d\d):(\d\d)(\.\d+)?(Z|([+-])(\d\d):(\d\d))/;
-
- var d = [];
- d = s.match(re);
-
- // "2010-12-07T11:00:00.000-09:00" parses to:
- // ["2010-12-07T11:00:00.000-09:00", "2010", "12", "07", "11",
- // "00", "00", ".000", "-09:00", "-", "09", "00"]
- // "2010-12-07T11:00:00.000Z" parses to:
- // ["2010-12-07T11:00:00.000Z", "2010", "12", "07", "11",
- // "00", "00", ".000", "Z", undefined, undefined, undefined]
-
- if (! d) {
- throw "Couldn't parse ISO 8601 date string '" + s + "'";
- }
-
- // parse strings, leading zeros into proper ints
- var a = [1,2,3,4,5,6,10,11];
- for (var i in a) {
- d[a[i]] = parseInt(d[a[i]], 10);
- }
- d[7] = parseFloat(d[7]);
-
- // Date.UTC(year, month[, date[, hrs[, min[, sec[, ms]]]]])
- // note that month is 0-11, not 1-12
- // see https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Date/UTC
- var ms = Date.UTC(d[1], d[2] - 1, d[3], d[4], d[5], d[6]);
-
- // if there are milliseconds, add them
- if (d[7] > 0) {
- ms += Math.round(d[7] * 1000);
- }
-
- // if there's a timezone, calculate it
- if (d[8] != "Z" && d[10]) {
- var offset = d[10] * 60 * 60 * 1000;
- if (d[11]) {
- offset += d[11] * 60 * 1000;
- }
- if (d[9] == "-") {
- ms -= offset;
- }
- else {
- ms += offset;
- }
- }
-
- return new Date(ms);
- };
-
- Twig.lib.strtotime = function (str, now) {
- // http://kevin.vanzonneveld.net
- // + original by: Caio Ariede (http://caioariede.com)
- // + improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
- // + input by: David
- // + improved by: Caio Ariede (http://caioariede.com)
- // + improved by: Brett Zamir (http://brett-zamir.me)
- // + bugfixed by: Wagner B. Soares
- // + bugfixed by: Artur Tchernychev
- // % note 1: Examples all have a fixed timestamp to prevent tests to fail because of variable time(zones)
- // * example 1: strtotime('+1 day', 1129633200);
- // * returns 1: 1129719600
- // * example 2: strtotime('+1 week 2 days 4 hours 2 seconds', 1129633200);
- // * returns 2: 1130425202
- // * example 3: strtotime('last month', 1129633200);
- // * returns 3: 1127041200
- // * example 4: strtotime('2009-05-04 08:30:00');
- // * returns 4: 1241418600
- var i, l, match, s, parse = '';
-
- str = str.replace(/\s{2,}|^\s|\s$/g, ' '); // unecessary spaces
- str = str.replace(/[\t\r\n]/g, ''); // unecessary chars
- if (str === 'now') {
- return now === null || isNaN(now) ? new Date().getTime() / 1000 | 0 : now | 0;
- } else if (!isNaN(parse = Date.parse(str))) {
- return parse / 1000 | 0;
- } else if (now) {
- now = new Date(now * 1000); // Accept PHP-style seconds
- } else {
- now = new Date();
- }
-
- var upperCaseStr = str;
-
- str = str.toLowerCase();
-
- var __is = {
- day: {
- 'sun': 0,
- 'mon': 1,
- 'tue': 2,
- 'wed': 3,
- 'thu': 4,
- 'fri': 5,
- 'sat': 6
- },
- mon: [
- 'jan',
- 'feb',
- 'mar',
- 'apr',
- 'may',
- 'jun',
- 'jul',
- 'aug',
- 'sep',
- 'oct',
- 'nov',
- 'dec'
- ]
- };
-
- var process = function (m) {
- var ago = (m[2] && m[2] === 'ago');
- var num = (num = m[0] === 'last' ? -1 : 1) * (ago ? -1 : 1);
-
- switch (m[0]) {
- case 'last':
- case 'next':
- switch (m[1].substring(0, 3)) {
- case 'yea':
- now.setFullYear(now.getFullYear() + num);
- break;
- case 'wee':
- now.setDate(now.getDate() + (num * 7));
- break;
- case 'day':
- now.setDate(now.getDate() + num);
- break;
- case 'hou':
- now.setHours(now.getHours() + num);
- break;
- case 'min':
- now.setMinutes(now.getMinutes() + num);
- break;
- case 'sec':
- now.setSeconds(now.getSeconds() + num);
- break;
- case 'mon':
- if (m[1] === "month") {
- now.setMonth(now.getMonth() + num);
- break;
- }
- // fall through
- default:
- var day = __is.day[m[1].substring(0, 3)];
- if (typeof day !== 'undefined') {
- var diff = day - now.getDay();
- if (diff === 0) {
- diff = 7 * num;
- } else if (diff > 0) {
- if (m[0] === 'last') {
- diff -= 7;
- }
- } else {
- if (m[0] === 'next') {
- diff += 7;
- }
- }
- now.setDate(now.getDate() + diff);
- now.setHours(0, 0, 0, 0); // when jumping to a specific last/previous day of week, PHP sets the time to 00:00:00
- }
- }
- break;
-
- default:
- if (/\d+/.test(m[0])) {
- num *= parseInt(m[0], 10);
-
- switch (m[1].substring(0, 3)) {
- case 'yea':
- now.setFullYear(now.getFullYear() + num);
- break;
- case 'mon':
- now.setMonth(now.getMonth() + num);
- break;
- case 'wee':
- now.setDate(now.getDate() + (num * 7));
- break;
- case 'day':
- now.setDate(now.getDate() + num);
- break;
- case 'hou':
- now.setHours(now.getHours() + num);
- break;
- case 'min':
- now.setMinutes(now.getMinutes() + num);
- break;
- case 'sec':
- now.setSeconds(now.getSeconds() + num);
- break;
- }
- } else {
- return false;
- }
- break;
- }
- return true;
- };
-
- match = str.match(/^(\d{2,4}-\d{2}-\d{2})(?:\s(\d{1,2}:\d{2}(:\d{2})?)?(?:\.(\d+))?)?$/);
- if (match !== null) {
- if (!match[2]) {
- match[2] = '00:00:00';
- } else if (!match[3]) {
- match[2] += ':00';
- }
-
- s = match[1].split(/-/g);
-
- s[1] = __is.mon[s[1] - 1] || s[1];
- s[0] = +s[0];
-
- s[0] = (s[0] >= 0 && s[0] <= 69) ? '20' + (s[0] < 10 ? '0' + s[0] : s[0] + '') : (s[0] >= 70 && s[0] <= 99) ? '19' + s[0] : s[0] + '';
- return parseInt(this.strtotime(s[2] + ' ' + s[1] + ' ' + s[0] + ' ' + match[2]) + (match[4] ? match[4] / 1000 : ''), 10);
- }
-
- var regex = '([+-]?\\d+\\s' + '(years?|months?|weeks?|days?|hours?|min|minutes?|sec|seconds?' + '|sun\\.?|sunday|mon\\.?|monday|tue\\.?|tuesday|wed\\.?|wednesday' + '|thu\\.?|thursday|fri\\.?|friday|sat\\.?|saturday)' + '|(last|next)\\s' + '(years?|months?|weeks?|days?|hours?|min|minutes?|sec|seconds?' + '|sun\\.?|sunday|mon\\.?|monday|tue\\.?|tuesday|wed\\.?|wednesday' + '|thu\\.?|thursday|fri\\.?|friday|sat\\.?|saturday))' + '(\\sago)?';
-
- match = str.match(new RegExp(regex, 'gi')); // Brett: seems should be case insensitive per docs, so added 'i'
- if (match === null) {
- // Try to parse ISO8601 in IE8
- try {
- num = Twig.lib.parseISO8601Date(upperCaseStr);
- if (num) {
- return num / 1000 | 0;
- }
- } catch (err) {
- return false;
- }
+ Twig.lib.sprintf = require('locutus/php/strings/sprintf');
+ Twig.lib.vsprintf = require('locutus/php/strings/vsprintf');
+ Twig.lib.round = require('locutus/php/math/round');
+ Twig.lib.max = require('locutus/php/math/max');
+ Twig.lib.min = require('locutus/php/math/min');
+ Twig.lib.stripTags = require('locutus/php/strings/strip_tags');
+ Twig.lib.strtotime = require('locutus/php/datetime/strtotime');
+ Twig.lib.date = require('locutus/php/datetime/date');
+ Twig.lib.boolval = require('locutus/php/var/boolval');
+
+ Twig.lib.is = function (type, obj) {
+ if (typeof obj === 'undefined' || obj === null) {
return false;
}
- for (i = 0, l = match.length; i < l; i++) {
- if (!process(match[i].split(' '))) {
+ switch (type) {
+ case 'Array':
+ return Array.isArray(obj);
+ case 'Date':
+ return obj instanceof Date;
+ case 'String':
+ return (typeof obj === 'string' || obj instanceof String);
+ case 'Number':
+ return (typeof obj === 'number' || obj instanceof Number);
+ case 'Function':
+ return (typeof obj === 'function');
+ case 'Object':
+ return obj instanceof Object;
+ default:
return false;
- }
}
-
- return now.getTime() / 1000 | 0;
};
- Twig.lib.is = function(type, obj) {
- var clas = Object.prototype.toString.call(obj).slice(8, -1);
- return obj !== undefined && obj !== null && clas === type;
+ Twig.lib.replaceAll = function (string, search, replace) {
+ // Convert type to string if needed
+ const stringToChange = typeof string === 'string' ? string : string.toString();
+ // Escape possible regular expression syntax
+ const searchEscaped = search.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
+ return stringToChange.replace(new RegExp(searchEscaped, 'g'), replace);
};
- // shallow-copy an object
- Twig.lib.copy = function(src) {
- var target = {},
- key;
- for (key in src)
- target[key] = src[key];
-
- return target;
- };
-
- Twig.lib.replaceAll = function(string, search, replace) {
- return string.split(search).join(replace);
- };
-
- // chunk an array (arr) into arrays of (size) items, returns an array of arrays, or an empty array on invalid input
+ // Chunk an array (arr) into arrays of (size) items, returns an array of arrays, or an empty array on invalid input
Twig.lib.chunkArray = function (arr, size) {
- var returnVal = [],
- x = 0,
- len = arr.length;
+ const returnVal = [];
+ let x = 0;
+ const len = arr.length;
- if (size < 1 || !Twig.lib.is("Array", arr)) {
+ if (size < 1 || !Array.isArray(arr)) {
return [];
}
@@ -629,60 +68,5 @@ var Twig = (function(Twig) {
return returnVal;
};
- Twig.lib.round = function round(value, precision, mode) {
- // discuss at: http://phpjs.org/functions/round/
- // original by: Philip Peterson
- // revised by: Onno Marsman
- // revised by: T.Wild
- // revised by: Rafał Kukawski (http://blog.kukawski.pl/)
- // input by: Greenseed
- // input by: meo
- // input by: William
- // input by: Josep Sanz (http://www.ws3.es/)
- // bugfixed by: Brett Zamir (http://brett-zamir.me)
- // note: Great work. Ideas for improvement:
- // note: - code more compliant with developer guidelines
- // note: - for implementing PHP constant arguments look at
- // note: the pathinfo() function, it offers the greatest
- // note: flexibility & compatibility possible
- // example 1: round(1241757, -3);
- // returns 1: 1242000
- // example 2: round(3.6);
- // returns 2: 4
- // example 3: round(2.835, 2);
- // returns 3: 2.84
- // example 4: round(1.1749999999999, 2);
- // returns 4: 1.17
- // example 5: round(58551.799999999996, 2);
- // returns 5: 58551.8
-
- var m, f, isHalf, sgn; // helper variables
- precision |= 0; // making sure precision is integer
- m = Math.pow(10, precision);
- value *= m;
- sgn = (value > 0) | -(value < 0); // sign of the number
- isHalf = value % 1 === 0.5 * sgn;
- f = Math.floor(value);
-
- if (isHalf) {
- switch (mode) {
- case 'PHP_ROUND_HALF_DOWN':
- value = f + (sgn < 0); // rounds .5 toward zero
- break;
- case 'PHP_ROUND_HALF_EVEN':
- value = f + (f % 2 * sgn); // rouds .5 towards the next even integer
- break;
- case 'PHP_ROUND_HALF_ODD':
- value = f + !(f % 2); // rounds .5 towards the next odd integer
- break;
- default:
- value = f + (sgn > 0); // rounds .5 away from zero
- }
- }
-
- return (isHalf ? value : Math.round(value)) / m;
- }
-
return Twig;
-
-})(Twig || { });
+};
diff --git a/src/twig.loader.ajax.js b/src/twig.loader.ajax.js
new file mode 100644
index 00000000..55c0b76e
--- /dev/null
+++ b/src/twig.loader.ajax.js
@@ -0,0 +1,53 @@
+module.exports = function (Twig) {
+ 'use strict';
+
+ Twig.Templates.registerLoader('ajax', function (location, params, callback, errorCallback) {
+ let template;
+ const {precompiled} = params;
+ const parser = this.parsers[params.parser] || this.parser.twig;
+
+ if (typeof XMLHttpRequest === 'undefined') {
+ throw new Twig.Error('Unsupported platform: Unable to do ajax requests ' +
+ 'because there is no "XMLHTTPRequest" implementation');
+ }
+
+ const xmlhttp = new XMLHttpRequest();
+ xmlhttp.onreadystatechange = function () {
+ let data = null;
+
+ if (xmlhttp.readyState === 4) {
+ if (xmlhttp.status === 200 || (window.cordova && xmlhttp.status === 0)) {
+ Twig.log.debug('Got template ', xmlhttp.responseText);
+
+ if (precompiled === true) {
+ data = JSON.parse(xmlhttp.responseText);
+ } else {
+ data = xmlhttp.responseText;
+ }
+
+ params.url = location;
+ params.data = data;
+
+ template = parser.call(this, params);
+
+ if (typeof callback === 'function') {
+ callback(template);
+ }
+ } else if (typeof errorCallback === 'function') {
+ errorCallback(xmlhttp);
+ }
+ }
+ };
+
+ xmlhttp.open('GET', location, Boolean(params.async));
+ xmlhttp.overrideMimeType('text/plain');
+ xmlhttp.send();
+
+ if (params.async) {
+ // TODO: return deferred promise
+ return true;
+ }
+
+ return template;
+ });
+};
diff --git a/src/twig.loader.fs.js b/src/twig.loader.fs.js
new file mode 100644
index 00000000..85487c6e
--- /dev/null
+++ b/src/twig.loader.fs.js
@@ -0,0 +1,81 @@
+module.exports = function (Twig) {
+ 'use strict';
+
+ let fs;
+ let path;
+
+ try {
+ // Require lib dependencies at runtime
+ fs = require('fs');
+ path = require('path');
+ } catch (error) {
+ // NOTE: this is in a try/catch to avoid errors cross platform
+ console.warn('Missing fs and path modules. ' + error);
+ }
+
+ Twig.Templates.registerLoader('fs', function (location, params, callback, errorCallback) {
+ let template;
+ let data = null;
+ const {precompiled} = params;
+ const parser = this.parsers[params.parser] || this.parser.twig;
+
+ if (!fs || !path) {
+ throw new Twig.Error('Unsupported platform: Unable to load from file ' +
+ 'because there is no "fs" or "path" implementation');
+ }
+
+ const loadTemplateFn = function (err, data) {
+ if (err) {
+ if (typeof errorCallback === 'function') {
+ errorCallback(err);
+ }
+
+ return;
+ }
+
+ if (precompiled === true) {
+ data = JSON.parse(data);
+ }
+
+ params.data = data;
+ params.path = params.path || location;
+
+ // Template is in data
+ template = parser.call(this, params);
+
+ if (typeof callback === 'function') {
+ callback(template);
+ }
+ };
+
+ params.path = params.path || location;
+
+ if (params.async) {
+ fs.stat(params.path, (err, stats) => {
+ if (err || !stats.isFile()) {
+ if (typeof errorCallback === 'function') {
+ errorCallback(new Twig.Error('Unable to find template file ' + params.path));
+ }
+
+ return;
+ }
+
+ fs.readFile(params.path, 'utf8', loadTemplateFn);
+ });
+ // TODO: return deferred promise
+ return true;
+ }
+
+ try {
+ if (!fs.statSync(params.path).isFile()) {
+ throw new Twig.Error('Unable to find template file ' + params.path);
+ }
+ } catch (error) {
+ throw new Twig.Error('Unable to find template file ' + params.path + '. ' + error);
+ }
+
+ data = fs.readFileSync(params.path, 'utf8');
+ loadTemplateFn(undefined, data);
+ return template;
+ });
+};
diff --git a/src/twig.logic.js b/src/twig.logic.js
index df865138..21cdc473 100644
--- a/src/twig.logic.js
+++ b/src/twig.logic.js
@@ -1,13 +1,8 @@
-// Twig.js
-// Copyright (c) 2011-2013 John Roepke
-// Available under the BSD 2-Clause License
-// https://github.com/justjohn/twig.js
-
// ## twig.logic.js
//
// This file handles tokenizing, compiling and parsing logic tokens. {% ... %}
-var Twig = (function (Twig) {
- "use strict";
+module.exports = function (Twig) {
+ 'use strict';
/**
* Namespace for logic handling.
@@ -18,31 +13,39 @@ var Twig = (function (Twig) {
* Logic token types.
*/
Twig.logic.type = {
- if_: 'Twig.logic.type.if',
- endif: 'Twig.logic.type.endif',
- for_: 'Twig.logic.type.for',
- endfor: 'Twig.logic.type.endfor',
- else_: 'Twig.logic.type.else',
- elseif: 'Twig.logic.type.elseif',
- set: 'Twig.logic.type.set',
- setcapture:'Twig.logic.type.setcapture',
- endset: 'Twig.logic.type.endset',
- filter: 'Twig.logic.type.filter',
+ if_: 'Twig.logic.type.if',
+ endif: 'Twig.logic.type.endif',
+ for_: 'Twig.logic.type.for',
+ endfor: 'Twig.logic.type.endfor',
+ else_: 'Twig.logic.type.else',
+ elseif: 'Twig.logic.type.elseif',
+ set: 'Twig.logic.type.set',
+ setcapture: 'Twig.logic.type.setcapture',
+ endset: 'Twig.logic.type.endset',
+ filter: 'Twig.logic.type.filter',
endfilter: 'Twig.logic.type.endfilter',
- block: 'Twig.logic.type.block',
- endblock: 'Twig.logic.type.endblock',
- extends_: 'Twig.logic.type.extends',
- use: 'Twig.logic.type.use',
- include: 'Twig.logic.type.include',
+ apply: 'Twig.logic.type.apply',
+ endapply: 'Twig.logic.type.endapply',
+ do: 'Twig.logic.type.do',
+ shortblock: 'Twig.logic.type.shortblock',
+ block: 'Twig.logic.type.block',
+ endblock: 'Twig.logic.type.endblock',
+ extends_: 'Twig.logic.type.extends',
+ use: 'Twig.logic.type.use',
+ include: 'Twig.logic.type.include',
spaceless: 'Twig.logic.type.spaceless',
endspaceless: 'Twig.logic.type.endspaceless',
- macro: 'Twig.logic.type.macro',
- endmacro: 'Twig.logic.type.endmacro',
- import_: 'Twig.logic.type.import',
- from: 'Twig.logic.type.from'
+ macro: 'Twig.logic.type.macro',
+ endmacro: 'Twig.logic.type.endmacro',
+ import_: 'Twig.logic.type.import',
+ from: 'Twig.logic.type.from',
+ embed: 'Twig.logic.type.embed',
+ endembed: 'Twig.logic.type.endembed',
+ with: 'Twig.logic.type.with',
+ endwith: 'Twig.logic.type.endwith',
+ deprecated: 'Twig.logic.type.deprecated'
};
-
// Regular expressions for handling logic tokens.
//
// Properties:
@@ -72,40 +75,44 @@ var Twig = (function (Twig) {
* Format: {% if expression %}
*/
type: Twig.logic.type.if_,
- regex: /^if\s+([^\s].+)$/,
+ regex: /^if\s?([\s\S]+)$/,
next: [
Twig.logic.type.else_,
Twig.logic.type.elseif,
Twig.logic.type.endif
],
open: true,
- compile: function (token) {
- var expression = token.match[1];
+ compile(token) {
+ const expression = token.match[1];
// Compile the expression.
- token.stack = Twig.expression.compile.apply(this, [{
- type: Twig.expression.type.expression,
+ token.stack = Twig.expression.compile.call(this, {
+ type: Twig.expression.type.expression,
value: expression
- }]).stack;
+ }).stack;
delete token.match;
return token;
},
- parse: function (token, context, chain) {
- var output = '',
- // Parse the expression
- result = Twig.expression.parse.apply(this, [token.stack, context]);
-
- // Start a new logic chain
- chain = true;
-
- if (result) {
- chain = false;
- // parse if output
- output = Twig.parse.apply(this, [token.output, context]);
- }
- return {
- chain: chain,
- output: output
- };
+ parse(token, context, chain) {
+ const state = this;
+
+ return Twig.expression.parseAsync.call(state, token.stack, context)
+ .then(result => {
+ chain = true;
+
+ if (Twig.lib.boolval(result)) {
+ chain = false;
+
+ return state.parseAsync(token.output, context);
+ }
+
+ return '';
+ })
+ .then(output => {
+ return {
+ chain,
+ output
+ };
+ });
}
},
{
@@ -115,43 +122,49 @@ var Twig = (function (Twig) {
* Format: {% elseif expression %}
*/
type: Twig.logic.type.elseif,
- regex: /^elseif\s+([^\s].*)$/,
+ regex: /^elseif\s*([^\s].*)$/,
next: [
Twig.logic.type.else_,
Twig.logic.type.elseif,
Twig.logic.type.endif
],
open: false,
- compile: function (token) {
- var expression = token.match[1];
+ compile(token) {
+ const expression = token.match[1];
// Compile the expression.
- token.stack = Twig.expression.compile.apply(this, [{
- type: Twig.expression.type.expression,
+ token.stack = Twig.expression.compile.call(this, {
+ type: Twig.expression.type.expression,
value: expression
- }]).stack;
+ }).stack;
delete token.match;
return token;
},
- parse: function (token, context, chain) {
- var output = '';
+ parse(token, context, chain) {
+ const state = this;
- if (chain && Twig.expression.parse.apply(this, [token.stack, context]) === true) {
- chain = false;
- // parse if output
- output = Twig.parse.apply(this, [token.output, context]);
- }
+ return Twig.expression.parseAsync.call(state, token.stack, context)
+ .then(result => {
+ if (chain && Twig.lib.boolval(result)) {
+ chain = false;
- return {
- chain: chain,
- output: output
- };
+ return state.parseAsync(token.output, context);
+ }
+
+ return '';
+ })
+ .then(output => {
+ return {
+ chain,
+ output
+ };
+ });
}
},
{
/**
- * Else if type logic tokens.
+ * Else type logic tokens.
*
- * Format: {% elseif expression %}
+ * Format: {% else %}
*/
type: Twig.logic.type.else_,
regex: /^else$/,
@@ -160,15 +173,20 @@ var Twig = (function (Twig) {
Twig.logic.type.endfor
],
open: false,
- parse: function (token, context, chain) {
- var output = '';
+ parse(token, context, chain) {
+ let promise = Twig.Promise.resolve('');
+ const state = this;
+
if (chain) {
- output = Twig.parse.apply(this, [token.output, context]);
+ promise = state.parseAsync(token.output, context);
}
- return {
- chain: chain,
- output: output
- };
+
+ return promise.then(output => {
+ return {
+ chain,
+ output
+ };
+ });
}
},
{
@@ -179,7 +197,7 @@ var Twig = (function (Twig) {
*/
type: Twig.logic.type.endif,
regex: /^endif$/,
- next: [ ],
+ next: [],
open: false
},
{
@@ -189,31 +207,31 @@ var Twig = (function (Twig) {
* Format: {% for expression %}
*/
type: Twig.logic.type.for_,
- regex: /^for\s+([a-zA-Z0-9_,\s]+)\s+in\s+([^\s].*?)(?:\s+if\s+([^\s].*))?$/,
+ regex: /^for\s+([a-zA-Z0-9_,\s]+)\s+in\s+([\S\s]+?)(?:\s+if\s+([^\s].*))?$/,
next: [
Twig.logic.type.else_,
Twig.logic.type.endfor
],
open: true,
- compile: function (token) {
- var key_value = token.match[1],
- expression = token.match[2],
- conditional = token.match[3],
- kv_split = null;
-
- token.key_var = null;
- token.value_var = null;
-
- if (key_value.indexOf(",") >= 0) {
- kv_split = key_value.split(',');
- if (kv_split.length === 2) {
- token.key_var = kv_split[0].trim();
- token.value_var = kv_split[1].trim();
+ compile(token) {
+ const keyValue = token.match[1];
+ const expression = token.match[2];
+ const conditional = token.match[3];
+ let kvSplit = null;
+
+ token.keyVar = null;
+ token.valueVar = null;
+
+ if (keyValue.includes(',')) {
+ kvSplit = keyValue.split(',');
+ if (kvSplit.length === 2) {
+ token.keyVar = kvSplit[0].trim();
+ token.valueVar = kvSplit[1].trim();
} else {
- throw new Twig.Error("Invalid expression in for loop: " + key_value);
+ throw new Twig.Error('Invalid expression in for loop: ' + keyValue);
}
} else {
- token.value_var = key_value;
+ token.valueVar = keyValue.trim();
}
// Valid expressions for a for loop
@@ -221,103 +239,134 @@ var Twig = (function (Twig) {
// for key,item in expression
// Compile the expression.
- token.expression = Twig.expression.compile.apply(this, [{
- type: Twig.expression.type.expression,
+ token.expression = Twig.expression.compile.call(this, {
+ type: Twig.expression.type.expression,
value: expression
- }]).stack;
+ }).stack;
// Compile the conditional (if available)
if (conditional) {
- token.conditional = Twig.expression.compile.apply(this, [{
- type: Twig.expression.type.expression,
+ token.conditional = Twig.expression.compile.call(this, {
+ type: Twig.expression.type.expression,
value: conditional
- }]).stack;
+ }).stack;
}
delete token.match;
return token;
},
- parse: function (token, context, continue_chain) {
+ parse(token, context, continueChain) {
// Parse expression
- var result = Twig.expression.parse.apply(this, [token.expression, context]),
- output = [],
- len,
- index = 0,
- keyset,
- that = this,
- conditional = token.conditional,
- buildLoop = function(index, len) {
- var isConditional = conditional !== undefined;
- return {
- index: index+1,
- index0: index,
- revindex: isConditional?undefined:len-index,
- revindex0: isConditional?undefined:len-index-1,
- first: (index === 0),
- last: isConditional?undefined:(index === len-1),
- length: isConditional?undefined:len,
- parent: context
- };
- },
- loop = function(key, value) {
- var inner_context = Twig.lib.copy(context);
+ const output = [];
+ let len;
+ let index = 0;
+ let keyset;
+ const state = this;
+ const {conditional} = token;
+ const buildLoop = function (index, len) {
+ const isConditional = conditional !== undefined;
+ return {
+ index: index + 1,
+ index0: index,
+ revindex: isConditional ? undefined : len - index,
+ revindex0: isConditional ? undefined : len - index - 1,
+ first: (index === 0),
+ last: isConditional ? undefined : (index === len - 1),
+ length: isConditional ? undefined : len,
+ parent: context
+ };
+ };
- inner_context[token.value_var] = value;
- if (token.key_var) {
- inner_context[token.key_var] = key;
- }
+ // Run once for each iteration of the loop
+ const loop = function (key, value) {
+ const innerContext = {...context};
- // Loop object
- inner_context.loop = buildLoop(index, len);
+ innerContext[token.valueVar] = value;
- if (conditional === undefined ||
- Twig.expression.parse.apply(that, [conditional, inner_context]))
- {
- output.push(Twig.parse.apply(that, [token.output, inner_context]));
- index += 1;
+ if (token.keyVar) {
+ innerContext[token.keyVar] = key;
+ }
+
+ // Loop object
+ innerContext.loop = buildLoop(index, len);
+
+ const promise = conditional === undefined ?
+ Twig.Promise.resolve(true) :
+ Twig.expression.parseAsync.call(state, conditional, innerContext);
+
+ return promise.then(condition => {
+ if (!condition) {
+ return;
}
- };
- if (result instanceof Array) {
- len = result.length;
- Twig.forEach(result, function (value) {
- var key = index;
+ return state.parseAsync(token.output, innerContext)
+ .then(tokenOutput => {
+ output.push(tokenOutput);
+ index += 1;
+ });
+ })
+ .then(() => {
+ // Delete loop-related variables from the context
+ delete innerContext.loop;
+ delete innerContext[token.valueVar];
+ delete innerContext[token.keyVar];
+
+ // Merge in values that exist in context but have changed
+ // in inner_context.
+ Twig.merge(context, innerContext, true);
+ });
+ };
- loop(key, value);
- });
- } else if (result instanceof Object) {
- if (result._keys !== undefined) {
- keyset = result._keys;
- } else {
- keyset = Object.keys(result);
- }
- len = keyset.length;
- Twig.forEach(keyset, function(key) {
- // Ignore the _keys property, it's internal to twig.js
- if (key === "_keys") return;
+ return Twig.expression.parseAsync.call(state, token.expression, context)
+ .then(result => {
+ if (Array.isArray(result)) {
+ len = result.length;
+ return Twig.async.forEach(result, value => {
+ const key = index;
- loop(key, result[key]);
- });
- }
+ return loop(key, value);
+ });
+ }
- // Only allow else statements if no output was generated
- continue_chain = (output.length === 0);
+ if (Twig.lib.is('Object', result)) {
+ if (result._keys === undefined) {
+ keyset = Object.keys(result);
+ } else {
+ keyset = result._keys;
+ }
+
+ len = keyset.length;
+ return Twig.async.forEach(keyset, key => {
+ // Ignore the _keys property, it's internal to twig.js
+ if (key === '_keys') {
+ return;
+ }
+
+ return loop(key, result[key]);
+ });
+ }
+ })
+ .then(() => {
+ // Only allow else statements if no output was generated
+ continueChain = (output.length === 0);
- return {
- chain: continue_chain,
- output: output.join("")
- };
+ return {
+ chain: continueChain,
+ context,
+ output: Twig.output.call(state.template, output)
+ };
+ });
}
},
{
/**
- * End if type logic tokens.
+ * End for type logic tokens.
*
- * Format: {% endif %}
+ * Format: {% endfor %}
*/
type: Twig.logic.type.endfor,
regex: /^endfor$/,
- next: [ ],
+ next: [],
open: false
},
{
@@ -327,36 +376,45 @@ var Twig = (function (Twig) {
* Format: {% set key = expression %}
*/
type: Twig.logic.type.set,
- regex: /^set\s+([a-zA-Z0-9_,\s]+)\s*=\s*(.+)$/,
- next: [ ],
+ regex: /^set\s+([a-zA-Z0-9_,\s]+)\s*=\s*([\s\S]+)$/,
+ next: [],
open: true,
- compile: function (token) {
- var key = token.match[1].trim(),
- expression = token.match[2],
- // Compile the expression.
- expression_stack = Twig.expression.compile.apply(this, [{
- type: Twig.expression.type.expression,
- value: expression
- }]).stack;
+ compile(token) { //
+ const key = token.match[1].trim();
+ const expression = token.match[2];
+ // Compile the expression.
+ const expressionStack = Twig.expression.compile.call(this, {
+ type: Twig.expression.type.expression,
+ value: expression
+ }).stack;
token.key = key;
- token.expression = expression_stack;
+ token.expression = expressionStack;
delete token.match;
return token;
},
- parse: function (token, context, continue_chain) {
- var value = Twig.expression.parse.apply(this, [token.expression, context]),
- key = token.key;
+ parse(token, context, continueChain) {
+ const {key} = token;
+ const state = this;
+
+ return Twig.expression.parseAsync.call(state, token.expression, context)
+ .then(value => {
+ if (value === context) {
+ /* If storing the context in a variable, it needs to be a clone of the current state of context.
+ Otherwise we have a context with infinite recursion.
+ Fixes #341
+ */
+ value = {...value};
+ }
- // set on both the global and local context
- this.context[key] = value;
- context[key] = value;
+ context[key] = value;
- return {
- chain: continue_chain,
- context: context
- };
+ return {
+ chain: continueChain,
+ context
+ };
+ });
}
},
{
@@ -371,27 +429,29 @@ var Twig = (function (Twig) {
Twig.logic.type.endset
],
open: true,
- compile: function (token) {
- var key = token.match[1].trim();
+ compile(token) {
+ const key = token.match[1].trim();
token.key = key;
delete token.match;
return token;
},
- parse: function (token, context, continue_chain) {
-
- var value = Twig.parse.apply(this, [token.output, context]),
- key = token.key;
+ parse(token, context, continueChain) {
+ const state = this;
+ const {key} = token;
- // set on both the global and local context
- this.context[key] = value;
- context[key] = value;
+ return state.parseAsync(token.output, context)
+ .then(output => {
+ // Set on both the global and local context
+ state.context[key] = output;
+ context[key] = output;
- return {
- chain: continue_chain,
- context: context
- };
+ return {
+ chain: continueChain,
+ context
+ };
+ });
}
},
{
@@ -402,7 +462,7 @@ var Twig = (function (Twig) {
*/
type: Twig.logic.type.endset,
regex: /^endset$/,
- next: [ ],
+ next: [],
open: false
},
{
@@ -417,29 +477,34 @@ var Twig = (function (Twig) {
Twig.logic.type.endfilter
],
open: true,
- compile: function (token) {
- var expression = "|" + token.match[1].trim();
+ compile(token) {
+ const expression = '|' + token.match[1].trim();
// Compile the expression.
- token.stack = Twig.expression.compile.apply(this, [{
- type: Twig.expression.type.expression,
+ token.stack = Twig.expression.compile.call(this, {
+ type: Twig.expression.type.expression,
value: expression
- }]).stack;
+ }).stack;
delete token.match;
return token;
},
- parse: function (token, context, chain) {
- var unfiltered = Twig.parse.apply(this, [token.output, context]),
- stack = [{
- type: Twig.expression.type.string,
- value: unfiltered
- }].concat(token.stack);
-
- var output = Twig.expression.parse.apply(this, [stack, context]);
-
- return {
- chain: chain,
- output: output
- };
+ parse(token, context, chain) {
+ const state = this;
+
+ return state.parseAsync(token.output, context)
+ .then(output => {
+ const stack = [{
+ type: Twig.expression.type.string,
+ value: output
+ }].concat(token.stack);
+
+ return Twig.expression.parseAsync.call(state, stack, context);
+ })
+ .then(output => {
+ return {
+ chain,
+ output
+ };
+ });
}
},
{
@@ -450,9 +515,97 @@ var Twig = (function (Twig) {
*/
type: Twig.logic.type.endfilter,
regex: /^endfilter$/,
- next: [ ],
+ next: [],
+ open: false
+ },
+ {
+ /**
+ * Apply logic tokens.
+ *
+ * Format: {% apply upper %} or {% apply lower|escape %}
+ */
+ type: Twig.logic.type.apply,
+ regex: /^apply\s+(.+)$/,
+ next: [
+ Twig.logic.type.endapply
+ ],
+ open: true,
+ compile(token) {
+ const expression = '|' + token.match[1].trim();
+ // Compile the expression.
+ token.stack = Twig.expression.compile.call(this, {
+ type: Twig.expression.type.expression,
+ value: expression
+ }).stack;
+ delete token.match;
+ return token;
+ },
+ parse(token, context, chain) {
+ const state = this;
+
+ return state.parseAsync(token.output, context)
+ .then(output => {
+ const stack = [{
+ type: Twig.expression.type.string,
+ value: output
+ }].concat(token.stack);
+
+ return Twig.expression.parseAsync.call(state, stack, context);
+ })
+ .then(output => {
+ return {
+ chain,
+ output
+ };
+ });
+ }
+ },
+ {
+ /**
+ * End apply logic tokens.
+ *
+ * Format: {% endapply %}
+ */
+ type: Twig.logic.type.endapply,
+ regex: /^endapply$/,
+ next: [],
open: false
},
+ {
+ /**
+ * Set type logic tokens.
+ *
+ * Format: {% do expression %}
+ */
+ type: Twig.logic.type.do,
+ regex: /^do\s+([\S\s]+)$/,
+ next: [],
+ open: true,
+ compile(token) { //
+ const expression = token.match[1];
+ // Compile the expression.
+ const expressionStack = Twig.expression.compile.call(this, {
+ type: Twig.expression.type.expression,
+ value: expression
+ }).stack;
+
+ token.expression = expressionStack;
+
+ delete token.match;
+ return token;
+ },
+ parse(token, context, continueChain) {
+ const state = this;
+
+ return Twig.expression.parseAsync.call(state, token.expression, context)
+ .then(() => {
+ return {
+ chain: continueChain,
+ context
+ };
+ });
+ }
+ },
{
/**
* Block logic tokens.
@@ -460,47 +613,63 @@ var Twig = (function (Twig) {
* Format: {% block title %}
*/
type: Twig.logic.type.block,
- regex: /^block\s+([a-zA-Z0-9_]+)$/,
+ regex: /^block\s+(\w+)$/,
next: [
Twig.logic.type.endblock
],
open: true,
- compile: function (token) {
- token.block = token.match[1].trim();
+ compile(token) {
+ token.blockName = token.match[1].trim();
delete token.match;
+
return token;
},
- parse: function (token, context, chain) {
- var block_output = "",
- output = "",
- hasParent = this.blocks[token.block] && this.blocks[token.block].indexOf(Twig.placeholders.parent) > -1;
-
- // Don't override previous blocks
- // Loops should be exempted as well.
- if (this.blocks[token.block] === undefined || hasParent || context.loop) {
- block_output = Twig.expression.parse.apply(this, [{
- type: Twig.expression.type.string,
- value: Twig.parse.apply(this, [token.output, context])
- }, context]);
-
- if (hasParent) {
- this.blocks[token.block] = this.blocks[token.block].replace(Twig.placeholders.parent, block_output);
- } else {
- this.blocks[token.block] = block_output;
- }
- }
+ parse(token, context, chain) {
+ const state = this;
+ let promise = Twig.Promise.resolve();
- // Check if a child block has been set from a template extending this one.
- if (this.child.blocks[token.block]) {
- output = this.child.blocks[token.block];
- } else {
- output = this.blocks[token.block];
+ state.template.blocks.defined[token.blockName] = new Twig.Block(state.template, token);
+
+ if (
+ state.template.parentTemplate === null ||
+ state.template.parentTemplate instanceof Twig.Template
+ ) {
+ promise = state.getBlock(token.blockName).render(state, context);
}
- return {
- chain: chain,
- output: output
- };
+ return promise.then(output => {
+ return {
+ chain,
+ output
+ };
+ });
+ }
+ },
+ {
+ /**
+ * Block shorthand logic tokens.
+ *
+ * Format: {% block title expression %}
+ */
+ type: Twig.logic.type.shortblock,
+ regex: /^block\s+(\w+)\s+(.+)$/,
+ next: [],
+ open: true,
+ compile(token) {
+ const template = this;
+
+ token.expression = token.match[2].trim();
+ token.output = Twig.expression.compile({
+ type: Twig.expression.type.expression,
+ value: token.expression
+ }).stack;
+
+ return Twig.logic.handler[Twig.logic.type.block].compile.apply(template, [token]);
+ },
+ parse(...args) {
+ const state = this;
+
+ return Twig.logic.handler[Twig.logic.type.block].parse.apply(state, args);
}
},
{
@@ -510,8 +679,8 @@ var Twig = (function (Twig) {
* Format: {% endblock %}
*/
type: Twig.logic.type.endblock,
- regex: /^endblock(?:\s+([a-zA-Z0-9_]+))?$/,
- next: [ ],
+ regex: /^endblock(?:\s+(\w+))?$/,
+ next: [],
open: false
},
{
@@ -522,64 +691,99 @@ var Twig = (function (Twig) {
*/
type: Twig.logic.type.extends_,
regex: /^extends\s+(.+)$/,
- next: [ ],
+ next: [],
open: true,
- compile: function (token) {
- var expression = token.match[1].trim();
+ compile(token) {
+ const expression = token.match[1].trim();
delete token.match;
- token.stack = Twig.expression.compile.apply(this, [{
- type: Twig.expression.type.expression,
+ token.stack = Twig.expression.compile.call(this, {
+ type: Twig.expression.type.expression,
value: expression
- }]).stack;
+ }).stack;
return token;
},
- parse: function (token, context, chain) {
- // Resolve filename
- var file = Twig.expression.parse.apply(this, [token.stack, context]);
-
- // Set parent template
- this.extend = file;
+ parse(token, context, chain) {
+ const state = this;
+
+ return Twig.expression.parseAsync.call(state, token.stack, context)
+ .then(fileName => {
+ if (Array.isArray(fileName)) {
+ const result = fileName.reverse().reduce((acc, file) => {
+ try {
+ return {
+ render: state.template.importFile(file),
+ fileName: file
+ };
+ /* eslint-disable-next-line no-unused-vars */
+ } catch (error) {
+ return acc;
+ }
+ }, {
+ render: null,
+ fileName: null
+ });
+ if (result.fileName !== null) {
+ state.template.parentTemplate = result.fileName;
+ }
+ } else {
+ state.template.parentTemplate = fileName;
+ }
- return {
- chain: chain,
- output: ''
- };
+ return {
+ chain,
+ output: ''
+ };
+ });
}
},
{
/**
* Block logic tokens.
*
- * Format: {% extends "template.twig" %}
+ * Format: {% use "template.twig" %}
*/
type: Twig.logic.type.use,
regex: /^use\s+(.+)$/,
- next: [ ],
+ next: [],
open: true,
- compile: function (token) {
- var expression = token.match[1].trim();
+ compile(token) {
+ const expression = token.match[1].trim();
delete token.match;
- token.stack = Twig.expression.compile.apply(this, [{
- type: Twig.expression.type.expression,
+ token.stack = Twig.expression.compile.call(this, {
+ type: Twig.expression.type.expression,
value: expression
- }]).stack;
+ }).stack;
return token;
},
- parse: function (token, context, chain) {
- // Resolve filename
- var file = Twig.expression.parse.apply(this, [token.stack, context]);
-
- // Import blocks
- this.importBlocks(file);
-
- return {
- chain: chain,
- output: ''
- };
+ parse(token, context, chain) {
+ const state = this;
+
+ return Twig.expression.parseAsync.call(state, token.stack, context)
+ .then(filePath => {
+ // Create a new state instead of using the current state
+ // any defined blocks will be created in isolation
+
+ const useTemplate = state.template.importFile(filePath);
+
+ const useState = new Twig.ParseState(useTemplate);
+ return useState.parseAsync(useTemplate.tokens)
+ .then(() => {
+ state.template.blocks.imported = {
+ ...state.template.blocks.imported,
+ ...useState.getBlocks()
+ };
+ });
+ })
+ .then(() => {
+ return {
+ chain,
+ output: ''
+ };
+ });
}
},
{
@@ -589,67 +793,119 @@ var Twig = (function (Twig) {
* Format: {% includes "template.twig" [with {some: 'values'} only] %}
*/
type: Twig.logic.type.include,
- regex: /^include\s+(ignore missing\s+)?(.+?)\s*(?:with\s+(.+?))?\s*(only)?$/,
- next: [ ],
+ regex: /^include\s+(.+?)(?:\s|$)(ignore missing(?:\s|$))?(?:with\s+([\S\s]+?))?(?:\s|$)(only)?$/,
+ next: [],
open: true,
- compile: function (token) {
- var match = token.match,
- includeMissing = match[1] !== undefined,
- expression = match[2].trim(),
- withContext = match[3],
- only = ((match[4] !== undefined) && match[4].length);
+ compile(token) {
+ const {match} = token;
+ const expression = match[1].trim();
+ const ignoreMissing = match[2] !== undefined;
+ const withContext = match[3];
+ const only = ((match[4] !== undefined) && match[4].length);
delete token.match;
token.only = only;
- token.includeMissing = includeMissing;
+ token.ignoreMissing = ignoreMissing;
- token.stack = Twig.expression.compile.apply(this, [{
- type: Twig.expression.type.expression,
+ token.stack = Twig.expression.compile.call(this, {
+ type: Twig.expression.type.expression,
value: expression
- }]).stack;
+ }).stack;
if (withContext !== undefined) {
- token.withStack = Twig.expression.compile.apply(this, [{
- type: Twig.expression.type.expression,
+ token.withStack = Twig.expression.compile.call(this, {
+ type: Twig.expression.type.expression,
value: withContext.trim()
- }]).stack;
+ }).stack;
}
return token;
},
- parse: function (token, context, chain) {
+ parse(token, context, chain) {
// Resolve filename
- var innerContext = {},
- withContext,
- i,
- template;
-
- if (!token.only) {
- for (i in context) {
- if (context.hasOwnProperty(i))
- innerContext[i] = context[i];
- }
+ let innerContext = token.only ? {} : {...context};
+ const {ignoreMissing} = token;
+ const state = this;
+ let promise = null;
+ const result = {chain, output: ''};
+
+ if (typeof token.withStack === 'undefined') {
+ promise = Twig.Promise.resolve();
+ } else {
+ promise = Twig.expression.parseAsync.call(state, token.withStack, context)
+ .then(withContext => {
+ innerContext = {
+ ...innerContext,
+ ...withContext
+ };
+ });
}
- if (token.withStack !== undefined) {
- withContext = Twig.expression.parse.apply(this, [token.withStack, context]);
+ return promise
+ .then(() => {
+ return Twig.expression.parseAsync.call(state, token.stack, context);
+ })
+ .then(file => {
+ let files;
+ if (Array.isArray(file)) {
+ files = file;
+ } else {
+ files = [file];
+ }
- for (i in withContext) {
- if (withContext.hasOwnProperty(i))
- innerContext[i] = withContext[i];
- }
- }
+ const result = files.reduce((acc, file) => {
+ if (acc.render === null) {
+ if (file instanceof Twig.Template) {
+ return {
+ render: file.renderAsync(
+ innerContext,
+ {
+ isInclude: true
+ }
+ ),
+ lastError: null
+ };
+ }
+
+ try {
+ return {
+ render: state.template.importFile(file).renderAsync(
+ innerContext,
+ {
+ isInclude: true
+ }
+ ),
+ lastError: null
+ };
+ } catch (error) {
+ return {
+ render: null,
+ lastError: error
+ };
+ }
+ }
+
+ return acc;
+ }, {render: null, lastError: null});
+
+ if (result.render !== null) {
+ return result.render;
+ }
- var file = Twig.expression.parse.apply(this, [token.stack, innerContext]);
+ if (result.render === null && ignoreMissing) {
+ return '';
+ }
- // Import file
- template = this.importFile(file);
+ throw result.lastError;
+ })
+ .then(output => {
+ if (output !== '') {
+ result.output = output;
+ }
- return {
- chain: chain,
- output: template.render(innerContext)
- };
+ return result;
+ });
}
},
{
@@ -661,18 +917,23 @@ var Twig = (function (Twig) {
open: true,
// Parse the html and return it without any spaces between tags
- parse: function (token, context, chain) {
- var // Parse the output without any filter
- unfiltered = Twig.parse.apply(this, [token.output, context]),
- // A regular expression to find closing and opening tags with spaces between them
- rBetweenTagSpaces = />\s+<').trim();
-
- return {
- chain: chain,
- output: output
- };
+ parse(token, context, chain) {
+ const state = this;
+
+ // Parse the output without any filter
+ return state.parseAsync(token.output, context)
+ .then(tokenOutput => {
+ const // A regular expression to find closing and opening tags with spaces between them
+ rBetweenTagSpaces = />\s+<').trim();
+ // Rewrap output as a Twig.Markup
+ output = new Twig.Markup(output);
+ return {
+ chain,
+ output
+ };
+ });
}
},
@@ -680,66 +941,104 @@ var Twig = (function (Twig) {
{
type: Twig.logic.type.endspaceless,
regex: /^endspaceless$/,
- next: [ ],
+ next: [],
open: false
},
{
/**
* Macro logic tokens.
*
- * Format: {% maro input(name, value, type, size) %}
+ * Format: {% macro input(name = default, value, type, size) %}
*
*/
type: Twig.logic.type.macro,
- regex: /^macro\s+([a-zA-Z0-9_]+)\s?\((([a-zA-Z0-9_]+(,\s?)?)*)\)$/,
+ regex: /^macro\s+(\w+)\s*\(\s*((?:\w+(?:\s*=\s*([\s\S]+))?(?:,\s*)?)*)\s*\)$/,
next: [
Twig.logic.type.endmacro
],
open: true,
- compile: function (token) {
- var macroName = token.match[1],
- parameters = token.match[2].split(/[ ,]+/);
-
- //TODO: Clean up duplicate check
- for (var i=0; i {
+ return rawParameter.split(/\s*=\s*/)[0];
+ });
+ const parametersCount = parameters.length;
+
+ // Duplicate check
+ if (parametersCount > 1) {
+ const uniq = {};
+ for (let i = 0; i < parametersCount; i++) {
+ const parameter = parameters[i];
+ if (uniq[parameter]) {
+ throw new Twig.Error('Duplicate arguments for parameter: ' + parameter);
+ } else {
+ uniq[parameter] = 1;
}
}
}
token.macroName = macroName;
token.parameters = parameters;
+ token.defaults = rawParameters.reduce(function (defaults, rawParameter) {
+ const pair = rawParameter.split(/\s*=\s*/);
+ const key = pair[0];
+ const expression = pair[1];
+
+ if (expression) {
+ defaults[key] = Twig.expression.compile.call(this, {
+ type: Twig.expression.type.expression,
+ value: expression
+ }).stack;
+ } else {
+ defaults[key] = undefined;
+ }
+
+ return defaults;
+ }, {});
delete token.match;
return token;
},
- parse: function (token, context, chain) {
- var template = this;
- this.macros[token.macroName] = function() {
+ parse(token, context, chain) {
+ const state = this;
+
+ state.macros[token.macroName] = function (...args) {
// Pass global context and other macros
- var macroContext = {
- _self: template.macros
- }
- // Add parameters from context to macroContext
- for (var i=0; i {
+ macroContext[prop] = value;
+ return Twig.Promise.resolve();
+ });
+ }
+
+ macroContext[prop] = undefined;
+ return true;
+ }).then(() => {
+ // Render
+ return state.parseAsync(token.output, macroContext);
+ });
};
return {
- chain: chain,
+ chain,
output: ''
};
-
}
},
{
@@ -748,83 +1047,88 @@ var Twig = (function (Twig) {
*
* Format: {% endmacro %}
*/
- type: Twig.logic.type.endmacro,
- regex: /^endmacro$/,
- next: [ ],
- open: false
+ type: Twig.logic.type.endmacro,
+ regex: /^endmacro$/,
+ next: [],
+ open: false
},
{
/*
- * import logic tokens.
+ * Import logic tokens.
*
* Format: {% import "template.twig" as form %}
*/
type: Twig.logic.type.import_,
- regex: /^import\s+(.+)\s+as\s+([a-zA-Z0-9_]+)$/,
- next: [ ],
+ regex: /^import\s+(.+)\s+as\s+(\w+)$/,
+ next: [],
open: true,
- compile: function (token) {
- var expression = token.match[1].trim(),
- contextName = token.match[2].trim();
+ compile(token) {
+ const expression = token.match[1].trim();
+ const contextName = token.match[2].trim();
delete token.match;
token.expression = expression;
token.contextName = contextName;
- token.stack = Twig.expression.compile.apply(this, [{
+ token.stack = Twig.expression.compile.call(this, {
type: Twig.expression.type.expression,
value: expression
- }]).stack;
+ }).stack;
return token;
},
- parse: function (token, context, chain) {
- if (token.expression !== "_self") {
- var file = Twig.expression.parse.apply(this, [token.stack, context]);
- var template = this.importMacros(file || token.expression);
- context[token.contextName] = template.render({}, {output: 'macros'});
- }
- else {
- context[token.contextName] = this.macros;
- }
-
- return {
- chain: chain,
+ parse(token, context, chain) {
+ const state = this;
+ const output = {
+ chain,
output: ''
+ };
+
+ if (token.expression === '_self') {
+ context[token.contextName] = state.macros;
+ return output;
}
+ return Twig.expression.parseAsync.call(state, token.stack, context)
+ .then(filePath => {
+ return state.template.importFile(filePath || token.expression);
+ })
+ .then(importTemplate => {
+ const importState = new Twig.ParseState(importTemplate);
+
+ return importState.parseAsync(importTemplate.tokens).then(() => {
+ context[token.contextName] = importState.macros;
+
+ return output;
+ });
+ });
}
},
{
/*
- * from logic tokens.
+ * From logic tokens.
*
* Format: {% from "template.twig" import func as form %}
*/
type: Twig.logic.type.from,
regex: /^from\s+(.+)\s+import\s+([a-zA-Z0-9_, ]+)$/,
- next: [ ],
+ next: [],
open: true,
- compile: function (token) {
- var expression = token.match[1].trim(),
- macroExpressions = token.match[2].trim().split(/[ ,]+/),
- macroNames = {};
-
- for (var i=0; i {
+ return state.template.importFile(filePath || token.expression);
+ })
+ .then(importTemplate => {
+ const importState = new Twig.ParseState(importTemplate);
+
+ return importState.parseAsync(importTemplate.tokens).then(() => {
+ return importState.macros;
+ });
+ });
+ }
+
+ return promise
+ .then(macros => {
+ for (const macroName in token.macroNames) {
+ if (macros[macroName] !== undefined) {
+ context[token.macroNames[macroName]] = macros[macroName];
+ }
+ }
+
+ return {
+ chain,
+ output: ''
+ };
+ });
+ }
+ },
+ {
+ /**
+ * The embed tag combines the behaviour of include and extends.
+ * It allows you to include another template's contents, just like include does.
+ *
+ * Format: {% embed "template.twig" [with {some: 'values'} only] %}
+ */
+ type: Twig.logic.type.embed,
+ regex: /^embed\s+(.+?)(?:\s+(ignore missing))?(?:\s+with\s+([\S\s]+?))?(?:\s+(only))?$/,
+ next: [
+ Twig.logic.type.endembed
+ ],
+ open: true,
+ compile(token) {
+ const {match} = token;
+ const expression = match[1].trim();
+ const ignoreMissing = match[2] !== undefined;
+ const withContext = match[3];
+ const only = ((match[4] !== undefined) && match[4].length);
+
+ delete token.match;
+
+ token.only = only;
+ token.ignoreMissing = ignoreMissing;
+
+ token.stack = Twig.expression.compile.call(this, {
type: Twig.expression.type.expression,
value: expression
- }]).stack;
+ }).stack;
+
+ if (withContext !== undefined) {
+ token.withStack = Twig.expression.compile.call(this, {
+ type: Twig.expression.type.expression,
+ value: withContext.trim()
+ }).stack;
+ }
return token;
},
- parse: function (token, context, chain) {
- var macros;
+ parse(token, context, chain) {
+ let embedContext = {};
+ let promise = Twig.Promise.resolve();
+ let state = this;
- if (token.expression !== "_self") {
- var file = Twig.expression.parse.apply(this, [token.stack, context]);
- var template = this.importMacros(file || token.expression);
- macros = template.render({}, {output: 'macros'});
+ if (!token.only) {
+ embedContext = {...context};
}
- else {
- macros = this.macros;
+
+ if (token.withStack !== undefined) {
+ promise = Twig.expression.parseAsync.call(state, token.withStack, context).then(withContext => {
+ embedContext = {...embedContext, ...withContext};
+ });
}
- for (var macroName in token.macroNames) {
- if (macros.hasOwnProperty(macroName)) {
- context[token.macroNames[macroName]] = macros[macroName];
- }
+ return promise
+ .then(() => {
+ return Twig.expression.parseAsync.call(state, token.stack, embedContext);
+ })
+ .then(fileName => {
+ const embedOverrideTemplate = new Twig.Template({
+ data: token.output,
+ base: state.template.base,
+ path: state.template.path,
+ url: state.template.url,
+ name: state.template.name,
+ method: state.template.method,
+ options: state.template.options
+ });
+
+ try {
+ embedOverrideTemplate.importFile(fileName);
+ } catch (error) {
+ if (token.ignoreMissing) {
+ return '';
+ }
+
+ // Errors preserve references to variables in scope,
+ // this removes `this` from the scope.
+ state = null;
+
+ throw error;
+ }
+
+ embedOverrideTemplate.parentTemplate = fileName;
+
+ return embedOverrideTemplate.renderAsync(
+ embedContext,
+ {
+ isInclude: true
+ }
+ );
+ })
+ .then(output => {
+ return {
+ chain,
+ output
+ };
+ });
+ }
+ },
+ /* Add the {% endembed %} token
+ *
+ */
+ {
+ type: Twig.logic.type.endembed,
+ regex: /^endembed$/,
+ next: [],
+ open: false
+ },
+ {
+ /**
+ * Block logic tokens.
+ *
+ * Format: {% with {some: 'values'} [only] %}
+ */
+ type: Twig.logic.type.with,
+ regex: /^(?:with(?:\s+([\S\s]+?))?)(?:\s|$)(only)?$/,
+ next: [
+ Twig.logic.type.endwith
+ ],
+ open: true,
+ compile(token) {
+ const {match} = token;
+ const withContext = match[1];
+ const only = ((match[2] !== undefined) && match[2].length);
+
+ delete token.match;
+
+ token.only = only;
+
+ if (withContext !== undefined) {
+ token.withStack = Twig.expression.compile.call(this, {
+ type: Twig.expression.type.expression,
+ value: withContext.trim()
+ }).stack;
}
- return {
- chain: chain,
- output: ''
+ return token;
+ },
+ parse(token, context, chain) {
+ // Resolve filename
+ let innerContext = {};
+ let i;
+ const state = this;
+ let promise = Twig.Promise.resolve();
+
+ if (!token.only) {
+ innerContext = {...context};
}
+ if (token.withStack !== undefined) {
+ promise = Twig.expression.parseAsync.call(state, token.withStack, context)
+ .then(withContext => {
+ for (i in withContext) {
+ if (Object.hasOwnProperty.call(withContext, i)) {
+ innerContext[i] = withContext[i];
+ }
+ }
+ });
+ }
+
+ const isolatedState = new Twig.ParseState(state.template, undefined, innerContext);
+
+ return promise
+ .then(() => {
+ return isolatedState.parseAsync(token.output);
+ })
+ .then(output => {
+ return {
+ chain,
+ output
+ };
+ });
+ }
+ },
+ {
+ type: Twig.logic.type.endwith,
+ regex: /^endwith$/,
+ next: [],
+ open: false
+ },
+ {
+ /**
+ * Deprecated type logic tokens.
+ *
+ * Format: {% deprecated 'Description' %}
+ */
+ type: Twig.logic.type.deprecated,
+ regex: /^deprecated\s+(.+)$/,
+ next: [],
+ open: true,
+ compile(token) {
+ console.warn('Deprecation notice: ' + token.match[1]);
+
+ return token;
+ },
+ parse() {
+ return {};
}
}
];
-
/**
* Registry for logic handlers.
*/
@@ -877,7 +1390,7 @@ var Twig = (function (Twig) {
* Define a new token type, available at Twig.logic.type.{type}
*/
Twig.logic.extendType = function (type, value) {
- value = value || ("Twig.logic.type" + type);
+ value = value || ('Twig.logic.type' + type);
Twig.logic.type[type] = value;
};
@@ -901,16 +1414,12 @@ var Twig = (function (Twig) {
* @param {Object} definition The new logic expression.
*/
Twig.logic.extend = function (definition) {
-
- if (!definition.type) {
- throw new Twig.Error("Unable to extend logic definition. No type provided for " + definition);
- }
- if (Twig.logic.type[definition.type]) {
- throw new Twig.Error("Unable to extend logic definitions. Type " +
- definition.type + " is already defined.");
- } else {
+ if (definition.type) {
Twig.logic.extendType(definition.type);
+ } else {
+ throw new Twig.Error('Unable to extend logic definition. No type provided for ' + definition);
}
+
Twig.logic.handler[definition.type] = definition;
};
@@ -922,19 +1431,19 @@ var Twig = (function (Twig) {
/**
* Compile a logic token into an object ready for parsing.
*
- * @param {Object} raw_token An uncompiled logic token.
+ * @param {Object} rawToken An uncompiled logic token.
*
* @return {Object} A compiled logic token, ready for parsing.
*/
- Twig.logic.compile = function (raw_token) {
- var expression = raw_token.value.trim(),
- token = Twig.logic.tokenize.apply(this, [expression]),
- token_template = Twig.logic.handler[token.type];
+ Twig.logic.compile = function (rawToken) {
+ const expression = rawToken.value.trim();
+ let token = Twig.logic.tokenize.call(this, expression);
+ const tokenTemplate = Twig.logic.handler[token.type];
// Check if the token needs compiling
- if (token_template.compile) {
- token = token_template.compile.apply(this, [token]);
- Twig.log.trace("Twig.logic.compile: ", "Compiled logic token to ", token);
+ if (tokenTemplate.compile) {
+ token = tokenTemplate.compile.call(this, token);
+ Twig.log.trace('Twig.logic.compile: ', 'Compiled logic token to ', token);
}
return token;
@@ -950,47 +1459,46 @@ var Twig = (function (Twig) {
* @return {Object} The matched token with type set to the token type and match to the regex match.
*/
Twig.logic.tokenize = function (expression) {
- var token = {},
- token_template_type = null,
- token_type = null,
- token_regex = null,
- regex_array = null,
- regex = null,
- match = null;
+ let tokenTemplateType = null;
+ let tokenType = null;
+ let tokenRegex = null;
+ let regexArray = null;
+ let regexLen = null;
+ let regexI = null;
+ let match = null;
// Ignore whitespace around expressions.
expression = expression.trim();
- for (token_template_type in Twig.logic.handler) {
- if (Twig.logic.handler.hasOwnProperty(token_template_type)) {
+ for (tokenTemplateType in Twig.logic.handler) {
+ if (Object.hasOwnProperty.call(Twig.logic.handler, tokenTemplateType)) {
// Get the type and regex for this template type
- token_type = Twig.logic.handler[token_template_type].type;
- token_regex = Twig.logic.handler[token_template_type].regex;
+ tokenType = Twig.logic.handler[tokenTemplateType].type;
+ tokenRegex = Twig.logic.handler[tokenTemplateType].regex;
// Handle multiple regular expressions per type.
- regex_array = [];
- if (token_regex instanceof Array) {
- regex_array = token_regex;
- } else {
- regex_array.push(token_regex);
+ regexArray = tokenRegex;
+ if (!Array.isArray(tokenRegex)) {
+ regexArray = [tokenRegex];
}
+ regexLen = regexArray.length;
// Check regular expressions in the order they were specified in the definition.
- while (regex_array.length > 0) {
- regex = regex_array.shift();
- match = regex.exec(expression.trim());
+ for (regexI = 0; regexI < regexLen; regexI++) {
+ match = regexArray[regexI].exec(expression);
if (match !== null) {
- token.type = token_type;
- token.match = match;
- Twig.log.trace("Twig.logic.tokenize: ", "Matched a ", token_type, " regular expression of ", match);
- return token;
+ Twig.log.trace('Twig.logic.tokenize: ', 'Matched a ', tokenType, ' regular expression of ', match);
+ return {
+ type: tokenType,
+ match
+ };
}
}
}
}
// No regex matches
- throw new Twig.Error("Unable to parse '" + expression.trim() + "'");
+ throw new Twig.Error('Unable to parse \'' + expression.trim() + '\'');
};
/**
@@ -1013,22 +1521,34 @@ var Twig = (function (Twig) {
* @param {boolean} chain Is this an open logic chain. If false, that means a
* chain is closed and no further cases should be parsed.
*/
- Twig.logic.parse = function (token, context, chain) {
- var output = '',
- token_template;
+ Twig.logic.parse = function (token, context, chain, allowAsync) {
+ return Twig.async.potentiallyAsync(this, allowAsync, function () {
+ Twig.log.debug('Twig.logic.parse: ', 'Parsing logic token ', token);
+
+ const tokenTemplate = Twig.logic.handler[token.type];
+ let result;
+ const state = this;
- context = context || { };
+ if (!tokenTemplate.parse) {
+ return '';
+ }
- Twig.log.debug("Twig.logic.parse: ", "Parsing logic token ", token);
+ state.nestingStack.unshift(token);
+ result = tokenTemplate.parse.call(state, token, context || {}, chain);
- token_template = Twig.logic.handler[token.type];
+ if (Twig.isPromise(result)) {
+ result = result.then(result => {
+ state.nestingStack.shift();
- if (token_template.parse) {
- output = token_template.parse.apply(this, [token, context, chain]);
- }
- return output;
+ return result;
+ });
+ } else {
+ state.nestingStack.shift();
+ }
+
+ return result;
+ });
};
return Twig;
-
-})(Twig || { });
+};
diff --git a/src/twig.module.js b/src/twig.module.js
deleted file mode 100644
index 59996a85..00000000
--- a/src/twig.module.js
+++ /dev/null
@@ -1,31 +0,0 @@
-// Twig.js
-// Copyright (c) 2011-2013 John Roepke
-// Available under the BSD 2-Clause License
-// https://github.com/justjohn/twig.js
-
-// ## twig.module.js
-// Provide a CommonJS/AMD/Node module export.
-
-if (typeof module !== 'undefined' && module.declare) {
- // Provide a CommonJS Modules/2.0 draft 8 module
- module.declare([], function(require, exports, module) {
- // Add exports from the Twig exports
- for (key in Twig.exports) {
- if (Twig.exports.hasOwnProperty(key)) {
- exports[key] = Twig.exports[key];
- }
- }
- });
-} else if (typeof define == 'function' && define.amd) {
- define(function() {
- return Twig.exports;
- });
-} else if (typeof module !== 'undefined' && module.exports) {
- // Provide a CommonJS Modules/1.1 module
- module.exports = Twig.exports;
-} else {
- // Export for browser use
- window.twig = Twig.exports.twig;
- window.Twig = Twig.exports;
-}
-
diff --git a/src/twig.parser.source.js b/src/twig.parser.source.js
new file mode 100644
index 00000000..d57d91a2
--- /dev/null
+++ b/src/twig.parser.source.js
@@ -0,0 +1,7 @@
+module.exports = function (Twig) {
+ 'use strict';
+
+ Twig.Templates.registerParser('source', params => {
+ return params.data || '';
+ });
+};
diff --git a/src/twig.parser.twig.js b/src/twig.parser.twig.js
new file mode 100644
index 00000000..9778acaa
--- /dev/null
+++ b/src/twig.parser.twig.js
@@ -0,0 +1,7 @@
+module.exports = function (Twig) {
+ 'use strict';
+
+ Twig.Templates.registerParser('twig', params => {
+ return new Twig.Template(params);
+ });
+};
diff --git a/src/twig.path.js b/src/twig.path.js
new file mode 100644
index 00000000..cd66f183
--- /dev/null
+++ b/src/twig.path.js
@@ -0,0 +1,117 @@
+// ## twig.path.js
+//
+// This file handles path parsing
+module.exports = function (Twig) {
+ 'use strict';
+
+ /**
+ * Namespace for path handling.
+ */
+ Twig.path = {};
+
+ /**
+ * @param {Twig.Template} template
+ * @param {string} path
+ */
+ Twig.path.expandNamespace = function (namespaces, path) {
+ const namespaceIdentifiers = Object.keys(namespaces);
+ const pattern = new RegExp(`^(?:@(${namespaceIdentifiers.join('|')})/|(${namespaceIdentifiers.join('|')})::)`);
+
+ return path.replace(pattern, (wholeMatch, atNamespace, colonNamespace) => {
+ const namespaceIdentifier = (atNamespace === undefined ? colonNamespace : atNamespace);
+
+ return `${namespaces[namespaceIdentifier]}/`;
+ });
+ };
+
+ /**
+ * Generate the canonical version of a url based on the given base path and file path and in
+ * the previously registered namespaces.
+ *
+ * @param {string} template The Twig Template
+ * @param {string} _file The file path, may be relative and may contain namespaces.
+ *
+ * @return {string} The canonical version of the path
+ */
+ Twig.path.parsePath = function (template, _file) {
+ const {namespaces} = template.options;
+ const file = _file || '';
+ const hasNamespaces = namespaces && typeof namespaces === 'object';
+
+ let path = (hasNamespaces ? Twig.path.expandNamespace(namespaces, file) : file);
+
+ if (path === file) {
+ path = Twig.path.relativePath(template, file);
+ }
+
+ return path;
+ };
+
+ /**
+ * Generate the relative canonical version of a url based on the given base path and file path.
+ *
+ * @param {Twig.Template} template The Twig.Template.
+ * @param {string} _file The file path, relative to the base path.
+ *
+ * @return {string} The canonical version of the path.
+ */
+ Twig.path.relativePath = function (template, _file) {
+ let base;
+ let basePath;
+ let sepChr = '/';
+ const newPath = [];
+ let file = _file || '';
+ let val;
+
+ if (template.url) {
+ if (typeof template.base === 'undefined') {
+ base = template.url;
+ } else {
+ // Add slash to the end of path
+ base = template.base.replace(/([^/])$/, '$1/');
+ }
+ } else if (template.path) {
+ // Get the system-specific path separator
+ const path = require('path');
+ const sep = path.sep || sepChr;
+ const relative = new RegExp('^\\.{1,2}' + sep.replace('\\', '\\\\'));
+ file = file.replace(/\//g, sep);
+
+ if (template.base !== undefined && file.match(relative) === null) {
+ file = file.replace(template.base, '');
+ base = template.base + sep;
+ } else {
+ base = path.normalize(template.path);
+ }
+
+ base = base.replace(sep + sep, sep);
+ sepChr = sep;
+ } else if ((template.name || template.id) && template.method && template.method !== 'fs' && template.method !== 'ajax') {
+ // Custom registered loader
+ base = template.base || template.name || template.id;
+ } else {
+ throw new Twig.Error('Cannot extend an inline template.');
+ }
+
+ basePath = base.split(sepChr);
+
+ // Remove file from url
+ basePath.pop();
+ basePath = basePath.concat(file.split(sepChr));
+
+ while (basePath.length > 0) {
+ val = basePath.shift();
+ if (val === '.') {
+ // Ignore
+ } else if (val === '..' && newPath.length > 0 && newPath[newPath.length - 1] !== '..') {
+ newPath.pop();
+ } else {
+ newPath.push(val);
+ }
+ }
+
+ return newPath.join(sepChr);
+ };
+
+ return Twig;
+};
diff --git a/src/twig.tests.js b/src/twig.tests.js
index b60a2bba..00faba75 100644
--- a/src/twig.tests.js
+++ b/src/twig.tests.js
@@ -1,62 +1,87 @@
-// Twig.js
-// Copyright (c) 2011-2013 John Roepke
-// Available under the BSD 2-Clause License
-// https://github.com/justjohn/twig.js
-
// ## twig.tests.js
//
// This file handles expression tests. (is empty, is not defined, etc...)
-var Twig = (function (Twig) {
- "use strict";
+module.exports = function (Twig) {
+ 'use strict';
Twig.tests = {
- empty: function(value) {
- if (value === null || value === undefined) return true;
+ empty(value) {
+ // Handle boolean true
+ if (value === true) {
+ return false;
+ }
+
+ // Handle null or undefined
+ if (value === null || value === undefined) {
+ return true;
+ }
+
// Handler numbers
- if (typeof value === "number") return false; // numbers are never "empty"
+ if (typeof value === 'number') {
+ return false;
+ } // Numbers are never "empty"
+
// Handle strings and arrays
- if (value.length && value.length > 0) return false;
+ if (value.length > 0) {
+ return false;
+ }
+
// Handle objects
- for (var key in value) {
- if (value.hasOwnProperty(key)) return false;
+ for (const key in value) {
+ if (Object.hasOwnProperty.call(value, key)) {
+ return false;
+ }
}
+
return true;
},
- odd: function(value) {
+ odd(value) {
return value % 2 === 1;
},
- even: function(value) {
+ even(value) {
return value % 2 === 0;
},
- divisibleby: function(value, params) {
+ 'divisible by'(value, params) {
return value % params[0] === 0;
},
- defined: function(value) {
+ divisibleby(value, params) {
+ console.warn('`divisibleby` is deprecated use `divisible by`');
+ return Twig.tests['divisible by'](value, params);
+ },
+ defined(value) {
return value !== undefined;
},
- none: function(value) {
+ none(value) {
return value === null;
},
- 'null': function(value) {
+ null(value) {
return this.none(value); // Alias of none
},
- sameas: function(value, params) {
+ 'same as'(value, params) {
return value === params[0];
+ },
+ sameas(value, params) {
+ console.warn('`sameas` is deprecated use `same as`');
+ return Twig.tests['same as'](value, params);
+ },
+ iterable(value) {
+ return value && (Twig.lib.is('Array', value) || Twig.lib.is('Object', value));
}
/*
- constant ?
+ Constant ?
*/
};
- Twig.test = function(test, value, params) {
+ Twig.test = function (test, value, params) {
if (!Twig.tests[test]) {
- throw "Test " + test + " is not defined.";
+ throw Twig.Error('Test ' + test + ' is not defined.');
}
+
return Twig.tests[test](value, params);
};
- Twig.test.extend = function(test, definition) {
+ Twig.test.extend = function (test, definition) {
Twig.tests[test] = definition;
};
return Twig;
-})( Twig || { } );
+};
diff --git a/test-ext/test.original.js b/test-ext/test.original.js
index 27304e2a..ef43e66b 100644
--- a/test-ext/test.original.js
+++ b/test-ext/test.original.js
@@ -1,245 +1,242 @@
-/*jshint node: true */
-
-( function( ) {
- "use strict";
- var fs = require( "fs" ),
- path = require("path"),
- twigPhpDir = "test-ext/twig.php",
-
- runTest = function( ) {
- describe( "Twig original test ->", function( ) {
- var
- Twig = Twig || require("../twig"),
- twig = twig || Twig.twig,
- walk = function( dir, done ) {
- var results = [],
- list = fs.readdirSync( dir ),
- i = 0;
-
- ( function next( ) {
- var file = list[i++],
- stat;
- if ( !file ) {
- return done( null, results );
- }
-
- file = dir + '/' + file;
- stat = fs.statSync( file );
- if ( stat && stat.isDirectory( ) ) {
- walk( file, function( err, res ) {
- results = results.concat( res );
- next( );
- } );
- } else {
- results.push( file );
- next( );
- }
- } )( );
- },
- testFile = function( filepath ) {
- var tmp = fs.readFileSync( filepath, "utf8" ),
- tmp2 = tmp.split( /^--/gm ),
- res = {};
-
- tmp2.forEach( function( data ) {
- if ( !data ) {
- return;
- }
-
- var name = ( "" + data.match( /^[A-Z]+--/ ) || "" ).replace( /--$/, '' );
-
- if ( name ) {
- res[ name ] = data.substring( name.length + 3 ).trim( );
- }
- } );
-
- res.filepath = filepath;
-
- return res;
- };
-
- walk( twigPhpDir + "/test", function( err, files ) {
- var testFiles = [];
-
- files.forEach( function( filepath ) {
- if ( filepath.substring( filepath.length - 5 ) === ".test" ) {
- testFiles.push( testFile( filepath ) );
- }
- } );
-
- testFiles.forEach( function( data, idx ) {
- var Tokenizer = require( "tokenizer" ),
- t = new Tokenizer( ),
- res,
- str = data.DATA,
- currentObject
- ;
-
- if ( !data.DATA || data.DATA.match( /^class|\$|^date_default_timezone_set|new Twig|new SimpleXMLElement|new ArrayObject|new ArrayIterator/ ) ) {
- if ( data.EXCEPTION ) {
- it( data.filepath + " -> " + data.TEST.trim( ), function( ) {
- try {
- twig( {
- "data" : data.TEMPLATE.trim( )
- } )
- .render( res )
- .trim( );
- } catch( exp ) {
- return;
- }
-
- throw "Should have thrown an exception: " + data.EXCEPTION;
- } );
- } else {
- it( data.filepath + " -> " + data.TEST.trim( ), function( ) {
- throw "Unsupported";
- } );
- }
- delete testFiles[ idx ];
- return;
- }
-
- t.on( "token", function( token, type ) {
- // console.log( token, type, res, currentObject );
-
- var tmpObject,
- match,
- tmpLength,
- tmpString,
- parentObject,
- i
- ;
-
- if ( type === 'symbol' ) {
- if ( token === "return" ) {
- return;
- }
- }
-
- if ( type === "whitespace" ) {
- return;
- }
-
- if ( type === "semicolon" ) {
- return;
- }
-
- if ( type === 'array' ) {
- if ( !currentObject ) {
-
- currentObject = {
- "type" : "array",
- "keys" : [],
- "values" : []
- };
- } else {
- tmpObject = currentObject;
- currentObject = {
- "type" : "array",
- "keys" : [],
- "values" : [],
- "parent" : tmpObject
- };
- }
-
- return;
- }
-
- if ( type === "string" ) {
- match = token.match( /^'(([^']*| \\')*)'$/ );
- if ( match && match[1] ) {
- tmpString = match[1];
- } else {
- match = token.match( /^"(([^"]*| \\")*)"$/ );
- if ( match && match[1] ) {
- tmpString = match[1];
- }
- }
-
- if ( tmpString ) {
- currentObject.last_value = tmpString.replace( /\\n/g, "\n" ).replace( /\\r/g, "\r" );
- return;
- }
- }
-
- if ( type === "number" ) {
- currentObject.last_value = parseFloat( token, 10 );
- return;
- }
-
- if ( type === "comma" ) {
- if ( currentObject.last_value ) {
- if ( currentObject.type === "array" ) {
- tmpLength = currentObject.values.length;
- currentObject.keys.push( tmpLength );
- currentObject.values.push( currentObject.last_value );
- delete currentObject.last_value;
-
- return;
- } else if ( currentObject.type === "object" ) {
- currentObject.keys.push( currentObject.last_key );
- currentObject.values.push( currentObject.last_value );
- delete currentObject.last_key;
- delete currentObject.last_value;
- return;
- }
- }
- }
-
- if ( type === "key-label" ) {
- currentObject.type = "object";
- currentObject.last_key = currentObject.last_value;
- delete currentObject.last_value;
-
- return;
- }
-
- if ( type === "end-object" ) {
- if ( currentObject.type === "array" ) {
- if ( currentObject.last_value ) {
- tmpLength = currentObject.values.length;
- currentObject.keys.push( tmpLength );
- currentObject.values.push( currentObject.last_value );
- delete currentObject.last_value;
- }
- } else if ( currentObject.type === "object" ) {
- if ( currentObject.last_key && currentObject.last_value ) {
- currentObject.keys.push( currentObject.last_key );
- currentObject.values.push( currentObject.last_value );
- delete currentObject.last_key;
- delete currentObject.last_value;
- }
- }
-
- if ( currentObject.type === "array" ) {
- tmpObject = [];
- } else if ( currentObject.type === "object" ) {
- tmpObject = {};
- }
-
- for ( i = 0; i < currentObject.values.length; i+=1 ) {
- tmpObject[ currentObject.keys[i] ] = currentObject.values[i];
- }
-
- if ( currentObject.parent ) {
- parentObject = currentObject.parent;
- delete currentObject.parent;
- delete currentObject.last_key;
- delete currentObject.last_value;
- currentObject = parentObject;
- currentObject.last_value = tmpObject;
- } else {
- res = tmpObject;
- currentObject = undefined;
- }
-
- return;
- }
- } );
-
- t.on( "end", function( ) {
- /*
- if ( data.TEST.trim( ) === 'Twig supports the in operator' ) {
+/* jshint node: true */
+
+(function () {
+ 'use strict';
+ const fs = require('fs');
+ const path = require('path');
+ const twigPhpDir = 'test-ext/twig.php';
+
+ const runTest = function () {
+ describe('Twig original test ->', function () {
+ var
+ Twig = Twig || require('..');
+ var twig = twig || Twig.twig;
+ var walk = function (dir, done) {
+ let results = [];
+ const list = fs.readdirSync(dir);
+ let i = 0;
+
+ (function next() {
+ let file = list[i++];
+ let stat;
+ if (!file) {
+ return done(null, results);
+ }
+
+ file = dir + '/' + file;
+ stat = fs.statSync(file);
+ if (stat && stat.isDirectory()) {
+ walk(file, (err, res) => {
+ results = results.concat(res);
+ next();
+ });
+ } else {
+ results.push(file);
+ next();
+ }
+ })();
+ };
+
+ const testFile = function (filepath) {
+ const tmp = fs.readFileSync(filepath, 'utf8');
+ const tmp2 = tmp.split(/^--/gm);
+ const res = {};
+
+ tmp2.forEach(data => {
+ if (!data) {
+ return;
+ }
+
+ const name = (String(data.match(/^[A-Z]+--/)) || '').replace(/--$/, '');
+
+ if (name) {
+ res[name] = data.slice(Math.max(0, name.length + 3)).trim();
+ }
+ });
+
+ res.filepath = filepath;
+
+ return res;
+ };
+
+ walk(twigPhpDir + '/test', (err, files) => {
+ const testFiles = [];
+
+ files.forEach(filepath => {
+ if (filepath.slice(Math.max(0, filepath.length - 5)) === '.test') {
+ testFiles.push(testFile(filepath));
+ }
+ });
+
+ testFiles.forEach((data, idx) => {
+ const Tokenizer = require('tokenizer2');
+ const t = new Tokenizer();
+ let res;
+ const str = data.DATA;
+ let currentObject;
+ if (!data.DATA || data.DATA.match(/^class|\$|^date_default_timezone_set|new Twig|new SimpleXMLElement|new ArrayObject|new ArrayIterator/)) {
+ if (data.EXCEPTION) {
+ it(data.filepath + ' -> ' + data.TEST.trim(), function () {
+ try {
+ twig({
+ data: data.TEMPLATE.trim()
+ })
+ .render(res)
+ .trim();
+ } catch (error) {
+ return;
+ }
+
+ throw 'Should have thrown an exception: ' + data.EXCEPTION;
+ });
+ } else {
+ it(data.filepath + ' -> ' + data.TEST.trim(), function () {
+ throw 'Unsupported';
+ });
+ }
+
+ delete testFiles[idx];
+ return;
+ }
+
+ t.on('token', (token, type) => {
+ // Console.log( token, type, res, currentObject );
+
+ let tmpObject;
+ let match;
+ let tmpLength;
+ let tmpString;
+ let parentObject;
+ let i;
+ if (type === 'symbol') {
+ if (token === 'return') {
+ return;
+ }
+ }
+
+ if (type === 'whitespace') {
+ return;
+ }
+
+ if (type === 'semicolon') {
+ return;
+ }
+
+ if (type === 'array') {
+ if (!currentObject) {
+ currentObject = {
+ type: 'array',
+ keys: [],
+ values: []
+ };
+ } else {
+ tmpObject = currentObject;
+ currentObject = {
+ type: 'array',
+ keys: [],
+ values: [],
+ parent: tmpObject
+ };
+ }
+
+ return;
+ }
+
+ if (type === 'string') {
+ match = token.match(/^'(([^']*| \\')*)'$/);
+ if (match && match[1]) {
+ tmpString = match[1];
+ } else {
+ match = token.match(/^"(([^"]*| \\")*)"$/);
+ if (match && match[1]) {
+ tmpString = match[1];
+ }
+ }
+
+ if (tmpString) {
+ currentObject.last_value = tmpString.replace(/\\n/g, '\n').replace(/\\r/g, '\r');
+ return;
+ }
+ }
+
+ if (type === 'number') {
+ currentObject.last_value = parseFloat(token, 10);
+ return;
+ }
+
+ if (type === 'comma') {
+ if (currentObject.last_value) {
+ if (currentObject.type === 'array') {
+ tmpLength = currentObject.values.length;
+ currentObject.keys.push(tmpLength);
+ currentObject.values.push(currentObject.last_value);
+ delete currentObject.last_value;
+
+ return;
+ }
+
+ if (currentObject.type === 'object') {
+ currentObject.keys.push(currentObject.last_key);
+ currentObject.values.push(currentObject.last_value);
+ delete currentObject.last_key;
+ delete currentObject.last_value;
+ return;
+ }
+ }
+ }
+
+ if (type === 'key-label') {
+ currentObject.type = 'object';
+ currentObject.last_key = currentObject.last_value;
+ delete currentObject.last_value;
+
+ return;
+ }
+
+ if (type === 'end-object') {
+ if (currentObject.type === 'array') {
+ if (currentObject.last_value) {
+ tmpLength = currentObject.values.length;
+ currentObject.keys.push(tmpLength);
+ currentObject.values.push(currentObject.last_value);
+ delete currentObject.last_value;
+ }
+ } else if (currentObject.type === 'object') {
+ if (currentObject.last_key && currentObject.last_value) {
+ currentObject.keys.push(currentObject.last_key);
+ currentObject.values.push(currentObject.last_value);
+ delete currentObject.last_key;
+ delete currentObject.last_value;
+ }
+ }
+
+ if (currentObject.type === 'array') {
+ tmpObject = [];
+ } else if (currentObject.type === 'object') {
+ tmpObject = {};
+ }
+
+ for (i = 0; i < currentObject.values.length; i += 1) {
+ tmpObject[currentObject.keys[i]] = currentObject.values[i];
+ }
+
+ if (currentObject.parent) {
+ parentObject = currentObject.parent;
+ delete currentObject.parent;
+ delete currentObject.last_key;
+ delete currentObject.last_value;
+ currentObject = parentObject;
+ currentObject.last_value = tmpObject;
+ } else {
+ res = tmpObject;
+ currentObject = undefined;
+ }
+ }
+ });
+
+ t.on('end', () => {
+ /*
+ If ( data.TEST.trim( ) === 'Twig supports the in operator' ) {
console.log( data.TEST.trim( ), res, data.DATA );
console.log( "data.TEMPLATE" );
console.log( data.TEMPLATE );
@@ -256,59 +253,58 @@
}
*/
- it( data.filepath + " -> " + data.TEST.trim( ), function( ) {
- twig( {
- "data" : data.TEMPLATE.trim( )
- } )
- .render( res )
- .trim( )
- .should
- .equal( data.EXPECT );
- } );
- } );
-
- t.on( "error", function( err ) {
- // console.log( err );
- } );
-
- t.addRule( /^'([^']|\\')*'$/, 'string' );
- t.addRule( /^"([^"]|\\")*"$/, 'string' );
- t.addRule( /^'([^']|\\')*$/, 'maybe-string' );
- t.addRule( /^"([^"]|\\")*$/, 'maybe-string' );
- t.addRule( /^=$/, 'equal' );
- t.addRule( /^=>$/, 'key-label' );
- t.addRule( /^-\?\d+(\.\d+)?$/, 'number' );
- t.addRule( /^\d+$/, 'number' );
- t.addRule( /^\d+\.$/, 'maybe-float' );
- t.addRule( /^(true|false)$/, 'bool' );
- t.addRule( /^null$/, 'null' );
- t.addRule( /^array\s*\($/, 'array' );
- t.addRule( /^\($/, 'begin-object' );
- t.addRule( /^\)$/, 'end-object' );
- t.addRule( /^\[$/, 'begin-array' );
- t.addRule( /^\]$/, 'end-array' );
- t.addRule( /^,$/, 'comma' );
- t.addRule( /^'$/, 'ping' );
- t.addRule( /^;$/, 'semicolon' );
- t.addRule( /^"$/, 'double-ping' );
- t.addRule( /^\w+$/, "symbol" );
- t.addRule( /^(\s)+$/, 'whitespace' );
-
- t.write( str + " " );
- t.end( );
- } );
- } );
- } );
- },
-
- setup = function( ) {
- var existsSync = fs.existsSync || path.existsSync;
-
- if ( existsSync( twigPhpDir ) ) {
- runTest( );
- return;
- }
- };
-
- setup( );
-} )( );
+ it(data.filepath + ' -> ' + data.TEST.trim(), function () {
+ twig({
+ data: data.TEMPLATE.trim()
+ })
+ .render(res)
+ .trim()
+ .should
+ .equal(data.EXPECT);
+ });
+ });
+
+ t.on('error', err => {
+ // Console.log( err );
+ });
+
+ t.addRule(/^'([^']|\\')*'$/, 'string');
+ t.addRule(/^"([^"]|\\")*"$/, 'string');
+ t.addRule(/^'([^']|\\')*$/, 'maybe-string');
+ t.addRule(/^"([^"]|\\")*$/, 'maybe-string');
+ t.addRule(/^=$/, 'equal');
+ t.addRule(/^=>$/, 'key-label');
+ t.addRule(/^-\?\d+(\.\d+)?$/, 'number');
+ t.addRule(/^\d+$/, 'number');
+ t.addRule(/^\d+\.$/, 'maybe-float');
+ t.addRule(/^(true|false)$/, 'bool');
+ t.addRule(/^null$/, 'null');
+ t.addRule(/^array\s*\($/, 'array');
+ t.addRule(/^\($/, 'begin-object');
+ t.addRule(/^\)$/, 'end-object');
+ t.addRule(/^\[$/, 'begin-array');
+ t.addRule(/^\]$/, 'end-array');
+ t.addRule(/^,$/, 'comma');
+ t.addRule(/^'$/, 'ping');
+ t.addRule(/^;$/, 'semicolon');
+ t.addRule(/^"$/, 'double-ping');
+ t.addRule(/^\w+$/, 'symbol');
+ t.addRule(/^(\s)+$/, 'whitespace');
+
+ t.write(str + ' ');
+ t.end();
+ });
+ });
+ });
+ };
+
+ const setup = function () {
+ const existsSync = fs.existsSync || path.existsSync;
+
+ if (existsSync(twigPhpDir)) {
+ runTest();
+ }
+ };
+
+ setup();
+})();
diff --git a/test/browser/test.block.js b/test/browser/test.block.js
index 0701b30b..2f40573c 100644
--- a/test/browser/test.block.js
+++ b/test/browser/test.block.js
@@ -1,117 +1,119 @@
-var Twig = Twig || require("../twig"),
- twig = twig || Twig.twig;
+const Twig = require('../..').factory();
-describe("Twig.js Blocks ->", function() {
- it("Should load content in blocks that are not replaced", function() {
+const {twig} = Twig;
+describe('Twig.js Blocks ->', function () {
+ it('Should load content in blocks that are not replaced', function () {
twig({
- id: 'remote-no-extends',
+ id: 'remote-no-extends',
href: 'templates/template.twig',
async: false
});
// Load the template
- twig({ref: 'remote-no-extends'}).render({ }).should.equal("Default Title - body" );
+ twig({ref: 'remote-no-extends'}).render({ }).should.equal('Default Title - body');
});
-
- it("Should replace block content from a child template", function(done) {
+ it('Should replace block content from a child template', function (done) {
// Test loading a template from a remote endpoint
twig({
- id: 'child-extends',
+ id: 'child-extends',
href: 'templates/child.twig',
- load: function(template) {
- template.render({ base: "template.twig" }).should.equal( "Other Title - child" );
+ load(template) {
+ template.render({base: 'template.twig'}).should.equal('Other Title - child');
done();
}
});
});
- it("Should support horizontal reuse of blocks", function(done) {
+ it('Should support horizontal reuse of blocks', function (done) {
// Test horizontal reuse
twig({
- id: 'use',
+ id: 'use',
href: 'templates/use.twig',
- load: function(template) {
- template.render({ place: "user" }).should.equal( "Coming soon to a user near you!" );
- done();
- }
- });
- });
-
- it("Should give access to rendered blocks", function(done) {
- // Test rendering and loading one block
- twig({
- id: 'blocks',
- href: 'templates/blocks.twig',
-
- load: function(template) {
- // Render the template with the blocks parameter
- template.render({ place: "block" }, {output: 'blocks'}).msg.should.equal( "Coming soon to a block near you!" );
+ load(template) {
+ template.render({place: 'user'}).should.equal('Coming soon to a user near you!');
done();
}
});
});
- it("should render nested blocks", function(done) {
+ it('should render nested blocks', function (done) {
// Test rendering of blocks within blocks
twig({
- id: 'blocks-nested',
- href: 'templates/blocks-nested.twig',
+ id: 'blocks-nested',
+ href: 'templates/blocks-nested.twig',
- load: function(template) {
- template.render({ }).should.equal( "parent:child" )
+ load(template) {
+ template.render({ }).should.equal('parent:child');
done();
}
- })
+ });
});
- it("should render extended nested blocks", function(done) {
+ it('should render extended nested blocks', function (done) {
// Test rendering of blocks within blocks
twig({
- id: 'child-blocks-nested',
- href: 'templates/child-blocks-nested.twig',
+ id: 'child-blocks-nested',
+ href: 'templates/child-blocks-nested.twig',
- load: function(template) {
- template.render({ base: "template.twig" }).should.equal( "Default Title - parent:child" )
+ load(template) {
+ template.render({base: 'template.twig'}).should.equal('Default Title - parent:child');
done();
}
- })
+ });
});
-
- describe("block function ->", function() {
- it("should render block content from an included block", function(done) {
+ describe('block function ->', function () {
+ it('should render block content from an included block', function (done) {
twig({
- href: 'templates/block-function.twig',
+ href: 'templates/block-function.twig',
- load: function(template) {
+ load(template) {
template.render({
- base: "block-function-parent.twig",
- val: "abcd"
+ base: 'block-function-parent.twig',
+ val: 'abcd'
})
- .should.equal( "Child content = abcd / Result: Child content = abcd" );
-
+ .should.equal('Child content = abcd / Result: Child content = abcd');
+
done();
}
- })
+ });
});
- it("should render block content from a parent block", function(done) {
+ it('should render block content from a parent block', function (done) {
twig({
- href: 'templates/block-parent.twig',
+ href: 'templates/block-parent.twig',
- load: function(template) {
+ load(template) {
template.render({
- base: "block-function-parent.twig"
+ base: 'block-function-parent.twig'
})
- .should.equal( "parent block / Result: parent block" );
+ .should.equal('parent block / Result: parent block');
done();
}
+ });
+ });
+ });
+
+ describe('block shorthand ->', function () {
+ it('should render block content using shorthand syntax', function () {
+ twig({
+ data: '{% set prefix = "shorthand" %}{% block title (prefix ~ " - " ~ blockValue)|title %}'
+ })
+ .render({blockValue: 'test succeeded'})
+ .should.equal('Shorthand - Test Succeeded');
+ });
+ it('should overload blocks from an extended template using shorthand syntax', function () {
+ twig({
+ allowInlineIncludes: true,
+ data: '{% extends "child-extends" %}{% block title "New Title" %}{% block body "new body uses the " ~ base ~ " template" %}'
})
+ .render({base: 'template.twig'})
+ .should.equal('New Title - new body uses the template.twig template');
});
});
});
diff --git a/test/browser/test.browser.js b/test/browser/test.browser.js
index 0ed487a9..a449e44c 100644
--- a/test/browser/test.browser.js
+++ b/test/browser/test.browser.js
@@ -1,86 +1,138 @@
-var Twig = Twig || require("../twig"),
- twig = twig || Twig.twig;
+const Twig = require('../..').factory();
-describe("Twig.js Browser Loading ->", function() {
- it("Should load a template synchronously", function() {
+const {twig} = Twig;
+describe('Twig.js Browser Loading ->', function () {
+ it('Should load a template synchronously', function () {
twig({
- id: 'remote-browser',
+ id: 'remote-browser',
href: 'templates/test.twig',
async: false
});
// Verify the template was loaded
twig({ref: 'remote-browser'}).render({
- test: "reload",
+ test: 'reload',
flag: false
- }).should.equal("Test template = reload\n\n");
+ }).should.equal('Test template = reload\n\n');
});
-
- it("Should trigger the error callback for a missing template", function(done) {
+ it('Should trigger the error callback for a missing template', function (done) {
twig({
href: 'templates/notthere.twig',
- load: function(template) {
- // failure
- throw "Template didn't trigger error callback";
+ load(_) {
+ // Failure
+ throw new Error('Template didn\'t trigger error callback');
},
- error: function(err) {
+ error(err) {
console.log(err);
done();
}
});
});
- it("Should load a template asynchronously", function(done) {
-
+ it('Should load a template asynchronously', function (done) {
// Test loading a template from a remote endpoint asynchronously
twig({
- id: 'remote-browser-async',
+ id: 'remote-browser-async',
href: 'templates/test.twig',
// Callback after template loads
- load: function(template) {
+ load(template) {
template.render({
- test: "yes",
+ test: 'yes',
flag: true
- }).should.equal("Test template = yes\n\nFlag set!");
+ }).should.equal('Test template = yes\n\nFlag set!');
// Verify the template was saved
twig({ref: 'remote-browser-async'}).render({
- test: "reload",
+ test: 'reload',
flag: false
- }).should.equal("Test template = reload\n\n");
+ }).should.equal('Test template = reload\n\n');
done();
}
});
});
- it("should be able to extend to a relative tempalte path", function(done) {
+ it('should be able to extend to a relative template path', function (done) {
// Test loading a template from a remote endpoint
twig({
href: 'templates/child.twig',
- load: function(template) {
- template.render({ base: "template.twig" }).should.equal( "Other Title - child" );
+ load(template) {
+ template.render({base: 'template.twig'}).should.equal('Other Title - child');
done();
}
});
});
- it("should be able to extend to a absolute tempalte path", function(done) {
+ it('should be able to extend to a absolute template path', function (done) {
// Test loading a template from a remote endpoint
twig({
base: 'templates',
href: 'templates/a/child.twig',
- load: function(template) {
- template.render({ base: "b/template.twig" }).should.equal( "Other Title - child" );
+ load(template) {
+ template.render({base: 'b/template.twig'}).should.equal('Other Title - child');
done();
}
});
});
-});
+ it('should load an included template with no context (sync)', function () {
+ twig({
+ id: 'include',
+ href: 'templates/include.twig',
+ async: false
+ });
+
+ // Load the template
+ twig({ref: 'include'}).render({test: 'tst'}).should.equal('BeforeTest template = tst\n\nAfter');
+ });
+
+ it('should load an included template with additional context (sync)', function () {
+ twig({
+ id: 'include-with',
+ href: 'templates/include-with.twig',
+ async: false
+ });
+
+ // Load the template
+ twig({ref: 'include-with'}).render({test: 'tst'}).should.equal('template: before,tst-mid-template: after,tst');
+ });
+
+ it('should load an included template with only additional context (sync)', function () {
+ twig({
+ id: 'include-only',
+ href: 'templates/include-only.twig',
+ async: false
+ });
+ // Load the template
+ twig({ref: 'include-only'}).render({test: 'tst'}).should.equal('template: before,-mid-template: after,');
+ });
+
+ describe('source ->', function () {
+ it('should load the non-compiled template source code', function () {
+ twig({data: '{{ source("templates/source.twig") }}'})
+ .render()
+ .should
+ .equal('{% if isUserNew == true %}\n Hello {{ name }}\n{% else %}\n Welcome back {{ name }}\n{% endif %}\n');
+ });
+
+ it('should indicate if there was a problem loading the template if \'ignore_missing\' is false', function () {
+ twig({data: '{{ source("templates/non-existing-source.twig", false) }}'})
+ .render()
+ .should
+ .equal('Template "templates/non-existing-source.twig" is not defined.');
+ });
+
+ it('should NOT indicate if there was a problem loading the template if \'ignore_missing\' is true', function () {
+ twig({data: '{{ source("templates/non-existing-source.twig", true) }}'})
+ .render()
+ .should
+ .equal('');
+ });
+ });
+});
diff --git a/test/browser/test.macro.js b/test/browser/test.macro.js
index 628d3474..2265f7e0 100644
--- a/test/browser/test.macro.js
+++ b/test/browser/test.macro.js
@@ -1,76 +1,76 @@
-var Twig = Twig || require("../twig"),
- twig = twig || Twig.twig;
+const Twig = require('../..').factory();
-describe("Twig.js Macro ->", function() {
+const {twig} = Twig;
+
+describe('Twig.js Macro ->', function () {
// Test loading a template from a remote endpoint
- it("it should load macro", function() {
+ it('it should load macro', function () {
twig({
- id: 'macro',
+ id: 'macro',
href: 'templates/macro.twig',
async: false
});
// Load the template
- twig({ref: 'macro'}).render({ }).should.equal( '' );
+ twig({ref: 'macro'}).render({ }).should.equal('');
});
-
- it("it should import macro", function() {
+
+ it('it should import macro', function () {
twig({
- id: 'import-macro',
+ id: 'import-macro',
href: 'templates/import.twig',
async: false
});
// Load the template
- twig({ref: 'import-macro'}).render({ }).trim().should.equal( "Hello World" );
+ twig({ref: 'import-macro'}).render({ }).trim().should.equal('Hello World');
});
- it("it should run macro with self reference", function() {
+ it('it should run macro with self reference', function () {
twig({
- id: 'import-macro-self',
+ id: 'import-macro-self',
href: 'templates/macro-self.twig',
async: false
});
// Load the template
- twig({ref: 'import-macro-self'}).render({ }).trim().should.equal( '
' );
+ twig({ref: 'import-macro-self'}).render({ }).trim().should.equal('
');
});
- it("it should run wrapped macro with self reference", function() {
+ it('it should run wrapped macro with self reference', function () {
twig({
- id: 'import-wrapped-macro-self',
+ id: 'import-wrapped-macro-self',
href: 'templates/macro-wrapped.twig',
async: false
});
// Load the template
- twig({ref: 'import-wrapped-macro-self'}).render({ }).trim().should.equal( '
' );
+ twig({ref: 'import-wrapped-macro-self'}).render({ }).trim().should.equal('
');
});
- it("it should run wrapped macro with context and self reference", function() {
+ it('it should run wrapped macro with context and self reference', function () {
twig({
- id: 'import-macro-context-self',
+ id: 'import-macro-context-self',
href: 'templates/macro-context.twig',
async: false
});
// Load the template
- twig({ref: 'import-macro-context-self'}).render({ 'greetings': 'Howdy' }).trim().should.equal( 'Howdy Twigjs' );
+ twig({ref: 'import-macro-context-self'}).render({greetings: 'Howdy'}).trim().should.equal('Howdy Twigjs');
});
- it("it should run wrapped macro inside blocks", function() {
+ it('it should run wrapped macro inside blocks', function () {
twig({
- id: 'import-macro-inside-block',
+ id: 'import-macro-inside-block',
href: 'templates/macro-blocks.twig',
async: false
});
// Load the template
- twig({ref: 'import-macro-inside-block'}).render({ }).trim().should.equal( 'Welcome Twig Js
' );
+ twig({ref: 'import-macro-inside-block'}).render({ }).trim().should.equal('Welcome Twig Js
');
});
- it("it should import selected macros from template", function() {
+ it('it should import selected macros from template', function () {
twig({
- id: 'from-macro-import',
+ id: 'from-macro-import',
href: 'templates/from.twig',
async: false
});
// Load the template
- twig({ref: 'from-macro-import'}).render({ }).trim().should.equal( 'Twig.js
' );
+ twig({ref: 'from-macro-import'}).render({ }).trim().should.equal('Twig.js
');
});
-
});
diff --git a/test/browser/test.namespace.js b/test/browser/test.namespace.js
new file mode 100644
index 00000000..cd5bd980
--- /dev/null
+++ b/test/browser/test.namespace.js
@@ -0,0 +1,104 @@
+const Twig = require('../..').factory();
+
+const {twig} = Twig;
+
+describe('Twig.js Namespaces ->', function () {
+ it('should support namespaces defined with ::', function (done) {
+ twig({
+ namespaces: {test: 'templates/namespaces/'},
+ path: 'templates/namespaces_coloncolon.twig',
+ load(template) {
+ // Render the template
+ template.render({
+ test: 'yes',
+ flag: true
+ }).should.equal('namespaces');
+
+ done();
+ }
+ });
+ });
+
+ it('should support namespaces defined with :: and without slash at the end of the path', function (done) {
+ twig({
+ namespaces: {test: 'templates/namespaces'},
+ path: 'templates/namespaces_coloncolon.twig',
+ load(template) {
+ // Render the template
+ template.render({
+ test: 'yes',
+ flag: true
+ }).should.equal('namespaces');
+
+ done();
+ }
+ });
+ });
+
+ it('should support namespaces defined with @', function (done) {
+ twig({
+ namespaces: {test: 'templates/namespaces/'},
+ path: 'templates/namespaces_@.twig',
+ load(template) {
+ // Render the template
+ template.render({
+ test: 'yes',
+ flag: true
+ }).should.equal('namespaces');
+
+ done();
+ }
+ });
+ });
+
+ it('should support namespaces defined with @ and without slash at the end of the path', function (done) {
+ twig({
+ namespaces: {test: 'templates/namespaces'},
+ path: 'templates/namespaces_@.twig',
+ load(template) {
+ // Render the template
+ template.render({
+ test: 'yes',
+ flag: true
+ }).should.equal('namespaces');
+
+ done();
+ }
+ });
+ });
+
+ it('should support non-namespaced includes with namespaces configured', function (done) {
+ twig({
+ namespaces: {test: 'templates/namespaces/'},
+ path: 'templates/namespaces_without_namespace.twig',
+ load(template) {
+ // Render the template
+ template.render({
+ test: 'yes',
+ flag: true
+ }).should.equal('namespaces\nnamespaces');
+
+ done();
+ }
+ });
+ });
+
+ it('should support multiple namespaces', function (done) {
+ twig({
+ namespaces: {
+ one: 'templates/namespaces/one/',
+ two: 'templates/namespaces/two/'
+ },
+ path: 'templates/namespaces_multiple.twig',
+ load(template) {
+ // Render the template
+ template.render({
+ test: 'yes',
+ flag: true
+ }).should.equal('namespace one\nnamespace two');
+
+ done();
+ }
+ });
+ });
+});
diff --git a/test/compiler/templates/dir_test.twig.js b/test/compiler/templates/dir_test.twig.js
index 02059e94..d5aef400 100644
--- a/test/compiler/templates/dir_test.twig.js
+++ b/test/compiler/templates/dir_test.twig.js
@@ -1,5 +1,4 @@
-module.declare([{ twig: "vendor/twig" }], function (require, exports, module) {
- var twig = require("twig").twig;
- exports.template = twig({id:"templates/dir_test.twig", data:[{"type":"logic","token":{"type":"Twig.logic.type.if","stack":[{"type":"Twig.expression.type.variable","value":"test","match":["test"]}],"output":[{"type":"raw","value":"\n Yep :)\n"}]}},{"type":"logic","token":{"type":"Twig.logic.type.else","match":["else"],"output":[{"type":"raw","value":"\n Nope :(\n"}]}},{"type":"raw","value":"\n"}], precompiled: true});
-
-});
\ No newline at end of file
+module.declare([{twig: 'vendor/twig'}], (require, exports, module) => {
+ const {twig} = require('twig');
+ exports.template = twig({id: 'templates/dir_test.twig', data: [{type: 'logic', token: {type: 'Twig.logic.type.if', stack: [{type: 'Twig.expression.type.variable', value: 'test', match: ['test']}], output: [{type: 'raw', value: '\n Yep :)\n'}]}}, {type: 'logic', token: {type: 'Twig.logic.type.else', match: ['else'], output: [{type: 'raw', value: '\n Nope :(\n'}]}}, {type: 'raw', value: '\n'}], precompiled: true});
+});
diff --git a/test/compiler/templates/sub/sub.twig.js b/test/compiler/templates/sub/sub.twig.js
index 5f90a4da..956b6b12 100644
--- a/test/compiler/templates/sub/sub.twig.js
+++ b/test/compiler/templates/sub/sub.twig.js
@@ -1,5 +1,4 @@
-module.declare([{ twig: "vendor/twig" }], function (require, exports, module) {
- var twig = require("twig").twig;
- exports.template = twig({id:"templates/sub/sub.twig", data:[{"type":"raw","value":"I'm a "},{"type":"output","stack":[{"type":"Twig.expression.type.variable","value":"type","match":["type"]}]},{"type":"raw","value":"\n"}], precompiled: true});
-
-});
\ No newline at end of file
+module.declare([{twig: 'vendor/twig'}], (require, exports, module) => {
+ const {twig} = require('twig');
+ exports.template = twig({id: 'templates/sub/sub.twig', data: [{type: 'raw', value: 'I\'m a '}, {type: 'output', stack: [{type: 'Twig.expression.type.variable', value: 'type', match: ['type']}]}, {type: 'raw', value: '\n'}], precompiled: true});
+});
diff --git a/test/compiler/templates/test.twig.js b/test/compiler/templates/test.twig.js
index ff8394d1..c1434555 100644
--- a/test/compiler/templates/test.twig.js
+++ b/test/compiler/templates/test.twig.js
@@ -1 +1 @@
-twig({id:"templates/test.twig", data:[{"type":"logic","token":{"type":"Twig.logic.type.if","stack":[{"type":"Twig.expression.type.variable","value":"test","match":["test"]}],"output":[{"type":"raw","value":"\n Yep\n"}]}},{"type":"logic","token":{"type":"Twig.logic.type.else","match":["else"],"output":[{"type":"raw","value":"\n Nope\n"}]}},{"type":"raw","value":"\n"}], precompiled: true});
+twig({id: 'templates/test.twig', data: [{type: 'logic', token: {type: 'Twig.logic.type.if', stack: [{type: 'Twig.expression.type.variable', value: 'test', match: ['test']}], output: [{type: 'raw', value: '\n Yep\n'}]}}, {type: 'logic', token: {type: 'Twig.logic.type.else', match: ['else'], output: [{type: 'raw', value: '\n Nope\n'}]}}, {type: 'raw', value: '\n'}], precompiled: true});
diff --git a/test/index.html b/test/index.html
index 51a9bd56..30f36f22 100644
--- a/test/index.html
+++ b/test/index.html
@@ -3,12 +3,11 @@
Mocha Tests
-
+
@@ -21,9 +20,12 @@
+
+
+