pax_global_header00006660000000000000000000000064140124402070014504gustar00rootroot0000000000000052 comment=a9a8e403213583ca90cb7c872d3a22796c37d961 handlebars.js-4.7.7/000077500000000000000000000000001401244020700142415ustar00rootroot00000000000000handlebars.js-4.7.7/.eslintignore000066400000000000000000000005601401244020700167450ustar00rootroot00000000000000.rvmrc .DS_Store /tmp/ *.sublime-project *.sublime-workspace npm-debug.log sauce_connect.log* .idea yarn-error.log node_modules /handlebars-release.tgz .nyc_output # Generated files lib/handlebars/compiler/parser.js /coverage/ /dist/ /integration-testing/*/dist/ # Third-party or files that must remain unchanged /spec/expected/ /spec/vendor # JS-Snippets src/*.js handlebars.js-4.7.7/.eslintrc.js000066400000000000000000000031161401244020700165010ustar00rootroot00000000000000module.exports = { extends: ['eslint:recommended', 'plugin:compat/recommended', 'prettier'], globals: { self: false }, env: { node: true, es6: true }, rules: { 'no-console': 'warn', // temporarily disabled until the violating places are fixed. 'no-func-assign': 'off', 'no-sparse-arrays': 'off', // Best Practices // //----------------// 'default-case': 'warn', 'guard-for-in': 'warn', 'no-alert': 'error', 'no-caller': 'error', 'no-div-regex': 'warn', 'no-eval': 'error', 'no-extend-native': 'error', 'no-extra-bind': 'error', 'no-floating-decimal': 'error', 'no-implied-eval': 'error', 'no-iterator': 'error', 'no-labels': 'error', 'no-lone-blocks': 'error', 'no-loop-func': 'error', 'no-multi-str': 'warn', 'no-global-assign': 'error', 'no-new': 'error', 'no-new-func': 'error', 'no-new-wrappers': 'error', 'no-octal-escape': 'error', 'no-process-env': 'error', 'no-proto': 'error', 'no-return-assign': 'error', 'no-script-url': 'error', 'no-self-compare': 'error', 'no-sequences': 'error', 'no-throw-literal': 'error', 'no-unused-expressions': 'error', 'no-warning-comments': 'warn', 'no-with': 'error', radix: 'error', // Variables // //-----------// 'no-label-var': 'error', 'no-undef-init': 'error', 'no-use-before-define': ['error', 'nofunc'], // ECMAScript 6 // //--------------// 'no-var': 'error' }, parserOptions: { sourceType: 'module', ecmaVersion: 6, ecmaFeatures: {} } }; handlebars.js-4.7.7/.gitattributes000066400000000000000000000002261401244020700171340ustar00rootroot00000000000000# Handlebars-template fixtures in test cases need deterministic eol *.handlebars text eol=lf *.hbs text eol=lf # Lexer files as well *.l text eol=lf handlebars.js-4.7.7/.gitignore000066400000000000000000000004371401244020700162350ustar00rootroot00000000000000.rvmrc .DS_Store /tmp/ *.sublime-project *.sublime-workspace npm-debug.log sauce_connect.log* .idea /yarn-error.log /yarn.lock node_modules /handlebars-release.tgz .nyc_output # Generated files lib/handlebars/compiler/parser.js /coverage/ /dist/ /integration-testing/*/dist/ /spec/tmp/*handlebars.js-4.7.7/.gitmodules000066400000000000000000000001341401244020700164140ustar00rootroot00000000000000[submodule "spec/mustache"] path = spec/mustache url = git://github.com/mustache/spec.git handlebars.js-4.7.7/.prettierignore000066400000000000000000000005301401244020700173020ustar00rootroot00000000000000.rvmrc .DS_Store /tmp/ *.sublime-project *.sublime-workspace npm-debug.log sauce_connect.log* .idea yarn-error.log node_modules /handlebars-release.tgz .nyc_output # Generated files lib/handlebars/compiler/parser.js /coverage/ /dist/ /integration-testing/*/dist/ # Third-party or files that must remain unchanged /spec/expected/ /spec/vendor handlebars.js-4.7.7/.travis.yml000066400000000000000000000025661401244020700163630ustar00rootroot00000000000000language: node_js jobs: include: - stage: test name: check javascript (eslint) node_js: lts/* script: npm run lint - stage: test name: check formatting (prettier) node_js: lts/* script: npm run check-format - stage: test name: check typescript definitions (dtslint) node_js: lts/* script: npm run dtslint - stage: test name: extensive tests and publish to aws script: npm run extensive-tests-and-publish-to-aws env: - S3_BUCKET_NAME=builds.handlebarsjs.com - secure: ckyEe5dzjdFDjmZ6wIrhGm0CFBEnKq8c1dYptfgVV/Q5/nJFGzu8T0yTjouS/ERxzdT2H327/63VCxhFnLCRHrsh4rlW/rCy4XI3O/0TeMLgFPa4TXkO8359qZ4CB44TBb3NsJyQXNMYdJpPLTCVTMpuiqqkFFOr+6OeggR7ufA= - secure: Nm4AgSfsgNB21kgKrF9Tl7qVZU8YYREhouQunFracTcZZh2NZ2XH5aHuSiXCj88B13Cr/jGbJKsZ4T3QS3wWYtz6lkyVOx3H3iI+TMtqhD9RM3a7A4O+4vVN8IioB2YjhEu0OKjwgX5gp+0uF+pLEi7Hpj6fupD3AbbL5uYcKg8= - SAUCE_USERNAME=handlebars - secure: 1VkLQhbsEug4ZMQ52tTOus/WLvW3Etqe7GbCzZfzsI8d2ygJPjFfzU8fNm4pVVwoTI21MaM5AQq7SVPu8DWN1YbDjJycMdY1zO3DsB9aZBxTal98fIB7ZIUce9r5z2EP6mETrsbYjZkeckzIBI0A4UVa+F2BO4KbRDXP1Db3u3I= node_js: '10' - stage: test name: test with latest nodejs-lts node_js: lts/* script: npm run test - stage: test name: test with active nodejs node_js: node script: npm run test cache: npm email: on_failure: change on_success: never git: depth: 100 handlebars.js-4.7.7/CONTRIBUTING.md000066400000000000000000000141521401244020700164750ustar00rootroot00000000000000# How to Contribute ## Reporting Issues Please see our [FAQ](https://github.com/wycats/handlebars.js/blob/master/FAQ.md) for common issues that people run into. Should you run into other issues with the project, please don't hesitate to let us know by filing an [issue][issue]! In general we are going to ask for an example of the problem failing, which can be as simple as a jsfiddle/jsbin/etc. We've put together a jsfiddle [template][jsfiddle] to ease this. (We will keep this link up to date as new releases occur, so feel free to check back here) Pull requests containing only failing tests demonstrating the issue are welcomed and this also helps ensure that your issue won't regress in the future once it's fixed. Documentation issues on the handlebarsjs.com site should be reported on [handlebars-site](https://github.com/wycats/handlebars-site). ## Branches - The branch `4.x` contains the currently released version. Bugfixes should be made in this branch. - The branch `master` contains the next version. A release date is not yet specified. Maintainers should merge the branch `4.x` into the master branch regularly. ## Pull Requests We also accept [pull requests][pull-request]! Generally we like to see pull requests that - Maintain the existing code style - Are focused on a single change (i.e. avoid large refactoring or style adjustments in untouched code if not the primary goal of the pull request) - Have [good commit messages](http://tbaggery.com/2008/04/19/a-note-about-git-commit-messages.html) - Have tests - Don't significantly decrease the current code coverage (see coverage/lcov-report/index.html) ## Building To build Handlebars.js you'll need a few things installed. - Node.js - [Grunt](http://gruntjs.com/getting-started) Before building, you need to make sure that the Git submodule `spec/mustache` is included (i.e. the directory `spec/mustache` should not be empty). To include it, if using Git version 1.6.5 or newer, use `git clone --recursive` rather than `git clone`. Or, if you already cloned without `--recursive`, use `git submodule update --init`. Project dependencies may be installed via `npm install`. To build Handlebars.js from scratch, you'll want to run `grunt` in the root of the project. That will build Handlebars and output the results to the dist/ folder. To re-run tests, run `grunt test` or `npm test`. You can also run our set of benchmarks with `grunt bench`. The `grunt dev` implements watching for tests and allows for in browser testing at `http://localhost:9999/spec/`. If you notice any problems, please report them to the GitHub issue tracker at [http://github.com/wycats/handlebars.js/issues](http://github.com/wycats/handlebars.js/issues). ##Running Tests To run tests locally, first install all dependencies. ```sh npm install ``` Clone the mustache specs into the spec/mustache folder. ```sh cd spec rm -r mustache git clone https://github.com/mustache/spec.git mustache ``` From the root directory, run the tests. ```sh npm test ``` ## Linting and Formatting Handlebars uses `eslint` to enforce best-practices and `prettier` to auto-format files. We do linting and formatting in two phases: - Committed files are linted and formatted in a pre-commit hook. In this stage eslint-errors are forbidden, while warnings are allowed. - The travis-ci job also lints all files and checks if they are formatted correctly. In this stage, warnings are forbidden. You can use the following scripts to make sure that the travis-job does not fail: - **npm run lint** will run `eslint` and fail on warnings - **npm run format** will run `prettier` on all files - **npm run check-before-pull-request** will perform all most checks that travis does in its build-job, excluding the "integration-test". - **npm run integration-test** will run integration tests (using old NodeJS versions and integrations with webpack, babel and so on) These tests only work on a Linux-machine with `nvm` installed (for running tests in multiple versions of NodeJS). ## Releasing the latest version Before attempting the release Handlebars, please make sure that you have the following authorizations: - Push-access to `wycats/handlebars.js` - Publishing rights on npmjs.com for the `handlebars` package - Publishing rights on gemfury for the `handlebars-source` package - Push-access to the repo for legacy package managers: `components/handlebars` - Push-access to the production-repo of the handlebars site: `handlebars-lang/handlebarsjs.com-github-pages` _When releasing a previous version of Handlebars, please look into the CONTRIBUNG.md in the corresponding branch._ Handlebars utilizes the [release yeoman generator][generator-release] to perform most release tasks. A full release may be completed with the following: ``` npm ci yo release npm publish yo release:publish components handlebars.js dist/components/ cd dist/components/ gem build handlebars-source.gemspec gem push handlebars-source-*.gem ``` After the release, you should check that all places have really been updated. Especially verify that the `latest`-tags in those places still point to the latest version - [The npm-package](https://www.npmjs.com/package/handlebars) (check latest-tag) - [The bower package](https://github.com/components/handlebars.js) (check the package.json) - [The AWS S3 Bucket](https://s3.amazonaws.com/builds.handlebarsjs.com) (check latest-tag) - [RubyGems](https://rubygems.org/gems/handlebars-source) When everything is OK, the **handlebars site** needs to be updated. Go to the master branch of the repo [handlebars-lang/handlebarsjs.com-github-pages](https://github.com/handlebars-lang/handlebarsjs.com-github-pages/tree/master) and make a minimal change to the README. This will invoke a github-action that redeploys the site, fetching the latest version-number from the npm-registry. (note that the default-branch of this repo is not the master and regular changes are done in the `handlebars-lang/docs`-repo). [generator-release]: https://github.com/walmartlabs/generator-release [pull-request]: https://github.com/wycats/handlebars.js/pull/new/master [issue]: https://github.com/wycats/handlebars.js/issues/new [jsfiddle]: https://jsfiddle.net/9D88g/180/ handlebars.js-4.7.7/FAQ.md000066400000000000000000000072701401244020700152000ustar00rootroot00000000000000# Frequently Asked Questions 1. How can I file a bug report: See our guidelines on [reporting issues](https://github.com/wycats/handlebars.js/blob/master/CONTRIBUTING.md#reporting-issues). 1. Why isn't my Mustache template working? Handlebars deviates from Mustache slightly on a few behaviors. These variations are documented in our [readme](https://github.com/wycats/handlebars.js#differences-between-handlebarsjs-and-mustache). 1. Why is it slower when compiling? The Handlebars compiler must parse the template and construct a JavaScript program which can then be run. Under some environments such as older mobile devices this can have a performance impact which can be avoided by precompiling. Generally it's recommended that precompilation and the runtime library be used on all clients. 1. Why doesn't this work with Content Security Policy restrictions? When not using the precompiler, Handlebars generates a dynamic function for each template which can cause issues with pages that have enabled Content Policy. It's recommended that templates are precompiled or the `unsafe-eval` policy is enabled for sites that must generate dynamic templates at runtime. 1. How can I include script tags in my template? If loading the template via an inlined ` ``` It's generally recommended that templates are served through external, precompiled, files, which do not suffer from this issue. 1. Why are my precompiled scripts throwing exceptions? When using the precompiler, it's important that a supporting version of the Handlebars runtime be loaded on the target page. In version 1.x there were rudimentary checks to compare the version but these did not always work. This is fixed under 2.x but the version checking does not work between these two versions. If you see unexpected errors such as `undefined is not a function` or similar, please verify that the same version is being used for both the precompiler and the client. This can be checked via: ```sh handlebars --version ``` If using the integrated precompiler and ```javascript console.log(Handlebars.VERSION); ``` On the client side. We include the built client libraries in the npm package for those who want to be certain that they are using the same client libraries as the compiler. Should these match, please file an issue with us, per our [issue filing guidelines](https://github.com/wycats/handlebars.js/blob/master/CONTRIBUTING.md#reporting-issues). 1. Why doesn't IE like the `default` name in the AMD module? Some browsers such as particular versions of IE treat `default` as a reserved word in JavaScript source files. To safely use this you need to reference this via the `Handlebars['default']` lookup method. This is an unfortunate side effect of the shims necessary to backport the Handlebars ES6 code to all current browsers. 1. How do I load the runtime library when using AMD? There are two options for loading under AMD environments. The first is to use the `handlebars.runtime.amd.js` file. This may require a [path mapping](https://github.com/wycats/handlebars.js/blob/master/spec/amd-runtime.html#L31) as well as access via the `default` field. The other option is to load the `handlebars.runtime.js` UMD build, which might not require path configuration and exposes the library as both the module root and the `default` field for compatibility. If not using ES6 transpilers or accessing submodules in the build the former option should be sufficient for most use cases. handlebars.js-4.7.7/Gruntfile.js000066400000000000000000000162371401244020700165470ustar00rootroot00000000000000/* eslint-disable no-process-env */ module.exports = function(grunt) { grunt.initConfig({ pkg: grunt.file.readJSON('package.json'), clean: [ 'tmp', 'dist', 'lib/handlebars/compiler/parser.js', 'integration-testing/**/node_modules' ], copy: { dist: { options: { processContent: function(content) { return ( grunt.template.process( '/**!\n\n @license\n <%= pkg.name %> v<%= pkg.version %>\n\n<%= grunt.file.read("LICENSE") %>\n*/\n' ) + content ); } }, files: [{ expand: true, cwd: 'dist/', src: ['*.js'], dest: 'dist/' }] }, cdnjs: { files: [ { expand: true, cwd: 'dist/', src: ['*.js'], dest: 'dist/cdnjs' } ] }, components: { files: [ { expand: true, cwd: 'components/', src: ['**'], dest: 'dist/components' }, { expand: true, cwd: 'dist/', src: ['*.js'], dest: 'dist/components' } ] } }, babel: { options: { sourceMaps: 'inline', loose: ['es6.modules'], auxiliaryCommentBefore: 'istanbul ignore next' }, amd: { options: { modules: 'amd' }, files: [ { expand: true, cwd: 'lib/', src: '**/!(index).js', dest: 'dist/amd/' } ] }, cjs: { options: { modules: 'common' }, files: [ { cwd: 'lib/', expand: true, src: '**/!(index).js', dest: 'dist/cjs/' } ] } }, webpack: { options: { context: __dirname, module: { loaders: [ // the optional 'runtime' transformer tells babel to require the runtime instead of inlining it. { test: /\.jsx?$/, exclude: /node_modules/, loader: 'babel-loader?optional=runtime&loose=es6.modules&auxiliaryCommentBefore=istanbul%20ignore%20next' } ] }, output: { path: 'dist/', library: 'Handlebars', libraryTarget: 'umd' } }, handlebars: { entry: './lib/handlebars.js', output: { filename: 'handlebars.js' } }, runtime: { entry: './lib/handlebars.runtime.js', output: { filename: 'handlebars.runtime.js' } } }, requirejs: { options: { optimize: 'none', baseUrl: 'dist/amd/' }, dist: { options: { name: 'handlebars', out: 'dist/handlebars.amd.js' } }, runtime: { options: { name: 'handlebars.runtime', out: 'dist/handlebars.runtime.amd.js' } } }, uglify: { options: { mangle: true, compress: true, preserveComments: /(?:^!|@(?:license|preserve|cc_on))/ }, dist: { files: [ { cwd: 'dist/', expand: true, src: ['handlebars*.js', '!*.min.js'], dest: 'dist/', rename: function(dest, src) { return dest + src.replace(/\.js$/, '.min.js'); } } ] } }, concat: { tests: { src: ['spec/!(require).js'], dest: 'tmp/tests.js' } }, connect: { server: { options: { base: '.', hostname: '*', port: 9999 } } }, 'saucelabs-mocha': { all: { options: { build: process.env.TRAVIS_JOB_ID, urls: [ 'http://localhost:9999/spec/?headless=true', 'http://localhost:9999/spec/amd.html?headless=true' ], detailedError: true, concurrency: 4, browsers: [ { browserName: 'chrome' }, { browserName: 'firefox', platform: 'Linux' } // {browserName: 'safari', version: 9, platform: 'OS X 10.11'}, // {browserName: 'safari', version: 8, platform: 'OS X 10.10'}, // { // browserName: 'internet explorer', // version: 11, // platform: 'Windows 8.1' // }, // { // browserName: 'internet explorer', // version: 10, // platform: 'Windows 8' // } ] } }, sanity: { options: { build: process.env.TRAVIS_JOB_ID, urls: [ 'http://localhost:9999/spec/umd.html?headless=true', 'http://localhost:9999/spec/amd-runtime.html?headless=true', 'http://localhost:9999/spec/umd-runtime.html?headless=true' ], detailedError: true, concurrency: 2, browsers: [{ browserName: 'chrome' }] } } }, bgShell: { integrationTests: { cmd: './integration-testing/run-integration-tests.sh', bg: false, fail: true } }, watch: { scripts: { options: { atBegin: true }, files: ['src/*', 'lib/**/*.js', 'spec/**/*.js'], tasks: ['on-file-change'] } } }); // Load tasks from npm grunt.loadNpmTasks('grunt-contrib-clean'); grunt.loadNpmTasks('grunt-contrib-concat'); grunt.loadNpmTasks('grunt-contrib-connect'); grunt.loadNpmTasks('grunt-contrib-copy'); grunt.loadNpmTasks('grunt-contrib-requirejs'); grunt.loadNpmTasks('grunt-contrib-uglify'); grunt.loadNpmTasks('grunt-contrib-watch'); grunt.loadNpmTasks('grunt-babel'); grunt.loadNpmTasks('grunt-bg-shell'); grunt.loadNpmTasks('@knappi/grunt-saucelabs'); grunt.loadNpmTasks('grunt-webpack'); grunt.task.loadTasks('tasks'); this.registerTask( 'build', 'Builds a distributable version of the current project', ['parser', 'node', 'globals'] ); this.registerTask('node', ['babel:cjs']); this.registerTask('globals', ['webpack']); this.registerTask('release', 'Build final packages', [ 'amd', 'uglify', 'test:min', 'copy:dist', 'copy:components', 'copy:cdnjs' ]); this.registerTask('amd', ['babel:amd', 'requirejs']); this.registerTask('test', ['test:bin', 'test:cov']); grunt.registerTask('bench', ['metrics']); if (process.env.SAUCE_ACCESS_KEY) { grunt.registerTask('sauce', ['concat:tests', 'connect', 'saucelabs-mocha']); } else { grunt.registerTask('sauce', []); } // Requires secret properties (saucelabs-credentials etc.) from .travis.yaml grunt.registerTask('extensive-tests-and-publish-to-aws', [ 'default', 'bgShell:integrationTests', 'sauce', 'metrics', 'publish-to-aws' ]); grunt.registerTask('on-file-change', [ 'build', 'amd', 'concat:tests', 'test' ]); // === Primary tasks === grunt.registerTask('dev', ['clean', 'connect', 'watch']); grunt.registerTask('default', ['clean', 'build', 'test', 'release']); grunt.registerTask('integration-tests', [ 'default', 'bgShell:integrationTests' ]); }; handlebars.js-4.7.7/LICENSE000066400000000000000000000020471401244020700152510ustar00rootroot00000000000000Copyright (C) 2011-2019 by Yehuda Katz 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. handlebars.js-4.7.7/README.markdown000066400000000000000000000215201401244020700167420ustar00rootroot00000000000000[![Travis Build Status](https://img.shields.io/travis/wycats/handlebars.js/master.svg)](https://travis-ci.org/wycats/handlebars.js) [![Appveyor Build Status](https://ci.appveyor.com/api/projects/status/github/wycats/handlebars.js?branch=master&svg=true)](https://ci.appveyor.com/project/wycats/handlebars-js) [![Selenium Test Status](https://saucelabs.com/buildstatus/handlebars)](https://saucelabs.com/u/handlebars) Handlebars.js ============= Handlebars.js is an extension to the [Mustache templating language](http://mustache.github.com/) created by Chris Wanstrath. Handlebars.js and Mustache are both logicless templating languages that keep the view and the code separated like we all know they should be. Checkout the official Handlebars docs site at [https://handlebarsjs.com/](https://handlebarsjs.com) and the live demo at [http://tryhandlebarsjs.com/](http://tryhandlebarsjs.com/). Installing ---------- See our [installation documentation](https://handlebarsjs.com/installation/). Usage ----- In general, the syntax of Handlebars.js templates is a superset of Mustache templates. For basic syntax, check out the [Mustache manpage](http://mustache.github.com/mustache.5.html). Once you have a template, use the `Handlebars.compile` method to compile the template into a function. The generated function takes a context argument, which will be used to render the template. ```js var source = "

Hello, my name is {{name}}. I am from {{hometown}}. I have " + "{{kids.length}} kids:

" + ""; var template = Handlebars.compile(source); var data = { "name": "Alan", "hometown": "Somewhere, TX", "kids": [{"name": "Jimmy", "age": "12"}, {"name": "Sally", "age": "4"}]}; var result = template(data); // Would render: //

Hello, my name is Alan. I am from Somewhere, TX. I have 2 kids:

// ``` Full documentation and more examples are at [handlebarsjs.com](https://handlebarsjs.com/). Precompiling Templates ---------------------- Handlebars allows templates to be precompiled and included as javascript code rather than the handlebars template allowing for faster startup time. Full details are located [here](https://handlebarsjs.com/installation/precompilation.html). Differences Between Handlebars.js and Mustache ---------------------------------------------- Handlebars.js adds a couple of additional features to make writing templates easier and also changes a tiny detail of how partials work. - [Nested Paths](https://handlebarsjs.com/guide/expressions.html#path-expressions) - [Helpers](https://handlebarsjs.com/guide/expressions.html#helpers) - [Block Expressions](https://handlebarsjs.com/guide/block-helpers.html#basic-blocks) - [Literal Values](https://handlebarsjs.com/guide/expressions.html#literal-segments) - [Delimited Comments](https://handlebarsjs.com/guide/#template-comments) Block expressions have the same syntax as mustache sections but should not be confused with one another. Sections are akin to an implicit `each` or `with` statement depending on the input data and helpers are explicit pieces of code that are free to implement whatever behavior they like. The [mustache spec](http://mustache.github.io/mustache.5.html) defines the exact behavior of sections. In the case of name conflicts, helpers are given priority. ### Compatibility There are a few Mustache behaviors that Handlebars does not implement. - Handlebars deviates from Mustache slightly in that it does not perform recursive lookup by default. The compile time `compat` flag must be set to enable this functionality. Users should note that there is a performance cost for enabling this flag. The exact cost varies by template, but it's recommended that performance sensitive operations should avoid this mode and instead opt for explicit path references. - The optional Mustache-style lambdas are not supported. Instead Handlebars provides its own lambda resolution that follows the behaviors of helpers. - Alternative delimiters are not supported. Supported Environments ---------------------- Handlebars has been designed to work in any ECMAScript 3 environment. This includes - Node.js - Chrome - Firefox - Safari 5+ - Opera 11+ - IE 6+ Older versions and other runtimes are likely to work but have not been formally tested. The compiler requires `JSON.stringify` to be implemented natively or via a polyfill. If using the precompiler this is not necessary. [![Selenium Test Status](https://saucelabs.com/browser-matrix/handlebars.svg)](https://saucelabs.com/u/handlebars) Performance ----------- In a rough performance test, precompiled Handlebars.js templates (in the original version of Handlebars.js) rendered in about half the time of Mustache templates. It would be a shame if it were any other way, since they were precompiled, but the difference in architecture does have some big performance advantages. Justin Marney, a.k.a. [gotascii](http://github.com/gotascii), confirmed that with an [independent test](http://sorescode.com/2010/09/12/benchmarks.html). The rewritten Handlebars (current version) is faster than the old version, with many [performance tests](https://travis-ci.org/wycats/handlebars.js/builds/33392182#L538) being 5 to 7 times faster than the Mustache equivalent. Upgrading --------- See [release-notes.md](https://github.com/wycats/handlebars.js/blob/master/release-notes.md) for upgrade notes. Known Issues ------------ See [FAQ.md](https://github.com/wycats/handlebars.js/blob/master/FAQ.md) for known issues and common pitfalls. Handlebars in the Wild ---------------------- * [Assemble](http://assemble.io), by [@jonschlinkert](https://github.com/jonschlinkert) and [@doowb](https://github.com/doowb), is a static site generator that uses Handlebars.js as its template engine. * [Cory](https://github.com/leo/cory), by [@leo](https://github.com/leo), is another tiny static site generator * [CoSchedule](http://coschedule.com) An editorial calendar for WordPress that uses Handlebars.js * [dashbars](https://github.com/pismute/dashbars) A modern helper library for Handlebars.js. * [Ember.js](http://www.emberjs.com) makes Handlebars.js the primary way to structure your views, also with automatic data binding support. * [Ghost](https://ghost.org/) Just a blogging platform. * [handlebars_assets](http://github.com/leshill/handlebars_assets): A Rails Asset Pipeline gem from Les Hill (@leshill). * [handlebars-helpers](https://github.com/assemble/handlebars-helpers) is an extensive library with 100+ handlebars helpers. * [handlebars-layouts](https://github.com/shannonmoeller/handlebars-layouts) is a set of helpers which implement extendible and embeddable layout blocks as seen in other popular templating languages. * [hbs](http://github.com/donpark/hbs): An Express.js view engine adapter for Handlebars.js, from Don Park. * [koa-hbs](https://github.com/jwilm/koa-hbs): [koa](https://github.com/koajs/koa) generator based renderer for Handlebars.js. * [jblotus](http://github.com/jblotus) created [http://tryhandlebarsjs.com](http://tryhandlebarsjs.com) for anyone who would like to try out Handlebars.js in their browser. * [jQuery plugin](http://71104.github.io/jquery-handlebars/): allows you to use Handlebars.js with [jQuery](http://jquery.com/). * [Lumbar](http://walmartlabs.github.io/lumbar) provides easy module-based template management for handlebars projects. * [Marionette.Handlebars](https://github.com/hashchange/marionette.handlebars) adds support for Handlebars and Mustache templates to Marionette. * [sammy.js](http://github.com/quirkey/sammy) by Aaron Quint, a.k.a. quirkey, supports Handlebars.js as one of its template plugins. * [SproutCore](http://www.sproutcore.com) uses Handlebars.js as its main templating engine, extending it with automatic data binding support. * [YUI](http://yuilibrary.com/yui/docs/handlebars/) implements a port of handlebars * [Swag](https://github.com/elving/swag) by [@elving](https://github.com/elving) is a growing collection of helpers for handlebars.js. Give your handlebars.js templates some swag son! * [DOMBars](https://github.com/blakeembrey/dombars) is a DOM-based templating engine built on the Handlebars parser and runtime **DEPRECATED** * [promised-handlebars](https://github.com/nknapp/promised-handlebars) is a wrapper for Handlebars that allows helpers to return Promises. * [just-handlebars-helpers](https://github.com/leapfrogtechnology/just-handlebars-helpers) A fully tested lightweight package with common Handlebars helpers. External Resources ------------------ * [Gist about Synchronous and asynchronous loading of external handlebars templates](https://gist.github.com/2287070) Have a project using Handlebars? Send us a [pull request][pull-request]! License ------- Handlebars.js is released under the MIT license. [pull-request]: https://github.com/wycats/handlebars.js/pull/new/master handlebars.js-4.7.7/appveyor.yml000066400000000000000000000014001401244020700166240ustar00rootroot00000000000000# Test against these versions of Node.js environment: matrix: - nodejs_version: "10" platform: - x64 # Install scripts (runs after repo cloning) install: # Get the latest stable version of Node.js - ps: Install-Product node $env:nodejs_version $env:platform # Clone submodules (mustache spec) - cmd: git submodule update --init --recursive # Install modules - cmd: npm ci # Post-install test scripts test_script: # Output useful info for debugging - cmd: node --version - cmd: npm --version # Run tests - cmd: npm run test # Don't actually build build: off on_failure: - cmd: 7z a coverage.zip coverage - cmd: appveyor PushArtifact coverage.zip # Set build version format here instead of in the admin panel version: "{build}" handlebars.js-4.7.7/bench/000077500000000000000000000000001401244020700153205ustar00rootroot00000000000000handlebars.js-4.7.7/bench/.eslintrc000066400000000000000000000003541401244020700171460ustar00rootroot00000000000000{ "extends": "prettier", "globals": { "require": true }, "rules": { // Disabling for tests, for now. "no-path-concat": 0, "no-var": 0, "no-shadow": 0, "handle-callback-err": 0, "no-console": 0 } } handlebars.js-4.7.7/bench/dist-size.js000066400000000000000000000016521401244020700175750ustar00rootroot00000000000000var async = require('neo-async'), fs = require('fs'), zlib = require('zlib'); module.exports = function(grunt, callback) { var distFiles = fs.readdirSync('dist'), distSizes = {}; async.each( distFiles, function(file, callback) { var content; try { content = fs.readFileSync('dist/' + file); } catch (err) { if (err.code === 'EISDIR') { callback(); return; } else { throw err; } } file = file.replace(/\.js/, '').replace(/\./g, '_'); distSizes[file] = content.length; zlib.gzip(content, function(err, data) { if (err) { throw err; } distSizes[file + '_gz'] = data.length; callback(); }); }, function() { grunt.log.writeln( 'Distribution sizes: ' + JSON.stringify(distSizes, undefined, 2) ); callback([distSizes]); } ); }; handlebars.js-4.7.7/bench/index.js000066400000000000000000000004721401244020700167700ustar00rootroot00000000000000var fs = require('fs'); var metrics = fs.readdirSync(__dirname); metrics.forEach(function(metric) { if (metric === 'index.js' || !/(.*)\.js$/.test(metric)) { return; } var name = RegExp.$1; metric = require('./' + name); if (metric instanceof Function) { module.exports[name] = metric; } }); handlebars.js-4.7.7/bench/precompile-size.js000066400000000000000000000014061401244020700207660ustar00rootroot00000000000000var _ = require('underscore'), templates = require('./templates'); module.exports = function(grunt, callback) { // Deferring to here in case we have a build for parser, etc as part of this grunt exec var Handlebars = require('../lib'); var templateSizes = {}; _.each(templates, function(info, template) { var src = info.handlebars, compiled = Handlebars.precompile(src, {}), knownHelpers = Handlebars.precompile(src, { knownHelpersOnly: true, knownHelpers: info.helpers }); templateSizes[template] = compiled.length; templateSizes['knownOnly_' + template] = knownHelpers.length; }); grunt.log.writeln( 'Precompiled sizes: ' + JSON.stringify(templateSizes, undefined, 2) ); callback([templateSizes]); }; handlebars.js-4.7.7/bench/templates/000077500000000000000000000000001401244020700173165ustar00rootroot00000000000000handlebars.js-4.7.7/bench/templates/arguments.js000066400000000000000000000003151401244020700216600ustar00rootroot00000000000000module.exports = { helpers: { foo: function() { return ''; } }, context: { bar: true }, handlebars: '{{foo person "person" 1 true foo=bar foo="person" foo=1 foo=true}}' }; handlebars.js-4.7.7/bench/templates/array-each.js000066400000000000000000000005301401244020700216660ustar00rootroot00000000000000module.exports = { context: { names: [ { name: 'Moe' }, { name: 'Larry' }, { name: 'Curly' }, { name: 'Shemp' } ] }, handlebars: '{{#each names}}{{name}}{{/each}}', dust: '{#names}{name}{/names}', mustache: '{{#names}}{{name}}{{/names}}', eco: '<% for item in @names: %><%= item.name %><% end %>' }; handlebars.js-4.7.7/bench/templates/array-mustache.js000066400000000000000000000003111401244020700225740ustar00rootroot00000000000000module.exports = { context: { names: [ { name: 'Moe' }, { name: 'Larry' }, { name: 'Curly' }, { name: 'Shemp' } ] }, handlebars: '{{#names}}{{name}}{{/names}}' }; handlebars.js-4.7.7/bench/templates/complex.dust000066400000000000000000000003661401244020700216730ustar00rootroot00000000000000

{header}

{?items} {:else}

The list is empty.

{/items} handlebars.js-4.7.7/bench/templates/complex.eco000066400000000000000000000005211401244020700214530ustar00rootroot00000000000000

<%= @header() %>

<% if @items.length: %> <% else: %>

The list is empty.

<% end %> handlebars.js-4.7.7/bench/templates/complex.handlebars000066400000000000000000000004101401244020700230050ustar00rootroot00000000000000

{{header}}

{{#if items}} {{^}}

The list is empty.

{{/if}} handlebars.js-4.7.7/bench/templates/complex.js000066400000000000000000000012461401244020700213260ustar00rootroot00000000000000var fs = require('fs'); module.exports = { context: { header: function() { return 'Colors'; }, hasItems: true, // To make things fairer in mustache land due to no `{{if}}` construct on arrays items: [ { name: 'red', current: true, url: '#Red' }, { name: 'green', current: false, url: '#Green' }, { name: 'blue', current: false, url: '#Blue' } ] }, handlebars: fs.readFileSync(__dirname + '/complex.handlebars').toString(), dust: fs.readFileSync(__dirname + '/complex.dust').toString(), eco: fs.readFileSync(__dirname + '/complex.eco').toString(), mustache: fs.readFileSync(__dirname + '/complex.mustache').toString() }; handlebars.js-4.7.7/bench/templates/complex.mustache000066400000000000000000000004041401244020700225160ustar00rootroot00000000000000

{{header}}

{{#hasItems}} {{/hasItems}} handlebars.js-4.7.7/bench/templates/data.js000066400000000000000000000003271401244020700205670ustar00rootroot00000000000000module.exports = { context: { names: [ { name: 'Moe' }, { name: 'Larry' }, { name: 'Curly' }, { name: 'Shemp' } ] }, handlebars: '{{#each names}}{{@index}}{{name}}{{/each}}' }; handlebars.js-4.7.7/bench/templates/depth-1.js000066400000000000000000000005021401244020700211130ustar00rootroot00000000000000module.exports = { context: { names: [ { name: 'Moe' }, { name: 'Larry' }, { name: 'Curly' }, { name: 'Shemp' } ], foo: 'bar' }, handlebars: '{{#each names}}{{../foo}}{{/each}}', mustache: '{{#names}}{{foo}}{{/names}}', eco: '<% for item in @names: %><%= @foo %><% end %>' }; handlebars.js-4.7.7/bench/templates/depth-2.js000066400000000000000000000007641401244020700211260ustar00rootroot00000000000000module.exports = { context: { names: [ { bat: 'foo', name: ['Moe'] }, { bat: 'foo', name: ['Larry'] }, { bat: 'foo', name: ['Curly'] }, { bat: 'foo', name: ['Shemp'] } ], foo: 'bar' }, handlebars: '{{#each names}}{{#each name}}{{../bat}}{{../../foo}}{{/each}}{{/each}}', mustache: '{{#names}}{{#name}}{{bat}}{{foo}}{{/name}}{{/names}}', eco: '<% for item in @names: %><% for child in item.name: %><%= item.bat %><%= @foo %><% end %><% end %>' }; handlebars.js-4.7.7/bench/templates/index.js000066400000000000000000000003701401244020700207630ustar00rootroot00000000000000var fs = require('fs'); var templates = fs.readdirSync(__dirname); templates.forEach(function(template) { if (template === 'index.js' || !/(.*)\.js$/.test(template)) { return; } module.exports[RegExp.$1] = require('./' + RegExp.$1); }); handlebars.js-4.7.7/bench/templates/object-mustache.js000066400000000000000000000001771401244020700227360ustar00rootroot00000000000000module.exports = { context: { person: { name: 'Larry', age: 45 } }, handlebars: '{{#person}}{{name}}{{age}}{{/person}}' }; handlebars.js-4.7.7/bench/templates/object.js000066400000000000000000000004201401244020700211160ustar00rootroot00000000000000module.exports = { context: { person: { name: 'Larry', age: 45 } }, handlebars: '{{#with person}}{{name}}{{age}}{{/with}}', dust: '{#person}{name}{age}{/person}', eco: '<%= @person.name %><%= @person.age %>', mustache: '{{#person}}{{name}}{{age}}{{/person}}' }; handlebars.js-4.7.7/bench/templates/partial-recursion.js000066400000000000000000000007101401244020700233150ustar00rootroot00000000000000module.exports = { context: { name: '1', kids: [{ name: '1.1', kids: [{ name: '1.1.1', kids: [] }] }] }, partials: { mustache: { recursion: '{{name}}{{#kids}}{{>recursion}}{{/kids}}' }, handlebars: { recursion: '{{name}}{{#each kids}}{{>recursion}}{{/each}}' } }, handlebars: '{{name}}{{#each kids}}{{>recursion}}{{/each}}', dust: '{name}{#kids}{>recursion:./}{/kids}', mustache: '{{name}}{{#kids}}{{>recursion}}{{/kids}}' }; handlebars.js-4.7.7/bench/templates/partial.js000066400000000000000000000007651401244020700213200ustar00rootroot00000000000000module.exports = { context: { peeps: [ { name: 'Moe', count: 15 }, { name: 'Larry', count: 5 }, { name: 'Curly', count: 1 } ] }, partials: { mustache: { variables: 'Hello {{name}}! You have {{count}} new messages.' }, handlebars: { variables: 'Hello {{name}}! You have {{count}} new messages.' } }, handlebars: '{{#each peeps}}{{>variables}}{{/each}}', dust: '{#peeps}{>variables/}{/peeps}', mustache: '{{#peeps}}{{>variables}}{{/peeps}}' }; handlebars.js-4.7.7/bench/templates/paths.js000066400000000000000000000007011401244020700207710ustar00rootroot00000000000000module.exports = { context: { person: { name: { bar: { baz: 'Larry' } }, age: 45 } }, handlebars: '{{person.name.bar.baz}}{{person.age}}{{person.foo}}{{animal.age}}', dust: '{person.name.bar.baz}{person.age}{person.foo}{animal.age}', eco: '<%= @person.name.bar.baz %><%= @person.age %><%= @person.foo %><% if @animal: %><%= @animal.age %><% end %>', mustache: '{{person.name.bar.baz}}{{person.age}}{{person.foo}}{{animal.age}}' }; handlebars.js-4.7.7/bench/templates/string.js000066400000000000000000000002111401244020700211540ustar00rootroot00000000000000module.exports = { context: {}, handlebars: 'Hello world', dust: 'Hello world', mustache: 'Hello world', eco: 'Hello world' }; handlebars.js-4.7.7/bench/templates/subexpression.js000066400000000000000000000004241401244020700225650ustar00rootroot00000000000000module.exports = { helpers: { echo: function(value) { return 'foo ' + value; }, header: function() { return 'Colors'; } }, handlebars: '{{echo (header)}}', eco: '<%= @echo(@header()) %>' }; module.exports.context = module.exports.helpers; handlebars.js-4.7.7/bench/templates/variables.js000066400000000000000000000004721401244020700216270ustar00rootroot00000000000000module.exports = { context: { name: 'Mick', count: 30 }, handlebars: 'Hello {{name}}! You have {{count}} new messages.', dust: 'Hello {name}! You have {count} new messages.', mustache: 'Hello {{name}}! You have {{count}} new messages.', eco: 'Hello <%= @name %>! You have <%= @count %> new messages.' }; handlebars.js-4.7.7/bench/throughput.js000066400000000000000000000063421401244020700200740ustar00rootroot00000000000000var _ = require('underscore'), runner = require('./util/template-runner'), eco, dust, Handlebars, Mustache; try { dust = require('dustjs-linkedin'); } catch (err) { /* NOP */ } try { Mustache = require('mustache'); } catch (err) { /* NOP */ } try { eco = require('eco'); } catch (err) { /* NOP */ } function error() { throw new Error('EWOT'); } function makeSuite(bench, name, template, handlebarsOnly) { // Create aliases to minimize any impact from having to walk up the closure tree. var templateName = name, context = template.context, partials = template.partials, handlebarsOut, compatOut, dustOut, ecoOut, mustacheOut; var handlebar = Handlebars.compile(template.handlebars, { data: false }), compat = Handlebars.compile(template.handlebars, { data: false, compat: true }), options = { helpers: template.helpers }; _.each(template.partials && template.partials.handlebars, function( partial, partialName ) { Handlebars.registerPartial( partialName, Handlebars.compile(partial, { data: false }) ); }); handlebarsOut = handlebar(context, options); bench('handlebars', function() { handlebar(context, options); }); compatOut = compat(context, options); bench('compat', function() { compat(context, options); }); if (handlebarsOnly) { return; } if (dust) { if (template.dust) { dustOut = false; dust.loadSource(dust.compile(template.dust, templateName)); dust.render(templateName, context, function(err, out) { dustOut = out; }); bench('dust', function() { dust.render(templateName, context, function() {}); }); } else { bench('dust', error); } } if (eco) { if (template.eco) { var ecoTemplate = eco.compile(template.eco); ecoOut = ecoTemplate(context); bench('eco', function() { ecoTemplate(context); }); } else { bench('eco', error); } } if (Mustache) { var mustacheSource = template.mustache, mustachePartials = partials && partials.mustache; if (mustacheSource) { mustacheOut = Mustache.to_html(mustacheSource, context, mustachePartials); bench('mustache', function() { Mustache.to_html(mustacheSource, context, mustachePartials); }); } else { bench('mustache', error); } } // Hack around whitespace until we have whitespace control handlebarsOut = handlebarsOut.replace(/\s/g, ''); function compare(b, lang) { if (b == null) { return; } b = b.replace(/\s/g, ''); if (handlebarsOut !== b) { throw new Error( 'Template output mismatch: ' + name + '\n\nHandlebars: ' + handlebarsOut + '\n\n' + lang + ': ' + b ); } } compare(compatOut, 'compat'); compare(dustOut, 'dust'); compare(ecoOut, 'eco'); compare(mustacheOut, 'mustache'); } module.exports = function(grunt, callback) { // Deferring load incase we are being run inline with the grunt build Handlebars = require('../lib'); console.log('Execution Throughput'); runner(grunt, makeSuite, function(times, scaled) { callback(scaled); }); }; handlebars.js-4.7.7/bench/util/000077500000000000000000000000001401244020700162755ustar00rootroot00000000000000handlebars.js-4.7.7/bench/util/benchwarmer.js000066400000000000000000000115771401244020700211430ustar00rootroot00000000000000var _ = require('underscore'), Benchmark = require('benchmark'); function BenchWarmer() { this.benchmarks = []; this.currentBenches = []; this.names = []; this.times = {}; this.minimum = Infinity; this.maximum = -Infinity; this.errors = {}; } var print = require('util').print; BenchWarmer.prototype = { winners: function(benches) { return Benchmark.filter(benches, 'fastest'); }, suite: function(suite, fn) { this.suiteName = suite; this.times[suite] = {}; this.first = true; var self = this; fn(function(name, benchFn) { self.push(name, benchFn); }); }, push: function(name, fn) { if (this.names.indexOf(name) === -1) { this.names.push(name); } var first = this.first, suiteName = this.suiteName, self = this; this.first = false; var bench = new Benchmark(fn, { name: this.suiteName + ': ' + name, onComplete: function() { if (first) { self.startLine(suiteName); } self.writeBench(bench); self.currentBenches.push(bench); }, onError: function() { self.errors[this.name] = this; } }); bench.suiteName = this.suiteName; bench.benchName = name; this.benchmarks.push(bench); }, bench: function(callback) { var self = this; this.printHeader('ops/msec', true); Benchmark.invoke(this.benchmarks, { name: 'run', onComplete: function() { self.scaleTimes(); self.startLine(''); print('\n'); self.printHeader('scaled'); _.each(self.scaled, function(value, name) { self.startLine(name); _.each(self.names, function(lang) { self.writeValue(value[lang] || ''); }); }); print('\n'); var errors = false, prop, bench; for (prop in self.errors) { if ( Object.prototype.hasOwnProperty.call(self, prop) && self.errors[prop].error.message !== 'EWOT' ) { errors = true; break; } } if (errors) { print('\n\nErrors:\n'); Object.keys(self.errors).forEach(function(prop) { if (self.errors[prop].error.message !== 'EWOT') { bench = self.errors[prop]; print('\n' + bench.name + ':\n'); print(bench.error.message); if (bench.error.stack) { print(bench.error.stack.join('\n')); } print('\n'); } }); } callback(); } }); print('\n'); }, scaleTimes: function() { var scaled = (this.scaled = {}); _.each( this.times, function(times, name) { var output = (scaled[name] = {}); _.each( times, function(time, lang) { output[lang] = ( ((time - this.minimum) / (this.maximum - this.minimum)) * 100 ).toFixed(2); }, this ); }, this ); }, printHeader: function(title, winners) { var benchSize = 0, names = this.names, i, l; for (i = 0, l = names.length; i < l; i++) { var name = names[i]; if (benchSize < name.length) { benchSize = name.length; } } this.nameSize = benchSize + 2; this.benchSize = 20; var horSize = 0; this.startLine(title); horSize = horSize + this.benchSize; for (i = 0, l = names.length; i < l; i++) { this.writeValue(names[i]); horSize = horSize + this.benchSize; } if (winners) { print('WINNER(S)'); horSize = horSize + 'WINNER(S)'.length; } print('\n' + new Array(horSize + 1).join('-')); }, startLine: function(name) { var winners = Benchmark.map(this.winners(this.currentBenches), function( bench ) { return bench.name.split(': ')[1]; }); this.currentBenches = []; print(winners.join(', ')); print('\n'); if (name) { this.writeValue(name); } }, writeBench: function(bench) { var out; if (!bench.error) { var count = bench.hz, moe = (count * bench.stats.rme) / 100, minimum, maximum; count = Math.round(count / 1000); moe = Math.round(moe / 1000); minimum = count - moe; maximum = count + moe; out = count + ' ±' + moe + ' (' + bench.cycles + ')'; this.times[bench.suiteName][bench.benchName] = count; this.minimum = Math.min(this.minimum, minimum); this.maximum = Math.max(this.maximum, maximum); } else if (bench.error.message === 'EWOT') { out = 'NA'; } else { out = 'E'; } this.writeValue(out); }, writeValue: function(out) { var padding = this.benchSize - out.length + 1; out = out + new Array(padding).join(' '); print(out); } }; module.exports = BenchWarmer; handlebars.js-4.7.7/bench/util/template-runner.js000066400000000000000000000012631401244020700217570ustar00rootroot00000000000000var _ = require('underscore'), BenchWarmer = require('./benchwarmer'), templates = require('../templates'); module.exports = function(grunt, makeSuite, callback) { var warmer = new BenchWarmer(); var handlebarsOnly = grunt.option('handlebars-only'), grep = grunt.option('grep'); if (grep) { grep = new RegExp(grep); } _.each(templates, function(template, name) { if (!template.handlebars || (grep && !grep.test(name))) { return; } warmer.suite(name, function(bench) { makeSuite(bench, name, template, handlebarsOnly); }); }); warmer.bench(function() { if (callback) { callback(warmer.times, warmer.scaled); } }); }; handlebars.js-4.7.7/bin/000077500000000000000000000000001401244020700150115ustar00rootroot00000000000000handlebars.js-4.7.7/bin/.eslintrc.js000066400000000000000000000001121401244020700172420ustar00rootroot00000000000000module.exports = { rules: { 'no-console': 0, 'no-var': 0 } }; handlebars.js-4.7.7/bin/handlebars000077500000000000000000000102241401244020700170410ustar00rootroot00000000000000#!/usr/bin/env node var argv = parseArgs({ 'f': { 'type': 'string', 'description': 'Output File', 'alias': 'output' }, 'map': { 'type': 'string', 'description': 'Source Map File' }, 'a': { 'type': 'boolean', 'description': 'Exports amd style (require.js)', 'alias': 'amd' }, 'c': { 'type': 'string', 'description': 'Exports CommonJS style, path to Handlebars module', 'alias': 'commonjs', 'default': null }, 'h': { 'type': 'string', 'description': 'Path to handlebar.js (only valid for amd-style)', 'alias': 'handlebarPath', 'default': '' }, 'k': { 'type': 'string', 'description': 'Known helpers', 'alias': 'known' }, 'o': { 'type': 'boolean', 'description': 'Known helpers only', 'alias': 'knownOnly' }, 'm': { 'type': 'boolean', 'description': 'Minimize output', 'alias': 'min' }, 'n': { 'type': 'string', 'description': 'Template namespace', 'alias': 'namespace', 'default': 'Handlebars.templates' }, 's': { 'type': 'boolean', 'description': 'Output template function only.', 'alias': 'simple' }, 'N': { 'type': 'string', 'description': 'Name of passed string templates. Optional if running in a simple mode. Required when operating on multiple templates.', 'alias': 'name' }, 'i': { 'type': 'string', 'description': 'Generates a template from the passed CLI argument.\n"-" is treated as a special value and causes stdin to be read for the template value.', 'alias': 'string' }, 'r': { 'type': 'string', 'description': 'Template root. Base value that will be stripped from template names.', 'alias': 'root' }, 'p': { 'type': 'boolean', 'description': 'Compiling a partial template', 'alias': 'partial' }, 'd': { 'type': 'boolean', 'description': 'Include data when compiling', 'alias': 'data' }, 'e': { 'type': 'string', 'description': 'Template extension.', 'alias': 'extension', 'default': 'handlebars' }, 'b': { 'type': 'boolean', 'description': 'Removes the BOM (Byte Order Mark) from the beginning of the templates.', 'alias': 'bom' }, 'v': { 'type': 'boolean', 'description': 'Prints the current compiler version', 'alias': 'version' }, 'help': { 'type': 'boolean', 'description': 'Outputs this message' } }); argv.files = argv._; delete argv._; var Precompiler = require('../dist/cjs/precompiler'); Precompiler.loadTemplates(argv, function(err, opts) { if (err) { throw err; } if (opts.help || (!opts.templates.length && !opts.version)) { printUsage(argv._spec, 120); } else { Precompiler.cli(opts); } }); function pad(n) { var str = ''; while (str.length < n) { str += ' '; } return str; } function parseArgs(spec) { var opts = { alias: {}, boolean: [], default: {}, string: [] }; Object.keys(spec).forEach(function (arg) { var opt = spec[arg]; opts[opt.type].push(arg); if ('alias' in opt) opts.alias[arg] = opt.alias; if ('default' in opt) opts.default[arg] = opt.default; }); var argv = require('minimist')(process.argv.slice(2), opts); argv._spec = spec; return argv; } function printUsage(spec, wrap) { var wordwrap = require('wordwrap'); console.log('Precompile handlebar templates.'); console.log('Usage: handlebars [template|directory]...'); var opts = []; var width = 0; Object.keys(spec).forEach(function (arg) { var opt = spec[arg]; var name = (arg.length === 1 ? '-' : '--') + arg; if ('alias' in opt) name += ', --' + opt.alias; var meta = '[' + opt.type + ']'; if ('default' in opt) meta += ' [default: ' + JSON.stringify(opt.default) + ']'; opts.push({ name: name, desc: opt.description, meta: meta }); if (name.length > width) width = name.length; }); console.log('Options:'); opts.forEach(function (opt) { var desc = wordwrap(width + 4, wrap + 1)(opt.desc); console.log(' %s%s%s%s%s', opt.name, pad(width - opt.name.length + 2), desc.slice(width + 4), pad(wrap - opt.meta.length - desc.split(/\n/).pop().length), opt.meta ); }); } handlebars.js-4.7.7/components/000077500000000000000000000000001401244020700164265ustar00rootroot00000000000000handlebars.js-4.7.7/components/bower.json000066400000000000000000000001661401244020700204420ustar00rootroot00000000000000{ "name": "handlebars", "version": "4.7.7", "main": "handlebars.js", "license": "MIT", "dependencies": {} } handlebars.js-4.7.7/components/component.json000066400000000000000000000002321401244020700213200ustar00rootroot00000000000000{ "name": "handlebars", "repo": "components/handlebars.js", "version": "1.0.0", "main": "handlebars.js", "scripts": [ "handlebars.js" ] } handlebars.js-4.7.7/components/composer.json000066400000000000000000000016011401244020700211460ustar00rootroot00000000000000{ "name": "components/handlebars.js", "description": "Handlebars.js and Mustache are both logicless templating languages that keep the view and the code separated like we all know they should be.", "homepage": "http://handlebarsjs.com", "license": "MIT", "type": "component", "keywords": [ "handlebars", "mustache", "html" ], "authors": [ { "name": "Chris Wanstrath", "homepage": "http://chriswanstrath.com" } ], "require": { "robloach/component-installer": "*" }, "extra": { "component": { "name": "handlebars", "scripts": [ "handlebars.js" ], "files": [ "handlebars.runtime.js" ], "shim": { "exports": "Handlebars" } } } } handlebars.js-4.7.7/components/handlebars-source.gemspec000066400000000000000000000012701401244020700233740ustar00rootroot00000000000000# -*- encoding: utf-8 -*- require 'json' package = JSON.parse(File.read('bower.json')) Gem::Specification.new do |gem| gem.name = "handlebars-source" gem.authors = ["Yehuda Katz"] gem.email = ["wycats@gmail.com"] gem.date = Time.now.strftime("%Y-%m-%d") gem.description = %q{Handlebars.js source code wrapper for (pre)compilation gems.} gem.summary = %q{Handlebars.js source code wrapper} gem.homepage = "https://github.com/wycats/handlebars.js/" gem.version = package["version"].sub "-", "." gem.license = "MIT" gem.files = [ 'handlebars.js', 'handlebars.runtime.js', 'lib/handlebars/source.rb' ] end handlebars.js-4.7.7/components/handlebars.js.nuspec000066400000000000000000000011521401244020700223620ustar00rootroot00000000000000 handlebars.js 4.7.7 handlebars.js Authors https://github.com/wycats/handlebars.js/blob/master/LICENSE https://github.com/wycats/handlebars.js/ false Extension of the Mustache logicless template language handlebars mustache template html handlebars.js-4.7.7/components/lib/000077500000000000000000000000001401244020700171745ustar00rootroot00000000000000handlebars.js-4.7.7/components/lib/handlebars/000077500000000000000000000000001401244020700212775ustar00rootroot00000000000000handlebars.js-4.7.7/components/lib/handlebars/source.rb000066400000000000000000000003671401244020700231320ustar00rootroot00000000000000module Handlebars module Source def self.bundled_path File.expand_path("../../../handlebars.js", __FILE__) end def self.runtime_bundled_path File.expand_path("../../../handlebars.runtime.js", __FILE__) end end end handlebars.js-4.7.7/components/package.json000066400000000000000000000004761401244020700207230ustar00rootroot00000000000000{ "name": "handlebars", "version": "4.7.7", "license": "MIT", "jspm": { "main": "handlebars", "shim": { "handlebars": { "exports": "Handlebars" } }, "files": [ "handlebars.js", "handlebars.runtime.js" ], "buildConfig": { "minify": true } } } handlebars.js-4.7.7/docs/000077500000000000000000000000001401244020700151715ustar00rootroot00000000000000handlebars.js-4.7.7/docs/compiler-api.md000066400000000000000000000240601401244020700200760ustar00rootroot00000000000000# Handlebars Compiler APIs There are a number of formal APIs that tool implementors may interact with. ## AST Other tools may interact with the formal AST as defined below. Any JSON structure matching this pattern may be used and passed into the `compile` and `precompile` methods in the same way as the text for a template. AST structures may be generated either with the `Handlebars.parse` method and then manipulated, via the `Handlebars.AST` objects of the same name, or constructed manually as a generic JavaScript object matching the structure defined below. ```javascript var ast = Handlebars.parse(myTemplate); // Modify ast Handlebars.precompile(ast); ``` ### Parsing There are two primary APIs that are used to parse an existing template into the AST: #### parseWithoutProcessing `Handlebars.parseWithoutProcessing` is the primary mechanism to turn a raw template string into the Handlebars AST described in this document. No processing is done on the resulting AST which makes this ideal for codemod (for source to source transformation) tooling. Example: ```js let ast = Handlebars.parseWithoutProcessing(myTemplate); ``` #### parse `Handlebars.parse` will parse the template with `parseWithoutProcessing` (see above) then it will update the AST to strip extraneous whitespace. The whitespace stripping functionality handles two distinct situations: * Removes whitespace around dynamic statements that are on a line by themselves (aka "stand alone") * Applies "whitespace control" characters (i.e. `~`) by truncating the `ContentStatement` `value` property appropriately (e.g. `\n\n{{~foo}}` would have a `ContentStatement` with a `value` of `''`) `Handlebars.parse` is used internally by `Handlebars.precompile` and `Handlebars.compile`. Example: ```js let ast = Handlebars.parse(myTemplate); ``` ### Basic ```java interface Node { type: string; loc: SourceLocation | null; } interface SourceLocation { source: string | null; start: Position; end: Position; } interface Position { line: uint >= 1; column: uint >= 0; } ``` ### Programs ```java interface Program <: Node { type: "Program"; body: [ Statement ]; blockParams: [ string ]; } ``` ### Statements ```java interface Statement <: Node { } interface MustacheStatement <: Statement { type: "MustacheStatement"; path: PathExpression | Literal; params: [ Expression ]; hash: Hash; escaped: boolean; strip: StripFlags | null; } interface BlockStatement <: Statement { type: "BlockStatement"; path: PathExpression | Literal; params: [ Expression ]; hash: Hash; program: Program | null; inverse: Program | null; openStrip: StripFlags | null; inverseStrip: StripFlags | null; closeStrip: StripFlags | null; } interface PartialStatement <: Statement { type: "PartialStatement"; name: PathExpression | SubExpression; params: [ Expression ]; hash: Hash; indent: string; strip: StripFlags | null; } interface PartialBlockStatement <: Statement { type: "PartialBlockStatement"; name: PathExpression | SubExpression; params: [ Expression ]; hash: Hash; program: Program | null; indent: string; openStrip: StripFlags | null; closeStrip: StripFlags | null; } ``` `name` will be a `SubExpression` when tied to a dynamic partial, i.e. `{{> (foo) }}`, otherwise this is a path or literal whose `original` value is used to lookup the desired partial. ```java interface ContentStatement <: Statement { type: "ContentStatement"; value: string; original: string; } interface CommentStatement <: Statement { type: "CommentStatement"; value: string; strip: StripFlags | null; } ``` ```java interface Decorator <: Statement { type: "Decorator"; path: PathExpression | Literal; params: [ Expression ]; hash: Hash; strip: StripFlags | null; } interface DecoratorBlock <: Statement { type: "DecoratorBlock"; path: PathExpression | Literal; params: [ Expression ]; hash: Hash; program: Program | null; openStrip: StripFlags | null; closeStrip: StripFlags | null; } ``` Decorator paths only utilize the `path.original` value and as a consequence do not support depthed evaluation. ### Expressions ```java interface Expression <: Node { } ``` ##### SubExpressions ```java interface SubExpression <: Expression { type: "SubExpression"; path: PathExpression; params: [ Expression ]; hash: Hash; } ``` ##### Paths ```java interface PathExpression <: Expression { type: "PathExpression"; data: boolean; depth: uint >= 0; parts: [ string ]; original: string; } ``` - `data` is true when the given expression is a `@data` reference. - `depth` is an integer representation of which context the expression references. `0` represents the current context, `1` would be `../`, etc. - `parts` is an array of the names in the path. `foo.bar` would be `['foo', 'bar']`. Scope references, `.`, `..`, and `this` should be omitted from this array. - `original` is the path as entered by the user. Separator and scope references are left untouched. ##### Literals ```java interface Literal <: Expression { } interface StringLiteral <: Literal { type: "StringLiteral"; value: string; original: string; } interface BooleanLiteral <: Literal { type: "BooleanLiteral"; value: boolean; original: boolean; } interface NumberLiteral <: Literal { type: "NumberLiteral"; value: number; original: number; } interface UndefinedLiteral <: Literal { type: "UndefinedLiteral"; } interface NullLiteral <: Literal { type: "NullLiteral"; } ``` ### Miscellaneous ```java interface Hash <: Node { type: "Hash"; pairs: [ HashPair ]; } interface HashPair <: Node { type: "HashPair"; key: string; value: Expression; } interface StripFlags { open: boolean; close: boolean; } ``` `StripFlags` are used to signify whitespace control character that may have been entered on a given statement. ## AST Visitor `Handlebars.Visitor` is available as a base class for general interaction with AST structures. This will by default traverse the entire tree and individual methods may be overridden to provide specific responses to particular nodes. Recording all referenced partial names: ```javascript var Visitor = Handlebars.Visitor; function ImportScanner() { this.partials = []; } ImportScanner.prototype = new Visitor(); ImportScanner.prototype.PartialStatement = function(partial) { this.partials.push({request: partial.name.original}); Visitor.prototype.PartialStatement.call(this, partial); }; var scanner = new ImportScanner(); scanner.accept(ast); ``` The current node's ancestors will be maintained in the `parents` array, with the most recent parent listed first. The visitor may also be configured to operate in mutation mode by setting the `mutation` field to true. When in this mode, handler methods may return any valid AST node and it will replace the one they are currently operating on. Returning `false` will remove the given value (if valid) and returning `undefined` will leave the node in tact. This return structure only apply to mutation mode and non-mutation mode visitors are free to return whatever values they wish. Implementors that may need to support mutation mode are encouraged to utilize the `acceptKey`, `acceptRequired` and `acceptArray` helpers which provide the conditional overwrite behavior as well as implement sanity checks where pertinent. ## JavaScript Compiler The `Handlebars.JavaScriptCompiler` object has a number of methods that may be customized to alter the output of the compiler: - `nameLookup(parent, name, type)` Used to generate the code to resolve a give path component. - `parent` is the existing code in the path resolution - `name` is the current path component - `type` is the type of name being evaluated. May be one of `context`, `data`, `helper`, `decorator`, or `partial`. Note that this does not impact dynamic partials, which implementors need to be aware of. Overriding `VM.resolvePartial` may be required to support dynamic cases. - `depthedLookup(name)` Used to generate code that resolves parameters within any context in the stack. Is only used in `compat` mode. - `compilerInfo()` Allows for custom compiler flags used in the runtime version checking logic. - `appendToBuffer(source, location, explicit)` Allows for code buffer emitting code. Defaults behavior is string concatenation. - `source` is the source code whose result is to be appending - `location` is the location of the source in the source map. - `explicit` is a flag signaling that the emit operation must occur, vs. the lazy evaled options otherwise. - `initializeBuffer()` Allows for buffers other than the default string buffer to be used. Generally needs to be paired with a custom `appendToBuffer` implementation. ### Example for the compiler api. This example changes all lookups of properties are performed by a helper (`lookupLowerCase`) which looks for `test` if `{{Test}}` occurs in the template. This is just to illustrate how compiler behavior can be change. There is also [a jsfiddle with this code](https://jsfiddle.net/9D88g/162/) if you want to play around with it. ```javascript function MyCompiler() { Handlebars.JavaScriptCompiler.apply(this, arguments); } MyCompiler.prototype = new Handlebars.JavaScriptCompiler(); // Use this compile to compile BlockStatment-Blocks MyCompiler.prototype.compiler = MyCompiler MyCompiler.prototype.nameLookup = function(parent, name, type) { if (type === 'context') { return this.source.functionCall('helpers.lookupLowerCase', '', [parent, JSON.stringify(name)]) } else { return Handlebars.JavaScriptCompiler.prototype.nameLookup.call(this, parent, name, type); } } var env = Handlebars.create(); env.registerHelper('lookupLowerCase', function(parent, name) { return parent[name.toLowerCase()] }) env.JavaScriptCompiler = MyCompiler; var template = env.compile('{{#each Test}} ({{Value}}) {{/each}}'); console.log(template({ test: [ {value: 'a'}, {value: 'b'}, {value: 'c'} ] })); ``` handlebars.js-4.7.7/docs/decorators-api.md000066400000000000000000000034541401244020700204350ustar00rootroot00000000000000# Decorators Decorators allow for blocks to be annotated with metadata or wrapped in functionality prior to execution of the block. This may be used to communicate with the containing helper or to setup a particular state in the system prior to running the block. Decorators are registered through similar methods as helpers, `registerDecorators` and `unregisterDecorators`. These can then be referenced via the friendly name in the template using the `{{* decorator}}` and `{{#* decorator}}{/decorator}}` syntaxes. These syntaxes are derivatives of the normal mustache syntax and as such have all of the same argument and whitespace behaviors. Decorators are executed when the block program is instantiated and are passed `(program, props, container, context, data, blockParams, depths)`. - `program`: The block to wrap - `props`: Object used to set metadata on the final function. Any values set on this object will be set on the function, regardless of if the original function is replaced or not. Metadata should be applied using this object as values applied to `program` may be masked by subsequent decorators that may wrap `program`. - `container`: The current runtime container - `context`: The current context. Since the decorator is run before the block that contains it, this is the parent context. - `data`: The current `@data` values - `blockParams`: The current block parameters stack - `depths`: The current context stack Decorators may set values on `props` or return a modified function that wraps `program` in particular behaviors. If the decorator returns nothing, then `program` is left unaltered. The [inline partial](https://github.com/wycats/handlebars.js/blob/master/lib/handlebars/decorators/inline.js) implementation provides an example of decorators being used for both metadata and wrapping behaviors. handlebars.js-4.7.7/integration-testing/000077500000000000000000000000001401244020700202375ustar00rootroot00000000000000handlebars.js-4.7.7/integration-testing/README.md000066400000000000000000000010451401244020700215160ustar00rootroot00000000000000Add a new integration test by creating a new subfolder Add a file "test.sh" to that runs the test. "test.sh" should exit with a non-zero exit code and display an error message, if something goes wrong. * An integration test should reflect real-world setups that use handlebars. * It should compile a minimal template and compare the output to an expected output. * It should use "../.." as dependency for Handlebars so that the currently built library is used. Currently, integration tests are only running on Linux, especially in travis-ci. handlebars.js-4.7.7/integration-testing/multi-nodejs-test/000077500000000000000000000000001401244020700236265ustar00rootroot00000000000000handlebars.js-4.7.7/integration-testing/multi-nodejs-test/.eslintrc.js000066400000000000000000000003301401244020700260610ustar00rootroot00000000000000module.exports = { extends: ['eslint:recommended', 'plugin:es5/no-es2015', 'prettier'], globals: { self: false }, env: { node: true }, rules: { 'no-console': 'off', 'no-var': 'off' } }; handlebars.js-4.7.7/integration-testing/multi-nodejs-test/.gitignore000066400000000000000000000000301401244020700256070ustar00rootroot00000000000000target package-lock.jsonhandlebars.js-4.7.7/integration-testing/multi-nodejs-test/package.json000066400000000000000000000006261401244020700261200ustar00rootroot00000000000000{ "name": "multi-nodejs-test", "version": "1.0.0", "description": "Simple integration test with all relevant NodeJS-versions.", "keywords": [], "author": "Nils Knappmeier", "private": true, "license": "MIT", "dependencies": { "handlebars": "file:../.." }, "scripts": { "test": "node run-handlebars.js", "test-precompile": "handlebars precompile-test-template.txt.hbs" } } handlebars.js-4.7.7/integration-testing/multi-nodejs-test/precompile-test-template.txt.hbs000066400000000000000000000000221401244020700320610ustar00rootroot00000000000000Author: {{author}}handlebars.js-4.7.7/integration-testing/multi-nodejs-test/run-handlebars.js000077500000000000000000000006521401244020700270770ustar00rootroot00000000000000// This test should run successfully with node 0.10++ as long as Handlebars has been compiled before var assert = require('assert'); var Handlebars = require('handlebars'); console.log('Testing built Handlebars with Node version ' + process.version); var template = Handlebars.compile('Author: {{author}}'); var output = template({ author: 'Yehuda' }); assert.strictEqual(output, 'Author: Yehuda'); console.log('Success'); handlebars.js-4.7.7/integration-testing/multi-nodejs-test/test.sh000077500000000000000000000023131401244020700251430ustar00rootroot00000000000000#!/bin/bash set -e cd "$( dirname "$( readlink -f "$0" )" )" || exit 1 # shellcheck disable=SC1090 [ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh" # This script tests with precompiler and the built distribution with multiple NodeJS version. # The rest of the travis-build will only work with newer NodeJS versions, because the build # tools don't support older versions. # However, the built distribution should work with older NodeJS versions as well. # This test is simple by design. It merely ensures, that calling Handlebars does not fail with old versions. # It does (almost) not test for correctness, because that is already done in the mocha-tests. # And it does not use any NodeJS based testing framework to make this part independent of the Node version. unset npm_config_prefix echo "Handlebars should be able to run in various versions of NodeJS" for node_version_to_test in 0.10 0.12 4 5 6 7 8 9 10 11 12 13 14 15; do rm target node_modules package-lock.json -rf mkdir target nvm install "$node_version_to_test" nvm exec "$node_version_to_test" npm install nvm exec "$node_version_to_test" npm run test nvm exec "$node_version_to_test" npm run test-precompile echo Success done handlebars.js-4.7.7/integration-testing/run-integration-tests.sh000077500000000000000000000004411401244020700250620ustar00rootroot00000000000000#!/bin/bash set -e cd "$( dirname "$( readlink -f "$0" )" )" for i in */test.sh ; do ( echo "----------------------------------------" echo "-- Running integration test: $i" echo "----------------------------------------" cd "$( dirname "$i" )" ./test.sh ) done handlebars.js-4.7.7/integration-testing/webpack-babel-test/000077500000000000000000000000001401244020700236735ustar00rootroot00000000000000handlebars.js-4.7.7/integration-testing/webpack-babel-test/.babelrc000066400000000000000000000002411401244020700252630ustar00rootroot00000000000000{ "plugins": [ "@roundingwellos/babel-plugin-handlebars-inline-precompile" // "istanbul" ], "presets": [ [ "@babel/preset-env" ] ] }handlebars.js-4.7.7/integration-testing/webpack-babel-test/.gitignore000066400000000000000000000000431401244020700256600ustar00rootroot00000000000000node_modules dist package-lock.jsonhandlebars.js-4.7.7/integration-testing/webpack-babel-test/package.json000066400000000000000000000011301401244020700261540ustar00rootroot00000000000000{ "name": "webpack-babel-test", "version": "1.0.0", "description": "", "main": "index.js", "keywords": [], "author": "", "license": "ISC", "dependencies": { "@babel/core": "^7.5.5", "@babel/preset-env": "^7.5.5", "@roundingwellos/babel-plugin-handlebars-inline-precompile": "^3.0.1", "babel-loader": "^8.0.6", "babel-plugin-istanbul": "^5.2.0", "handlebars": "file:../..", "handlebars-loader": "^1.7.1", "nyc": "^14.1.1", "webpack": "^4.39.3", "webpack-cli": "^3.3.7" }, "scripts": { "build": "webpack --config webpack.config.js" } } handlebars.js-4.7.7/integration-testing/webpack-babel-test/src/000077500000000000000000000000001401244020700244625ustar00rootroot00000000000000handlebars.js-4.7.7/integration-testing/webpack-babel-test/src/handlebars-inline-precompile-test.js000066400000000000000000000005551401244020700335160ustar00rootroot00000000000000import * as Handlebars from 'handlebars/runtime'; import hbs from 'handlebars-inline-precompile'; import { assertEquals } from '../../webpack-test/src/lib/assert'; Handlebars.registerHelper('loud', function(text) { return text.toUpperCase(); }); const template = hbs`{{loud name}}`; const output = template({ name: 'yehuda' }); assertEquals(output, 'YEHUDA'); handlebars.js-4.7.7/integration-testing/webpack-babel-test/src/lib/000077500000000000000000000000001401244020700252305ustar00rootroot00000000000000handlebars.js-4.7.7/integration-testing/webpack-babel-test/src/lib/assert.js000066400000000000000000000002301401244020700270620ustar00rootroot00000000000000export function assertEquals(actual, expected) { if (actual !== expected) { throw new Error(`Expected "${actual}" to equal "${expected}"`); } } handlebars.js-4.7.7/integration-testing/webpack-babel-test/test.sh000077500000000000000000000004571401244020700252170ustar00rootroot00000000000000#!/bin/bash set -e # Cleanup: package-lock and "npm ci" is not working with local dependencies rm dist package-lock.json -rf npm install npm run build for i in dist/*-test.js ; do echo "----------------------" echo "-- Running $i" echo "----------------------" node "$i" echo "Success" donehandlebars.js-4.7.7/integration-testing/webpack-babel-test/webpack.config.js000066400000000000000000000011101401244020700271020ustar00rootroot00000000000000const fs = require('fs'); const testFiles = fs.readdirSync('src'); const entryPoints = {}; testFiles .filter(file => file.match(/-test.js$/)) .forEach(file => { entryPoints[file] = `./src/${file}`; }); module.exports = { entry: entryPoints, output: { filename: '[name]', path: __dirname + '/dist' }, module: { rules: [ { test: /\.js?$/, exclude: /node_modules/, use: { loader: 'babel-loader', options: { cacheDirectory: false } } } ] }, optimization: { minimize: false } }; handlebars.js-4.7.7/integration-testing/webpack-test/000077500000000000000000000000001401244020700226305ustar00rootroot00000000000000handlebars.js-4.7.7/integration-testing/webpack-test/.gitignore000066400000000000000000000000431401244020700246150ustar00rootroot00000000000000node_modules dist package-lock.jsonhandlebars.js-4.7.7/integration-testing/webpack-test/package.json000066400000000000000000000007421401244020700251210ustar00rootroot00000000000000{ "name": "webpack-test", "description": "Various tests with Handlebars and Webpack", "version": "1.0.0", "main": "index.js", "scripts": { "build": "webpack --config webpack.config.js", "test": "node dist/main.js" }, "private": true, "keywords": [], "author": "", "license": "ISC", "dependencies": {}, "devDependencies": { "handlebars": "file:../..", "handlebars-loader": "^1.7.1", "webpack": "^4.39.3", "webpack-cli": "^3.3.7" } } handlebars.js-4.7.7/integration-testing/webpack-test/src/000077500000000000000000000000001401244020700234175ustar00rootroot00000000000000handlebars.js-4.7.7/integration-testing/webpack-test/src/handlebars-default-import-pre-4.2-test.js000066400000000000000000000003371401244020700330570ustar00rootroot00000000000000import Handlebars from 'handlebars/dist/handlebars'; import { assertEquals } from './lib/assert'; const template = Handlebars.compile('Author: {{author}}'); assertEquals(template({ author: 'Yehuda' }), 'Author: Yehuda'); handlebars.js-4.7.7/integration-testing/webpack-test/src/handlebars-default-import-test.js000066400000000000000000000003161401244020700317670ustar00rootroot00000000000000import Handlebars from 'handlebars'; import { assertEquals } from './lib/assert'; const template = Handlebars.compile('Author: {{author}}'); assertEquals(template({ author: 'Yehuda' }), 'Author: Yehuda'); handlebars.js-4.7.7/integration-testing/webpack-test/src/handlebars-loader-test.js000066400000000000000000000005141401244020700303010ustar00rootroot00000000000000import { assertEquals } from './lib/assert'; import testTemplate from './test-template.handlebars'; assertEquals(testTemplate({ author: 'Yehuda' }).trim(), 'Author: Yehuda'); const testTemplateRequire = require('./test-template.handlebars'); assertEquals( testTemplateRequire({ author: 'Yehuda' }).trim(), 'Author: Yehuda' ); handlebars.js-4.7.7/integration-testing/webpack-test/src/handlebars-require-vs-import-test.js000066400000000000000000000005751401244020700324540ustar00rootroot00000000000000import * as HandlebarsViaImport from 'handlebars'; const HandlebarsViaRequire = require('handlebars'); import { assertEquals } from './lib/assert'; HandlebarsViaImport.registerHelper('loud', function(text) { return text.toUpperCase(); }); const template = HandlebarsViaRequire.compile('Author: {{loud author}}'); assertEquals(template({ author: 'Yehuda' }), 'Author: YEHUDA'); handlebars.js-4.7.7/integration-testing/webpack-test/src/handlebars-wildcard-import-pre-4.2-test.js000066400000000000000000000003441401244020700332220ustar00rootroot00000000000000import * as Handlebars from 'handlebars/dist/handlebars'; import { assertEquals } from './lib/assert'; const template = Handlebars.compile('Author: {{author}}'); assertEquals(template({ author: 'Yehuda' }), 'Author: Yehuda'); handlebars.js-4.7.7/integration-testing/webpack-test/src/handlebars-wildcard-import-test.js000066400000000000000000000003231401244020700321320ustar00rootroot00000000000000import * as Handlebars from 'handlebars'; import { assertEquals } from './lib/assert'; const template = Handlebars.compile('Author: {{author}}'); assertEquals(template({ author: 'Yehuda' }), 'Author: Yehuda'); handlebars.js-4.7.7/integration-testing/webpack-test/src/lib/000077500000000000000000000000001401244020700241655ustar00rootroot00000000000000handlebars.js-4.7.7/integration-testing/webpack-test/src/lib/assert.js000066400000000000000000000002301401244020700260170ustar00rootroot00000000000000export function assertEquals(actual, expected) { if (actual !== expected) { throw new Error(`Expected "${actual}" to equal "${expected}"`); } } handlebars.js-4.7.7/integration-testing/webpack-test/src/test-template.handlebars000066400000000000000000000000241401244020700302300ustar00rootroot00000000000000Author: {{author}} handlebars.js-4.7.7/integration-testing/webpack-test/test.sh000077500000000000000000000004571401244020700241540ustar00rootroot00000000000000#!/bin/bash set -e # Cleanup: package-lock and "npm ci" is not working with local dependencies rm dist package-lock.json -rf npm install npm run build for i in dist/*-test.js ; do echo "----------------------" echo "-- Running $i" echo "----------------------" node "$i" echo "Success" donehandlebars.js-4.7.7/integration-testing/webpack-test/webpack.config.js000066400000000000000000000006351401244020700260520ustar00rootroot00000000000000const fs = require('fs'); const testFiles = fs.readdirSync('src'); const entryPoints = {}; testFiles .filter(file => file.match(/-test.js$/)) .forEach(file => { entryPoints[file] = `./src/${file}`; }); module.exports = { entry: entryPoints, output: { filename: '[name]', path: __dirname + '/dist' }, module: { rules: [{ test: /\.handlebars$/, loader: 'handlebars-loader' }] } }; handlebars.js-4.7.7/lib/000077500000000000000000000000001401244020700150075ustar00rootroot00000000000000handlebars.js-4.7.7/lib/handlebars.js000066400000000000000000000020451401244020700174510ustar00rootroot00000000000000import runtime from './handlebars.runtime'; // Compiler imports import AST from './handlebars/compiler/ast'; import { parser as Parser, parse, parseWithoutProcessing } from './handlebars/compiler/base'; import { Compiler, compile, precompile } from './handlebars/compiler/compiler'; import JavaScriptCompiler from './handlebars/compiler/javascript-compiler'; import Visitor from './handlebars/compiler/visitor'; import noConflict from './handlebars/no-conflict'; let _create = runtime.create; function create() { let hb = _create(); hb.compile = function(input, options) { return compile(input, options, hb); }; hb.precompile = function(input, options) { return precompile(input, options, hb); }; hb.AST = AST; hb.Compiler = Compiler; hb.JavaScriptCompiler = JavaScriptCompiler; hb.Parser = Parser; hb.parse = parse; hb.parseWithoutProcessing = parseWithoutProcessing; return hb; } let inst = create(); inst.create = create; noConflict(inst); inst.Visitor = Visitor; inst['default'] = inst; export default inst; handlebars.js-4.7.7/lib/handlebars.runtime.js000066400000000000000000000017131401244020700211340ustar00rootroot00000000000000import * as base from './handlebars/base'; // Each of these augment the Handlebars object. No need to setup here. // (This is done to easily share code between commonjs and browse envs) import SafeString from './handlebars/safe-string'; import Exception from './handlebars/exception'; import * as Utils from './handlebars/utils'; import * as runtime from './handlebars/runtime'; import noConflict from './handlebars/no-conflict'; // For compatibility and usage outside of module systems, make the Handlebars object a namespace function create() { let hb = new base.HandlebarsEnvironment(); Utils.extend(hb, base); hb.SafeString = SafeString; hb.Exception = Exception; hb.Utils = Utils; hb.escapeExpression = Utils.escapeExpression; hb.VM = runtime; hb.template = function(spec) { return runtime.template(spec, hb); }; return hb; } let inst = create(); inst.create = create; noConflict(inst); inst['default'] = inst; export default inst; handlebars.js-4.7.7/lib/handlebars/000077500000000000000000000000001401244020700171125ustar00rootroot00000000000000handlebars.js-4.7.7/lib/handlebars/base.js000066400000000000000000000047071401244020700203720ustar00rootroot00000000000000import { createFrame, extend, toString } from './utils'; import Exception from './exception'; import { registerDefaultHelpers } from './helpers'; import { registerDefaultDecorators } from './decorators'; import logger from './logger'; import { resetLoggedProperties } from './internal/proto-access'; export const VERSION = '4.7.7'; export const COMPILER_REVISION = 8; export const LAST_COMPATIBLE_COMPILER_REVISION = 7; export const REVISION_CHANGES = { 1: '<= 1.0.rc.2', // 1.0.rc.2 is actually rev2 but doesn't report it 2: '== 1.0.0-rc.3', 3: '== 1.0.0-rc.4', 4: '== 1.x.x', 5: '== 2.0.0-alpha.x', 6: '>= 2.0.0-beta.1', 7: '>= 4.0.0 <4.3.0', 8: '>= 4.3.0' }; const objectType = '[object Object]'; export function HandlebarsEnvironment(helpers, partials, decorators) { this.helpers = helpers || {}; this.partials = partials || {}; this.decorators = decorators || {}; registerDefaultHelpers(this); registerDefaultDecorators(this); } HandlebarsEnvironment.prototype = { constructor: HandlebarsEnvironment, logger: logger, log: logger.log, registerHelper: function(name, fn) { if (toString.call(name) === objectType) { if (fn) { throw new Exception('Arg not supported with multiple helpers'); } extend(this.helpers, name); } else { this.helpers[name] = fn; } }, unregisterHelper: function(name) { delete this.helpers[name]; }, registerPartial: function(name, partial) { if (toString.call(name) === objectType) { extend(this.partials, name); } else { if (typeof partial === 'undefined') { throw new Exception( `Attempting to register a partial called "${name}" as undefined` ); } this.partials[name] = partial; } }, unregisterPartial: function(name) { delete this.partials[name]; }, registerDecorator: function(name, fn) { if (toString.call(name) === objectType) { if (fn) { throw new Exception('Arg not supported with multiple decorators'); } extend(this.decorators, name); } else { this.decorators[name] = fn; } }, unregisterDecorator: function(name) { delete this.decorators[name]; }, /** * Reset the memory of illegal property accesses that have already been logged. * @deprecated should only be used in handlebars test-cases */ resetLoggedPropertyAccesses() { resetLoggedProperties(); } }; export let log = logger.log; export { createFrame, logger }; handlebars.js-4.7.7/lib/handlebars/compiler/000077500000000000000000000000001401244020700207245ustar00rootroot00000000000000handlebars.js-4.7.7/lib/handlebars/compiler/ast.js000066400000000000000000000017271401244020700220600ustar00rootroot00000000000000let AST = { // Public API used to evaluate derived attributes regarding AST nodes helpers: { // a mustache is definitely a helper if: // * it is an eligible helper, and // * it has at least one parameter or hash segment helperExpression: function(node) { return ( node.type === 'SubExpression' || ((node.type === 'MustacheStatement' || node.type === 'BlockStatement') && !!((node.params && node.params.length) || node.hash)) ); }, scopedId: function(path) { return /^\.|this\b/.test(path.original); }, // an ID is simple if it only has one part, and that part is not // `..` or `this`. simpleId: function(path) { return ( path.parts.length === 1 && !AST.helpers.scopedId(path) && !path.depth ); } } }; // Must be exported as an object rather than the root of the module as the jison lexer // must modify the object to operate properly. export default AST; handlebars.js-4.7.7/lib/handlebars/compiler/base.js000066400000000000000000000014651401244020700222020ustar00rootroot00000000000000import parser from './parser'; import WhitespaceControl from './whitespace-control'; import * as Helpers from './helpers'; import { extend } from '../utils'; export { parser }; let yy = {}; extend(yy, Helpers); export function parseWithoutProcessing(input, options) { // Just return if an already-compiled AST was passed in. if (input.type === 'Program') { return input; } parser.yy = yy; // Altering the shared object here, but this is ok as parser is a sync operation yy.locInfo = function(locInfo) { return new yy.SourceLocation(options && options.srcName, locInfo); }; let ast = parser.parse(input); return ast; } export function parse(input, options) { let ast = parseWithoutProcessing(input, options); let strip = new WhitespaceControl(options); return strip.accept(ast); } handlebars.js-4.7.7/lib/handlebars/compiler/code-gen.js000066400000000000000000000074321401244020700227510ustar00rootroot00000000000000/* global define */ import { isArray } from '../utils'; let SourceNode; try { /* istanbul ignore next */ if (typeof define !== 'function' || !define.amd) { // We don't support this in AMD environments. For these environments, we asusme that // they are running on the browser and thus have no need for the source-map library. let SourceMap = require('source-map'); SourceNode = SourceMap.SourceNode; } } catch (err) { /* NOP */ } /* istanbul ignore if: tested but not covered in istanbul due to dist build */ if (!SourceNode) { SourceNode = function(line, column, srcFile, chunks) { this.src = ''; if (chunks) { this.add(chunks); } }; /* istanbul ignore next */ SourceNode.prototype = { add: function(chunks) { if (isArray(chunks)) { chunks = chunks.join(''); } this.src += chunks; }, prepend: function(chunks) { if (isArray(chunks)) { chunks = chunks.join(''); } this.src = chunks + this.src; }, toStringWithSourceMap: function() { return { code: this.toString() }; }, toString: function() { return this.src; } }; } function castChunk(chunk, codeGen, loc) { if (isArray(chunk)) { let ret = []; for (let i = 0, len = chunk.length; i < len; i++) { ret.push(codeGen.wrap(chunk[i], loc)); } return ret; } else if (typeof chunk === 'boolean' || typeof chunk === 'number') { // Handle primitives that the SourceNode will throw up on return chunk + ''; } return chunk; } function CodeGen(srcFile) { this.srcFile = srcFile; this.source = []; } CodeGen.prototype = { isEmpty() { return !this.source.length; }, prepend: function(source, loc) { this.source.unshift(this.wrap(source, loc)); }, push: function(source, loc) { this.source.push(this.wrap(source, loc)); }, merge: function() { let source = this.empty(); this.each(function(line) { source.add([' ', line, '\n']); }); return source; }, each: function(iter) { for (let i = 0, len = this.source.length; i < len; i++) { iter(this.source[i]); } }, empty: function() { let loc = this.currentLocation || { start: {} }; return new SourceNode(loc.start.line, loc.start.column, this.srcFile); }, wrap: function(chunk, loc = this.currentLocation || { start: {} }) { if (chunk instanceof SourceNode) { return chunk; } chunk = castChunk(chunk, this, loc); return new SourceNode( loc.start.line, loc.start.column, this.srcFile, chunk ); }, functionCall: function(fn, type, params) { params = this.generateList(params); return this.wrap([fn, type ? '.' + type + '(' : '(', params, ')']); }, quotedString: function(str) { return ( '"' + (str + '') .replace(/\\/g, '\\\\') .replace(/"/g, '\\"') .replace(/\n/g, '\\n') .replace(/\r/g, '\\r') .replace(/\u2028/g, '\\u2028') // Per Ecma-262 7.3 + 7.8.4 .replace(/\u2029/g, '\\u2029') + '"' ); }, objectLiteral: function(obj) { let pairs = []; Object.keys(obj).forEach(key => { let value = castChunk(obj[key], this); if (value !== 'undefined') { pairs.push([this.quotedString(key), ':', value]); } }); let ret = this.generateList(pairs); ret.prepend('{'); ret.add('}'); return ret; }, generateList: function(entries) { let ret = this.empty(); for (let i = 0, len = entries.length; i < len; i++) { if (i) { ret.add(','); } ret.add(castChunk(entries[i], this)); } return ret; }, generateArray: function(entries) { let ret = this.generateList(entries); ret.prepend('['); ret.add(']'); return ret; } }; export default CodeGen; handlebars.js-4.7.7/lib/handlebars/compiler/compiler.js000066400000000000000000000355611401244020700231060ustar00rootroot00000000000000/* eslint-disable new-cap */ import Exception from '../exception'; import { isArray, indexOf, extend } from '../utils'; import AST from './ast'; const slice = [].slice; export function Compiler() {} // the foundHelper register will disambiguate helper lookup from finding a // function in a context. This is necessary for mustache compatibility, which // requires that context functions in blocks are evaluated by blockHelperMissing, // and then proceed as if the resulting value was provided to blockHelperMissing. Compiler.prototype = { compiler: Compiler, equals: function(other) { let len = this.opcodes.length; if (other.opcodes.length !== len) { return false; } for (let i = 0; i < len; i++) { let opcode = this.opcodes[i], otherOpcode = other.opcodes[i]; if ( opcode.opcode !== otherOpcode.opcode || !argEquals(opcode.args, otherOpcode.args) ) { return false; } } // We know that length is the same between the two arrays because they are directly tied // to the opcode behavior above. len = this.children.length; for (let i = 0; i < len; i++) { if (!this.children[i].equals(other.children[i])) { return false; } } return true; }, guid: 0, compile: function(program, options) { this.sourceNode = []; this.opcodes = []; this.children = []; this.options = options; this.stringParams = options.stringParams; this.trackIds = options.trackIds; options.blockParams = options.blockParams || []; options.knownHelpers = extend( Object.create(null), { helperMissing: true, blockHelperMissing: true, each: true, if: true, unless: true, with: true, log: true, lookup: true }, options.knownHelpers ); return this.accept(program); }, compileProgram: function(program) { let childCompiler = new this.compiler(), // eslint-disable-line new-cap result = childCompiler.compile(program, this.options), guid = this.guid++; this.usePartial = this.usePartial || result.usePartial; this.children[guid] = result; this.useDepths = this.useDepths || result.useDepths; return guid; }, accept: function(node) { /* istanbul ignore next: Sanity code */ if (!this[node.type]) { throw new Exception('Unknown type: ' + node.type, node); } this.sourceNode.unshift(node); let ret = this[node.type](node); this.sourceNode.shift(); return ret; }, Program: function(program) { this.options.blockParams.unshift(program.blockParams); let body = program.body, bodyLength = body.length; for (let i = 0; i < bodyLength; i++) { this.accept(body[i]); } this.options.blockParams.shift(); this.isSimple = bodyLength === 1; this.blockParams = program.blockParams ? program.blockParams.length : 0; return this; }, BlockStatement: function(block) { transformLiteralToPath(block); let program = block.program, inverse = block.inverse; program = program && this.compileProgram(program); inverse = inverse && this.compileProgram(inverse); let type = this.classifySexpr(block); if (type === 'helper') { this.helperSexpr(block, program, inverse); } else if (type === 'simple') { this.simpleSexpr(block); // now that the simple mustache is resolved, we need to // evaluate it by executing `blockHelperMissing` this.opcode('pushProgram', program); this.opcode('pushProgram', inverse); this.opcode('emptyHash'); this.opcode('blockValue', block.path.original); } else { this.ambiguousSexpr(block, program, inverse); // now that the simple mustache is resolved, we need to // evaluate it by executing `blockHelperMissing` this.opcode('pushProgram', program); this.opcode('pushProgram', inverse); this.opcode('emptyHash'); this.opcode('ambiguousBlockValue'); } this.opcode('append'); }, DecoratorBlock(decorator) { let program = decorator.program && this.compileProgram(decorator.program); let params = this.setupFullMustacheParams(decorator, program, undefined), path = decorator.path; this.useDecorators = true; this.opcode('registerDecorator', params.length, path.original); }, PartialStatement: function(partial) { this.usePartial = true; let program = partial.program; if (program) { program = this.compileProgram(partial.program); } let params = partial.params; if (params.length > 1) { throw new Exception( 'Unsupported number of partial arguments: ' + params.length, partial ); } else if (!params.length) { if (this.options.explicitPartialContext) { this.opcode('pushLiteral', 'undefined'); } else { params.push({ type: 'PathExpression', parts: [], depth: 0 }); } } let partialName = partial.name.original, isDynamic = partial.name.type === 'SubExpression'; if (isDynamic) { this.accept(partial.name); } this.setupFullMustacheParams(partial, program, undefined, true); let indent = partial.indent || ''; if (this.options.preventIndent && indent) { this.opcode('appendContent', indent); indent = ''; } this.opcode('invokePartial', isDynamic, partialName, indent); this.opcode('append'); }, PartialBlockStatement: function(partialBlock) { this.PartialStatement(partialBlock); }, MustacheStatement: function(mustache) { this.SubExpression(mustache); if (mustache.escaped && !this.options.noEscape) { this.opcode('appendEscaped'); } else { this.opcode('append'); } }, Decorator(decorator) { this.DecoratorBlock(decorator); }, ContentStatement: function(content) { if (content.value) { this.opcode('appendContent', content.value); } }, CommentStatement: function() {}, SubExpression: function(sexpr) { transformLiteralToPath(sexpr); let type = this.classifySexpr(sexpr); if (type === 'simple') { this.simpleSexpr(sexpr); } else if (type === 'helper') { this.helperSexpr(sexpr); } else { this.ambiguousSexpr(sexpr); } }, ambiguousSexpr: function(sexpr, program, inverse) { let path = sexpr.path, name = path.parts[0], isBlock = program != null || inverse != null; this.opcode('getContext', path.depth); this.opcode('pushProgram', program); this.opcode('pushProgram', inverse); path.strict = true; this.accept(path); this.opcode('invokeAmbiguous', name, isBlock); }, simpleSexpr: function(sexpr) { let path = sexpr.path; path.strict = true; this.accept(path); this.opcode('resolvePossibleLambda'); }, helperSexpr: function(sexpr, program, inverse) { let params = this.setupFullMustacheParams(sexpr, program, inverse), path = sexpr.path, name = path.parts[0]; if (this.options.knownHelpers[name]) { this.opcode('invokeKnownHelper', params.length, name); } else if (this.options.knownHelpersOnly) { throw new Exception( 'You specified knownHelpersOnly, but used the unknown helper ' + name, sexpr ); } else { path.strict = true; path.falsy = true; this.accept(path); this.opcode( 'invokeHelper', params.length, path.original, AST.helpers.simpleId(path) ); } }, PathExpression: function(path) { this.addDepth(path.depth); this.opcode('getContext', path.depth); let name = path.parts[0], scoped = AST.helpers.scopedId(path), blockParamId = !path.depth && !scoped && this.blockParamIndex(name); if (blockParamId) { this.opcode('lookupBlockParam', blockParamId, path.parts); } else if (!name) { // Context reference, i.e. `{{foo .}}` or `{{foo ..}}` this.opcode('pushContext'); } else if (path.data) { this.options.data = true; this.opcode('lookupData', path.depth, path.parts, path.strict); } else { this.opcode( 'lookupOnContext', path.parts, path.falsy, path.strict, scoped ); } }, StringLiteral: function(string) { this.opcode('pushString', string.value); }, NumberLiteral: function(number) { this.opcode('pushLiteral', number.value); }, BooleanLiteral: function(bool) { this.opcode('pushLiteral', bool.value); }, UndefinedLiteral: function() { this.opcode('pushLiteral', 'undefined'); }, NullLiteral: function() { this.opcode('pushLiteral', 'null'); }, Hash: function(hash) { let pairs = hash.pairs, i = 0, l = pairs.length; this.opcode('pushHash'); for (; i < l; i++) { this.pushParam(pairs[i].value); } while (i--) { this.opcode('assignToHash', pairs[i].key); } this.opcode('popHash'); }, // HELPERS opcode: function(name) { this.opcodes.push({ opcode: name, args: slice.call(arguments, 1), loc: this.sourceNode[0].loc }); }, addDepth: function(depth) { if (!depth) { return; } this.useDepths = true; }, classifySexpr: function(sexpr) { let isSimple = AST.helpers.simpleId(sexpr.path); let isBlockParam = isSimple && !!this.blockParamIndex(sexpr.path.parts[0]); // a mustache is an eligible helper if: // * its id is simple (a single part, not `this` or `..`) let isHelper = !isBlockParam && AST.helpers.helperExpression(sexpr); // if a mustache is an eligible helper but not a definite // helper, it is ambiguous, and will be resolved in a later // pass or at runtime. let isEligible = !isBlockParam && (isHelper || isSimple); // if ambiguous, we can possibly resolve the ambiguity now // An eligible helper is one that does not have a complex path, i.e. `this.foo`, `../foo` etc. if (isEligible && !isHelper) { let name = sexpr.path.parts[0], options = this.options; if (options.knownHelpers[name]) { isHelper = true; } else if (options.knownHelpersOnly) { isEligible = false; } } if (isHelper) { return 'helper'; } else if (isEligible) { return 'ambiguous'; } else { return 'simple'; } }, pushParams: function(params) { for (let i = 0, l = params.length; i < l; i++) { this.pushParam(params[i]); } }, pushParam: function(val) { let value = val.value != null ? val.value : val.original || ''; if (this.stringParams) { if (value.replace) { value = value.replace(/^(\.?\.\/)*/g, '').replace(/\//g, '.'); } if (val.depth) { this.addDepth(val.depth); } this.opcode('getContext', val.depth || 0); this.opcode('pushStringParam', value, val.type); if (val.type === 'SubExpression') { // SubExpressions get evaluated and passed in // in string params mode. this.accept(val); } } else { if (this.trackIds) { let blockParamIndex; if (val.parts && !AST.helpers.scopedId(val) && !val.depth) { blockParamIndex = this.blockParamIndex(val.parts[0]); } if (blockParamIndex) { let blockParamChild = val.parts.slice(1).join('.'); this.opcode('pushId', 'BlockParam', blockParamIndex, blockParamChild); } else { value = val.original || value; if (value.replace) { value = value .replace(/^this(?:\.|$)/, '') .replace(/^\.\//, '') .replace(/^\.$/, ''); } this.opcode('pushId', val.type, value); } } this.accept(val); } }, setupFullMustacheParams: function(sexpr, program, inverse, omitEmpty) { let params = sexpr.params; this.pushParams(params); this.opcode('pushProgram', program); this.opcode('pushProgram', inverse); if (sexpr.hash) { this.accept(sexpr.hash); } else { this.opcode('emptyHash', omitEmpty); } return params; }, blockParamIndex: function(name) { for ( let depth = 0, len = this.options.blockParams.length; depth < len; depth++ ) { let blockParams = this.options.blockParams[depth], param = blockParams && indexOf(blockParams, name); if (blockParams && param >= 0) { return [depth, param]; } } } }; export function precompile(input, options, env) { if ( input == null || (typeof input !== 'string' && input.type !== 'Program') ) { throw new Exception( 'You must pass a string or Handlebars AST to Handlebars.precompile. You passed ' + input ); } options = options || {}; if (!('data' in options)) { options.data = true; } if (options.compat) { options.useDepths = true; } let ast = env.parse(input, options), environment = new env.Compiler().compile(ast, options); return new env.JavaScriptCompiler().compile(environment, options); } export function compile(input, options = {}, env) { if ( input == null || (typeof input !== 'string' && input.type !== 'Program') ) { throw new Exception( 'You must pass a string or Handlebars AST to Handlebars.compile. You passed ' + input ); } options = extend({}, options); if (!('data' in options)) { options.data = true; } if (options.compat) { options.useDepths = true; } let compiled; function compileInput() { let ast = env.parse(input, options), environment = new env.Compiler().compile(ast, options), templateSpec = new env.JavaScriptCompiler().compile( environment, options, undefined, true ); return env.template(templateSpec); } // Template is only compiled on first use and cached after that point. function ret(context, execOptions) { if (!compiled) { compiled = compileInput(); } return compiled.call(this, context, execOptions); } ret._setup = function(setupOptions) { if (!compiled) { compiled = compileInput(); } return compiled._setup(setupOptions); }; ret._child = function(i, data, blockParams, depths) { if (!compiled) { compiled = compileInput(); } return compiled._child(i, data, blockParams, depths); }; return ret; } function argEquals(a, b) { if (a === b) { return true; } if (isArray(a) && isArray(b) && a.length === b.length) { for (let i = 0; i < a.length; i++) { if (!argEquals(a[i], b[i])) { return false; } } return true; } } function transformLiteralToPath(sexpr) { if (!sexpr.path.parts) { let literal = sexpr.path; // Casting to string here to make false and 0 literal values play nicely with the rest // of the system. sexpr.path = { type: 'PathExpression', data: false, depth: 0, parts: [literal.original + ''], original: literal.original + '', loc: literal.loc }; } } handlebars.js-4.7.7/lib/handlebars/compiler/helpers.js000066400000000000000000000111611401244020700227240ustar00rootroot00000000000000import Exception from '../exception'; function validateClose(open, close) { close = close.path ? close.path.original : close; if (open.path.original !== close) { let errorNode = { loc: open.path.loc }; throw new Exception( open.path.original + " doesn't match " + close, errorNode ); } } export function SourceLocation(source, locInfo) { this.source = source; this.start = { line: locInfo.first_line, column: locInfo.first_column }; this.end = { line: locInfo.last_line, column: locInfo.last_column }; } export function id(token) { if (/^\[.*\]$/.test(token)) { return token.substring(1, token.length - 1); } else { return token; } } export function stripFlags(open, close) { return { open: open.charAt(2) === '~', close: close.charAt(close.length - 3) === '~' }; } export function stripComment(comment) { return comment.replace(/^\{\{~?!-?-?/, '').replace(/-?-?~?\}\}$/, ''); } export function preparePath(data, parts, loc) { loc = this.locInfo(loc); let original = data ? '@' : '', dig = [], depth = 0; for (let i = 0, l = parts.length; i < l; i++) { let part = parts[i].part, // If we have [] syntax then we do not treat path references as operators, // i.e. foo.[this] resolves to approximately context.foo['this'] isLiteral = parts[i].original !== part; original += (parts[i].separator || '') + part; if (!isLiteral && (part === '..' || part === '.' || part === 'this')) { if (dig.length > 0) { throw new Exception('Invalid path: ' + original, { loc }); } else if (part === '..') { depth++; } } else { dig.push(part); } } return { type: 'PathExpression', data, depth, parts: dig, original, loc }; } export function prepareMustache(path, params, hash, open, strip, locInfo) { // Must use charAt to support IE pre-10 let escapeFlag = open.charAt(3) || open.charAt(2), escaped = escapeFlag !== '{' && escapeFlag !== '&'; let decorator = /\*/.test(open); return { type: decorator ? 'Decorator' : 'MustacheStatement', path, params, hash, escaped, strip, loc: this.locInfo(locInfo) }; } export function prepareRawBlock(openRawBlock, contents, close, locInfo) { validateClose(openRawBlock, close); locInfo = this.locInfo(locInfo); let program = { type: 'Program', body: contents, strip: {}, loc: locInfo }; return { type: 'BlockStatement', path: openRawBlock.path, params: openRawBlock.params, hash: openRawBlock.hash, program, openStrip: {}, inverseStrip: {}, closeStrip: {}, loc: locInfo }; } export function prepareBlock( openBlock, program, inverseAndProgram, close, inverted, locInfo ) { if (close && close.path) { validateClose(openBlock, close); } let decorator = /\*/.test(openBlock.open); program.blockParams = openBlock.blockParams; let inverse, inverseStrip; if (inverseAndProgram) { if (decorator) { throw new Exception( 'Unexpected inverse block on decorator', inverseAndProgram ); } if (inverseAndProgram.chain) { inverseAndProgram.program.body[0].closeStrip = close.strip; } inverseStrip = inverseAndProgram.strip; inverse = inverseAndProgram.program; } if (inverted) { inverted = inverse; inverse = program; program = inverted; } return { type: decorator ? 'DecoratorBlock' : 'BlockStatement', path: openBlock.path, params: openBlock.params, hash: openBlock.hash, program, inverse, openStrip: openBlock.strip, inverseStrip, closeStrip: close && close.strip, loc: this.locInfo(locInfo) }; } export function prepareProgram(statements, loc) { if (!loc && statements.length) { const firstLoc = statements[0].loc, lastLoc = statements[statements.length - 1].loc; /* istanbul ignore else */ if (firstLoc && lastLoc) { loc = { source: firstLoc.source, start: { line: firstLoc.start.line, column: firstLoc.start.column }, end: { line: lastLoc.end.line, column: lastLoc.end.column } }; } } return { type: 'Program', body: statements, strip: {}, loc: loc }; } export function preparePartialBlock(open, program, close, locInfo) { validateClose(open, close); return { type: 'PartialBlockStatement', name: open.path, params: open.params, hash: open.hash, program, openStrip: open.strip, closeStrip: close && close.strip, loc: this.locInfo(locInfo) }; } handlebars.js-4.7.7/lib/handlebars/compiler/javascript-compiler.js000066400000000000000000001027331401244020700252460ustar00rootroot00000000000000import { COMPILER_REVISION, REVISION_CHANGES } from '../base'; import Exception from '../exception'; import { isArray } from '../utils'; import CodeGen from './code-gen'; function Literal(value) { this.value = value; } function JavaScriptCompiler() {} JavaScriptCompiler.prototype = { // PUBLIC API: You can override these methods in a subclass to provide // alternative compiled forms for name lookup and buffering semantics nameLookup: function(parent, name /*, type */) { return this.internalNameLookup(parent, name); }, depthedLookup: function(name) { return [ this.aliasable('container.lookup'), '(depths, ', JSON.stringify(name), ')' ]; }, compilerInfo: function() { const revision = COMPILER_REVISION, versions = REVISION_CHANGES[revision]; return [revision, versions]; }, appendToBuffer: function(source, location, explicit) { // Force a source as this simplifies the merge logic. if (!isArray(source)) { source = [source]; } source = this.source.wrap(source, location); if (this.environment.isSimple) { return ['return ', source, ';']; } else if (explicit) { // This is a case where the buffer operation occurs as a child of another // construct, generally braces. We have to explicitly output these buffer // operations to ensure that the emitted code goes in the correct location. return ['buffer += ', source, ';']; } else { source.appendToBuffer = true; return source; } }, initializeBuffer: function() { return this.quotedString(''); }, // END PUBLIC API internalNameLookup: function(parent, name) { this.lookupPropertyFunctionIsUsed = true; return ['lookupProperty(', parent, ',', JSON.stringify(name), ')']; }, lookupPropertyFunctionIsUsed: false, compile: function(environment, options, context, asObject) { this.environment = environment; this.options = options; this.stringParams = this.options.stringParams; this.trackIds = this.options.trackIds; this.precompile = !asObject; this.name = this.environment.name; this.isChild = !!context; this.context = context || { decorators: [], programs: [], environments: [] }; this.preamble(); this.stackSlot = 0; this.stackVars = []; this.aliases = {}; this.registers = { list: [] }; this.hashes = []; this.compileStack = []; this.inlineStack = []; this.blockParams = []; this.compileChildren(environment, options); this.useDepths = this.useDepths || environment.useDepths || environment.useDecorators || this.options.compat; this.useBlockParams = this.useBlockParams || environment.useBlockParams; let opcodes = environment.opcodes, opcode, firstLoc, i, l; for (i = 0, l = opcodes.length; i < l; i++) { opcode = opcodes[i]; this.source.currentLocation = opcode.loc; firstLoc = firstLoc || opcode.loc; this[opcode.opcode].apply(this, opcode.args); } // Flush any trailing content that might be pending. this.source.currentLocation = firstLoc; this.pushSource(''); /* istanbul ignore next */ if (this.stackSlot || this.inlineStack.length || this.compileStack.length) { throw new Exception('Compile completed with content left on stack'); } if (!this.decorators.isEmpty()) { this.useDecorators = true; this.decorators.prepend([ 'var decorators = container.decorators, ', this.lookupPropertyFunctionVarDeclaration(), ';\n' ]); this.decorators.push('return fn;'); if (asObject) { this.decorators = Function.apply(this, [ 'fn', 'props', 'container', 'depth0', 'data', 'blockParams', 'depths', this.decorators.merge() ]); } else { this.decorators.prepend( 'function(fn, props, container, depth0, data, blockParams, depths) {\n' ); this.decorators.push('}\n'); this.decorators = this.decorators.merge(); } } else { this.decorators = undefined; } let fn = this.createFunctionContext(asObject); if (!this.isChild) { let ret = { compiler: this.compilerInfo(), main: fn }; if (this.decorators) { ret.main_d = this.decorators; // eslint-disable-line camelcase ret.useDecorators = true; } let { programs, decorators } = this.context; for (i = 0, l = programs.length; i < l; i++) { if (programs[i]) { ret[i] = programs[i]; if (decorators[i]) { ret[i + '_d'] = decorators[i]; ret.useDecorators = true; } } } if (this.environment.usePartial) { ret.usePartial = true; } if (this.options.data) { ret.useData = true; } if (this.useDepths) { ret.useDepths = true; } if (this.useBlockParams) { ret.useBlockParams = true; } if (this.options.compat) { ret.compat = true; } if (!asObject) { ret.compiler = JSON.stringify(ret.compiler); this.source.currentLocation = { start: { line: 1, column: 0 } }; ret = this.objectLiteral(ret); if (options.srcName) { ret = ret.toStringWithSourceMap({ file: options.destName }); ret.map = ret.map && ret.map.toString(); } else { ret = ret.toString(); } } else { ret.compilerOptions = this.options; } return ret; } else { return fn; } }, preamble: function() { // track the last context pushed into place to allow skipping the // getContext opcode when it would be a noop this.lastContext = 0; this.source = new CodeGen(this.options.srcName); this.decorators = new CodeGen(this.options.srcName); }, createFunctionContext: function(asObject) { let varDeclarations = ''; let locals = this.stackVars.concat(this.registers.list); if (locals.length > 0) { varDeclarations += ', ' + locals.join(', '); } // Generate minimizer alias mappings // // When using true SourceNodes, this will update all references to the given alias // as the source nodes are reused in situ. For the non-source node compilation mode, // aliases will not be used, but this case is already being run on the client and // we aren't concern about minimizing the template size. let aliasCount = 0; Object.keys(this.aliases).forEach(alias => { let node = this.aliases[alias]; if (node.children && node.referenceCount > 1) { varDeclarations += ', alias' + ++aliasCount + '=' + alias; node.children[0] = 'alias' + aliasCount; } }); if (this.lookupPropertyFunctionIsUsed) { varDeclarations += ', ' + this.lookupPropertyFunctionVarDeclaration(); } let params = ['container', 'depth0', 'helpers', 'partials', 'data']; if (this.useBlockParams || this.useDepths) { params.push('blockParams'); } if (this.useDepths) { params.push('depths'); } // Perform a second pass over the output to merge content when possible let source = this.mergeSource(varDeclarations); if (asObject) { params.push(source); return Function.apply(this, params); } else { return this.source.wrap([ 'function(', params.join(','), ') {\n ', source, '}' ]); } }, mergeSource: function(varDeclarations) { let isSimple = this.environment.isSimple, appendOnly = !this.forceBuffer, appendFirst, sourceSeen, bufferStart, bufferEnd; this.source.each(line => { if (line.appendToBuffer) { if (bufferStart) { line.prepend(' + '); } else { bufferStart = line; } bufferEnd = line; } else { if (bufferStart) { if (!sourceSeen) { appendFirst = true; } else { bufferStart.prepend('buffer += '); } bufferEnd.add(';'); bufferStart = bufferEnd = undefined; } sourceSeen = true; if (!isSimple) { appendOnly = false; } } }); if (appendOnly) { if (bufferStart) { bufferStart.prepend('return '); bufferEnd.add(';'); } else if (!sourceSeen) { this.source.push('return "";'); } } else { varDeclarations += ', buffer = ' + (appendFirst ? '' : this.initializeBuffer()); if (bufferStart) { bufferStart.prepend('return buffer + '); bufferEnd.add(';'); } else { this.source.push('return buffer;'); } } if (varDeclarations) { this.source.prepend( 'var ' + varDeclarations.substring(2) + (appendFirst ? '' : ';\n') ); } return this.source.merge(); }, lookupPropertyFunctionVarDeclaration: function() { return ` lookupProperty = container.lookupProperty || function(parent, propertyName) { if (Object.prototype.hasOwnProperty.call(parent, propertyName)) { return parent[propertyName]; } return undefined } `.trim(); }, // [blockValue] // // On stack, before: hash, inverse, program, value // On stack, after: return value of blockHelperMissing // // The purpose of this opcode is to take a block of the form // `{{#this.foo}}...{{/this.foo}}`, resolve the value of `foo`, and // replace it on the stack with the result of properly // invoking blockHelperMissing. blockValue: function(name) { let blockHelperMissing = this.aliasable( 'container.hooks.blockHelperMissing' ), params = [this.contextName(0)]; this.setupHelperArgs(name, 0, params); let blockName = this.popStack(); params.splice(1, 0, blockName); this.push(this.source.functionCall(blockHelperMissing, 'call', params)); }, // [ambiguousBlockValue] // // On stack, before: hash, inverse, program, value // Compiler value, before: lastHelper=value of last found helper, if any // On stack, after, if no lastHelper: same as [blockValue] // On stack, after, if lastHelper: value ambiguousBlockValue: function() { // We're being a bit cheeky and reusing the options value from the prior exec let blockHelperMissing = this.aliasable( 'container.hooks.blockHelperMissing' ), params = [this.contextName(0)]; this.setupHelperArgs('', 0, params, true); this.flushInline(); let current = this.topStack(); params.splice(1, 0, current); this.pushSource([ 'if (!', this.lastHelper, ') { ', current, ' = ', this.source.functionCall(blockHelperMissing, 'call', params), '}' ]); }, // [appendContent] // // On stack, before: ... // On stack, after: ... // // Appends the string value of `content` to the current buffer appendContent: function(content) { if (this.pendingContent) { content = this.pendingContent + content; } else { this.pendingLocation = this.source.currentLocation; } this.pendingContent = content; }, // [append] // // On stack, before: value, ... // On stack, after: ... // // Coerces `value` to a String and appends it to the current buffer. // // If `value` is truthy, or 0, it is coerced into a string and appended // Otherwise, the empty string is appended append: function() { if (this.isInline()) { this.replaceStack(current => [' != null ? ', current, ' : ""']); this.pushSource(this.appendToBuffer(this.popStack())); } else { let local = this.popStack(); this.pushSource([ 'if (', local, ' != null) { ', this.appendToBuffer(local, undefined, true), ' }' ]); if (this.environment.isSimple) { this.pushSource([ 'else { ', this.appendToBuffer("''", undefined, true), ' }' ]); } } }, // [appendEscaped] // // On stack, before: value, ... // On stack, after: ... // // Escape `value` and append it to the buffer appendEscaped: function() { this.pushSource( this.appendToBuffer([ this.aliasable('container.escapeExpression'), '(', this.popStack(), ')' ]) ); }, // [getContext] // // On stack, before: ... // On stack, after: ... // Compiler value, after: lastContext=depth // // Set the value of the `lastContext` compiler value to the depth getContext: function(depth) { this.lastContext = depth; }, // [pushContext] // // On stack, before: ... // On stack, after: currentContext, ... // // Pushes the value of the current context onto the stack. pushContext: function() { this.pushStackLiteral(this.contextName(this.lastContext)); }, // [lookupOnContext] // // On stack, before: ... // On stack, after: currentContext[name], ... // // Looks up the value of `name` on the current context and pushes // it onto the stack. lookupOnContext: function(parts, falsy, strict, scoped) { let i = 0; if (!scoped && this.options.compat && !this.lastContext) { // The depthed query is expected to handle the undefined logic for the root level that // is implemented below, so we evaluate that directly in compat mode this.push(this.depthedLookup(parts[i++])); } else { this.pushContext(); } this.resolvePath('context', parts, i, falsy, strict); }, // [lookupBlockParam] // // On stack, before: ... // On stack, after: blockParam[name], ... // // Looks up the value of `parts` on the given block param and pushes // it onto the stack. lookupBlockParam: function(blockParamId, parts) { this.useBlockParams = true; this.push(['blockParams[', blockParamId[0], '][', blockParamId[1], ']']); this.resolvePath('context', parts, 1); }, // [lookupData] // // On stack, before: ... // On stack, after: data, ... // // Push the data lookup operator lookupData: function(depth, parts, strict) { if (!depth) { this.pushStackLiteral('data'); } else { this.pushStackLiteral('container.data(data, ' + depth + ')'); } this.resolvePath('data', parts, 0, true, strict); }, resolvePath: function(type, parts, i, falsy, strict) { if (this.options.strict || this.options.assumeObjects) { this.push(strictLookup(this.options.strict && strict, this, parts, type)); return; } let len = parts.length; for (; i < len; i++) { /* eslint-disable no-loop-func */ this.replaceStack(current => { let lookup = this.nameLookup(current, parts[i], type); // We want to ensure that zero and false are handled properly if the context (falsy flag) // needs to have the special handling for these values. if (!falsy) { return [' != null ? ', lookup, ' : ', current]; } else { // Otherwise we can use generic falsy handling return [' && ', lookup]; } }); /* eslint-enable no-loop-func */ } }, // [resolvePossibleLambda] // // On stack, before: value, ... // On stack, after: resolved value, ... // // If the `value` is a lambda, replace it on the stack by // the return value of the lambda resolvePossibleLambda: function() { this.push([ this.aliasable('container.lambda'), '(', this.popStack(), ', ', this.contextName(0), ')' ]); }, // [pushStringParam] // // On stack, before: ... // On stack, after: string, currentContext, ... // // This opcode is designed for use in string mode, which // provides the string value of a parameter along with its // depth rather than resolving it immediately. pushStringParam: function(string, type) { this.pushContext(); this.pushString(type); // If it's a subexpression, the string result // will be pushed after this opcode. if (type !== 'SubExpression') { if (typeof string === 'string') { this.pushString(string); } else { this.pushStackLiteral(string); } } }, emptyHash: function(omitEmpty) { if (this.trackIds) { this.push('{}'); // hashIds } if (this.stringParams) { this.push('{}'); // hashContexts this.push('{}'); // hashTypes } this.pushStackLiteral(omitEmpty ? 'undefined' : '{}'); }, pushHash: function() { if (this.hash) { this.hashes.push(this.hash); } this.hash = { values: {}, types: [], contexts: [], ids: [] }; }, popHash: function() { let hash = this.hash; this.hash = this.hashes.pop(); if (this.trackIds) { this.push(this.objectLiteral(hash.ids)); } if (this.stringParams) { this.push(this.objectLiteral(hash.contexts)); this.push(this.objectLiteral(hash.types)); } this.push(this.objectLiteral(hash.values)); }, // [pushString] // // On stack, before: ... // On stack, after: quotedString(string), ... // // Push a quoted version of `string` onto the stack pushString: function(string) { this.pushStackLiteral(this.quotedString(string)); }, // [pushLiteral] // // On stack, before: ... // On stack, after: value, ... // // Pushes a value onto the stack. This operation prevents // the compiler from creating a temporary variable to hold // it. pushLiteral: function(value) { this.pushStackLiteral(value); }, // [pushProgram] // // On stack, before: ... // On stack, after: program(guid), ... // // Push a program expression onto the stack. This takes // a compile-time guid and converts it into a runtime-accessible // expression. pushProgram: function(guid) { if (guid != null) { this.pushStackLiteral(this.programExpression(guid)); } else { this.pushStackLiteral(null); } }, // [registerDecorator] // // On stack, before: hash, program, params..., ... // On stack, after: ... // // Pops off the decorator's parameters, invokes the decorator, // and inserts the decorator into the decorators list. registerDecorator(paramSize, name) { let foundDecorator = this.nameLookup('decorators', name, 'decorator'), options = this.setupHelperArgs(name, paramSize); this.decorators.push([ 'fn = ', this.decorators.functionCall(foundDecorator, '', [ 'fn', 'props', 'container', options ]), ' || fn;' ]); }, // [invokeHelper] // // On stack, before: hash, inverse, program, params..., ... // On stack, after: result of helper invocation // // Pops off the helper's parameters, invokes the helper, // and pushes the helper's return value onto the stack. // // If the helper is not found, `helperMissing` is called. invokeHelper: function(paramSize, name, isSimple) { let nonHelper = this.popStack(), helper = this.setupHelper(paramSize, name); let possibleFunctionCalls = []; if (isSimple) { // direct call to helper possibleFunctionCalls.push(helper.name); } // call a function from the input object possibleFunctionCalls.push(nonHelper); if (!this.options.strict) { possibleFunctionCalls.push( this.aliasable('container.hooks.helperMissing') ); } let functionLookupCode = [ '(', this.itemsSeparatedBy(possibleFunctionCalls, '||'), ')' ]; let functionCall = this.source.functionCall( functionLookupCode, 'call', helper.callParams ); this.push(functionCall); }, itemsSeparatedBy: function(items, separator) { let result = []; result.push(items[0]); for (let i = 1; i < items.length; i++) { result.push(separator, items[i]); } return result; }, // [invokeKnownHelper] // // On stack, before: hash, inverse, program, params..., ... // On stack, after: result of helper invocation // // This operation is used when the helper is known to exist, // so a `helperMissing` fallback is not required. invokeKnownHelper: function(paramSize, name) { let helper = this.setupHelper(paramSize, name); this.push(this.source.functionCall(helper.name, 'call', helper.callParams)); }, // [invokeAmbiguous] // // On stack, before: hash, inverse, program, params..., ... // On stack, after: result of disambiguation // // This operation is used when an expression like `{{foo}}` // is provided, but we don't know at compile-time whether it // is a helper or a path. // // This operation emits more code than the other options, // and can be avoided by passing the `knownHelpers` and // `knownHelpersOnly` flags at compile-time. invokeAmbiguous: function(name, helperCall) { this.useRegister('helper'); let nonHelper = this.popStack(); this.emptyHash(); let helper = this.setupHelper(0, name, helperCall); let helperName = (this.lastHelper = this.nameLookup( 'helpers', name, 'helper' )); let lookup = ['(', '(helper = ', helperName, ' || ', nonHelper, ')']; if (!this.options.strict) { lookup[0] = '(helper = '; lookup.push( ' != null ? helper : ', this.aliasable('container.hooks.helperMissing') ); } this.push([ '(', lookup, helper.paramsInit ? ['),(', helper.paramsInit] : [], '),', '(typeof helper === ', this.aliasable('"function"'), ' ? ', this.source.functionCall('helper', 'call', helper.callParams), ' : helper))' ]); }, // [invokePartial] // // On stack, before: context, ... // On stack after: result of partial invocation // // This operation pops off a context, invokes a partial with that context, // and pushes the result of the invocation back. invokePartial: function(isDynamic, name, indent) { let params = [], options = this.setupParams(name, 1, params); if (isDynamic) { name = this.popStack(); delete options.name; } if (indent) { options.indent = JSON.stringify(indent); } options.helpers = 'helpers'; options.partials = 'partials'; options.decorators = 'container.decorators'; if (!isDynamic) { params.unshift(this.nameLookup('partials', name, 'partial')); } else { params.unshift(name); } if (this.options.compat) { options.depths = 'depths'; } options = this.objectLiteral(options); params.push(options); this.push(this.source.functionCall('container.invokePartial', '', params)); }, // [assignToHash] // // On stack, before: value, ..., hash, ... // On stack, after: ..., hash, ... // // Pops a value off the stack and assigns it to the current hash assignToHash: function(key) { let value = this.popStack(), context, type, id; if (this.trackIds) { id = this.popStack(); } if (this.stringParams) { type = this.popStack(); context = this.popStack(); } let hash = this.hash; if (context) { hash.contexts[key] = context; } if (type) { hash.types[key] = type; } if (id) { hash.ids[key] = id; } hash.values[key] = value; }, pushId: function(type, name, child) { if (type === 'BlockParam') { this.pushStackLiteral( 'blockParams[' + name[0] + '].path[' + name[1] + ']' + (child ? ' + ' + JSON.stringify('.' + child) : '') ); } else if (type === 'PathExpression') { this.pushString(name); } else if (type === 'SubExpression') { this.pushStackLiteral('true'); } else { this.pushStackLiteral('null'); } }, // HELPERS compiler: JavaScriptCompiler, compileChildren: function(environment, options) { let children = environment.children, child, compiler; for (let i = 0, l = children.length; i < l; i++) { child = children[i]; compiler = new this.compiler(); // eslint-disable-line new-cap let existing = this.matchExistingProgram(child); if (existing == null) { this.context.programs.push(''); // Placeholder to prevent name conflicts for nested children let index = this.context.programs.length; child.index = index; child.name = 'program' + index; this.context.programs[index] = compiler.compile( child, options, this.context, !this.precompile ); this.context.decorators[index] = compiler.decorators; this.context.environments[index] = child; this.useDepths = this.useDepths || compiler.useDepths; this.useBlockParams = this.useBlockParams || compiler.useBlockParams; child.useDepths = this.useDepths; child.useBlockParams = this.useBlockParams; } else { child.index = existing.index; child.name = 'program' + existing.index; this.useDepths = this.useDepths || existing.useDepths; this.useBlockParams = this.useBlockParams || existing.useBlockParams; } } }, matchExistingProgram: function(child) { for (let i = 0, len = this.context.environments.length; i < len; i++) { let environment = this.context.environments[i]; if (environment && environment.equals(child)) { return environment; } } }, programExpression: function(guid) { let child = this.environment.children[guid], programParams = [child.index, 'data', child.blockParams]; if (this.useBlockParams || this.useDepths) { programParams.push('blockParams'); } if (this.useDepths) { programParams.push('depths'); } return 'container.program(' + programParams.join(', ') + ')'; }, useRegister: function(name) { if (!this.registers[name]) { this.registers[name] = true; this.registers.list.push(name); } }, push: function(expr) { if (!(expr instanceof Literal)) { expr = this.source.wrap(expr); } this.inlineStack.push(expr); return expr; }, pushStackLiteral: function(item) { this.push(new Literal(item)); }, pushSource: function(source) { if (this.pendingContent) { this.source.push( this.appendToBuffer( this.source.quotedString(this.pendingContent), this.pendingLocation ) ); this.pendingContent = undefined; } if (source) { this.source.push(source); } }, replaceStack: function(callback) { let prefix = ['('], stack, createdStack, usedLiteral; /* istanbul ignore next */ if (!this.isInline()) { throw new Exception('replaceStack on non-inline'); } // We want to merge the inline statement into the replacement statement via ',' let top = this.popStack(true); if (top instanceof Literal) { // Literals do not need to be inlined stack = [top.value]; prefix = ['(', stack]; usedLiteral = true; } else { // Get or create the current stack name for use by the inline createdStack = true; let name = this.incrStack(); prefix = ['((', this.push(name), ' = ', top, ')']; stack = this.topStack(); } let item = callback.call(this, stack); if (!usedLiteral) { this.popStack(); } if (createdStack) { this.stackSlot--; } this.push(prefix.concat(item, ')')); }, incrStack: function() { this.stackSlot++; if (this.stackSlot > this.stackVars.length) { this.stackVars.push('stack' + this.stackSlot); } return this.topStackName(); }, topStackName: function() { return 'stack' + this.stackSlot; }, flushInline: function() { let inlineStack = this.inlineStack; this.inlineStack = []; for (let i = 0, len = inlineStack.length; i < len; i++) { let entry = inlineStack[i]; /* istanbul ignore if */ if (entry instanceof Literal) { this.compileStack.push(entry); } else { let stack = this.incrStack(); this.pushSource([stack, ' = ', entry, ';']); this.compileStack.push(stack); } } }, isInline: function() { return this.inlineStack.length; }, popStack: function(wrapped) { let inline = this.isInline(), item = (inline ? this.inlineStack : this.compileStack).pop(); if (!wrapped && item instanceof Literal) { return item.value; } else { if (!inline) { /* istanbul ignore next */ if (!this.stackSlot) { throw new Exception('Invalid stack pop'); } this.stackSlot--; } return item; } }, topStack: function() { let stack = this.isInline() ? this.inlineStack : this.compileStack, item = stack[stack.length - 1]; /* istanbul ignore if */ if (item instanceof Literal) { return item.value; } else { return item; } }, contextName: function(context) { if (this.useDepths && context) { return 'depths[' + context + ']'; } else { return 'depth' + context; } }, quotedString: function(str) { return this.source.quotedString(str); }, objectLiteral: function(obj) { return this.source.objectLiteral(obj); }, aliasable: function(name) { let ret = this.aliases[name]; if (ret) { ret.referenceCount++; return ret; } ret = this.aliases[name] = this.source.wrap(name); ret.aliasable = true; ret.referenceCount = 1; return ret; }, setupHelper: function(paramSize, name, blockHelper) { let params = [], paramsInit = this.setupHelperArgs(name, paramSize, params, blockHelper); let foundHelper = this.nameLookup('helpers', name, 'helper'), callContext = this.aliasable( `${this.contextName(0)} != null ? ${this.contextName( 0 )} : (container.nullContext || {})` ); return { params: params, paramsInit: paramsInit, name: foundHelper, callParams: [callContext].concat(params) }; }, setupParams: function(helper, paramSize, params) { let options = {}, contexts = [], types = [], ids = [], objectArgs = !params, param; if (objectArgs) { params = []; } options.name = this.quotedString(helper); options.hash = this.popStack(); if (this.trackIds) { options.hashIds = this.popStack(); } if (this.stringParams) { options.hashTypes = this.popStack(); options.hashContexts = this.popStack(); } let inverse = this.popStack(), program = this.popStack(); // Avoid setting fn and inverse if neither are set. This allows // helpers to do a check for `if (options.fn)` if (program || inverse) { options.fn = program || 'container.noop'; options.inverse = inverse || 'container.noop'; } // The parameters go on to the stack in order (making sure that they are evaluated in order) // so we need to pop them off the stack in reverse order let i = paramSize; while (i--) { param = this.popStack(); params[i] = param; if (this.trackIds) { ids[i] = this.popStack(); } if (this.stringParams) { types[i] = this.popStack(); contexts[i] = this.popStack(); } } if (objectArgs) { options.args = this.source.generateArray(params); } if (this.trackIds) { options.ids = this.source.generateArray(ids); } if (this.stringParams) { options.types = this.source.generateArray(types); options.contexts = this.source.generateArray(contexts); } if (this.options.data) { options.data = 'data'; } if (this.useBlockParams) { options.blockParams = 'blockParams'; } return options; }, setupHelperArgs: function(helper, paramSize, params, useRegister) { let options = this.setupParams(helper, paramSize, params); options.loc = JSON.stringify(this.source.currentLocation); options = this.objectLiteral(options); if (useRegister) { this.useRegister('options'); params.push('options'); return ['options=', options]; } else if (params) { params.push(options); return ''; } else { return options; } } }; (function() { const reservedWords = ( 'break else new var' + ' case finally return void' + ' catch for switch while' + ' continue function this with' + ' default if throw' + ' delete in try' + ' do instanceof typeof' + ' abstract enum int short' + ' boolean export interface static' + ' byte extends long super' + ' char final native synchronized' + ' class float package throws' + ' const goto private transient' + ' debugger implements protected volatile' + ' double import public let yield await' + ' null true false' ).split(' '); const compilerWords = (JavaScriptCompiler.RESERVED_WORDS = {}); for (let i = 0, l = reservedWords.length; i < l; i++) { compilerWords[reservedWords[i]] = true; } })(); /** * @deprecated May be removed in the next major version */ JavaScriptCompiler.isValidJavaScriptVariableName = function(name) { return ( !JavaScriptCompiler.RESERVED_WORDS[name] && /^[a-zA-Z_$][0-9a-zA-Z_$]*$/.test(name) ); }; function strictLookup(requireTerminal, compiler, parts, type) { let stack = compiler.popStack(), i = 0, len = parts.length; if (requireTerminal) { len--; } for (; i < len; i++) { stack = compiler.nameLookup(stack, parts[i], type); } if (requireTerminal) { return [ compiler.aliasable('container.strict'), '(', stack, ', ', compiler.quotedString(parts[i]), ', ', JSON.stringify(compiler.source.currentLocation), ' )' ]; } else { return stack; } } export default JavaScriptCompiler; handlebars.js-4.7.7/lib/handlebars/compiler/printer.js000066400000000000000000000102141401244020700227430ustar00rootroot00000000000000/* eslint-disable new-cap */ import Visitor from './visitor'; export function print(ast) { return new PrintVisitor().accept(ast); } export function PrintVisitor() { this.padding = 0; } PrintVisitor.prototype = new Visitor(); PrintVisitor.prototype.pad = function(string) { let out = ''; for (let i = 0, l = this.padding; i < l; i++) { out += ' '; } out += string + '\n'; return out; }; PrintVisitor.prototype.Program = function(program) { let out = '', body = program.body, i, l; if (program.blockParams) { let blockParams = 'BLOCK PARAMS: ['; for (i = 0, l = program.blockParams.length; i < l; i++) { blockParams += ' ' + program.blockParams[i]; } blockParams += ' ]'; out += this.pad(blockParams); } for (i = 0, l = body.length; i < l; i++) { out += this.accept(body[i]); } this.padding--; return out; }; PrintVisitor.prototype.MustacheStatement = function(mustache) { return this.pad('{{ ' + this.SubExpression(mustache) + ' }}'); }; PrintVisitor.prototype.Decorator = function(mustache) { return this.pad('{{ DIRECTIVE ' + this.SubExpression(mustache) + ' }}'); }; PrintVisitor.prototype.BlockStatement = PrintVisitor.prototype.DecoratorBlock = function( block ) { let out = ''; out += this.pad( (block.type === 'DecoratorBlock' ? 'DIRECTIVE ' : '') + 'BLOCK:' ); this.padding++; out += this.pad(this.SubExpression(block)); if (block.program) { out += this.pad('PROGRAM:'); this.padding++; out += this.accept(block.program); this.padding--; } if (block.inverse) { if (block.program) { this.padding++; } out += this.pad('{{^}}'); this.padding++; out += this.accept(block.inverse); this.padding--; if (block.program) { this.padding--; } } this.padding--; return out; }; PrintVisitor.prototype.PartialStatement = function(partial) { let content = 'PARTIAL:' + partial.name.original; if (partial.params[0]) { content += ' ' + this.accept(partial.params[0]); } if (partial.hash) { content += ' ' + this.accept(partial.hash); } return this.pad('{{> ' + content + ' }}'); }; PrintVisitor.prototype.PartialBlockStatement = function(partial) { let content = 'PARTIAL BLOCK:' + partial.name.original; if (partial.params[0]) { content += ' ' + this.accept(partial.params[0]); } if (partial.hash) { content += ' ' + this.accept(partial.hash); } content += ' ' + this.pad('PROGRAM:'); this.padding++; content += this.accept(partial.program); this.padding--; return this.pad('{{> ' + content + ' }}'); }; PrintVisitor.prototype.ContentStatement = function(content) { return this.pad("CONTENT[ '" + content.value + "' ]"); }; PrintVisitor.prototype.CommentStatement = function(comment) { return this.pad("{{! '" + comment.value + "' }}"); }; PrintVisitor.prototype.SubExpression = function(sexpr) { let params = sexpr.params, paramStrings = [], hash; for (let i = 0, l = params.length; i < l; i++) { paramStrings.push(this.accept(params[i])); } params = '[' + paramStrings.join(', ') + ']'; hash = sexpr.hash ? ' ' + this.accept(sexpr.hash) : ''; return this.accept(sexpr.path) + ' ' + params + hash; }; PrintVisitor.prototype.PathExpression = function(id) { let path = id.parts.join('/'); return (id.data ? '@' : '') + 'PATH:' + path; }; PrintVisitor.prototype.StringLiteral = function(string) { return '"' + string.value + '"'; }; PrintVisitor.prototype.NumberLiteral = function(number) { return 'NUMBER{' + number.value + '}'; }; PrintVisitor.prototype.BooleanLiteral = function(bool) { return 'BOOLEAN{' + bool.value + '}'; }; PrintVisitor.prototype.UndefinedLiteral = function() { return 'UNDEFINED'; }; PrintVisitor.prototype.NullLiteral = function() { return 'NULL'; }; PrintVisitor.prototype.Hash = function(hash) { let pairs = hash.pairs, joinedPairs = []; for (let i = 0, l = pairs.length; i < l; i++) { joinedPairs.push(this.accept(pairs[i])); } return 'HASH{' + joinedPairs.join(', ') + '}'; }; PrintVisitor.prototype.HashPair = function(pair) { return pair.key + '=' + this.accept(pair.value); }; /* eslint-enable new-cap */ handlebars.js-4.7.7/lib/handlebars/compiler/visitor.js000066400000000000000000000063361401244020700227710ustar00rootroot00000000000000import Exception from '../exception'; function Visitor() { this.parents = []; } Visitor.prototype = { constructor: Visitor, mutating: false, // Visits a given value. If mutating, will replace the value if necessary. acceptKey: function(node, name) { let value = this.accept(node[name]); if (this.mutating) { // Hacky sanity check: This may have a few false positives for type for the helper // methods but will generally do the right thing without a lot of overhead. if (value && !Visitor.prototype[value.type]) { throw new Exception( 'Unexpected node type "' + value.type + '" found when accepting ' + name + ' on ' + node.type ); } node[name] = value; } }, // Performs an accept operation with added sanity check to ensure // required keys are not removed. acceptRequired: function(node, name) { this.acceptKey(node, name); if (!node[name]) { throw new Exception(node.type + ' requires ' + name); } }, // Traverses a given array. If mutating, empty respnses will be removed // for child elements. acceptArray: function(array) { for (let i = 0, l = array.length; i < l; i++) { this.acceptKey(array, i); if (!array[i]) { array.splice(i, 1); i--; l--; } } }, accept: function(object) { if (!object) { return; } /* istanbul ignore next: Sanity code */ if (!this[object.type]) { throw new Exception('Unknown type: ' + object.type, object); } if (this.current) { this.parents.unshift(this.current); } this.current = object; let ret = this[object.type](object); this.current = this.parents.shift(); if (!this.mutating || ret) { return ret; } else if (ret !== false) { return object; } }, Program: function(program) { this.acceptArray(program.body); }, MustacheStatement: visitSubExpression, Decorator: visitSubExpression, BlockStatement: visitBlock, DecoratorBlock: visitBlock, PartialStatement: visitPartial, PartialBlockStatement: function(partial) { visitPartial.call(this, partial); this.acceptKey(partial, 'program'); }, ContentStatement: function(/* content */) {}, CommentStatement: function(/* comment */) {}, SubExpression: visitSubExpression, PathExpression: function(/* path */) {}, StringLiteral: function(/* string */) {}, NumberLiteral: function(/* number */) {}, BooleanLiteral: function(/* bool */) {}, UndefinedLiteral: function(/* literal */) {}, NullLiteral: function(/* literal */) {}, Hash: function(hash) { this.acceptArray(hash.pairs); }, HashPair: function(pair) { this.acceptRequired(pair, 'value'); } }; function visitSubExpression(mustache) { this.acceptRequired(mustache, 'path'); this.acceptArray(mustache.params); this.acceptKey(mustache, 'hash'); } function visitBlock(block) { visitSubExpression.call(this, block); this.acceptKey(block, 'program'); this.acceptKey(block, 'inverse'); } function visitPartial(partial) { this.acceptRequired(partial, 'name'); this.acceptArray(partial.params); this.acceptKey(partial, 'hash'); } export default Visitor; handlebars.js-4.7.7/lib/handlebars/compiler/whitespace-control.js000066400000000000000000000142641401244020700251030ustar00rootroot00000000000000import Visitor from './visitor'; function WhitespaceControl(options = {}) { this.options = options; } WhitespaceControl.prototype = new Visitor(); WhitespaceControl.prototype.Program = function(program) { const doStandalone = !this.options.ignoreStandalone; let isRoot = !this.isRootSeen; this.isRootSeen = true; let body = program.body; for (let i = 0, l = body.length; i < l; i++) { let current = body[i], strip = this.accept(current); if (!strip) { continue; } let _isPrevWhitespace = isPrevWhitespace(body, i, isRoot), _isNextWhitespace = isNextWhitespace(body, i, isRoot), openStandalone = strip.openStandalone && _isPrevWhitespace, closeStandalone = strip.closeStandalone && _isNextWhitespace, inlineStandalone = strip.inlineStandalone && _isPrevWhitespace && _isNextWhitespace; if (strip.close) { omitRight(body, i, true); } if (strip.open) { omitLeft(body, i, true); } if (doStandalone && inlineStandalone) { omitRight(body, i); if (omitLeft(body, i)) { // If we are on a standalone node, save the indent info for partials if (current.type === 'PartialStatement') { // Pull out the whitespace from the final line current.indent = /([ \t]+$)/.exec(body[i - 1].original)[1]; } } } if (doStandalone && openStandalone) { omitRight((current.program || current.inverse).body); // Strip out the previous content node if it's whitespace only omitLeft(body, i); } if (doStandalone && closeStandalone) { // Always strip the next node omitRight(body, i); omitLeft((current.inverse || current.program).body); } } return program; }; WhitespaceControl.prototype.BlockStatement = WhitespaceControl.prototype.DecoratorBlock = WhitespaceControl.prototype.PartialBlockStatement = function( block ) { this.accept(block.program); this.accept(block.inverse); // Find the inverse program that is involed with whitespace stripping. let program = block.program || block.inverse, inverse = block.program && block.inverse, firstInverse = inverse, lastInverse = inverse; if (inverse && inverse.chained) { firstInverse = inverse.body[0].program; // Walk the inverse chain to find the last inverse that is actually in the chain. while (lastInverse.chained) { lastInverse = lastInverse.body[lastInverse.body.length - 1].program; } } let strip = { open: block.openStrip.open, close: block.closeStrip.close, // Determine the standalone candiacy. Basically flag our content as being possibly standalone // so our parent can determine if we actually are standalone openStandalone: isNextWhitespace(program.body), closeStandalone: isPrevWhitespace((firstInverse || program).body) }; if (block.openStrip.close) { omitRight(program.body, null, true); } if (inverse) { let inverseStrip = block.inverseStrip; if (inverseStrip.open) { omitLeft(program.body, null, true); } if (inverseStrip.close) { omitRight(firstInverse.body, null, true); } if (block.closeStrip.open) { omitLeft(lastInverse.body, null, true); } // Find standalone else statments if ( !this.options.ignoreStandalone && isPrevWhitespace(program.body) && isNextWhitespace(firstInverse.body) ) { omitLeft(program.body); omitRight(firstInverse.body); } } else if (block.closeStrip.open) { omitLeft(program.body, null, true); } return strip; }; WhitespaceControl.prototype.Decorator = WhitespaceControl.prototype.MustacheStatement = function( mustache ) { return mustache.strip; }; WhitespaceControl.prototype.PartialStatement = WhitespaceControl.prototype.CommentStatement = function( node ) { /* istanbul ignore next */ let strip = node.strip || {}; return { inlineStandalone: true, open: strip.open, close: strip.close }; }; function isPrevWhitespace(body, i, isRoot) { if (i === undefined) { i = body.length; } // Nodes that end with newlines are considered whitespace (but are special // cased for strip operations) let prev = body[i - 1], sibling = body[i - 2]; if (!prev) { return isRoot; } if (prev.type === 'ContentStatement') { return (sibling || !isRoot ? /\r?\n\s*?$/ : /(^|\r?\n)\s*?$/).test( prev.original ); } } function isNextWhitespace(body, i, isRoot) { if (i === undefined) { i = -1; } let next = body[i + 1], sibling = body[i + 2]; if (!next) { return isRoot; } if (next.type === 'ContentStatement') { return (sibling || !isRoot ? /^\s*?\r?\n/ : /^\s*?(\r?\n|$)/).test( next.original ); } } // Marks the node to the right of the position as omitted. // I.e. {{foo}}' ' will mark the ' ' node as omitted. // // If i is undefined, then the first child will be marked as such. // // If mulitple is truthy then all whitespace will be stripped out until non-whitespace // content is met. function omitRight(body, i, multiple) { let current = body[i == null ? 0 : i + 1]; if ( !current || current.type !== 'ContentStatement' || (!multiple && current.rightStripped) ) { return; } let original = current.value; current.value = current.value.replace( multiple ? /^\s+/ : /^[ \t]*\r?\n?/, '' ); current.rightStripped = current.value !== original; } // Marks the node to the left of the position as omitted. // I.e. ' '{{foo}} will mark the ' ' node as omitted. // // If i is undefined then the last child will be marked as such. // // If mulitple is truthy then all whitespace will be stripped out until non-whitespace // content is met. function omitLeft(body, i, multiple) { let current = body[i == null ? body.length - 1 : i - 1]; if ( !current || current.type !== 'ContentStatement' || (!multiple && current.leftStripped) ) { return; } // We omit the last node if it's whitespace only and not preceded by a non-content node. let original = current.value; current.value = current.value.replace(multiple ? /\s+$/ : /[ \t]+$/, ''); current.leftStripped = current.value !== original; return current.leftStripped; } export default WhitespaceControl; handlebars.js-4.7.7/lib/handlebars/decorators.js000066400000000000000000000002071401244020700216140ustar00rootroot00000000000000import registerInline from './decorators/inline'; export function registerDefaultDecorators(instance) { registerInline(instance); } handlebars.js-4.7.7/lib/handlebars/decorators/000077500000000000000000000000001401244020700212575ustar00rootroot00000000000000handlebars.js-4.7.7/lib/handlebars/decorators/inline.js000066400000000000000000000011621401244020700230730ustar00rootroot00000000000000import { extend } from '../utils'; export default function(instance) { instance.registerDecorator('inline', function(fn, props, container, options) { let ret = fn; if (!props.partials) { props.partials = {}; ret = function(context, options) { // Create a new partials stack frame prior to exec. let original = container.partials; container.partials = extend({}, original, props.partials); let ret = fn(context, options); container.partials = original; return ret; }; } props.partials[options.args[0]] = options.fn; return ret; }); } handlebars.js-4.7.7/lib/handlebars/exception.js000066400000000000000000000030101401244020700214400ustar00rootroot00000000000000const errorProps = [ 'description', 'fileName', 'lineNumber', 'endLineNumber', 'message', 'name', 'number', 'stack' ]; function Exception(message, node) { let loc = node && node.loc, line, endLineNumber, column, endColumn; if (loc) { line = loc.start.line; endLineNumber = loc.end.line; column = loc.start.column; endColumn = loc.end.column; message += ' - ' + line + ':' + column; } let tmp = Error.prototype.constructor.call(this, message); // Unfortunately errors are not enumerable in Chrome (at least), so `for prop in tmp` doesn't work. for (let idx = 0; idx < errorProps.length; idx++) { this[errorProps[idx]] = tmp[errorProps[idx]]; } /* istanbul ignore else */ if (Error.captureStackTrace) { Error.captureStackTrace(this, Exception); } try { if (loc) { this.lineNumber = line; this.endLineNumber = endLineNumber; // Work around issue under safari where we can't directly set the column value /* istanbul ignore next */ if (Object.defineProperty) { Object.defineProperty(this, 'column', { value: column, enumerable: true }); Object.defineProperty(this, 'endColumn', { value: endColumn, enumerable: true }); } else { this.column = column; this.endColumn = endColumn; } } } catch (nop) { /* Ignore if the browser is very particular */ } } Exception.prototype = new Error(); export default Exception; handlebars.js-4.7.7/lib/handlebars/helpers.js000066400000000000000000000015301401244020700211110ustar00rootroot00000000000000import registerBlockHelperMissing from './helpers/block-helper-missing'; import registerEach from './helpers/each'; import registerHelperMissing from './helpers/helper-missing'; import registerIf from './helpers/if'; import registerLog from './helpers/log'; import registerLookup from './helpers/lookup'; import registerWith from './helpers/with'; export function registerDefaultHelpers(instance) { registerBlockHelperMissing(instance); registerEach(instance); registerHelperMissing(instance); registerIf(instance); registerLog(instance); registerLookup(instance); registerWith(instance); } export function moveHelperToHooks(instance, helperName, keepHelper) { if (instance.helpers[helperName]) { instance.hooks[helperName] = instance.helpers[helperName]; if (!keepHelper) { delete instance.helpers[helperName]; } } } handlebars.js-4.7.7/lib/handlebars/helpers/000077500000000000000000000000001401244020700205545ustar00rootroot00000000000000handlebars.js-4.7.7/lib/handlebars/helpers/block-helper-missing.js000066400000000000000000000016511401244020700251330ustar00rootroot00000000000000import { appendContextPath, createFrame, isArray } from '../utils'; export default function(instance) { instance.registerHelper('blockHelperMissing', function(context, options) { let inverse = options.inverse, fn = options.fn; if (context === true) { return fn(this); } else if (context === false || context == null) { return inverse(this); } else if (isArray(context)) { if (context.length > 0) { if (options.ids) { options.ids = [options.name]; } return instance.helpers.each(context, options); } else { return inverse(this); } } else { if (options.data && options.ids) { let data = createFrame(options.data); data.contextPath = appendContextPath( options.data.contextPath, options.name ); options = { data: data }; } return fn(context, options); } }); } handlebars.js-4.7.7/lib/handlebars/helpers/each.js000066400000000000000000000047341401244020700220220ustar00rootroot00000000000000import { appendContextPath, blockParams, createFrame, isArray, isFunction } from '../utils'; import Exception from '../exception'; export default function(instance) { instance.registerHelper('each', function(context, options) { if (!options) { throw new Exception('Must pass iterator to #each'); } let fn = options.fn, inverse = options.inverse, i = 0, ret = '', data, contextPath; if (options.data && options.ids) { contextPath = appendContextPath(options.data.contextPath, options.ids[0]) + '.'; } if (isFunction(context)) { context = context.call(this); } if (options.data) { data = createFrame(options.data); } function execIteration(field, index, last) { if (data) { data.key = field; data.index = index; data.first = index === 0; data.last = !!last; if (contextPath) { data.contextPath = contextPath + field; } } ret = ret + fn(context[field], { data: data, blockParams: blockParams( [context[field], field], [contextPath + field, null] ) }); } if (context && typeof context === 'object') { if (isArray(context)) { for (let j = context.length; i < j; i++) { if (i in context) { execIteration(i, i, i === context.length - 1); } } } else if (global.Symbol && context[global.Symbol.iterator]) { const newContext = []; const iterator = context[global.Symbol.iterator](); for (let it = iterator.next(); !it.done; it = iterator.next()) { newContext.push(it.value); } context = newContext; for (let j = context.length; i < j; i++) { execIteration(i, i, i === context.length - 1); } } else { let priorKey; Object.keys(context).forEach(key => { // We're running the iterations one step out of sync so we can detect // the last iteration without have to scan the object twice and create // an itermediate keys array. if (priorKey !== undefined) { execIteration(priorKey, i - 1); } priorKey = key; i++; }); if (priorKey !== undefined) { execIteration(priorKey, i - 1, true); } } } if (i === 0) { ret = inverse(this); } return ret; }); } handlebars.js-4.7.7/lib/handlebars/helpers/helper-missing.js000066400000000000000000000007131401244020700240410ustar00rootroot00000000000000import Exception from '../exception'; export default function(instance) { instance.registerHelper('helperMissing', function(/* [args, ]options */) { if (arguments.length === 1) { // A missing field in a {{foo}} construct. return undefined; } else { // Someone is actually trying to call something, blow up. throw new Exception( 'Missing helper: "' + arguments[arguments.length - 1].name + '"' ); } }); } handlebars.js-4.7.7/lib/handlebars/helpers/if.js000066400000000000000000000022331401244020700215100ustar00rootroot00000000000000import { isEmpty, isFunction } from '../utils'; import Exception from '../exception'; export default function(instance) { instance.registerHelper('if', function(conditional, options) { if (arguments.length != 2) { throw new Exception('#if requires exactly one argument'); } if (isFunction(conditional)) { conditional = conditional.call(this); } // Default behavior is to render the positive path if the value is truthy and not empty. // The `includeZero` option may be set to treat the condtional as purely not empty based on the // behavior of isEmpty. Effectively this determines if 0 is handled by the positive path or negative. if ((!options.hash.includeZero && !conditional) || isEmpty(conditional)) { return options.inverse(this); } else { return options.fn(this); } }); instance.registerHelper('unless', function(conditional, options) { if (arguments.length != 2) { throw new Exception('#unless requires exactly one argument'); } return instance.helpers['if'].call(this, conditional, { fn: options.inverse, inverse: options.fn, hash: options.hash }); }); } handlebars.js-4.7.7/lib/handlebars/helpers/log.js000066400000000000000000000010111401244020700216640ustar00rootroot00000000000000export default function(instance) { instance.registerHelper('log', function(/* message, options */) { let args = [undefined], options = arguments[arguments.length - 1]; for (let i = 0; i < arguments.length - 1; i++) { args.push(arguments[i]); } let level = 1; if (options.hash.level != null) { level = options.hash.level; } else if (options.data && options.data.level != null) { level = options.data.level; } args[0] = level; instance.log(...args); }); } handlebars.js-4.7.7/lib/handlebars/helpers/lookup.js000066400000000000000000000003751401244020700224300ustar00rootroot00000000000000export default function(instance) { instance.registerHelper('lookup', function(obj, field, options) { if (!obj) { // Note for 5.0: Change to "obj == null" in 5.0 return obj; } return options.lookupProperty(obj, field); }); } handlebars.js-4.7.7/lib/handlebars/helpers/with.js000066400000000000000000000016141401244020700220670ustar00rootroot00000000000000import { appendContextPath, blockParams, createFrame, isEmpty, isFunction } from '../utils'; import Exception from '../exception'; export default function(instance) { instance.registerHelper('with', function(context, options) { if (arguments.length != 2) { throw new Exception('#with requires exactly one argument'); } if (isFunction(context)) { context = context.call(this); } let fn = options.fn; if (!isEmpty(context)) { let data = options.data; if (options.data && options.ids) { data = createFrame(options.data); data.contextPath = appendContextPath( options.data.contextPath, options.ids[0] ); } return fn(context, { data: data, blockParams: blockParams([context], [data && data.contextPath]) }); } else { return options.inverse(this); } }); } handlebars.js-4.7.7/lib/handlebars/internal/000077500000000000000000000000001401244020700207265ustar00rootroot00000000000000handlebars.js-4.7.7/lib/handlebars/internal/create-new-lookup-object.js000066400000000000000000000006711401244020700260750ustar00rootroot00000000000000import { extend } from '../utils'; /** * Create a new object with "null"-prototype to avoid truthy results on prototype properties. * The resulting object can be used with "object[property]" to check if a property exists * @param {...object} sources a varargs parameter of source objects that will be merged * @returns {object} */ export function createNewLookupObject(...sources) { return extend(Object.create(null), ...sources); } handlebars.js-4.7.7/lib/handlebars/internal/proto-access.js000066400000000000000000000045671401244020700237020ustar00rootroot00000000000000import { createNewLookupObject } from './create-new-lookup-object'; import * as logger from '../logger'; const loggedProperties = Object.create(null); export function createProtoAccessControl(runtimeOptions) { let defaultMethodWhiteList = Object.create(null); defaultMethodWhiteList['constructor'] = false; defaultMethodWhiteList['__defineGetter__'] = false; defaultMethodWhiteList['__defineSetter__'] = false; defaultMethodWhiteList['__lookupGetter__'] = false; let defaultPropertyWhiteList = Object.create(null); // eslint-disable-next-line no-proto defaultPropertyWhiteList['__proto__'] = false; return { properties: { whitelist: createNewLookupObject( defaultPropertyWhiteList, runtimeOptions.allowedProtoProperties ), defaultValue: runtimeOptions.allowProtoPropertiesByDefault }, methods: { whitelist: createNewLookupObject( defaultMethodWhiteList, runtimeOptions.allowedProtoMethods ), defaultValue: runtimeOptions.allowProtoMethodsByDefault } }; } export function resultIsAllowed(result, protoAccessControl, propertyName) { if (typeof result === 'function') { return checkWhiteList(protoAccessControl.methods, propertyName); } else { return checkWhiteList(protoAccessControl.properties, propertyName); } } function checkWhiteList(protoAccessControlForType, propertyName) { if (protoAccessControlForType.whitelist[propertyName] !== undefined) { return protoAccessControlForType.whitelist[propertyName] === true; } if (protoAccessControlForType.defaultValue !== undefined) { return protoAccessControlForType.defaultValue; } logUnexpecedPropertyAccessOnce(propertyName); return false; } function logUnexpecedPropertyAccessOnce(propertyName) { if (loggedProperties[propertyName] !== true) { loggedProperties[propertyName] = true; logger.log( 'error', `Handlebars: Access has been denied to resolve the property "${propertyName}" because it is not an "own property" of its parent.\n` + `You can add a runtime option to disable the check or this warning:\n` + `See https://handlebarsjs.com/api-reference/runtime-options.html#options-to-control-prototype-access for details` ); } } export function resetLoggedProperties() { Object.keys(loggedProperties).forEach(propertyName => { delete loggedProperties[propertyName]; }); } handlebars.js-4.7.7/lib/handlebars/internal/wrapHelper.js000066400000000000000000000010701401244020700233730ustar00rootroot00000000000000export function wrapHelper(helper, transformOptionsFn) { if (typeof helper !== 'function') { // This should not happen, but apparently it does in https://github.com/wycats/handlebars.js/issues/1639 // We try to make the wrapper least-invasive by not wrapping it, if the helper is not a function. return helper; } let wrapper = function(/* dynamic arguments */) { const options = arguments[arguments.length - 1]; arguments[arguments.length - 1] = transformOptionsFn(options); return helper.apply(this, arguments); }; return wrapper; } handlebars.js-4.7.7/lib/handlebars/logger.js000066400000000000000000000016671401244020700207410ustar00rootroot00000000000000import { indexOf } from './utils'; let logger = { methodMap: ['debug', 'info', 'warn', 'error'], level: 'info', // Maps a given level value to the `methodMap` indexes above. lookupLevel: function(level) { if (typeof level === 'string') { let levelMap = indexOf(logger.methodMap, level.toLowerCase()); if (levelMap >= 0) { level = levelMap; } else { level = parseInt(level, 10); } } return level; }, // Can be overridden in the host environment log: function(level, ...message) { level = logger.lookupLevel(level); if ( typeof console !== 'undefined' && logger.lookupLevel(logger.level) <= level ) { let method = logger.methodMap[level]; // eslint-disable-next-line no-console if (!console[method]) { method = 'log'; } console[method](...message); // eslint-disable-line no-console } } }; export default logger; handlebars.js-4.7.7/lib/handlebars/no-conflict.js000066400000000000000000000005331401244020700216640ustar00rootroot00000000000000export default function(Handlebars) { /* istanbul ignore next */ let root = typeof global !== 'undefined' ? global : window, $Handlebars = root.Handlebars; /* istanbul ignore next */ Handlebars.noConflict = function() { if (root.Handlebars === Handlebars) { root.Handlebars = $Handlebars; } return Handlebars; }; } handlebars.js-4.7.7/lib/handlebars/runtime.js000066400000000000000000000302031401244020700211310ustar00rootroot00000000000000import * as Utils from './utils'; import Exception from './exception'; import { COMPILER_REVISION, createFrame, LAST_COMPATIBLE_COMPILER_REVISION, REVISION_CHANGES } from './base'; import { moveHelperToHooks } from './helpers'; import { wrapHelper } from './internal/wrapHelper'; import { createProtoAccessControl, resultIsAllowed } from './internal/proto-access'; export function checkRevision(compilerInfo) { const compilerRevision = (compilerInfo && compilerInfo[0]) || 1, currentRevision = COMPILER_REVISION; if ( compilerRevision >= LAST_COMPATIBLE_COMPILER_REVISION && compilerRevision <= COMPILER_REVISION ) { return; } if (compilerRevision < LAST_COMPATIBLE_COMPILER_REVISION) { const runtimeVersions = REVISION_CHANGES[currentRevision], compilerVersions = REVISION_CHANGES[compilerRevision]; throw new Exception( 'Template was precompiled with an older version of Handlebars than the current runtime. ' + 'Please update your precompiler to a newer version (' + runtimeVersions + ') or downgrade your runtime to an older version (' + compilerVersions + ').' ); } else { // Use the embedded version info since the runtime doesn't know about this revision yet throw new Exception( 'Template was precompiled with a newer version of Handlebars than the current runtime. ' + 'Please update your runtime to a newer version (' + compilerInfo[1] + ').' ); } } export function template(templateSpec, env) { /* istanbul ignore next */ if (!env) { throw new Exception('No environment passed to template'); } if (!templateSpec || !templateSpec.main) { throw new Exception('Unknown template object: ' + typeof templateSpec); } templateSpec.main.decorator = templateSpec.main_d; // Note: Using env.VM references rather than local var references throughout this section to allow // for external users to override these as pseudo-supported APIs. env.VM.checkRevision(templateSpec.compiler); // backwards compatibility for precompiled templates with compiler-version 7 (<4.3.0) const templateWasPrecompiledWithCompilerV7 = templateSpec.compiler && templateSpec.compiler[0] === 7; function invokePartialWrapper(partial, context, options) { if (options.hash) { context = Utils.extend({}, context, options.hash); if (options.ids) { options.ids[0] = true; } } partial = env.VM.resolvePartial.call(this, partial, context, options); let extendedOptions = Utils.extend({}, options, { hooks: this.hooks, protoAccessControl: this.protoAccessControl }); let result = env.VM.invokePartial.call( this, partial, context, extendedOptions ); if (result == null && env.compile) { options.partials[options.name] = env.compile( partial, templateSpec.compilerOptions, env ); result = options.partials[options.name](context, extendedOptions); } if (result != null) { if (options.indent) { let lines = result.split('\n'); for (let i = 0, l = lines.length; i < l; i++) { if (!lines[i] && i + 1 === l) { break; } lines[i] = options.indent + lines[i]; } result = lines.join('\n'); } return result; } else { throw new Exception( 'The partial ' + options.name + ' could not be compiled when running in runtime-only mode' ); } } // Just add water let container = { strict: function(obj, name, loc) { if (!obj || !(name in obj)) { throw new Exception('"' + name + '" not defined in ' + obj, { loc: loc }); } return container.lookupProperty(obj, name); }, lookupProperty: function(parent, propertyName) { let result = parent[propertyName]; if (result == null) { return result; } if (Object.prototype.hasOwnProperty.call(parent, propertyName)) { return result; } if (resultIsAllowed(result, container.protoAccessControl, propertyName)) { return result; } return undefined; }, lookup: function(depths, name) { const len = depths.length; for (let i = 0; i < len; i++) { let result = depths[i] && container.lookupProperty(depths[i], name); if (result != null) { return depths[i][name]; } } }, lambda: function(current, context) { return typeof current === 'function' ? current.call(context) : current; }, escapeExpression: Utils.escapeExpression, invokePartial: invokePartialWrapper, fn: function(i) { let ret = templateSpec[i]; ret.decorator = templateSpec[i + '_d']; return ret; }, programs: [], program: function(i, data, declaredBlockParams, blockParams, depths) { let programWrapper = this.programs[i], fn = this.fn(i); if (data || depths || blockParams || declaredBlockParams) { programWrapper = wrapProgram( this, i, fn, data, declaredBlockParams, blockParams, depths ); } else if (!programWrapper) { programWrapper = this.programs[i] = wrapProgram(this, i, fn); } return programWrapper; }, data: function(value, depth) { while (value && depth--) { value = value._parent; } return value; }, mergeIfNeeded: function(param, common) { let obj = param || common; if (param && common && param !== common) { obj = Utils.extend({}, common, param); } return obj; }, // An empty object to use as replacement for null-contexts nullContext: Object.seal({}), noop: env.VM.noop, compilerInfo: templateSpec.compiler }; function ret(context, options = {}) { let data = options.data; ret._setup(options); if (!options.partial && templateSpec.useData) { data = initData(context, data); } let depths, blockParams = templateSpec.useBlockParams ? [] : undefined; if (templateSpec.useDepths) { if (options.depths) { depths = context != options.depths[0] ? [context].concat(options.depths) : options.depths; } else { depths = [context]; } } function main(context /*, options*/) { return ( '' + templateSpec.main( container, context, container.helpers, container.partials, data, blockParams, depths ) ); } main = executeDecorators( templateSpec.main, main, container, options.depths || [], data, blockParams ); return main(context, options); } ret.isTop = true; ret._setup = function(options) { if (!options.partial) { let mergedHelpers = Utils.extend({}, env.helpers, options.helpers); wrapHelpersToPassLookupProperty(mergedHelpers, container); container.helpers = mergedHelpers; if (templateSpec.usePartial) { // Use mergeIfNeeded here to prevent compiling global partials multiple times container.partials = container.mergeIfNeeded( options.partials, env.partials ); } if (templateSpec.usePartial || templateSpec.useDecorators) { container.decorators = Utils.extend( {}, env.decorators, options.decorators ); } container.hooks = {}; container.protoAccessControl = createProtoAccessControl(options); let keepHelperInHelpers = options.allowCallsToHelperMissing || templateWasPrecompiledWithCompilerV7; moveHelperToHooks(container, 'helperMissing', keepHelperInHelpers); moveHelperToHooks(container, 'blockHelperMissing', keepHelperInHelpers); } else { container.protoAccessControl = options.protoAccessControl; // internal option container.helpers = options.helpers; container.partials = options.partials; container.decorators = options.decorators; container.hooks = options.hooks; } }; ret._child = function(i, data, blockParams, depths) { if (templateSpec.useBlockParams && !blockParams) { throw new Exception('must pass block params'); } if (templateSpec.useDepths && !depths) { throw new Exception('must pass parent depths'); } return wrapProgram( container, i, templateSpec[i], data, 0, blockParams, depths ); }; return ret; } export function wrapProgram( container, i, fn, data, declaredBlockParams, blockParams, depths ) { function prog(context, options = {}) { let currentDepths = depths; if ( depths && context != depths[0] && !(context === container.nullContext && depths[0] === null) ) { currentDepths = [context].concat(depths); } return fn( container, context, container.helpers, container.partials, options.data || data, blockParams && [options.blockParams].concat(blockParams), currentDepths ); } prog = executeDecorators(fn, prog, container, depths, data, blockParams); prog.program = i; prog.depth = depths ? depths.length : 0; prog.blockParams = declaredBlockParams || 0; return prog; } /** * This is currently part of the official API, therefore implementation details should not be changed. */ export function resolvePartial(partial, context, options) { if (!partial) { if (options.name === '@partial-block') { partial = options.data['partial-block']; } else { partial = options.partials[options.name]; } } else if (!partial.call && !options.name) { // This is a dynamic partial that returned a string options.name = partial; partial = options.partials[partial]; } return partial; } export function invokePartial(partial, context, options) { // Use the current closure context to save the partial-block if this partial const currentPartialBlock = options.data && options.data['partial-block']; options.partial = true; if (options.ids) { options.data.contextPath = options.ids[0] || options.data.contextPath; } let partialBlock; if (options.fn && options.fn !== noop) { options.data = createFrame(options.data); // Wrapper function to get access to currentPartialBlock from the closure let fn = options.fn; partialBlock = options.data['partial-block'] = function partialBlockWrapper( context, options = {} ) { // Restore the partial-block from the closure for the execution of the block // i.e. the part inside the block of the partial call. options.data = createFrame(options.data); options.data['partial-block'] = currentPartialBlock; return fn(context, options); }; if (fn.partials) { options.partials = Utils.extend({}, options.partials, fn.partials); } } if (partial === undefined && partialBlock) { partial = partialBlock; } if (partial === undefined) { throw new Exception('The partial ' + options.name + ' could not be found'); } else if (partial instanceof Function) { return partial(context, options); } } export function noop() { return ''; } function initData(context, data) { if (!data || !('root' in data)) { data = data ? createFrame(data) : {}; data.root = context; } return data; } function executeDecorators(fn, prog, container, depths, data, blockParams) { if (fn.decorator) { let props = {}; prog = fn.decorator( prog, props, container, depths && depths[0], data, blockParams, depths ); Utils.extend(prog, props); } return prog; } function wrapHelpersToPassLookupProperty(mergedHelpers, container) { Object.keys(mergedHelpers).forEach(helperName => { let helper = mergedHelpers[helperName]; mergedHelpers[helperName] = passLookupPropertyOption(helper, container); }); } function passLookupPropertyOption(helper, container) { const lookupProperty = container.lookupProperty; return wrapHelper(helper, options => { return Utils.extend({ lookupProperty }, options); }); } handlebars.js-4.7.7/lib/handlebars/safe-string.js000066400000000000000000000003451401244020700216740ustar00rootroot00000000000000// Build out our basic SafeString type function SafeString(string) { this.string = string; } SafeString.prototype.toString = SafeString.prototype.toHTML = function() { return '' + this.string; }; export default SafeString; handlebars.js-4.7.7/lib/handlebars/utils.js000066400000000000000000000052161401244020700206140ustar00rootroot00000000000000const escape = { '&': '&', '<': '<', '>': '>', '"': '"', "'": ''', '`': '`', '=': '=' }; const badChars = /[&<>"'`=]/g, possible = /[&<>"'`=]/; function escapeChar(chr) { return escape[chr]; } export function extend(obj /* , ...source */) { for (let i = 1; i < arguments.length; i++) { for (let key in arguments[i]) { if (Object.prototype.hasOwnProperty.call(arguments[i], key)) { obj[key] = arguments[i][key]; } } } return obj; } export let toString = Object.prototype.toString; // Sourced from lodash // https://github.com/bestiejs/lodash/blob/master/LICENSE.txt /* eslint-disable func-style */ let isFunction = function(value) { return typeof value === 'function'; }; // fallback for older versions of Chrome and Safari /* istanbul ignore next */ if (isFunction(/x/)) { isFunction = function(value) { return ( typeof value === 'function' && toString.call(value) === '[object Function]' ); }; } export { isFunction }; /* eslint-enable func-style */ /* istanbul ignore next */ export const isArray = Array.isArray || function(value) { return value && typeof value === 'object' ? toString.call(value) === '[object Array]' : false; }; // Older IE versions do not directly support indexOf so we must implement our own, sadly. export function indexOf(array, value) { for (let i = 0, len = array.length; i < len; i++) { if (array[i] === value) { return i; } } return -1; } export function escapeExpression(string) { if (typeof string !== 'string') { // don't escape SafeStrings, since they're already safe if (string && string.toHTML) { return string.toHTML(); } else if (string == null) { return ''; } else if (!string) { return string + ''; } // Force a string conversion as this will be done by the append regardless and // the regex test will do this transparently behind the scenes, causing issues if // an object's to string has escaped characters in it. string = '' + string; } if (!possible.test(string)) { return string; } return string.replace(badChars, escapeChar); } export function isEmpty(value) { if (!value && value !== 0) { return true; } else if (isArray(value) && value.length === 0) { return true; } else { return false; } } export function createFrame(object) { let frame = extend({}, object); frame._parent = object; return frame; } export function blockParams(params, ids) { params.path = ids; return params; } export function appendContextPath(contextPath, id) { return (contextPath ? contextPath + '.' : '') + id; } handlebars.js-4.7.7/lib/index.js000066400000000000000000000014301401244020700164520ustar00rootroot00000000000000// USAGE: // var handlebars = require('handlebars'); /* eslint-disable no-var */ // var local = handlebars.create(); var handlebars = require('../dist/cjs/handlebars')['default']; var printer = require('../dist/cjs/handlebars/compiler/printer'); handlebars.PrintVisitor = printer.PrintVisitor; handlebars.print = printer.print; module.exports = handlebars; // Publish a Node.js require() handler for .handlebars and .hbs files function extension(module, filename) { var fs = require('fs'); var templateString = fs.readFileSync(filename, 'utf8'); module.exports = handlebars.compile(templateString); } /* istanbul ignore else */ if (typeof require !== 'undefined' && require.extensions) { require.extensions['.handlebars'] = extension; require.extensions['.hbs'] = extension; } handlebars.js-4.7.7/lib/precompiler.js000066400000000000000000000204651401244020700176750ustar00rootroot00000000000000/* eslint-disable no-console */ import Async from 'neo-async'; import fs from 'fs'; import * as Handlebars from './handlebars'; import { basename } from 'path'; import { SourceMapConsumer, SourceNode } from 'source-map'; module.exports.loadTemplates = function(opts, callback) { loadStrings(opts, function(err, strings) { if (err) { callback(err); } else { loadFiles(opts, function(err, files) { if (err) { callback(err); } else { opts.templates = strings.concat(files); callback(undefined, opts); } }); } }); }; function loadStrings(opts, callback) { let strings = arrayCast(opts.string), names = arrayCast(opts.name); if (names.length !== strings.length && strings.length > 1) { return callback( new Handlebars.Exception( 'Number of names did not match the number of string inputs' ) ); } Async.map( strings, function(string, callback) { if (string !== '-') { callback(undefined, string); } else { // Load from stdin let buffer = ''; process.stdin.setEncoding('utf8'); process.stdin.on('data', function(chunk) { buffer += chunk; }); process.stdin.on('end', function() { callback(undefined, buffer); }); } }, function(err, strings) { strings = strings.map((string, index) => ({ name: names[index], path: names[index], source: string })); callback(err, strings); } ); } function loadFiles(opts, callback) { // Build file extension pattern let extension = (opts.extension || 'handlebars').replace( /[\\^$*+?.():=!|{}\-[\]]/g, function(arg) { return '\\' + arg; } ); extension = new RegExp('\\.' + extension + '$'); let ret = [], queue = (opts.files || []).map(template => ({ template, root: opts.root })); Async.whilst( () => queue.length, function(callback) { let { template: path, root } = queue.shift(); fs.stat(path, function(err, stat) { if (err) { return callback( new Handlebars.Exception(`Unable to open template file "${path}"`) ); } if (stat.isDirectory()) { opts.hasDirectory = true; fs.readdir(path, function(err, children) { /* istanbul ignore next : Race condition that being too lazy to test */ if (err) { return callback(err); } children.forEach(function(file) { let childPath = path + '/' + file; if ( extension.test(childPath) || fs.statSync(childPath).isDirectory() ) { queue.push({ template: childPath, root: root || path }); } }); callback(); }); } else { fs.readFile(path, 'utf8', function(err, data) { /* istanbul ignore next : Race condition that being too lazy to test */ if (err) { return callback(err); } if (opts.bom && data.indexOf('\uFEFF') === 0) { data = data.substring(1); } // Clean the template name let name = path; if (!root) { name = basename(name); } else if (name.indexOf(root) === 0) { name = name.substring(root.length + 1); } name = name.replace(extension, ''); ret.push({ path: path, name: name, source: data }); callback(); }); } }); }, function(err) { if (err) { callback(err); } else { callback(undefined, ret); } } ); } module.exports.cli = function(opts) { if (opts.version) { console.log(Handlebars.VERSION); return; } if (!opts.templates.length && !opts.hasDirectory) { throw new Handlebars.Exception( 'Must define at least one template or directory.' ); } if (opts.simple && opts.min) { throw new Handlebars.Exception('Unable to minimize simple output'); } const multiple = opts.templates.length !== 1 || opts.hasDirectory; if (opts.simple && multiple) { throw new Handlebars.Exception( 'Unable to output multiple templates in simple mode' ); } // Force simple mode if we have only one template and it's unnamed. if ( !opts.amd && !opts.commonjs && opts.templates.length === 1 && !opts.templates[0].name ) { opts.simple = true; } // Convert the known list into a hash let known = {}; if (opts.known && !Array.isArray(opts.known)) { opts.known = [opts.known]; } if (opts.known) { for (let i = 0, len = opts.known.length; i < len; i++) { known[opts.known[i]] = true; } } const objectName = opts.partial ? 'Handlebars.partials' : 'templates'; let output = new SourceNode(); if (!opts.simple) { if (opts.amd) { output.add( "define(['" + opts.handlebarPath + 'handlebars.runtime\'], function(Handlebars) {\n Handlebars = Handlebars["default"];' ); } else if (opts.commonjs) { output.add('var Handlebars = require("' + opts.commonjs + '");'); } else { output.add('(function() {\n'); } output.add(' var template = Handlebars.template, templates = '); if (opts.namespace) { output.add(opts.namespace); output.add(' = '); output.add(opts.namespace); output.add(' || '); } output.add('{};\n'); } opts.templates.forEach(function(template) { let options = { knownHelpers: known, knownHelpersOnly: opts.o }; if (opts.map) { options.srcName = template.path; } if (opts.data) { options.data = true; } let precompiled = Handlebars.precompile(template.source, options); // If we are generating a source map, we have to reconstruct the SourceNode object if (opts.map) { let consumer = new SourceMapConsumer(precompiled.map); precompiled = SourceNode.fromStringWithSourceMap( precompiled.code, consumer ); } if (opts.simple) { output.add([precompiled, '\n']); } else { if (!template.name) { throw new Handlebars.Exception('Name missing for template'); } if (opts.amd && !multiple) { output.add('return '); } output.add([ objectName, "['", template.name, "'] = template(", precompiled, ');\n' ]); } }); // Output the content if (!opts.simple) { if (opts.amd) { if (multiple) { output.add(['return ', objectName, ';\n']); } output.add('});'); } else if (!opts.commonjs) { output.add('})();'); } } if (opts.map) { output.add('\n//# sourceMappingURL=' + opts.map + '\n'); } output = output.toStringWithSourceMap(); output.map = output.map + ''; if (opts.min) { output = minify(output, opts.map); } if (opts.map) { fs.writeFileSync(opts.map, output.map, 'utf8'); } output = output.code; if (opts.output) { fs.writeFileSync(opts.output, output, 'utf8'); } else { console.log(output); } }; function arrayCast(value) { value = value != null ? value : []; if (!Array.isArray(value)) { value = [value]; } return value; } /** * Run uglify to minify the compiled template, if uglify exists in the dependencies. * * We are using `require` instead of `import` here, because es6-modules do not allow * dynamic imports and uglify-js is an optional dependency. Since we are inside NodeJS here, this * should not be a problem. * * @param {string} output the compiled template * @param {string} sourceMapFile the file to write the source map to. */ function minify(output, sourceMapFile) { try { // Try to resolve uglify-js in order to see if it does exist require.resolve('uglify-js'); } catch (e) { if (e.code !== 'MODULE_NOT_FOUND') { // Something else seems to be wrong throw e; } // it does not exist! console.error( 'Code minimization is disabled due to missing uglify-js dependency' ); return output; } return require('uglify-js').minify(output.code, { sourceMap: { content: output.map, url: sourceMapFile } }); } handlebars.js-4.7.7/nyc.config.js000066400000000000000000000003061401244020700166330ustar00rootroot00000000000000module.exports = { 'check-coverage': true, branches: 100, lines: 100, functions: 100, statements: 100, exclude: ['**/spec/**', '**/handlebars/compiler/parser.js'], reporter: 'html' }; handlebars.js-4.7.7/package-lock.json000066400000000000000000014150641401244020700174700ustar00rootroot00000000000000{ "name": "handlebars", "version": "4.7.6", "lockfileVersion": 1, "requires": true, "dependencies": { "@babel/code-frame": { "version": "7.8.3", "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.8.3.tgz", "integrity": "sha512-a9gxpmdXtZEInkCSHUJDLHZVBgb1QS0jhss4cPP93EW7s+uC5bikET2twEF3KV+7rDblJcmNvTR7VJejqd2C2g==", "dev": true, "requires": { "@babel/highlight": "^7.8.3" } }, "@babel/generator": { "version": "7.8.8", "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.8.8.tgz", "integrity": "sha512-HKyUVu69cZoclptr8t8U5b6sx6zoWjh8jiUhnuj3MpZuKT2dJ8zPTuiy31luq32swhI0SpwItCIlU8XW7BZeJg==", "dev": true, "requires": { "@babel/types": "^7.8.7", "jsesc": "^2.5.1", "lodash": "^4.17.13", "source-map": "^0.5.0" }, "dependencies": { "jsesc": { "version": "2.5.2", "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", "dev": true }, "source-map": { "version": "0.5.7", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", "dev": true } } }, "@babel/helper-function-name": { "version": "7.8.3", "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.8.3.tgz", "integrity": "sha512-BCxgX1BC2hD/oBlIFUgOCQDOPV8nSINxCwM3o93xP4P9Fq6aV5sgv2cOOITDMtCfQ+3PvHp3l689XZvAM9QyOA==", "dev": true, "requires": { "@babel/helper-get-function-arity": "^7.8.3", "@babel/template": "^7.8.3", "@babel/types": "^7.8.3" } }, "@babel/helper-get-function-arity": { "version": "7.8.3", "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.8.3.tgz", "integrity": "sha512-FVDR+Gd9iLjUMY1fzE2SR0IuaJToR4RkCDARVfsBBPSP53GEqSFjD8gNyxg246VUyc/ALRxFaAK8rVG7UT7xRA==", "dev": true, "requires": { "@babel/types": "^7.8.3" } }, "@babel/helper-split-export-declaration": { "version": "7.8.3", "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.8.3.tgz", "integrity": "sha512-3x3yOeyBhW851hroze7ElzdkeRXQYQbFIb7gLK1WQYsw2GWDay5gAJNw1sWJ0VFP6z5J1whqeXH/WCdCjZv6dA==", "dev": true, "requires": { "@babel/types": "^7.8.3" } }, "@babel/highlight": { "version": "7.8.3", "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.8.3.tgz", "integrity": "sha512-PX4y5xQUvy0fnEVHrYOarRPXVWafSjTW9T0Hab8gVIawpl2Sj0ORyrygANq+KjcNlSSTw0YCLSNA8OyZ1I4yEg==", "dev": true, "requires": { "chalk": "^2.0.0", "esutils": "^2.0.2", "js-tokens": "^4.0.0" }, "dependencies": { "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 } } }, "@babel/parser": { "version": "7.8.8", "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.8.8.tgz", "integrity": "sha512-mO5GWzBPsPf6865iIbzNE0AvkKF3NE+2S3eRUpE+FE07BOAkXh6G+GW/Pj01hhXjve1WScbaIO4UlY1JKeqCcA==", "dev": true }, "@babel/runtime": { "version": "7.8.7", "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.8.7.tgz", "integrity": "sha512-+AATMUFppJDw6aiR5NVPHqIQBlV/Pj8wY/EZH+lmvRdUo9xBaz/rF3alAwFJQavvKfeOlPE7oaaDHVbcySbCsg==", "dev": true, "requires": { "regenerator-runtime": "^0.13.4" } }, "@babel/template": { "version": "7.8.6", "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.8.6.tgz", "integrity": "sha512-zbMsPMy/v0PWFZEhQJ66bqjhH+z0JgMoBWuikXybgG3Gkd/3t5oQ1Rw2WQhnSrsOmsKXnZOx15tkC4qON/+JPg==", "dev": true, "requires": { "@babel/code-frame": "^7.8.3", "@babel/parser": "^7.8.6", "@babel/types": "^7.8.6" } }, "@babel/traverse": { "version": "7.8.6", "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.8.6.tgz", "integrity": "sha512-2B8l0db/DPi8iinITKuo7cbPznLCEk0kCxDoB9/N6gGNg/gxOXiR/IcymAFPiBwk5w6TtQ27w4wpElgp9btR9A==", "dev": true, "requires": { "@babel/code-frame": "^7.8.3", "@babel/generator": "^7.8.6", "@babel/helper-function-name": "^7.8.3", "@babel/helper-split-export-declaration": "^7.8.3", "@babel/parser": "^7.8.6", "@babel/types": "^7.8.6", "debug": "^4.1.0", "globals": "^11.1.0", "lodash": "^4.17.13" }, "dependencies": { "debug": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", "dev": true, "requires": { "ms": "^2.1.1" } }, "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 } } }, "@babel/types": { "version": "7.8.7", "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.8.7.tgz", "integrity": "sha512-k2TreEHxFA4CjGkL+GYjRyx35W0Mr7DP5+9q6WMkyKXB+904bYmG40syjMFV0oLlhhFCwWl0vA0DyzTDkwAiJw==", "dev": true, "requires": { "esutils": "^2.0.2", "lodash": "^4.17.13", "to-fast-properties": "^2.0.0" }, "dependencies": { "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 } } }, "@knappi/grunt-saucelabs": { "version": "9.0.2", "resolved": "https://registry.npmjs.org/@knappi/grunt-saucelabs/-/grunt-saucelabs-9.0.2.tgz", "integrity": "sha512-PHnusXA+begWFgZS084ZAC8kT7FNRvvJIWg5FOqusRjr4LSe++RIk2HRULAQ8Dx+6HiKJiQXzrAsDagKh3k1pw==", "dev": true, "requires": { "@knappi/sauce-tunnel": "^2.5.0", "colors": "~1.1.2", "lodash": "^4.17.11", "q": "~1.4.1", "requestretry": "~1.9.0", "saucelabs": "^1.5.0" } }, "@knappi/sauce-tunnel": { "version": "2.5.0", "resolved": "https://registry.npmjs.org/@knappi/sauce-tunnel/-/sauce-tunnel-2.5.0.tgz", "integrity": "sha512-8f60HrHH4SRHOspcVLbN0gpDiBYLQjmZCXwmqibhzJDHGaD/fflPpdUD2kJJyeioydcf1T0xfpbMcJW0dLjpnw==", "dev": true, "requires": { "chalk": "^2.4.2", "request": "^2.88.0", "split": "^1.0.1" } }, "@nodelib/fs.scandir": { "version": "2.1.3", "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.3.tgz", "integrity": "sha512-eGmwYQn3gxo4r7jdQnkrrN6bY478C3P+a/y72IJukF8LjB6ZHeB3c+Ehacj3sYeSmUXGlnA67/PmbM9CVwL7Dw==", "dev": true, "requires": { "@nodelib/fs.stat": "2.0.3", "run-parallel": "^1.1.9" } }, "@nodelib/fs.stat": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.3.tgz", "integrity": "sha512-bQBFruR2TAwoevBEd/NWMoAAtNGzTRgdrqnYCc7dhzfoNvqPzLyqlEQnzZ3kVnNrSp25iyxE00/3h2fqGAGArA==", "dev": true }, "@nodelib/fs.walk": { "version": "1.2.4", "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.4.tgz", "integrity": "sha512-1V9XOY4rDW0rehzbrcqAmHnz8e7SKvX27gh8Gt2WgB0+pdzdiLV83p72kZPU+jvMbS1qU5mauP2iOvO8rhmurQ==", "dev": true, "requires": { "@nodelib/fs.scandir": "2.1.3", "fastq": "^1.6.0" } }, "@samverschueren/stream-to-observable": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/@samverschueren/stream-to-observable/-/stream-to-observable-0.3.0.tgz", "integrity": "sha512-MI4Xx6LHs4Webyvi6EbspgyAb4D2Q2VtnCQ1blOJcoLS6mVa8lNN2rkIy1CVxfTUpoyIbCTkXES1rLXztFD1lg==", "dev": true, "requires": { "any-observable": "^0.3.0" } }, "@sinonjs/commons": { "version": "1.7.1", "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.7.1.tgz", "integrity": "sha512-Debi3Baff1Qu1Unc3mjJ96MgpbwTn43S1+9yJ0llWygPwDNu2aaWBD6yc9y/Z8XDRNhx7U+u2UDg2OGQXkclUQ==", "dev": true, "requires": { "type-detect": "4.0.8" } }, "@sinonjs/formatio": { "version": "3.2.2", "resolved": "https://registry.npmjs.org/@sinonjs/formatio/-/formatio-3.2.2.tgz", "integrity": "sha512-B8SEsgd8gArBLMD6zpRw3juQ2FVSsmdd7qlevyDqzS9WTCtvF55/gAL+h6gue8ZvPYcdiPdvueM/qm//9XzyTQ==", "dev": true, "requires": { "@sinonjs/commons": "^1", "@sinonjs/samsam": "^3.1.0" } }, "@sinonjs/samsam": { "version": "3.3.3", "resolved": "https://registry.npmjs.org/@sinonjs/samsam/-/samsam-3.3.3.tgz", "integrity": "sha512-bKCMKZvWIjYD0BLGnNrxVuw4dkWCYsLqFOUWw8VgKF/+5Y+mE7LfHWPIYoDXowH+3a9LsWDMo0uAP8YDosPvHQ==", "dev": true, "requires": { "@sinonjs/commons": "^1.3.0", "array-from": "^2.1.1", "lodash": "^4.17.15" } }, "@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 }, "@types/color-name": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/@types/color-name/-/color-name-1.1.1.tgz", "integrity": "sha512-rr+OQyAjxze7GgWrSaJwydHStIhHq2lvY3BOC2Mj7KnzI7XK0Uw1TOOdI9lDoajEbSWLiYgoo4f1R51erQfhPQ==", "dev": true }, "@types/events": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/@types/events/-/events-3.0.0.tgz", "integrity": "sha512-EaObqwIvayI5a8dCzhFrjKzVwKLxjoG9T6Ppd5CEo07LRKfQ8Yokw54r5+Wq7FaBQ+yXRvQAYPrHwya1/UFt9g==", "dev": true }, "@types/glob": { "version": "7.1.1", "resolved": "https://registry.npmjs.org/@types/glob/-/glob-7.1.1.tgz", "integrity": "sha512-1Bh06cbWJUHMC97acuD6UMG29nMt0Aqz1vF3guLfG+kHHJhy3AyohZFFxYk2f7Q1SQIrNwvncxAE0N/9s70F2w==", "dev": true, "requires": { "@types/events": "*", "@types/minimatch": "*", "@types/node": "*" } }, "@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": "13.9.2", "resolved": "https://registry.npmjs.org/@types/node/-/node-13.9.2.tgz", "integrity": "sha512-bnoqK579sAYrQbp73wwglccjJ4sfRdKU7WNEZ5FW4K2U6Kc0/eZ5kvXG0JKsEKFB50zrFmfFt52/cvBbZa7eXg==", "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 }, "@types/parsimmon": { "version": "1.10.1", "resolved": "https://registry.npmjs.org/@types/parsimmon/-/parsimmon-1.10.1.tgz", "integrity": "sha512-MoF2IC9oGSgArJwlxdst4XsvWuoYfNUWtBw0kpnCi6K05kV+Ecl7siEeJ40tgCbI9uqEMGQL/NlPMRv6KVkY5Q==", "dev": true }, "JSONSelect": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/JSONSelect/-/JSONSelect-0.4.0.tgz", "integrity": "sha1-oI7cxn6z/L6Z7WMIVTRKDPKCu40=", "dev": true }, "abbrev": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==", "dev": true }, "accepts": { "version": "1.3.7", "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.7.tgz", "integrity": "sha512-Il80Qs2WjYlJIBNzNkK6KYqlVMTbZLXgHx2oT0pU/fjRHyEp+PEfEPY0R3WCwAGVOtauxh1hOxNgIf5bv7dQpA==", "dev": true, "requires": { "mime-types": "~2.1.24", "negotiator": "0.6.2" } }, "acorn": { "version": "5.7.4", "resolved": "https://registry.npmjs.org/acorn/-/acorn-5.7.4.tgz", "integrity": "sha512-1D++VG7BhrtvQpNbBzovKNc1FLGGEE/oGe7b9xJm/RFHMBeUaUGpluV9RLjZa47YFdPcDAenEYuq9pQPcMdLJg==", "dev": true }, "acorn-jsx": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.2.0.tgz", "integrity": "sha512-HiUX/+K2YpkpJ+SzBffkM/AQ2YE03S0U1kjTLVpoJdhZMOWy8qvXVN9JdLqv2QsaQ6MPYQIuNmwD8zOiYUofLQ==", "dev": true }, "agent-base": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-4.3.0.tgz", "integrity": "sha512-salcGninV0nPrwpGNn4VTXBb1SOuXQBiqbrNXoeizJsHrsL6ERFM2Ne3JUSBWRE6aeNJI2ROP/WEEIDUiDe3cg==", "dev": true, "requires": { "es6-promisify": "^5.0.0" } }, "aggregate-error": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.0.1.tgz", "integrity": "sha512-quoaXsZ9/BLNae5yiNoUz+Nhkwz83GhWwtYFglcjEQB2NDHCIpApbqXxIFnm4Pq/Nvhrsq5sYJFyohrrxnTGAA==", "dev": true, "requires": { "clean-stack": "^2.0.0", "indent-string": "^4.0.0" }, "dependencies": { "indent-string": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==", "dev": true } } }, "ajv": { "version": "6.12.0", "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.0.tgz", "integrity": "sha512-D6gFiFA0RRLyUbvijN74DWAjXSFxWKaWP7mldxkVhyhAV3+SWA9HEJPHQ2c9soIeTFJqcSdFDGFgdqs1iUU2Hw==", "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" } }, "align-text": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/align-text/-/align-text-0.1.4.tgz", "integrity": "sha1-DNkKVhCT810KmSVsIrcGlDP60Rc=", "dev": true, "requires": { "kind-of": "^3.0.2", "longest": "^1.0.1", "repeat-string": "^1.5.2" } }, "alter": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/alter/-/alter-0.2.0.tgz", "integrity": "sha1-x1iICGF1cgNKrmJICvJrHU0cs80=", "dev": true, "requires": { "stable": "~0.1.3" } }, "amdefine": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/amdefine/-/amdefine-1.0.1.tgz", "integrity": "sha1-SlKCrBZHKek2Gbz9OtFR+BfOkfU=", "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.0", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==", "dev": true }, "ansi-styles": { "version": "4.2.1", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz", "integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==", "dev": true, "requires": { "@types/color-name": "^1.1.1", "color-convert": "^2.0.1" } }, "any-observable": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/any-observable/-/any-observable-0.3.0.tgz", "integrity": "sha512-/FQM1EDkTsf63Ub2C6O7GuYFDsSXUwsaZDurV0np41ocwq0jthUAYCmhBX9f+KwlaCgIuWyr/4WlUQUBfKfZog==", "dev": true }, "anymatch": { "version": "1.3.2", "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-1.3.2.tgz", "integrity": "sha512-0XNayC8lTHQ2OI8aljNCN3sSx6hsr/1+rlcDAotXJR7C1oZZHCNsfpbKwMjRA3Uqb5tF1Rae2oloTr4xpq+WjA==", "dev": true, "requires": { "micromatch": "^2.1.5", "normalize-path": "^2.0.0" } }, "append-transform": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/append-transform/-/append-transform-1.0.0.tgz", "integrity": "sha512-P009oYkeHyU742iSZJzZZywj4QRJdnTWffaKuJQLablCZ1uz6/cW4yaRgcDaoQ+uwOxxnt0gRUcwfsNP2ri0gw==", "dev": true, "requires": { "default-require-extensions": "^2.0.0" } }, "archy": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/archy/-/archy-1.0.0.tgz", "integrity": "sha1-+cjBN1fMHde8N5rHeyxipcKGjEA=", "dev": true }, "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": "2.0.0", "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-2.0.0.tgz", "integrity": "sha1-jzuCf5Vai9ZpaX5KQlasPOrjVs8=", "dev": true, "requires": { "arr-flatten": "^1.0.1" } }, "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-each": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/array-each/-/array-each-1.0.1.tgz", "integrity": "sha1-p5SvDAWrF1KEbudTofIRoFugxE8=", "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-flatten": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", "integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI=", "dev": true }, "array-from": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/array-from/-/array-from-2.1.1.tgz", "integrity": "sha1-z+nYwmYoudxa7MYqn12PHzUsEZU=", "dev": true }, "array-slice": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/array-slice/-/array-slice-1.1.0.tgz", "integrity": "sha512-B1qMD3RBP7O8o0H2KbrXDyB0IccejMF15+87Lvlor12ONPRHP6gTjXMNkt/d3ZuOGbAe66hFmaCfECI24Ufp6w==", "dev": true }, "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 }, "array-unique": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.2.1.tgz", "integrity": "sha1-odl8yvy8JiXMcPrc6zalDFiwGlM=", "dev": true }, "asn1": { "version": "0.2.4", "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz", "integrity": "sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg==", "dev": true, "requires": { "safer-buffer": "~2.1.0" } }, "assert": { "version": "1.5.0", "resolved": "https://registry.npmjs.org/assert/-/assert-1.5.0.tgz", "integrity": "sha512-EDsgawzwoun2CZkCgtxJbv392v4nbk9XDD06zI+kQYoBM/3RBWLlEyJARDOmhAAosBjWACEkKL6S+lIZtcAubA==", "dev": true, "requires": { "object-assign": "^4.1.1", "util": "0.10.3" }, "dependencies": { "inherits": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz", "integrity": "sha1-sX0I0ya0Qj5Wjv9xn5GwscvfafE=", "dev": true }, "object-assign": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", "dev": true }, "util": { "version": "0.10.3", "resolved": "https://registry.npmjs.org/util/-/util-0.10.3.tgz", "integrity": "sha1-evsa/lCAUkZInj23/g7TeTNqwPk=", "dev": true, "requires": { "inherits": "2.0.1" } } } }, "assert-plus": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=", "dev": true }, "assertion-error": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.1.0.tgz", "integrity": "sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==", "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 }, "ast-metadata-inferer": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/ast-metadata-inferer/-/ast-metadata-inferer-0.1.1.tgz", "integrity": "sha512-hc9w8Qrgg9Lf9iFcZVhNjUnhrd2BBpTlyCnegPVvCe6O0yMrF57a6Cmh7k+xUsfUOMh9wajOL5AsGOBNEyTCcw==", "dev": true }, "ast-traverse": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/ast-traverse/-/ast-traverse-0.1.1.tgz", "integrity": "sha1-ac8rg4bxnc2hux4F1o/jWdiJfeY=", "dev": true }, "ast-types": { "version": "0.9.6", "resolved": "https://registry.npmjs.org/ast-types/-/ast-types-0.9.6.tgz", "integrity": "sha1-ECyenpAF0+fjgpvwxPok7oYu6bk=", "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 }, "async": { "version": "1.5.2", "resolved": "https://registry.npmjs.org/async/-/async-1.5.2.tgz", "integrity": "sha1-7GphrlZIDAw8skHJVhjiCJL5Zyo=", "dev": true }, "async-each": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/async-each/-/async-each-1.0.3.tgz", "integrity": "sha512-z/WhQ5FPySLdvREByI2vZiTWwCnF0moMJ1hK9YQwDTHKh6I7/uSckMetoRGb5UBZPC1z0jlw+n/XCgjeH7y1AQ==", "dev": true }, "asynckit": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=", "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 }, "aws-sdk": { "version": "2.642.0", "resolved": "https://registry.npmjs.org/aws-sdk/-/aws-sdk-2.642.0.tgz", "integrity": "sha512-0ZNgL1HBXRVobFD9Z64RyQk50cNABDMU1GV4lYIAvao4urYqYJi2MEVQmq+7WyXyzkBWu3lAPNDiJ8WW7emTzg==", "dev": true, "requires": { "buffer": "4.9.1", "events": "1.1.1", "ieee754": "1.1.13", "jmespath": "0.15.0", "querystring": "0.2.0", "sax": "1.2.1", "url": "0.10.3", "uuid": "3.3.2", "xml2js": "0.4.19" }, "dependencies": { "uuid": { "version": "3.3.2", "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.2.tgz", "integrity": "sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA==", "dev": true } } }, "aws-sign2": { "version": "0.7.0", "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=", "dev": true }, "aws4": { "version": "1.9.1", "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.9.1.tgz", "integrity": "sha512-wMHVg2EOHaMRxbzgFJ9gtjOOCrI80OHLG14rxi28XwOW8ux6IiEbRCGGGqCtdAIg4FQCbW20k9RsT4y3gJlFug==", "dev": true }, "babel-core": { "version": "5.8.38", "resolved": "https://registry.npmjs.org/babel-core/-/babel-core-5.8.38.tgz", "integrity": "sha1-H8ruedfmG3ULALjlT238nQr4ZVg=", "dev": true, "requires": { "babel-plugin-constant-folding": "^1.0.1", "babel-plugin-dead-code-elimination": "^1.0.2", "babel-plugin-eval": "^1.0.1", "babel-plugin-inline-environment-variables": "^1.0.1", "babel-plugin-jscript": "^1.0.4", "babel-plugin-member-expression-literals": "^1.0.1", "babel-plugin-property-literals": "^1.0.1", "babel-plugin-proto-to-assign": "^1.0.3", "babel-plugin-react-constant-elements": "^1.0.3", "babel-plugin-react-display-name": "^1.0.3", "babel-plugin-remove-console": "^1.0.1", "babel-plugin-remove-debugger": "^1.0.1", "babel-plugin-runtime": "^1.0.7", "babel-plugin-undeclared-variables-check": "^1.0.2", "babel-plugin-undefined-to-void": "^1.1.6", "babylon": "^5.8.38", "bluebird": "^2.9.33", "chalk": "^1.0.0", "convert-source-map": "^1.1.0", "core-js": "^1.0.0", "debug": "^2.1.1", "detect-indent": "^3.0.0", "esutils": "^2.0.0", "fs-readdir-recursive": "^0.1.0", "globals": "^6.4.0", "home-or-tmp": "^1.0.0", "is-integer": "^1.0.4", "js-tokens": "1.0.1", "json5": "^0.4.0", "lodash": "^3.10.0", "minimatch": "^2.0.3", "output-file-sync": "^1.1.0", "path-exists": "^1.0.0", "path-is-absolute": "^1.0.0", "private": "^0.1.6", "regenerator": "0.8.40", "regexpu": "^1.3.0", "repeating": "^1.1.2", "resolve": "^1.1.6", "shebang-regex": "^1.0.0", "slash": "^1.0.0", "source-map": "^0.5.0", "source-map-support": "^0.2.10", "to-fast-properties": "^1.0.0", "trim-right": "^1.0.0", "try-resolve": "^1.0.0" }, "dependencies": { "ansi-regex": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", "dev": true }, "ansi-styles": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", "dev": true }, "chalk": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", "dev": true, "requires": { "ansi-styles": "^2.2.1", "escape-string-regexp": "^1.0.2", "has-ansi": "^2.0.0", "strip-ansi": "^3.0.0", "supports-color": "^2.0.0" } }, "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" } }, "lodash": { "version": "3.10.1", "resolved": "https://registry.npmjs.org/lodash/-/lodash-3.10.1.tgz", "integrity": "sha1-W/Rejkm6QYnhfUgnid/RW9FAt7Y=", "dev": true }, "minimatch": { "version": "2.0.10", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-2.0.10.tgz", "integrity": "sha1-jQh8OcazjAAbl/ynzm0OHoCvusc=", "dev": true, "requires": { "brace-expansion": "^1.0.0" } }, "ms": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", "dev": true }, "path-exists": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-1.0.0.tgz", "integrity": "sha1-1aiZjrce83p0w06w2eum6HjuoIE=", "dev": true }, "source-map": { "version": "0.5.7", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", "dev": true }, "strip-ansi": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", "dev": true, "requires": { "ansi-regex": "^2.0.0" } }, "supports-color": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", "dev": true } } }, "babel-loader": { "version": "5.4.2", "resolved": "https://registry.npmjs.org/babel-loader/-/babel-loader-5.4.2.tgz", "integrity": "sha1-d/4o2OYNDwVrHBvKJbhJTNqrnHY=", "dev": true, "requires": { "babel-core": "^5.4.0", "loader-utils": "^0.2.9", "object-assign": "^3.0.0" } }, "babel-plugin-constant-folding": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/babel-plugin-constant-folding/-/babel-plugin-constant-folding-1.0.1.tgz", "integrity": "sha1-g2HTZMmORJw2kr26Ue/whEKQqo4=", "dev": true }, "babel-plugin-dead-code-elimination": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/babel-plugin-dead-code-elimination/-/babel-plugin-dead-code-elimination-1.0.2.tgz", "integrity": "sha1-X3xFEnTc18zNv7s+C4XdKBIfD2U=", "dev": true }, "babel-plugin-eval": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/babel-plugin-eval/-/babel-plugin-eval-1.0.1.tgz", "integrity": "sha1-ovrtJc5r5preS/7CY/cBaRlZUNo=", "dev": true }, "babel-plugin-inline-environment-variables": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/babel-plugin-inline-environment-variables/-/babel-plugin-inline-environment-variables-1.0.1.tgz", "integrity": "sha1-H1jOkSB61qgmqL9kX6/mj/X+P/4=", "dev": true }, "babel-plugin-jscript": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/babel-plugin-jscript/-/babel-plugin-jscript-1.0.4.tgz", "integrity": "sha1-jzQsOCduh6R9X6CovT1etsytj8w=", "dev": true }, "babel-plugin-member-expression-literals": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/babel-plugin-member-expression-literals/-/babel-plugin-member-expression-literals-1.0.1.tgz", "integrity": "sha1-zF7bD6qNyScXDnTW0cAkQAIWJNM=", "dev": true }, "babel-plugin-property-literals": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/babel-plugin-property-literals/-/babel-plugin-property-literals-1.0.1.tgz", "integrity": "sha1-AlIwGQAZKYCxwRjv6kjOk6q4MzY=", "dev": true }, "babel-plugin-proto-to-assign": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/babel-plugin-proto-to-assign/-/babel-plugin-proto-to-assign-1.0.4.tgz", "integrity": "sha1-xJ56/QL1d7xNoF6i3wAiUM980SM=", "dev": true, "requires": { "lodash": "^3.9.3" }, "dependencies": { "lodash": { "version": "3.10.1", "resolved": "https://registry.npmjs.org/lodash/-/lodash-3.10.1.tgz", "integrity": "sha1-W/Rejkm6QYnhfUgnid/RW9FAt7Y=", "dev": true } } }, "babel-plugin-react-constant-elements": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/babel-plugin-react-constant-elements/-/babel-plugin-react-constant-elements-1.0.3.tgz", "integrity": "sha1-lGc26DeEKcvDSdz/YvUcFDs041o=", "dev": true }, "babel-plugin-react-display-name": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/babel-plugin-react-display-name/-/babel-plugin-react-display-name-1.0.3.tgz", "integrity": "sha1-dU/jiSboQkpOexWrbqYTne4FFPw=", "dev": true }, "babel-plugin-remove-console": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/babel-plugin-remove-console/-/babel-plugin-remove-console-1.0.1.tgz", "integrity": "sha1-2PJFVsOgUAXUKqqv0neH9T/wE6c=", "dev": true }, "babel-plugin-remove-debugger": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/babel-plugin-remove-debugger/-/babel-plugin-remove-debugger-1.0.1.tgz", "integrity": "sha1-/S6jzWGkKK0fO5yJiC/0KT6MFMc=", "dev": true }, "babel-plugin-runtime": { "version": "1.0.7", "resolved": "https://registry.npmjs.org/babel-plugin-runtime/-/babel-plugin-runtime-1.0.7.tgz", "integrity": "sha1-v3x9lm3Vbs1cF/ocslPJrLflSq8=", "dev": true }, "babel-plugin-undeclared-variables-check": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/babel-plugin-undeclared-variables-check/-/babel-plugin-undeclared-variables-check-1.0.2.tgz", "integrity": "sha1-XPGqU52BP/ZOmWQSkK9iCWX2Xe4=", "dev": true, "requires": { "leven": "^1.0.2" } }, "babel-plugin-undefined-to-void": { "version": "1.1.6", "resolved": "https://registry.npmjs.org/babel-plugin-undefined-to-void/-/babel-plugin-undefined-to-void-1.1.6.tgz", "integrity": "sha1-f1eO+LeN+uYAM4XYQXph7aBuL4E=", "dev": true }, "babel-runtime": { "version": "5.8.38", "resolved": "https://registry.npmjs.org/babel-runtime/-/babel-runtime-5.8.38.tgz", "integrity": "sha1-HAsC62MxL18If/IEUIJ7QlydTBk=", "dev": true, "requires": { "core-js": "^1.0.0" } }, "babylon": { "version": "5.8.38", "resolved": "https://registry.npmjs.org/babylon/-/babylon-5.8.38.tgz", "integrity": "sha1-7JsSCxG/bM1Bc6GL8hfmC3mFn/0=", "dev": true }, "balanced-match": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", "dev": true }, "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" } }, "isobject": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", "dev": true }, "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 } } }, "base64-js": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.3.1.tgz", "integrity": "sha512-mLQ4i2QO1ytvGWFWmcngKO//JXAQueZvwEKtjgQFM4jIK0kU+ytMfplL8j+n5mspOfjHwoAg+9yhb7BwAHm36g==", "dev": true }, "basic-auth": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/basic-auth/-/basic-auth-2.0.1.tgz", "integrity": "sha512-NF+epuEdnUYVlGuhaxbbq+dvJttwLnGY+YixlXlME5KpQ5W3CnXA5cVTneY3SPbPDRkcjMbifrwmFYcClgOZeg==", "dev": true, "requires": { "safe-buffer": "5.1.2" }, "dependencies": { "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 } } }, "batch": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/batch/-/batch-0.6.1.tgz", "integrity": "sha1-3DQxT05nkxgJP8dgJyUl+UvyXBY=", "dev": true }, "bcrypt-pbkdf": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", "integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=", "dev": true, "requires": { "tweetnacl": "^0.14.3" } }, "benchmark": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/benchmark/-/benchmark-1.0.0.tgz", "integrity": "sha1-Lx4vpMNZ8REiqhgwgiGOlX45DHM=", "dev": true }, "big.js": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/big.js/-/big.js-3.2.0.tgz", "integrity": "sha512-+hN/Zh2D08Mx65pZ/4g5bsmNiZUuChDiQfTUQ7qJr4/kuopCr88xZsAXv6mBoZEsUI4OuGHlX59qE94K2mMW8Q==", "dev": true }, "binary-extensions": { "version": "1.13.1", "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.13.1.tgz", "integrity": "sha512-Un7MIEDdUC5gNpcGDV97op1Ywk748MpHcFTHoYs6qnj1Z3j7I53VG3nwZhKzoBZmbdRNnb6WRdFlwl7tSDuZGw==", "dev": true }, "bindings": { "version": "1.5.0", "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz", "integrity": "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==", "dev": true, "optional": true, "requires": { "file-uri-to-path": "1.0.0" } }, "bluebird": { "version": "2.11.0", "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-2.11.0.tgz", "integrity": "sha1-U0uQM8AiyVecVro7Plpcqvu2UOE=", "dev": true }, "body": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/body/-/body-5.1.0.tgz", "integrity": "sha1-5LoM5BCkaTYyM2dgnstOZVMSUGk=", "dev": true, "requires": { "continuable-cache": "^0.3.1", "error": "^7.0.0", "raw-body": "~1.1.0", "safe-json-parse": "~1.0.1" } }, "body-parser": { "version": "1.19.0", "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.19.0.tgz", "integrity": "sha512-dhEPs72UPbDnAQJ9ZKMNTP6ptJaionhP5cBb541nXPlW60Jepo9RV/a4fX4XWW9CuFNK22krhrj1+rgzifNCsw==", "dev": true, "requires": { "bytes": "3.1.0", "content-type": "~1.0.4", "debug": "2.6.9", "depd": "~1.1.2", "http-errors": "1.7.2", "iconv-lite": "0.4.24", "on-finished": "~2.3.0", "qs": "6.7.0", "raw-body": "2.4.0", "type-is": "~1.6.17" }, "dependencies": { "bytes": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.0.tgz", "integrity": "sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg==", "dev": true }, "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" } }, "http-errors": { "version": "1.7.2", "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.7.2.tgz", "integrity": "sha512-uUQBt3H/cSIVfch6i1EuPNy/YsRSOUBXTVfZ+yR7Zjez3qjBz6i9+i4zjNaoqcoFVI4lQJ5plg63TvGfRSDCRg==", "dev": true, "requires": { "depd": "~1.1.2", "inherits": "2.0.3", "setprototypeof": "1.1.1", "statuses": ">= 1.5.0 < 2", "toidentifier": "1.0.0" } }, "inherits": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", "dev": true }, "ms": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", "dev": true }, "qs": { "version": "6.7.0", "resolved": "https://registry.npmjs.org/qs/-/qs-6.7.0.tgz", "integrity": "sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ==", "dev": true }, "raw-body": { "version": "2.4.0", "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.4.0.tgz", "integrity": "sha512-4Oz8DUIwdvoa5qMJelxipzi/iJIi40O5cGV1wNYp5hvZP8ZN0T+jiNkL0QepXs+EsQ9XJ8ipEDoiH70ySUJP3Q==", "dev": true, "requires": { "bytes": "3.1.0", "http-errors": "1.7.2", "iconv-lite": "0.4.24", "unpipe": "1.0.0" } }, "setprototypeof": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.1.tgz", "integrity": "sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw==", "dev": true } } }, "brace-expansion": { "version": "1.1.11", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", "dev": true, "requires": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" } }, "braces": { "version": "1.8.5", "resolved": "https://registry.npmjs.org/braces/-/braces-1.8.5.tgz", "integrity": "sha1-uneWLhLf+WnWt2cR6RS3N4V79qc=", "dev": true, "requires": { "expand-range": "^1.8.1", "preserve": "^0.2.0", "repeat-element": "^1.1.2" } }, "breakable": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/breakable/-/breakable-1.0.0.tgz", "integrity": "sha1-eEp5eRWjjq0nutRWtVcstLuqeME=", "dev": true }, "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 }, "browserify-aes": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/browserify-aes/-/browserify-aes-0.4.0.tgz", "integrity": "sha1-BnFJtmjfMcS1hTPgLQHoBthgjiw=", "dev": true, "requires": { "inherits": "^2.0.1" } }, "browserify-zlib": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/browserify-zlib/-/browserify-zlib-0.1.4.tgz", "integrity": "sha1-uzX4pRn2AOD6a4SFJByXnQFB+y0=", "dev": true, "requires": { "pako": "~0.2.0" } }, "browserslist": { "version": "4.9.1", "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.9.1.tgz", "integrity": "sha512-Q0DnKq20End3raFulq6Vfp1ecB9fh8yUNV55s8sekaDDeqBaCtWlRHCUdaWyUeSSBJM7IbM6HcsyaeYqgeDhnw==", "dev": true, "requires": { "caniuse-lite": "^1.0.30001030", "electron-to-chromium": "^1.3.363", "node-releases": "^1.1.50" } }, "buffer": { "version": "4.9.1", "resolved": "https://registry.npmjs.org/buffer/-/buffer-4.9.1.tgz", "integrity": "sha1-bRu2AbB6TvztlwlBMgkwJ8lbwpg=", "dev": true, "requires": { "base64-js": "^1.0.2", "ieee754": "^1.1.4", "isarray": "^1.0.0" } }, "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 }, "builtin-modules": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-1.1.1.tgz", "integrity": "sha1-Jw8HbFpywC9bZaR9+Uxf46J4iS8=", "dev": true }, "builtin-status-codes": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/builtin-status-codes/-/builtin-status-codes-3.0.0.tgz", "integrity": "sha1-hZgoeOIbmOHGZCXgPQF0eI9Wnug=", "dev": true }, "bytes": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/bytes/-/bytes-1.0.0.tgz", "integrity": "sha1-NWnt6Lo0MV+rmcPpLLBMciDeH6g=", "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" }, "dependencies": { "isobject": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", "dev": true } } }, "caching-transform": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/caching-transform/-/caching-transform-3.0.2.tgz", "integrity": "sha512-Mtgcv3lh3U0zRii/6qVgQODdPA4G3zhG+jtbCWj39RXuUFTMzH0vcdMtaJS1jPowd+It2Pqr6y3NJMQqOqCE2w==", "dev": true, "requires": { "hasha": "^3.0.0", "make-dir": "^2.0.0", "package-hash": "^3.0.0", "write-file-atomic": "^2.4.2" } }, "caller-callsite": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/caller-callsite/-/caller-callsite-2.0.0.tgz", "integrity": "sha1-hH4PzgoiN1CpoCfFSzNzGtMVQTQ=", "dev": true, "requires": { "callsites": "^2.0.0" }, "dependencies": { "callsites": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/callsites/-/callsites-2.0.0.tgz", "integrity": "sha1-BuuE8A7qQT2oav/vrL/7Ngk7PFA=", "dev": true } } }, "caller-path": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/caller-path/-/caller-path-2.0.0.tgz", "integrity": "sha1-Ro+DBE42mrIBD6xfBs7uFbsssfQ=", "dev": true, "requires": { "caller-callsite": "^2.0.0" } }, "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": "2.1.0", "resolved": "https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-2.1.0.tgz", "integrity": "sha1-MIvur/3ygRkFHvodkyITyRuPkuc=", "dev": true, "requires": { "camelcase": "^2.0.0", "map-obj": "^1.0.0" }, "dependencies": { "camelcase": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-2.1.1.tgz", "integrity": "sha1-fB0W1nmhu+WcoCys7PsBHiAfWh8=", "dev": true } } }, "caniuse-db": { "version": "1.0.30001035", "resolved": "https://registry.npmjs.org/caniuse-db/-/caniuse-db-1.0.30001035.tgz", "integrity": "sha512-kLUON4XN3tq5Nwl7ZICDw+7/vMynSpRMVYDRkzLL31lgnpa6M2YXYdjst3h+xbzjMgdcveRTnRGE1h/1IcKK6A==", "dev": true }, "caniuse-lite": { "version": "1.0.30001035", "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001035.tgz", "integrity": "sha512-C1ZxgkuA4/bUEdMbU5WrGY4+UhMFFiXrgNAfxiMIqWgFTWfv/xsZCS2xEHT2LMq7xAZfuAnu6mcqyDl0ZR6wLQ==", "dev": true }, "caseless": { "version": "0.12.0", "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=", "dev": true }, "center-align": { "version": "0.1.3", "resolved": "https://registry.npmjs.org/center-align/-/center-align-0.1.3.tgz", "integrity": "sha1-qg0yYptu6XIgBBHL1EYckHvCt60=", "dev": true, "requires": { "align-text": "^0.1.3", "lazy-cache": "^1.0.3" } }, "chai": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/chai/-/chai-4.2.0.tgz", "integrity": "sha512-XQU3bhBukrOsQCuwZndwGcCVQHyZi53fQ6Ys1Fym7E4olpIqqZZhhoFJoaKVvV17lWQoXYwgWN2nF5crA8J2jw==", "dev": true, "requires": { "assertion-error": "^1.1.0", "check-error": "^1.0.2", "deep-eql": "^3.0.1", "get-func-name": "^2.0.0", "pathval": "^1.1.0", "type-detect": "^4.0.5" } }, "chai-diff": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/chai-diff/-/chai-diff-1.0.1.tgz", "integrity": "sha1-bGaJRwDYDNkDUKtORANiXU9TocE=", "dev": true, "requires": { "diff": "^2.2.1" } }, "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" }, "dependencies": { "ansi-styles": { "version": "3.2.1", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", "dev": true, "requires": { "color-convert": "^1.9.0" } }, "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 } } }, "chardet": { "version": "0.7.0", "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.7.0.tgz", "integrity": "sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==", "dev": true }, "check-error": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.2.tgz", "integrity": "sha1-V00xLt2Iu13YkS6Sht1sCu1KrII=", "dev": true }, "chokidar": { "version": "1.5.2", "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-1.5.2.tgz", "integrity": "sha1-KT5yhkDMk92Cd0JDNLPG1K06NIo=", "dev": true, "requires": { "anymatch": "^1.3.0", "async-each": "^1.0.0", "fsevents": "^1.0.0", "glob-parent": "^2.0.0", "inherits": "^2.0.1", "is-binary-path": "^1.0.0", "is-glob": "^2.0.0", "path-is-absolute": "^1.0.0", "readdirp": "^2.0.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" } }, "isobject": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", "dev": true } } }, "clean-stack": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz", "integrity": "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==", "dev": true }, "cli": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/cli/-/cli-1.0.1.tgz", "integrity": "sha1-IoF1NPJL+klQw01TLUjsvGIbjBQ=", "dev": true, "requires": { "exit": "0.1.2", "glob": "^7.1.1" }, "dependencies": { "glob": { "version": "7.1.6", "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", "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" } }, "minimatch": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", "dev": true, "requires": { "brace-expansion": "^1.1.7" } } } }, "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-truncate": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/cli-truncate/-/cli-truncate-0.2.1.tgz", "integrity": "sha1-nxXPuwcFAFNpIWxiasfQWrkN1XQ=", "dev": true, "requires": { "slice-ansi": "0.0.4", "string-width": "^1.0.1" }, "dependencies": { "ansi-regex": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", "dev": true }, "is-fullwidth-code-point": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", "dev": true, "requires": { "number-is-nan": "^1.0.0" } }, "slice-ansi": { "version": "0.0.4", "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-0.0.4.tgz", "integrity": "sha1-7b+JA/ZvfOL46v1s7tZeJkyDGzU=", "dev": true }, "string-width": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", "dev": true, "requires": { "code-point-at": "^1.0.0", "is-fullwidth-code-point": "^1.0.0", "strip-ansi": "^3.0.0" } }, "strip-ansi": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", "dev": true, "requires": { "ansi-regex": "^2.0.0" } } } }, "cli-width": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-2.2.0.tgz", "integrity": "sha1-/xnt6Kml5XkyQUewwR8PvLq+1jk=", "dev": true }, "clone": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/clone/-/clone-1.0.4.tgz", "integrity": "sha1-2jCcwmPfFZlMaIypAheco8fNfH4=", "dev": true }, "code-point-at": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz", "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=", "dev": true }, "coffee-script": { "version": "1.12.7", "resolved": "https://registry.npmjs.org/coffee-script/-/coffee-script-1.12.7.tgz", "integrity": "sha512-fLeEhqwymYat/MpTPUjSKHVYYl0ec2mOyALEMLmzr5i1isuG+6jfI2j2d5oBO3VIzgUXgBVIcOT9uH1TFxBckw==", "dev": true }, "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": "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 }, "colors": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/colors/-/colors-1.1.2.tgz", "integrity": "sha1-FopHAXVran9RoSzgyXv6KMCE7WM=", "dev": true }, "combined-stream": { "version": "1.0.8", "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", "dev": true, "requires": { "delayed-stream": "~1.0.0" } }, "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==" }, "commondir": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", "integrity": "sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs=", "dev": true }, "commoner": { "version": "0.10.8", "resolved": "https://registry.npmjs.org/commoner/-/commoner-0.10.8.tgz", "integrity": "sha1-NPw2cs0kOT6LtH5wyqApOBH08sU=", "dev": true, "requires": { "commander": "^2.5.0", "detective": "^4.3.1", "glob": "^5.0.15", "graceful-fs": "^4.1.2", "iconv-lite": "^0.4.5", "mkdirp": "^0.5.0", "private": "^0.1.6", "q": "^1.1.2", "recast": "^0.11.17" }, "dependencies": { "esprima": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/esprima/-/esprima-3.1.3.tgz", "integrity": "sha1-/cpRzuYTOJXjyI1TXOSdv/YqRjM=", "dev": true }, "recast": { "version": "0.11.23", "resolved": "https://registry.npmjs.org/recast/-/recast-0.11.23.tgz", "integrity": "sha1-RR/TAEqx5N+bTktmN2sqIZEkYtM=", "dev": true, "requires": { "ast-types": "0.9.6", "esprima": "~3.1.0", "private": "~0.1.5", "source-map": "~0.5.0" } }, "source-map": { "version": "0.5.7", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", "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 }, "compressible": { "version": "2.0.18", "resolved": "https://registry.npmjs.org/compressible/-/compressible-2.0.18.tgz", "integrity": "sha512-AF3r7P5dWxL8MxyITRMlORQNaOA2IkAFaTr4k7BUumjPtRpGDTZpl0Pb1XCO6JeDCBdp126Cgs9sMxqSjgYyRg==", "dev": true, "requires": { "mime-db": ">= 1.43.0 < 2" } }, "compression": { "version": "1.7.4", "resolved": "https://registry.npmjs.org/compression/-/compression-1.7.4.tgz", "integrity": "sha512-jaSIDzP9pZVS4ZfQ+TzvtiWhdpFhE2RDHz8QJkpX9SIpLq88VueF5jJw6t+6CUQcAoA6t+x89MLrWAqpfDE8iQ==", "dev": true, "requires": { "accepts": "~1.3.5", "bytes": "3.0.0", "compressible": "~2.0.16", "debug": "2.6.9", "on-headers": "~1.0.2", "safe-buffer": "5.1.2", "vary": "~1.1.2" }, "dependencies": { "bytes": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz", "integrity": "sha1-0ygVQE1olpn4Wk6k+odV3ROpYEg=", "dev": true }, "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 }, "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 } } }, "concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", "dev": true }, "concat-stream": { "version": "1.6.2", "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz", "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==", "dev": true, "requires": { "buffer-from": "^1.0.0", "inherits": "^2.0.3", "readable-stream": "^2.2.2", "typedarray": "^0.0.6" } }, "concurrently": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/concurrently/-/concurrently-5.1.0.tgz", "integrity": "sha512-9ViZMu3OOCID3rBgU31mjBftro2chOop0G2u1olq1OuwRBVRw/GxHTg80TVJBUTJfoswMmEUeuOg1g1yu1X2dA==", "dev": true, "requires": { "chalk": "^2.4.2", "date-fns": "^2.0.1", "lodash": "^4.17.15", "read-pkg": "^4.0.1", "rxjs": "^6.5.2", "spawn-command": "^0.0.2-1", "supports-color": "^6.1.0", "tree-kill": "^1.2.2", "yargs": "^13.3.0" }, "dependencies": { "ansi-regex": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", "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" } }, "cliui": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz", "integrity": "sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==", "dev": true, "requires": { "string-width": "^3.1.0", "strip-ansi": "^5.2.0", "wrap-ansi": "^5.1.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 }, "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 }, "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" } }, "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 }, "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" } }, "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" } }, "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 }, "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" } }, "supports-color": { "version": "6.1.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz", "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==", "dev": true, "requires": { "has-flag": "^3.0.0" } }, "wrap-ansi": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-5.1.0.tgz", "integrity": "sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q==", "dev": true, "requires": { "ansi-styles": "^3.2.0", "string-width": "^3.0.0", "strip-ansi": "^5.0.0" } }, "yargs": { "version": "13.3.2", "resolved": "https://registry.npmjs.org/yargs/-/yargs-13.3.2.tgz", "integrity": "sha512-AX3Zw5iPruN5ie6xGRIDgqkT+ZhnRlZMLMHAs8tg7nRruy2Nb+i5o9bwghAogtM08q1dpr2LVoS8KSTMYpWXUw==", "dev": true, "requires": { "cliui": "^5.0.0", "find-up": "^3.0.0", "get-caller-file": "^2.0.1", "require-directory": "^2.1.1", "require-main-filename": "^2.0.0", "set-blocking": "^2.0.0", "string-width": "^3.0.0", "which-module": "^2.0.0", "y18n": "^4.0.0", "yargs-parser": "^13.1.2" } }, "yargs-parser": { "version": "13.1.2", "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.1.2.tgz", "integrity": "sha512-3lbsNRf/j+A4QuSZfDRA7HRSfWrzO0YjqTJd5kjAq37Zep1CEgaYmrH9Q3GwPiB9cHyd1Y1UwggGhJGoxipbzg==", "dev": true, "requires": { "camelcase": "^5.0.0", "decamelize": "^1.2.0" } } } }, "connect": { "version": "3.7.0", "resolved": "https://registry.npmjs.org/connect/-/connect-3.7.0.tgz", "integrity": "sha512-ZqRXc+tZukToSNmh5C2iWMSoV3X1YUcPbqEM4DkEG5tNQXrQUZCNVGGv3IuicnkMtPfGf3Xtp8WCXs295iQ1pQ==", "dev": true, "requires": { "debug": "2.6.9", "finalhandler": "1.1.2", "parseurl": "~1.3.3", "utils-merge": "1.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" } }, "ms": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", "dev": true } } }, "connect-history-api-fallback": { "version": "1.6.0", "resolved": "https://registry.npmjs.org/connect-history-api-fallback/-/connect-history-api-fallback-1.6.0.tgz", "integrity": "sha512-e54B99q/OUoH64zYYRf3HBP5z24G38h5D3qXu23JGRoigpX5Ss4r9ZnDk3g0Z8uQC2x2lPaJ+UlWBc1ZWBWdLg==", "dev": true }, "connect-livereload": { "version": "0.5.4", "resolved": "https://registry.npmjs.org/connect-livereload/-/connect-livereload-0.5.4.tgz", "integrity": "sha1-gBV9E3HJ83zBQDmrGJWXDRGdw7w=", "dev": true }, "console-browserify": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/console-browserify/-/console-browserify-1.2.0.tgz", "integrity": "sha512-ZMkYO/LkF17QvCPqM0gxw8yUzigAOZOSWSHg91FH6orS7vcEj5dVZTidN2fQ14yBSdg97RqhSNwLUXInd52OTA==", "dev": true }, "constants-browserify": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/constants-browserify/-/constants-browserify-1.0.0.tgz", "integrity": "sha1-wguW2MYXdIqvHBYCF2DNJ/y4y3U=", "dev": true }, "content-disposition": { "version": "0.5.3", "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.3.tgz", "integrity": "sha512-ExO0774ikEObIAEV9kDo50o+79VCUdEB6n6lzKgGwupcVeRlhrj3qGAfwq8G6uBJjkqLrhT0qEYFcWng8z1z0g==", "dev": true, "requires": { "safe-buffer": "5.1.2" }, "dependencies": { "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 } } }, "content-type": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz", "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==", "dev": true }, "continuable-cache": { "version": "0.3.1", "resolved": "https://registry.npmjs.org/continuable-cache/-/continuable-cache-0.3.1.tgz", "integrity": "sha1-vXJ6f67XfnH/OYWskzUakSczrQ8=", "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" }, "dependencies": { "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 } } }, "cookie": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.0.tgz", "integrity": "sha512-+Hp8fLp57wnUSt0tY0tHEXh4voZRDnoIrZPqlo3DPiI4y9lwg/jqx+1Om94/W6ZaPDOUbnjOt/99w66zk+l1Xg==", "dev": true }, "cookie-signature": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", "integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw=", "dev": true }, "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-js": { "version": "1.2.7", "resolved": "https://registry.npmjs.org/core-js/-/core-js-1.2.7.tgz", "integrity": "sha1-ZSKUwUZR2yj6k70tX/KYOk8IxjY=", "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 }, "cosmiconfig": { "version": "5.2.1", "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-5.2.1.tgz", "integrity": "sha512-H65gsXo1SKjf8zmrJ67eJk8aIRKV5ff2D4uKZIBZShbhGSpEmsQOPW/SKMKYhSTrqR7ufy6RP69rPogdaPh/kA==", "dev": true, "requires": { "import-fresh": "^2.0.0", "is-directory": "^0.3.1", "js-yaml": "^3.13.1", "parse-json": "^4.0.0" }, "dependencies": { "import-fresh": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-2.0.0.tgz", "integrity": "sha1-2BNVwVYS04bGH53dOSLUMEgipUY=", "dev": true, "requires": { "caller-path": "^2.0.0", "resolve-from": "^3.0.0" } }, "resolve-from": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-3.0.0.tgz", "integrity": "sha1-six699nWiBvItuZTM17rywoYh0g=", "dev": true } } }, "cp-file": { "version": "6.2.0", "resolved": "https://registry.npmjs.org/cp-file/-/cp-file-6.2.0.tgz", "integrity": "sha512-fmvV4caBnofhPe8kOcitBwSn2f39QLjnAnGq3gO9dfd75mUytzKNZB1hde6QHunW2Rt+OwuBOMc3i1tNElbszA==", "dev": true, "requires": { "graceful-fs": "^4.1.2", "make-dir": "^2.0.0", "nested-error-stacks": "^2.0.0", "pify": "^4.0.1", "safe-buffer": "^5.0.1" }, "dependencies": { "pify": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", "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-browserify": { "version": "3.3.0", "resolved": "https://registry.npmjs.org/crypto-browserify/-/crypto-browserify-3.3.0.tgz", "integrity": "sha1-ufx1u0oO1h3PHNXa6W6zDJw+UGw=", "dev": true, "requires": { "browserify-aes": "0.4.0", "pbkdf2-compat": "2.0.1", "ripemd160": "0.2.0", "sha.js": "2.2.6" } }, "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" } }, "dashdash": { "version": "1.14.1", "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=", "dev": true, "requires": { "assert-plus": "^1.0.0" } }, "date-fns": { "version": "2.11.0", "resolved": "https://registry.npmjs.org/date-fns/-/date-fns-2.11.0.tgz", "integrity": "sha512-8P1cDi8ebZyDxUyUprBXwidoEtiQAawYPGvpfb+Dg0G6JrQ+VozwOmm91xYC0vAv1+0VmLehEPb+isg4BGUFfA==", "dev": true }, "dateformat": { "version": "1.0.12", "resolved": "https://registry.npmjs.org/dateformat/-/dateformat-1.0.12.tgz", "integrity": "sha1-nxJLZ1lMk3/3BpMuSmQsyo27/uk=", "dev": true, "requires": { "get-stdin": "^4.0.1", "meow": "^3.3.0" } }, "debug": { "version": "3.2.6", "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", "dev": true, "requires": { "ms": "^2.1.1" } }, "decamelize": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=", "dev": true }, "decode-uri-component": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.0.tgz", "integrity": "sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU=", "dev": true }, "dedent": { "version": "0.7.0", "resolved": "https://registry.npmjs.org/dedent/-/dedent-0.7.0.tgz", "integrity": "sha1-JJXduvbrh0q7Dhvp3yLS5aVEMmw=", "dev": true }, "deep-eql": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-3.0.1.tgz", "integrity": "sha512-+QeIQyN5ZuO+3Uk5DYh6/1eKO0m0YmJFGNmFHGACpf1ClL1nmlV/p4gNgbl2pJGxgXb4faqo6UE+M5ACEMyVcw==", "dev": true, "requires": { "type-detect": "^4.0.0" } }, "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 }, "default-require-extensions": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/default-require-extensions/-/default-require-extensions-2.0.0.tgz", "integrity": "sha1-9fj7sYp9bVCyH2QfZJ67Uiz+JPc=", "dev": true, "requires": { "strip-bom": "^3.0.0" }, "dependencies": { "strip-bom": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", "dev": true } } }, "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" } }, "isobject": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", "dev": true }, "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 } } }, "defined": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/defined/-/defined-1.0.0.tgz", "integrity": "sha1-yY2bzvdWdBiOEQlpFRGZ45sfppM=", "dev": true }, "definitelytyped-header-parser": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/definitelytyped-header-parser/-/definitelytyped-header-parser-1.2.0.tgz", "integrity": "sha512-xpg8uu/2YD/reaVsZV4oJ4g7UDYFqQGWvT1W9Tsj6q4VtWBSaig38Qgah0ZMnQGF9kAsAim08EXDO1nSi0+Nog==", "dev": true, "requires": { "@types/parsimmon": "^1.3.0", "parsimmon": "^1.2.0" } }, "defs": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/defs/-/defs-1.1.1.tgz", "integrity": "sha1-siYJ8sehG6ej2xFoBcE5scr/qdI=", "dev": true, "requires": { "alter": "~0.2.0", "ast-traverse": "~0.1.1", "breakable": "~1.0.0", "esprima-fb": "~15001.1001.0-dev-harmony-fb", "simple-fmt": "~0.1.0", "simple-is": "~0.2.0", "stringmap": "~0.2.2", "stringset": "~0.2.1", "tryor": "~0.1.2", "yargs": "~3.27.0" }, "dependencies": { "camelcase": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-1.2.1.tgz", "integrity": "sha1-m7UwTS4LVmmLLHWLCKPqqdqlijk=", "dev": true }, "cliui": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/cliui/-/cliui-2.1.0.tgz", "integrity": "sha1-S0dXYP+AJkx2LDoXGQMukcf+oNE=", "dev": true, "requires": { "center-align": "^0.1.1", "right-align": "^0.1.1", "wordwrap": "0.0.2" }, "dependencies": { "wordwrap": { "version": "0.0.2", "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.2.tgz", "integrity": "sha1-t5Zpu0LstAn4PVg8rVLKF+qhZD8=", "dev": true } } }, "y18n": { "version": "3.2.1", "resolved": "https://registry.npmjs.org/y18n/-/y18n-3.2.1.tgz", "integrity": "sha1-bRX7qITAhnnA136I53WegR4H+kE=", "dev": true }, "yargs": { "version": "3.27.0", "resolved": "https://registry.npmjs.org/yargs/-/yargs-3.27.0.tgz", "integrity": "sha1-ISBUaTFuk5Ex1Z8toMbX+YIh6kA=", "dev": true, "requires": { "camelcase": "^1.2.1", "cliui": "^2.1.0", "decamelize": "^1.0.0", "os-locale": "^1.4.0", "window-size": "^0.1.2", "y18n": "^3.2.0" } } } }, "del": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/del/-/del-5.1.0.tgz", "integrity": "sha512-wH9xOVHnczo9jN2IW68BabcecVPxacIA3g/7z6vhSU/4stOKQzeCRK0yD0A24WiAAUJmmVpWqrERcTxnLo3AnA==", "dev": true, "requires": { "globby": "^10.0.1", "graceful-fs": "^4.2.2", "is-glob": "^4.0.1", "is-path-cwd": "^2.2.0", "is-path-inside": "^3.0.1", "p-map": "^3.0.0", "rimraf": "^3.0.0", "slash": "^3.0.0" }, "dependencies": { "glob": { "version": "7.1.6", "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", "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" } }, "is-extglob": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", "dev": true }, "is-glob": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz", "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==", "dev": true, "requires": { "is-extglob": "^2.1.1" } }, "minimatch": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", "dev": true, "requires": { "brace-expansion": "^1.1.7" } }, "rimraf": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", "dev": true, "requires": { "glob": "^7.1.3" } }, "slash": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", "dev": true } } }, "delayed-stream": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=", "dev": true }, "depd": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=", "dev": true }, "destroy": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz", "integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA=", "dev": true }, "detect-file": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/detect-file/-/detect-file-1.0.0.tgz", "integrity": "sha1-8NZtA2cqglyxtzvbP+YjEMjlUrc=", "dev": true }, "detect-indent": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/detect-indent/-/detect-indent-3.0.1.tgz", "integrity": "sha1-ncXl3bzu+DJXZLlFGwK8bVQIT3U=", "dev": true, "requires": { "get-stdin": "^4.0.1", "minimist": "^1.1.0", "repeating": "^1.1.0" } }, "detective": { "version": "4.7.1", "resolved": "https://registry.npmjs.org/detective/-/detective-4.7.1.tgz", "integrity": "sha512-H6PmeeUcZloWtdt4DAkFyzFL94arpHr3NOwwmVILFiy+9Qd4JTxxXrzfyGk/lmct2qVGBwTSwSXagqu2BxmWig==", "dev": true, "requires": { "acorn": "^5.2.1", "defined": "^1.0.0" } }, "diff": { "version": "2.2.3", "resolved": "https://registry.npmjs.org/diff/-/diff-2.2.3.tgz", "integrity": "sha1-YOr9DSjukG5Oj/ClLBIpUhAzv5k=", "dev": true }, "dir-glob": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", "dev": true, "requires": { "path-type": "^4.0.0" }, "dependencies": { "path-type": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", "dev": true } } }, "dirty-chai": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/dirty-chai/-/dirty-chai-2.0.1.tgz", "integrity": "sha512-ys79pWKvDMowIDEPC6Fig8d5THiC0DJ2gmTeGzVAoEH18J8OzLud0Jh7I9IWg3NSk8x2UocznUuFmfHCXYZx9w==", "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" } }, "domain-browser": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/domain-browser/-/domain-browser-1.2.0.tgz", "integrity": "sha512-jnjyiM6eRyZl2H+W8Q/zLMA481hzi0eszAaBUzIVnmYVDBbnLxVNnfu1HgEBvCbL+71FrxMl3E6lpKH7Ge3OXA==", "dev": true }, "download-file-sync": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/download-file-sync/-/download-file-sync-1.0.4.tgz", "integrity": "sha1-0+PFQ/g29BA5RVuQNMcuNVsDYBk=", "dev": true }, "dts-critic": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/dts-critic/-/dts-critic-1.2.0.tgz", "integrity": "sha512-z6VI1Sz7xxy0BgN6YsWuG9hbRIfph3U9hwrfNHLnLzsq865VYyjo5xKKUgXPuqMgJ04BUF1LGYQJ+kWyWwvUvQ==", "dev": true, "requires": { "definitelytyped-header-parser": "^1.2.0", "download-file-sync": "^1.0.4", "yargs": "^12.0.5" }, "dependencies": { "ansi-regex": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", "dev": true }, "cliui": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/cliui/-/cliui-4.1.0.tgz", "integrity": "sha512-4FG+RSG9DL7uEwRUZXZn3SS34DiDPfzP0VOiEwtUWlE+AR2EIg+hSyvrIgUUfhdgR/UkAeW2QHgeP+hWrXs7jQ==", "dev": true, "requires": { "string-width": "^2.1.1", "strip-ansi": "^4.0.0", "wrap-ansi": "^2.0.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" } }, "get-caller-file": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-1.0.3.tgz", "integrity": "sha512-3t6rVToeoZfYSGd8YoLFR2DJkiQrIiUrGcjvFX2mDw3bn6k2OtwHN0TNCLbBO+w8qTvimhDkv+LSscbJY1vE6w==", "dev": true }, "invert-kv": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/invert-kv/-/invert-kv-2.0.0.tgz", "integrity": "sha512-wPVv/y/QQ/Uiirj/vh3oP+1Ww+AWehmi1g5fFWGPF6IpCBCDVrhgHRMvrLfdYcwDh3QJbGXDW4JAuzxElLSqKA==", "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 }, "lcid": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/lcid/-/lcid-2.0.0.tgz", "integrity": "sha512-avPEb8P8EGnwXKClwsNUgryVjllcRqtMYa49NTsbQagYuT1DcXnl1915oxWjoyGrXR6zH/Y0Zc96xWsPcoDKeA==", "dev": true, "requires": { "invert-kv": "^2.0.0" } }, "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" } }, "os-locale": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-3.1.0.tgz", "integrity": "sha512-Z8l3R4wYWM40/52Z+S265okfFj8Kt2cC2MKY+xNi3kFs+XGI7WXu/I309QQQYbRW4ijiZ+yxs9pqEhJh0DqW3Q==", "dev": true, "requires": { "execa": "^1.0.0", "lcid": "^2.0.0", "mem": "^4.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" } }, "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 }, "require-main-filename": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-1.0.1.tgz", "integrity": "sha1-l/cXtp1IeE9fUmpsWqj/3aBVpNE=", "dev": true }, "string-width": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", "dev": true, "requires": { "is-fullwidth-code-point": "^2.0.0", "strip-ansi": "^4.0.0" } }, "strip-ansi": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", "dev": true, "requires": { "ansi-regex": "^3.0.0" } }, "wrap-ansi": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-2.1.0.tgz", "integrity": "sha1-2Pw9KE3QV5T+hJc8rs3Rz4JP3YU=", "dev": true, "requires": { "string-width": "^1.0.1", "strip-ansi": "^3.0.1" }, "dependencies": { "ansi-regex": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", "dev": true }, "is-fullwidth-code-point": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", "dev": true, "requires": { "number-is-nan": "^1.0.0" } }, "string-width": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", "dev": true, "requires": { "code-point-at": "^1.0.0", "is-fullwidth-code-point": "^1.0.0", "strip-ansi": "^3.0.0" } }, "strip-ansi": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", "dev": true, "requires": { "ansi-regex": "^2.0.0" } } } }, "yargs": { "version": "12.0.5", "resolved": "https://registry.npmjs.org/yargs/-/yargs-12.0.5.tgz", "integrity": "sha512-Lhz8TLaYnxq/2ObqHDql8dX8CJi97oHxrjUcYtzKbbykPtVW9WB+poxI+NM2UIzsMgNCZTIf0AQwsjK5yMAqZw==", "dev": true, "requires": { "cliui": "^4.0.0", "decamelize": "^1.2.0", "find-up": "^3.0.0", "get-caller-file": "^1.0.1", "os-locale": "^3.0.0", "require-directory": "^2.1.1", "require-main-filename": "^1.0.1", "set-blocking": "^2.0.0", "string-width": "^2.0.0", "which-module": "^2.0.0", "y18n": "^3.2.1 || ^4.0.0", "yargs-parser": "^11.1.1" } }, "yargs-parser": { "version": "11.1.1", "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-11.1.1.tgz", "integrity": "sha512-C6kB/WJDiaxONLJQnF8ccx9SEeoTTLek8RVbaOIsrAUS8VrBEXfmeSnCZxygc+XC2sNMBIwOOnfcxiynjHsVSQ==", "dev": true, "requires": { "camelcase": "^5.0.0", "decamelize": "^1.2.0" } } } }, "dtslint": { "version": "0.5.9", "resolved": "https://registry.npmjs.org/dtslint/-/dtslint-0.5.9.tgz", "integrity": "sha512-/RU8h05QMS1DLZsMsDpJ6rvtEXrXQ0KRGT0q7IkqvDbCDa3fJRGLqGrVFLLaUTCl/4p2+sgsOEBCPsFqV5BRXA==", "dev": true, "requires": { "definitelytyped-header-parser": "^1.0.1", "dts-critic": "^1.0.4", "fs-extra": "^6.0.1", "request": "^2.88.0", "strip-json-comments": "^2.0.1", "tslint": "^5.14.0", "typescript": "^4.3.0-dev.20210213" }, "dependencies": { "fs-extra": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-6.0.1.tgz", "integrity": "sha512-GnyIkKhhzXZUWFCaJzvyDLEEgDkPfb4/TPvJCJVuS8MWZgoSsErf++QpiAlDnKFcqhRlm+tIOcencCjyJE6ZCA==", "dev": true, "requires": { "graceful-fs": "^4.1.2", "jsonfile": "^4.0.0", "universalify": "^0.1.0" } }, "typescript": { "version": "4.3.0-dev.20210213", "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.3.0-dev.20210213.tgz", "integrity": "sha512-zJG5QIkviTzzYRmKylVXIG2YTV7P18rKLclZu67WypYhsPtaC3KSDD5mOiXJsurDw5rqTqN/OgjQ37cpc11P3A==", "dev": true } } }, "dustjs-linkedin": { "version": "2.7.5", "resolved": "https://registry.npmjs.org/dustjs-linkedin/-/dustjs-linkedin-2.7.5.tgz", "integrity": "sha1-YY8GP3LBm3jIBVrCMBx1t7a73Mw=", "dev": true, "requires": { "chokidar": "~1.5.1", "cli": "^1.0.1" } }, "ecc-jsbn": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", "integrity": "sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=", "dev": true, "requires": { "jsbn": "~0.1.0", "safer-buffer": "^2.1.0" } }, "eco": { "version": "1.1.0-rc-3", "resolved": "https://registry.npmjs.org/eco/-/eco-1.1.0-rc-3.tgz", "integrity": "sha1-dCoyxGFa9wWrPppGts5cFtvFcmI=", "dev": true, "requires": { "coffee-script": ">=1.2.0", "strscan": ">=1.0.1" } }, "ee-first": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=", "dev": true }, "electron-to-chromium": { "version": "1.3.378", "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.378.tgz", "integrity": "sha512-nBp/AfhaVIOnfwgL1CZxt80IcqWcyYXiX6v5gflAksxy+SzBVz7A7UWR1Nos92c9ofXW74V9PoapzRb0jJfYXw==", "dev": true }, "elegant-spinner": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/elegant-spinner/-/elegant-spinner-1.0.1.tgz", "integrity": "sha1-2wQ1IcldfjA/2PNFvtwzSc+wcp4=", "dev": true }, "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 }, "emojis-list": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-2.1.0.tgz", "integrity": "sha1-TapNnbAPmBmIDHn6RXrlsJof04k=", "dev": true }, "encodeurl": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=", "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" } }, "enhanced-resolve": { "version": "0.9.1", "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-0.9.1.tgz", "integrity": "sha1-TW5omzcl+GCQknzMhs2fFjW4ni4=", "dev": true, "requires": { "graceful-fs": "^4.1.2", "memory-fs": "^0.2.0", "tapable": "^0.1.8" }, "dependencies": { "memory-fs": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/memory-fs/-/memory-fs-0.2.0.tgz", "integrity": "sha1-8rslNovBIeORwlIN6Slpyu4KApA=", "dev": true } } }, "errno": { "version": "0.1.7", "resolved": "https://registry.npmjs.org/errno/-/errno-0.1.7.tgz", "integrity": "sha512-MfrRBDWzIWifgq6tJj60gkAwtLNb6sQPlcFrSOflcP1aFmmruKQ2wRnze/8V6kgyz7H3FF8Npzv78mZ7XLLflg==", "dev": true, "requires": { "prr": "~1.0.1" } }, "error": { "version": "7.2.1", "resolved": "https://registry.npmjs.org/error/-/error-7.2.1.tgz", "integrity": "sha512-fo9HBvWnx3NGUKMvMwB/CBCMMrfEJgbDTVDEkPygA3Bdd3lM1OyCd+rbQ8BwnpF6GdVeOLDNmyL4N5Bg80ZvdA==", "dev": true, "requires": { "string-template": "~0.2.1" } }, "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" } }, "es6-error": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/es6-error/-/es6-error-4.1.1.tgz", "integrity": "sha512-Um/+FxMr9CISWh0bi5Zv0iOD+4cFh5qLeks1qhAopKVAJw3drgKbKySikp7wGhDL0HPeaja0P5ULZrxLkniUVg==", "dev": true }, "es6-promise": { "version": "4.2.8", "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.8.tgz", "integrity": "sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w==", "dev": true }, "es6-promisify": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/es6-promisify/-/es6-promisify-5.0.0.tgz", "integrity": "sha1-UQnWLz5W6pZ8S2NQWu8IKRyKUgM=", "dev": true, "requires": { "es6-promise": "^4.0.3" } }, "escape-html": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=", "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.0", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", "dev": true }, "debug": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", "dev": true, "requires": { "ms": "^2.1.1" } }, "glob-parent": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.0.tgz", "integrity": "sha512-qjtRgnIVmOfnKUE3NJAQEdk+lKrxfw8t5ke7SXtfMTHcjsBfOfWXCQfdb30zfDoZQ2IRSIiidmjtbHZPZ++Ihw==", "dev": true, "requires": { "is-glob": "^4.0.1" } }, "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" } }, "is-extglob": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", "dev": true }, "is-glob": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz", "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==", "dev": true, "requires": { "is-extglob": "^2.1.1" } }, "minimatch": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", "dev": true, "requires": { "brace-expansion": "^1.1.7" } }, "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.0.1", "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.0.1.tgz", "integrity": "sha512-VTyMAUfdm047mwKl+u79WIdrZxtFtn+nBxHeb844XBQ9uMNTuTHdx2hc5RiAJYqwTj3wc/xe5HLSdJSkJ+WfZw==", "dev": true } } }, "eslint-config-prettier": { "version": "6.10.0", "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-6.10.0.tgz", "integrity": "sha512-AtndijGte1rPILInUdHjvKEGbIV06NuvPrqlIEaEaWtbtvJh464mDeyGMdZEQMsGvC0ZVkiex1fSNcC4HAbRGg==", "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-plugin-compat": { "version": "3.5.1", "resolved": "https://registry.npmjs.org/eslint-plugin-compat/-/eslint-plugin-compat-3.5.1.tgz", "integrity": "sha512-dhfW12vZxxKLEVhrPoblmEopgwpYU2Sd4GdXj5OSfbQ+as9+1aY+S5pqnJYJvXXNWFFJ6aspLkCyk4NMQ/pgtA==", "dev": true, "requires": { "@babel/runtime": "^7.7.7", "ast-metadata-inferer": "^0.1.1", "browserslist": "^4.8.2", "caniuse-db": "^1.0.30001017", "lodash.memoize": "4.1.2", "mdn-browser-compat-data": "^1.0.3", "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 } } }, "eslint-plugin-es5": { "version": "1.5.0", "resolved": "https://registry.npmjs.org/eslint-plugin-es5/-/eslint-plugin-es5-1.5.0.tgz", "integrity": "sha512-Qxmfo7v2B7SGAEURJo0dpBweFf+JU15kSyALfiB2rXWcBuJ96r6X9kFHXFnhdopPHCaHjoQs1xQPUJVbGMb1AA==", "dev": true }, "eslint-scope": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.0.0.tgz", "integrity": "sha512-oYrhJW7S0bxAFDvWqzvMPRm6pcgcnWc4QnofCAqRTRfQC0JcwenzGglTtsLyIuuWFfkqDG9vz67cnttSd53djw==", "dev": true, "requires": { "esrecurse": "^4.1.0", "estraverse": "^4.1.1" } }, "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" } }, "eslint-visitor-keys": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.1.0.tgz", "integrity": "sha512-8y9YjtM1JBJU/A9Kc+SbaOV4y29sSWckBwMHa+FGtVj5gN/sbnKDf6xJUl+8g7FAij9LVaP8C24DUiH/f/2Z9A==", "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.1.1", "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.1.1.tgz", "integrity": "sha512-add7dgA5ppRPxCFJoAGfMDi7PIBXq1RtGo7BhbLaxwrXPOmw8gq48Y9ozT01hUKy9byMjlR20EJhu5zlkErEkg==", "dev": true } } }, "esprima-fb": { "version": "15001.1001.0-dev-harmony-fb", "resolved": "https://registry.npmjs.org/esprima-fb/-/esprima-fb-15001.1001.0-dev-harmony-fb.tgz", "integrity": "sha1-Q761fsJujPI3092LM+QlM1d/Jlk=", "dev": true }, "esquery": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.1.0.tgz", "integrity": "sha512-MxYW9xKmROWF672KqjO75sszsA8Mxhw06YFeS5VHlB98KDHbOSurm3ArsjO60Eaf3QmGMCP1yn+0JQkNLo/97Q==", "dev": true, "requires": { "estraverse": "^4.0.0" } }, "esrecurse": { "version": "4.2.1", "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.2.1.tgz", "integrity": "sha512-64RBB++fIOAXPw3P9cy89qfMlvZEXZkqqJkjqqXIvzP5ezRZjW+lPWjw35UX/3EhUPFYbg5ER4JYgDw4007/DQ==", "dev": true, "requires": { "estraverse": "^4.1.0" } }, "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 }, "etag": { "version": "1.8.1", "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", "integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=", "dev": true }, "eventemitter2": { "version": "0.4.14", "resolved": "https://registry.npmjs.org/eventemitter2/-/eventemitter2-0.4.14.tgz", "integrity": "sha1-j2G3XN4BKy6esoTUVFWDtWQ7Yas=", "dev": true }, "eventemitter3": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.0.tgz", "integrity": "sha512-qerSRB0p+UDEssxTtm6EDKcE7W4OaoisfIMl4CngyEhjpYglocpNg6UEqCvemdGhosAsg4sO2dXJOdyBifPGCg==", "dev": true }, "events": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/events/-/events-1.1.1.tgz", "integrity": "sha1-nr23Y1rQmccNzEwqH1AEKI6L2SQ=", "dev": true }, "eventsource": { "version": "1.0.7", "resolved": "https://registry.npmjs.org/eventsource/-/eventsource-1.0.7.tgz", "integrity": "sha512-4Ln17+vVT0k8aWq+t/bF5arcS3EpT9gYtW66EPacdj/mAFevznsnyoHLPy2BA8gbIQeIHoPsvwmfBftfcG//BQ==", "dev": true, "requires": { "original": "^1.0.0" } }, "execa": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/execa/-/execa-1.0.0.tgz", "integrity": "sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA==", "dev": true, "requires": { "cross-spawn": "^6.0.0", "get-stream": "^4.0.0", "is-stream": "^1.1.0", "npm-run-path": "^2.0.0", "p-finally": "^1.0.0", "signal-exit": "^3.0.0", "strip-eof": "^1.0.0" } }, "exit": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz", "integrity": "sha1-BjJjj42HfMghB9MKD/8aF8uhzQw=", "dev": true }, "expand-brackets": { "version": "0.1.5", "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-0.1.5.tgz", "integrity": "sha1-3wcoTjQqgHzXM6xa9yQR5YHRF3s=", "dev": true, "requires": { "is-posix-bracket": "^0.1.0" } }, "expand-range": { "version": "1.8.2", "resolved": "https://registry.npmjs.org/expand-range/-/expand-range-1.8.2.tgz", "integrity": "sha1-opnv/TNf4nIeuujiV+x5ZE/IUzc=", "dev": true, "requires": { "fill-range": "^2.1.0" } }, "expand-tilde": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/expand-tilde/-/expand-tilde-2.0.2.tgz", "integrity": "sha1-l+gBqgUt8CRU3kawK/YhZCzchQI=", "dev": true, "requires": { "homedir-polyfill": "^1.0.1" } }, "express": { "version": "4.17.1", "resolved": "https://registry.npmjs.org/express/-/express-4.17.1.tgz", "integrity": "sha512-mHJ9O79RqluphRrcw2X/GTh3k9tVv8YcoyY4Kkh4WDMUYKRZUq0h1o0w2rrrxBqM7VoeUVqgb27xlEMXTnYt4g==", "dev": true, "requires": { "accepts": "~1.3.7", "array-flatten": "1.1.1", "body-parser": "1.19.0", "content-disposition": "0.5.3", "content-type": "~1.0.4", "cookie": "0.4.0", "cookie-signature": "1.0.6", "debug": "2.6.9", "depd": "~1.1.2", "encodeurl": "~1.0.2", "escape-html": "~1.0.3", "etag": "~1.8.1", "finalhandler": "~1.1.2", "fresh": "0.5.2", "merge-descriptors": "1.0.1", "methods": "~1.1.2", "on-finished": "~2.3.0", "parseurl": "~1.3.3", "path-to-regexp": "0.1.7", "proxy-addr": "~2.0.5", "qs": "6.7.0", "range-parser": "~1.2.1", "safe-buffer": "5.1.2", "send": "0.17.1", "serve-static": "1.14.1", "setprototypeof": "1.1.1", "statuses": "~1.5.0", "type-is": "~1.6.18", "utils-merge": "1.0.1", "vary": "~1.1.2" }, "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 }, "path-to-regexp": { "version": "0.1.7", "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", "integrity": "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w=", "dev": true }, "qs": { "version": "6.7.0", "resolved": "https://registry.npmjs.org/qs/-/qs-6.7.0.tgz", "integrity": "sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ==", "dev": true }, "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 }, "setprototypeof": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.1.tgz", "integrity": "sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw==", "dev": true } } }, "extend": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", "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": "0.3.2", "resolved": "https://registry.npmjs.org/extglob/-/extglob-0.3.2.tgz", "integrity": "sha1-Lhj/PS9JqydlzskCPwEdqo2DSaE=", "dev": true, "requires": { "is-extglob": "^1.0.0" } }, "extsprintf": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=", "dev": true }, "fast-deep-equal": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.1.tgz", "integrity": "sha512-8UEa58QDLauDNfpbrX55Q9jrGHThw2ZMdOky5Gl1CDtVeJDPVrG4Jxx1N8jw2gkWaff5UUuX1KJd+9zGe2B+ZA==", "dev": true }, "fast-glob": { "version": "3.2.2", "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.2.tgz", "integrity": "sha512-UDV82o4uQyljznxwMxyVRJgZZt3O5wENYojjzbaGEGZgeOxkLFf+V4cnUD+krzb2F72E18RhamkMZ7AdeggF7A==", "dev": true, "requires": { "@nodelib/fs.stat": "^2.0.2", "@nodelib/fs.walk": "^1.2.3", "glob-parent": "^5.1.0", "merge2": "^1.3.0", "micromatch": "^4.0.2", "picomatch": "^2.2.1" }, "dependencies": { "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" } }, "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" } }, "glob-parent": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.0.tgz", "integrity": "sha512-qjtRgnIVmOfnKUE3NJAQEdk+lKrxfw8t5ke7SXtfMTHcjsBfOfWXCQfdb30zfDoZQ2IRSIiidmjtbHZPZ++Ihw==", "dev": true, "requires": { "is-glob": "^4.0.1" } }, "is-extglob": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", "dev": true }, "is-glob": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz", "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==", "dev": true, "requires": { "is-extglob": "^2.1.1" } }, "is-number": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", "dev": true }, "micromatch": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.2.tgz", "integrity": "sha512-y7FpHSbMUMoyPbYUSzO6PaZ6FyRnQOpHuKwbo1G+Knck95XVU4QAiKdGEnj5wwoS7PlOgthX/09u5iFJ+aYf5Q==", "dev": true, "requires": { "braces": "^3.0.1", "picomatch": "^2.0.5" } }, "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" } } } }, "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 }, "fastq": { "version": "1.6.1", "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.6.1.tgz", "integrity": "sha512-mpIH5sKYueh3YyeJwqtVo8sORi0CgtmkVbK6kZStpQlZBYQuTzG2CZ7idSiJuA7bY0SFCWUc5WIs+oYumGCQNw==", "dev": true, "requires": { "reusify": "^1.0.4" } }, "faye-websocket": { "version": "0.10.0", "resolved": "https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.10.0.tgz", "integrity": "sha1-TkkvjQTftviQA1B/btvy1QHnxvQ=", "dev": true, "requires": { "websocket-driver": ">=0.5.1" } }, "fg-lodash": { "version": "0.0.2", "resolved": "https://registry.npmjs.org/fg-lodash/-/fg-lodash-0.0.2.tgz", "integrity": "sha1-mINSU39CfaavIiEpu2OsyknmL6M=", "dev": true, "requires": { "lodash": "^2.4.1", "underscore.string": "~2.3.3" }, "dependencies": { "lodash": { "version": "2.4.2", "resolved": "https://registry.npmjs.org/lodash/-/lodash-2.4.2.tgz", "integrity": "sha1-+t2DS5aDBz2hebPq5tnA0VBT9z4=", "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" } }, "file-sync-cmp": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/file-sync-cmp/-/file-sync-cmp-0.1.1.tgz", "integrity": "sha1-peeo/7+kk7Q7kju9TKiaU7Y7YSs=", "dev": true }, "file-uri-to-path": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz", "integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==", "dev": true, "optional": true }, "filename-regex": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/filename-regex/-/filename-regex-2.0.1.tgz", "integrity": "sha1-wcS5vuPglyXdsQa3XB4wH+LxiyY=", "dev": true }, "fill-range": { "version": "2.2.4", "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-2.2.4.tgz", "integrity": "sha512-cnrcCbj01+j2gTG921VZPnHbjmdAf8oQV/iGeV2kZxGSyfYjjTyY79ErsK1WJWMpw6DaApEX72binqJE+/d+5Q==", "dev": true, "requires": { "is-number": "^2.1.0", "isobject": "^2.0.0", "randomatic": "^3.0.0", "repeat-element": "^1.1.2", "repeat-string": "^1.5.2" } }, "finalhandler": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.2.tgz", "integrity": "sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA==", "dev": true, "requires": { "debug": "2.6.9", "encodeurl": "~1.0.2", "escape-html": "~1.0.3", "on-finished": "~2.3.0", "parseurl": "~1.3.3", "statuses": "~1.5.0", "unpipe": "~1.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" } }, "ms": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", "dev": true } } }, "find-cache-dir": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-2.1.0.tgz", "integrity": "sha512-Tq6PixE0w/VMFfCgbONnkiQIVol/JJL7nRMi20fqzA4NRs9AfeqMGeRdPi3wIhYkxjeBaWh2rxwapn5Tu3IqOQ==", "dev": true, "requires": { "commondir": "^1.0.1", "make-dir": "^2.0.0", "pkg-dir": "^3.0.0" }, "dependencies": { "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" } }, "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" } }, "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" } }, "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 }, "pkg-dir": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-3.0.0.tgz", "integrity": "sha512-/E57AYkoeQ25qkxMj5PBOVgF8Kiu/h7cYS30Z5+R7WaiCCBfLq58ZI/dSeaEKb9WVJV5n/03QwrN3IeWIFllvw==", "dev": true, "requires": { "find-up": "^3.0.0" } } } }, "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" } }, "findup-sync": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/findup-sync/-/findup-sync-0.3.0.tgz", "integrity": "sha1-N5MKpdgWt3fANEXhlmzGeQpMCxY=", "dev": true, "requires": { "glob": "~5.0.0" } }, "fined": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/fined/-/fined-1.2.0.tgz", "integrity": "sha512-ZYDqPLGxDkDhDZBjZBb+oD1+j0rA4E0pXY50eplAAOPg2N/gUBSSk5IM1/QhPfyVo19lJ+CvXpqfvk+b2p/8Ng==", "dev": true, "requires": { "expand-tilde": "^2.0.2", "is-plain-object": "^2.0.3", "object.defaults": "^1.1.0", "object.pick": "^1.2.0", "parse-filepath": "^1.0.1" } }, "flagged-respawn": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/flagged-respawn/-/flagged-respawn-1.0.1.tgz", "integrity": "sha512-lNaHNVymajmk0OJMBn8fVUAU1BtDeKIqKoVhk4xAALB57aALg6b4W0MfJ/cUE0g9YBXy5XhSlPIpYIJ7HaY/3Q==", "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" } }, "flatted": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/flatted/-/flatted-2.0.1.tgz", "integrity": "sha512-a1hQMktqW9Nmqr5aktAux3JMNqaucxGcjtjWnZLHX7yyPCmlSV3M54nGYbqT8K+0GhF3NBgmJCc3ma+WOgX8Jg==", "dev": true }, "follow-redirects": { "version": "1.10.0", "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.10.0.tgz", "integrity": "sha512-4eyLK6s6lH32nOvLLwlIOnr9zrL8Sm+OvW4pVTJNoXeGzYIkHVf+pADQi+OJ0E67hiuSLezPVPyBcIZO50TmmQ==", "dev": true, "requires": { "debug": "^3.0.0" } }, "for-in": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz", "integrity": "sha1-gQaNKVqBQuwKxybG4iAMMPttXoA=", "dev": true }, "for-own": { "version": "0.1.5", "resolved": "https://registry.npmjs.org/for-own/-/for-own-0.1.5.tgz", "integrity": "sha1-UmXGgaTylNq78XyVCbZ2OqhFEM4=", "dev": true, "requires": { "for-in": "^1.0.1" } }, "foreground-child": { "version": "1.5.6", "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-1.5.6.tgz", "integrity": "sha1-T9ca0t/elnibmApcCilZN8svXOk=", "dev": true, "requires": { "cross-spawn": "^4", "signal-exit": "^3.0.0" }, "dependencies": { "cross-spawn": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-4.0.2.tgz", "integrity": "sha1-e5JHYhwjrf3ThWAEqCPL45dCTUE=", "dev": true, "requires": { "lru-cache": "^4.0.1", "which": "^1.2.9" } } } }, "forever-agent": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=", "dev": true }, "form-data": { "version": "2.3.3", "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz", "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==", "dev": true, "requires": { "asynckit": "^0.4.0", "combined-stream": "^1.0.6", "mime-types": "^2.1.12" } }, "forwarded": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.1.2.tgz", "integrity": "sha1-mMI9qxF1ZXuMBXPozszZGw/xjIQ=", "dev": true }, "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" } }, "fresh": { "version": "0.5.2", "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=", "dev": true }, "fs-extra": { "version": "8.1.0", "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz", "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==", "dev": true, "requires": { "graceful-fs": "^4.2.0", "jsonfile": "^4.0.0", "universalify": "^0.1.0" } }, "fs-readdir-recursive": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/fs-readdir-recursive/-/fs-readdir-recursive-0.1.2.tgz", "integrity": "sha1-MVtPuMHKW4xH3v7zGdBz2tNWgFk=", "dev": true }, "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": "1.2.13", "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.13.tgz", "integrity": "sha512-oWb1Z6mkHIskLzEJ/XWX0srkpkTQ7vaopMQkyaEIoq0fmtFVxOthb8cCxeT+p3ynTdkk/RZwbgG4brR5BeWECw==", "dev": true, "optional": true, "requires": { "bindings": "^1.5.0", "nan": "^2.12.1" } }, "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 }, "gaze": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/gaze/-/gaze-1.1.3.tgz", "integrity": "sha512-BRdNm8hbWzFzWHERTrejLqwHDfS4GibPoq5wjTPIoJHoBtKGPg3xAFfxmM+9ztbXelxcf2hwQcaz1PtmFeue8g==", "dev": true, "requires": { "globule": "^1.0.0" } }, "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-func-name": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.0.tgz", "integrity": "sha1-6td0q+5y4gQJQzoGY2YCPdaIekE=", "dev": true }, "get-own-enumerable-property-symbols": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/get-own-enumerable-property-symbols/-/get-own-enumerable-property-symbols-3.0.2.tgz", "integrity": "sha512-I0UBV/XOz1XkIJHEUDMZAbzCThU/H8DxmSfmdGcKPnVhu2VfFqr34jr9777IyaTYvxjedWhqVIilEDsCdP5G6g==", "dev": true }, "get-stdin": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-4.0.1.tgz", "integrity": "sha1-uWjGsKBDhDJJAui/Gl3zJXmkUP4=", "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 }, "getobject": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/getobject/-/getobject-0.1.0.tgz", "integrity": "sha1-BHpEl4n6Fg0Bj1SG7ZEyC27HiFw=", "dev": true }, "getpass": { "version": "0.1.7", "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=", "dev": true, "requires": { "assert-plus": "^1.0.0" } }, "glob": { "version": "5.0.15", "resolved": "https://registry.npmjs.org/glob/-/glob-5.0.15.tgz", "integrity": "sha1-G8k2ueAvSmA/zCIuz3Yz0wuLk7E=", "dev": true, "requires": { "inflight": "^1.0.4", "inherits": "2", "minimatch": "2 || 3", "once": "^1.3.0", "path-is-absolute": "^1.0.0" } }, "glob-base": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/glob-base/-/glob-base-0.3.0.tgz", "integrity": "sha1-27Fk9iIbHAscz4Kuoyi0l98Oo8Q=", "dev": true, "requires": { "glob-parent": "^2.0.0", "is-glob": "^2.0.0" } }, "glob-parent": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-2.0.0.tgz", "integrity": "sha1-gTg9ctsFT8zPUzbaqQLxgvbtuyg=", "dev": true, "requires": { "is-glob": "^2.0.0" } }, "global-modules": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/global-modules/-/global-modules-1.0.0.tgz", "integrity": "sha512-sKzpEkf11GpOFuw0Zzjzmt4B4UZwjOcG757PPvrfhxcLFbq0wpsgpOqxpxtxFiCG4DtG93M6XRVbF2oGdev7bg==", "dev": true, "requires": { "global-prefix": "^1.0.1", "is-windows": "^1.0.1", "resolve-dir": "^1.0.0" } }, "global-prefix": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/global-prefix/-/global-prefix-1.0.2.tgz", "integrity": "sha1-2/dDxsFJklk8ZVVoy2btMsASLr4=", "dev": true, "requires": { "expand-tilde": "^2.0.2", "homedir-polyfill": "^1.0.1", "ini": "^1.3.4", "is-windows": "^1.0.1", "which": "^1.2.14" } }, "globals": { "version": "6.4.1", "resolved": "https://registry.npmjs.org/globals/-/globals-6.4.1.tgz", "integrity": "sha1-hJgDKzttHMge68X3lpDY/in6v08=", "dev": true }, "globby": { "version": "10.0.2", "resolved": "https://registry.npmjs.org/globby/-/globby-10.0.2.tgz", "integrity": "sha512-7dUi7RvCoT/xast/o/dLN53oqND4yk0nsHkhRgn9w65C4PofCLOoJ39iSOg+qVDdWQPIEj+eszMHQ+aLVwwQSg==", "dev": true, "requires": { "@types/glob": "^7.1.1", "array-union": "^2.1.0", "dir-glob": "^3.0.1", "fast-glob": "^3.0.3", "glob": "^7.1.3", "ignore": "^5.1.1", "merge2": "^1.2.3", "slash": "^3.0.0" }, "dependencies": { "glob": { "version": "7.1.6", "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", "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" } }, "ignore": { "version": "5.1.4", "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.1.4.tgz", "integrity": "sha512-MzbUSahkTW1u7JpKKjY7LCARd1fU5W2rLdxlM4kdkayuCwZImjkpluF9CM1aLewYJguPDqewLam18Y6AU69A8A==", "dev": true }, "minimatch": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", "dev": true, "requires": { "brace-expansion": "^1.1.7" } }, "slash": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", "dev": true } } }, "globule": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/globule/-/globule-1.3.1.tgz", "integrity": "sha512-OVyWOHgw29yosRHCHo7NncwR1hW5ew0W/UrvtwvjefVJeQ26q4/8r8FmPsSF1hJ93IgWkyv16pCTz6WblMzm/g==", "dev": true, "requires": { "glob": "~7.1.1", "lodash": "~4.17.12", "minimatch": "~3.0.2" }, "dependencies": { "glob": { "version": "7.1.6", "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", "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" } }, "minimatch": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", "dev": true, "requires": { "brace-expansion": "^1.1.7" } } } }, "graceful-fs": { "version": "4.2.3", "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.3.tgz", "integrity": "sha512-a30VEBm4PEdx1dRB7MFK7BejejvCvBronbLjht+sHuGYj8PHs7M/5Z+rt5lw551vZ7yfTCj4Vuyy3mSJytDWRQ==", "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 }, "grunt": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/grunt/-/grunt-1.1.0.tgz", "integrity": "sha512-+NGod0grmviZ7Nzdi9am7vuRS/h76PcWDsV635mEXF0PEQMUV6Kb+OjTdsVxbi0PZmfQOjCMKb3w8CVZcqsn1g==", "dev": true, "requires": { "coffeescript": "~1.10.0", "dateformat": "~1.0.12", "eventemitter2": "~0.4.13", "exit": "~0.1.1", "findup-sync": "~0.3.0", "glob": "~7.0.0", "grunt-cli": "~1.2.0", "grunt-known-options": "~1.1.0", "grunt-legacy-log": "~2.0.0", "grunt-legacy-util": "~1.1.1", "iconv-lite": "~0.4.13", "js-yaml": "~3.13.1", "minimatch": "~3.0.2", "mkdirp": "~1.0.3", "nopt": "~3.0.6", "path-is-absolute": "~1.0.0", "rimraf": "~2.6.2" }, "dependencies": { "coffeescript": { "version": "1.10.0", "resolved": "https://registry.npmjs.org/coffeescript/-/coffeescript-1.10.0.tgz", "integrity": "sha1-56qDAZF+9iGzXYo580jc3R234z4=", "dev": true }, "glob": { "version": "7.0.6", "resolved": "https://registry.npmjs.org/glob/-/glob-7.0.6.tgz", "integrity": "sha1-IRuvr0nlJbjNkyYNFKsTYVKz9Xo=", "dev": true, "requires": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", "inherits": "2", "minimatch": "^3.0.2", "once": "^1.3.0", "path-is-absolute": "^1.0.0" } }, "grunt-cli": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/grunt-cli/-/grunt-cli-1.2.0.tgz", "integrity": "sha1-VisRnrsGndtGSs4oRVAb6Xs1tqg=", "dev": true, "requires": { "findup-sync": "~0.3.0", "grunt-known-options": "~1.1.0", "nopt": "~3.0.6", "resolve": "~1.1.0" } }, "minimatch": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", "dev": true, "requires": { "brace-expansion": "^1.1.7" } }, "mkdirp": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.3.tgz", "integrity": "sha512-6uCP4Qc0sWsgMLy1EOqqS/3rjDHOEnsStVr/4vtAIK2Y5i2kA7lFFejYrpIyiN9w0pYf4ckeCYT9f1r1P9KX5g==", "dev": true }, "resolve": { "version": "1.1.7", "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.1.7.tgz", "integrity": "sha1-IDEU2CrSxe2ejgQRs5ModeiJ6Xs=", "dev": true } } }, "grunt-babel": { "version": "5.0.3", "resolved": "https://registry.npmjs.org/grunt-babel/-/grunt-babel-5.0.3.tgz", "integrity": "sha1-hiIOsyAu+uIzqEGKHX+Htgre4yM=", "dev": true, "requires": { "babel-core": "^5.0.0" } }, "grunt-bg-shell": { "version": "2.3.3", "resolved": "https://registry.npmjs.org/grunt-bg-shell/-/grunt-bg-shell-2.3.3.tgz", "integrity": "sha1-E5ro+cdvaKDbTunbvU7IJbkif/8=", "dev": true }, "grunt-cli": { "version": "1.3.2", "resolved": "https://registry.npmjs.org/grunt-cli/-/grunt-cli-1.3.2.tgz", "integrity": "sha512-8OHDiZZkcptxVXtMfDxJvmN7MVJNE8L/yIcPb4HB7TlyFD1kDvjHrb62uhySsU14wJx9ORMnTuhRMQ40lH/orQ==", "dev": true, "requires": { "grunt-known-options": "~1.1.0", "interpret": "~1.1.0", "liftoff": "~2.5.0", "nopt": "~4.0.1", "v8flags": "~3.1.1" }, "dependencies": { "nopt": { "version": "4.0.3", "resolved": "https://registry.npmjs.org/nopt/-/nopt-4.0.3.tgz", "integrity": "sha512-CvaGwVMztSMJLOeXPrez7fyfObdZqNUK1cPAEzLHrTybIua9pMdmmPR5YwtfNftIOMv3DPUhFaxsZMNTQO20Kg==", "dev": true, "requires": { "abbrev": "1", "osenv": "^0.1.4" } } } }, "grunt-contrib-clean": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/grunt-contrib-clean/-/grunt-contrib-clean-1.1.0.tgz", "integrity": "sha1-Vkq/LQN4qYOhW54/MO51tzjEBjg=", "dev": true, "requires": { "async": "^1.5.2", "rimraf": "^2.5.1" } }, "grunt-contrib-concat": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/grunt-contrib-concat/-/grunt-contrib-concat-1.0.1.tgz", "integrity": "sha1-YVCYYwhOhx1+ht5IwBUlntl3Rb0=", "dev": true, "requires": { "chalk": "^1.0.0", "source-map": "^0.5.3" }, "dependencies": { "ansi-regex": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", "dev": true }, "ansi-styles": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", "dev": true }, "chalk": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", "dev": true, "requires": { "ansi-styles": "^2.2.1", "escape-string-regexp": "^1.0.2", "has-ansi": "^2.0.0", "strip-ansi": "^3.0.0", "supports-color": "^2.0.0" } }, "source-map": { "version": "0.5.7", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", "dev": true }, "strip-ansi": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", "dev": true, "requires": { "ansi-regex": "^2.0.0" } }, "supports-color": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", "dev": true } } }, "grunt-contrib-connect": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/grunt-contrib-connect/-/grunt-contrib-connect-1.0.2.tgz", "integrity": "sha1-XPkzuRpnOGBEJzwLJERgPNmIebo=", "dev": true, "requires": { "async": "^1.5.2", "connect": "^3.4.0", "connect-livereload": "^0.5.0", "http2": "^3.3.4", "morgan": "^1.6.1", "opn": "^4.0.0", "portscanner": "^1.0.0", "serve-index": "^1.7.1", "serve-static": "^1.10.0" } }, "grunt-contrib-copy": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/grunt-contrib-copy/-/grunt-contrib-copy-1.0.0.tgz", "integrity": "sha1-cGDGWB6QS4qw0A8HbgqPbj58NXM=", "dev": true, "requires": { "chalk": "^1.1.1", "file-sync-cmp": "^0.1.0" }, "dependencies": { "ansi-regex": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", "dev": true }, "ansi-styles": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", "dev": true }, "chalk": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", "dev": true, "requires": { "ansi-styles": "^2.2.1", "escape-string-regexp": "^1.0.2", "has-ansi": "^2.0.0", "strip-ansi": "^3.0.0", "supports-color": "^2.0.0" } }, "strip-ansi": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", "dev": true, "requires": { "ansi-regex": "^2.0.0" } }, "supports-color": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", "dev": true } } }, "grunt-contrib-requirejs": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/grunt-contrib-requirejs/-/grunt-contrib-requirejs-1.0.0.tgz", "integrity": "sha1-7BZwyvwycTkC7lNWlFRxWy48utU=", "dev": true, "requires": { "requirejs": "^2.1.0" } }, "grunt-contrib-uglify": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/grunt-contrib-uglify/-/grunt-contrib-uglify-1.0.2.tgz", "integrity": "sha1-rmekb5FT7dTLEYE6Vetpxw19svs=", "dev": true, "requires": { "chalk": "^1.0.0", "lodash": "^4.0.1", "maxmin": "^1.1.0", "uglify-js": "~2.6.2", "uri-path": "^1.0.0" }, "dependencies": { "ansi-regex": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", "dev": true }, "ansi-styles": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", "dev": true }, "async": { "version": "0.2.10", "resolved": "https://registry.npmjs.org/async/-/async-0.2.10.tgz", "integrity": "sha1-trvgsGdLnXGXCMo43owjfLUmw9E=", "dev": true }, "camelcase": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-1.2.1.tgz", "integrity": "sha1-m7UwTS4LVmmLLHWLCKPqqdqlijk=", "dev": true }, "chalk": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", "dev": true, "requires": { "ansi-styles": "^2.2.1", "escape-string-regexp": "^1.0.2", "has-ansi": "^2.0.0", "strip-ansi": "^3.0.0", "supports-color": "^2.0.0" } }, "cliui": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/cliui/-/cliui-2.1.0.tgz", "integrity": "sha1-S0dXYP+AJkx2LDoXGQMukcf+oNE=", "dev": true, "requires": { "center-align": "^0.1.1", "right-align": "^0.1.1", "wordwrap": "0.0.2" }, "dependencies": { "wordwrap": { "version": "0.0.2", "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.2.tgz", "integrity": "sha1-t5Zpu0LstAn4PVg8rVLKF+qhZD8=", "dev": true } } }, "source-map": { "version": "0.5.7", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", "dev": true }, "strip-ansi": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", "dev": true, "requires": { "ansi-regex": "^2.0.0" } }, "supports-color": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", "dev": true }, "uglify-js": { "version": "2.6.4", "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-2.6.4.tgz", "integrity": "sha1-ZeovswWck5RpLxX+2HwrNsFrmt8=", "dev": true, "requires": { "async": "~0.2.6", "source-map": "~0.5.1", "uglify-to-browserify": "~1.0.0", "yargs": "~3.10.0" } }, "window-size": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/window-size/-/window-size-0.1.0.tgz", "integrity": "sha1-VDjNLqk7IC76Ohn+iIeu58lPnJ0=", "dev": true }, "yargs": { "version": "3.10.0", "resolved": "https://registry.npmjs.org/yargs/-/yargs-3.10.0.tgz", "integrity": "sha1-9+572FfdfB0tOMDnTvvWgdFDH9E=", "dev": true, "requires": { "camelcase": "^1.0.2", "cliui": "^2.1.0", "decamelize": "^1.0.0", "window-size": "0.1.0" } } } }, "grunt-contrib-watch": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/grunt-contrib-watch/-/grunt-contrib-watch-1.1.0.tgz", "integrity": "sha512-yGweN+0DW5yM+oo58fRu/XIRrPcn3r4tQx+nL7eMRwjpvk+rQY6R8o94BPK0i2UhTg9FN21hS+m8vR8v9vXfeg==", "dev": true, "requires": { "async": "^2.6.0", "gaze": "^1.1.0", "lodash": "^4.17.10", "tiny-lr": "^1.1.1" }, "dependencies": { "async": { "version": "2.6.3", "resolved": "https://registry.npmjs.org/async/-/async-2.6.3.tgz", "integrity": "sha512-zflvls11DCy+dQWzTW2dzuilv8Z5X/pjfmZOWba6TNIVDm+2UDaJmXSOXlasHKfNBs8oo3M0aT50fDEWfKZjXg==", "dev": true, "requires": { "lodash": "^4.17.14" } } } }, "grunt-known-options": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/grunt-known-options/-/grunt-known-options-1.1.1.tgz", "integrity": "sha512-cHwsLqoighpu7TuYj5RonnEuxGVFnztcUqTqp5rXFGYL4OuPFofwC4Ycg7n9fYwvK6F5WbYgeVOwph9Crs2fsQ==", "dev": true }, "grunt-legacy-log": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/grunt-legacy-log/-/grunt-legacy-log-2.0.0.tgz", "integrity": "sha512-1m3+5QvDYfR1ltr8hjiaiNjddxGdQWcH0rw1iKKiQnF0+xtgTazirSTGu68RchPyh1OBng1bBUjLmX8q9NpoCw==", "dev": true, "requires": { "colors": "~1.1.2", "grunt-legacy-log-utils": "~2.0.0", "hooker": "~0.2.3", "lodash": "~4.17.5" } }, "grunt-legacy-log-utils": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/grunt-legacy-log-utils/-/grunt-legacy-log-utils-2.0.1.tgz", "integrity": "sha512-o7uHyO/J+i2tXG8r2bZNlVk20vlIFJ9IEYyHMCQGfWYru8Jv3wTqKZzvV30YW9rWEjq0eP3cflQ1qWojIe9VFA==", "dev": true, "requires": { "chalk": "~2.4.1", "lodash": "~4.17.10" } }, "grunt-legacy-util": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/grunt-legacy-util/-/grunt-legacy-util-1.1.1.tgz", "integrity": "sha512-9zyA29w/fBe6BIfjGENndwoe1Uy31BIXxTH3s8mga0Z5Bz2Sp4UCjkeyv2tI449ymkx3x26B+46FV4fXEddl5A==", "dev": true, "requires": { "async": "~1.5.2", "exit": "~0.1.1", "getobject": "~0.1.0", "hooker": "~0.2.3", "lodash": "~4.17.10", "underscore.string": "~3.3.4", "which": "~1.3.0" }, "dependencies": { "underscore.string": { "version": "3.3.5", "resolved": "https://registry.npmjs.org/underscore.string/-/underscore.string-3.3.5.tgz", "integrity": "sha512-g+dpmgn+XBneLmXXo+sGlW5xQEt4ErkS3mgeN2GFbremYeMBSJKr9Wf2KJplQVaiPY/f7FN6atosWYNm9ovrYg==", "dev": true, "requires": { "sprintf-js": "^1.0.3", "util-deprecate": "^1.0.2" } } } }, "grunt-webpack": { "version": "1.0.18", "resolved": "https://registry.npmjs.org/grunt-webpack/-/grunt-webpack-1.0.18.tgz", "integrity": "sha1-/ybEP/NbrmzKcHqTxLzdlQo+y7c=", "dev": true, "requires": { "lodash": "^4.7.0" } }, "gzip-size": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/gzip-size/-/gzip-size-1.0.0.tgz", "integrity": "sha1-Zs+LEBBHInuVus5uodoMF37Vwi8=", "dev": true, "requires": { "browserify-zlib": "^0.1.4", "concat-stream": "^1.4.1" } }, "har-schema": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=", "dev": true }, "har-validator": { "version": "5.1.3", "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.3.tgz", "integrity": "sha512-sNvOCzEQNr/qrvJgc3UG/kD4QtlHycrzwS+6mfTrrSq97BvaYcPZZI1ZSqGSPR73Cxn4LKTD4PttRwfU7jWq5g==", "dev": true, "requires": { "ajv": "^6.5.5", "har-schema": "^2.0.0" } }, "has-ansi": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=", "dev": true, "requires": { "ansi-regex": "^2.0.0" }, "dependencies": { "ansi-regex": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", "dev": true } } }, "has-flag": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", "dev": true }, "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" }, "dependencies": { "isobject": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", "dev": true } } }, "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-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" } } } }, "hasha": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/hasha/-/hasha-3.0.0.tgz", "integrity": "sha1-UqMvq4Vp1BymmmH/GiFPjrfIvTk=", "dev": true, "requires": { "is-stream": "^1.0.1" } }, "he": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/he/-/he-1.1.1.tgz", "integrity": "sha1-k0EP0hsAlzUVH4howvJx80J+I/0=", "dev": true }, "home-or-tmp": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/home-or-tmp/-/home-or-tmp-1.0.0.tgz", "integrity": "sha1-S58eQIAMPlDGwn94FnavzOcfOYU=", "dev": true, "requires": { "os-tmpdir": "^1.0.1", "user-home": "^1.1.1" } }, "homedir-polyfill": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/homedir-polyfill/-/homedir-polyfill-1.0.3.tgz", "integrity": "sha512-eSmmWE5bZTK2Nou4g0AI3zZ9rswp7GRKoKXS1BLUkvPviOqs4YTN1djQIqrXy9k5gEtdLPy86JjRwsNM9tnDcA==", "dev": true, "requires": { "parse-passwd": "^1.0.0" } }, "hooker": { "version": "0.2.3", "resolved": "https://registry.npmjs.org/hooker/-/hooker-0.2.3.tgz", "integrity": "sha1-uDT3I8xKJCqmWWNFnfbZhMXT2Vk=", "dev": true }, "hosted-git-info": { "version": "2.8.8", "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.8.tgz", "integrity": "sha512-f/wzC2QaWBs7t9IYqB4T3sR1xviIViXJRJTWBlx2Gf3g0Xi5vI7Yy4koXQ1c9OYDGHN9sBy1DQ2AB8fqZBWhUg==", "dev": true }, "html-escaper": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.0.tgz", "integrity": "sha512-a4u9BeERWGu/S8JiWEAQcdrg9v4QArtP9keViQjGMdff20fBdd8waotXaNmODqBe6uZ3Nafi7K/ho4gCQHV3Ig==", "dev": true }, "http-errors": { "version": "1.6.3", "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.6.3.tgz", "integrity": "sha1-i1VoC7S+KDoLW/TqLjhYC+HZMg0=", "dev": true, "requires": { "depd": "~1.1.2", "inherits": "2.0.3", "setprototypeof": "1.1.0", "statuses": ">= 1.4.0 < 2" }, "dependencies": { "inherits": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", "dev": true } } }, "http-parser-js": { "version": "0.4.10", "resolved": "https://registry.npmjs.org/http-parser-js/-/http-parser-js-0.4.10.tgz", "integrity": "sha1-ksnBN0w1CF912zWexWzCV8u5P6Q=", "dev": true }, "http-proxy": { "version": "1.18.0", "resolved": "https://registry.npmjs.org/http-proxy/-/http-proxy-1.18.0.tgz", "integrity": "sha512-84I2iJM/n1d4Hdgc6y2+qY5mDaz2PUVjlg9znE9byl+q0uC3DeByqBGReQu5tpLK0TAqTIXScRUV+dg7+bUPpQ==", "dev": true, "requires": { "eventemitter3": "^4.0.0", "follow-redirects": "^1.0.0", "requires-port": "^1.0.0" } }, "http-proxy-middleware": { "version": "0.17.4", "resolved": "https://registry.npmjs.org/http-proxy-middleware/-/http-proxy-middleware-0.17.4.tgz", "integrity": "sha1-ZC6ISIUdZvCdTxJJEoRtuutBuDM=", "dev": true, "requires": { "http-proxy": "^1.16.2", "is-glob": "^3.1.0", "lodash": "^4.17.2", "micromatch": "^2.3.11" }, "dependencies": { "is-extglob": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", "dev": true }, "is-glob": { "version": "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" } } } }, "http-signature": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=", "dev": true, "requires": { "assert-plus": "^1.0.0", "jsprim": "^1.2.2", "sshpk": "^1.7.0" } }, "http2": { "version": "3.3.7", "resolved": "https://registry.npmjs.org/http2/-/http2-3.3.7.tgz", "integrity": "sha512-puSi8M8WNlFJm9Pk4c/Mbz9Gwparuj3gO9/RRO5zv6piQ0FY+9Qywp0PdWshYgsMJSalixFY7eC6oPu0zRxLAQ==", "dev": true }, "https-browserify": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/https-browserify/-/https-browserify-0.0.1.tgz", "integrity": "sha1-P5E2XKvmC3ftDruiS0VOPgnZWoI=", "dev": true }, "https-proxy-agent": { "version": "2.2.4", "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-2.2.4.tgz", "integrity": "sha512-OmvfoQ53WLjtA9HeYP9RNrWMJzzAz1JGaSFr1nijg0PVR1JaD/xbJq1mdEIIlxGpXp9eSe/O2LgU9DJmTPd0Eg==", "dev": true, "requires": { "agent-base": "^4.3.0", "debug": "^3.1.0" } }, "husky": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/husky/-/husky-3.1.0.tgz", "integrity": "sha512-FJkPoHHB+6s4a+jwPqBudBDvYZsoQW5/HBuMSehC8qDiCe50kpcxeqFoDSlow+9I6wg47YxBoT3WxaURlrDIIQ==", "dev": true, "requires": { "chalk": "^2.4.2", "ci-info": "^2.0.0", "cosmiconfig": "^5.2.1", "execa": "^1.0.0", "get-stdin": "^7.0.0", "opencollective-postinstall": "^2.0.2", "pkg-dir": "^4.2.0", "please-upgrade-node": "^3.2.0", "read-pkg": "^5.2.0", "run-node": "^1.0.0", "slash": "^3.0.0" }, "dependencies": { "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 }, "parse-json": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.0.0.tgz", "integrity": "sha512-OOY5b7PAEFV0E2Fir1KOkxchnZNCdowAJgQ5NuxjpBKTRP3pQhwkrkxqQjeoKJ+fO7bCpmIZaogI4eZGDMEGOw==", "dev": true, "requires": { "@babel/code-frame": "^7.0.0", "error-ex": "^1.3.1", "json-parse-better-errors": "^1.0.1", "lines-and-columns": "^1.1.6" } }, "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" } }, "slash": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", "dev": true }, "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 } } }, "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" } }, "ieee754": { "version": "1.1.13", "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.1.13.tgz", "integrity": "sha512-4vf7I2LYV/HaWerSo3XmlMkp5eZ83i+/CDluXi/IGTs/O1sejBNhTtnxzmRZfvOUqj7lZjqHkeTvpgSFDlWZTg==", "dev": true }, "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.1", "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.2.1.tgz", "integrity": "sha512-6e1q1cnWP2RXD9/keSkxHScg508CdXqXWgWBaETNhyuBFz+kUZlKboh+ISK+bU++DmbHimVBrOz/zzPe0sZ3sQ==", "dev": true, "requires": { "parent-module": "^1.0.0", "resolve-from": "^4.0.0" } }, "imurmurhash": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", "dev": true }, "indent-string": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-2.1.0.tgz", "integrity": "sha1-ji1INIdCEhtKghi3oTfppSBJ3IA=", "dev": true, "requires": { "repeating": "^2.0.0" }, "dependencies": { "repeating": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/repeating/-/repeating-2.0.1.tgz", "integrity": "sha1-UhTFOpJtNVJwdSf7q0FdvAjQbdo=", "dev": true, "requires": { "is-finite": "^1.0.0" } } } }, "indexof": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/indexof/-/indexof-0.0.1.tgz", "integrity": "sha1-gtwzbSMrkGIXnQWrMpOmYFn9Q10=", "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.5", "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.5.tgz", "integrity": "sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw==", "dev": true }, "inquirer": { "version": "7.1.0", "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-7.1.0.tgz", "integrity": "sha512-5fJMWEmikSYu0nv/flMc475MhGbB7TSPd/2IpFV4I4rMklboCH2rQjYY5kKiYGHqUF9gvaambupcJFFG9dvReg==", "dev": true, "requires": { "ansi-escapes": "^4.2.1", "chalk": "^3.0.0", "cli-cursor": "^3.1.0", "cli-width": "^2.0.0", "external-editor": "^3.0.3", "figures": "^3.0.0", "lodash": "^4.17.15", "mute-stream": "0.0.8", "run-async": "^2.4.0", "rxjs": "^6.5.3", "string-width": "^4.1.0", "strip-ansi": "^6.0.0", "through": "^2.3.6" }, "dependencies": { "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" } }, "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.1.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz", "integrity": "sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g==", "dev": true, "requires": { "has-flag": "^4.0.0" } } } }, "interpret": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/interpret/-/interpret-1.1.0.tgz", "integrity": "sha1-ftGxQQxqDg94z5XTuEQMY/eLhhQ=", "dev": true }, "invert-kv": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/invert-kv/-/invert-kv-1.0.0.tgz", "integrity": "sha1-EEqOSqym09jNFXqO+L+rLXo//bY=", "dev": true }, "ipaddr.js": { "version": "1.9.1", "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==", "dev": true }, "is-absolute": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-absolute/-/is-absolute-1.0.0.tgz", "integrity": "sha512-dOWoqflvcydARa360Gvv18DZ/gRuHKi2NU/wU5X1ZFzdYfH29nkiNZsF3mp4OJ3H4yo9Mx8A/uAGNzpzPN3yBA==", "dev": true, "requires": { "is-relative": "^1.0.0", "is-windows": "^1.0.1" } }, "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" } }, "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": "1.0.1", "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-1.0.1.tgz", "integrity": "sha1-dfFmQrSA8YenEcgUFh/TpKdlWJg=", "dev": true, "requires": { "binary-extensions": "^1.0.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-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" } }, "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-directory": { "version": "0.3.1", "resolved": "https://registry.npmjs.org/is-directory/-/is-directory-0.3.1.tgz", "integrity": "sha1-YTObbyR1/Hcv2cnYP1yFddwVSuE=", "dev": true }, "is-dotfile": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/is-dotfile/-/is-dotfile-1.0.3.tgz", "integrity": "sha1-pqLzL/0t+wT1yiXs0Pa4PPeYoeE=", "dev": true }, "is-equal-shallow": { "version": "0.1.3", "resolved": "https://registry.npmjs.org/is-equal-shallow/-/is-equal-shallow-0.1.3.tgz", "integrity": "sha1-IjgJj8Ih3gvPpdnqxMRdY4qhxTQ=", "dev": true, "requires": { "is-primitive": "^2.0.0" } }, "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": "1.0.0", "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-1.0.0.tgz", "integrity": "sha1-rEaBd8SUNAWgkvyPKXYMb/xiBsA=", "dev": true }, "is-finite": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/is-finite/-/is-finite-1.1.0.tgz", "integrity": "sha512-cdyMtqX/BOqqNBBiKlIVkytNHm49MtMlYyn1zxzvJKWmFMlGzm+ry5BBfYyeY9YmNKbRSo/o7OX9w9ale0wg3w==", "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 }, "is-glob": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-2.0.1.tgz", "integrity": "sha1-0Jb5JqPe1WAPP9/ZEZjLCIjC2GM=", "dev": true, "requires": { "is-extglob": "^1.0.0" } }, "is-integer": { "version": "1.0.7", "resolved": "https://registry.npmjs.org/is-integer/-/is-integer-1.0.7.tgz", "integrity": "sha1-a96Bqs3feLZZtmKdYpytxRqIbVw=", "dev": true, "requires": { "is-finite": "^1.0.0" } }, "is-number": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/is-number/-/is-number-2.1.0.tgz", "integrity": "sha1-Afy7s5NGOlSPL0ZszhbezknbkI8=", "dev": true, "requires": { "kind-of": "^3.0.2" } }, "is-obj": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-1.0.1.tgz", "integrity": "sha1-PkcprB9f3gJc19g6iW2rn09n2w8=", "dev": true }, "is-observable": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/is-observable/-/is-observable-1.1.0.tgz", "integrity": "sha512-NqCa4Sa2d+u7BWc6CukaObG3Fh+CU9bvixbpcXYhy2VvYS7vVGIdAgnIS5Ks3A/cqk4rebLJ9s8zBstT2aKnIA==", "dev": true, "requires": { "symbol-observable": "^1.1.0" } }, "is-path-cwd": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/is-path-cwd/-/is-path-cwd-2.2.0.tgz", "integrity": "sha512-w942bTcih8fdJPJmQHFzkS76NEP8Kzzvmw92cXsazb8intwLqPibPPdXf4ANdKV3rYMuuQYGIWtvz9JilB3NFQ==", "dev": true }, "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-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" }, "dependencies": { "isobject": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", "dev": true } } }, "is-posix-bracket": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/is-posix-bracket/-/is-posix-bracket-0.1.1.tgz", "integrity": "sha1-MzTceXdDaOkvAW5vvAqI9c1ua8Q=", "dev": true }, "is-primitive": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/is-primitive/-/is-primitive-2.0.0.tgz", "integrity": "sha1-IHurkWOEmcB7Kt8kCkGochADRXU=", "dev": true }, "is-promise": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-2.1.0.tgz", "integrity": "sha1-eaKp7OfwlugPNtKy87wWwf9L8/o=", "dev": true }, "is-regexp": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-regexp/-/is-regexp-1.0.0.tgz", "integrity": "sha1-/S2INUXEa6xaYz57mgnof6LLUGk=", "dev": true }, "is-relative": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-relative/-/is-relative-1.0.0.tgz", "integrity": "sha512-Kw/ReK0iqwKeu0MITLFuj0jbPAmEiOsIwyIXvvbfa6QfmN9pkD1M+8pdk7Rl/dTKbH34/XBFMbgD4iMJhLQbGA==", "dev": true, "requires": { "is-unc-path": "^1.0.0" } }, "is-stream": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=", "dev": true }, "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-unc-path": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-unc-path/-/is-unc-path-1.0.0.tgz", "integrity": "sha512-mrGpVd0fs7WWLfVsStvgF6iEJnbjDFZh9/emhRDcGWTduTfNHd9CHeUwH3gYIjdbwo4On6hunkztwOaAw0yllQ==", "dev": true, "requires": { "unc-path-regex": "^0.1.2" } }, "is-utf8": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/is-utf8/-/is-utf8-0.2.1.tgz", "integrity": "sha1-Sw2hRCEE0bM2NA6AeX6GXPOffXI=", "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 }, "isarray": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", "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": "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" } }, "isstream": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=", "dev": true }, "istanbul-lib-coverage": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.5.tgz", "integrity": "sha512-8aXznuEPCJvGnMSRft4udDRDtb1V3pkQkMMI5LI+6HuQz5oQ4J2UFn1H82raA3qJtyOLkkwVqICBQkjnGtn5mA==", "dev": true }, "istanbul-lib-hook": { "version": "2.0.7", "resolved": "https://registry.npmjs.org/istanbul-lib-hook/-/istanbul-lib-hook-2.0.7.tgz", "integrity": "sha512-vrRztU9VRRFDyC+aklfLoeXyNdTfga2EI3udDGn4cZ6fpSXpHLV9X6CHvfoMCPtggg8zvDDmC4b9xfu0z6/llA==", "dev": true, "requires": { "append-transform": "^1.0.0" } }, "istanbul-lib-instrument": { "version": "3.3.0", "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-3.3.0.tgz", "integrity": "sha512-5nnIN4vo5xQZHdXno/YDXJ0G+I3dAm4XgzfSVTPLQpj/zAV2dV6Juy0yaf10/zrJOJeHoN3fraFe+XRq2bFVZA==", "dev": true, "requires": { "@babel/generator": "^7.4.0", "@babel/parser": "^7.4.3", "@babel/template": "^7.4.0", "@babel/traverse": "^7.4.3", "@babel/types": "^7.4.0", "istanbul-lib-coverage": "^2.0.5", "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 } } }, "istanbul-lib-report": { "version": "2.0.8", "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-2.0.8.tgz", "integrity": "sha512-fHBeG573EIihhAblwgxrSenp0Dby6tJMFR/HvlerBsrCTD5bkUuoNtn3gVh29ZCS824cGGBPn7Sg7cNk+2xUsQ==", "dev": true, "requires": { "istanbul-lib-coverage": "^2.0.5", "make-dir": "^2.1.0", "supports-color": "^6.1.0" }, "dependencies": { "supports-color": { "version": "6.1.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz", "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==", "dev": true, "requires": { "has-flag": "^3.0.0" } } } }, "istanbul-lib-source-maps": { "version": "3.0.6", "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-3.0.6.tgz", "integrity": "sha512-R47KzMtDJH6X4/YW9XTx+jrLnZnscW4VpNN+1PViSYTejLVPWv7oov+Duf8YQSPyVRUvueQqz1TcsC6mooZTXw==", "dev": true, "requires": { "debug": "^4.1.1", "istanbul-lib-coverage": "^2.0.5", "make-dir": "^2.1.0", "rimraf": "^2.6.3", "source-map": "^0.6.1" }, "dependencies": { "debug": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", "dev": true, "requires": { "ms": "^2.1.1" } } } }, "istanbul-reports": { "version": "2.2.7", "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-2.2.7.tgz", "integrity": "sha512-uu1F/L1o5Y6LzPVSVZXNOoD/KXpJue9aeLRd0sM9uMXfZvzomB0WxVamWb5ue8kA2vVWEmW7EG+A5n3f1kqHKg==", "dev": true, "requires": { "html-escaper": "^2.0.0" } }, "jison": { "version": "0.3.12", "resolved": "https://registry.npmjs.org/jison/-/jison-0.3.12.tgz", "integrity": "sha1-IN1EjuvCxWneJdDBMGL34adzNaI=", "dev": true, "requires": { "JSONSelect": "0.4.0", "nomnom": "0.4.3", "reflect": "0.0.7" } }, "jmespath": { "version": "0.15.0", "resolved": "https://registry.npmjs.org/jmespath/-/jmespath-0.15.0.tgz", "integrity": "sha1-o/Iiqarp+Wb10nx5ZRDigJF2Qhc=", "dev": true }, "js-tokens": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-1.0.1.tgz", "integrity": "sha1-zENaXIuUrRWst5gxQPyAGCyJrq4=", "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" }, "dependencies": { "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 } } }, "jsbn": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=", "dev": true }, "jsesc": { "version": "0.5.0", "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-0.5.0.tgz", "integrity": "sha1-597mbjXW/Bb3EP6R1c9p9w8IkR0=", "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-schema": { "version": "0.2.3", "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz", "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=", "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 }, "json-stringify-safe": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=", "dev": true }, "json3": { "version": "3.3.3", "resolved": "https://registry.npmjs.org/json3/-/json3-3.3.3.tgz", "integrity": "sha512-c7/8mbUsKigAbLkD5B010BK4D9LZm7A1pNItkEwiUZRpIN66exu/e7YQWysGun+TRKaJp8MhemM+VkfWv42aCA==", "dev": true }, "json5": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/json5/-/json5-0.4.0.tgz", "integrity": "sha1-BUNS5MTIDIbAkjh31EneF2pzLI0=", "dev": true }, "jsonfile": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", "integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=", "dev": true, "requires": { "graceful-fs": "^4.1.6" } }, "jsprim": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz", "integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=", "dev": true, "requires": { "assert-plus": "1.0.0", "extsprintf": "1.3.0", "json-schema": "0.2.3", "verror": "1.10.0" } }, "just-extend": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/just-extend/-/just-extend-4.1.0.tgz", "integrity": "sha512-ApcjaOdVTJ7y4r08xI5wIqpvwS48Q0PBG4DJROcEkH1f8MdAiNFyFxz3xoL0LWAVwjrwPYZdVHHxhRHcx/uGLA==", "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" } }, "lazy-cache": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/lazy-cache/-/lazy-cache-1.0.4.tgz", "integrity": "sha1-odePw6UEdMuAhF07O24dpJpEbo4=", "dev": true }, "lcid": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/lcid/-/lcid-1.0.0.tgz", "integrity": "sha1-MIrMr6C8SDo4Z7S28rlQYlHRuDU=", "dev": true, "requires": { "invert-kv": "^1.0.0" } }, "leven": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/leven/-/leven-1.0.2.tgz", "integrity": "sha1-kUS27ryl8dBoAWnxpncNzqYLdcM=", "dev": true }, "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" } }, "liftoff": { "version": "2.5.0", "resolved": "https://registry.npmjs.org/liftoff/-/liftoff-2.5.0.tgz", "integrity": "sha1-IAkpG7Mc6oYbvxCnwVooyvdcMew=", "dev": true, "requires": { "extend": "^3.0.0", "findup-sync": "^2.0.0", "fined": "^1.0.1", "flagged-respawn": "^1.0.0", "is-plain-object": "^2.0.4", "object.map": "^1.0.0", "rechoir": "^0.6.2", "resolve": "^1.1.7" }, "dependencies": { "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 }, "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 }, "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" } } } }, "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" } }, "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": { "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" } }, "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": { "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-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": { "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-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" } }, "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 } } }, "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" } } } }, "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" } } } }, "findup-sync": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/findup-sync/-/findup-sync-2.0.0.tgz", "integrity": "sha1-kyaxSIwi0aYIhlCoaQGy2akKLLw=", "dev": true, "requires": { "detect-file": "^1.0.0", "is-glob": "^3.1.0", "micromatch": "^3.0.4", "resolve-dir": "^1.0.1" } }, "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" } }, "is-extglob": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", "dev": true }, "is-glob": { "version": "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" } }, "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" } } } }, "isobject": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", "dev": true }, "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 }, "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" } }, "ms": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", "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 }, "lint-staged": { "version": "9.5.0", "resolved": "https://registry.npmjs.org/lint-staged/-/lint-staged-9.5.0.tgz", "integrity": "sha512-nawMob9cb/G1J98nb8v3VC/E8rcX1rryUYXVZ69aT9kde6YWX+uvNOEHY5yf2gcWcTJGiD0kqXmCnS3oD75GIA==", "dev": true, "requires": { "chalk": "^2.4.2", "commander": "^2.20.0", "cosmiconfig": "^5.2.1", "debug": "^4.1.1", "dedent": "^0.7.0", "del": "^5.0.0", "execa": "^2.0.3", "listr": "^0.14.3", "log-symbols": "^3.0.0", "micromatch": "^4.0.2", "normalize-path": "^3.0.0", "please-upgrade-node": "^3.1.1", "string-argv": "^0.3.0", "stringify-object": "^3.3.0" }, "dependencies": { "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" } }, "cross-spawn": { "version": "7.0.1", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.1.tgz", "integrity": "sha512-u7v4o84SwFpD32Z8IIcPZ6z1/ie24O6RU3RbtL5Y316l3KuHVPx9ItBgWQ6VlfAFnRnTtMUrsQ9MUUTuEZjogg==", "dev": true, "requires": { "path-key": "^3.1.0", "shebang-command": "^2.0.0", "which": "^2.0.1" } }, "debug": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", "dev": true, "requires": { "ms": "^2.1.1" } }, "execa": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/execa/-/execa-2.1.0.tgz", "integrity": "sha512-Y/URAVapfbYy2Xp/gb6A0E7iR8xeqOCXsuuaoMn7A5PzrXUK84E1gyiEfq0wQd/GHA6GsoHWwhNq8anb0mleIw==", "dev": true, "requires": { "cross-spawn": "^7.0.0", "get-stream": "^5.0.0", "is-stream": "^2.0.0", "merge-stream": "^2.0.0", "npm-run-path": "^3.0.0", "onetime": "^5.1.0", "p-finally": "^2.0.0", "signal-exit": "^3.0.2", "strip-final-newline": "^2.0.0" } }, "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" } }, "get-stream": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.1.0.tgz", "integrity": "sha512-EXr1FOzrzTfGeL0gQdeFEvOMm2mzMOglyiOXSTpPC+iAjAKftbr3jpCMWynogwYnM+eSj9sHGc6wjIcDvYiygw==", "dev": true, "requires": { "pump": "^3.0.0" } }, "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-stream": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.0.tgz", "integrity": "sha512-XCoy+WlUr7d1+Z8GgSuXmpuUFC9fOhRXglJMx+dwLKTkL44Cjd4W1Z5P+BQZpr+cR93aGP4S/s7Ftw6Nd/kiEw==", "dev": true }, "micromatch": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.2.tgz", "integrity": "sha512-y7FpHSbMUMoyPbYUSzO6PaZ6FyRnQOpHuKwbo1G+Knck95XVU4QAiKdGEnj5wwoS7PlOgthX/09u5iFJ+aYf5Q==", "dev": true, "requires": { "braces": "^3.0.1", "picomatch": "^2.0.5" } }, "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 }, "npm-run-path": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-3.1.0.tgz", "integrity": "sha512-Dbl4A/VfiVGLgQv29URL9xshU8XDY1GeLy+fsaZ1AA8JDSfjvr5P5+pzRbWqRSBxk6/DW7MIh8lTM/PaGnP2kg==", "dev": true, "requires": { "path-key": "^3.0.0" } }, "p-finally": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-2.0.1.tgz", "integrity": "sha512-vpm09aKwq6H9phqRQzecoDpD8TmVyGw70qmWlyq5onxY7tqyTTFVvxMykxQSQKILBSFlbXpypIw2T1Ml7+DDtw==", "dev": true }, "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 }, "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" } }, "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" } } } }, "listr": { "version": "0.14.3", "resolved": "https://registry.npmjs.org/listr/-/listr-0.14.3.tgz", "integrity": "sha512-RmAl7su35BFd/xoMamRjpIE4j3v+L28o8CT5YhAXQJm1fD+1l9ngXY8JAQRJ+tFK2i5njvi0iRUKV09vPwA0iA==", "dev": true, "requires": { "@samverschueren/stream-to-observable": "^0.3.0", "is-observable": "^1.1.0", "is-promise": "^2.1.0", "is-stream": "^1.1.0", "listr-silent-renderer": "^1.1.1", "listr-update-renderer": "^0.5.0", "listr-verbose-renderer": "^0.5.0", "p-map": "^2.0.0", "rxjs": "^6.3.3" }, "dependencies": { "p-map": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/p-map/-/p-map-2.1.0.tgz", "integrity": "sha512-y3b8Kpd8OAN444hxfBbFfj1FY/RjtTd8tzYwhUqNYXx0fXx2iX4maP4Qr6qhIKbQXI02wTLAda4fYUbDagTUFw==", "dev": true } } }, "listr-silent-renderer": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/listr-silent-renderer/-/listr-silent-renderer-1.1.1.tgz", "integrity": "sha1-kktaN1cVN3C/Go4/v3S4u/P5JC4=", "dev": true }, "listr-update-renderer": { "version": "0.5.0", "resolved": "https://registry.npmjs.org/listr-update-renderer/-/listr-update-renderer-0.5.0.tgz", "integrity": "sha512-tKRsZpKz8GSGqoI/+caPmfrypiaq+OQCbd+CovEC24uk1h952lVj5sC7SqyFUm+OaJ5HN/a1YLt5cit2FMNsFA==", "dev": true, "requires": { "chalk": "^1.1.3", "cli-truncate": "^0.2.1", "elegant-spinner": "^1.0.1", "figures": "^1.7.0", "indent-string": "^3.0.0", "log-symbols": "^1.0.2", "log-update": "^2.3.0", "strip-ansi": "^3.0.1" }, "dependencies": { "ansi-regex": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", "dev": true }, "ansi-styles": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", "dev": true }, "chalk": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", "dev": true, "requires": { "ansi-styles": "^2.2.1", "escape-string-regexp": "^1.0.2", "has-ansi": "^2.0.0", "strip-ansi": "^3.0.0", "supports-color": "^2.0.0" } }, "figures": { "version": "1.7.0", "resolved": "https://registry.npmjs.org/figures/-/figures-1.7.0.tgz", "integrity": "sha1-y+Hjr/zxzUS4DK3+0o3Hk6lwHS4=", "dev": true, "requires": { "escape-string-regexp": "^1.0.5", "object-assign": "^4.1.0" } }, "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 }, "log-symbols": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-1.0.2.tgz", "integrity": "sha1-N2/3tY6jCGoPCfrMdGF+ylAeGhg=", "dev": true, "requires": { "chalk": "^1.0.0" } }, "object-assign": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", "dev": true }, "strip-ansi": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", "dev": true, "requires": { "ansi-regex": "^2.0.0" } }, "supports-color": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", "dev": true } } }, "listr-verbose-renderer": { "version": "0.5.0", "resolved": "https://registry.npmjs.org/listr-verbose-renderer/-/listr-verbose-renderer-0.5.0.tgz", "integrity": "sha512-04PDPqSlsqIOaaaGZ+41vq5FejI9auqTInicFRndCBgE3bXG8D6W1I+mWhk+1nqbHmyhla/6BUrd5OSiHwKRXw==", "dev": true, "requires": { "chalk": "^2.4.1", "cli-cursor": "^2.1.0", "date-fns": "^1.27.2", "figures": "^2.0.0" }, "dependencies": { "cli-cursor": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-2.1.0.tgz", "integrity": "sha1-s12sN2R5+sw+lHR9QdDQ9SOP/LU=", "dev": true, "requires": { "restore-cursor": "^2.0.0" } }, "date-fns": { "version": "1.30.1", "resolved": "https://registry.npmjs.org/date-fns/-/date-fns-1.30.1.tgz", "integrity": "sha512-hBSVCvSmWC+QypYObzwGOd9wqdDpOt+0wl0KbU+R+uuZBS1jN8VsD1ss3irQDknRj5NvxiTF6oj/nDRnN/UQNw==", "dev": true }, "figures": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/figures/-/figures-2.0.0.tgz", "integrity": "sha1-OrGi0qYsi/tDGgyUy3l6L84nyWI=", "dev": true, "requires": { "escape-string-regexp": "^1.0.5" } }, "mimic-fn": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-1.2.0.tgz", "integrity": "sha512-jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ==", "dev": true }, "onetime": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/onetime/-/onetime-2.0.1.tgz", "integrity": "sha1-BnQoIw/WdEOyeUsiu6UotoZ5YtQ=", "dev": true, "requires": { "mimic-fn": "^1.0.0" } }, "restore-cursor": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-2.0.0.tgz", "integrity": "sha1-n37ih/gv0ybU/RYpI9YhKe7g368=", "dev": true, "requires": { "onetime": "^2.0.0", "signal-exit": "^3.0.2" } } } }, "livereload-js": { "version": "2.4.0", "resolved": "https://registry.npmjs.org/livereload-js/-/livereload-js-2.4.0.tgz", "integrity": "sha512-XPQH8Z2GDP/Hwz2PCDrh2mth4yFejwA1OZ/81Ti3LgKyhDcEjsSsqFWZojHG0va/duGd+WyosY7eXLDoOyqcPw==", "dev": true }, "load-json-file": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-1.1.0.tgz", "integrity": "sha1-lWkFcI1YtLq0wiYbBPWfMcmTdMA=", "dev": true, "requires": { "graceful-fs": "^4.1.2", "parse-json": "^2.2.0", "pify": "^2.0.0", "pinkie-promise": "^2.0.0", "strip-bom": "^2.0.0" }, "dependencies": { "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" } }, "pify": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", "dev": true } } }, "loader-utils": { "version": "0.2.17", "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-0.2.17.tgz", "integrity": "sha1-+G5jdNQyBabmxg6RlvF8Apm/s0g=", "dev": true, "requires": { "big.js": "^3.1.3", "emojis-list": "^2.0.0", "json5": "^0.5.0", "object-assign": "^4.0.1" }, "dependencies": { "json5": { "version": "0.5.1", "resolved": "https://registry.npmjs.org/json5/-/json5-0.5.1.tgz", "integrity": "sha1-Hq3nrMASA0rYTiOWdn6tn6VJWCE=", "dev": true }, "object-assign": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", "dev": true } } }, "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" } }, "lodash": { "version": "4.17.15", "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz", "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==", "dev": true }, "lodash.flattendeep": { "version": "4.4.0", "resolved": "https://registry.npmjs.org/lodash.flattendeep/-/lodash.flattendeep-4.4.0.tgz", "integrity": "sha1-+wMJF/hqMTTlvJvsDWngAT3f7bI=", "dev": true }, "lodash.memoize": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz", "integrity": "sha1-vMbEmkKihA7Zl/Mj6tpezRguC/4=", "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" } }, "log-update": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/log-update/-/log-update-2.3.0.tgz", "integrity": "sha1-iDKP19HOeTiykoN0bwsbwSayRwg=", "dev": true, "requires": { "ansi-escapes": "^3.0.0", "cli-cursor": "^2.0.0", "wrap-ansi": "^3.0.1" }, "dependencies": { "ansi-escapes": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-3.2.0.tgz", "integrity": "sha512-cBhpre4ma+U0T1oM5fXg7Dy1Jw7zzwv7lt/GoCpr+hDQJoYnKVPLL4dCvSEFMmQurOQvSrwT7SL/DAlhBI97RQ==", "dev": true }, "ansi-regex": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", "dev": true }, "cli-cursor": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-2.1.0.tgz", "integrity": "sha1-s12sN2R5+sw+lHR9QdDQ9SOP/LU=", "dev": true, "requires": { "restore-cursor": "^2.0.0" } }, "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 }, "mimic-fn": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-1.2.0.tgz", "integrity": "sha512-jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ==", "dev": true }, "onetime": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/onetime/-/onetime-2.0.1.tgz", "integrity": "sha1-BnQoIw/WdEOyeUsiu6UotoZ5YtQ=", "dev": true, "requires": { "mimic-fn": "^1.0.0" } }, "restore-cursor": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-2.0.0.tgz", "integrity": "sha1-n37ih/gv0ybU/RYpI9YhKe7g368=", "dev": true, "requires": { "onetime": "^2.0.0", "signal-exit": "^3.0.2" } }, "string-width": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", "dev": true, "requires": { "is-fullwidth-code-point": "^2.0.0", "strip-ansi": "^4.0.0" } }, "strip-ansi": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", "dev": true, "requires": { "ansi-regex": "^3.0.0" } }, "wrap-ansi": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-3.0.1.tgz", "integrity": "sha1-KIoE2H7aXChuBg3+jxNc6NAH+Lo=", "dev": true, "requires": { "string-width": "^2.1.1", "strip-ansi": "^4.0.0" } } } }, "lolex": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/lolex/-/lolex-4.2.0.tgz", "integrity": "sha512-gKO5uExCXvSm6zbF562EvM+rd1kQDnB9AZBbiQVzf1ZmdDpxUSvpnAaVOP83N/31mRK8Ml8/VE8DMvsAZQ+7wg==", "dev": true }, "longest": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/longest/-/longest-1.0.1.tgz", "integrity": "sha1-MKCy2jj3N3DoKUoNIuZiXtd9AJc=", "dev": true }, "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" } }, "lru-cache": { "version": "4.1.5", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.5.tgz", "integrity": "sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==", "dev": true, "requires": { "pseudomap": "^1.0.2", "yallist": "^2.1.2" } }, "make-dir": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-2.1.0.tgz", "integrity": "sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==", "dev": true, "requires": { "pify": "^4.0.1", "semver": "^5.6.0" }, "dependencies": { "pify": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", "dev": true } } }, "make-iterator": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/make-iterator/-/make-iterator-1.0.1.tgz", "integrity": "sha512-pxiuXh0iVEq7VM7KMIhs5gxsfxCux2URptUQaXo4iZZJxBAzTPOLE2BumO5dbfVYq/hBJFBR/a1mFDmOx5AGmw==", "dev": true, "requires": { "kind-of": "^6.0.2" }, "dependencies": { "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 } } }, "map-age-cleaner": { "version": "0.1.3", "resolved": "https://registry.npmjs.org/map-age-cleaner/-/map-age-cleaner-0.1.3.tgz", "integrity": "sha512-bJzx6nMoP6PDLPBFmg7+xRKeFZvFboMrGlxmNj9ClvX53KrmvM5bXFXEWjbz4cz1AFn+jWJ9z/DJSz7hrs0w3w==", "dev": true, "requires": { "p-defer": "^1.0.0" } }, "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": "1.0.1", "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-1.0.1.tgz", "integrity": "sha1-2TPOuSBdgr3PSIb2dCvcK03qFG0=", "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" } }, "math-random": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/math-random/-/math-random-1.0.4.tgz", "integrity": "sha512-rUxjysqif/BZQH2yhd5Aaq7vXMSx9NdEsQcyA07uEzIvxgI7zIr33gGsh+RU0/XjmQpCW7RsVof1vlkvQVCK5A==", "dev": true }, "maxmin": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/maxmin/-/maxmin-1.1.0.tgz", "integrity": "sha1-cTZehKmd2Piz99X94vANHn9zvmE=", "dev": true, "requires": { "chalk": "^1.0.0", "figures": "^1.0.1", "gzip-size": "^1.0.0", "pretty-bytes": "^1.0.0" }, "dependencies": { "ansi-regex": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", "dev": true }, "ansi-styles": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", "dev": true }, "chalk": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", "dev": true, "requires": { "ansi-styles": "^2.2.1", "escape-string-regexp": "^1.0.2", "has-ansi": "^2.0.0", "strip-ansi": "^3.0.0", "supports-color": "^2.0.0" } }, "figures": { "version": "1.7.0", "resolved": "https://registry.npmjs.org/figures/-/figures-1.7.0.tgz", "integrity": "sha1-y+Hjr/zxzUS4DK3+0o3Hk6lwHS4=", "dev": true, "requires": { "escape-string-regexp": "^1.0.5", "object-assign": "^4.1.0" } }, "object-assign": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", "dev": true }, "strip-ansi": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", "dev": true, "requires": { "ansi-regex": "^2.0.0" } }, "supports-color": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", "dev": true } } }, "mdn-browser-compat-data": { "version": "1.0.12", "resolved": "https://registry.npmjs.org/mdn-browser-compat-data/-/mdn-browser-compat-data-1.0.12.tgz", "integrity": "sha512-YykSFfz779LbgRjyieBMQy9/VHFAIz52gf7bLOiJnCkp0xltpnC9l2kQGu4UWOkBeSxJ1R5YLcKTf4Gklq6clQ==", "dev": true, "requires": { "extend": "3.0.2" } }, "media-typer": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=", "dev": true }, "mem": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/mem/-/mem-4.3.0.tgz", "integrity": "sha512-qX2bG48pTqYRVmDB37rn/6PT7LcR8T7oAX3bf99u1Tt1nzxYfxkgqDwUwolPlXweM0XzBOBFzSx4kfp7KP1s/w==", "dev": true, "requires": { "map-age-cleaner": "^0.1.1", "mimic-fn": "^2.0.0", "p-is-promise": "^2.0.0" } }, "memory-fs": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/memory-fs/-/memory-fs-0.3.0.tgz", "integrity": "sha1-e8xrYp46Q+hx1+Kaymrop/FcuyA=", "dev": true, "requires": { "errno": "^0.1.3", "readable-stream": "^2.0.1" } }, "meow": { "version": "3.7.0", "resolved": "https://registry.npmjs.org/meow/-/meow-3.7.0.tgz", "integrity": "sha1-cstmi0JSKCkKu/qFaJJYcwioAfs=", "dev": true, "requires": { "camelcase-keys": "^2.0.0", "decamelize": "^1.1.2", "loud-rejection": "^1.0.0", "map-obj": "^1.0.1", "minimist": "^1.1.3", "normalize-package-data": "^2.3.4", "object-assign": "^4.0.1", "read-pkg-up": "^1.0.1", "redent": "^1.0.0", "trim-newlines": "^1.0.0" }, "dependencies": { "object-assign": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", "dev": true } } }, "merge-descriptors": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", "integrity": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E=", "dev": true }, "merge-source-map": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/merge-source-map/-/merge-source-map-1.1.0.tgz", "integrity": "sha512-Qkcp7P2ygktpMPh2mCQZaf3jhN6D3Z/qVZHSdWvQ+2Ef5HgRAPBO57A77+ENm0CPx2+1Ce/MYKi3ymqdfuqibw==", "dev": true, "requires": { "source-map": "^0.6.1" } }, "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.3.0", "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.3.0.tgz", "integrity": "sha512-2j4DAdlBOkiSZIsaXk4mTE3sRS02yBHAtfy127xRV3bQUFqXkjHCHLW6Scv7DwNRbIWNHH8zpnz9zMaKXIdvYw==", "dev": true }, "methods": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", "integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4=", "dev": true }, "micromatch": { "version": "2.3.11", "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-2.3.11.tgz", "integrity": "sha1-hmd8l9FyCzY0MdBNDRUpO9OMFWU=", "dev": true, "requires": { "arr-diff": "^2.0.0", "array-unique": "^0.2.1", "braces": "^1.8.2", "expand-brackets": "^0.1.4", "extglob": "^0.3.1", "filename-regex": "^2.0.0", "is-extglob": "^1.0.0", "is-glob": "^2.0.1", "kind-of": "^3.0.2", "normalize-path": "^2.0.1", "object.omit": "^2.0.0", "parse-glob": "^3.0.4", "regex-cache": "^0.4.2" } }, "mime": { "version": "1.6.0", "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", "dev": true }, "mime-db": { "version": "1.43.0", "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.43.0.tgz", "integrity": "sha512-+5dsGEEovYbT8UY9yD7eE4XTc4UwJ1jBYlgaQQF38ENsKR3wj/8q8RFZrF9WIZpB2V1ArTVFUva8sAul1NzRzQ==", "dev": true }, "mime-types": { "version": "2.1.26", "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.26.tgz", "integrity": "sha512-01paPWYgLrkqAyrlDorC1uDwl2p3qZT7yl806vW7DvDoxwXi46jsjFbg+WdwotBIk6/MbEhO/dh5aZ5sNj/dWQ==", "dev": true, "requires": { "mime-db": "1.43.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 }, "minimatch": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", "dev": true, "requires": { "brace-expansion": "^1.1.7" } }, "minimist": { "version": "1.2.5", "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==" }, "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.3", "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.3.tgz", "integrity": "sha512-P+2gwrFqx8lhew375MQHHeTlY8AuOJSrGf0R5ddkEndUkmwpgUob/vQuBD1V22/Cw1/lJr4x+EjllSezBThzBg==", "dev": true, "requires": { "minimist": "^1.2.5" } }, "mocha": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/mocha/-/mocha-5.2.0.tgz", "integrity": "sha512-2IUgKDhc3J7Uug+FxMXuqIyYzH7gJjXECKe/w43IGgQHTSj3InJi+yAA7T24L9bQMRKiUEHxEX37G5JpVUGLcQ==", "dev": true, "requires": { "browser-stdout": "1.3.1", "commander": "2.15.1", "debug": "3.1.0", "diff": "3.5.0", "escape-string-regexp": "1.0.5", "glob": "7.1.2", "growl": "1.10.5", "he": "1.1.1", "minimatch": "3.0.4", "mkdirp": "0.5.1", "supports-color": "5.4.0" }, "dependencies": { "commander": { "version": "2.15.1", "resolved": "https://registry.npmjs.org/commander/-/commander-2.15.1.tgz", "integrity": "sha512-VlfT9F3V0v+jr4yxPc5gg9s62/fIVWsd2Bk2iD435um1NlGMYdVCq+MjcXnhYq2icNOizHr1kK+5TI6H0Hy0ag==", "dev": true }, "debug": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", "dev": true, "requires": { "ms": "2.0.0" } }, "diff": { "version": "3.5.0", "resolved": "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz", "integrity": "sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==", "dev": true }, "glob": { "version": "7.1.2", "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz", "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==", "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" } }, "minimatch": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", "dev": true, "requires": { "brace-expansion": "^1.1.7" } }, "minimist": { "version": "0.0.8", "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=", "dev": true }, "mkdirp": { "version": "0.5.1", "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", "dev": true, "requires": { "minimist": "0.0.8" } }, "ms": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", "dev": true }, "supports-color": { "version": "5.4.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.4.0.tgz", "integrity": "sha512-zjaXglF5nnWpsq470jSv6P9DwPvgLkuapYmfDm3JWOm0vkNTVF2tI4UrN2r6jH1qM/uc/WtxYY1hYoA2dOKj5w==", "dev": true, "requires": { "has-flag": "^3.0.0" } } } }, "mock-stdin": { "version": "0.3.1", "resolved": "https://registry.npmjs.org/mock-stdin/-/mock-stdin-0.3.1.tgz", "integrity": "sha1-xlfZZC2QeGQ1xkyl6Zu9TQm9fdM=", "dev": true }, "morgan": { "version": "1.9.1", "resolved": "https://registry.npmjs.org/morgan/-/morgan-1.9.1.tgz", "integrity": "sha512-HQStPIV4y3afTiCYVxirakhlCfGkI161c76kKFca7Fk1JusM//Qeo1ej2XaMniiNeaZklMVrh3vTtIzpzwbpmA==", "dev": true, "requires": { "basic-auth": "~2.0.0", "debug": "2.6.9", "depd": "~1.1.2", "on-finished": "~2.3.0", "on-headers": "~1.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" } }, "ms": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", "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 }, "mustache": { "version": "2.3.2", "resolved": "https://registry.npmjs.org/mustache/-/mustache-2.3.2.tgz", "integrity": "sha512-KpMNwdQsYz3O/SBS1qJ/o3sqUJ5wSb8gb0pul8CO0S56b9Y2ALm8zCfsjPXsqGFfoNBkDwZuZIAjhsZI03gYVQ==", "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 }, "nan": { "version": "2.14.2", "resolved": "https://registry.npmjs.org/nan/-/nan-2.14.2.tgz", "integrity": "sha512-M2ufzIiINKCuDfBSAUr1vWQ+vuVcA9kqx8JJUsbQi6yf1uGRyb7HfpdfUr5qLXf3B/t8dPvcjhKMmlfnP47EzQ==", "dev": true, "optional": 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" }, "dependencies": { "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 }, "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 }, "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 } } }, "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 }, "negotiator": { "version": "0.6.2", "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.2.tgz", "integrity": "sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw==", "dev": true }, "neo-async": { "version": "2.6.1", "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.1.tgz", "integrity": "sha512-iyam8fBuCUpWeKPGpaNMetEocMt364qkCsfL9JuhjXX6dRnguRVOfk2GZaDpPjcOKiiXCPINZC1GczQ7iTq3Zw==" }, "nested-error-stacks": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/nested-error-stacks/-/nested-error-stacks-2.1.0.tgz", "integrity": "sha512-AO81vsIO1k1sM4Zrd6Hu7regmJN1NSiAja10gc4bX3F0wd+9rQmcuHQaHVQCYIEC8iFXnE+mavh23GOt7wBgug==", "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": "1.5.3", "resolved": "https://registry.npmjs.org/nise/-/nise-1.5.3.tgz", "integrity": "sha512-Ymbac/94xeIrMf59REBPOv0thr+CJVFMhrlAkW/gjCIE58BGQdCj0x7KRCb3yz+Ga2Rz3E9XXSvUyyxqqhjQAQ==", "dev": true, "requires": { "@sinonjs/formatio": "^3.2.1", "@sinonjs/text-encoding": "^0.7.1", "just-extend": "^4.0.2", "lolex": "^5.0.1", "path-to-regexp": "^1.7.0" }, "dependencies": { "lolex": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/lolex/-/lolex-5.1.2.tgz", "integrity": "sha512-h4hmjAvHTmd+25JSwrtTIuwbKdwg5NzZVRMLn9saij4SZaepCrTCxPr35H/3bjwfMJtN+t3CX8672UIkglz28A==", "dev": true, "requires": { "@sinonjs/commons": "^1.7.0" } } } }, "node-libs-browser": { "version": "0.7.0", "resolved": "https://registry.npmjs.org/node-libs-browser/-/node-libs-browser-0.7.0.tgz", "integrity": "sha1-PicsCBnjCJNeJmdECNevDhSRuDs=", "dev": true, "requires": { "assert": "^1.1.1", "browserify-zlib": "^0.1.4", "buffer": "^4.9.0", "console-browserify": "^1.1.0", "constants-browserify": "^1.0.0", "crypto-browserify": "3.3.0", "domain-browser": "^1.1.1", "events": "^1.0.0", "https-browserify": "0.0.1", "os-browserify": "^0.2.0", "path-browserify": "0.0.0", "process": "^0.11.0", "punycode": "^1.2.4", "querystring-es3": "^0.2.0", "readable-stream": "^2.0.5", "stream-browserify": "^2.0.1", "stream-http": "^2.3.1", "string_decoder": "^0.10.25", "timers-browserify": "^2.0.2", "tty-browserify": "0.0.0", "url": "^0.11.0", "util": "^0.10.3", "vm-browserify": "0.0.4" }, "dependencies": { "punycode": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=", "dev": true }, "string_decoder": { "version": "0.10.31", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=", "dev": true }, "url": { "version": "0.11.0", "resolved": "https://registry.npmjs.org/url/-/url-0.11.0.tgz", "integrity": "sha1-ODjpfPxgUh63PFJajlW/3Z4uKPE=", "dev": true, "requires": { "punycode": "1.3.2", "querystring": "0.2.0" }, "dependencies": { "punycode": { "version": "1.3.2", "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.3.2.tgz", "integrity": "sha1-llOgNvt8HuQjQvIyXM7v6jkmxI0=", "dev": true } } } } }, "node-releases": { "version": "1.1.52", "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.52.tgz", "integrity": "sha512-snSiT1UypkgGt2wxPqS6ImEUICbNCMb31yaxWrOLXjhlt2z2/IBpaOxzONExqSm4y5oLnAqjjRWu+wsDzK5yNQ==", "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 } } }, "nomnom": { "version": "0.4.3", "resolved": "https://registry.npmjs.org/nomnom/-/nomnom-0.4.3.tgz", "integrity": "sha1-bC2xJH3v9vZ1fjVyASOPB9lxhOM=", "dev": true, "requires": { "underscore": ">= 1.1.5" } }, "nopt": { "version": "3.0.6", "resolved": "https://registry.npmjs.org/nopt/-/nopt-3.0.6.tgz", "integrity": "sha1-xkZdvwirzU2zWTF/eaxopkayj/k=", "dev": true, "requires": { "abbrev": "1" } }, "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": "2.1.1", "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", "dev": true, "requires": { "remove-trailing-separator": "^1.0.1" } }, "npm-run-path": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz", "integrity": "sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8=", "dev": true, "requires": { "path-key": "^2.0.0" } }, "number-is-nan": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=", "dev": true }, "nyc": { "version": "14.1.1", "resolved": "https://registry.npmjs.org/nyc/-/nyc-14.1.1.tgz", "integrity": "sha512-OI0vm6ZGUnoGZv/tLdZ2esSVzDwUC88SNs+6JoSOMVxA+gKMB8Tk7jBwgemLx4O40lhhvZCVw1C+OYLOBOPXWw==", "dev": true, "requires": { "archy": "^1.0.0", "caching-transform": "^3.0.2", "convert-source-map": "^1.6.0", "cp-file": "^6.2.0", "find-cache-dir": "^2.1.0", "find-up": "^3.0.0", "foreground-child": "^1.5.6", "glob": "^7.1.3", "istanbul-lib-coverage": "^2.0.5", "istanbul-lib-hook": "^2.0.7", "istanbul-lib-instrument": "^3.3.0", "istanbul-lib-report": "^2.0.8", "istanbul-lib-source-maps": "^3.0.6", "istanbul-reports": "^2.2.4", "js-yaml": "^3.13.1", "make-dir": "^2.1.0", "merge-source-map": "^1.1.0", "resolve-from": "^4.0.0", "rimraf": "^2.6.3", "signal-exit": "^3.0.2", "spawn-wrap": "^1.4.2", "test-exclude": "^5.2.3", "uuid": "^3.3.2", "yargs": "^13.2.2", "yargs-parser": "^13.0.0" }, "dependencies": { "ansi-regex": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", "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" } }, "cliui": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz", "integrity": "sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==", "dev": true, "requires": { "string-width": "^3.1.0", "strip-ansi": "^5.2.0", "wrap-ansi": "^5.1.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 }, "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 }, "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" } }, "glob": { "version": "7.1.6", "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", "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" } }, "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 }, "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" } }, "minimatch": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", "dev": true, "requires": { "brace-expansion": "^1.1.7" } }, "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" } }, "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 }, "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" } }, "wrap-ansi": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-5.1.0.tgz", "integrity": "sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q==", "dev": true, "requires": { "ansi-styles": "^3.2.0", "string-width": "^3.0.0", "strip-ansi": "^5.0.0" } }, "yargs": { "version": "13.3.2", "resolved": "https://registry.npmjs.org/yargs/-/yargs-13.3.2.tgz", "integrity": "sha512-AX3Zw5iPruN5ie6xGRIDgqkT+ZhnRlZMLMHAs8tg7nRruy2Nb+i5o9bwghAogtM08q1dpr2LVoS8KSTMYpWXUw==", "dev": true, "requires": { "cliui": "^5.0.0", "find-up": "^3.0.0", "get-caller-file": "^2.0.1", "require-directory": "^2.1.1", "require-main-filename": "^2.0.0", "set-blocking": "^2.0.0", "string-width": "^3.0.0", "which-module": "^2.0.0", "y18n": "^4.0.0", "yargs-parser": "^13.1.2" } }, "yargs-parser": { "version": "13.1.2", "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.1.2.tgz", "integrity": "sha512-3lbsNRf/j+A4QuSZfDRA7HRSfWrzO0YjqTJd5kjAq37Zep1CEgaYmrH9Q3GwPiB9cHyd1Y1UwggGhJGoxipbzg==", "dev": true, "requires": { "camelcase": "^5.0.0", "decamelize": "^1.2.0" } } } }, "oauth-sign": { "version": "0.9.0", "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz", "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==", "dev": true }, "object-assign": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-3.0.0.tgz", "integrity": "sha1-m+3VygiXlJvKR+f/QIBi1Un1h/I=", "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" } } } }, "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" }, "dependencies": { "isobject": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", "dev": true } } }, "object.defaults": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/object.defaults/-/object.defaults-1.1.0.tgz", "integrity": "sha1-On+GgzS0B96gbaFtiNXNKeQ1/s8=", "dev": true, "requires": { "array-each": "^1.0.1", "array-slice": "^1.0.0", "for-own": "^1.0.0", "isobject": "^3.0.0" }, "dependencies": { "for-own": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/for-own/-/for-own-1.0.0.tgz", "integrity": "sha1-xjMy9BXO3EsE2/5wz4NklMU8tEs=", "dev": true, "requires": { "for-in": "^1.0.1" } }, "isobject": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", "dev": true } } }, "object.map": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/object.map/-/object.map-1.0.1.tgz", "integrity": "sha1-z4Plncj8wK1fQlDh94s7gb2AHTc=", "dev": true, "requires": { "for-own": "^1.0.0", "make-iterator": "^1.0.0" }, "dependencies": { "for-own": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/for-own/-/for-own-1.0.0.tgz", "integrity": "sha1-xjMy9BXO3EsE2/5wz4NklMU8tEs=", "dev": true, "requires": { "for-in": "^1.0.1" } } } }, "object.omit": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/object.omit/-/object.omit-2.0.1.tgz", "integrity": "sha1-Gpx0SCnznbuFjHbKNXmuKlTr0fo=", "dev": true, "requires": { "for-own": "^0.1.4", "is-extendable": "^0.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" }, "dependencies": { "isobject": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", "dev": true } } }, "on-finished": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", "integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=", "dev": true, "requires": { "ee-first": "1.1.1" } }, "on-headers": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/on-headers/-/on-headers-1.0.2.tgz", "integrity": "sha512-pZAE+FJLoyITytdqK0U5s+FIpjN0JP3OzFi/u8Rx+EV5/W+JTWGXG8xFzevE7AjBfDqHv/8vL8qQsIhHnqRkrA==", "dev": true }, "once": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", "dev": true, "requires": { "wrappy": "1" } }, "onetime": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.0.tgz", "integrity": "sha512-5NcSkPHhwTVFIQN+TUqXoS5+dlElHXdpAWu9I0HP20YOtIi+aZ0Ct82jdlILDxjLEAWwvm+qj1m6aEtsDVmm6Q==", "dev": true, "requires": { "mimic-fn": "^2.1.0" } }, "open": { "version": "0.0.5", "resolved": "https://registry.npmjs.org/open/-/open-0.0.5.tgz", "integrity": "sha1-QsPhjslUZra/DcQvOilFw/DK2Pw=", "dev": true }, "opencollective-postinstall": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/opencollective-postinstall/-/opencollective-postinstall-2.0.2.tgz", "integrity": "sha512-pVOEP16TrAO2/fjej1IdOyupJY8KDUM1CvsaScRbw6oddvpQoOfGk4ywha0HKKVAD6RkW4x6Q+tNBwhf3Bgpuw==", "dev": true }, "opn": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/opn/-/opn-4.0.2.tgz", "integrity": "sha1-erwi5kTf9jsKltWrfyeQwPAavJU=", "dev": true, "requires": { "object-assign": "^4.0.1", "pinkie-promise": "^2.0.0" }, "dependencies": { "object-assign": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", "dev": true } } }, "optimist": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/optimist/-/optimist-0.6.1.tgz", "integrity": "sha1-2j6nRob6IaGaERwybpDrFaAZZoY=", "dev": true, "requires": { "minimist": "~0.0.1", "wordwrap": "~0.0.2" }, "dependencies": { "minimist": { "version": "0.0.10", "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.10.tgz", "integrity": "sha1-3j+YVD2/lggr5IrRoMfNqDYwHc8=", "dev": true }, "wordwrap": { "version": "0.0.3", "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.3.tgz", "integrity": "sha1-o9XabNXAvAAI03I0u68b7WMFkQc=", "dev": true } } }, "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" } }, "original": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/original/-/original-1.0.2.tgz", "integrity": "sha512-hyBVl6iqqUOJ8FqRe+l/gS8H+kKYjrEndd5Pm1MfBtsEKA038HkkdbAl/72EAXGyonD/PFsvmVG+EvcIpliMBg==", "dev": true, "requires": { "url-parse": "^1.4.3" } }, "os-browserify": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/os-browserify/-/os-browserify-0.2.1.tgz", "integrity": "sha1-Y/xMzuXS13Y9Jrv4YBB45sLgBE8=", "dev": true }, "os-homedir": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz", "integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M=", "dev": true }, "os-locale": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-1.4.0.tgz", "integrity": "sha1-IPnxeuKe00XoveWDsT0gCYA8FNk=", "dev": true, "requires": { "lcid": "^1.0.0" } }, "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 }, "osenv": { "version": "0.1.5", "resolved": "https://registry.npmjs.org/osenv/-/osenv-0.1.5.tgz", "integrity": "sha512-0CWcCECdMVc2Rw3U5w9ZjqX6ga6ubk1xDVKxtBQPK7wis/0F2r9T6k4ydGYhecl7YUBxBVxhL5oisPsNxAPe2g==", "dev": true, "requires": { "os-homedir": "^1.0.0", "os-tmpdir": "^1.0.0" } }, "output-file-sync": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/output-file-sync/-/output-file-sync-1.1.2.tgz", "integrity": "sha1-0KM+7+YaIF+suQCS6CZZjVJFznY=", "dev": true, "requires": { "graceful-fs": "^4.1.4", "mkdirp": "^0.5.1", "object-assign": "^4.1.0" }, "dependencies": { "object-assign": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", "dev": true } } }, "p-defer": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/p-defer/-/p-defer-1.0.0.tgz", "integrity": "sha1-n26xgvbJqozXQwBKfU+WsZaw+ww=", "dev": true }, "p-finally": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=", "dev": true }, "p-is-promise": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/p-is-promise/-/p-is-promise-2.1.0.tgz", "integrity": "sha512-Y3W0wlRPK8ZMRbNq97l4M5otioeA5lm1z7bkNkxCka8HSPjR0xRWmpCmc9utiaLP9Jb1eD8BgeIxTW4AIF45Pg==", "dev": true }, "p-limit": { "version": "2.2.2", "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.2.2.tgz", "integrity": "sha512-WGR+xHecKTr7EbUEhyLSh5Dube9JtdiG78ufaeLxTgpudf/20KqyMioIUZJAezlTIi6evxuoUs9YXc11cU+yzQ==", "dev": true, "requires": { "p-try": "^2.0.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" } }, "p-map": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/p-map/-/p-map-3.0.0.tgz", "integrity": "sha512-d3qXVTF/s+W+CdJ5A29wywV2n8CQQYahlgz2bFiA+4eVNJbHJodPZ+/gXwPGh0bOqA+j8S+6+ckmvLGPk1QpxQ==", "dev": true, "requires": { "aggregate-error": "^3.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-hash": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/package-hash/-/package-hash-3.0.0.tgz", "integrity": "sha512-lOtmukMDVvtkL84rJHI7dpTYq+0rli8N2wlnqUcBuDWCfVhRUfOmnR9SsoHFMLpACvEV60dX7rd0rFaYDZI+FA==", "dev": true, "requires": { "graceful-fs": "^4.1.15", "hasha": "^3.0.0", "lodash.flattendeep": "^4.4.0", "release-zalgo": "^1.0.0" } }, "pako": { "version": "0.2.9", "resolved": "https://registry.npmjs.org/pako/-/pako-0.2.9.tgz", "integrity": "sha1-8/dSL073gjSNqBYbrZ7P1Rv4OnU=", "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-filepath": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/parse-filepath/-/parse-filepath-1.0.2.tgz", "integrity": "sha1-pjISf1Oq89FYdvWHLz/6x2PWyJE=", "dev": true, "requires": { "is-absolute": "^1.0.0", "map-cache": "^0.2.0", "path-root": "^0.1.1" } }, "parse-glob": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/parse-glob/-/parse-glob-3.0.4.tgz", "integrity": "sha1-ssN2z7EfNVE7rdFz7wu246OIORw=", "dev": true, "requires": { "glob-base": "^0.3.0", "is-dotfile": "^1.0.0", "is-extglob": "^1.0.0", "is-glob": "^2.0.0" } }, "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" } }, "parse-passwd": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/parse-passwd/-/parse-passwd-1.0.0.tgz", "integrity": "sha1-bVuTSkVpk7I9N/QKOC1vFmao5cY=", "dev": true }, "parseurl": { "version": "1.3.3", "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", "dev": true }, "parsimmon": { "version": "1.13.0", "resolved": "https://registry.npmjs.org/parsimmon/-/parsimmon-1.13.0.tgz", "integrity": "sha512-5UIrOCW+gjbILkjKPgTgmq8LKf8TT3Iy7kN2VD7OtQ81facKn8B4gG1X94jWqXYZsxG2KbJhrv/Yq/5H6BQn7A==", "dev": true }, "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": "0.0.0", "resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-0.0.0.tgz", "integrity": "sha1-oLhwcpquIUAFt9UDLsLLuw+0RRo=", "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 }, "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.6", "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz", "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==", "dev": true }, "path-root": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/path-root/-/path-root-0.1.1.tgz", "integrity": "sha1-mkpoFMrBwM1zNgqV8yCDyOpHRbc=", "dev": true, "requires": { "path-root-regex": "^0.1.0" } }, "path-root-regex": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/path-root-regex/-/path-root-regex-0.1.2.tgz", "integrity": "sha1-v8zcjfWxLcUsi0PsONGNcsBLqW0=", "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" }, "dependencies": { "isarray": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=", "dev": true } } }, "path-type": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/path-type/-/path-type-1.1.0.tgz", "integrity": "sha1-WcRPfuSR2nBNpBXaWkBwuk+P5EE=", "dev": true, "requires": { "graceful-fs": "^4.1.2", "pify": "^2.0.0", "pinkie-promise": "^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 } } }, "pathval": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/pathval/-/pathval-1.1.0.tgz", "integrity": "sha1-uULm1L3mUwBe9rcTYd74cn0GReA=", "dev": true }, "pbkdf2-compat": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/pbkdf2-compat/-/pbkdf2-compat-2.0.1.tgz", "integrity": "sha1-tuDI+plJTZTgURV1gCpZpcFC8og=", "dev": true }, "performance-now": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=", "dev": true }, "picomatch": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.2.1.tgz", "integrity": "sha512-ISBaA8xQNmwELC7eOjqFKMESB2VIqt4PPDD0nsS95b/9dZXvVKOlz9keMSnoGGKcOHXfTvDD6WMaRoSc9UuhRA==", "dev": true }, "pify": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", "dev": true }, "pinkie": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz", "integrity": "sha1-clVrgM+g1IqXToDnckjoDtT3+HA=", "dev": true }, "pinkie-promise": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz", "integrity": "sha1-ITXW36ejWMBprJsXh3YogihFD/o=", "dev": true, "requires": { "pinkie": "^2.0.0" } }, "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" } }, "please-upgrade-node": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/please-upgrade-node/-/please-upgrade-node-3.2.0.tgz", "integrity": "sha512-gQR3WpIgNIKwBMVLkpMUeR3e1/E1y42bqDQZfql+kDeXd8COYfM8PQA4X6y7a8u9Ua9FHmsrrmirW2vHs45hWg==", "dev": true, "requires": { "semver-compare": "^1.0.0" } }, "portscanner": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/portscanner/-/portscanner-1.2.0.tgz", "integrity": "sha1-sUu9olfRTDEPqcwJaCrwLUCWGAI=", "dev": true, "requires": { "async": "1.5.2" } }, "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 }, "preserve": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/preserve/-/preserve-0.2.0.tgz", "integrity": "sha1-gV7R9uvGWSb4ZbMQwHE7yzMVzks=", "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 }, "pretty-bytes": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/pretty-bytes/-/pretty-bytes-1.0.4.tgz", "integrity": "sha1-CiLoIQYJrTVUL4yNXSFZr/B1HIQ=", "dev": true, "requires": { "get-stdin": "^4.0.1", "meow": "^3.1.0" } }, "private": { "version": "0.1.8", "resolved": "https://registry.npmjs.org/private/-/private-0.1.8.tgz", "integrity": "sha512-VvivMrbvd2nKkiG38qjULzlc+4Vx4wm/whI9pQD35YrARNnhxeiRktSOhSukRLFNlzg6Br/cJPet5J/u19r/mg==", "dev": true }, "process": { "version": "0.11.10", "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", "integrity": "sha1-czIwDoQBYb2j5podHZGn1LwW8YI=", "dev": true }, "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 }, "proxy-addr": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.6.tgz", "integrity": "sha512-dh/frvCBVmSsDYzw6n926jv974gddhkFPfiN8hPOi30Wax25QZyZEGveluCgliBnqmuM+UJmBErbAUFIoDbjOw==", "dev": true, "requires": { "forwarded": "~0.1.2", "ipaddr.js": "1.9.1" } }, "prr": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/prr/-/prr-1.0.1.tgz", "integrity": "sha1-0/wRS6BplaRexok/SEzrHXj19HY=", "dev": true }, "pseudomap": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz", "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=", "dev": true }, "psl": { "version": "1.7.0", "resolved": "https://registry.npmjs.org/psl/-/psl-1.7.0.tgz", "integrity": "sha512-5NsSEDv8zY70ScRnOTn7bK7eanl2MvFrOrS/R6x+dBt5g1ghnj9Zv90kO8GwT8gxcu2ANyFprnFYB85IogIJOQ==", "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 }, "q": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/q/-/q-1.4.1.tgz", "integrity": "sha1-VXBbzZPF82c1MMLCy8DCs63cKG4=", "dev": true }, "qs": { "version": "6.5.2", "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz", "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==", "dev": true }, "querystring": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/querystring/-/querystring-0.2.0.tgz", "integrity": "sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA=", "dev": true }, "querystring-es3": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/querystring-es3/-/querystring-es3-0.2.1.tgz", "integrity": "sha1-nsYfeQSYdXB9aUFFlv2Qek1xHnM=", "dev": true }, "querystringify": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.1.1.tgz", "integrity": "sha512-w7fLxIRCRT7U8Qu53jQnJyPkYZIaR4n5151KMfcJlO/A9397Wxb1amJvROTK6TOnp7PfoAmg/qXiNHI+08jRfA==", "dev": true }, "randomatic": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/randomatic/-/randomatic-3.1.1.tgz", "integrity": "sha512-TuDE5KxZ0J461RVjrJZCJc+J+zCkTb1MbH9AQUq68sMhOMcy9jLcb3BrZKgp9q9Ncltdg4QVqWrH02W2EFFVYw==", "dev": true, "requires": { "is-number": "^4.0.0", "kind-of": "^6.0.0", "math-random": "^1.0.1" }, "dependencies": { "is-number": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/is-number/-/is-number-4.0.0.tgz", "integrity": "sha512-rSklcAIlf1OmFdyAqbnWTLVelsQ58uvZ66S/ZyawjWqIviTWCjg2PzVGw8WUA+nNuPTqb4wgA+NszrJ+08LlgQ==", "dev": true }, "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 } } }, "range-parser": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", "dev": true }, "raw-body": { "version": "1.1.7", "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-1.1.7.tgz", "integrity": "sha1-HQJ8K/oRasxmI7yo8AAWVyqH1CU=", "dev": true, "requires": { "bytes": "1", "string_decoder": "0.10" }, "dependencies": { "string_decoder": { "version": "0.10.31", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=", "dev": true } } }, "read-pkg": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-4.0.1.tgz", "integrity": "sha1-ljYlN48+HE1IyFhytabsfV0JMjc=", "dev": true, "requires": { "normalize-package-data": "^2.3.2", "parse-json": "^4.0.0", "pify": "^3.0.0" } }, "read-pkg-up": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-1.0.1.tgz", "integrity": "sha1-nWPBMnbAZZGNV/ACpX9AobZD+wI=", "dev": true, "requires": { "find-up": "^1.0.0", "read-pkg": "^1.0.0" }, "dependencies": { "find-up": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/find-up/-/find-up-1.1.2.tgz", "integrity": "sha1-ay6YIrGizgpgq2TWEOzK1TyyTQ8=", "dev": true, "requires": { "path-exists": "^2.0.0", "pinkie-promise": "^2.0.0" } }, "path-exists": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-2.1.0.tgz", "integrity": "sha1-D+tsZPD8UY2adU3V77YscCJ2H0s=", "dev": true, "requires": { "pinkie-promise": "^2.0.0" } }, "read-pkg": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-1.1.0.tgz", "integrity": "sha1-9f+qXs0pyzHAR0vKfXVra7KePyg=", "dev": true, "requires": { "load-json-file": "^1.0.0", "normalize-package-data": "^2.3.2", "path-type": "^1.0.0" } } } }, "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": { "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 } } }, "readdirp": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-2.2.1.tgz", "integrity": "sha512-1JU/8q+VgFZyxwrJ+SVIOsh+KywWGpds3NTqikiKpDMZWScmAYyKIgqkO+ARvNWJfXeXR1zxz7aHF4u4CyH6vQ==", "dev": true, "requires": { "graceful-fs": "^4.1.11", "micromatch": "^3.1.10", "readable-stream": "^2.0.2" }, "dependencies": { "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 }, "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 }, "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" } } } }, "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" } }, "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": { "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" } }, "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": { "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-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": { "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-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" } }, "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 } } }, "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" } } } }, "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-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" } }, "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" } } } }, "isobject": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", "dev": true }, "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 }, "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" } }, "ms": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", "dev": true } } }, "recast": { "version": "0.10.33", "resolved": "https://registry.npmjs.org/recast/-/recast-0.10.33.tgz", "integrity": "sha1-lCgI96oBbx+nFCxGHX5XBKqo1pc=", "dev": true, "requires": { "ast-types": "0.8.12", "esprima-fb": "~15001.1001.0-dev-harmony-fb", "private": "~0.1.5", "source-map": "~0.5.0" }, "dependencies": { "ast-types": { "version": "0.8.12", "resolved": "https://registry.npmjs.org/ast-types/-/ast-types-0.8.12.tgz", "integrity": "sha1-oNkOQ1G7iHcWyD/WN+v4GK9K38w=", "dev": true }, "source-map": { "version": "0.5.7", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", "dev": true } } }, "rechoir": { "version": "0.6.2", "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.6.2.tgz", "integrity": "sha1-hSBLVNuoLVdC4oyWdW70OvUOM4Q=", "dev": true, "requires": { "resolve": "^1.1.6" } }, "redent": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/redent/-/redent-1.0.0.tgz", "integrity": "sha1-z5Fqsf1fHxbfsggi3W7H9zDCr94=", "dev": true, "requires": { "indent-string": "^2.1.0", "strip-indent": "^1.0.1" } }, "reflect": { "version": "0.0.7", "resolved": "https://registry.npmjs.org/reflect/-/reflect-0.0.7.tgz", "integrity": "sha1-Zmbty0D+rLEgTsAImeKMcV2vQXw=", "dev": true }, "regenerate": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.0.tgz", "integrity": "sha512-1G6jJVDWrt0rK99kBjvEtziZNCICAuvIPkSiUFIQxVP06RCVpq3dmDo2oi6ABpYaDYaTRr67BEhL8r1wgEZZKg==", "dev": true }, "regenerator": { "version": "0.8.40", "resolved": "https://registry.npmjs.org/regenerator/-/regenerator-0.8.40.tgz", "integrity": "sha1-oORXxY69uuV1yfjNdRJ+k3VkNdg=", "dev": true, "requires": { "commoner": "~0.10.3", "defs": "~1.1.0", "esprima-fb": "~15001.1001.0-dev-harmony-fb", "private": "~0.1.5", "recast": "0.10.33", "through": "~2.3.8" } }, "regenerator-runtime": { "version": "0.13.5", "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.5.tgz", "integrity": "sha512-ZS5w8CpKFinUzOwW3c83oPeVXoNsrLsaCoLtJvAClH135j/R77RuymhiSErhm2lKcwSCIpmvIWSbDkIfAqKQlA==", "dev": true }, "regex-cache": { "version": "0.4.4", "resolved": "https://registry.npmjs.org/regex-cache/-/regex-cache-0.4.4.tgz", "integrity": "sha512-nVIZwtCjkC9YgvWkpM55B5rBhBYRZhAaJbgcFYXXsHnbZ9UZI9nnVWYZpBlCqv9ho2eZryPnWrZGsOdPwVWXWQ==", "dev": true, "requires": { "is-equal-shallow": "^0.1.3" } }, "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" } }, "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": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/regexpu/-/regexpu-1.3.0.tgz", "integrity": "sha1-5TTcmRqeWEYFDJjebX3UpVyeoW0=", "dev": true, "requires": { "esprima": "^2.6.0", "recast": "^0.10.10", "regenerate": "^1.2.1", "regjsgen": "^0.2.0", "regjsparser": "^0.1.4" }, "dependencies": { "esprima": { "version": "2.7.3", "resolved": "https://registry.npmjs.org/esprima/-/esprima-2.7.3.tgz", "integrity": "sha1-luO3DVd59q1JzQMmc9HDEnZ7pYE=", "dev": true } } }, "regjsgen": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/regjsgen/-/regjsgen-0.2.0.tgz", "integrity": "sha1-bAFq3qxVT3WCP+N6wFuS1aTtsfc=", "dev": true }, "regjsparser": { "version": "0.1.5", "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.1.5.tgz", "integrity": "sha1-fuj4Tcb6eS0/0K4ijSS9lJ6tIFw=", "dev": true, "requires": { "jsesc": "~0.5.0" } }, "release-zalgo": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/release-zalgo/-/release-zalgo-1.0.0.tgz", "integrity": "sha1-CXALflB0Mpc5Mw5TXFqQ+2eFFzA=", "dev": true, "requires": { "es6-error": "^4.0.1" } }, "remove-trailing-separator": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz", "integrity": "sha1-wkvOKig62tW8P1jg1IJJuSN52O8=", "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 }, "repeating": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/repeating/-/repeating-1.1.3.tgz", "integrity": "sha1-PUEUIYh3U3SU+X93+Xhfq4EPpKw=", "dev": true, "requires": { "is-finite": "^1.0.0" } }, "request": { "version": "2.88.2", "resolved": "https://registry.npmjs.org/request/-/request-2.88.2.tgz", "integrity": "sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw==", "dev": true, "requires": { "aws-sign2": "~0.7.0", "aws4": "^1.8.0", "caseless": "~0.12.0", "combined-stream": "~1.0.6", "extend": "~3.0.2", "forever-agent": "~0.6.1", "form-data": "~2.3.2", "har-validator": "~5.1.3", "http-signature": "~1.2.0", "is-typedarray": "~1.0.0", "isstream": "~0.1.2", "json-stringify-safe": "~5.0.1", "mime-types": "~2.1.19", "oauth-sign": "~0.9.0", "performance-now": "^2.1.0", "qs": "~6.5.2", "safe-buffer": "^5.1.2", "tough-cookie": "~2.5.0", "tunnel-agent": "^0.6.0", "uuid": "^3.3.2" } }, "requestretry": { "version": "1.9.1", "resolved": "https://registry.npmjs.org/requestretry/-/requestretry-1.9.1.tgz", "integrity": "sha1-CioATq8hGWnEzCz+vz/p5XuSx04=", "dev": true, "requires": { "extend": "^3.0.0", "fg-lodash": "0.0.2", "request": "^2.74.x", "when": "~3.7.5" } }, "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 }, "require-main-filename": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==", "dev": true }, "requirejs": { "version": "2.3.6", "resolved": "https://registry.npmjs.org/requirejs/-/requirejs-2.3.6.tgz", "integrity": "sha512-ipEzlWQe6RK3jkzikgCupiTbTvm4S0/CAU5GlgptkN5SO6F3u0UD0K18wy6ErDqiCyP4J4YYe1HuAShvsxePLg==", "dev": true }, "requires-port": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", "integrity": "sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8=", "dev": true }, "resolve": { "version": "1.15.1", "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.15.1.tgz", "integrity": "sha512-84oo6ZTtoTUpjgNEr5SJyzQhzL72gaRodsSfyxC/AXRvwu0Yse9H8eF9IpGo7b8YetZhlI6v7ZQ6bKBFV/6S7w==", "dev": true, "requires": { "path-parse": "^1.0.6" } }, "resolve-dir": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/resolve-dir/-/resolve-dir-1.0.1.tgz", "integrity": "sha1-eaQGRMNivoLybv/nOcm7U4IEb0M=", "dev": true, "requires": { "expand-tilde": "^2.0.0", "global-modules": "^1.0.0" } }, "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 }, "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 }, "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 }, "reusify": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", "dev": true }, "right-align": { "version": "0.1.3", "resolved": "https://registry.npmjs.org/right-align/-/right-align-0.1.3.tgz", "integrity": "sha1-YTObci/mo1FWiSENJOFMlhSGE+8=", "dev": true, "requires": { "align-text": "^0.1.1" } }, "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" }, "dependencies": { "glob": { "version": "7.1.6", "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", "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" } }, "minimatch": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", "dev": true, "requires": { "brace-expansion": "^1.1.7" } } } }, "ripemd160": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-0.2.0.tgz", "integrity": "sha1-K/GYveFnys+lHAqSjoS2i74XH84=", "dev": true }, "run-async": { "version": "2.4.0", "resolved": "https://registry.npmjs.org/run-async/-/run-async-2.4.0.tgz", "integrity": "sha512-xJTbh/d7Lm7SBhc1tNvTpeCHaEzoyxPrqNlvSdMfBTYwaY++UJFyXUOxAtsRUXjlqOfj8luNaR9vjCh4KeV+pg==", "dev": true, "requires": { "is-promise": "^2.1.0" } }, "run-node": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/run-node/-/run-node-1.0.0.tgz", "integrity": "sha512-kc120TBlQ3mih1LSzdAJXo4xn/GWS2ec0l3S+syHDXP9uRr0JAT8Qd3mdMuyjqCzeZktgP3try92cEgf9Nks8A==", "dev": true }, "run-parallel": { "version": "1.1.9", "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.1.9.tgz", "integrity": "sha512-DEqnSRTDw/Tc3FXf49zedI638Z9onwUotBMiUFKmrO2sdFKIbXamXGQ3Axd4qgphxKB4kw/qP1w5kTxnfU1B9Q==", "dev": true }, "rxjs": { "version": "6.5.4", "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.5.4.tgz", "integrity": "sha512-naMQXcgEo3csAEGvw/NydRA0fuS2nDZJiw1YUWFKU7aPPAPGZEsD4Iimit96qwCieH6y614MCLYwdkrWx7z/7Q==", "dev": true, "requires": { "tslib": "^1.9.0" } }, "safe-buffer": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.0.tgz", "integrity": "sha512-fZEwUGbVl7kouZs1jCdMLdt95hdIv0ZeHg6L7qPeciMZhZ+/gdesW4wgTARkrFWEpspjEATAzUGPG8N2jJiwbg==", "dev": true }, "safe-json-parse": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/safe-json-parse/-/safe-json-parse-1.0.1.tgz", "integrity": "sha1-PnZyPjjf3aE8mx0poeB//uSzC1c=", "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 }, "saucelabs": { "version": "1.5.0", "resolved": "https://registry.npmjs.org/saucelabs/-/saucelabs-1.5.0.tgz", "integrity": "sha512-jlX3FGdWvYf4Q3LFfFWS1QvPg3IGCGWxIc8QBFdPTbpTJnt/v17FHXYVAn7C8sHf1yUXo2c7yIM0isDryfYtHQ==", "dev": true, "requires": { "https-proxy-agent": "^2.2.1" } }, "sax": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.1.tgz", "integrity": "sha1-e45lYZCyKOgaZq6nSEgNgozS03o=", "dev": true }, "semver": { "version": "5.7.1", "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", "dev": true }, "semver-compare": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/semver-compare/-/semver-compare-1.0.0.tgz", "integrity": "sha1-De4hahyUGrN+nvsXiPavxf9VN/w=", "dev": true }, "send": { "version": "0.17.1", "resolved": "https://registry.npmjs.org/send/-/send-0.17.1.tgz", "integrity": "sha512-BsVKsiGcQMFwT8UxypobUKyv7irCNRHk1T0G680vk88yf6LBByGcZJOTJCrTP2xVN6yI+XjPJcNuE3V4fT9sAg==", "dev": true, "requires": { "debug": "2.6.9", "depd": "~1.1.2", "destroy": "~1.0.4", "encodeurl": "~1.0.2", "escape-html": "~1.0.3", "etag": "~1.8.1", "fresh": "0.5.2", "http-errors": "~1.7.2", "mime": "1.6.0", "ms": "2.1.1", "on-finished": "~2.3.0", "range-parser": "~1.2.1", "statuses": "~1.5.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" }, "dependencies": { "ms": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", "dev": true } } }, "http-errors": { "version": "1.7.3", "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.7.3.tgz", "integrity": "sha512-ZTTX0MWrsQ2ZAhA1cejAwDLycFsd7I7nVtnkT3Ol0aqodaKW+0CTZDQ1uBv5whptCnc8e8HeRRJxRs0kmm/Qfw==", "dev": true, "requires": { "depd": "~1.1.2", "inherits": "2.0.4", "setprototypeof": "1.1.1", "statuses": ">= 1.5.0 < 2", "toidentifier": "1.0.0" } }, "ms": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==", "dev": true }, "setprototypeof": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.1.tgz", "integrity": "sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw==", "dev": true } } }, "serve-index": { "version": "1.9.1", "resolved": "https://registry.npmjs.org/serve-index/-/serve-index-1.9.1.tgz", "integrity": "sha1-03aNabHn2C5c4FD/9bRTvqEqkjk=", "dev": true, "requires": { "accepts": "~1.3.4", "batch": "0.6.1", "debug": "2.6.9", "escape-html": "~1.0.3", "http-errors": "~1.6.2", "mime-types": "~2.1.17", "parseurl": "~1.3.2" }, "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 } } }, "serve-static": { "version": "1.14.1", "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.14.1.tgz", "integrity": "sha512-JMrvUwE54emCYWlTI+hGrGv5I8dEwmco/00EvkzIIsR7MqrHonbD9pO2MOfFnpFntl7ecpZs+3mW+XbQZu9QCg==", "dev": true, "requires": { "encodeurl": "~1.0.2", "escape-html": "~1.0.3", "parseurl": "~1.3.3", "send": "0.17.1" } }, "set-blocking": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=", "dev": true }, "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" } } } }, "setimmediate": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz", "integrity": "sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU=", "dev": true }, "setprototypeof": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.0.tgz", "integrity": "sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ==", "dev": true }, "sha.js": { "version": "2.2.6", "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.2.6.tgz", "integrity": "sha1-F93t3F9yL7ZlAWWIlUYZd4ZzFbo=", "dev": true }, "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 }, "signal-exit": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz", "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=", "dev": true }, "simple-fmt": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/simple-fmt/-/simple-fmt-0.1.0.tgz", "integrity": "sha1-GRv1ZqWeZTBILLJatTtKjchcOms=", "dev": true }, "simple-is": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/simple-is/-/simple-is-0.2.0.tgz", "integrity": "sha1-Krt1qt453rXMgVzhDmGRFkhQuvA=", "dev": true }, "sinon": { "version": "7.5.0", "resolved": "https://registry.npmjs.org/sinon/-/sinon-7.5.0.tgz", "integrity": "sha512-AoD0oJWerp0/rY9czP/D6hDTTUYGpObhZjMpd7Cl/A6+j0xBE+ayL/ldfggkBXUs0IkvIiM1ljM8+WkOc5k78Q==", "dev": true, "requires": { "@sinonjs/commons": "^1.4.0", "@sinonjs/formatio": "^3.2.1", "@sinonjs/samsam": "^3.3.3", "diff": "^3.5.0", "lolex": "^4.2.0", "nise": "^1.5.2", "supports-color": "^5.5.0" }, "dependencies": { "diff": { "version": "3.5.0", "resolved": "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz", "integrity": "sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==", "dev": true } } }, "slash": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/slash/-/slash-1.0.0.tgz", "integrity": "sha1-xB8vbDn8FtHNF61LXYlhFK5HDVU=", "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" }, "dependencies": { "ansi-styles": { "version": "3.2.1", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", "dev": true, "requires": { "color-convert": "^1.9.0" } }, "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 }, "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 } } }, "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 }, "source-map": { "version": "0.5.7", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", "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" } }, "isobject": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", "dev": true }, "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 } } }, "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" } }, "sockjs": { "version": "0.3.20", "resolved": "https://registry.npmjs.org/sockjs/-/sockjs-0.3.20.tgz", "integrity": "sha512-SpmVOVpdq0DJc0qArhF3E5xsxvaiqGNb73XfgBpK1y3UD5gs8DSo8aCTsuT5pX8rssdc2NDIzANwP9eCAiSdTA==", "dev": true, "requires": { "faye-websocket": "^0.10.0", "uuid": "^3.4.0", "websocket-driver": "0.6.5" }, "dependencies": { "websocket-driver": { "version": "0.6.5", "resolved": "https://registry.npmjs.org/websocket-driver/-/websocket-driver-0.6.5.tgz", "integrity": "sha1-XLJVbOuF9Dc8bYI4qmkchFThOjY=", "dev": true, "requires": { "websocket-extensions": ">=0.1.1" } } } }, "sockjs-client": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/sockjs-client/-/sockjs-client-1.4.0.tgz", "integrity": "sha512-5zaLyO8/nri5cua0VtOrFXBPK1jbL4+1cebT/mmKA1E1ZXOvJrII75bPu0l0k843G/+iAbhEqzyKr0w/eCCj7g==", "dev": true, "requires": { "debug": "^3.2.5", "eventsource": "^1.0.7", "faye-websocket": "~0.11.1", "inherits": "^2.0.3", "json3": "^3.3.2", "url-parse": "^1.4.3" }, "dependencies": { "faye-websocket": { "version": "0.11.3", "resolved": "https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.11.3.tgz", "integrity": "sha512-D2y4bovYpzziGgbHYtGCMjlJM36vAl/y+xUyn1C+FVx8szd1E+86KwVw6XvYSzOP8iMpm1X0I4xJD+QtUb36OA==", "dev": true, "requires": { "websocket-driver": ">=0.5.1" } } } }, "source-list-map": { "version": "0.1.8", "resolved": "https://registry.npmjs.org/source-list-map/-/source-list-map-0.1.8.tgz", "integrity": "sha1-xVCyq1Qn9rPyH1r+rYjE9Vh7IQY=", "dev": true }, "source-map": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" }, "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.2.10", "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.2.10.tgz", "integrity": "sha1-6lo5AKHByyUJagrozFwrSxDe09w=", "dev": true, "requires": { "source-map": "0.1.32" }, "dependencies": { "source-map": { "version": "0.1.32", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.1.32.tgz", "integrity": "sha1-yLbBZ3l7pHQKjqMyUhYv8IWRsmY=", "dev": true, "requires": { "amdefine": ">=0.0.4" } } } }, "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 }, "spawn-command": { "version": "0.0.2-1", "resolved": "https://registry.npmjs.org/spawn-command/-/spawn-command-0.0.2-1.tgz", "integrity": "sha1-YvXpRmmBwbeW3Fkpk34RycaSG9A=", "dev": true }, "spawn-wrap": { "version": "1.4.3", "resolved": "https://registry.npmjs.org/spawn-wrap/-/spawn-wrap-1.4.3.tgz", "integrity": "sha512-IgB8md0QW/+tWqcavuFgKYR/qIRvJkRLPJDFaoXtLLUaVcCDK0+HeFTkmQHj3eprcYhc+gOl0aEA1w7qZlYezw==", "dev": true, "requires": { "foreground-child": "^1.5.6", "mkdirp": "^0.5.0", "os-homedir": "^1.0.1", "rimraf": "^2.6.2", "signal-exit": "^3.0.2", "which": "^1.3.0" } }, "spdx-correct": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.1.0.tgz", "integrity": "sha512-lr2EZCctC2BNR7j7WzJ2FpDznxky1sjfxvvYEyzxNyb6lZXHODmEoJeFu4JupYlkfha1KZpJyoqiJ7pgA1qq8Q==", "dev": true, "requires": { "spdx-expression-parse": "^3.0.0", "spdx-license-ids": "^3.0.0" } }, "spdx-exceptions": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.2.0.tgz", "integrity": "sha512-2XQACfElKi9SlVb1CYadKDXvoajPgBVPn/gOQLrTvHdElaVhr7ZEbqJaRnJLVNeaI4cMEAgVCeBMKF6MWRDCRA==", "dev": true }, "spdx-expression-parse": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.0.tgz", "integrity": "sha512-Yg6D3XpRD4kkOmTpdgbUiEJFKghJH03fiC1OPll5h/0sO6neh2jqRDVHOQ4o/LMea0tgCkbMgea5ip/e+MkWyg==", "dev": true, "requires": { "spdx-exceptions": "^2.1.0", "spdx-license-ids": "^3.0.0" } }, "spdx-license-ids": { "version": "3.0.5", "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.5.tgz", "integrity": "sha512-J+FWzZoynJEXGphVIS+XEh3kFSjZX/1i9gFBaWQcB+/tmpe2qUsSBABpcxqxnAxFdiUFEgAX1bjYGQvIZmoz9Q==", "dev": true }, "split": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/split/-/split-1.0.1.tgz", "integrity": "sha512-mTyOoPbrivtXnwnIxZRFYRrPNtEFKlpB2fvjSnCQUiAA6qAZzqwna5envK4uk6OIeP17CsdF3rSBGYVBsU0Tkg==", "dev": true, "requires": { "through": "2" } }, "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 }, "sshpk": { "version": "1.16.1", "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.16.1.tgz", "integrity": "sha512-HXXqVUq7+pcKeLqqZj6mHFUMvXtOJt1uoUx09pFW6011inTMxqI8BA8PM95myrIyyKwdnzjdFjLiE6KBPVtJIg==", "dev": true, "requires": { "asn1": "~0.2.3", "assert-plus": "^1.0.0", "bcrypt-pbkdf": "^1.0.0", "dashdash": "^1.12.0", "ecc-jsbn": "~0.1.1", "getpass": "^0.1.1", "jsbn": "~0.1.0", "safer-buffer": "^2.0.2", "tweetnacl": "~0.14.0" } }, "stable": { "version": "0.1.8", "resolved": "https://registry.npmjs.org/stable/-/stable-0.1.8.tgz", "integrity": "sha512-ji9qxRnOVfcuLDySj9qzhGSEFVobyt1kIOSkj1qZzYLzq7Tos/oUUWvotUPQLlrsidqsK6tBH89Bc9kL5zHA6w==", "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" } } } }, "statuses": { "version": "1.5.0", "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", "integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=", "dev": true }, "stream-browserify": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/stream-browserify/-/stream-browserify-2.0.2.tgz", "integrity": "sha512-nX6hmklHs/gr2FuxYDltq8fJA1GDlxKQCz8O/IM4atRqBH8OORmBNgfvW5gG10GT/qQ9u0CzIvr2X5Pkt6ntqg==", "dev": true, "requires": { "inherits": "~2.0.1", "readable-stream": "^2.0.2" } }, "stream-cache": { "version": "0.0.2", "resolved": "https://registry.npmjs.org/stream-cache/-/stream-cache-0.0.2.tgz", "integrity": "sha1-GsWtaDJCjKVWZ9ve45Xa1ObbEY8=", "dev": true }, "stream-http": { "version": "2.8.3", "resolved": "https://registry.npmjs.org/stream-http/-/stream-http-2.8.3.tgz", "integrity": "sha512-+TSkfINHDo4J+ZobQLWiMouQYB+UVYFttRA94FpEzzJ7ZdqcL4uUUQ7WkdkI4DSozGmgBUE/a47L+38PenXhUw==", "dev": true, "requires": { "builtin-status-codes": "^3.0.0", "inherits": "^2.0.1", "readable-stream": "^2.3.6", "to-arraybuffer": "^1.0.0", "xtend": "^4.0.0" } }, "string-argv": { "version": "0.3.1", "resolved": "https://registry.npmjs.org/string-argv/-/string-argv-0.3.1.tgz", "integrity": "sha512-a1uQGz7IyVy9YwhqjZIZu1c8JO8dNIe20xBmSS6qu9kv++k3JGzCVmprbNN5Kn+BgzD5E7YYwg1CcjuJMRNsvg==", "dev": true }, "string-template": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/string-template/-/string-template-0.2.1.tgz", "integrity": "sha1-QpMuWYo1LQH8IuwzZ9nYTuxsmt0=", "dev": true }, "string-width": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.0.tgz", "integrity": "sha512-zUz5JD+tgqtuDjMhwIg5uFVV3dtqZ9yQJlZVfq4I01/K5Paj5UHj7VyrQOJvzawSVlKpObApbfD0Ed6yJc+1eg==", "dev": true, "requires": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", "strip-ansi": "^6.0.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" }, "dependencies": { "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 } } }, "stringify-object": { "version": "3.3.0", "resolved": "https://registry.npmjs.org/stringify-object/-/stringify-object-3.3.0.tgz", "integrity": "sha512-rHqiFh1elqCQ9WPLIC8I0Q/g/wj5J1eMkyoiD6eoQApWHP0FtlK7rqnhmabL5VUY9JQCcqwwvlOaSuutekgyrw==", "dev": true, "requires": { "get-own-enumerable-property-symbols": "^3.0.0", "is-obj": "^1.0.1", "is-regexp": "^1.0.0" } }, "stringmap": { "version": "0.2.2", "resolved": "https://registry.npmjs.org/stringmap/-/stringmap-0.2.2.tgz", "integrity": "sha1-VWwTeyWPlCuHdvWy71gqoGnX0bE=", "dev": true }, "stringset": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/stringset/-/stringset-0.2.1.tgz", "integrity": "sha1-7yWcTjSTRDd/zRyRPdLoSMnAQrU=", "dev": true }, "strip-ansi": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", "dev": true, "requires": { "ansi-regex": "^5.0.0" } }, "strip-bom": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-2.0.0.tgz", "integrity": "sha1-YhmoVhZSBJHzV4i9vxRHqZx+aw4=", "dev": true, "requires": { "is-utf8": "^0.2.0" } }, "strip-eof": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz", "integrity": "sha1-u0P/VZim6wXYm1n80SnJgzE2Br8=", "dev": true }, "strip-final-newline": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz", "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==", "dev": true }, "strip-indent": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-1.0.1.tgz", "integrity": "sha1-DHlipq3vp7vUrDZkYKY4VSrhoKI=", "dev": true, "requires": { "get-stdin": "^4.0.1" } }, "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 }, "strscan": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/strscan/-/strscan-1.0.1.tgz", "integrity": "sha1-Ry2bwAxo6QbvL8Is33Yr58YazE0=", "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" } }, "symbol-observable": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/symbol-observable/-/symbol-observable-1.2.0.tgz", "integrity": "sha512-e900nM8RRtGhlV36KGEU9k65K3mPb1WV70OdjfxlG2EAuM1noi/E/BaW/uMhL7bPEssK8QV57vN3esixjUvcXQ==", "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.0", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", "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 }, "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 }, "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": "0.1.10", "resolved": "https://registry.npmjs.org/tapable/-/tapable-0.1.10.tgz", "integrity": "sha1-KcNXB8K3DlDQdIK10gLo7URtr9Q=", "dev": true }, "test-exclude": { "version": "5.2.3", "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-5.2.3.tgz", "integrity": "sha512-M+oxtseCFO3EDtAaGH7iiej3CBkzXqFMbzqYAACdzKui4eZA+pq3tZEwChvOdNfa7xxy8BfbmgJSIr43cC/+2g==", "dev": true, "requires": { "glob": "^7.1.3", "minimatch": "^3.0.4", "read-pkg-up": "^4.0.0", "require-main-filename": "^2.0.0" }, "dependencies": { "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" } }, "glob": { "version": "7.1.6", "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", "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" } }, "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": "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" } }, "minimatch": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", "dev": true, "requires": { "brace-expansion": "^1.1.7" } }, "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" } }, "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-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" } }, "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": "4.0.0", "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-4.0.0.tgz", "integrity": "sha512-6etQSH7nJGsK0RbG/2TeDzZFa8shjQ1um+SwQQ5cwKy0dhSXdOncEhb1CPpvQG4h7FyOV6EB6YlV0yJvZQNAkA==", "dev": true, "requires": { "find-up": "^3.0.0", "read-pkg": "^3.0.0" } }, "strip-bom": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", "dev": true } } }, "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 }, "time-stamp": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/time-stamp/-/time-stamp-2.2.0.tgz", "integrity": "sha512-zxke8goJQpBeEgD82CXABeMh0LSJcj7CXEd0OHOg45HgcofF7pxNwZm9+RknpxpDhwN4gFpySkApKfFYfRQnUA==", "dev": true }, "timers-browserify": { "version": "2.0.11", "resolved": "https://registry.npmjs.org/timers-browserify/-/timers-browserify-2.0.11.tgz", "integrity": "sha512-60aV6sgJ5YEbzUdn9c8kYGIqOubPoUdqQCul3SBAsRCZ40s6Y5cMcrW4dt3/k/EsbLVJNl9n6Vz3fTc+k2GeKQ==", "dev": true, "requires": { "setimmediate": "^1.0.4" } }, "tiny-lr": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/tiny-lr/-/tiny-lr-1.1.1.tgz", "integrity": "sha512-44yhA3tsaRoMOjQQ+5v5mVdqef+kH6Qze9jTpqtVufgYjYt08zyZAwNwwVBj3i1rJMnR52IxOW0LK0vBzgAkuA==", "dev": true, "requires": { "body": "^5.1.0", "debug": "^3.1.0", "faye-websocket": "~0.10.0", "livereload-js": "^2.3.0", "object-assign": "^4.1.0", "qs": "^6.4.0" }, "dependencies": { "object-assign": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", "dev": true } } }, "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-arraybuffer": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/to-arraybuffer/-/to-arraybuffer-1.0.1.tgz", "integrity": "sha1-fSKbH8xjfkZsoIEYCDanqr/4P0M=", "dev": true }, "to-fast-properties": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-1.0.3.tgz", "integrity": "sha1-uDVx+k2MJbguIxsG46MFXeTKGkc=", "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" } }, "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": "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" }, "dependencies": { "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" } } } }, "toidentifier": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.0.tgz", "integrity": "sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw==", "dev": true }, "tough-cookie": { "version": "2.5.0", "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz", "integrity": "sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==", "dev": true, "requires": { "psl": "^1.1.28", "punycode": "^2.1.1" } }, "tree-kill": { "version": "1.2.2", "resolved": "https://registry.npmjs.org/tree-kill/-/tree-kill-1.2.2.tgz", "integrity": "sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==", "dev": true }, "trim-newlines": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/trim-newlines/-/trim-newlines-1.0.0.tgz", "integrity": "sha1-WIeWa7WCpFA6QetST301ARgVphM=", "dev": true }, "trim-right": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/trim-right/-/trim-right-1.0.1.tgz", "integrity": "sha1-yy4SAwZ+DI3h9hQJS5/kVwTqYAM=", "dev": true }, "try-resolve": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/try-resolve/-/try-resolve-1.0.1.tgz", "integrity": "sha1-z95vq9ctY+V5fPqrhzq76OcA6RI=", "dev": true }, "tryor": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/tryor/-/tryor-0.1.2.tgz", "integrity": "sha1-gUXkynyv9ArN48z5Rui4u3W0Fys=", "dev": true }, "tslib": { "version": "1.11.1", "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.11.1.tgz", "integrity": "sha512-aZW88SY8kQbU7gpV19lN24LtXh/yD4ZZg6qieAJDDg+YBsJcSmLGK9QpnUjAKVG/xefmvJGd1WUmfpT/g6AJGA==", "dev": true }, "tslint": { "version": "5.20.1", "resolved": "https://registry.npmjs.org/tslint/-/tslint-5.20.1.tgz", "integrity": "sha512-EcMxhzCFt8k+/UP5r8waCf/lzmeSyVlqxqMEDQE7rWYiQky8KpIBz1JAoYXfROHrPZ1XXd43q8yQnULOLiBRQg==", "dev": true, "requires": { "@babel/code-frame": "^7.0.0", "builtin-modules": "^1.1.1", "chalk": "^2.3.0", "commander": "^2.12.1", "diff": "^4.0.1", "glob": "^7.1.1", "js-yaml": "^3.13.1", "minimatch": "^3.0.4", "mkdirp": "^0.5.1", "resolve": "^1.3.2", "semver": "^5.3.0", "tslib": "^1.8.0", "tsutils": "^2.29.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 }, "glob": { "version": "7.1.6", "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", "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" } }, "minimatch": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", "dev": true, "requires": { "brace-expansion": "^1.1.7" } } } }, "tsutils": { "version": "2.29.0", "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-2.29.0.tgz", "integrity": "sha512-g5JVHCIJwzfISaXpXE1qvNalca5Jwob6FjI4AoPlqMusJ6ftFE7IkkFoMhVLRgK+4Kx3gkzb8UZK5t5yTTvEmA==", "dev": true, "requires": { "tslib": "^1.8.1" } }, "tty-browserify": { "version": "0.0.0", "resolved": "https://registry.npmjs.org/tty-browserify/-/tty-browserify-0.0.0.tgz", "integrity": "sha1-oVe6QC2iTpv5V/mqadUk7tQpAaY=", "dev": true }, "tunnel-agent": { "version": "0.6.0", "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=", "dev": true, "requires": { "safe-buffer": "^5.0.1" } }, "tweetnacl": { "version": "0.14.5", "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=", "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 }, "type-is": { "version": "1.6.18", "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", "dev": true, "requires": { "media-typer": "0.3.0", "mime-types": "~2.1.24" } }, "typedarray": { "version": "0.0.6", "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=", "dev": true }, "typescript": { "version": "3.8.3", "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.8.3.tgz", "integrity": "sha512-MYlEfn5VrLNsgudQTVJeNaQFUAI7DkhnOjdpAp4T+ku1TfQClewlbSuTVHiA+8skNBgaf02TL/kLOvig4y3G8w==", "dev": true }, "uglify-js": { "version": "3.8.0", "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.8.0.tgz", "integrity": "sha512-ugNSTT8ierCsDHso2jkBHXYrU8Y5/fY2ZUprfrJUiD7YpuFvV4jODLFmb3h4btQjqr5Nh4TX4XtgDfCU1WdioQ==", "optional": true, "requires": { "commander": "~2.20.3", "source-map": "~0.6.1" } }, "uglify-to-browserify": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/uglify-to-browserify/-/uglify-to-browserify-1.0.2.tgz", "integrity": "sha1-bgkk1r2mta/jSeOabWMoUKD4grc=", "dev": true }, "unc-path-regex": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/unc-path-regex/-/unc-path-regex-0.1.2.tgz", "integrity": "sha1-5z3T17DXxe2G+6xrCufYxqadUPo=", "dev": true }, "underscore": { "version": "1.9.2", "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.9.2.tgz", "integrity": "sha512-D39qtimx0c1fI3ya1Lnhk3E9nONswSKhnffBI0gME9C99fYOkNi04xs8K6pePLhvl1frbDemkaBQ5ikWllR2HQ==", "dev": true }, "underscore.string": { "version": "2.3.3", "resolved": "https://registry.npmjs.org/underscore.string/-/underscore.string-2.3.3.tgz", "integrity": "sha1-ccCL9rQosRM/N+ePo6Icgvcymw0=", "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" } }, "universalify": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", "dev": true }, "unpipe": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=", "dev": true }, "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 }, "isobject": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", "dev": true } } }, "uri-js": { "version": "4.2.2", "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.2.2.tgz", "integrity": "sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ==", "dev": true, "requires": { "punycode": "^2.1.0" } }, "uri-path": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/uri-path/-/uri-path-1.0.0.tgz", "integrity": "sha1-l0fwGDWJM8Md4PzP2C0TjmcmLjI=", "dev": true }, "urix": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/urix/-/urix-0.1.0.tgz", "integrity": "sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI=", "dev": true }, "url": { "version": "0.10.3", "resolved": "https://registry.npmjs.org/url/-/url-0.10.3.tgz", "integrity": "sha1-Ah5NnHcF8hu/N9A861h2dAJ3TGQ=", "dev": true, "requires": { "punycode": "1.3.2", "querystring": "0.2.0" }, "dependencies": { "punycode": { "version": "1.3.2", "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.3.2.tgz", "integrity": "sha1-llOgNvt8HuQjQvIyXM7v6jkmxI0=", "dev": true } } }, "url-parse": { "version": "1.4.7", "resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.4.7.tgz", "integrity": "sha512-d3uaVyzDB9tQoSXFvuSUNFibTd9zxd2bkVrDRvF5TmvWWQwqE4lgYJ5m+x1DbecWkw+LK4RNl2CU1hHuOKPVlg==", "dev": true, "requires": { "querystringify": "^2.1.1", "requires-port": "^1.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 }, "user-home": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/user-home/-/user-home-1.1.1.tgz", "integrity": "sha1-K1viOjK2Onyd640PKNSFcko98ZA=", "dev": true }, "util": { "version": "0.10.4", "resolved": "https://registry.npmjs.org/util/-/util-0.10.4.tgz", "integrity": "sha512-0Pm9hTQ3se5ll1XihRic3FDIku70C+iHUdT/W926rSgHV5QgXsYbKZN8MSC3tJtSkhuROzvsQjAaFENRXr+19A==", "dev": true, "requires": { "inherits": "2.0.3" }, "dependencies": { "inherits": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", "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 }, "utils-merge": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", "integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=", "dev": true }, "uuid": { "version": "3.4.0", "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==", "dev": true }, "v8-compile-cache": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.1.0.tgz", "integrity": "sha512-usZBT3PW+LOjM25wbqIlZwPeJV+3OSz3M1k1Ws8snlW39dZyYL9lOGC5FgPVHfk0jKmjiDV8Z0mIbVQPiwFs7g==", "dev": true }, "v8flags": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/v8flags/-/v8flags-3.1.3.tgz", "integrity": "sha512-amh9CCg3ZxkzQ48Mhcb8iX7xpAfYJgePHxWMQCBWECpOSqJUXgY26ncA61UTV0BkPqfhcy6mzwCIoP4ygxpW8w==", "dev": true, "requires": { "homedir-polyfill": "^1.0.1" } }, "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" } }, "vary": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=", "dev": true }, "verror": { "version": "1.10.0", "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=", "dev": true, "requires": { "assert-plus": "^1.0.0", "core-util-is": "1.0.2", "extsprintf": "^1.2.0" } }, "vm-browserify": { "version": "0.0.4", "resolved": "https://registry.npmjs.org/vm-browserify/-/vm-browserify-0.0.4.tgz", "integrity": "sha1-XX6kW7755Kb/ZflUOOCofDV9WnM=", "dev": true, "requires": { "indexof": "0.0.1" } }, "watchpack": { "version": "0.2.9", "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-0.2.9.tgz", "integrity": "sha1-Yuqkq15bo1/fwBgnVibjwPXj+ws=", "dev": true, "requires": { "async": "^0.9.0", "chokidar": "^1.0.0", "graceful-fs": "^4.1.2" }, "dependencies": { "async": { "version": "0.9.2", "resolved": "https://registry.npmjs.org/async/-/async-0.9.2.tgz", "integrity": "sha1-rqdNXmHB+JlhO/ZL2mbUx48v0X0=", "dev": true } } }, "webpack": { "version": "1.15.0", "resolved": "https://registry.npmjs.org/webpack/-/webpack-1.15.0.tgz", "integrity": "sha1-T/MfU9sDM55VFkqdRo7gMklo/pg=", "dev": true, "requires": { "acorn": "^3.0.0", "async": "^1.3.0", "clone": "^1.0.2", "enhanced-resolve": "~0.9.0", "interpret": "^0.6.4", "loader-utils": "^0.2.11", "memory-fs": "~0.3.0", "mkdirp": "~0.5.0", "node-libs-browser": "^0.7.0", "optimist": "~0.6.0", "supports-color": "^3.1.0", "tapable": "~0.1.8", "uglify-js": "~2.7.3", "watchpack": "^0.2.1", "webpack-core": "~0.6.9" }, "dependencies": { "acorn": { "version": "3.3.0", "resolved": "https://registry.npmjs.org/acorn/-/acorn-3.3.0.tgz", "integrity": "sha1-ReN/s56No/JbruP/U2niu18iAXo=", "dev": true }, "camelcase": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-1.2.1.tgz", "integrity": "sha1-m7UwTS4LVmmLLHWLCKPqqdqlijk=", "dev": true }, "cliui": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/cliui/-/cliui-2.1.0.tgz", "integrity": "sha1-S0dXYP+AJkx2LDoXGQMukcf+oNE=", "dev": true, "requires": { "center-align": "^0.1.1", "right-align": "^0.1.1", "wordwrap": "0.0.2" }, "dependencies": { "wordwrap": { "version": "0.0.2", "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.2.tgz", "integrity": "sha1-t5Zpu0LstAn4PVg8rVLKF+qhZD8=", "dev": true } } }, "has-flag": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz", "integrity": "sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo=", "dev": true }, "interpret": { "version": "0.6.6", "resolved": "https://registry.npmjs.org/interpret/-/interpret-0.6.6.tgz", "integrity": "sha1-/s16GOfOXKar+5U+H4YhOknxYls=", "dev": true }, "source-map": { "version": "0.5.7", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", "dev": true }, "supports-color": { "version": "3.2.3", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz", "integrity": "sha1-ZawFBLOVQXHYpklGsq48u4pfVPY=", "dev": true, "requires": { "has-flag": "^1.0.0" } }, "uglify-js": { "version": "2.7.5", "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-2.7.5.tgz", "integrity": "sha1-RhLAx7qu4rp8SH3kkErhIgefLKg=", "dev": true, "requires": { "async": "~0.2.6", "source-map": "~0.5.1", "uglify-to-browserify": "~1.0.0", "yargs": "~3.10.0" }, "dependencies": { "async": { "version": "0.2.10", "resolved": "https://registry.npmjs.org/async/-/async-0.2.10.tgz", "integrity": "sha1-trvgsGdLnXGXCMo43owjfLUmw9E=", "dev": true } } }, "window-size": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/window-size/-/window-size-0.1.0.tgz", "integrity": "sha1-VDjNLqk7IC76Ohn+iIeu58lPnJ0=", "dev": true }, "yargs": { "version": "3.10.0", "resolved": "https://registry.npmjs.org/yargs/-/yargs-3.10.0.tgz", "integrity": "sha1-9+572FfdfB0tOMDnTvvWgdFDH9E=", "dev": true, "requires": { "camelcase": "^1.0.2", "cliui": "^2.1.0", "decamelize": "^1.0.0", "window-size": "0.1.0" } } } }, "webpack-core": { "version": "0.6.9", "resolved": "https://registry.npmjs.org/webpack-core/-/webpack-core-0.6.9.tgz", "integrity": "sha1-/FcViMhVjad76e+23r3Fo7FyvcI=", "dev": true, "requires": { "source-list-map": "~0.1.7", "source-map": "~0.4.1" }, "dependencies": { "source-map": { "version": "0.4.4", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.4.4.tgz", "integrity": "sha1-66T12pwNyZneaAMti092FzZSA2s=", "dev": true, "requires": { "amdefine": ">=0.0.4" } } } }, "webpack-dev-middleware": { "version": "1.12.2", "resolved": "https://registry.npmjs.org/webpack-dev-middleware/-/webpack-dev-middleware-1.12.2.tgz", "integrity": "sha512-FCrqPy1yy/sN6U/SaEZcHKRXGlqU0DUaEBL45jkUYoB8foVb6wCnbIJ1HKIx+qUFTW+3JpVcCJCxZ8VATL4e+A==", "dev": true, "requires": { "memory-fs": "~0.4.1", "mime": "^1.5.0", "path-is-absolute": "^1.0.0", "range-parser": "^1.0.3", "time-stamp": "^2.0.0" }, "dependencies": { "memory-fs": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/memory-fs/-/memory-fs-0.4.1.tgz", "integrity": "sha1-OpoguEYlI+RHz7x+i7gO1me/xVI=", "dev": true, "requires": { "errno": "^0.1.3", "readable-stream": "^2.0.1" } } } }, "webpack-dev-server": { "version": "1.16.5", "resolved": "https://registry.npmjs.org/webpack-dev-server/-/webpack-dev-server-1.16.5.tgz", "integrity": "sha1-DL1fLSrI1OWTqs1clwLnu9XlmJI=", "dev": true, "requires": { "compression": "^1.5.2", "connect-history-api-fallback": "^1.3.0", "express": "^4.13.3", "http-proxy-middleware": "~0.17.1", "open": "0.0.5", "optimist": "~0.6.1", "serve-index": "^1.7.2", "sockjs": "^0.3.15", "sockjs-client": "^1.0.3", "stream-cache": "~0.0.1", "strip-ansi": "^3.0.0", "supports-color": "^3.1.1", "webpack-dev-middleware": "^1.10.2" }, "dependencies": { "ansi-regex": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", "dev": true }, "has-flag": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz", "integrity": "sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo=", "dev": true }, "strip-ansi": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", "dev": true, "requires": { "ansi-regex": "^2.0.0" } }, "supports-color": { "version": "3.2.3", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz", "integrity": "sha1-ZawFBLOVQXHYpklGsq48u4pfVPY=", "dev": true, "requires": { "has-flag": "^1.0.0" } } } }, "websocket-driver": { "version": "0.7.3", "resolved": "https://registry.npmjs.org/websocket-driver/-/websocket-driver-0.7.3.tgz", "integrity": "sha512-bpxWlvbbB459Mlipc5GBzzZwhoZgGEZLuqPaR0INBGnPAY1vdBX6hPnoFXiw+3yWxDuHyQjO2oXTMyS8A5haFg==", "dev": true, "requires": { "http-parser-js": ">=0.4.0 <0.4.11", "safe-buffer": ">=5.1.0", "websocket-extensions": ">=0.1.1" } }, "websocket-extensions": { "version": "0.1.3", "resolved": "https://registry.npmjs.org/websocket-extensions/-/websocket-extensions-0.1.3.tgz", "integrity": "sha512-nqHUnMXmBzT0w570r2JpJxfiSD1IzoI+HGVdd3aZ0yNi3ngvQ4jv1dtHt5VGxfI2yj5yqImPhOK4vmIh2xMbGg==", "dev": true }, "when": { "version": "3.7.8", "resolved": "https://registry.npmjs.org/when/-/when-3.7.8.tgz", "integrity": "sha1-xxMLan6gRpPoQs3J56Hyqjmjn4I=", "dev": true }, "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" } }, "which-module": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=", "dev": true }, "window-size": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/window-size/-/window-size-0.1.4.tgz", "integrity": "sha1-+OGqHuWlPsW/FR/6CXQqatdpeHY=", "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 }, "wordwrap": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", "integrity": "sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus=" }, "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": "2.4.3", "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-2.4.3.tgz", "integrity": "sha512-GaETH5wwsX+GcnzhPgKcKjJ6M2Cq3/iZp1WyY/X1CSqrW+jVNM9Y7D8EC2sM4ZG/V8wZlSniJnCKWPmBYAucRQ==", "dev": true, "requires": { "graceful-fs": "^4.1.11", "imurmurhash": "^0.1.4", "signal-exit": "^3.0.2" } }, "xml2js": { "version": "0.4.19", "resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.4.19.tgz", "integrity": "sha512-esZnJZJOiJR9wWKMyuvSE1y6Dq5LCuJanqhxslH2bxM6duahNZ+HMpCLhBQGZkbX6xRf8x1Y2eJlgt2q3qo49Q==", "dev": true, "requires": { "sax": ">=0.6.0", "xmlbuilder": "~9.0.1" } }, "xmlbuilder": { "version": "9.0.7", "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-9.0.7.tgz", "integrity": "sha1-Ey7mPS7FVlxVfiD0wi35rKaGsQ0=", "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 }, "y18n": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.0.tgz", "integrity": "sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w==", "dev": true }, "yallist": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=", "dev": true } } } handlebars.js-4.7.7/package.json000066400000000000000000000064551401244020700165410ustar00rootroot00000000000000{ "name": "handlebars", "barename": "handlebars", "version": "4.7.7", "description": "Handlebars provides the power necessary to let you build semantic templates effectively with no frustration", "homepage": "http://www.handlebarsjs.com/", "keywords": [ "handlebars", "mustache", "template", "html" ], "repository": { "type": "git", "url": "https://github.com/wycats/handlebars.js.git" }, "author": "Yehuda Katz", "license": "MIT", "readmeFilename": "README.md", "engines": { "node": ">=0.4.7" }, "dependencies": { "minimist": "^1.2.5", "neo-async": "^2.6.0", "source-map": "^0.6.1", "wordwrap": "^1.0.0" }, "optionalDependencies": { "uglify-js": "^3.1.4" }, "devDependencies": { "@knappi/grunt-saucelabs": "^9.0.2", "aws-sdk": "^2.1.49", "babel-loader": "^5.0.0", "babel-runtime": "^5.1.10", "benchmark": "~1.0", "chai": "^4.2.0", "chai-diff": "^1.0.1", "concurrently": "^5.0.0", "dirty-chai": "^2.0.1", "dtslint": "^0.5.5", "dustjs-linkedin": "^2.0.2", "eco": "~1.1.0-rc-3", "eslint": "^6.7.2", "eslint-config-prettier": "^6.7.0", "eslint-plugin-compat": "^3.3.0", "eslint-plugin-es5": "^1.4.1", "fs-extra": "^8.1.0", "grunt": "^1.0.4", "grunt-babel": "^5.0.0", "grunt-bg-shell": "^2.3.3", "grunt-cli": "^1", "grunt-contrib-clean": "^1", "grunt-contrib-concat": "^1", "grunt-contrib-connect": "^1", "grunt-contrib-copy": "^1", "grunt-contrib-requirejs": "^1", "grunt-contrib-uglify": "^1", "grunt-contrib-watch": "^1.1.0", "grunt-webpack": "^1.0.8", "husky": "^3.1.0", "jison": "~0.3.0", "lint-staged": "^9.5.0", "mocha": "^5", "mock-stdin": "^0.3.0", "mustache": "^2.1.3", "nyc": "^14.1.1", "prettier": "^1.19.1", "semver": "^5.0.1", "sinon": "^7.5.0", "typescript": "^3.4.3", "underscore": "^1.5.1", "webpack": "^1.12.6", "webpack-dev-server": "^1.12.1" }, "main": "lib/index.js", "types": "types/index.d.ts", "browser": { ".": "./dist/cjs/handlebars.js", "./runtime": "./dist/cjs/handlebars.runtime.js" }, "bin": { "handlebars": "bin/handlebars" }, "scripts": { "format": "prettier --write '**/*.js' && eslint --fix .", "check-format": "prettier --check '**/*.js'", "lint": "eslint --max-warnings 0 .", "dtslint": "dtslint types", "test": "grunt", "extensive-tests-and-publish-to-aws": "npx mocha tasks/task-tests/ && grunt --stack extensive-tests-and-publish-to-aws", "integration-test": "grunt integration-tests", "--- combined tasks ---": "", "check-before-pull-request": "concurrently --kill-others-on-fail npm:lint npm:dtslint npm:check-format npm:test" }, "jspm": { "main": "handlebars", "directories": { "lib": "dist/amd" }, "buildConfig": { "minify": true } }, "files": [ "bin", "dist/*.js", "dist/amd/**/*.js", "dist/cjs/**/*.js", "lib", "print-script", "release-notes.md", "runtime.js", "types/*.d.ts", "runtime.d.ts" ], "husky": { "hooks": { "pre-commit": "lint-staged" } }, "lint-staged": { "*.{js,css,json,md}": [ "prettier --write", "git add" ], "*.js": [ "eslint --fix", "git add" ] } } handlebars.js-4.7.7/prettier.config.js000066400000000000000000000001071401244020700176770ustar00rootroot00000000000000module.exports = { tabWidth: 2, semi: true, singleQuote: true }; handlebars.js-4.7.7/print-script000077500000000000000000000053271401244020700166340ustar00rootroot00000000000000#! /usr/bin/env node /* eslint-disable no-console, no-var */ // Util script for debugging source code generation issues var script = process.argv[2].replace(/\\n/g, '\n'), verbose = process.argv[3] === '-v'; var Handlebars = require('./lib'), SourceMap = require('source-map'), SourceMapConsumer = SourceMap.SourceMapConsumer; var template = Handlebars.precompile(script, { srcName: 'input.hbs', destName: 'output.js', assumeObjects: true, compat: false, strict: true, trackIds: true, knownHelpersOnly: false }); if (!verbose) { console.log(template); } else { var consumer = new SourceMapConsumer(template.map), lines = template.code.split('\n'), srcLines = script.split('\n'); console.log(); console.log('Source:'); srcLines.forEach(function(source, index) { console.log(index + 1, source); }); console.log(); console.log('Generated:'); console.log(template.code); lines.forEach(function(source, index) { console.log(index + 1, source); }); console.log(); console.log('Map:'); console.log(template.map); console.log(); function collectSource(lines, lineName, colName, order) { var ret = {}, ordered = [], last; function collect(current) { if (last) { var mapLines = lines.slice(last[lineName] - 1, current && current[lineName]); if (mapLines.length) { if (current) { mapLines[mapLines.length - 1] = mapLines[mapLines.length - 1].slice(0, current[colName]); } mapLines[0] = mapLines[0].slice(last[colName]); } ret[last[lineName] + ':' + last[colName]] = mapLines.join('\n'); ordered.push({ startLine: last[lineName], startCol: last[colName], endLine: current && current[lineName] }); } last = current; } consumer.eachMapping(collect, undefined, order); collect(); return ret; } srcLines = collectSource(srcLines, 'originalLine', 'originalColumn', SourceMapConsumer.ORIGINAL_ORDER); lines = collectSource(lines, 'generatedLine', 'generatedColumn'); consumer.eachMapping(function(mapping) { var originalSrc = srcLines[mapping.originalLine + ':' + mapping.originalColumn], generatedSrc = lines[mapping.generatedLine + ':' + mapping.generatedColumn]; if (!mapping.originalLine) { console.log('generated', mapping.generatedLine + ':' + mapping.generatedColumn, generatedSrc); } else { console.log('map', mapping.source, mapping.originalLine + ':' + mapping.originalColumn, originalSrc, '->', mapping.generatedLine + ':' + mapping.generatedColumn, generatedSrc); } }); } handlebars.js-4.7.7/release-notes.md000066400000000000000000001667241401244020700173510ustar00rootroot00000000000000# Release Notes ## Development [Commits](https://github.com/handlebars-lang/handlebars.js/compare/v4.7.7...master) ## v4.7.7 - February 15th, 2021 - fix weird error in integration tests - eb860c0 - fix: check prototype property access in strict-mode (#1736) - b6d3de7 - fix: escape property names in compat mode (#1736) - f058970 - refactor: In spec tests, use expectTemplate over equals and shouldThrow (#1683) - 77825f8 - chore: start testing on Node.js 12 and 13 - 3789a30 (POSSIBLY) BREAKING CHANGES: - the changes from version [4.6.0](https://github.com/handlebars-lang/handlebars.js/blob/master/release-notes.md#v460---january-8th-2020) now also apply in when using the compile-option "strict: true". Access to prototype properties is forbidden completely by default, specific properties or methods can be allowed via runtime-options. See #1633 for details. If you are using Handlebars as documented, you should not be accessing prototype properties from your template anyway, so the changes should not be a problem for you. Only the use of undocumented features can break your build. That is why we only bump the patch version despite mentioning breaking changes. [Commits](https://github.com/wycats/handlebars.js/compare/v4.7.6...v4.7.7) ## v4.7.6 - April 3rd, 2020 Chore/Housekeeping: - [#1672](https://github.com/wycats/handlebars.js/issues/1672) - Switch cmd parser to latest minimist ([@dougwilson](https://api.github.com/users/dougwilson) Compatibility notes: - Restored Node.js compatibility [Commits](https://github.com/wycats/handlebars.js/compare/v4.7.5...v4.7.6) ## v4.7.5 - April 2nd, 2020 Chore/Housekeeping: - ~Node.js version support has been changed to v6+~ Reverted in 4.7.6 Compatibility notes: - ~Node.js < v6 is no longer supported~ Reverted in 4.7.6 [Commits](https://github.com/wycats/handlebars.js/compare/v4.7.4...v4.7.5) ## v4.7.4 - April 1st, 2020 Chore/Housekeeping: - [#1666](https://github.com/wycats/handlebars.js/issues/1666) - Replaced minimist with yargs for handlebars CLI ([@aorinevo](https://api.github.com/users/aorinevo), [@AviVahl](https://api.github.com/users/AviVahl) & [@fabb](https://api.github.com/users/fabb)) Compatibility notes: - No incompatibilities are to be expected [Commits](https://github.com/wycats/handlebars.js/compare/v4.7.3...v4.7.4) ## v4.7.3 - February 5th, 2020 Chore/Housekeeping: - [#1644](https://github.com/wycats/handlebars.js/issues/1644) - Download links to aws broken on handlebarsjs.com - access denied ([@Tea56](https://api.github.com/users/Tea56)) - Fix spelling and punctuation in changelog - d78cc73 Bugfixes: - Add Type Definition for Handlebars.VERSION, Fixes #1647 - 4de51fe - Include Type Definition for runtime.js in Package - a32d05f Compatibility notes: - No incompatibilities are to be expected [Commits](https://github.com/wycats/handlebars.js/compare/v4.7.2...v4.7.3) ## v4.7.2 - January 13th, 2020 Bugfixes: - fix: don't wrap helpers that are not functions - 9d5aa36, #1639 Chore/Build: - chore: execute saucelabs-task only if access-key exists - a4fd391 Compatibility notes: - No breaking changes are to be expected [Commits](https://github.com/wycats/handlebars.js/compare/v4.7.1...v4.7.2) ## v4.7.1 - January 12th, 2020 Bugfixes: - fix: fix log output in case of illegal property access - f152dfc - fix: log error for illegal property access only once per property - 3c1e252 Compatibility notes: - no incompatibilities are to be expected. [Commits](https://github.com/wycats/handlebars.js/compare/v4.7.0...v4.7.1) ## v4.7.0 - January 10th, 2020 Features: - feat: default options for controlling proto access - 7af1c12, #1635 - This makes it possible to disable the prototype access restrictions added in 4.6.0 - an error is logged in the console, if access to prototype properties is attempted and denied and no explicit configuration has taken place. Compatibility notes: - no compatibilities are expected [Commits](https://github.com/wycats/handlebars.js/compare/v4.6.0...v4.7.0) ## v4.6.0 - January 8th, 2020 Features: - feat: access control to prototype properties via whitelist (#1633)- d03b6ec Bugfixes: - fix(runtime.js): partials compile not caching (#1600) - 23d58e7 Chores, docs: - various refactorings and improvements to tests - d7f0dcf, 187d611, d337f40 - modernize the build-setup - use prettier to format and eslint to verify - c40d9f3, 8901c28, e97685e, 1f61f21 - use nyc instead of istanbul to collect coverage - 164b7ff, 1ebce2b - update build code to use modern javascript and make it cleaner - 14b621c, 1ec1737, 3a5b65e, dde108e, 04b1984, 587e7a3 - restructur build commands - e913dc5, - eslint rule changes - ac4655e, dc54952 - Update (C) year in the LICENSE file - d1fb07b - chore: try to fix saucelabs credentials (#1627) - - Update readme.md with updated links (#1620) - edcc84f BREAKING CHANGES: - access to prototype properties is forbidden completely by default, specific properties or methods can be allowed via runtime-options. See #1633 for details. If you are using Handlebars as documented, you should not be accessing prototype properties from your template anyway, so the changes should not be a problem for you. Only the use of undocumented features can break your build. That is why we only bump the minor version despite mentioning breaking changes. [Commits](https://github.com/wycats/handlebars.js/compare/v4.5.3...v4.6.0) ## v4.5.3 - November 18th, 2019 Bugfixes: - fix: add "no-prototype-builtins" eslint-rule and fix all occurences - f7f05d7 - fix: add more properties required to be enumerable - 1988878 Chores / Build: - fix: use !== 0 instead of != 0 - c02b05f - add chai and dirty-chai and sinon, for cleaner test-assertions and spies, deprecate old assertion-methods - 93e284e, 886ba86, 0817dad, 93516a0 Security: - The properties `__proto__`, `__defineGetter__`, `__defineSetter__` and `__lookupGetter__` have been added to the list of "properties that must be enumerable". If a property by that name is found and not enumerable on its parent, it will silently evaluate to `undefined`. This is done in both the compiled template and the "lookup"-helper. This will prevent new Remote-Code-Execution exploits that have been published recently. Compatibility notes: - Due to the security-fixes. The semantics of the templates using `__proto__`, `__defineGetter__`, `__defineSetter__` and `__lookupGetter__` in the respect that those expression now return `undefined` rather than their actual value from the proto. - The semantics have not changed in cases where the properties are enumerable, as in: ```js { __proto__: 'some string'; } ``` - The change may be breaking in that respect, but we still only increase the patch-version, because the incompatible use-cases are not intended, undocumented and far less important than fixing Remote-Code-Execution exploits on existing systems. [Commits](https://github.com/wycats/handlebars.js/compare/v4.5.2...v4.5.3) ## v4.5.2 - November 13th, 2019 # Bugfixes - fix: use String(field) in lookup when checking for "constructor" - d541378 - test: add fluent API for testing Handlebars - c2ac79c Compatibility notes: - no incompatibility are to be expected [Commits](https://github.com/wycats/handlebars.js/compare/v4.5.1...v4.5.2) ## v4.5.1 - October 29th, 2019 Bugfixs - fix: move "eslint-plugin-compat" to devDependencies - 5e9d17f (#1589) Compatibility notes: - No compatibility issues are to be expected [Commits](https://github.com/wycats/handlebars.js/compare/v4.5.0...v4.5.1) ## v4.5.0 - October 28th, 2019 Features / Improvements - Add method Handlebars.parseWithoutProcessing (#1584) - 62ed3c2 - add guard to if & unless helpers (#1549) - show source location for the strict lookup exceptions - feb60f8 Bugfixes: - Use objects for hash value tracking - 7fcf9d2 Chore: - Resolve deprecation warning message from eslint while running eslint (#1586) - 7052e88 - chore: add eslint-plugin-compat and eslint-plugin-es5 - 088e618 Compatibility notes: - No compatibility issues are to be expected [Commits](https://github.com/wycats/handlebars.js/compare/v4.4.5...v4.5.0) ## v4.4.5 - October 20th, 2019 Bugfixes: - Contents of raw-blocks must be matched with non-eager regex-matching - 8d5530e, #1579 [Commits](https://github.com/wycats/handlebars.js/compare/v4.4.4...v4.4.5) ## v4.4.4 - October 20th, 2019 Bugfixes: - fix: prevent zero length tokens in raw-blocks (#1577, #1578) - f1752fe Chore: - chore: link to s3 bucket with https, add "npm ci" to build instructions - 0b593bf Compatibility notes: - no compatibility issues are expected [Commits](https://github.com/wycats/handlebars.js/compare/v4.4.3...v4.4.4) ## v4.4.3 - October 8th, 2019 Bugfixes Typings: - add missing type fields to AST typings and add tests for them - 0440af2 [Commits](https://github.com/wycats/handlebars.js/compare/v4.4.2...v4.4.3) ## v4.4.2 - October 2nd, 2019 - chore: fix grunt-saucelabs dependency - b7eada0 [Commits](https://github.com/wycats/handlebars.js/compare/v4.4.1...v4.4.2) ## v4.4.1 - October 2nd, 2019 - [#1562](https://github.com/wycats/handlebars.js/issues/1562) - Error message for syntax error missing location in 4.2.1+ [Commits](https://github.com/wycats/handlebars.js/compare/v4.4.0...v4.4.1) ## v4.4.0 - September 29th, 2019 - Added support for iterable objects in {{#each}} helper (#1557) - cf7545e [Commits](https://github.com/wycats/handlebars.js/compare/v4.3.4...v4.4.0) ## v4.3.4 - September 28th, 2019 - fix: harden "propertyIsEnumerable"-check - ff4d827 Compatibility notes: - No incompatibilities are known. [Commits](https://github.com/wycats/handlebars.js/compare/v4.3.3...v4.3.4) ## v4.3.3 - September 27th, 2019 - fix test case for browsers that do not support **defineGetter** - 8742bde [Commits](https://github.com/wycats/handlebars.js/compare/v4.3.2...v4.3.3) ## v4.3.2 - September 26th, 2019 - Use Object.prototype.propertyIsEnumerable to check for constructors - 213c0bb, #1563 Compatibility notes: - There are no breaking changes [Commits](https://github.com/wycats/handlebars.js/compare/v4.3.1...v4.3.2) ## v4.3.1 - September 25th, 2019 Fixes: - do not break on precompiled templates from Handlebars >=4.0.0 <4.3.0 - 1266838, #1561 - Ensure allowCallsToHelperMissing runtime option is optional in typings - 93444c5, 64ecb9e, #1560 [Commits](https://github.com/wycats/handlebars.js/compare/v4.3.0...v4.3.1) ## v4.3.0 - September 24th, 2019 Fixes: - Security: Disallow calling "helperMissing" and "blockHelperMissing" directly - 2078c72 - Disallow calling "helperMissing" and "blockHelperMissing" directly - 2078c72 Features: - Add new runtime option `allowCallsToHelperMissing` to allow calling `blockHelperMissing` and `helperMissing`. Breaking changes: Compatibility notes: - Compiler revision increased - 06b7224 - This means that template compiled with versions prior to 4.3.0 will not work with runtimes >= 4.3.0 The increase was done because the "helperMissing" and "blockHelperMissing" are now moved from the helpers to the internal "container.hooks" object, so old templates will not be able to call them anymore. We suggest that you always recompile your templates with the latest compiler in your build pipelines. - Disallow calling "helperMissing" and "blockHelperMissing" directly - 2078c72 - Calling "helperMissing" and "blockHelperMissing" directly from a template (like in `{{blockHelperMissing}}` was never intended and was part of the exploits that have been revealed early in 2019 (see https://github.com/wycats/handlebars.js/issues/1495). _It is also part of a new exploit that is not captured by the earlier fix._ In order to harden Handlebars against such exploits, calling thos helpers is now not possible anymore. _Overriding_ those helpers is still possible. - If you really need this behavior, you can set the runtime option `allowCallsToHelperMissing` to `true` and the calls will again be possible Both bullet points imly that Handlebars is not 100% percent compatible to 4.2.0, despite the minor version bump. We consider it more important to resolve a major security issue than to maintain 100% compatibility. [Commits](https://github.com/wycats/handlebars.js/compare/v4.2.1...v4.3.0) ## v4.2.1 - September 20th, 2019 Bugfixes: - The "browser" property in the package.json has been updated to use the common-js builds instead of the minified UMD - c55a7be, #1553 Compatibility notes: - No compatibility issues should arise [Commits](https://github.com/wycats/handlebars.js/compare/v4.2.0...v4.2.1) ## v4.2.0 - September 3rd, 2019 Chore/Test: - Use custom `grunt-saucelab` with current sauce-connect proxy - f119497 - Add framework for various integration tests - f9cce4d - Add integration test for webpack - a57b682 Bugfixes: - [#1544](https://github.com/wycats/handlebars.js/issues/1544) - Typescript types: `knownHelpers` doesnt allow for custom helpers ([@NickCis](https://api.github.com/users/NickCis)) - [#1534](https://github.com/wycats/handlebars.js/pull/1534) - Add typings for "Handlebars.VM.resolvePartial ([@AndrewLeedham](https://api.github.com/users/AndrewLeedham)) Features: - [#1540](https://github.com/wycats/handlebars.js/pull/1540) - added "browser"-property to package.json, resolves #1102 ([@ouijan](https://api.github.com/users/ouijan)) Compatibility notes: - The new "browser"-property should not break anything, but you can never be sure. The integration test for webpack shows that it works, but if it doesn't please open an issue. [Commits](https://github.com/wycats/handlebars.js/compare/v4.1.2-0...v4.2.0) ## v4.1.2-0 - August 25th, 2019 [#1540](https://github.com/wycats/handlebars.js/pull/1540) - added browser to package.json, resolves #1102 ([@ouijan](https://api.github.com/users/ouijan)) Compatibility notes: - We are not sure if imports via webpack are still working, which is why this release is a pre-release [Commits](https://github.com/wycats/handlebars.js/compare/v4.1.2...v4.1.2-0) ## v4.1.2 - April 13th, 2019 Chore/Test: - [#1515](https://github.com/wycats/handlebars.js/pull/1515) - Port over linting and test for typings ([@zimmi88](https://api.github.com/users/zimmi88)) - chore: add missing typescript dependency, add package-lock.json - 594f1e3 - test: remove safari from saucelabs - 871accc Bugfixes: - fix: prevent RCE through the "lookup"-helper - cd38583 Compatibility notes: Access to the constructor of a class thought `{{lookup obj "constructor" }}` is now prohibited. This closes a leak that only half closed in versions 4.0.13 and 4.1.0, but it is a slight incompatibility. This kind of access is not the intended use of Handlebars and leads to the vulnerability described in #1495. We will **not** increase the major version, because such use is not intended or documented, and because of the potential impact of the issue (we fear that most people won't use a new major version and the issue may not be resolved on many systems). [Commits](https://github.com/wycats/handlebars.js/compare/v4.1.1...v4.1.2) ## v4.1.1 - March 16th, 2019 Bugfixes: - fix: add "runtime.d.ts" to allow "require('handlebars/runtime')" in TypeScript - 5cedd62 Refactorings: - replace "async" with "neo-async" - 048f2ce - use "substring"-function instead of "substr" - 445ae12 Compatibility notes: - This is a bugfix release. There are no breaking change and no new features. [Commits](https://github.com/wycats/handlebars.js/compare/v4.1.0...v4.1.1) ## v4.1.0 - February 7th, 2019 New Features - import TypeScript typings - 27ac1ee Security fixes: - disallow access to the constructor in templates to prevent RCE - 42841c4, #1495 Housekeeping - chore: fix components/handlebars package.json and auto-update on release - bacd473 - chore: Use node 10 to build handlebars - 78dd89c - chore/doc: Add more release docs - 6b87c21 Compatibility notes: Access to class constructors (i.e. `({}).constructor`) is now prohibited to prevent Remote Code Execution. This means that following construct will no work anymore: ``` class SomeClass { } SomeClass.staticProperty = 'static' var template = Handlebars.compile('{{constructor.staticProperty}}'); document.getElementById('output').innerHTML = template(new SomeClass()); // expected: 'static', but now this is empty. ``` This kind of access is not the intended use of Handlebars and leads to the vulnerability described in #1495. We will **not** increase the major version, because such use is not intended or documented, and because of the potential impact of the issue (we fear that most people won't use a new major version and the issue may not be resolved on many systems). [Commits](https://github.com/wycats/handlebars.js/compare/v4.0.12...v4.1.0) ## v4.0.12 - September 4th, 2018 New features: - none Various dependency updates - [#1464](https://github.com/wycats/handlebars.js/pull/1464) - Bump versions of grunt-plugins to 1.x - [#1398](https://github.com/wycats/handlebars.js/pull/1398) - Chore: updated various dev dependencies - upgrade uglify-js - d3d3942 - Update grunt-eslint to 20.1.0 - 7729aa9 - Update dependencies "async" to 2.5.0 and "source-map" to 0.6.1 (73d5637) Bugfixes: - [components/handlebars.js#24](https://github.com/components/handlebars.js#24) Add package.json to components shim - Updated `source-map`-package should work better with `rollup`[#1463](https://github.com/wycats/handlebars.js/issues/1463) Removed obsolete code: - unnecessary check - 0ddff8b - Use `files` field - 69c6ca5 - Update jsfiddle to 4.0.11 - 8947dd0 Compatibility notes: - No compatibility issues are to be expected [Commits](https://github.com/wycats/handlebars.js/compare/v4.0.11...v4.0.12) ## v4.0.11 - October 17th, 2017 - [#1391](https://github.com/wycats/handlebars.js/issues/1391) - `uglify-js` is unconditionally imported, but only listed as optional dependency ([@Turbo87](https://github.com/Turbo87)) - [#1233](https://github.com/wycats/handlebars.js/issues/1233) - Unable to build under windows - error at test:bin task ([@blikblum](https://github.com/blikblum)) - Update (C) year in the LICENSE file - 21386b6 Compatibility notes: - This is a bugfix release. There are no breaking change and no new features. [Commits](https://github.com/wycats/handlebars.js/compare/v4.0.10...v4.0.11) ## v4.0.10 - May 21st, 2017 - Fix regression in 4.0.9: Replace "Object.assign" (not support in IE) by "util/extend" - 0e953d1 [Commits](https://github.com/wycats/handlebars.js/compare/v4.0.9...v4.0.10) ## v4.0.9 - May 21st, 2017 - [#1327](https://github.com/wycats/handlebars.js/issues/1327) Handlebars.compile() does not modify "options" anymore - pending [#1331](https://github.com/wycats/handlebars.js/issues/1331) Attempts to build Handlebars in a Windows environment - Fix build in windows - cc554a5 - Ensure LF line-edings in handlebars-template fixtures (\*.hbs) - ed879a6 - Run integration test with `node handlebars -a ...` on Windows - 2e21e2b - Ensure LF line-edings in lexer-files (\*.l) - bdfdbea - Force LF line-endings for spec/artifacts - b50ef03 - Use istanbul/lib/cli.js instead of node_modules/.bin/istanbul - 6e6269f - TravisCI: Publish valid semver tags independently of the branch - 7378f85 Compatibility notes: - No compatibility issues are expected. [Commits](https://github.com/wycats/handlebars.js/compare/v4.0.8...v4.0.9) ## v4.0.8 - May 2nd, 2017 - [#1341](https://github.com/wycats/handlebars.js/issues/1341) [#1342](https://github.com/wycats/handlebars.js/issues/1342) Allow partial-blocks to be executed without "options" ([@nknapp](https://github.com/nknapp)) - a00c598 Compatibility notes: - No breaking changes [Commits](https://github.com/wycats/handlebars.js/compare/v4.0.7...v4.0.8) ## v4.0.7 - April 29th, 2017 - [#1319](https://github.com/wycats/handlebars.js/issues/1319): Fix context-stack when calling block-helpers on null values ([@nknapp](https://github.com/nknapp)) - c8f4b57 - [#1315](https://github.com/wycats/handlebars.js/pull/1315) Parser: Change suffix to use ES6 default module export ([@Turbo87](https://github.com/Turbo87))- b617375 - [#1290](https://github.com/wycats/handlebars.js/pull/1290) [#1252](https://github.com/wycats/handlebars.js/issue/1290) Add more tests for partial-blocks and inline partials ([@nknapp](https://github.com/nknapp)) - 63a8e0c - [#1252](https://github.com/wycats/handlebars.js/issue/1290) Using @partial-block twice in a template not possible ([@nknapp](https://github.com/nknapp)) - 5a164d0 - [#1310](https://github.com/wycats/handlebars.js/pull/1310) Avoid duplicate "sourceMappingURL=" lines. ([@joonas-lahtinen](https://github.com/joonas-lahtinen)) - 01b0f65 - [#1275](https://github.com/wycats/handlebars.js/pull/1275) require('sys') is deprecated, using 'util' instead ([@travnels](https://github.com/travnels)) - 406f2ee - [#1285](https://github.com/wycats/handlebars.js/pull/1285) [#1284](https://github.com/wycats/handlebars.js/issues/1284) Make "column"-property of Errors enumerable ([@nknapp](https://github.com/nknapp)) - a023cb4 - [#1285](https://github.com/wycats/handlebars.js/pull/1285) Testcase to verify that compile-errors have a column-property ([@nknapp](https://github.com/nknapp)) - c7dc353 [Commits](https://github.com/wycats/handlebars.js/compare/v4.0.6...v4.0.7) ## v4.0.6 - November 12th, 2016 - [#1243](https://github.com/wycats/handlebars.js/pull/1243) - Walk up data frames for nested @partial-block ([@lawnsea](https://github.com/lawnsea)) - [#1210](https://github.com/wycats/handlebars.js/pull/1210) - Add a new lightweight package based on handlebars in the README ([@kabirbaidhya](https://github.com/kabirbaidhya)) - [#1187](https://github.com/wycats/handlebars.js/pull/1187) - Ensure that existing blockParams and depths are respected on dupe programs ([@charleso](https://github.com/charleso)) - [#1191](https://github.com/wycats/handlebars.js/pull/1191) - Added cory ([@leo](https://github.com/leo)) - [#1177](https://github.com/wycats/handlebars.js/pull/1177) - Preserve License info in Closure Compiler ([@gennadiylitvinyuk](https://github.com/gennadiylitvinyuk)) - [#1171](https://github.com/wycats/handlebars.js/pull/1171) - Contributing doc fix: failing thats -> failing tests ([@paulfalgout](https://github.com/paulfalgout)) - [#1166](https://github.com/wycats/handlebars.js/pull/1166) - Update license date ([@timwangdev](https://github.com/timwangdev)) - Update jsfiddle to point to latest - 959ee55 (originally dfc7554 by [@kpdecker](https://github.com/kpdecker)) - [#1163](https://github.com/wycats/handlebars.js/pull/1163) - Fix typos on decorators-api.md. ([@adjohnson916](https://github.com/adjohnson916)) - Drop extra Error params - 8c19874 (originally 63fdb92 by [@kpdecker](https://github.com/kpdecker)) - [#1153](https://github.com/wycats/handlebars.js/pull/1153) - Add documentation for running tests to contributing.md ([@ryanmurakami](https://github.com/ryanmurakami)) - Avoid error in older browsers in test - 400916c (originally a6121ca by [@kpdecker](https://github.com/kpdecker)) - Update target browser test versions - fee2334 (originally 871c32a by [@kpdecker](https://github.com/kpdecker)) - Exclude coverage check in exception conditional - 32d6363 (originally 326734b by [@kpdecker](https://github.com/kpdecker)) - Fix throw when creating exception object in Safari - 20c965c (originally 2ea6119 by [@kpdecker](https://github.com/kpdecker)) - Update build for modern node versions - 6c9f98c (originally 8289c0b by [@kpdecker](https://github.com/kpdecker)) - [#1135](https://github.com/wycats/handlebars.js/issues/1135) - Relax depth check for context push - c393c81 (originally 25458fd by [@kpdecker](https://github.com/kpdecker)) [Commits](https://github.com/wycats/handlebars.js/compare/v4.0.5...v4.0.6) ## v4.0.5 - November 19th, 2015 - [#1132](https://github.com/wycats/handlebars.js/pull/1132) - Update uglify-js to avoid vulnerability ([@plynchnlm](https://github.com/plynchnlm)) - [#1129](https://github.com/wycats/handlebars.js/issues/1129) - Minified lib returns an empty string ([@bricss](https://github.com/bricss)) - Return current handlebars instance from noConflict - 685cf92 - Add webpack to dev dependency to support npm 3 - 7a6c228 - Further relax uglify dependency - 0a3b3c2 - Include tests for minimized artifacts - c21118d - Fix lint errors under latest eslint - 9f59de9 - Add print-script helper script - 98a6717 [Commits](https://github.com/wycats/handlebars.js/compare/v4.0.4...v4.0.5) ## v4.0.4 - October 29th, 2015 - [#1121](https://github.com/wycats/handlebars.js/pull/1121) - Include partial name in 'undefined partial' exception message ([@shinypb](https://github.com/shinypb)) - [#1125](https://github.com/wycats/handlebars.js/pull/1125) - Add promised-handlebars to "in-the-wild"-list ([@nknapp](https://github.com/nknapp)) [Commits](https://github.com/wycats/handlebars.js/compare/v4.0.3...v4.0.4) ## v4.0.3 - September 23rd, 2015 - [#1099](https://github.com/wycats/handlebars.js/issues/1099) - @partial-block is overridden ([@btmorex](https://github.com/btmorex)) - [#1093](https://github.com/wycats/handlebars.js/issues/1093) - #each skips iteration on undefined values ([@florianpilz](https://github.com/florianpilz)) - [#1092](https://github.com/wycats/handlebars.js/issues/1092) - Square braces in key name ([@distantnative](https://github.com/distantnative)) - [#1091](https://github.com/wycats/handlebars.js/pull/1091) - fix typo in release notes ([@nikolas](https://github.com/nikolas)) - [#1090](https://github.com/wycats/handlebars.js/pull/1090) - grammar fixes in 4.0.0 release notes ([@nikolas](https://github.com/nikolas)) Compatibility notes: - `each` iteration with `undefined` values has been restored to the 3.0 behaviors. Helper calls with undefined context values will now execute against an arbitrary empty object to avoid executing against global object in non-strict mode. - `]` can now be included in `[]` wrapped identifiers by escaping with `\`. Any `[]` identifiers that include `\` will now have to properly escape these values. [Commits](https://github.com/wycats/handlebars.js/compare/v4.0.2...v4.0.3) ## v4.0.2 - September 4th, 2015 - [#1089](https://github.com/wycats/handlebars.js/issues/1089) - "Failover content" not working in multiple levels of inline partials ([@michaellopez](https://github.com/michaellopez)) [Commits](https://github.com/wycats/handlebars.js/compare/v4.0.1...v4.0.2) ## v4.0.1 - September 2nd, 2015 - Fix failure when using decorators in partials - 05b82a2 [Commits](https://github.com/wycats/handlebars.js/compare/v4.0.0...v4.0.1) ## v4.0.0 - September 1st, 2015 - [#1082](https://github.com/wycats/handlebars.js/pull/1082) - Decorators and Inline Partials ([@kpdecker](https://github.com/kpdecker)) - [#1076](https://github.com/wycats/handlebars.js/pull/1076) - Implement partial blocks ([@kpdecker](https://github.com/kpdecker)) - [#1087](https://github.com/wycats/handlebars.js/pull/1087) - Fix #each when last object entry has empty key ([@denniskuczynski](https://github.com/denniskuczynski)) - [#1084](https://github.com/wycats/handlebars.js/pull/1084) - Bump uglify version to fix vulnerability ([@John-Steidley](https://github.com/John-Steidley)) - [#1068](https://github.com/wycats/handlebars.js/pull/1068) - Fix typo ([@0xack13](https://github.com/0xack13)) - [#1060](https://github.com/wycats/handlebars.js/pull/1060) - #1056 Fixed grammar for nested raw blocks ([@ericbn](https://github.com/ericbn)) - [#1052](https://github.com/wycats/handlebars.js/pull/1052) - Updated year in License ([@maqnouch](https://github.com/maqnouch)) - [#1037](https://github.com/wycats/handlebars.js/pull/1037) - Fix minor typos in README ([@tomxtobin](https://github.com/tomxtobin)) - [#1032](https://github.com/wycats/handlebars.js/issues/1032) - Is it possible to render a partial without the parent scope? ([@aputinski](https://github.com/aputinski)) - [#1019](https://github.com/wycats/handlebars.js/pull/1019) - Fixes typo in tests ([@aymerick](https://github.com/aymerick)) - [#1016](https://github.com/wycats/handlebars.js/issues/1016) - Version mis-match ([@mayankdedhia](https://github.com/mayankdedhia)) - [#1023](https://github.com/wycats/handlebars.js/issues/1023) - is it possible for nested custom helpers to communicate between each other? - [#893](https://github.com/wycats/handlebars.js/issues/893) - [Proposal] Section blocks. - [#792](https://github.com/wycats/handlebars.js/issues/792) - feature request: inline partial definitions - [#583](https://github.com/wycats/handlebars.js/issues/583) - Parent path continues to drill down depth with multiple conditionals - [#404](https://github.com/wycats/handlebars.js/issues/404) - Add named child helpers that can be referenced by block helpers - Escape = in HTML content - [83b8e84](https://github.com/wycats/handlebars.js/commit/83b8e84) - Drop AST constructors in favor of JSON - [95d84ba](https://github.com/wycats/handlebars.js/commit/95d84ba) - Pass container rather than exec as context - [9a2d1d6](https://github.com/wycats/handlebars.js/commit/9a2d1d6) - Add ignoreStandalone compiler option - [ea3a5a1](https://github.com/wycats/handlebars.js/commit/ea3a5a1) - Ignore empty when iterating on sparse arrays - [06d515a](https://github.com/wycats/handlebars.js/commit/06d515a) - Add support for string and stdin precompilation - [0de8dac](https://github.com/wycats/handlebars.js/commit/0de8dac) - Simplify object assignment generation logic - [77e6bfc](https://github.com/wycats/handlebars.js/commit/77e6bfc) - Bulletproof AST.helpers.helperExpression - [93b0760](https://github.com/wycats/handlebars.js/commit/93b0760) - Always return string responses - [8e868ab](https://github.com/wycats/handlebars.js/commit/8e868ab) - Pass undefined fields to helpers in strict mode - [5d4b8da](https://github.com/wycats/handlebars.js/commit/5d4b8da) - Avoid depth creation when context remains the same - [279e038](https://github.com/wycats/handlebars.js/commit/279e038) - Improve logging API - [9a49d35](https://github.com/wycats/handlebars.js/commit/9a49d35) - Fix with operator in no @data mode - [231a8d7](https://github.com/wycats/handlebars.js/commit/231a8d7) - Allow empty key name in each iteration - [1bb640b](https://github.com/wycats/handlebars.js/commit/1bb640b) - Add with block parameter support - [2a85106](https://github.com/wycats/handlebars.js/commit/2a85106) - Fix escaping of non-javascript identifiers - [410141c](https://github.com/wycats/handlebars.js/commit/410141c) - Fix location information for programs - [93faffa](https://github.com/wycats/handlebars.js/commit/93faffa) Compatibility notes: - Depthed paths are now conditionally pushed on to the stack. If the helper uses the same context, then a new stack is not created. This leads to behavior that better matches expectations for helpers like `if` that do not seem to alter the context. Any instances of `../` in templates will need to be checked for the correct behavior under 4.0.0. In general templates will either reduce the number of `../` instances or leave them as is. See [#1028](https://github.com/wycats/handlebars.js/issues/1028). - The `=` character is now HTML escaped. This closes a potential exploit case when using unquoted attributes, i.e. `
`. In general it's recommended that attributes always be quoted when their values are generated from a mustache to avoid any potential exploit surfaces. - AST constructors have been dropped in favor of plain old javascript objects - The runtime version has been increased. Precompiled templates will need to use runtime of at least 4.0.0. [Commits](https://github.com/wycats/handlebars.js/compare/v3.0.3...v4.0.0) ## v3.0.3 - April 28th, 2015 - [#1004](https://github.com/wycats/handlebars.js/issues/1004) - Latest version breaks with RequireJS (global is undefined) ([@boskee](https://github.com/boskee)) [Commits](https://github.com/wycats/handlebars.js/compare/v3.0.2...v3.0.3) ## v3.0.2 - April 20th, 2015 - [#998](https://github.com/wycats/handlebars.js/pull/998) - Add full support for es6 ([@kpdecker](https://github.com/kpdecker)) - [#994](https://github.com/wycats/handlebars.js/issues/994) - Access Handlebars.Visitor in browser ([@tamlyn](https://github.com/tamlyn)) - [#990](https://github.com/wycats/handlebars.js/issues/990) - Allow passing null/undefined literals subexpressions ([@blimmer](https://github.com/blimmer)) - [#989](https://github.com/wycats/handlebars.js/issues/989) - Source-map error with requirejs ([@SteppeEagle](https://github.com/SteppeEagle)) - [#967](https://github.com/wycats/handlebars.js/issues/967) - can't access "this" property ([@75lb](https://github.com/75lb)) - Use captureStackTrace for error handler - a009a97 - Ignore branches tested without coverage monitoring - 37a664b [Commits](https://github.com/wycats/handlebars.js/compare/v3.0.1...v3.0.2) ## v3.0.1 - March 24th, 2015 - [#984](https://github.com/wycats/handlebars.js/pull/984) - Adding documentation for passing arguments into partials ([@johneke](https://github.com/johneke)) - [#973](https://github.com/wycats/handlebars.js/issues/973) - version 3 is slower than version 2 ([@elover](https://github.com/elover)) - [#966](https://github.com/wycats/handlebars.js/issues/966) - "handlebars --version" does not work with v3.0.0 ([@abloomston](https://github.com/abloomston)) - [#964](https://github.com/wycats/handlebars.js/pull/964) - default is a reserved word ([@grassick](https://github.com/grassick)) - [#962](https://github.com/wycats/handlebars.js/pull/962) - Add dashbars' link on README. ([@pismute](https://github.com/pismute)) [Commits](https://github.com/wycats/handlebars.js/compare/v3.0.0...v3.0.1) ## v3.0.0 - February 10th, 2015 - [#941](https://github.com/wycats/handlebars.js/pull/941) - Add support for dynamic partial names ([@kpdecker](https://github.com/kpdecker)) - [#940](https://github.com/wycats/handlebars.js/pull/940) - Add missing reserved words so compiler knows to use array syntax: ([@mattflaschen](https://github.com/mattflaschen)) - [#938](https://github.com/wycats/handlebars.js/pull/938) - Fix example using #with helper ([@diwo](https://github.com/diwo)) - [#930](https://github.com/wycats/handlebars.js/pull/930) - Add parent tracking and mutation to AST visitors ([@kpdecker](https://github.com/kpdecker)) - [#926](https://github.com/wycats/handlebars.js/issues/926) - Depthed lookups fail when program duplicator runs ([@kpdecker](https://github.com/kpdecker)) - [#918](https://github.com/wycats/handlebars.js/pull/918) - Add instructions for 'spec/mustache' to CONTRIBUTING.md, fix a few typos ([@oneeman](https://github.com/oneeman)) - [#915](https://github.com/wycats/handlebars.js/pull/915) - Ast update ([@kpdecker](https://github.com/kpdecker)) - [#910](https://github.com/wycats/handlebars.js/issues/910) - Different behavior of {{@last}} when {{#each}} in {{#each}} ([@zordius](https://github.com/zordius)) - [#907](https://github.com/wycats/handlebars.js/issues/907) - Implement named helper variable references ([@kpdecker](https://github.com/kpdecker)) - [#906](https://github.com/wycats/handlebars.js/pull/906) - Add parser support for block params ([@mmun](https://github.com/mmun)) - [#903](https://github.com/wycats/handlebars.js/issues/903) - Only provide aliases for multiple use calls ([@kpdecker](https://github.com/kpdecker)) - [#902](https://github.com/wycats/handlebars.js/pull/902) - Generate Source Maps ([@kpdecker](https://github.com/kpdecker)) - [#901](https://github.com/wycats/handlebars.js/issues/901) - Still escapes with noEscape enabled on isolated Handlebars environment ([@zedknight](https://github.com/zedknight)) - [#896](https://github.com/wycats/handlebars.js/pull/896) - Simplify BlockNode by removing intermediate MustacheNode ([@mmun](https://github.com/mmun)) - [#892](https://github.com/wycats/handlebars.js/pull/892) - Implement parser for else chaining of helpers ([@kpdecker](https://github.com/kpdecker)) - [#889](https://github.com/wycats/handlebars.js/issues/889) - Consider extensible parser API ([@kpdecker](https://github.com/kpdecker)) - [#887](https://github.com/wycats/handlebars.js/issues/887) - Handlebars.noConflict() option? ([@bradvogel](https://github.com/bradvogel)) - [#886](https://github.com/wycats/handlebars.js/issues/886) - Add SafeString to context (or use duck-typing) ([@dominicbarnes](https://github.com/dominicbarnes)) - [#870](https://github.com/wycats/handlebars.js/pull/870) - Registering undefined partial throws exception. ([@max-b](https://github.com/max-b)) - [#866](https://github.com/wycats/handlebars.js/issues/866) - comments don't respect whitespace control ([@75lb](https://github.com/75lb)) - [#863](https://github.com/wycats/handlebars.js/pull/863) - + jsDelivr CDN info ([@tomByrer](https://github.com/tomByrer)) - [#858](https://github.com/wycats/handlebars.js/issues/858) - Disable new default auto-indent at included partials ([@majodev](https://github.com/majodev)) - [#856](https://github.com/wycats/handlebars.js/pull/856) - jspm compatibility ([@MajorBreakfast](https://github.com/MajorBreakfast)) - [#805](https://github.com/wycats/handlebars.js/issues/805) - Request: "strict" lookups ([@nzakas](https://github.com/nzakas)) - Export the default object for handlebars/runtime - 5594416 - Lookup partials when undefined - 617dd57 Compatibility notes: - Runtime breaking changes. Must match 3.x runtime and precompiler. - The AST has been upgraded to a public API. - There are a number of changes to this, but the format is now documented in docs/compiler-api.md - The Visitor API has been expanded to support mutation and provide a base implementation - The `JavaScriptCompiler` APIs have been formalized and documented. As part of the sourcemap handling these should be updated to return arrays for concatenation. - `JavaScriptCompiler.namespace` has been removed as it was unused. - `SafeString` is now duck typed on `toHTML` New Features: - noConflict - Source Maps - Block Params - Strict Mode - @last and other each changes - Chained else blocks - @data methods can now have helper parameters passed to them - Dynamic partials [Commits](https://github.com/wycats/handlebars.js/compare/v2.0.0...v3.0.0) ## v2.0.0 - September 1st, 2014 - Update jsfiddle to 2.0.0-beta.1 - 0670f65 - Add contrib note regarding handlebarsjs.com docs - 4d17e3c - Play nice with gemspec version numbers - 64d5481 [Commits](https://github.com/wycats/handlebars.js/compare/v2.0.0-beta.1...v2.0.0) ## v2.0.0-beta.1 - August 26th, 2014 - [#787](https://github.com/wycats/handlebars.js/pull/787) - Remove whitespace surrounding standalone statements ([@kpdecker](https://github.com/kpdecker)) - [#827](https://github.com/wycats/handlebars.js/issues/827) - Render false literal as “false” ([@scoot557](https://github.com/scoot557)) - [#767](https://github.com/wycats/handlebars.js/issues/767) - Subexpressions bug with hash and context ([@evensoul](https://github.com/evensoul)) - Changes to 0/undefined handling - [#731](https://github.com/wycats/handlebars.js/pull/731) - Strange behavior for {{#foo}} {{bar}} {{/foo}} when foo is 0 ([@kpdecker](https://github.com/kpdecker)) - [#820](https://github.com/wycats/handlebars.js/issues/820) - strange behavior for {{foo.bar}} when foo is 0 or null or false ([@zordius](https://github.com/zordius)) - [#837](https://github.com/wycats/handlebars.js/issues/837) - Strange input for custom helper ( foo.bar == false when foo is undefined ) ([@zordius](https://github.com/zordius)) - [#819](https://github.com/wycats/handlebars.js/pull/819) - Implement recursive field lookup ([@kpdecker](https://github.com/kpdecker)) - [#764](https://github.com/wycats/handlebars.js/issues/764) - This reference not working for helpers ([@kpdecker](https://github.com/kpdecker)) - [#773](https://github.com/wycats/handlebars.js/issues/773) - Implicit parameters in {{#each}} introduces a peculiarity in helpers calling convention ([@Bertrand](https://github.com/Bertrand)) - [#783](https://github.com/wycats/handlebars.js/issues/783) - helperMissing and consistency for different expression types ([@ErisDS](https://github.com/ErisDS)) - [#795](https://github.com/wycats/handlebars.js/pull/795) - Turn the precompile script into a wrapper around a module. ([@jwietelmann](https://github.com/jwietelmann)) - [#823](https://github.com/wycats/handlebars.js/pull/823) - Support inverse sections on the with helper ([@dan-manges](https://github.com/dan-manges)) - [#834](https://github.com/wycats/handlebars.js/pull/834) - Refactor blocks, programs and inverses ([@mmun](https://github.com/mmun)) - [#852](https://github.com/wycats/handlebars.js/issues/852) - {{foo~}} space control behavior is different from older version ([@zordius](https://github.com/zordius)) - [#835](https://github.com/wycats/handlebars.js/issues/835) - Templates overwritten if file is loaded twice - Expose escapeExpression on the root object - 980c38c - Remove nested function eval in blockHelperMissing - 6f22ec1 - Fix compiler program de-duping - 9e3f824 Compatibility notes: - The default build now outputs a generic UMD wrapper. This should be transparent change but may cause issues in some environments. - Runtime compatibility breaks in both directions. Ensure that both compiler and client are upgraded to 2.0.0-beta.1 or higher at the same time. - `programWithDepth` has been removed an instead an array of context values is passed to fields needing depth lookups. - `false` values are now printed to output rather than silently dropped - Lines containing only block statements and whitespace are now removed. This matches the Mustache spec but may cause issues with code that expects whitespace to exist but would not otherwise. - Partials that are standalone will now indent their rendered content - `AST.ProgramNode`'s signature has changed. - Numerious methods/features removed from pseudo-API classes - `JavaScriptCompiler.register` - `JavaScriptCompiler.replaceStack` no longer supports non-inline replace - `Compiler.disassemble` - `DECLARE` opcode - `strip` opcode - `lookup` opcode - Content nodes may have their `string` values mutated over time. `original` field provides the unmodified value. - Removed unused `Handlebars.registerHelper` `inverse` parameter - `each` helper requires iterator parameter [Commits](https://github.com/wycats/handlebars.js/compare/v2.0.0-alpha.4...v2.0.0-beta.1) ## v2.0.0-alpha.4 - May 19th, 2014 - Expose setup wrappers for compiled templates - 3638874 [Commits](https://github.com/wycats/handlebars.js/compare/v2.0.0-alpha.3...v2.0.0-alpha.4) ## v2.0.0-alpha.3 - May 19th, 2014 - [#797](https://github.com/wycats/handlebars.js/pull/797) - Pass full helper ID to helperMissing when options are provided ([@tomdale](https://github.com/tomdale)) - [#793](https://github.com/wycats/handlebars.js/pull/793) - Ensure isHelper is coerced to a boolean ([@mmun](https://github.com/mmun)) - Refactor template init logic - 085e5e1 [Commits](https://github.com/wycats/handlebars.js/compare/v2.0.0-alpha.2...v2.0.0-alpha.3) ## v2.0.0-alpha.2 - March 6th, 2014 - [#756](https://github.com/wycats/handlebars.js/pull/756) - fix bug in IE<=8 (no Array::map), closes #751 ([@jenseng](https://github.com/jenseng)) - [#749](https://github.com/wycats/handlebars.js/pull/749) - properly handle multiple subexpressions in the same hash, fixes #748 ([@jenseng](https://github.com/jenseng)) - [#743](https://github.com/wycats/handlebars.js/issues/743) - subexpression confusion/problem? ([@waynedpj](https://github.com/waynedpj)) - [#746](https://github.com/wycats/handlebars.js/issues/746) - [CLI] support `handlebars --version` ([@apfelbox](https://github.com/apfelbox)) - [#747](https://github.com/wycats/handlebars.js/pull/747) - updated grunt-saucelabs, failing tests revealed ([@Jonahss](https://github.com/Jonahss)) - Make JSON a requirement for the compiler. - 058c0fb - Temporarily kill the AWS publish CI step - 8347ee2 Compatibility notes: - A JSON polyfill is required to run the compiler under IE8 and below. It's recommended that the precompiler be used in lieu of running the compiler on these legacy environments. [Commits](https://github.com/wycats/handlebars.js/compare/v2.0.0-alpha.1...v2.0.0-alpha.2) ## v2.0.0-alpha.1 - February 10th, 2014 - [#182](https://github.com/wycats/handlebars.js/pull/182) - Allow passing hash parameters to partials ([@kpdecker](https://github.com/kpdecker)) - [#392](https://github.com/wycats/handlebars.js/pull/392) - Access to root context in partials and helpers ([@kpdecker](https://github.com/kpdecker)) - [#472](https://github.com/wycats/handlebars.js/issues/472) - Helpers cannot have decimal parameters ([@kayleg](https://github.com/kayleg)) - [#569](https://github.com/wycats/handlebars.js/pull/569) - Unable to lookup array values using @index ([@kpdecker](https://github.com/kpdecker)) - [#491](https://github.com/wycats/handlebars.js/pull/491) - For nested helpers: get the @ variables of the outer helper from the inner one ([@kpdecker](https://github.com/kpdecker)) - [#669](https://github.com/wycats/handlebars.js/issues/669) - Ability to unregister a helper ([@dbachrach](https://github.com/dbachrach)) - [#730](https://github.com/wycats/handlebars.js/pull/730) - Raw block helpers ([@kpdecker](https://github.com/kpdecker)) - [#634](https://github.com/wycats/handlebars.js/pull/634) - It would be great to have the helper name passed to `blockHelperMissing` ([@kpdecker](https://github.com/kpdecker)) - [#729](https://github.com/wycats/handlebars.js/pull/729) - Convert template spec to object literal ([@kpdecker](https://github.com/kpdecker)) - [#658](https://github.com/wycats/handlebars.js/issues/658) - Depthed helpers do not work after an upgrade from 1.0.0 ([@xibxor](https://github.com/xibxor)) - [#671](https://github.com/wycats/handlebars.js/issues/671) - Crashes on no-parameter {{#each}} ([@stepancheg](https://github.com/stepancheg)) - [#689](https://github.com/wycats/handlebars.js/issues/689) - broken template precompilation ([@AAS](https://github.com/AAS)) - [#698](https://github.com/wycats/handlebars.js/pull/698) - Fix parser generation under windows ([@osiris43](https://github.com/osiris43)) - [#699](https://github.com/wycats/handlebars.js/issues/699) - @DATA not compiles to invalid JS in stringParams mode ([@kpdecker](https://github.com/kpdecker)) - [#705](https://github.com/wycats/handlebars.js/issues/705) - 1.3.0 can not be wrapped in an IIFE ([@craigteegarden](https://github.com/craigteegarden)) - [#706](https://github.com/wycats/handlebars.js/pull/706) - README: Use with helper instead of relying on blockHelperMissing ([@scottgonzalez](https://github.com/scottgonzalez)) - [#700](https://github.com/wycats/handlebars.js/pull/700) - Remove redundant conditions ([@blakeembrey](https://github.com/blakeembrey)) - [#704](https://github.com/wycats/handlebars.js/pull/704) - JavaScript Compiler Cleanup ([@blakeembrey](https://github.com/blakeembrey)) Compatibility notes: - `helperMissing` helper no longer has the indexed name argument. Helper name is now available via `options.name`. - Precompiler output has changed, which breaks compatibility with prior versions of the runtime and precompiled output. - `JavaScriptCompiler.compilerInfo` now returns generic objects rather than javascript source. - AST changes - INTEGER -> NUMBER - Additional PartialNode hash parameter - New RawBlockNode type - Data frames now have a `_parent` field. This is internal but is enumerable for performance/compatibility reasons. [Commits](https://github.com/wycats/handlebars.js/compare/v1.3.0...v2.0.0-alpha.1) ## v1.3.0 - January 1st, 2014 - [#690](https://github.com/wycats/handlebars.js/pull/690) - Added support for subexpressions ([@machty](https://github.com/machty)) - [#696](https://github.com/wycats/handlebars.js/pull/696) - Fix for reserved keyword "default" ([@nateirwin](https://github.com/nateirwin)) - [#692](https://github.com/wycats/handlebars.js/pull/692) - add line numbers to nodes when parsing ([@fivetanley](https://github.com/fivetanley)) - [#695](https://github.com/wycats/handlebars.js/pull/695) - Pull options out from param setup to allow easier extension ([@blakeembrey](https://github.com/blakeembrey)) - [#694](https://github.com/wycats/handlebars.js/pull/694) - Make the environment reusable ([@blakeembrey](https://github.com/blakeembrey)) - [#636](https://github.com/wycats/handlebars.js/issues/636) - Print line and column of errors ([@sgronblo](https://github.com/sgronblo)) - Use literal for data lookup - c1a93d3 - Add stack handling sanity checks - cd885bf - Fix stack id "leak" on replaceStack - ddfe457 - Fix incorrect stack pop when replacing literals - f4d337d [Commits](https://github.com/wycats/handlebars.js/compare/v1.2.1...v1.3.0) ## v1.2.1 - December 26th, 2013 - [#684](https://github.com/wycats/handlebars.js/pull/684) - Allow any number of trailing characters for valid JavaScript variable ([@blakeembrey](https://github.com/blakeembrey)) - [#686](https://github.com/wycats/handlebars.js/pull/686) - Falsy AMD module names in version 1.2.0 ([@kpdecker](https://github.com/kpdecker)) [Commits](https://github.com/wycats/handlebars.js/compare/v1.2.0...v1.2.1) ## v1.2.0 - December 23rd, 2013 - [#675](https://github.com/wycats/handlebars.js/issues/675) - Cannot compile empty template for partial ([@erwinw](https://github.com/erwinw)) - [#677](https://github.com/wycats/handlebars.js/issues/677) - Triple brace statements fail under IE ([@hamzaCM](https://github.com/hamzaCM)) - [#655](https://github.com/wycats/handlebars.js/issues/655) - Loading Handlebars using bower ([@niki4810](https://github.com/niki4810)) - [#657](https://github.com/wycats/handlebars.js/pull/657) - Fixes issue where cli compiles non handlebars templates ([@chrishoage](https://github.com/chrishoage)) - [#681](https://github.com/wycats/handlebars.js/pull/681) - Adds in-browser testing and Saucelabs CI ([@kpdecker](https://github.com/kpdecker)) - [#661](https://github.com/wycats/handlebars.js/pull/661) - Add @first and @index to #each object iteration ([@cgp](https://github.com/cgp)) - [#650](https://github.com/wycats/handlebars.js/pull/650) - Handlebars is MIT-licensed ([@thomasboyt](https://github.com/thomasboyt)) - [#641](https://github.com/wycats/handlebars.js/pull/641) - Document ember testing process ([@kpdecker](https://github.com/kpdecker)) - [#662](https://github.com/wycats/handlebars.js/issues/662) - handlebars-source 1.1.2 is missing from RubyGems. - [#656](https://github.com/wycats/handlebars.js/issues/656) - Expose COMPILER_REVISION checks as a hook ([@machty](https://github.com/machty)) - [#668](https://github.com/wycats/handlebars.js/issues/668) - Consider publishing handlebars-runtime as a separate module on npm ([@dlmanning](https://github.com/dlmanning)) - [#679](https://github.com/wycats/handlebars.js/issues/679) - Unable to override invokePartial ([@mattbrailsford](https://github.com/mattbrailsford)) - [#646](https://github.com/wycats/handlebars.js/pull/646) - Fix "\\{{" immediately following "\{{" ([@dmarcotte](https://github.com/dmarcotte)) - Allow extend to work with non-prototyped objects - eb53f2e - Add JavascriptCompiler public API tests - 1a751b2 - Add AST test coverage for more complex paths - ddea5be - Fix handling of boolean escape in MustacheNode - b4968bb Compatibility notes: - `@index` and `@first` are now supported for `each` iteration on objects - `Handlebars.VM.checkRevision` and `Handlebars.JavaScriptCompiler.prototype.compilerInfo` now available to modify the version checking behavior. - Browserify users may link to the runtime library via `require('handlebars/runtime')` [Commits](https://github.com/wycats/handlebars.js/compare/v1.1.2...v1.2.0) ## v1.1.2 - November 5th, 2013 - [#645](https://github.com/wycats/handlebars.js/issues/645) - 1.1.1 fails under IE8 ([@kpdecker](https://github.com/kpdecker)) - [#644](https://github.com/wycats/handlebars.js/issues/644) - Using precompiled templates (AMD mode) with handlebars.runtime 1.1.1 ([@fddima](https://github.com/fddima)) - Add simple binary utility tests - 96a45a4 - Fix empty string compilation - eea708a [Commits](https://github.com/wycats/handlebars.js/compare/v1.1.1...v1.1.2) ## v1.1.1 - November 4th, 2013 - [#642](https://github.com/wycats/handlebars.js/issues/642) - handlebars 1.1.0 are broken with nodejs - Fix release notes link - 17ba258 [Commits](https://github.com/wycats/handlebars.js/compare/v1.1.0...v1.1.1) ## v1.1.0 - November 3rd, 2013 - [#628](https://github.com/wycats/handlebars.js/pull/628) - Convert code to ES6 modules ([@kpdecker](https://github.com/kpdecker)) - [#336](https://github.com/wycats/handlebars.js/pull/336) - Add whitespace control syntax ([@kpdecker](https://github.com/kpdecker)) - [#535](https://github.com/wycats/handlebars.js/pull/535) - Fix for probable JIT error under Safari ([@sorentwo](https://github.com/sorentwo)) - [#483](https://github.com/wycats/handlebars.js/issues/483) - Add first and last @ vars to each helper ([@denniskuczynski](https://github.com/denniskuczynski)) - [#557](https://github.com/wycats/handlebars.js/pull/557) - `\\{{foo}}` escaping only works in some situations ([@dmarcotte](https://github.com/dmarcotte)) - [#552](https://github.com/wycats/handlebars.js/pull/552) - Added BOM removal flag. ([@blessenm](https://github.com/blessenm)) - [#543](https://github.com/wycats/handlebars.js/pull/543) - publish passing master builds to s3 ([@fivetanley](https://github.com/fivetanley)) - [#608](https://github.com/wycats/handlebars.js/issues/608) - Add `includeZero` flag to `if` conditional - [#498](https://github.com/wycats/handlebars.js/issues/498) - `Handlebars.compile` fails on empty string although a single blank works fine - [#599](https://github.com/wycats/handlebars.js/issues/599) - lambda helpers only receive options if used with arguments - [#592](https://github.com/wycats/handlebars.js/issues/592) - Optimize array and subprogram performance - [#571](https://github.com/wycats/handlebars.js/issues/571) - uglify upgrade breaks compatibility with older versions of node - [#587](https://github.com/wycats/handlebars.js/issues/587) - Partial inside partial breaks? Compatibility notes: - The project now includes separate artifacts for AMD, CommonJS, and global objects. - AMD: Users may load the bundled `handlebars.amd.js` or `handlebars.runtime.amd.js` files or load individual modules directly. AMD users should also note that the handlebars object is exposed via the `default` field on the imported object. This [gist](https://gist.github.com/wycats/7417be0dc361a69d5916) provides some discussion of possible compatibility shims. - CommonJS/Node: Node loading occurs as normal via `require` - Globals: The `handlebars.js` and `handlebars.runtime.js` files should behave in the same manner as the v1.0.12 / 1.0.0 release. - Build artifacts have been removed from the repository. [npm][npm], [components/handlebars.js][components], [cdnjs][cdnjs], or the [builds page][builds-page] should now be used as the source of built artifacts. - Context-stored helpers are now always passed the `options` hash. Previously no-argument helpers did not have this argument. [Commits](https://github.com/wycats/handlebars.js/compare/v1.0.12...v1.1.0) ## v1.0.12 / 1.0.0 - May 31 2013 - [#515](https://github.com/wycats/handlebars.js/issues/515) - Add node require extensions support ([@jjclark1982](https://github.com/jjclark1982)) - [#517](https://github.com/wycats/handlebars.js/issues/517) - Fix amd precompiler output with directories ([@blessenm](https://github.com/blessenm)) - [#433](https://github.com/wycats/handlebars.js/issues/433) - Add support for unicode ids - [#469](https://github.com/wycats/handlebars.js/issues/469) - Add support for `?` in ids - [#534](https://github.com/wycats/handlebars.js/issues/534) - Protect from object prototype modifications - [#519](https://github.com/wycats/handlebars.js/issues/519) - Fix partials with . name ([@jamesgorrie](https://github.com/jamesgorrie)) - [#519](https://github.com/wycats/handlebars.js/issues/519) - Allow ID or strings in partial names - [#437](https://github.com/wycats/handlebars.js/issues/437) - Require matching brace counts in escaped expressions - Merge passed partials and helpers with global namespace values - Add support for complex ids in @data references - Docs updates Compatibility notes: - The parser is now stricter on `{{{`, requiring that the end token be `}}}`. Templates that do not follow this convention should add the additional brace value. - Code that relies on global the namespace being muted when custom helpers or partials are passed will need to explicitly pass an `undefined` value for any helpers that should not be available. - The compiler version has changed. Precompiled templates with 1.0.12 or higher must use the 1.0.0 or higher runtime. [Commits](https://github.com/wycats/handlebars.js/compare/v1.0.11...v1.0.12) ## v1.0.11 / 1.0.0-rc4 - May 13 2013 - [#458](https://github.com/wycats/handlebars.js/issues/458) - Fix `./foo` syntax ([@jpfiset](https://github.com/jpfiset)) - [#460](https://github.com/wycats/handlebars.js/issues/460) - Allow `:` in unescaped identifiers ([@jpfiset](https://github.com/jpfiset)) - [#471](https://github.com/wycats/handlebars.js/issues/471) - Create release notes (These!) - [#456](https://github.com/wycats/handlebars.js/issues/456) - Allow escaping of `\\` - [#211](https://github.com/wycats/handlebars.js/issues/211) - Fix exception in `escapeExpression` - [#375](https://github.com/wycats/handlebars.js/issues/375) - Escape unicode newlines - [#461](https://github.com/wycats/handlebars.js/issues/461) - Do not fail when compiling `""` - [#302](https://github.com/wycats/handlebars.js/issues/302) - Fix sanity check in knownHelpersOnly mode - [#369](https://github.com/wycats/handlebars.js/issues/369) - Allow registration of multiple helpers and partial by passing definition object - Add bower package declaration ([@DevinClark](https://github.com/DevinClark)) - Add NuSpec package declaration ([@MikeMayer](https://github.com/MikeMayer)) - Handle empty context in `with` ([@thejohnfreeman](https://github.com/thejohnfreeman)) - Support custom template extensions in CLI ([@matteoagosti](https://github.com/matteoagosti)) - Fix Rhino support ([@broady](https://github.com/broady)) - Include contexts in string mode ([@leshill](https://github.com/leshill)) - Return precompiled scripts when compiling to AMD ([@JamesMaroney](https://github.com/JamesMaroney)) - Docs updates ([@iangreenleaf](https://github.com/iangreenleaf), [@gilesbowkett](https://github.com/gilesbowkett), [@utkarsh2012](https://github.com/utkarsh2012)) - Fix `toString` handling under IE and browserify ([@tommydudebreaux](https://github.com/tommydudebreaux)) - Add program metadata [Commits](https://github.com/wycats/handlebars.js/compare/v1.0.10...v1.0.11) ## v1.0.10 - Node - Feb 27 2013 - [#428](https://github.com/wycats/handlebars.js/issues/428) - Fix incorrect rendering of nested programs - Fix exception message ([@tricknotes](https://github.com/tricknotes)) - Added negative number literal support - Concert library to single IIFE - Add handlebars-source gemspec ([@machty](https://github.com/machty)) [Commits](https://github.com/wycats/handlebars.js/compare/v1.0.9...v1.0.10) ## v1.0.9 - Node - Feb 15 2013 - Added `Handlebars.create` API in node module for sandboxed instances ([@tommydudebreaux](https://github.com/tommydudebreaux)) [Commits](https://github.com/wycats/handlebars.js/compare/1.0.0-rc.3...v1.0.9) ## 1.0.0-rc3 - Browser - Feb 14 2013 - Prevent use of `this` or `..` in illogical place ([@leshill](https://github.com/leshill)) - Allow AST passing for `parse`/`compile`/`precompile` ([@machty](https://github.com/machty)) - Optimize generated output by inlining statements where possible - Check compiler version when evaluating templates - Package browser dist in npm package [Commits](https://github.com/wycats/handlebars.js/compare/v1.0.8...1.0.0-rc.3) ## Prior Versions When upgrading from the Handlebars 0.9 series, be aware that the signature for passing custom helpers or partials to templates has changed. Instead of: ```js template(context, helpers, partials, [data]); ``` Use: ```js template(context, { helpers: helpers, partials: partials, data: data }); ``` [builds-page]: http://builds.handlebarsjs.com.s3.amazonaws.com/index.html [cdnjs]: http://cdnjs.com/libraries/handlebars.js/ [components]: https://github.com/components/handlebars.js [npm]: https://npmjs.org/package/handlebars handlebars.js-4.7.7/runtime.d.ts000066400000000000000000000001261401244020700165150ustar00rootroot00000000000000import Handlebars = require('handlebars') declare module "handlebars/runtime" { }handlebars.js-4.7.7/runtime.js000066400000000000000000000002471401244020700162650ustar00rootroot00000000000000// Create a simple path alias to allow browserify to resolve // the runtime on a supported path. module.exports = require('./dist/cjs/handlebars.runtime')['default']; handlebars.js-4.7.7/spec/000077500000000000000000000000001401244020700151735ustar00rootroot00000000000000handlebars.js-4.7.7/spec/.eslintrc000066400000000000000000000015561401244020700170260ustar00rootroot00000000000000{ "extends": [ "../.eslintrc.js", "plugin:es5/no-es2015", "prettier" ], "plugins": [ "es5" ], "globals": { "CompilerContext": true, "Handlebars": true, "handlebarsEnv": true, "shouldCompileTo": true, "shouldCompileToWithPartials": true, "shouldThrow": true, "expectTemplate": true, "compileWithPartials": true, "console": true, "require": true, "suite": true, "equal": true, "equals": true, "test": true, "testBoth": true, "raises": true, "deepEqual": true, "start": true, "stop": true, "ok": true, "sinon": true, "strictEqual": true, "define": true, "expect": true, "chai": true }, "env": { "mocha": true }, "rules": { // Disabling for tests, for now. "no-path-concat": "off", "no-var": "off", "dot-notation": "off" } } handlebars.js-4.7.7/spec/amd-runtime.html000066400000000000000000000062501401244020700203060ustar00rootroot00000000000000 Mocha
handlebars.js-4.7.7/spec/amd.html000066400000000000000000000073531401244020700166320ustar00rootroot00000000000000 Mocha
handlebars.js-4.7.7/spec/artifacts/000077500000000000000000000000001401244020700171535ustar00rootroot00000000000000handlebars.js-4.7.7/spec/artifacts/bom.handlebars000066400000000000000000000000041401244020700217470ustar00rootroot00000000000000ahandlebars.js-4.7.7/spec/artifacts/empty.handlebars000066400000000000000000000000001401244020700223240ustar00rootroot00000000000000handlebars.js-4.7.7/spec/artifacts/example_1.handlebars000066400000000000000000000000101401244020700230420ustar00rootroot00000000000000{{foo}} handlebars.js-4.7.7/spec/artifacts/example_2.hbs000066400000000000000000000000211401244020700215160ustar00rootroot00000000000000Hello, {{name}}! handlebars.js-4.7.7/spec/artifacts/known.helpers.handlebars000066400000000000000000000002321401244020700237720ustar00rootroot00000000000000{{#someHelper true}}
Some known helper
{{#anotherHelper true}}
Another known helper
{{/anotherHelper}} {{/someHelper}} handlebars.js-4.7.7/spec/artifacts/non.default.extension.hbs000066400000000000000000000000311401244020700240730ustar00rootroot00000000000000
This is a test
handlebars.js-4.7.7/spec/artifacts/partial.template.handlebars000066400000000000000000000000271401244020700244450ustar00rootroot00000000000000
Test Partial
handlebars.js-4.7.7/spec/ast.js000066400000000000000000000334101401244020700163210ustar00rootroot00000000000000describe('ast', function() { if (!Handlebars.AST) { return; } var AST = Handlebars.AST; describe('BlockStatement', function() { it('should throw on mustache mismatch', function() { shouldThrow( function() { handlebarsEnv.parse('\n {{#foo}}{{/bar}}'); }, Handlebars.Exception, "foo doesn't match bar - 2:5" ); }); }); describe('helpers', function() { describe('#helperExpression', function() { it('should handle mustache statements', function() { equals( AST.helpers.helperExpression({ type: 'MustacheStatement', params: [], hash: undefined }), false ); equals( AST.helpers.helperExpression({ type: 'MustacheStatement', params: [1], hash: undefined }), true ); equals( AST.helpers.helperExpression({ type: 'MustacheStatement', params: [], hash: {} }), true ); }); it('should handle block statements', function() { equals( AST.helpers.helperExpression({ type: 'BlockStatement', params: [], hash: undefined }), false ); equals( AST.helpers.helperExpression({ type: 'BlockStatement', params: [1], hash: undefined }), true ); equals( AST.helpers.helperExpression({ type: 'BlockStatement', params: [], hash: {} }), true ); }); it('should handle subexpressions', function() { equals(AST.helpers.helperExpression({ type: 'SubExpression' }), true); }); it('should work with non-helper nodes', function() { equals(AST.helpers.helperExpression({ type: 'Program' }), false); equals( AST.helpers.helperExpression({ type: 'PartialStatement' }), false ); equals( AST.helpers.helperExpression({ type: 'ContentStatement' }), false ); equals( AST.helpers.helperExpression({ type: 'CommentStatement' }), false ); equals(AST.helpers.helperExpression({ type: 'PathExpression' }), false); equals(AST.helpers.helperExpression({ type: 'StringLiteral' }), false); equals(AST.helpers.helperExpression({ type: 'NumberLiteral' }), false); equals(AST.helpers.helperExpression({ type: 'BooleanLiteral' }), false); equals( AST.helpers.helperExpression({ type: 'UndefinedLiteral' }), false ); equals(AST.helpers.helperExpression({ type: 'NullLiteral' }), false); equals(AST.helpers.helperExpression({ type: 'Hash' }), false); equals(AST.helpers.helperExpression({ type: 'HashPair' }), false); }); }); }); describe('Line Numbers', function() { var ast, body; function testColumns(node, firstLine, lastLine, firstColumn, lastColumn) { equals(node.loc.start.line, firstLine); equals(node.loc.start.column, firstColumn); equals(node.loc.end.line, lastLine); equals(node.loc.end.column, lastColumn); } /* eslint-disable no-multi-spaces */ ast = Handlebars.parse( 'line 1 {{line1Token}}\n' + // 1 ' line 2 {{line2token}}\n' + // 2 ' line 3 {{#blockHelperOnLine3}}\n' + // 3 'line 4{{line4token}}\n' + // 4 'line5{{else}}\n' + // 5 '{{line6Token}}\n' + // 6 '{{/blockHelperOnLine3}}\n' + // 7 '{{#open}}\n' + // 8 '{{else inverse}}\n' + // 9 '{{else}}\n' + // 10 '{{/open}}' ); // 11 /* eslint-enable no-multi-spaces */ body = ast.body; it('gets ContentNode line numbers', function() { var contentNode = body[0]; testColumns(contentNode, 1, 1, 0, 7); }); it('gets MustacheStatement line numbers', function() { var mustacheNode = body[1]; testColumns(mustacheNode, 1, 1, 7, 21); }); it('gets line numbers correct when newlines appear', function() { testColumns(body[2], 1, 2, 21, 8); }); it('gets MustacheStatement line numbers correct across newlines', function() { var secondMustacheStatement = body[3]; testColumns(secondMustacheStatement, 2, 2, 8, 22); }); it('gets the block helper information correct', function() { var blockHelperNode = body[5]; testColumns(blockHelperNode, 3, 7, 8, 23); }); it('correctly records the line numbers the program of a block helper', function() { var blockHelperNode = body[5], program = blockHelperNode.program; testColumns(program, 3, 5, 31, 5); }); it('correctly records the line numbers of an inverse of a block helper', function() { var blockHelperNode = body[5], inverse = blockHelperNode.inverse; testColumns(inverse, 5, 7, 13, 0); }); it('correctly records the line number of chained inverses', function() { var chainInverseNode = body[7]; testColumns(chainInverseNode.program, 8, 9, 9, 0); testColumns(chainInverseNode.inverse, 9, 10, 16, 0); testColumns(chainInverseNode.inverse.body[0].program, 9, 10, 16, 0); testColumns(chainInverseNode.inverse.body[0].inverse, 10, 11, 8, 0); }); }); describe('whitespace control', function() { describe('parse', function() { it('mustache', function() { var ast = Handlebars.parse(' {{~comment~}} '); equals(ast.body[0].value, ''); equals(ast.body[2].value, ''); }); it('block statements', function() { var ast = Handlebars.parse(' {{# comment~}} \nfoo\n {{~/comment}}'); equals(ast.body[0].value, ''); equals(ast.body[1].program.body[0].value, 'foo'); }); }); describe('parseWithoutProcessing', function() { it('mustache', function() { var ast = Handlebars.parseWithoutProcessing(' {{~comment~}} '); equals(ast.body[0].value, ' '); equals(ast.body[2].value, ' '); }); it('block statements', function() { var ast = Handlebars.parseWithoutProcessing( ' {{# comment~}} \nfoo\n {{~/comment}}' ); equals(ast.body[0].value, ' '); equals(ast.body[1].program.body[0].value, ' \nfoo\n '); }); }); }); describe('standalone flags', function() { describe('mustache', function() { it('does not mark mustaches as standalone', function() { var ast = Handlebars.parse(' {{comment}} '); equals(!!ast.body[0].value, true); equals(!!ast.body[2].value, true); }); }); describe('blocks - parseWithoutProcessing', function() { it('block mustaches', function() { var ast = Handlebars.parseWithoutProcessing( ' {{# comment}} \nfoo\n {{else}} \n bar \n {{/comment}} ' ), block = ast.body[1]; equals(ast.body[0].value, ' '); equals(block.program.body[0].value, ' \nfoo\n '); equals(block.inverse.body[0].value, ' \n bar \n '); equals(ast.body[2].value, ' '); }); it('initial block mustaches', function() { var ast = Handlebars.parseWithoutProcessing( '{{# comment}} \nfoo\n {{/comment}}' ), block = ast.body[0]; equals(block.program.body[0].value, ' \nfoo\n '); }); it('mustaches with children', function() { var ast = Handlebars.parseWithoutProcessing( '{{# comment}} \n{{foo}}\n {{/comment}}' ), block = ast.body[0]; equals(block.program.body[0].value, ' \n'); equals(block.program.body[1].path.original, 'foo'); equals(block.program.body[2].value, '\n '); }); it('nested block mustaches', function() { var ast = Handlebars.parseWithoutProcessing( '{{#foo}} \n{{# comment}} \nfoo\n {{else}} \n bar \n {{/comment}} \n{{/foo}}' ), body = ast.body[0].program.body, block = body[1]; equals(body[0].value, ' \n'); equals(block.program.body[0].value, ' \nfoo\n '); equals(block.inverse.body[0].value, ' \n bar \n '); }); it('column 0 block mustaches', function() { var ast = Handlebars.parseWithoutProcessing( 'test\n{{# comment}} \nfoo\n {{else}} \n bar \n {{/comment}} ' ), block = ast.body[1]; equals(ast.body[0].omit, undefined); equals(block.program.body[0].value, ' \nfoo\n '); equals(block.inverse.body[0].value, ' \n bar \n '); equals(ast.body[2].value, ' '); }); }); describe('blocks', function() { it('marks block mustaches as standalone', function() { var ast = Handlebars.parse( ' {{# comment}} \nfoo\n {{else}} \n bar \n {{/comment}} ' ), block = ast.body[1]; equals(ast.body[0].value, ''); equals(block.program.body[0].value, 'foo\n'); equals(block.inverse.body[0].value, ' bar \n'); equals(ast.body[2].value, ''); }); it('marks initial block mustaches as standalone', function() { var ast = Handlebars.parse('{{# comment}} \nfoo\n {{/comment}}'), block = ast.body[0]; equals(block.program.body[0].value, 'foo\n'); }); it('marks mustaches with children as standalone', function() { var ast = Handlebars.parse('{{# comment}} \n{{foo}}\n {{/comment}}'), block = ast.body[0]; equals(block.program.body[0].value, ''); equals(block.program.body[1].path.original, 'foo'); equals(block.program.body[2].value, '\n'); }); it('marks nested block mustaches as standalone', function() { var ast = Handlebars.parse( '{{#foo}} \n{{# comment}} \nfoo\n {{else}} \n bar \n {{/comment}} \n{{/foo}}' ), body = ast.body[0].program.body, block = body[1]; equals(body[0].value, ''); equals(block.program.body[0].value, 'foo\n'); equals(block.inverse.body[0].value, ' bar \n'); equals(body[0].value, ''); }); it('does not mark nested block mustaches as standalone', function() { var ast = Handlebars.parse( '{{#foo}} {{# comment}} \nfoo\n {{else}} \n bar \n {{/comment}} {{/foo}}' ), body = ast.body[0].program.body, block = body[1]; equals(body[0].omit, undefined); equals(block.program.body[0].value, ' \nfoo\n'); equals(block.inverse.body[0].value, ' bar \n '); equals(body[0].omit, undefined); }); it('does not mark nested initial block mustaches as standalone', function() { var ast = Handlebars.parse( '{{#foo}}{{# comment}} \nfoo\n {{else}} \n bar \n {{/comment}}{{/foo}}' ), body = ast.body[0].program.body, block = body[0]; equals(block.program.body[0].value, ' \nfoo\n'); equals(block.inverse.body[0].value, ' bar \n '); equals(body[0].omit, undefined); }); it('marks column 0 block mustaches as standalone', function() { var ast = Handlebars.parse( 'test\n{{# comment}} \nfoo\n {{else}} \n bar \n {{/comment}} ' ), block = ast.body[1]; equals(ast.body[0].omit, undefined); equals(block.program.body[0].value, 'foo\n'); equals(block.inverse.body[0].value, ' bar \n'); equals(ast.body[2].value, ''); }); }); describe('partials - parseWithoutProcessing', function() { it('simple partial', function() { var ast = Handlebars.parseWithoutProcessing('{{> partial }} '); equals(ast.body[1].value, ' '); }); it('indented partial', function() { var ast = Handlebars.parseWithoutProcessing(' {{> partial }} '); equals(ast.body[0].value, ' '); equals(ast.body[1].indent, ''); equals(ast.body[2].value, ' '); }); }); describe('partials', function() { it('marks partial as standalone', function() { var ast = Handlebars.parse('{{> partial }} '); equals(ast.body[1].value, ''); }); it('marks indented partial as standalone', function() { var ast = Handlebars.parse(' {{> partial }} '); equals(ast.body[0].value, ''); equals(ast.body[1].indent, ' '); equals(ast.body[2].value, ''); }); it('marks those around content as not standalone', function() { var ast = Handlebars.parse('a{{> partial }}'); equals(ast.body[0].omit, undefined); ast = Handlebars.parse('{{> partial }}a'); equals(ast.body[1].omit, undefined); }); }); describe('comments - parseWithoutProcessing', function() { it('simple comment', function() { var ast = Handlebars.parseWithoutProcessing('{{! comment }} '); equals(ast.body[1].value, ' '); }); it('indented comment', function() { var ast = Handlebars.parseWithoutProcessing(' {{! comment }} '); equals(ast.body[0].value, ' '); equals(ast.body[2].value, ' '); }); }); describe('comments', function() { it('marks comment as standalone', function() { var ast = Handlebars.parse('{{! comment }} '); equals(ast.body[1].value, ''); }); it('marks indented comment as standalone', function() { var ast = Handlebars.parse(' {{! comment }} '); equals(ast.body[0].value, ''); equals(ast.body[2].value, ''); }); it('marks those around content as not standalone', function() { var ast = Handlebars.parse('a{{! comment }}'); equals(ast.body[0].omit, undefined); ast = Handlebars.parse('{{! comment }}a'); equals(ast.body[1].omit, undefined); }); }); }); }); handlebars.js-4.7.7/spec/basic.js000066400000000000000000000411311401244020700166120ustar00rootroot00000000000000global.handlebarsEnv = null; beforeEach(function() { global.handlebarsEnv = Handlebars.create(); }); describe('basic context', function() { it('most basic', function() { expectTemplate('{{foo}}') .withInput({ foo: 'foo' }) .toCompileTo('foo'); }); it('escaping', function() { expectTemplate('\\{{foo}}') .withInput({ foo: 'food' }) .toCompileTo('{{foo}}'); expectTemplate('content \\{{foo}}') .withInput({ foo: 'food' }) .toCompileTo('content {{foo}}'); expectTemplate('\\\\{{foo}}') .withInput({ foo: 'food' }) .toCompileTo('\\food'); expectTemplate('content \\\\{{foo}}') .withInput({ foo: 'food' }) .toCompileTo('content \\food'); expectTemplate('\\\\ {{foo}}') .withInput({ foo: 'food' }) .toCompileTo('\\\\ food'); }); it('compiling with a basic context', function() { expectTemplate('Goodbye\n{{cruel}}\n{{world}}!') .withInput({ cruel: 'cruel', world: 'world' }) .withMessage('It works if all the required keys are provided') .toCompileTo('Goodbye\ncruel\nworld!'); }); it('compiling with a string context', function() { expectTemplate('{{.}}{{length}}') .withInput('bye') .toCompileTo('bye3'); }); it('compiling with an undefined context', function() { expectTemplate('Goodbye\n{{cruel}}\n{{world.bar}}!') .withInput(undefined) .toCompileTo('Goodbye\n\n!'); expectTemplate('{{#unless foo}}Goodbye{{../test}}{{test2}}{{/unless}}') .withInput(undefined) .toCompileTo('Goodbye'); }); it('comments', function() { expectTemplate('{{! Goodbye}}Goodbye\n{{cruel}}\n{{world}}!') .withInput({ cruel: 'cruel', world: 'world' }) .withMessage('comments are ignored') .toCompileTo('Goodbye\ncruel\nworld!'); expectTemplate(' {{~! comment ~}} blah').toCompileTo('blah'); expectTemplate(' {{~!-- long-comment --~}} blah').toCompileTo( 'blah' ); expectTemplate(' {{! comment ~}} blah').toCompileTo(' blah'); expectTemplate(' {{!-- long-comment --~}} blah').toCompileTo( ' blah' ); expectTemplate(' {{~! comment}} blah').toCompileTo(' blah'); expectTemplate(' {{~!-- long-comment --}} blah').toCompileTo( ' blah' ); }); it('boolean', function() { var string = '{{#goodbye}}GOODBYE {{/goodbye}}cruel {{world}}!'; expectTemplate(string) .withInput({ goodbye: true, world: 'world' }) .withMessage('booleans show the contents when true') .toCompileTo('GOODBYE cruel world!'); expectTemplate(string) .withInput({ goodbye: false, world: 'world' }) .withMessage('booleans do not show the contents when false') .toCompileTo('cruel world!'); }); it('zeros', function() { expectTemplate('num1: {{num1}}, num2: {{num2}}') .withInput({ num1: 42, num2: 0 }) .toCompileTo('num1: 42, num2: 0'); expectTemplate('num: {{.}}') .withInput(0) .toCompileTo('num: 0'); expectTemplate('num: {{num1/num2}}') .withInput({ num1: { num2: 0 } }) .toCompileTo('num: 0'); }); it('false', function() { /* eslint-disable no-new-wrappers */ expectTemplate('val1: {{val1}}, val2: {{val2}}') .withInput({ val1: false, val2: new Boolean(false) }) .toCompileTo('val1: false, val2: false'); expectTemplate('val: {{.}}') .withInput(false) .toCompileTo('val: false'); expectTemplate('val: {{val1/val2}}') .withInput({ val1: { val2: false } }) .toCompileTo('val: false'); expectTemplate('val1: {{{val1}}}, val2: {{{val2}}}') .withInput({ val1: false, val2: new Boolean(false) }) .toCompileTo('val1: false, val2: false'); expectTemplate('val: {{{val1/val2}}}') .withInput({ val1: { val2: false } }) .toCompileTo('val: false'); /* eslint-enable */ }); it('should handle undefined and null', function() { expectTemplate('{{awesome undefined null}}') .withInput({ awesome: function(_undefined, _null, options) { return ( (_undefined === undefined) + ' ' + (_null === null) + ' ' + typeof options ); } }) .toCompileTo('true true object'); expectTemplate('{{undefined}}') .withInput({ undefined: function() { return 'undefined!'; } }) .toCompileTo('undefined!'); expectTemplate('{{null}}') .withInput({ null: function() { return 'null!'; } }) .toCompileTo('null!'); }); it('newlines', function() { expectTemplate("Alan's\nTest").toCompileTo("Alan's\nTest"); expectTemplate("Alan's\rTest").toCompileTo("Alan's\rTest"); }); it('escaping text', function() { expectTemplate("Awesome's") .withMessage( "text is escaped so that it doesn't get caught on single quotes" ) .toCompileTo("Awesome's"); expectTemplate('Awesome\\') .withMessage("text is escaped so that the closing quote can't be ignored") .toCompileTo('Awesome\\'); expectTemplate('Awesome\\\\ foo') .withMessage("text is escaped so that it doesn't mess up backslashes") .toCompileTo('Awesome\\\\ foo'); expectTemplate('Awesome {{foo}}') .withInput({ foo: '\\' }) .withMessage("text is escaped so that it doesn't mess up backslashes") .toCompileTo('Awesome \\'); expectTemplate(" ' ' ") .withMessage('double quotes never produce invalid javascript') .toCompileTo(" ' ' "); }); it('escaping expressions', function() { expectTemplate('{{{awesome}}}') .withInput({ awesome: "&'\\<>" }) .withMessage("expressions with 3 handlebars aren't escaped") .toCompileTo("&'\\<>"); expectTemplate('{{&awesome}}') .withInput({ awesome: "&'\\<>" }) .withMessage("expressions with {{& handlebars aren't escaped") .toCompileTo("&'\\<>"); expectTemplate('{{awesome}}') .withInput({ awesome: '&"\'`\\<>' }) .withMessage('by default expressions should be escaped') .toCompileTo('&"'`\\<>'); expectTemplate('{{awesome}}') .withInput({ awesome: 'Escaped, looks like: <b>' }) .withMessage('escaping should properly handle amperstands') .toCompileTo('Escaped, <b> looks like: &lt;b&gt;'); }); it("functions returning safestrings shouldn't be escaped", function() { expectTemplate('{{awesome}}') .withInput({ awesome: function() { return new Handlebars.SafeString("&'\\<>"); } }) .withMessage("functions returning safestrings aren't escaped") .toCompileTo("&'\\<>"); }); it('functions', function() { expectTemplate('{{awesome}}') .withInput({ awesome: function() { return 'Awesome'; } }) .withMessage('functions are called and render their output') .toCompileTo('Awesome'); expectTemplate('{{awesome}}') .withInput({ awesome: function() { return this.more; }, more: 'More awesome' }) .withMessage('functions are bound to the context') .toCompileTo('More awesome'); }); it('functions with context argument', function() { expectTemplate('{{awesome frank}}') .withInput({ awesome: function(context) { return context; }, frank: 'Frank' }) .withMessage('functions are called with context arguments') .toCompileTo('Frank'); }); it('pathed functions with context argument', function() { expectTemplate('{{bar.awesome frank}}') .withInput({ bar: { awesome: function(context) { return context; } }, frank: 'Frank' }) .withMessage('functions are called with context arguments') .toCompileTo('Frank'); }); it('depthed functions with context argument', function() { expectTemplate('{{#with frank}}{{../awesome .}}{{/with}}') .withInput({ awesome: function(context) { return context; }, frank: 'Frank' }) .withMessage('functions are called with context arguments') .toCompileTo('Frank'); }); it('block functions with context argument', function() { expectTemplate('{{#awesome 1}}inner {{.}}{{/awesome}}') .withInput({ awesome: function(context, options) { return options.fn(context); } }) .withMessage('block functions are called with context and options') .toCompileTo('inner 1'); }); it('depthed block functions with context argument', function() { expectTemplate( '{{#with value}}{{#../awesome 1}}inner {{.}}{{/../awesome}}{{/with}}' ) .withInput({ value: true, awesome: function(context, options) { return options.fn(context); } }) .withMessage('block functions are called with context and options') .toCompileTo('inner 1'); }); it('block functions without context argument', function() { expectTemplate('{{#awesome}}inner{{/awesome}}') .withInput({ awesome: function(options) { return options.fn(this); } }) .withMessage('block functions are called with options') .toCompileTo('inner'); }); it('pathed block functions without context argument', function() { expectTemplate('{{#foo.awesome}}inner{{/foo.awesome}}') .withInput({ foo: { awesome: function() { return this; } } }) .withMessage('block functions are called with options') .toCompileTo('inner'); }); it('depthed block functions without context argument', function() { expectTemplate( '{{#with value}}{{#../awesome}}inner{{/../awesome}}{{/with}}' ) .withInput({ value: true, awesome: function() { return this; } }) .withMessage('block functions are called with options') .toCompileTo('inner'); }); it('paths with hyphens', function() { expectTemplate('{{foo-bar}}') .withInput({ 'foo-bar': 'baz' }) .withMessage('Paths can contain hyphens (-)') .toCompileTo('baz'); expectTemplate('{{foo.foo-bar}}') .withInput({ foo: { 'foo-bar': 'baz' } }) .withMessage('Paths can contain hyphens (-)') .toCompileTo('baz'); expectTemplate('{{foo/foo-bar}}') .withInput({ foo: { 'foo-bar': 'baz' } }) .withMessage('Paths can contain hyphens (-)') .toCompileTo('baz'); }); it('nested paths', function() { expectTemplate('Goodbye {{alan/expression}} world!') .withInput({ alan: { expression: 'beautiful' } }) .withMessage('Nested paths access nested objects') .toCompileTo('Goodbye beautiful world!'); }); it('nested paths with empty string value', function() { expectTemplate('Goodbye {{alan/expression}} world!') .withInput({ alan: { expression: '' } }) .withMessage('Nested paths access nested objects with empty string') .toCompileTo('Goodbye world!'); }); it('literal paths', function() { expectTemplate('Goodbye {{[@alan]/expression}} world!') .withInput({ '@alan': { expression: 'beautiful' } }) .withMessage('Literal paths can be used') .toCompileTo('Goodbye beautiful world!'); expectTemplate('Goodbye {{[foo bar]/expression}} world!') .withInput({ 'foo bar': { expression: 'beautiful' } }) .withMessage('Literal paths can be used') .toCompileTo('Goodbye beautiful world!'); }); it('literal references', function() { expectTemplate('Goodbye {{[foo bar]}} world!') .withInput({ 'foo bar': 'beautiful' }) .toCompileTo('Goodbye beautiful world!'); expectTemplate('Goodbye {{"foo bar"}} world!') .withInput({ 'foo bar': 'beautiful' }) .toCompileTo('Goodbye beautiful world!'); expectTemplate("Goodbye {{'foo bar'}} world!") .withInput({ 'foo bar': 'beautiful' }) .toCompileTo('Goodbye beautiful world!'); expectTemplate('Goodbye {{"foo[bar"}} world!') .withInput({ 'foo[bar': 'beautiful' }) .toCompileTo('Goodbye beautiful world!'); expectTemplate('Goodbye {{"foo\'bar"}} world!') .withInput({ "foo'bar": 'beautiful' }) .toCompileTo('Goodbye beautiful world!'); expectTemplate("Goodbye {{'foo\"bar'}} world!") .withInput({ 'foo"bar': 'beautiful' }) .toCompileTo('Goodbye beautiful world!'); }); it("that current context path ({{.}}) doesn't hit helpers", function() { expectTemplate('test: {{.}}') .withInput(null) .withHelpers({ helper: 'awesome' }) .toCompileTo('test: '); }); it('complex but empty paths', function() { expectTemplate('{{person/name}}') .withInput({ person: { name: null } }) .toCompileTo(''); expectTemplate('{{person/name}}') .withInput({ person: {} }) .toCompileTo(''); }); it('this keyword in paths', function() { expectTemplate('{{#goodbyes}}{{this}}{{/goodbyes}}') .withInput({ goodbyes: ['goodbye', 'Goodbye', 'GOODBYE'] }) .withMessage('This keyword in paths evaluates to current context') .toCompileTo('goodbyeGoodbyeGOODBYE'); expectTemplate('{{#hellos}}{{this/text}}{{/hellos}}') .withInput({ hellos: [{ text: 'hello' }, { text: 'Hello' }, { text: 'HELLO' }] }) .withMessage('This keyword evaluates in more complex paths') .toCompileTo('helloHelloHELLO'); }); it('this keyword nested inside path', function() { expectTemplate('{{#hellos}}{{text/this/foo}}{{/hellos}}').toThrow( Error, 'Invalid path: text/this - 1:13' ); expectTemplate('{{[this]}}') .withInput({ this: 'bar' }) .toCompileTo('bar'); expectTemplate('{{text/[this]}}') .withInput({ text: { this: 'bar' } }) .toCompileTo('bar'); }); it('this keyword in helpers', function() { var helpers = { foo: function(value) { return 'bar ' + value; } }; expectTemplate('{{#goodbyes}}{{foo this}}{{/goodbyes}}') .withInput({ goodbyes: ['goodbye', 'Goodbye', 'GOODBYE'] }) .withHelpers(helpers) .withMessage('This keyword in paths evaluates to current context') .toCompileTo('bar goodbyebar Goodbyebar GOODBYE'); expectTemplate('{{#hellos}}{{foo this/text}}{{/hellos}}') .withInput({ hellos: [{ text: 'hello' }, { text: 'Hello' }, { text: 'HELLO' }] }) .withHelpers(helpers) .withMessage('This keyword evaluates in more complex paths') .toCompileTo('bar hellobar Hellobar HELLO'); }); it('this keyword nested inside helpers param', function() { expectTemplate('{{#hellos}}{{foo text/this/foo}}{{/hellos}}').toThrow( Error, 'Invalid path: text/this - 1:17' ); expectTemplate('{{foo [this]}}') .withInput({ foo: function(value) { return value; }, this: 'bar' }) .toCompileTo('bar'); expectTemplate('{{foo text/[this]}}') .withInput({ foo: function(value) { return value; }, text: { this: 'bar' } }) .toCompileTo('bar'); }); it('pass string literals', function() { expectTemplate('{{"foo"}}').toCompileTo(''); expectTemplate('{{"foo"}}') .withInput({ foo: 'bar' }) .toCompileTo('bar'); expectTemplate('{{#"foo"}}{{.}}{{/"foo"}}') .withInput({ foo: ['bar', 'baz'] }) .toCompileTo('barbaz'); }); it('pass number literals', function() { expectTemplate('{{12}}').toCompileTo(''); expectTemplate('{{12}}') .withInput({ '12': 'bar' }) .toCompileTo('bar'); expectTemplate('{{12.34}}').toCompileTo(''); expectTemplate('{{12.34}}') .withInput({ '12.34': 'bar' }) .toCompileTo('bar'); expectTemplate('{{12.34 1}}') .withInput({ '12.34': function(arg) { return 'bar' + arg; } }) .toCompileTo('bar1'); }); it('pass boolean literals', function() { expectTemplate('{{true}}').toCompileTo(''); expectTemplate('{{true}}') .withInput({ '': 'foo' }) .toCompileTo(''); expectTemplate('{{false}}') .withInput({ false: 'foo' }) .toCompileTo('foo'); }); it('should handle literals in subexpression', function() { expectTemplate('{{foo (false)}}') .withInput({ false: function() { return 'bar'; } }) .withHelper('foo', function(arg) { return arg; }) .toCompileTo('bar'); }); }); handlebars.js-4.7.7/spec/blocks.js000066400000000000000000000333721401244020700170160ustar00rootroot00000000000000describe('blocks', function() { it('array', function() { var string = '{{#goodbyes}}{{text}}! {{/goodbyes}}cruel {{world}}!'; expectTemplate(string) .withInput({ goodbyes: [ { text: 'goodbye' }, { text: 'Goodbye' }, { text: 'GOODBYE' } ], world: 'world' }) .withMessage('Arrays iterate over the contents when not empty') .toCompileTo('goodbye! Goodbye! GOODBYE! cruel world!'); expectTemplate(string) .withInput({ goodbyes: [], world: 'world' }) .withMessage('Arrays ignore the contents when empty') .toCompileTo('cruel world!'); }); it('array without data', function() { expectTemplate( '{{#goodbyes}}{{text}}{{/goodbyes}} {{#goodbyes}}{{text}}{{/goodbyes}}' ) .withInput({ goodbyes: [ { text: 'goodbye' }, { text: 'Goodbye' }, { text: 'GOODBYE' } ], world: 'world' }) .withCompileOptions({ compat: false }) .toCompileTo('goodbyeGoodbyeGOODBYE goodbyeGoodbyeGOODBYE'); }); it('array with @index', function() { expectTemplate( '{{#goodbyes}}{{@index}}. {{text}}! {{/goodbyes}}cruel {{world}}!' ) .withInput({ goodbyes: [ { text: 'goodbye' }, { text: 'Goodbye' }, { text: 'GOODBYE' } ], world: 'world' }) .withMessage('The @index variable is used') .toCompileTo('0. goodbye! 1. Goodbye! 2. GOODBYE! cruel world!'); }); it('empty block', function() { var string = '{{#goodbyes}}{{/goodbyes}}cruel {{world}}!'; expectTemplate(string) .withInput({ goodbyes: [ { text: 'goodbye' }, { text: 'Goodbye' }, { text: 'GOODBYE' } ], world: 'world' }) .withMessage('Arrays iterate over the contents when not empty') .toCompileTo('cruel world!'); expectTemplate(string) .withInput({ goodbyes: [], world: 'world' }) .withMessage('Arrays ignore the contents when empty') .toCompileTo('cruel world!'); }); it('block with complex lookup', function() { expectTemplate('{{#goodbyes}}{{text}} cruel {{../name}}! {{/goodbyes}}') .withInput({ name: 'Alan', goodbyes: [ { text: 'goodbye' }, { text: 'Goodbye' }, { text: 'GOODBYE' } ] }) .withMessage( 'Templates can access variables in contexts up the stack with relative path syntax' ) .toCompileTo( 'goodbye cruel Alan! Goodbye cruel Alan! GOODBYE cruel Alan! ' ); }); it('multiple blocks with complex lookup', function() { expectTemplate('{{#goodbyes}}{{../name}}{{../name}}{{/goodbyes}}') .withInput({ name: 'Alan', goodbyes: [ { text: 'goodbye' }, { text: 'Goodbye' }, { text: 'GOODBYE' } ] }) .toCompileTo('AlanAlanAlanAlanAlanAlan'); }); it('block with complex lookup using nested context', function() { expectTemplate( '{{#goodbyes}}{{text}} cruel {{foo/../name}}! {{/goodbyes}}' ).toThrow(Error); }); it('block with deep nested complex lookup', function() { expectTemplate( '{{#outer}}Goodbye {{#inner}}cruel {{../sibling}} {{../../omg}}{{/inner}}{{/outer}}' ) .withInput({ omg: 'OMG!', outer: [{ sibling: 'sad', inner: [{ text: 'goodbye' }] }] }) .toCompileTo('Goodbye cruel sad OMG!'); }); it('works with cached blocks', function() { expectTemplate( '{{#each person}}{{#with .}}{{first}} {{last}}{{/with}}{{/each}}' ) .withCompileOptions({ data: false }) .withInput({ person: [ { first: 'Alan', last: 'Johnson' }, { first: 'Alan', last: 'Johnson' } ] }) .toCompileTo('Alan JohnsonAlan Johnson'); }); describe('inverted sections', function() { it('inverted sections with unset value', function() { expectTemplate( '{{#goodbyes}}{{this}}{{/goodbyes}}{{^goodbyes}}Right On!{{/goodbyes}}' ) .withMessage("Inverted section rendered when value isn't set.") .toCompileTo('Right On!'); }); it('inverted section with false value', function() { expectTemplate( '{{#goodbyes}}{{this}}{{/goodbyes}}{{^goodbyes}}Right On!{{/goodbyes}}' ) .withInput({ goodbyes: false }) .withMessage('Inverted section rendered when value is false.') .toCompileTo('Right On!'); }); it('inverted section with empty set', function() { expectTemplate( '{{#goodbyes}}{{this}}{{/goodbyes}}{{^goodbyes}}Right On!{{/goodbyes}}' ) .withInput({ goodbyes: [] }) .withMessage('Inverted section rendered when value is empty set.') .toCompileTo('Right On!'); }); it('block inverted sections', function() { expectTemplate('{{#people}}{{name}}{{^}}{{none}}{{/people}}') .withInput({ none: 'No people' }) .toCompileTo('No people'); }); it('chained inverted sections', function() { expectTemplate('{{#people}}{{name}}{{else if none}}{{none}}{{/people}}') .withInput({ none: 'No people' }) .toCompileTo('No people'); expectTemplate( '{{#people}}{{name}}{{else if nothere}}fail{{else unless nothere}}{{none}}{{/people}}' ) .withInput({ none: 'No people' }) .toCompileTo('No people'); expectTemplate( '{{#people}}{{name}}{{else if none}}{{none}}{{else}}fail{{/people}}' ) .withInput({ none: 'No people' }) .toCompileTo('No people'); }); it('chained inverted sections with mismatch', function() { expectTemplate( '{{#people}}{{name}}{{else if none}}{{none}}{{/if}}' ).toThrow(Error); }); it('block inverted sections with empty arrays', function() { expectTemplate('{{#people}}{{name}}{{^}}{{none}}{{/people}}') .withInput({ none: 'No people', people: [] }) .toCompileTo('No people'); }); }); describe('standalone sections', function() { it('block standalone else sections', function() { expectTemplate('{{#people}}\n{{name}}\n{{^}}\n{{none}}\n{{/people}}\n') .withInput({ none: 'No people' }) .toCompileTo('No people\n'); expectTemplate('{{#none}}\n{{.}}\n{{^}}\n{{none}}\n{{/none}}\n') .withInput({ none: 'No people' }) .toCompileTo('No people\n'); expectTemplate('{{#people}}\n{{name}}\n{{^}}\n{{none}}\n{{/people}}\n') .withInput({ none: 'No people' }) .toCompileTo('No people\n'); }); it('block standalone else sections can be disabled', function() { expectTemplate('{{#people}}\n{{name}}\n{{^}}\n{{none}}\n{{/people}}\n') .withInput({ none: 'No people' }) .withCompileOptions({ ignoreStandalone: true }) .toCompileTo('\nNo people\n\n'); expectTemplate('{{#none}}\n{{.}}\n{{^}}\nFail\n{{/none}}\n') .withInput({ none: 'No people' }) .withCompileOptions({ ignoreStandalone: true }) .toCompileTo('\nNo people\n\n'); }); it('block standalone chained else sections', function() { expectTemplate( '{{#people}}\n{{name}}\n{{else if none}}\n{{none}}\n{{/people}}\n' ) .withInput({ none: 'No people' }) .toCompileTo('No people\n'); expectTemplate( '{{#people}}\n{{name}}\n{{else if none}}\n{{none}}\n{{^}}\n{{/people}}\n' ) .withInput({ none: 'No people' }) .toCompileTo('No people\n'); }); it('should handle nesting', function() { expectTemplate('{{#data}}\n{{#if true}}\n{{.}}\n{{/if}}\n{{/data}}\nOK.') .withInput({ data: [1, 3, 5] }) .toCompileTo('1\n3\n5\nOK.'); }); }); describe('compat mode', function() { it('block with deep recursive lookup lookup', function() { expectTemplate( '{{#outer}}Goodbye {{#inner}}cruel {{omg}}{{/inner}}{{/outer}}' ) .withInput({ omg: 'OMG!', outer: [{ inner: [{ text: 'goodbye' }] }] }) .withCompileOptions({ compat: true }) .toCompileTo('Goodbye cruel OMG!'); }); it('block with deep recursive pathed lookup', function() { expectTemplate( '{{#outer}}Goodbye {{#inner}}cruel {{omg.yes}}{{/inner}}{{/outer}}' ) .withInput({ omg: { yes: 'OMG!' }, outer: [{ inner: [{ yes: 'no', text: 'goodbye' }] }] }) .withCompileOptions({ compat: true }) .toCompileTo('Goodbye cruel OMG!'); }); it('block with missed recursive lookup', function() { expectTemplate( '{{#outer}}Goodbye {{#inner}}cruel {{omg.yes}}{{/inner}}{{/outer}}' ) .withInput({ omg: { no: 'OMG!' }, outer: [{ inner: [{ yes: 'no', text: 'goodbye' }] }] }) .withCompileOptions({ compat: true }) .toCompileTo('Goodbye cruel '); }); }); describe('decorators', function() { it('should apply mustache decorators', function() { expectTemplate('{{#helper}}{{*decorator}}{{/helper}}') .withHelper('helper', function(options) { return options.fn.run; }) .withDecorator('decorator', function(fn) { fn.run = 'success'; return fn; }) .toCompileTo('success'); }); it('should apply allow undefined return', function() { expectTemplate('{{#helper}}{{*decorator}}suc{{/helper}}') .withHelper('helper', function(options) { return options.fn() + options.fn.run; }) .withDecorator('decorator', function(fn) { fn.run = 'cess'; }) .toCompileTo('success'); }); it('should apply block decorators', function() { expectTemplate( '{{#helper}}{{#*decorator}}success{{/decorator}}{{/helper}}' ) .withHelper('helper', function(options) { return options.fn.run; }) .withDecorator('decorator', function(fn, props, container, options) { fn.run = options.fn(); return fn; }) .toCompileTo('success'); }); it('should support nested decorators', function() { expectTemplate( '{{#helper}}{{#*decorator}}{{#*nested}}suc{{/nested}}cess{{/decorator}}{{/helper}}' ) .withHelper('helper', function(options) { return options.fn.run; }) .withDecorators({ decorator: function(fn, props, container, options) { fn.run = options.fn.nested + options.fn(); return fn; }, nested: function(fn, props, container, options) { props.nested = options.fn(); } }) .toCompileTo('success'); }); it('should apply multiple decorators', function() { expectTemplate( '{{#helper}}{{#*decorator}}suc{{/decorator}}{{#*decorator}}cess{{/decorator}}{{/helper}}' ) .withHelper('helper', function(options) { return options.fn.run; }) .withDecorator('decorator', function(fn, props, container, options) { fn.run = (fn.run || '') + options.fn(); return fn; }) .toCompileTo('success'); }); it('should access parent variables', function() { expectTemplate('{{#helper}}{{*decorator foo}}{{/helper}}') .withHelper('helper', function(options) { return options.fn.run; }) .withDecorator('decorator', function(fn, props, container, options) { fn.run = options.args; return fn; }) .withInput({ foo: 'success' }) .toCompileTo('success'); }); it('should work with root program', function() { var run; expectTemplate('{{*decorator "success"}}') .withDecorator('decorator', function(fn, props, container, options) { equals(options.args[0], 'success'); run = true; return fn; }) .withInput({ foo: 'success' }) .toCompileTo(''); equals(run, true); }); it('should fail when accessing variables from root', function() { var run; expectTemplate('{{*decorator foo}}') .withDecorator('decorator', function(fn, props, container, options) { equals(options.args[0], undefined); run = true; return fn; }) .withInput({ foo: 'fail' }) .toCompileTo(''); equals(run, true); }); describe('registration', function() { it('unregisters', function() { handlebarsEnv.decorators = {}; handlebarsEnv.registerDecorator('foo', function() { return 'fail'; }); equals(!!handlebarsEnv.decorators.foo, true); handlebarsEnv.unregisterDecorator('foo'); equals(handlebarsEnv.decorators.foo, undefined); }); it('allows multiple globals', function() { handlebarsEnv.decorators = {}; handlebarsEnv.registerDecorator({ foo: function() {}, bar: function() {} }); equals(!!handlebarsEnv.decorators.foo, true); equals(!!handlebarsEnv.decorators.bar, true); handlebarsEnv.unregisterDecorator('foo'); handlebarsEnv.unregisterDecorator('bar'); equals(handlebarsEnv.decorators.foo, undefined); equals(handlebarsEnv.decorators.bar, undefined); }); it('fails with multiple and args', function() { shouldThrow( function() { handlebarsEnv.registerDecorator( { world: function() { return 'world!'; }, testHelper: function() { return 'found it!'; } }, {} ); }, Error, 'Arg not supported with multiple decorators' ); }); }); }); }); handlebars.js-4.7.7/spec/builtins.js000066400000000000000000000530641401244020700173720ustar00rootroot00000000000000describe('builtin helpers', function() { describe('#if', function() { it('if', function() { var string = '{{#if goodbye}}GOODBYE {{/if}}cruel {{world}}!'; expectTemplate(string) .withInput({ goodbye: true, world: 'world' }) .withMessage('if with boolean argument shows the contents when true') .toCompileTo('GOODBYE cruel world!'); expectTemplate(string) .withInput({ goodbye: 'dummy', world: 'world' }) .withMessage('if with string argument shows the contents') .toCompileTo('GOODBYE cruel world!'); expectTemplate(string) .withInput({ goodbye: false, world: 'world' }) .withMessage( 'if with boolean argument does not show the contents when false' ) .toCompileTo('cruel world!'); expectTemplate(string) .withInput({ world: 'world' }) .withMessage('if with undefined does not show the contents') .toCompileTo('cruel world!'); expectTemplate(string) .withInput({ goodbye: ['foo'], world: 'world' }) .withMessage('if with non-empty array shows the contents') .toCompileTo('GOODBYE cruel world!'); expectTemplate(string) .withInput({ goodbye: [], world: 'world' }) .withMessage('if with empty array does not show the contents') .toCompileTo('cruel world!'); expectTemplate(string) .withInput({ goodbye: 0, world: 'world' }) .withMessage('if with zero does not show the contents') .toCompileTo('cruel world!'); expectTemplate( '{{#if goodbye includeZero=true}}GOODBYE {{/if}}cruel {{world}}!' ) .withInput({ goodbye: 0, world: 'world' }) .withMessage('if with zero does not show the contents') .toCompileTo('GOODBYE cruel world!'); }); it('if with function argument', function() { var string = '{{#if goodbye}}GOODBYE {{/if}}cruel {{world}}!'; expectTemplate(string) .withInput({ goodbye: function() { return true; }, world: 'world' }) .withMessage( 'if with function shows the contents when function returns true' ) .toCompileTo('GOODBYE cruel world!'); expectTemplate(string) .withInput({ goodbye: function() { return this.world; }, world: 'world' }) .withMessage( 'if with function shows the contents when function returns string' ) .toCompileTo('GOODBYE cruel world!'); expectTemplate(string) .withInput({ goodbye: function() { return false; }, world: 'world' }) .withMessage( 'if with function does not show the contents when returns false' ) .toCompileTo('cruel world!'); expectTemplate(string) .withInput({ goodbye: function() { return this.foo; }, world: 'world' }) .withMessage( 'if with function does not show the contents when returns undefined' ) .toCompileTo('cruel world!'); }); it('should not change the depth list', function() { expectTemplate( '{{#with foo}}{{#if goodbye}}GOODBYE cruel {{../world}}!{{/if}}{{/with}}' ) .withInput({ foo: { goodbye: true }, world: 'world' }) .toCompileTo('GOODBYE cruel world!'); }); }); describe('#with', function() { it('with', function() { expectTemplate('{{#with person}}{{first}} {{last}}{{/with}}') .withInput({ person: { first: 'Alan', last: 'Johnson' } }) .toCompileTo('Alan Johnson'); }); it('with with function argument', function() { expectTemplate('{{#with person}}{{first}} {{last}}{{/with}}') .withInput({ person: function() { return { first: 'Alan', last: 'Johnson' }; } }) .toCompileTo('Alan Johnson'); }); it('with with else', function() { expectTemplate( '{{#with person}}Person is present{{else}}Person is not present{{/with}}' ).toCompileTo('Person is not present'); }); it('with provides block parameter', function() { expectTemplate('{{#with person as |foo|}}{{foo.first}} {{last}}{{/with}}') .withInput({ person: { first: 'Alan', last: 'Johnson' } }) .toCompileTo('Alan Johnson'); }); it('works when data is disabled', function() { expectTemplate('{{#with person as |foo|}}{{foo.first}} {{last}}{{/with}}') .withInput({ person: { first: 'Alan', last: 'Johnson' } }) .withCompileOptions({ data: false }) .toCompileTo('Alan Johnson'); }); }); describe('#each', function() { beforeEach(function() { handlebarsEnv.registerHelper('detectDataInsideEach', function(options) { return options.data && options.data.exclaim; }); }); it('each', function() { var string = '{{#each goodbyes}}{{text}}! {{/each}}cruel {{world}}!'; expectTemplate(string) .withInput({ goodbyes: [ { text: 'goodbye' }, { text: 'Goodbye' }, { text: 'GOODBYE' } ], world: 'world' }) .withMessage( 'each with array argument iterates over the contents when not empty' ) .toCompileTo('goodbye! Goodbye! GOODBYE! cruel world!'); expectTemplate(string) .withInput({ goodbyes: [], world: 'world' }) .withMessage('each with array argument ignores the contents when empty') .toCompileTo('cruel world!'); }); it('each without data', function() { expectTemplate('{{#each goodbyes}}{{text}}! {{/each}}cruel {{world}}!') .withInput({ goodbyes: [ { text: 'goodbye' }, { text: 'Goodbye' }, { text: 'GOODBYE' } ], world: 'world' }) .withRuntimeOptions({ data: false }) .withCompileOptions({ data: false }) .toCompileTo('goodbye! Goodbye! GOODBYE! cruel world!'); expectTemplate('{{#each .}}{{.}}{{/each}}') .withInput({ goodbyes: 'cruel', world: 'world' }) .withRuntimeOptions({ data: false }) .withCompileOptions({ data: false }) .toCompileTo('cruelworld'); }); it('each without context', function() { expectTemplate('{{#each goodbyes}}{{text}}! {{/each}}cruel {{world}}!') .withInput(undefined) .toCompileTo('cruel !'); }); it('each with an object and @key', function() { var string = '{{#each goodbyes}}{{@key}}. {{text}}! {{/each}}cruel {{world}}!'; function Clazz() { this['#1'] = { text: 'goodbye' }; this[2] = { text: 'GOODBYE' }; } Clazz.prototype.foo = 'fail'; var hash = { goodbyes: new Clazz(), world: 'world' }; // Object property iteration order is undefined according to ECMA spec, // so we need to check both possible orders // @see http://stackoverflow.com/questions/280713/elements-order-in-a-for-in-loop var actual = compileWithPartials(string, hash); var expected1 = '<b>#1</b>. goodbye! 2. GOODBYE! cruel world!'; var expected2 = '2. GOODBYE! <b>#1</b>. goodbye! cruel world!'; equals( actual === expected1 || actual === expected2, true, 'each with object argument iterates over the contents when not empty' ); expectTemplate(string) .withInput({ goodbyes: {}, world: 'world' }) .toCompileTo('cruel world!'); }); it('each with @index', function() { expectTemplate( '{{#each goodbyes}}{{@index}}. {{text}}! {{/each}}cruel {{world}}!' ) .withInput({ goodbyes: [ { text: 'goodbye' }, { text: 'Goodbye' }, { text: 'GOODBYE' } ], world: 'world' }) .withMessage('The @index variable is used') .toCompileTo('0. goodbye! 1. Goodbye! 2. GOODBYE! cruel world!'); }); it('each with nested @index', function() { expectTemplate( '{{#each goodbyes}}{{@index}}. {{text}}! {{#each ../goodbyes}}{{@index}} {{/each}}After {{@index}} {{/each}}{{@index}}cruel {{world}}!' ) .withInput({ goodbyes: [ { text: 'goodbye' }, { text: 'Goodbye' }, { text: 'GOODBYE' } ], world: 'world' }) .withMessage('The @index variable is used') .toCompileTo( '0. goodbye! 0 1 2 After 0 1. Goodbye! 0 1 2 After 1 2. GOODBYE! 0 1 2 After 2 cruel world!' ); }); it('each with block params', function() { expectTemplate( '{{#each goodbyes as |value index|}}{{index}}. {{value.text}}! {{#each ../goodbyes as |childValue childIndex|}} {{index}} {{childIndex}}{{/each}} After {{index}} {{/each}}{{index}}cruel {{world}}!' ) .withInput({ goodbyes: [{ text: 'goodbye' }, { text: 'Goodbye' }], world: 'world' }) .toCompileTo( '0. goodbye! 0 0 0 1 After 0 1. Goodbye! 1 0 1 1 After 1 cruel world!' ); }); it('each object with @index', function() { expectTemplate( '{{#each goodbyes}}{{@index}}. {{text}}! {{/each}}cruel {{world}}!' ) .withInput({ goodbyes: { a: { text: 'goodbye' }, b: { text: 'Goodbye' }, c: { text: 'GOODBYE' } }, world: 'world' }) .withMessage('The @index variable is used') .toCompileTo('0. goodbye! 1. Goodbye! 2. GOODBYE! cruel world!'); }); it('each with @first', function() { expectTemplate( '{{#each goodbyes}}{{#if @first}}{{text}}! {{/if}}{{/each}}cruel {{world}}!' ) .withInput({ goodbyes: [ { text: 'goodbye' }, { text: 'Goodbye' }, { text: 'GOODBYE' } ], world: 'world' }) .withMessage('The @first variable is used') .toCompileTo('goodbye! cruel world!'); }); it('each with nested @first', function() { expectTemplate( '{{#each goodbyes}}({{#if @first}}{{text}}! {{/if}}{{#each ../goodbyes}}{{#if @first}}{{text}}!{{/if}}{{/each}}{{#if @first}} {{text}}!{{/if}}) {{/each}}cruel {{world}}!' ) .withInput({ goodbyes: [ { text: 'goodbye' }, { text: 'Goodbye' }, { text: 'GOODBYE' } ], world: 'world' }) .withMessage('The @first variable is used') .toCompileTo( '(goodbye! goodbye! goodbye!) (goodbye!) (goodbye!) cruel world!' ); }); it('each object with @first', function() { expectTemplate( '{{#each goodbyes}}{{#if @first}}{{text}}! {{/if}}{{/each}}cruel {{world}}!' ) .withInput({ goodbyes: { foo: { text: 'goodbye' }, bar: { text: 'Goodbye' } }, world: 'world' }) .withMessage('The @first variable is used') .toCompileTo('goodbye! cruel world!'); }); it('each with @last', function() { expectTemplate( '{{#each goodbyes}}{{#if @last}}{{text}}! {{/if}}{{/each}}cruel {{world}}!' ) .withInput({ goodbyes: [ { text: 'goodbye' }, { text: 'Goodbye' }, { text: 'GOODBYE' } ], world: 'world' }) .withMessage('The @last variable is used') .toCompileTo('GOODBYE! cruel world!'); }); it('each object with @last', function() { expectTemplate( '{{#each goodbyes}}{{#if @last}}{{text}}! {{/if}}{{/each}}cruel {{world}}!' ) .withInput({ goodbyes: { foo: { text: 'goodbye' }, bar: { text: 'Goodbye' } }, world: 'world' }) .withMessage('The @last variable is used') .toCompileTo('Goodbye! cruel world!'); }); it('each with nested @last', function() { expectTemplate( '{{#each goodbyes}}({{#if @last}}{{text}}! {{/if}}{{#each ../goodbyes}}{{#if @last}}{{text}}!{{/if}}{{/each}}{{#if @last}} {{text}}!{{/if}}) {{/each}}cruel {{world}}!' ) .withInput({ goodbyes: [ { text: 'goodbye' }, { text: 'Goodbye' }, { text: 'GOODBYE' } ], world: 'world' }) .withMessage('The @last variable is used') .toCompileTo( '(GOODBYE!) (GOODBYE!) (GOODBYE! GOODBYE! GOODBYE!) cruel world!' ); }); it('each with function argument', function() { var string = '{{#each goodbyes}}{{text}}! {{/each}}cruel {{world}}!'; expectTemplate(string) .withInput({ goodbyes: function() { return [ { text: 'goodbye' }, { text: 'Goodbye' }, { text: 'GOODBYE' } ]; }, world: 'world' }) .withMessage( 'each with array function argument iterates over the contents when not empty' ) .toCompileTo('goodbye! Goodbye! GOODBYE! cruel world!'); expectTemplate(string) .withInput({ goodbyes: [], world: 'world' }) .withMessage( 'each with array function argument ignores the contents when empty' ) .toCompileTo('cruel world!'); }); it('each object when last key is an empty string', function() { expectTemplate( '{{#each goodbyes}}{{@index}}. {{text}}! {{/each}}cruel {{world}}!' ) .withInput({ goodbyes: { a: { text: 'goodbye' }, b: { text: 'Goodbye' }, '': { text: 'GOODBYE' } }, world: 'world' }) .withMessage('Empty string key is not skipped') .toCompileTo('0. goodbye! 1. Goodbye! 2. GOODBYE! cruel world!'); }); it('data passed to helpers', function() { expectTemplate( '{{#each letters}}{{this}}{{detectDataInsideEach}}{{/each}}' ) .withInput({ letters: ['a', 'b', 'c'] }) .withMessage('should output data') .withRuntimeOptions({ data: { exclaim: '!' } }) .toCompileTo('a!b!c!'); }); it('each on implicit context', function() { expectTemplate('{{#each}}{{text}}! {{/each}}cruel world!').toThrow( handlebarsEnv.Exception, 'Must pass iterator to #each' ); }); if (global.Symbol && global.Symbol.iterator) { it('each on iterable', function() { function Iterator(arr) { this.arr = arr; this.index = 0; } Iterator.prototype.next = function() { var value = this.arr[this.index]; var done = this.index === this.arr.length; if (!done) { this.index++; } return { value: value, done: done }; }; function Iterable(arr) { this.arr = arr; } Iterable.prototype[global.Symbol.iterator] = function() { return new Iterator(this.arr); }; var string = '{{#each goodbyes}}{{text}}! {{/each}}cruel {{world}}!'; expectTemplate(string) .withInput({ goodbyes: new Iterable([ { text: 'goodbye' }, { text: 'Goodbye' }, { text: 'GOODBYE' } ]), world: 'world' }) .withMessage( 'each with array argument iterates over the contents when not empty' ) .toCompileTo('goodbye! Goodbye! GOODBYE! cruel world!'); expectTemplate(string) .withInput({ goodbyes: new Iterable([]), world: 'world' }) .withMessage( 'each with array argument ignores the contents when empty' ) .toCompileTo('cruel world!'); }); } }); describe('#log', function() { /* eslint-disable no-console */ if (typeof console === 'undefined') { return; } var $log, $info, $error; beforeEach(function() { $log = console.log; $info = console.info; $error = console.error; }); afterEach(function() { console.log = $log; console.info = $info; console.error = $error; }); it('should call logger at default level', function() { var levelArg, logArg; handlebarsEnv.log = function(level, arg) { levelArg = level; logArg = arg; }; expectTemplate('{{log blah}}') .withInput({ blah: 'whee' }) .withMessage('log should not display') .toCompileTo(''); equals(1, levelArg, 'should call log with 1'); equals('whee', logArg, "should call log with 'whee'"); }); it('should call logger at data level', function() { var levelArg, logArg; handlebarsEnv.log = function(level, arg) { levelArg = level; logArg = arg; }; expectTemplate('{{log blah}}') .withInput({ blah: 'whee' }) .withRuntimeOptions({ data: { level: '03' } }) .withCompileOptions({ data: true }) .toCompileTo(''); equals('03', levelArg); equals('whee', logArg); }); it('should output to info', function() { var called; console.info = function(info) { equals('whee', info); called = true; console.info = $info; console.log = $log; }; console.log = function(log) { equals('whee', log); called = true; console.info = $info; console.log = $log; }; expectTemplate('{{log blah}}') .withInput({ blah: 'whee' }) .toCompileTo(''); equals(true, called); }); it('should log at data level', function() { var called; console.error = function(log) { equals('whee', log); called = true; console.error = $error; }; expectTemplate('{{log blah}}') .withInput({ blah: 'whee' }) .withRuntimeOptions({ data: { level: '03' } }) .withCompileOptions({ data: true }) .toCompileTo(''); equals(true, called); }); it('should handle missing logger', function() { var called = false; console.error = undefined; console.log = function(log) { equals('whee', log); called = true; console.log = $log; }; expectTemplate('{{log blah}}') .withInput({ blah: 'whee' }) .withRuntimeOptions({ data: { level: '03' } }) .withCompileOptions({ data: true }) .toCompileTo(''); equals(true, called); }); it('should handle string log levels', function() { var called; console.error = function(log) { equals('whee', log); called = true; }; expectTemplate('{{log blah}}') .withInput({ blah: 'whee' }) .withRuntimeOptions({ data: { level: 'error' } }) .withCompileOptions({ data: true }) .toCompileTo(''); equals(true, called); called = false; expectTemplate('{{log blah}}') .withInput({ blah: 'whee' }) .withRuntimeOptions({ data: { level: 'ERROR' } }) .withCompileOptions({ data: true }) .toCompileTo(''); equals(true, called); }); it('should handle hash log levels', function() { var called; console.error = function(log) { equals('whee', log); called = true; }; expectTemplate('{{log blah level="error"}}') .withInput({ blah: 'whee' }) .toCompileTo(''); equals(true, called); }); it('should handle hash log levels', function() { var called = false; console.info = console.log = console.error = console.debug = function() { called = true; console.info = console.log = console.error = console.debug = $log; }; expectTemplate('{{log blah level="debug"}}') .withInput({ blah: 'whee' }) .toCompileTo(''); equals(false, called); }); it('should pass multiple log arguments', function() { var called; console.info = console.log = function(log1, log2, log3) { equals('whee', log1); equals('foo', log2); equals(1, log3); called = true; console.log = $log; }; expectTemplate('{{log blah "foo" 1}}') .withInput({ blah: 'whee' }) .toCompileTo(''); equals(true, called); }); it('should pass zero log arguments', function() { var called; console.info = console.log = function() { expect(arguments.length).to.equal(0); called = true; console.log = $log; }; expectTemplate('{{log}}') .withInput({ blah: 'whee' }) .toCompileTo(''); expect(called).to.be.true(); }); /* eslint-enable no-console */ }); describe('#lookup', function() { it('should lookup arbitrary content', function() { expectTemplate('{{#each goodbyes}}{{lookup ../data .}}{{/each}}') .withInput({ goodbyes: [0, 1], data: ['foo', 'bar'] }) .toCompileTo('foobar'); }); it('should not fail on undefined value', function() { expectTemplate('{{#each goodbyes}}{{lookup ../bar .}}{{/each}}') .withInput({ goodbyes: [0, 1], data: ['foo', 'bar'] }) .toCompileTo(''); }); }); }); handlebars.js-4.7.7/spec/compiler.js000066400000000000000000000130141401244020700173420ustar00rootroot00000000000000describe('compiler', function() { if (!Handlebars.compile) { return; } describe('#equals', function() { function compile(string) { var ast = Handlebars.parse(string); return new Handlebars.Compiler().compile(ast, {}); } it('should treat as equal', function() { equal(compile('foo').equals(compile('foo')), true); equal(compile('{{foo}}').equals(compile('{{foo}}')), true); equal(compile('{{foo.bar}}').equals(compile('{{foo.bar}}')), true); equal( compile('{{foo.bar baz "foo" true false bat=1}}').equals( compile('{{foo.bar baz "foo" true false bat=1}}') ), true ); equal( compile('{{foo.bar (baz bat=1)}}').equals( compile('{{foo.bar (baz bat=1)}}') ), true ); equal( compile('{{#foo}} {{/foo}}').equals(compile('{{#foo}} {{/foo}}')), true ); }); it('should treat as not equal', function() { equal(compile('foo').equals(compile('bar')), false); equal(compile('{{foo}}').equals(compile('{{bar}}')), false); equal(compile('{{foo.bar}}').equals(compile('{{bar.bar}}')), false); equal( compile('{{foo.bar baz bat=1}}').equals( compile('{{foo.bar bar bat=1}}') ), false ); equal( compile('{{foo.bar (baz bat=1)}}').equals( compile('{{foo.bar (bar bat=1)}}') ), false ); equal( compile('{{#foo}} {{/foo}}').equals(compile('{{#bar}} {{/bar}}')), false ); equal( compile('{{#foo}} {{/foo}}').equals( compile('{{#foo}} {{foo}}{{/foo}}') ), false ); }); }); describe('#compile', function() { it('should fail with invalid input', function() { shouldThrow( function() { Handlebars.compile(null); }, Error, 'You must pass a string or Handlebars AST to Handlebars.compile. You passed null' ); shouldThrow( function() { Handlebars.compile({}); }, Error, 'You must pass a string or Handlebars AST to Handlebars.compile. You passed [object Object]' ); }); it('should include the location in the error (row and column)', function() { try { Handlebars.compile(' \n {{#if}}\n{{/def}}')(); equal( true, false, 'Statement must throw exception. This line should not be executed.' ); } catch (err) { equal( err.message, "if doesn't match def - 2:5", 'Checking error message' ); if (Object.getOwnPropertyDescriptor(err, 'column').writable) { // In Safari 8, the column-property is read-only. This means that even if it is set with defineProperty, // its value won't change (https://github.com/jquery/esprima/issues/1290#issuecomment-132455482) // Since this was neither working in Handlebars 3 nor in 4.0.5, we only check the column for other browsers. equal(err.column, 5, 'Checking error column'); } equal(err.lineNumber, 2, 'Checking error row'); } }); it('should include the location as enumerable property', function() { try { Handlebars.compile(' \n {{#if}}\n{{/def}}')(); equal( true, false, 'Statement must throw exception. This line should not be executed.' ); } catch (err) { equal( Object.prototype.propertyIsEnumerable.call(err, 'column'), true, 'Checking error column' ); } }); it('can utilize AST instance', function() { equal( Handlebars.compile({ type: 'Program', body: [{ type: 'ContentStatement', value: 'Hello' }] })(), 'Hello' ); }); it('can pass through an empty string', function() { equal(Handlebars.compile('')(), ''); }); it('should not modify the options.data property(GH-1327)', function() { var options = { data: [{ a: 'foo' }, { a: 'bar' }] }; Handlebars.compile('{{#each data}}{{@index}}:{{a}} {{/each}}', options)(); equal( JSON.stringify(options, 0, 2), JSON.stringify({ data: [{ a: 'foo' }, { a: 'bar' }] }, 0, 2) ); }); it('should not modify the options.knownHelpers property(GH-1327)', function() { var options = { knownHelpers: {} }; Handlebars.compile('{{#each data}}{{@index}}:{{a}} {{/each}}', options)(); equal( JSON.stringify(options, 0, 2), JSON.stringify({ knownHelpers: {} }, 0, 2) ); }); }); describe('#precompile', function() { it('should fail with invalid input', function() { shouldThrow( function() { Handlebars.precompile(null); }, Error, 'You must pass a string or Handlebars AST to Handlebars.precompile. You passed null' ); shouldThrow( function() { Handlebars.precompile({}); }, Error, 'You must pass a string or Handlebars AST to Handlebars.precompile. You passed [object Object]' ); }); it('can utilize AST instance', function() { equal( /return "Hello"/.test( Handlebars.precompile({ type: 'Program', body: [{ type: 'ContentStatement', value: 'Hello' }] }) ), true ); }); it('can pass through an empty string', function() { equal(/return ""/.test(Handlebars.precompile('')), true); }); }); }); handlebars.js-4.7.7/spec/data.js000066400000000000000000000234171401244020700164510ustar00rootroot00000000000000describe('data', function() { it('passing in data to a compiled function that expects data - works with helpers', function() { expectTemplate('{{hello}}') .withCompileOptions({ data: true }) .withHelper('hello', function(options) { return options.data.adjective + ' ' + this.noun; }) .withRuntimeOptions({ data: { adjective: 'happy' } }) .withInput({ noun: 'cat' }) .withMessage('Data output by helper') .toCompileTo('happy cat'); }); it('data can be looked up via @foo', function() { expectTemplate('{{@hello}}') .withRuntimeOptions({ data: { hello: 'hello' } }) .withMessage('@foo retrieves template data') .toCompileTo('hello'); }); it('deep @foo triggers automatic top-level data', function() { var helpers = Handlebars.createFrame(handlebarsEnv.helpers); helpers.let = function(options) { var frame = Handlebars.createFrame(options.data); for (var prop in options.hash) { if (prop in options.hash) { frame[prop] = options.hash[prop]; } } return options.fn(this, { data: frame }); }; expectTemplate( '{{#let world="world"}}{{#if foo}}{{#if foo}}Hello {{@world}}{{/if}}{{/if}}{{/let}}' ) .withInput({ foo: true }) .withHelpers(helpers) .withMessage('Automatic data was triggered') .toCompileTo('Hello world'); }); it('parameter data can be looked up via @foo', function() { expectTemplate('{{hello @world}}') .withRuntimeOptions({ data: { world: 'world' } }) .withHelper('hello', function(noun) { return 'Hello ' + noun; }) .withMessage('@foo as a parameter retrieves template data') .toCompileTo('Hello world'); }); it('hash values can be looked up via @foo', function() { expectTemplate('{{hello noun=@world}}') .withRuntimeOptions({ data: { world: 'world' } }) .withHelper('hello', function(options) { return 'Hello ' + options.hash.noun; }) .withMessage('@foo as a parameter retrieves template data') .toCompileTo('Hello world'); }); it('nested parameter data can be looked up via @foo.bar', function() { expectTemplate('{{hello @world.bar}}') .withRuntimeOptions({ data: { world: { bar: 'world' } } }) .withHelper('hello', function(noun) { return 'Hello ' + noun; }) .withMessage('@foo as a parameter retrieves template data') .toCompileTo('Hello world'); }); it('nested parameter data does not fail with @world.bar', function() { expectTemplate('{{hello @world.bar}}') .withRuntimeOptions({ data: { foo: { bar: 'world' } } }) .withHelper('hello', function(noun) { return 'Hello ' + noun; }) .withMessage('@foo as a parameter retrieves template data') .toCompileTo('Hello undefined'); }); it('parameter data throws when using complex scope references', function() { expectTemplate( '{{#goodbyes}}{{text}} cruel {{@foo/../name}}! {{/goodbyes}}' ).toThrow(Error); }); it('data can be functions', function() { expectTemplate('{{@hello}}') .withRuntimeOptions({ data: { hello: function() { return 'hello'; } } }) .toCompileTo('hello'); }); it('data can be functions with params', function() { expectTemplate('{{@hello "hello"}}') .withRuntimeOptions({ data: { hello: function(arg) { return arg; } } }) .toCompileTo('hello'); }); it('data is inherited downstream', function() { expectTemplate( '{{#let foo=1 bar=2}}{{#let foo=bar.baz}}{{@bar}}{{@foo}}{{/let}}{{@foo}}{{/let}}' ) .withInput({ bar: { baz: 'hello world' } }) .withCompileOptions({ data: true }) .withHelper('let', function(options) { var frame = Handlebars.createFrame(options.data); for (var prop in options.hash) { if (prop in options.hash) { frame[prop] = options.hash[prop]; } } return options.fn(this, { data: frame }); }) .withRuntimeOptions({ data: {} }) .withMessage('data variables are inherited downstream') .toCompileTo('2hello world1'); }); it('passing in data to a compiled function that expects data - works with helpers in partials', function() { expectTemplate('{{>myPartial}}') .withCompileOptions({ data: true }) .withPartial('myPartial', '{{hello}}') .withHelper('hello', function(options) { return options.data.adjective + ' ' + this.noun; }) .withInput({ noun: 'cat' }) .withRuntimeOptions({ data: { adjective: 'happy' } }) .withMessage('Data output by helper inside partial') .toCompileTo('happy cat'); }); it('passing in data to a compiled function that expects data - works with helpers and parameters', function() { expectTemplate('{{hello world}}') .withCompileOptions({ data: true }) .withHelper('hello', function(noun, options) { return options.data.adjective + ' ' + noun + (this.exclaim ? '!' : ''); }) .withInput({ exclaim: true, world: 'world' }) .withRuntimeOptions({ data: { adjective: 'happy' } }) .withMessage('Data output by helper') .toCompileTo('happy world!'); }); it('passing in data to a compiled function that expects data - works with block helpers', function() { expectTemplate('{{#hello}}{{world}}{{/hello}}') .withCompileOptions({ data: true }) .withHelper('hello', function(options) { return options.fn(this); }) .withHelper('world', function(options) { return options.data.adjective + ' world' + (this.exclaim ? '!' : ''); }) .withInput({ exclaim: true }) .withRuntimeOptions({ data: { adjective: 'happy' } }) .withMessage('Data output by helper') .toCompileTo('happy world!'); }); it('passing in data to a compiled function that expects data - works with block helpers that use ..', function() { expectTemplate('{{#hello}}{{world ../zomg}}{{/hello}}') .withCompileOptions({ data: true }) .withHelper('hello', function(options) { return options.fn({ exclaim: '?' }); }) .withHelper('world', function(thing, options) { return options.data.adjective + ' ' + thing + (this.exclaim || ''); }) .withInput({ exclaim: true, zomg: 'world' }) .withRuntimeOptions({ data: { adjective: 'happy' } }) .withMessage('Data output by helper') .toCompileTo('happy world?'); }); it('passing in data to a compiled function that expects data - data is passed to with block helpers where children use ..', function() { expectTemplate('{{#hello}}{{world ../zomg}}{{/hello}}') .withCompileOptions({ data: true }) .withHelper('hello', function(options) { return options.data.accessData + ' ' + options.fn({ exclaim: '?' }); }) .withHelper('world', function(thing, options) { return options.data.adjective + ' ' + thing + (this.exclaim || ''); }) .withInput({ exclaim: true, zomg: 'world' }) .withRuntimeOptions({ data: { adjective: 'happy', accessData: '#win' } }) .withMessage('Data output by helper') .toCompileTo('#win happy world?'); }); it('you can override inherited data when invoking a helper', function() { expectTemplate('{{#hello}}{{world zomg}}{{/hello}}') .withCompileOptions({ data: true }) .withHelper('hello', function(options) { return options.fn( { exclaim: '?', zomg: 'world' }, { data: { adjective: 'sad' } } ); }) .withHelper('world', function(thing, options) { return options.data.adjective + ' ' + thing + (this.exclaim || ''); }) .withInput({ exclaim: true, zomg: 'planet' }) .withRuntimeOptions({ data: { adjective: 'happy' } }) .withMessage('Overriden data output by helper') .toCompileTo('sad world?'); }); it('you can override inherited data when invoking a helper with depth', function() { expectTemplate('{{#hello}}{{world ../zomg}}{{/hello}}') .withCompileOptions({ data: true }) .withHelper('hello', function(options) { return options.fn({ exclaim: '?' }, { data: { adjective: 'sad' } }); }) .withHelper('world', function(thing, options) { return options.data.adjective + ' ' + thing + (this.exclaim || ''); }) .withInput({ exclaim: true, zomg: 'world' }) .withRuntimeOptions({ data: { adjective: 'happy' } }) .withMessage('Overriden data output by helper') .toCompileTo('sad world?'); }); describe('@root', function() { it('the root context can be looked up via @root', function() { expectTemplate('{{@root.foo}}') .withInput({ foo: 'hello' }) .withRuntimeOptions({ data: {} }) .toCompileTo('hello'); expectTemplate('{{@root.foo}}') .withInput({ foo: 'hello' }) .toCompileTo('hello'); }); it('passed root values take priority', function() { expectTemplate('{{@root.foo}}') .withInput({ foo: 'should not be used' }) .withRuntimeOptions({ data: { root: { foo: 'hello' } } }) .toCompileTo('hello'); }); }); describe('nesting', function() { it('the root context can be looked up via @root', function() { expectTemplate( '{{#helper}}{{#helper}}{{@./depth}} {{@../depth}} {{@../../depth}}{{/helper}}{{/helper}}' ) .withInput({ foo: 'hello' }) .withHelper('helper', function(options) { var frame = Handlebars.createFrame(options.data); frame.depth = options.data.depth + 1; return options.fn(this, { data: frame }); }) .withRuntimeOptions({ data: { depth: 0 } }) .toCompileTo('2 1 0'); }); }); }); handlebars.js-4.7.7/spec/env/000077500000000000000000000000001401244020700157635ustar00rootroot00000000000000handlebars.js-4.7.7/spec/env/browser.js000066400000000000000000000020641401244020700200060ustar00rootroot00000000000000require('./common'); var fs = require('fs'), vm = require('vm'); var chai = require('chai'); var dirtyChai = require('dirty-chai'); chai.use(dirtyChai); global.expect = chai.expect; global.sinon = require('sinon'); global.Handlebars = 'no-conflict'; var filename = 'dist/handlebars.js'; if (global.minimizedTest) { filename = 'dist/handlebars.min.js'; } var distHandlebars = fs.readFileSync( require.resolve('../../' + filename), 'utf-8' ); vm.runInThisContext(distHandlebars, filename); global.CompilerContext = { browser: true, compile: function(template, options) { var templateSpec = handlebarsEnv.precompile(template, options); return handlebarsEnv.template(safeEval(templateSpec)); }, compileWithPartial: function(template, options) { return handlebarsEnv.compile(template, options); } }; function safeEval(templateSpec) { /* eslint-disable no-eval, no-console */ try { return eval('(' + templateSpec + ')'); } catch (err) { console.error(templateSpec); throw err; } /* eslint-enable no-eval, no-console */ } handlebars.js-4.7.7/spec/env/common.js000066400000000000000000000144761401244020700176250ustar00rootroot00000000000000var global = (function() { return this; })(); var AssertError; if (Error.captureStackTrace) { AssertError = function AssertError(message, caller) { Error.prototype.constructor.call(this, message); this.message = message; if (Error.captureStackTrace) { Error.captureStackTrace(this, caller || AssertError); } }; AssertError.prototype = new Error(); } else { AssertError = Error; } /** * @deprecated Use "expectTemplate(template)...toCompileTo(output)" instead */ global.shouldCompileTo = function(string, hashOrArray, expected, message) { shouldCompileToWithPartials(string, hashOrArray, false, expected, message); }; /** * @deprecated Use "expectTemplate(template)...toCompileTo(output)" instead */ global.shouldCompileToWithPartials = function shouldCompileToWithPartials( string, hashOrArray, partials, expected, message ) { var result = compileWithPartials(string, hashOrArray, partials); if (result !== expected) { throw new AssertError( "'" + result + "' should === '" + expected + "': " + message, shouldCompileToWithPartials ); } }; /** * @deprecated Use "expectTemplate(template)...toCompileTo(output)" instead */ global.compileWithPartials = function(string, hashOrArray, partials) { var template, ary, options; if (hashOrArray && hashOrArray.hash) { ary = [hashOrArray.hash, hashOrArray]; delete hashOrArray.hash; } else if (Object.prototype.toString.call(hashOrArray) === '[object Array]') { ary = []; ary.push(hashOrArray[0]); // input ary.push({ helpers: hashOrArray[1], partials: hashOrArray[2] }); options = typeof hashOrArray[3] === 'object' ? hashOrArray[3] : { compat: hashOrArray[3] }; if (hashOrArray[4] != null) { options.data = !!hashOrArray[4]; ary[1].data = hashOrArray[4]; } } else { ary = [hashOrArray]; } template = CompilerContext[partials ? 'compileWithPartial' : 'compile']( string, options ); return template.apply(this, ary); }; /** * @deprecated Use chai's expect-style API instead (`expect(actualValue).to.equal(expectedValue)`) * @see https://www.chaijs.com/api/bdd/ */ global.equals = global.equal = function equals(a, b, msg) { if (a !== b) { throw new AssertError( "'" + a + "' should === '" + b + "'" + (msg ? ': ' + msg : ''), equals ); } }; /** * @deprecated Use chai's expect-style API instead (`expect(actualValue).to.equal(expectedValue)`) * @see https://www.chaijs.com/api/bdd/#method_throw */ global.shouldThrow = function(callback, type, msg) { var failed; try { callback(); failed = true; } catch (caught) { if (type && !(caught instanceof type)) { throw new AssertError('Type failure: ' + caught); } if ( msg && !(msg.test ? msg.test(caught.message) : msg === caught.message) ) { throw new AssertError( 'Throw mismatch: Expected ' + caught.message + ' to match ' + msg + '\n\n' + caught.stack, shouldThrow ); } } if (failed) { throw new AssertError('It failed to throw', shouldThrow); } }; global.expectTemplate = function(templateAsString) { return new HandlebarsTestBench(templateAsString); }; function HandlebarsTestBench(templateAsString) { this.templateAsString = templateAsString; this.helpers = {}; this.partials = {}; this.decorators = {}; this.input = {}; this.message = 'Template' + templateAsString + ' does not evaluate to expected output'; this.compileOptions = {}; this.runtimeOptions = {}; } HandlebarsTestBench.prototype.withInput = function(input) { this.input = input; return this; }; HandlebarsTestBench.prototype.withHelper = function(name, helperFunction) { this.helpers[name] = helperFunction; return this; }; HandlebarsTestBench.prototype.withHelpers = function(helperFunctions) { var self = this; Object.keys(helperFunctions).forEach(function(name) { self.withHelper(name, helperFunctions[name]); }); return this; }; HandlebarsTestBench.prototype.withPartial = function(name, partialAsString) { this.partials[name] = partialAsString; return this; }; HandlebarsTestBench.prototype.withPartials = function(partials) { var self = this; Object.keys(partials).forEach(function(name) { self.withPartial(name, partials[name]); }); return this; }; HandlebarsTestBench.prototype.withDecorator = function( name, decoratorFunction ) { this.decorators[name] = decoratorFunction; return this; }; HandlebarsTestBench.prototype.withDecorators = function(decorators) { var self = this; Object.keys(decorators).forEach(function(name) { self.withDecorator(name, decorators[name]); }); return this; }; HandlebarsTestBench.prototype.withCompileOptions = function(compileOptions) { this.compileOptions = compileOptions; return this; }; HandlebarsTestBench.prototype.withRuntimeOptions = function(runtimeOptions) { this.runtimeOptions = runtimeOptions; return this; }; HandlebarsTestBench.prototype.withMessage = function(message) { this.message = message; return this; }; HandlebarsTestBench.prototype.toCompileTo = function(expectedOutputAsString) { expect(this._compileAndExecute()).to.equal( expectedOutputAsString, this.message ); }; // see chai "to.throw" (https://www.chaijs.com/api/bdd/#method_throw) HandlebarsTestBench.prototype.toThrow = function(errorLike, errMsgMatcher) { var self = this; expect(function() { self._compileAndExecute(); }).to.throw(errorLike, errMsgMatcher, this.message); }; HandlebarsTestBench.prototype._compileAndExecute = function() { var compile = Object.keys(this.partials).length > 0 ? CompilerContext.compileWithPartial : CompilerContext.compile; var combinedRuntimeOptions = this._combineRuntimeOptions(); var template = compile(this.templateAsString, this.compileOptions); return template(this.input, combinedRuntimeOptions); }; HandlebarsTestBench.prototype._combineRuntimeOptions = function() { var self = this; var combinedRuntimeOptions = {}; Object.keys(this.runtimeOptions).forEach(function(key) { combinedRuntimeOptions[key] = self.runtimeOptions[key]; }); combinedRuntimeOptions.helpers = this.helpers; combinedRuntimeOptions.partials = this.partials; combinedRuntimeOptions.decorators = this.decorators; return combinedRuntimeOptions; }; handlebars.js-4.7.7/spec/env/node.js000066400000000000000000000014051401244020700172460ustar00rootroot00000000000000require('./common'); var chai = require('chai'); var dirtyChai = require('dirty-chai'); chai.use(dirtyChai); global.expect = chai.expect; global.sinon = require('sinon'); global.Handlebars = require('../../lib'); global.CompilerContext = { compile: function(template, options) { var templateSpec = handlebarsEnv.precompile(template, options); return handlebarsEnv.template(safeEval(templateSpec)); }, compileWithPartial: function(template, options) { return handlebarsEnv.compile(template, options); } }; function safeEval(templateSpec) { /* eslint-disable no-eval, no-console */ try { return eval('(' + templateSpec + ')'); } catch (err) { console.error(templateSpec); throw err; } /* eslint-enable no-eval, no-console */ } handlebars.js-4.7.7/spec/env/runner.js000066400000000000000000000024271401244020700176370ustar00rootroot00000000000000/* eslint-disable no-console */ var fs = require('fs'), Mocha = require('mocha'), path = require('path'); var errors = 0, testDir = path.dirname(__dirname), grep = process.argv[2]; // Lazy hack, but whatever if (grep === '--min') { global.minimizedTest = true; grep = undefined; } var files = fs .readdirSync(testDir) .filter(function(name) { return /.*\.js$/.test(name); }) .map(function(name) { return testDir + path.sep + name; }); if (global.minimizedTest) { run('./runtime', function() { run('./browser', function() { /* eslint-disable no-process-exit */ process.exit(errors); /* eslint-enable no-process-exit */ }); }); } else { run('./runtime', function() { run('./browser', function() { run('./node', function() { /* eslint-disable no-process-exit */ process.exit(errors); /* eslint-enable no-process-exit */ }); }); }); } function run(env, callback) { var mocha = new Mocha(); mocha.ui('bdd'); mocha.files = files.slice(); if (grep) { mocha.grep(grep); } files.forEach(function(name) { delete require.cache[name]; }); console.log('Running env: ' + env); require(env); mocha.run(function(errorCount) { errors += errorCount; callback(); }); } handlebars.js-4.7.7/spec/env/runtime.js000066400000000000000000000040241401244020700200040ustar00rootroot00000000000000require('./common'); var fs = require('fs'), vm = require('vm'); var chai = require('chai'); var dirtyChai = require('dirty-chai'); chai.use(dirtyChai); global.expect = chai.expect; global.sinon = require('sinon'); global.Handlebars = 'no-conflict'; var filename = 'dist/handlebars.runtime.js'; if (global.minimizedTest) { filename = 'dist/handlebars.runtime.min.js'; } vm.runInThisContext( fs.readFileSync(__dirname + '/../../' + filename), filename ); var parse = require('../../dist/cjs/handlebars/compiler/base').parse; var compiler = require('../../dist/cjs/handlebars/compiler/compiler'); var JavaScriptCompiler = require('../../dist/cjs/handlebars/compiler/javascript-compiler'); global.CompilerContext = { browser: true, compile: function(template, options) { // Hack the compiler on to the environment for these specific tests handlebarsEnv.precompile = function(precompileTemplate, precompileOptions) { return compiler.precompile( precompileTemplate, precompileOptions, handlebarsEnv ); }; handlebarsEnv.parse = parse; handlebarsEnv.Compiler = compiler.Compiler; handlebarsEnv.JavaScriptCompiler = JavaScriptCompiler; var templateSpec = handlebarsEnv.precompile(template, options); return handlebarsEnv.template(safeEval(templateSpec)); }, compileWithPartial: function(template, options) { // Hack the compiler on to the environment for these specific tests handlebarsEnv.compile = function(compileTemplate, compileOptions) { return compiler.compile(compileTemplate, compileOptions, handlebarsEnv); }; handlebarsEnv.parse = parse; handlebarsEnv.Compiler = compiler.Compiler; handlebarsEnv.JavaScriptCompiler = JavaScriptCompiler; return handlebarsEnv.compile(template, options); } }; function safeEval(templateSpec) { /* eslint-disable no-eval, no-console */ try { return eval('(' + templateSpec + ')'); } catch (err) { console.error(templateSpec); throw err; } /* eslint-enable no-eval, no-console */ } handlebars.js-4.7.7/spec/expected/000077500000000000000000000000001401244020700167745ustar00rootroot00000000000000handlebars.js-4.7.7/spec/expected/bom.amd.js000066400000000000000000000005511401244020700206500ustar00rootroot00000000000000define(['handlebars.runtime'], function(Handlebars) { Handlebars = Handlebars["default"]; var template = Handlebars.template, templates = Handlebars.templates = Handlebars.templates || {}; return templates['bom'] = template({"compiler":[8,">= 4.3.0"],"main":function(container,depth0,helpers,partials,data) { return "a"; },"useData":true}); });handlebars.js-4.7.7/spec/expected/compiled.string.txt000066400000000000000000000002131401244020700226320ustar00rootroot00000000000000{"compiler":[8,">= 4.3.0"],"main":function(container,depth0,helpers,partials,data) { return "
Test String
"; },"useData":true}handlebars.js-4.7.7/spec/expected/empty.amd.js000066400000000000000000000005411401244020700212300ustar00rootroot00000000000000define(['handlebars.runtime'], function(Handlebars) { Handlebars = Handlebars["default"]; var template = Handlebars.template, templates = Handlebars.templates = Handlebars.templates || {}; return templates['empty'] = template({"compiler":[8,">= 4.3.0"],"main":function(container,depth0,helpers,partials,data) { return ""; },"useData":true}); }); handlebars.js-4.7.7/spec/expected/empty.amd.min.js000066400000000000000000000002761401244020700220170ustar00rootroot00000000000000define(["handlebars.runtime"],function(e){var t=(e=e.default).template;return(e.templates=e.templates||{}).empty=t({compiler:[8,">= 4.3.0"],main:function(e,t,a,n,r){return""},useData:!0})});handlebars.js-4.7.7/spec/expected/empty.amd.namespace.js000066400000000000000000000005531401244020700231660ustar00rootroot00000000000000define(['handlebars.runtime'], function(Handlebars) { Handlebars = Handlebars["default"]; var template = Handlebars.template, templates = CustomNamespace.templates = CustomNamespace.templates || {}; return templates['empty'] = template({"compiler":[8,">= 4.3.0"],"main":function(container,depth0,helpers,partials,data) { return ""; },"useData":true}); }); handlebars.js-4.7.7/spec/expected/empty.amd.simple.js000066400000000000000000000001631401244020700225200ustar00rootroot00000000000000{"compiler":[8,">= 4.3.0"],"main":function(container,depth0,helpers,partials,data) { return ""; },"useData":true}handlebars.js-4.7.7/spec/expected/empty.common.js000066400000000000000000000004161401244020700217600ustar00rootroot00000000000000(function() { var template = Handlebars.template, templates = Handlebars.templates = Handlebars.templates || {}; templates['empty'] = template({"compiler":[8,">= 4.3.0"],"main":function(container,depth0,helpers,partials,data) { return ""; },"useData":true}); })();handlebars.js-4.7.7/spec/expected/empty.name.amd.js000066400000000000000000000010521401244020700221450ustar00rootroot00000000000000define(['handlebars.runtime'], function(Handlebars) { Handlebars = Handlebars["default"]; var template = Handlebars.template, templates = Handlebars.templates = Handlebars.templates || {}; templates['firstTemplate'] = template({"compiler":[8,">= 4.3.0"],"main":function(container,depth0,helpers,partials,data) { return "
1
"; },"useData":true}); templates['secondTemplate'] = template({"compiler":[8,">= 4.3.0"],"main":function(container,depth0,helpers,partials,data) { return "
2
"; },"useData":true}); return templates; });handlebars.js-4.7.7/spec/expected/empty.root.amd.js000066400000000000000000000006141401244020700222130ustar00rootroot00000000000000define(['handlebars.runtime'], function(Handlebars) { Handlebars = Handlebars["default"]; var template = Handlebars.template, templates = Handlebars.templates = Handlebars.templates || {}; return templates['artifacts/partial.template'] = template({"compiler":[8,">= 4.3.0"],"main":function(container,depth0,helpers,partials,data) { return "
Test Partial
"; },"useData":true}); });handlebars.js-4.7.7/spec/expected/handlebar.path.amd.js000066400000000000000000000005641401244020700227520ustar00rootroot00000000000000define(['some-path/handlebars.runtime'], function(Handlebars) { Handlebars = Handlebars["default"]; var template = Handlebars.template, templates = Handlebars.templates = Handlebars.templates || {}; return templates['empty'] = template({"compiler":[8,">= 4.3.0"],"main":function(container,depth0,helpers,partials,data) { return ""; },"useData":true}); });handlebars.js-4.7.7/spec/expected/help.menu.txt000066400000000000000000000050211401244020700214260ustar00rootroot00000000000000Precompile handlebar templates. Usage: handlebars [template|directory]... Options: -f, --output Output File [string] --map Source Map File [string] -a, --amd Exports amd style (require.js) [boolean] -c, --commonjs Exports CommonJS style, path to Handlebars module [string] [default: null] -h, --handlebarPath Path to handlebar.js (only valid for amd-style) [string] [default: ""] -k, --known Known helpers [string] -o, --knownOnly Known helpers only [boolean] -m, --min Minimize output [boolean] -n, --namespace Template namespace [string] [default: "Handlebars.templates"] -s, --simple Output template function only. [boolean] -N, --name Name of passed string templates. Optional if running in a simple mode. Required when operating on multiple templates. [string] -i, --string Generates a template from the passed CLI argument. "-" is treated as a special value and causes stdin to be read for the template value. [string] -r, --root Template root. Base value that will be stripped from template names. [string] -p, --partial Compiling a partial template [boolean] -d, --data Include data when compiling [boolean] -e, --extension Template extension. [string] [default: "handlebars"] -b, --bom Removes the BOM (Byte Order Mark) from the beginning of the templates. [boolean] -v, --version Prints the current compiler version [boolean] --help Outputs this message [boolean]handlebars.js-4.7.7/spec/expected/namespace.amd.js000066400000000000000000000010051401244020700220220ustar00rootroot00000000000000define(['handlebars.runtime'], function(Handlebars) { Handlebars = Handlebars["default"]; var template = Handlebars.template, templates = someNameSpace = someNameSpace || {}; templates['empty'] = template({"compiler":[8,">= 4.3.0"],"main":function(container,depth0,helpers,partials,data) { return ""; },"useData":true}); templates['empty'] = template({"compiler":[8,">= 4.3.0"],"main":function(container,depth0,helpers,partials,data) { return ""; },"useData":true}); return templates; });handlebars.js-4.7.7/spec/expected/non.default.extension.amd.js000066400000000000000000000006231401244020700243230ustar00rootroot00000000000000define(['handlebars.runtime'], function(Handlebars) { Handlebars = Handlebars["default"]; var template = Handlebars.template, templates = Handlebars.templates = Handlebars.templates || {}; return templates['non.default.extension'] = template({"compiler":[8,">= 4.3.0"],"main":function(container,depth0,helpers,partials,data) { return "
This is a test
"; },"useData":true}); });handlebars.js-4.7.7/spec/expected/non.empty.amd.known.helper.js000066400000000000000000000030771401244020700244410ustar00rootroot00000000000000define(['handlebars.runtime'], function(Handlebars) { Handlebars = Handlebars["default"]; var template = Handlebars.template, templates = Handlebars.templates = Handlebars.templates || {}; return templates['known.helpers'] = template({"1":function(container,depth0,helpers,partials,data) { var stack1, lookupProperty = container.lookupProperty || function(parent, propertyName) { if (Object.prototype.hasOwnProperty.call(parent, propertyName)) { return parent[propertyName]; } return undefined }; return "
Some known helper
\n" + ((stack1 = lookupProperty(helpers,"anotherHelper").call(depth0 != null ? depth0 : (container.nullContext || {}),true,{"name":"anotherHelper","hash":{},"fn":container.program(2, data, 0),"inverse":container.noop,"data":data,"loc":{"start":{"line":3,"column":4},"end":{"line":5,"column":22}}})) != null ? stack1 : ""); },"2":function(container,depth0,helpers,partials,data) { return "
Another known helper
\n"; },"compiler":[8,">= 4.3.0"],"main":function(container,depth0,helpers,partials,data) { var stack1, lookupProperty = container.lookupProperty || function(parent, propertyName) { if (Object.prototype.hasOwnProperty.call(parent, propertyName)) { return parent[propertyName]; } return undefined }; return ((stack1 = lookupProperty(helpers,"someHelper").call(depth0 != null ? depth0 : (container.nullContext || {}),true,{"name":"someHelper","hash":{},"fn":container.program(1, data, 0),"inverse":container.noop,"data":data,"loc":{"start":{"line":1,"column":0},"end":{"line":6,"column":15}}})) != null ? stack1 : ""); },"useData":true}); }); handlebars.js-4.7.7/spec/expected/partial.template.js000066400000000000000000000006261401244020700226040ustar00rootroot00000000000000define(['handlebars.runtime'], function(Handlebars) { Handlebars = Handlebars["default"]; var template = Handlebars.template, templates = Handlebars.templates = Handlebars.templates || {}; return Handlebars.partials['partial.template'] = template({"compiler":[8,">= 4.3.0"],"main":function(container,depth0,helpers,partials,data) { return "
Test Partial
"; },"useData":true}); });handlebars.js-4.7.7/spec/expected/source.map.amd.js000066400000000000000000000003741401244020700221520ustar00rootroot00000000000000define(["handlebars.runtime"],function(e){var t=(e=e.default).template;return(e.templates=e.templates||{}).test=t({compiler:[8,">= 4.3.0"],main:function(e,t,a,n,i){return"
1
"},useData:!0})}); //# sourceMappingURL=./spec/tmp/source.map.amd.txthandlebars.js-4.7.7/spec/helpers.js000066400000000000000000001015421401244020700171760ustar00rootroot00000000000000describe('helpers', function() { it('helper with complex lookup$', function() { expectTemplate('{{#goodbyes}}{{{link ../prefix}}}{{/goodbyes}}') .withInput({ prefix: '/root', goodbyes: [{ text: 'Goodbye', url: 'goodbye' }] }) .withHelper('link', function(prefix) { return ( '' + this.text + '' ); }) .toCompileTo('Goodbye'); }); it('helper for raw block gets raw content', function() { expectTemplate('{{{{raw}}}} {{test}} {{{{/raw}}}}') .withInput({ test: 'hello' }) .withHelper('raw', function(options) { return options.fn(); }) .withMessage('raw block helper gets raw content') .toCompileTo(' {{test}} '); }); it('helper for raw block gets parameters', function() { expectTemplate('{{{{raw 1 2 3}}}} {{test}} {{{{/raw}}}}') .withInput({ test: 'hello' }) .withHelper('raw', function(a, b, c, options) { return options.fn() + a + b + c; }) .withMessage('raw block helper gets raw content') .toCompileTo(' {{test}} 123'); }); describe('raw block parsing (with identity helper-function)', function() { function runWithIdentityHelper(template, expected) { expectTemplate(template) .withHelper('identity', function(options) { return options.fn(); }) .toCompileTo(expected); } it('helper for nested raw block gets raw content', function() { runWithIdentityHelper( '{{{{identity}}}} {{{{b}}}} {{{{/b}}}} {{{{/identity}}}}', ' {{{{b}}}} {{{{/b}}}} ' ); }); it('helper for nested raw block works with empty content', function() { runWithIdentityHelper('{{{{identity}}}}{{{{/identity}}}}', ''); }); xit('helper for nested raw block works if nested raw blocks are broken', function() { // This test was introduced in 4.4.4, but it was not the actual problem that lead to the patch release // The test is deactivated, because in 3.x this template cases an exception and it also does not work in 4.4.3 // If anyone can make this template work without breaking everything else, then go for it, // but for now, this is just a known bug, that will be documented. runWithIdentityHelper( '{{{{identity}}}} {{{{a}}}} {{{{ {{{{/ }}}} }}}} {{{{/identity}}}}', ' {{{{a}}}} {{{{ {{{{/ }}}} }}}} ' ); }); it('helper for nested raw block closes after first matching close', function() { runWithIdentityHelper( '{{{{identity}}}}abc{{{{/identity}}}} {{{{identity}}}}abc{{{{/identity}}}}', 'abc abc' ); }); it('helper for nested raw block throw exception when with missing closing braces', function() { var string = '{{{{a}}}} {{{{/a'; expectTemplate(string).toThrow(); }); }); it('helper block with identical context', function() { expectTemplate('{{#goodbyes}}{{name}}{{/goodbyes}}') .withInput({ name: 'Alan' }) .withHelper('goodbyes', function(options) { var out = ''; var byes = ['Goodbye', 'goodbye', 'GOODBYE']; for (var i = 0, j = byes.length; i < j; i++) { out += byes[i] + ' ' + options.fn(this) + '! '; } return out; }) .toCompileTo('Goodbye Alan! goodbye Alan! GOODBYE Alan! '); }); it('helper block with complex lookup expression', function() { expectTemplate('{{#goodbyes}}{{../name}}{{/goodbyes}}') .withInput({ name: 'Alan' }) .withHelper('goodbyes', function(options) { var out = ''; var byes = ['Goodbye', 'goodbye', 'GOODBYE']; for (var i = 0, j = byes.length; i < j; i++) { out += byes[i] + ' ' + options.fn({}) + '! '; } return out; }) .toCompileTo('Goodbye Alan! goodbye Alan! GOODBYE Alan! '); }); it('helper with complex lookup and nested template', function() { expectTemplate( '{{#goodbyes}}{{#link ../prefix}}{{text}}{{/link}}{{/goodbyes}}' ) .withInput({ prefix: '/root', goodbyes: [{ text: 'Goodbye', url: 'goodbye' }] }) .withHelper('link', function(prefix, options) { return ( '' + options.fn(this) + '' ); }) .toCompileTo('Goodbye'); }); it('helper with complex lookup and nested template in VM+Compiler', function() { expectTemplate( '{{#goodbyes}}{{#link ../prefix}}{{text}}{{/link}}{{/goodbyes}}' ) .withInput({ prefix: '/root', goodbyes: [{ text: 'Goodbye', url: 'goodbye' }] }) .withHelper('link', function(prefix, options) { return ( '' + options.fn(this) + '' ); }) .toCompileTo('Goodbye'); }); it('helper returning undefined value', function() { expectTemplate(' {{nothere}}') .withHelpers({ nothere: function() {} }) .toCompileTo(' '); expectTemplate(' {{#nothere}}{{/nothere}}') .withHelpers({ nothere: function() {} }) .toCompileTo(' '); }); it('block helper', function() { expectTemplate('{{#goodbyes}}{{text}}! {{/goodbyes}}cruel {{world}}!') .withInput({ world: 'world' }) .withHelper('goodbyes', function(options) { return options.fn({ text: 'GOODBYE' }); }) .withMessage('Block helper executed') .toCompileTo('GOODBYE! cruel world!'); }); it('block helper staying in the same context', function() { expectTemplate('{{#form}}

{{name}}

{{/form}}') .withInput({ name: 'Yehuda' }) .withHelper('form', function(options) { return '
' + options.fn(this) + '
'; }) .withMessage('Block helper executed with current context') .toCompileTo('

Yehuda

'); }); it('block helper should have context in this', function() { function link(options) { return '' + options.fn(this) + ''; } expectTemplate( '' ) .withInput({ people: [ { name: 'Alan', id: 1 }, { name: 'Yehuda', id: 2 } ] }) .withHelper('link', link) .toCompileTo( '' ); }); it('block helper for undefined value', function() { expectTemplate("{{#empty}}shouldn't render{{/empty}}").toCompileTo(''); }); it('block helper passing a new context', function() { expectTemplate('{{#form yehuda}}

{{name}}

{{/form}}') .withInput({ yehuda: { name: 'Yehuda' } }) .withHelper('form', function(context, options) { return '
' + options.fn(context) + '
'; }) .withMessage('Context variable resolved') .toCompileTo('

Yehuda

'); }); it('block helper passing a complex path context', function() { expectTemplate('{{#form yehuda/cat}}

{{name}}

{{/form}}') .withInput({ yehuda: { name: 'Yehuda', cat: { name: 'Harold' } } }) .withHelper('form', function(context, options) { return '
' + options.fn(context) + '
'; }) .withMessage('Complex path variable resolved') .toCompileTo('

Harold

'); }); it('nested block helpers', function() { expectTemplate( '{{#form yehuda}}

{{name}}

{{#link}}Hello{{/link}}{{/form}}' ) .withInput({ yehuda: { name: 'Yehuda' } }) .withHelper('link', function(options) { return '' + options.fn(this) + ''; }) .withHelper('form', function(context, options) { return '
' + options.fn(context) + '
'; }) .withMessage('Both blocks executed') .toCompileTo('

Yehuda

Hello
'); }); it('block helper inverted sections', function() { var string = "{{#list people}}{{name}}{{^}}Nobody's here{{/list}}"; function list(context, options) { if (context.length > 0) { var out = ''; return out; } else { return '

' + options.inverse(this) + '

'; } } // the meaning here may be kind of hard to catch, but list.not is always called, // so we should see the output of both expectTemplate(string) .withInput({ people: [{ name: 'Alan' }, { name: 'Yehuda' }] }) .withHelpers({ list: list }) .withMessage('an inverse wrapper is passed in as a new context') .toCompileTo(''); expectTemplate(string) .withInput({ people: [] }) .withHelpers({ list: list }) .withMessage('an inverse wrapper can be optionally called') .toCompileTo("

Nobody's here

"); expectTemplate('{{#list people}}Hello{{^}}{{message}}{{/list}}') .withInput({ people: [], message: "Nobody's here" }) .withHelpers({ list: list }) .withMessage('the context of an inverse is the parent of the block') .toCompileTo('

Nobody's here

'); }); it('pathed lambas with parameters', function() { var hash = { helper: function() { return 'winning'; } }; hash.hash = hash; var helpers = { './helper': function() { return 'fail'; } }; expectTemplate('{{./helper 1}}') .withInput(hash) .withHelpers(helpers) .toCompileTo('winning'); expectTemplate('{{hash/helper 1}}') .withInput(hash) .withHelpers(helpers) .toCompileTo('winning'); }); describe('helpers hash', function() { it('providing a helpers hash', function() { expectTemplate('Goodbye {{cruel}} {{world}}!') .withInput({ cruel: 'cruel' }) .withHelpers({ world: function() { return 'world'; } }) .withMessage('helpers hash is available') .toCompileTo('Goodbye cruel world!'); expectTemplate('Goodbye {{#iter}}{{cruel}} {{world}}{{/iter}}!') .withInput({ iter: [{ cruel: 'cruel' }] }) .withHelpers({ world: function() { return 'world'; } }) .withMessage('helpers hash is available inside other blocks') .toCompileTo('Goodbye cruel world!'); }); it('in cases of conflict, helpers win', function() { expectTemplate('{{{lookup}}}') .withInput({ lookup: 'Explicit' }) .withHelpers({ lookup: function() { return 'helpers'; } }) .withMessage('helpers hash has precedence escaped expansion') .toCompileTo('helpers'); expectTemplate('{{lookup}}') .withInput({ lookup: 'Explicit' }) .withHelpers({ lookup: function() { return 'helpers'; } }) .withMessage('helpers hash has precedence simple expansion') .toCompileTo('helpers'); }); it('the helpers hash is available is nested contexts', function() { expectTemplate('{{#outer}}{{#inner}}{{helper}}{{/inner}}{{/outer}}') .withInput({ outer: { inner: { unused: [] } } }) .withHelpers({ helper: function() { return 'helper'; } }) .withMessage('helpers hash is available in nested contexts.') .toCompileTo('helper'); }); it('the helper hash should augment the global hash', function() { handlebarsEnv.registerHelper('test_helper', function() { return 'found it!'; }); expectTemplate( '{{test_helper}} {{#if cruel}}Goodbye {{cruel}} {{world}}!{{/if}}' ) .withInput({ cruel: 'cruel' }) .withHelpers({ world: function() { return 'world!'; } }) .toCompileTo('found it! Goodbye cruel world!!'); }); }); describe('registration', function() { it('unregisters', function() { handlebarsEnv.helpers = {}; handlebarsEnv.registerHelper('foo', function() { return 'fail'; }); handlebarsEnv.unregisterHelper('foo'); equals(handlebarsEnv.helpers.foo, undefined); }); it('allows multiple globals', function() { var helpers = handlebarsEnv.helpers; handlebarsEnv.helpers = {}; handlebarsEnv.registerHelper({ if: helpers['if'], world: function() { return 'world!'; }, testHelper: function() { return 'found it!'; } }); expectTemplate( '{{testHelper}} {{#if cruel}}Goodbye {{cruel}} {{world}}!{{/if}}' ) .withInput({ cruel: 'cruel' }) .toCompileTo('found it! Goodbye cruel world!!'); }); it('fails with multiple and args', function() { shouldThrow( function() { handlebarsEnv.registerHelper( { world: function() { return 'world!'; }, testHelper: function() { return 'found it!'; } }, {} ); }, Error, 'Arg not supported with multiple helpers' ); }); }); it('decimal number literals work', function() { expectTemplate('Message: {{hello -1.2 1.2}}') .withHelper('hello', function(times, times2) { if (typeof times !== 'number') { times = 'NaN'; } if (typeof times2 !== 'number') { times2 = 'NaN'; } return 'Hello ' + times + ' ' + times2 + ' times'; }) .withMessage('template with a negative integer literal') .toCompileTo('Message: Hello -1.2 1.2 times'); }); it('negative number literals work', function() { expectTemplate('Message: {{hello -12}}') .withHelper('hello', function(times) { if (typeof times !== 'number') { times = 'NaN'; } return 'Hello ' + times + ' times'; }) .withMessage('template with a negative integer literal') .toCompileTo('Message: Hello -12 times'); }); describe('String literal parameters', function() { it('simple literals work', function() { expectTemplate('Message: {{hello "world" 12 true false}}') .withHelper('hello', function(param, times, bool1, bool2) { if (typeof times !== 'number') { times = 'NaN'; } if (typeof bool1 !== 'boolean') { bool1 = 'NaB'; } if (typeof bool2 !== 'boolean') { bool2 = 'NaB'; } return ( 'Hello ' + param + ' ' + times + ' times: ' + bool1 + ' ' + bool2 ); }) .withMessage('template with a simple String literal') .toCompileTo('Message: Hello world 12 times: true false'); }); it('using a quote in the middle of a parameter raises an error', function() { expectTemplate('Message: {{hello wo"rld"}}').toThrow(Error); }); it('escaping a String is possible', function() { expectTemplate('Message: {{{hello "\\"world\\""}}}') .withHelper('hello', function(param) { return 'Hello ' + param; }) .withMessage('template with an escaped String literal') .toCompileTo('Message: Hello "world"'); }); it("it works with ' marks", function() { expectTemplate('Message: {{{hello "Alan\'s world"}}}') .withHelper('hello', function(param) { return 'Hello ' + param; }) .withMessage("template with a ' mark") .toCompileTo("Message: Hello Alan's world"); }); }); it('negative number literals work', function() { expectTemplate('Message: {{hello -12}}') .withHelper('hello', function(times) { if (typeof times !== 'number') { times = 'NaN'; } return 'Hello ' + times + ' times'; }) .withMessage('template with a negative integer literal') .toCompileTo('Message: Hello -12 times'); }); describe('multiple parameters', function() { it('simple multi-params work', function() { expectTemplate('Message: {{goodbye cruel world}}') .withInput({ cruel: 'cruel', world: 'world' }) .withHelper('goodbye', function(cruel, world) { return 'Goodbye ' + cruel + ' ' + world; }) .withMessage('regular helpers with multiple params') .toCompileTo('Message: Goodbye cruel world'); }); it('block multi-params work', function() { expectTemplate( 'Message: {{#goodbye cruel world}}{{greeting}} {{adj}} {{noun}}{{/goodbye}}' ) .withInput({ cruel: 'cruel', world: 'world' }) .withHelper('goodbye', function(cruel, world, options) { return options.fn({ greeting: 'Goodbye', adj: cruel, noun: world }); }) .withMessage('block helpers with multiple params') .toCompileTo('Message: Goodbye cruel world'); }); }); describe('hash', function() { it('helpers can take an optional hash', function() { expectTemplate('{{goodbye cruel="CRUEL" world="WORLD" times=12}}') .withHelper('goodbye', function(options) { return ( 'GOODBYE ' + options.hash.cruel + ' ' + options.hash.world + ' ' + options.hash.times + ' TIMES' ); }) .withMessage('Helper output hash') .toCompileTo('GOODBYE CRUEL WORLD 12 TIMES'); }); it('helpers can take an optional hash with booleans', function() { function goodbye(options) { if (options.hash.print === true) { return 'GOODBYE ' + options.hash.cruel + ' ' + options.hash.world; } else if (options.hash.print === false) { return 'NOT PRINTING'; } else { return 'THIS SHOULD NOT HAPPEN'; } } expectTemplate('{{goodbye cruel="CRUEL" world="WORLD" print=true}}') .withHelper('goodbye', goodbye) .withMessage('Helper output hash') .toCompileTo('GOODBYE CRUEL WORLD'); expectTemplate('{{goodbye cruel="CRUEL" world="WORLD" print=false}}') .withHelper('goodbye', goodbye) .withMessage('Boolean helper parameter honored') .toCompileTo('NOT PRINTING'); }); it('block helpers can take an optional hash', function() { expectTemplate('{{#goodbye cruel="CRUEL" times=12}}world{{/goodbye}}') .withHelper('goodbye', function(options) { return ( 'GOODBYE ' + options.hash.cruel + ' ' + options.fn(this) + ' ' + options.hash.times + ' TIMES' ); }) .withMessage('Hash parameters output') .toCompileTo('GOODBYE CRUEL world 12 TIMES'); }); it('block helpers can take an optional hash with single quoted stings', function() { expectTemplate('{{#goodbye cruel="CRUEL" times=12}}world{{/goodbye}}') .withHelper('goodbye', function(options) { return ( 'GOODBYE ' + options.hash.cruel + ' ' + options.fn(this) + ' ' + options.hash.times + ' TIMES' ); }) .withMessage('Hash parameters output') .toCompileTo('GOODBYE CRUEL world 12 TIMES'); }); it('block helpers can take an optional hash with booleans', function() { function goodbye(options) { if (options.hash.print === true) { return 'GOODBYE ' + options.hash.cruel + ' ' + options.fn(this); } else if (options.hash.print === false) { return 'NOT PRINTING'; } else { return 'THIS SHOULD NOT HAPPEN'; } } expectTemplate('{{#goodbye cruel="CRUEL" print=true}}world{{/goodbye}}') .withHelper('goodbye', goodbye) .withMessage('Boolean hash parameter honored') .toCompileTo('GOODBYE CRUEL world'); expectTemplate('{{#goodbye cruel="CRUEL" print=false}}world{{/goodbye}}') .withHelper('goodbye', goodbye) .withMessage('Boolean hash parameter honored') .toCompileTo('NOT PRINTING'); }); }); describe('helperMissing', function() { it('if a context is not found, helperMissing is used', function() { expectTemplate('{{hello}} {{link_to world}}').toThrow( /Missing helper: "link_to"/ ); }); it('if a context is not found, custom helperMissing is used', function() { expectTemplate('{{hello}} {{link_to world}}') .withInput({ hello: 'Hello', world: 'world' }) .withHelper('helperMissing', function(mesg, options) { if (options.name === 'link_to') { return new Handlebars.SafeString('' + mesg + ''); } }) .toCompileTo('Hello world'); }); it('if a value is not found, custom helperMissing is used', function() { expectTemplate('{{hello}} {{link_to}}') .withInput({ hello: 'Hello', world: 'world' }) .withHelper('helperMissing', function(options) { if (options.name === 'link_to') { return new Handlebars.SafeString('winning'); } }) .toCompileTo('Hello winning'); }); }); describe('knownHelpers', function() { it('Known helper should render helper', function() { expectTemplate('{{hello}}') .withCompileOptions({ knownHelpers: { hello: true } }) .withHelper('hello', function() { return 'foo'; }) .toCompileTo('foo'); }); it('Unknown helper in knownHelpers only mode should be passed as undefined', function() { expectTemplate('{{typeof hello}}') .withCompileOptions({ knownHelpers: { typeof: true }, knownHelpersOnly: true }) .withHelper('typeof', function(arg) { return typeof arg; }) .withHelper('hello', function() { return 'foo'; }) .toCompileTo('undefined'); }); it('Builtin helpers available in knownHelpers only mode', function() { expectTemplate('{{#unless foo}}bar{{/unless}}') .withCompileOptions({ knownHelpersOnly: true }) .toCompileTo('bar'); }); it('Field lookup works in knownHelpers only mode', function() { expectTemplate('{{foo}}') .withCompileOptions({ knownHelpersOnly: true }) .withInput({ foo: 'bar' }) .toCompileTo('bar'); }); it('Conditional blocks work in knownHelpers only mode', function() { expectTemplate('{{#foo}}bar{{/foo}}') .withCompileOptions({ knownHelpersOnly: true }) .withInput({ foo: 'baz' }) .toCompileTo('bar'); }); it('Invert blocks work in knownHelpers only mode', function() { expectTemplate('{{^foo}}bar{{/foo}}') .withCompileOptions({ knownHelpersOnly: true }) .withInput({ foo: false }) .toCompileTo('bar'); }); it('Functions are bound to the context in knownHelpers only mode', function() { expectTemplate('{{foo}}') .withCompileOptions({ knownHelpersOnly: true }) .withInput({ foo: function() { return this.bar; }, bar: 'bar' }) .toCompileTo('bar'); }); it('Unknown helper call in knownHelpers only mode should throw', function() { expectTemplate('{{typeof hello}}') .withCompileOptions({ knownHelpersOnly: true }) .toThrow(Error); }); }); describe('blockHelperMissing', function() { it('lambdas are resolved by blockHelperMissing, not handlebars proper', function() { expectTemplate('{{#truthy}}yep{{/truthy}}') .withInput({ truthy: function() { return true; } }) .toCompileTo('yep'); }); it('lambdas resolved by blockHelperMissing are bound to the context', function() { expectTemplate('{{#truthy}}yep{{/truthy}}') .withInput({ truthy: function() { return this.truthiness(); }, truthiness: function() { return false; } }) .toCompileTo(''); }); }); describe('name field', function() { var helpers = { blockHelperMissing: function() { return 'missing: ' + arguments[arguments.length - 1].name; }, helperMissing: function() { return 'helper missing: ' + arguments[arguments.length - 1].name; }, helper: function() { return 'ran: ' + arguments[arguments.length - 1].name; } }; it('should include in ambiguous mustache calls', function() { expectTemplate('{{helper}}') .withHelpers(helpers) .toCompileTo('ran: helper'); }); it('should include in helper mustache calls', function() { expectTemplate('{{helper 1}}') .withHelpers(helpers) .toCompileTo('ran: helper'); }); it('should include in ambiguous block calls', function() { expectTemplate('{{#helper}}{{/helper}}') .withHelpers(helpers) .toCompileTo('ran: helper'); }); it('should include in simple block calls', function() { expectTemplate('{{#./helper}}{{/./helper}}') .withHelpers(helpers) .toCompileTo('missing: ./helper'); }); it('should include in helper block calls', function() { expectTemplate('{{#helper 1}}{{/helper}}') .withHelpers(helpers) .toCompileTo('ran: helper'); }); it('should include in known helper calls', function() { expectTemplate('{{helper}}') .withCompileOptions({ knownHelpers: { helper: true }, knownHelpersOnly: true }) .withHelpers(helpers) .toCompileTo('ran: helper'); }); it('should include full id', function() { expectTemplate('{{#foo.helper}}{{/foo.helper}}') .withInput({ foo: {} }) .withHelpers(helpers) .toCompileTo('missing: foo.helper'); }); it('should include full id if a hash is passed', function() { expectTemplate('{{#foo.helper bar=baz}}{{/foo.helper}}') .withInput({ foo: {} }) .withHelpers(helpers) .toCompileTo('helper missing: foo.helper'); }); }); describe('name conflicts', function() { it('helpers take precedence over same-named context properties', function() { expectTemplate('{{goodbye}} {{cruel world}}') .withHelper('goodbye', function() { return this.goodbye.toUpperCase(); }) .withHelper('cruel', function(world) { return 'cruel ' + world.toUpperCase(); }) .withInput({ goodbye: 'goodbye', world: 'world' }) .withMessage('Helper executed') .toCompileTo('GOODBYE cruel WORLD'); }); it('helpers take precedence over same-named context properties$', function() { expectTemplate('{{#goodbye}} {{cruel world}}{{/goodbye}}') .withHelper('goodbye', function(options) { return this.goodbye.toUpperCase() + options.fn(this); }) .withHelper('cruel', function(world) { return 'cruel ' + world.toUpperCase(); }) .withInput({ goodbye: 'goodbye', world: 'world' }) .withMessage('Helper executed') .toCompileTo('GOODBYE cruel WORLD'); }); it('Scoped names take precedence over helpers', function() { expectTemplate('{{this.goodbye}} {{cruel world}} {{cruel this.goodbye}}') .withHelper('goodbye', function() { return this.goodbye.toUpperCase(); }) .withHelper('cruel', function(world) { return 'cruel ' + world.toUpperCase(); }) .withInput({ goodbye: 'goodbye', world: 'world' }) .withMessage('Helper not executed') .toCompileTo('goodbye cruel WORLD cruel GOODBYE'); }); it('Scoped names take precedence over block helpers', function() { expectTemplate( '{{#goodbye}} {{cruel world}}{{/goodbye}} {{this.goodbye}}' ) .withHelper('goodbye', function(options) { return this.goodbye.toUpperCase() + options.fn(this); }) .withHelper('cruel', function(world) { return 'cruel ' + world.toUpperCase(); }) .withInput({ goodbye: 'goodbye', world: 'world' }) .withMessage('Helper executed') .toCompileTo('GOODBYE cruel WORLD goodbye'); }); }); describe('block params', function() { it('should take presedence over context values', function() { expectTemplate('{{#goodbyes as |value|}}{{value}}{{/goodbyes}}{{value}}') .withInput({ value: 'foo' }) .withHelper('goodbyes', function(options) { equals(options.fn.blockParams, 1); return options.fn({ value: 'bar' }, { blockParams: [1, 2] }); }) .toCompileTo('1foo'); }); it('should take presedence over helper values', function() { expectTemplate('{{#goodbyes as |value|}}{{value}}{{/goodbyes}}{{value}}') .withHelper('value', function() { return 'foo'; }) .withHelper('goodbyes', function(options) { equals(options.fn.blockParams, 1); return options.fn({}, { blockParams: [1, 2] }); }) .toCompileTo('1foo'); }); it('should not take presedence over pathed values', function() { expectTemplate( '{{#goodbyes as |value|}}{{./value}}{{/goodbyes}}{{value}}' ) .withInput({ value: 'bar' }) .withHelper('value', function() { return 'foo'; }) .withHelper('goodbyes', function(options) { equals(options.fn.blockParams, 1); return options.fn(this, { blockParams: [1, 2] }); }) .toCompileTo('barfoo'); }); it('should take presednece over parent block params', function() { var value = 1; expectTemplate( '{{#goodbyes as |value|}}{{#goodbyes}}{{value}}{{#goodbyes as |value|}}{{value}}{{/goodbyes}}{{/goodbyes}}{{/goodbyes}}{{value}}' ) .withInput({ value: 'foo' }) .withHelper('goodbyes', function(options) { return options.fn( { value: 'bar' }, { blockParams: options.fn.blockParams === 1 ? [value++, value++] : undefined } ); }) .toCompileTo('13foo'); }); it('should allow block params on chained helpers', function() { expectTemplate( '{{#if bar}}{{else goodbyes as |value|}}{{value}}{{/if}}{{value}}' ) .withInput({ value: 'foo' }) .withHelper('goodbyes', function(options) { equals(options.fn.blockParams, 1); return options.fn({ value: 'bar' }, { blockParams: [1, 2] }); }) .toCompileTo('1foo'); }); }); describe('built-in helpers malformed arguments ', function() { it('if helper - too few arguments', function() { expectTemplate('{{#if}}{{/if}}').toThrow( /#if requires exactly one argument/ ); }); it('if helper - too many arguments, string', function() { expectTemplate('{{#if test "string"}}{{/if}}').toThrow( /#if requires exactly one argument/ ); }); it('if helper - too many arguments, undefined', function() { expectTemplate('{{#if test undefined}}{{/if}}').toThrow( /#if requires exactly one argument/ ); }); it('if helper - too many arguments, null', function() { expectTemplate('{{#if test null}}{{/if}}').toThrow( /#if requires exactly one argument/ ); }); it('unless helper - too few arguments', function() { expectTemplate('{{#unless}}{{/unless}}').toThrow( /#unless requires exactly one argument/ ); }); it('unless helper - too many arguments', function() { expectTemplate('{{#unless test null}}{{/unless}}').toThrow( /#unless requires exactly one argument/ ); }); it('with helper - too few arguments', function() { expectTemplate('{{#with}}{{/with}}').toThrow( /#with requires exactly one argument/ ); }); it('with helper - too many arguments', function() { expectTemplate('{{#with test "string"}}{{/with}}').toThrow( /#with requires exactly one argument/ ); }); }); describe('the lookupProperty-option', function() { it('should be passed to custom helpers', function() { expectTemplate('{{testHelper}}') .withHelper('testHelper', function testHelper(options) { return options.lookupProperty(this, 'testProperty'); }) .withInput({ testProperty: 'abc' }) .toCompileTo('abc'); }); }); }); handlebars.js-4.7.7/spec/index.html000066400000000000000000000055451401244020700172010ustar00rootroot00000000000000 Mocha
handlebars.js-4.7.7/spec/javascript-compiler.js000066400000000000000000000101261401244020700215070ustar00rootroot00000000000000describe('javascript-compiler api', function() { if (!Handlebars.JavaScriptCompiler) { return; } describe('#nameLookup', function() { var $superName; beforeEach(function() { $superName = handlebarsEnv.JavaScriptCompiler.prototype.nameLookup; }); afterEach(function() { handlebarsEnv.JavaScriptCompiler.prototype.nameLookup = $superName; }); it('should allow override', function() { handlebarsEnv.JavaScriptCompiler.prototype.nameLookup = function( parent, name ) { return parent + '.bar_' + name; }; /* eslint-disable camelcase */ expectTemplate('{{foo}}') .withInput({ bar_foo: 'food' }) .toCompileTo('food'); /* eslint-enable camelcase */ }); // Tests nameLookup dot vs. bracket behavior. Bracket is required in certain cases // to avoid errors in older browsers. it('should handle reserved words', function() { expectTemplate('{{foo}} {{~null~}}') .withInput({ foo: 'food' }) .toCompileTo('food'); }); }); describe('#compilerInfo', function() { var $superCheck, $superInfo; beforeEach(function() { $superCheck = handlebarsEnv.VM.checkRevision; $superInfo = handlebarsEnv.JavaScriptCompiler.prototype.compilerInfo; }); afterEach(function() { handlebarsEnv.VM.checkRevision = $superCheck; handlebarsEnv.JavaScriptCompiler.prototype.compilerInfo = $superInfo; }); it('should allow compilerInfo override', function() { handlebarsEnv.JavaScriptCompiler.prototype.compilerInfo = function() { return 'crazy'; }; handlebarsEnv.VM.checkRevision = function(compilerInfo) { if (compilerInfo !== 'crazy') { throw new Error("It didn't work"); } }; expectTemplate('{{foo}} ') .withInput({ foo: 'food' }) .toCompileTo('food '); }); }); describe('buffer', function() { var $superAppend, $superCreate; beforeEach(function() { handlebarsEnv.JavaScriptCompiler.prototype.forceBuffer = true; $superAppend = handlebarsEnv.JavaScriptCompiler.prototype.appendToBuffer; $superCreate = handlebarsEnv.JavaScriptCompiler.prototype.initializeBuffer; }); afterEach(function() { handlebarsEnv.JavaScriptCompiler.prototype.forceBuffer = false; handlebarsEnv.JavaScriptCompiler.prototype.appendToBuffer = $superAppend; handlebarsEnv.JavaScriptCompiler.prototype.initializeBuffer = $superCreate; }); it('should allow init buffer override', function() { handlebarsEnv.JavaScriptCompiler.prototype.initializeBuffer = function() { return this.quotedString('foo_'); }; expectTemplate('{{foo}} ') .withInput({ foo: 'food' }) .toCompileTo('foo_food '); }); it('should allow append buffer override', function() { handlebarsEnv.JavaScriptCompiler.prototype.appendToBuffer = function( string ) { return $superAppend.call(this, [string, ' + "_foo"']); }; expectTemplate('{{foo}}') .withInput({ foo: 'food' }) .toCompileTo('food_foo'); }); }); describe('#isValidJavaScriptVariableName', function() { // It is there and accessible and could be used by someone. That's why we don't remove it // it 4.x. But if we keep it, we add a test // This test should not encourage you to use the function. It is not needed any more // and might be removed in 5.0 ['test', 'abc123', 'abc_123'].forEach(function(validVariableName) { it("should return true for '" + validVariableName + "'", function() { expect( handlebarsEnv.JavaScriptCompiler.isValidJavaScriptVariableName( validVariableName ) ).to.be.true(); }); }); [('123test', 'abc()', 'abc.cde')].forEach(function(invalidVariableName) { it("should return true for '" + invalidVariableName + "'", function() { expect( handlebarsEnv.JavaScriptCompiler.isValidJavaScriptVariableName( invalidVariableName ) ).to.be.false(); }); }); }); }); handlebars.js-4.7.7/spec/mustache/000077500000000000000000000000001401244020700170045ustar00rootroot00000000000000handlebars.js-4.7.7/spec/parser.js000066400000000000000000000313541401244020700170330ustar00rootroot00000000000000describe('parser', function() { if (!Handlebars.print) { return; } function astFor(template) { var ast = Handlebars.parse(template); return Handlebars.print(ast); } it('parses simple mustaches', function() { equals(astFor('{{123}}'), '{{ NUMBER{123} [] }}\n'); equals(astFor('{{"foo"}}'), '{{ "foo" [] }}\n'); equals(astFor('{{false}}'), '{{ BOOLEAN{false} [] }}\n'); equals(astFor('{{true}}'), '{{ BOOLEAN{true} [] }}\n'); equals(astFor('{{foo}}'), '{{ PATH:foo [] }}\n'); equals(astFor('{{foo?}}'), '{{ PATH:foo? [] }}\n'); equals(astFor('{{foo_}}'), '{{ PATH:foo_ [] }}\n'); equals(astFor('{{foo-}}'), '{{ PATH:foo- [] }}\n'); equals(astFor('{{foo:}}'), '{{ PATH:foo: [] }}\n'); }); it('parses simple mustaches with data', function() { equals(astFor('{{@foo}}'), '{{ @PATH:foo [] }}\n'); }); it('parses simple mustaches with data paths', function() { equals(astFor('{{@../foo}}'), '{{ @PATH:foo [] }}\n'); }); it('parses mustaches with paths', function() { equals(astFor('{{foo/bar}}'), '{{ PATH:foo/bar [] }}\n'); }); it('parses mustaches with this/foo', function() { equals(astFor('{{this/foo}}'), '{{ PATH:foo [] }}\n'); }); it('parses mustaches with - in a path', function() { equals(astFor('{{foo-bar}}'), '{{ PATH:foo-bar [] }}\n'); }); it('parses mustaches with escaped [] in a path', function() { equals(astFor('{{[foo[\\]]}}'), '{{ PATH:foo[] [] }}\n'); }); it('parses escaped \\\\ in path', function() { equals(astFor('{{[foo\\\\]}}'), '{{ PATH:foo\\ [] }}\n'); }); it('parses mustaches with parameters', function() { equals(astFor('{{foo bar}}'), '{{ PATH:foo [PATH:bar] }}\n'); }); it('parses mustaches with string parameters', function() { equals(astFor('{{foo bar "baz" }}'), '{{ PATH:foo [PATH:bar, "baz"] }}\n'); }); it('parses mustaches with NUMBER parameters', function() { equals(astFor('{{foo 1}}'), '{{ PATH:foo [NUMBER{1}] }}\n'); }); it('parses mustaches with BOOLEAN parameters', function() { equals(astFor('{{foo true}}'), '{{ PATH:foo [BOOLEAN{true}] }}\n'); equals(astFor('{{foo false}}'), '{{ PATH:foo [BOOLEAN{false}] }}\n'); }); it('parses mustaches with undefined and null paths', function() { equals(astFor('{{undefined}}'), '{{ UNDEFINED [] }}\n'); equals(astFor('{{null}}'), '{{ NULL [] }}\n'); }); it('parses mustaches with undefined and null parameters', function() { equals( astFor('{{foo undefined null}}'), '{{ PATH:foo [UNDEFINED, NULL] }}\n' ); }); it('parses mustaches with DATA parameters', function() { equals(astFor('{{foo @bar}}'), '{{ PATH:foo [@PATH:bar] }}\n'); }); it('parses mustaches with hash arguments', function() { equals(astFor('{{foo bar=baz}}'), '{{ PATH:foo [] HASH{bar=PATH:baz} }}\n'); equals(astFor('{{foo bar=1}}'), '{{ PATH:foo [] HASH{bar=NUMBER{1}} }}\n'); equals( astFor('{{foo bar=true}}'), '{{ PATH:foo [] HASH{bar=BOOLEAN{true}} }}\n' ); equals( astFor('{{foo bar=false}}'), '{{ PATH:foo [] HASH{bar=BOOLEAN{false}} }}\n' ); equals( astFor('{{foo bar=@baz}}'), '{{ PATH:foo [] HASH{bar=@PATH:baz} }}\n' ); equals( astFor('{{foo bar=baz bat=bam}}'), '{{ PATH:foo [] HASH{bar=PATH:baz, bat=PATH:bam} }}\n' ); equals( astFor('{{foo bar=baz bat="bam"}}'), '{{ PATH:foo [] HASH{bar=PATH:baz, bat="bam"} }}\n' ); equals(astFor("{{foo bat='bam'}}"), '{{ PATH:foo [] HASH{bat="bam"} }}\n'); equals( astFor('{{foo omg bar=baz bat="bam"}}'), '{{ PATH:foo [PATH:omg] HASH{bar=PATH:baz, bat="bam"} }}\n' ); equals( astFor('{{foo omg bar=baz bat="bam" baz=1}}'), '{{ PATH:foo [PATH:omg] HASH{bar=PATH:baz, bat="bam", baz=NUMBER{1}} }}\n' ); equals( astFor('{{foo omg bar=baz bat="bam" baz=true}}'), '{{ PATH:foo [PATH:omg] HASH{bar=PATH:baz, bat="bam", baz=BOOLEAN{true}} }}\n' ); equals( astFor('{{foo omg bar=baz bat="bam" baz=false}}'), '{{ PATH:foo [PATH:omg] HASH{bar=PATH:baz, bat="bam", baz=BOOLEAN{false}} }}\n' ); }); it('parses contents followed by a mustache', function() { equals( astFor('foo bar {{baz}}'), "CONTENT[ 'foo bar ' ]\n{{ PATH:baz [] }}\n" ); }); it('parses a partial', function() { equals(astFor('{{> foo }}'), '{{> PARTIAL:foo }}\n'); equals(astFor('{{> "foo" }}'), '{{> PARTIAL:foo }}\n'); equals(astFor('{{> 1 }}'), '{{> PARTIAL:1 }}\n'); }); it('parses a partial with context', function() { equals(astFor('{{> foo bar}}'), '{{> PARTIAL:foo PATH:bar }}\n'); }); it('parses a partial with hash', function() { equals( astFor('{{> foo bar=bat}}'), '{{> PARTIAL:foo HASH{bar=PATH:bat} }}\n' ); }); it('parses a partial with context and hash', function() { equals( astFor('{{> foo bar bat=baz}}'), '{{> PARTIAL:foo PATH:bar HASH{bat=PATH:baz} }}\n' ); }); it('parses a partial with a complex name', function() { equals( astFor('{{> shared/partial?.bar}}'), '{{> PARTIAL:shared/partial?.bar }}\n' ); }); it('parsers partial blocks', function() { equals( astFor('{{#> foo}}bar{{/foo}}'), "{{> PARTIAL BLOCK:foo PROGRAM:\n CONTENT[ 'bar' ]\n }}\n" ); }); it('should handle parser block mismatch', function() { shouldThrow( function() { astFor('{{#> goodbyes}}{{/hellos}}'); }, Error, /goodbyes doesn't match hellos/ ); }); it('parsers partial blocks with arguments', function() { equals( astFor('{{#> foo context hash=value}}bar{{/foo}}'), "{{> PARTIAL BLOCK:foo PATH:context HASH{hash=PATH:value} PROGRAM:\n CONTENT[ 'bar' ]\n }}\n" ); }); it('parses a comment', function() { equals( astFor('{{! this is a comment }}'), "{{! ' this is a comment ' }}\n" ); }); it('parses a multi-line comment', function() { equals( astFor('{{!\nthis is a multi-line comment\n}}'), "{{! '\nthis is a multi-line comment\n' }}\n" ); }); it('parses an inverse section', function() { equals( astFor('{{#foo}} bar {{^}} baz {{/foo}}'), "BLOCK:\n PATH:foo []\n PROGRAM:\n CONTENT[ ' bar ' ]\n {{^}}\n CONTENT[ ' baz ' ]\n" ); }); it('parses an inverse (else-style) section', function() { equals( astFor('{{#foo}} bar {{else}} baz {{/foo}}'), "BLOCK:\n PATH:foo []\n PROGRAM:\n CONTENT[ ' bar ' ]\n {{^}}\n CONTENT[ ' baz ' ]\n" ); }); it('parses multiple inverse sections', function() { equals( astFor('{{#foo}} bar {{else if bar}}{{else}} baz {{/foo}}'), "BLOCK:\n PATH:foo []\n PROGRAM:\n CONTENT[ ' bar ' ]\n {{^}}\n BLOCK:\n PATH:if [PATH:bar]\n PROGRAM:\n {{^}}\n CONTENT[ ' baz ' ]\n" ); }); it('parses empty blocks', function() { equals(astFor('{{#foo}}{{/foo}}'), 'BLOCK:\n PATH:foo []\n PROGRAM:\n'); }); it('parses empty blocks with empty inverse section', function() { equals( astFor('{{#foo}}{{^}}{{/foo}}'), 'BLOCK:\n PATH:foo []\n PROGRAM:\n {{^}}\n' ); }); it('parses empty blocks with empty inverse (else-style) section', function() { equals( astFor('{{#foo}}{{else}}{{/foo}}'), 'BLOCK:\n PATH:foo []\n PROGRAM:\n {{^}}\n' ); }); it('parses non-empty blocks with empty inverse section', function() { equals( astFor('{{#foo}} bar {{^}}{{/foo}}'), "BLOCK:\n PATH:foo []\n PROGRAM:\n CONTENT[ ' bar ' ]\n {{^}}\n" ); }); it('parses non-empty blocks with empty inverse (else-style) section', function() { equals( astFor('{{#foo}} bar {{else}}{{/foo}}'), "BLOCK:\n PATH:foo []\n PROGRAM:\n CONTENT[ ' bar ' ]\n {{^}}\n" ); }); it('parses empty blocks with non-empty inverse section', function() { equals( astFor('{{#foo}}{{^}} bar {{/foo}}'), "BLOCK:\n PATH:foo []\n PROGRAM:\n {{^}}\n CONTENT[ ' bar ' ]\n" ); }); it('parses empty blocks with non-empty inverse (else-style) section', function() { equals( astFor('{{#foo}}{{else}} bar {{/foo}}'), "BLOCK:\n PATH:foo []\n PROGRAM:\n {{^}}\n CONTENT[ ' bar ' ]\n" ); }); it('parses a standalone inverse section', function() { equals( astFor('{{^foo}}bar{{/foo}}'), "BLOCK:\n PATH:foo []\n {{^}}\n CONTENT[ 'bar' ]\n" ); }); it('throws on old inverse section', function() { shouldThrow(function() { astFor('{{else foo}}bar{{/foo}}'); }, Error); }); it('parses block with block params', function() { equals( astFor('{{#foo as |bar baz|}}content{{/foo}}'), "BLOCK:\n PATH:foo []\n PROGRAM:\n BLOCK PARAMS: [ bar baz ]\n CONTENT[ 'content' ]\n" ); }); it('parses inverse block with block params', function() { equals( astFor('{{^foo as |bar baz|}}content{{/foo}}'), "BLOCK:\n PATH:foo []\n {{^}}\n BLOCK PARAMS: [ bar baz ]\n CONTENT[ 'content' ]\n" ); }); it('parses chained inverse block with block params', function() { equals( astFor('{{#foo}}{{else foo as |bar baz|}}content{{/foo}}'), "BLOCK:\n PATH:foo []\n PROGRAM:\n {{^}}\n BLOCK:\n PATH:foo []\n PROGRAM:\n BLOCK PARAMS: [ bar baz ]\n CONTENT[ 'content' ]\n" ); }); it("raises if there's a Parse error", function() { shouldThrow( function() { astFor('foo{{^}}bar'); }, Error, /Parse error on line 1/ ); shouldThrow( function() { astFor('{{foo}'); }, Error, /Parse error on line 1/ ); shouldThrow( function() { astFor('{{foo &}}'); }, Error, /Parse error on line 1/ ); shouldThrow( function() { astFor('{{#goodbyes}}{{/hellos}}'); }, Error, /goodbyes doesn't match hellos/ ); shouldThrow( function() { astFor('{{{{goodbyes}}}} {{{{/hellos}}}}'); }, Error, /goodbyes doesn't match hellos/ ); }); it('should handle invalid paths', function() { shouldThrow( function() { astFor('{{foo/../bar}}'); }, Error, /Invalid path: foo\/\.\. - 1:2/ ); shouldThrow( function() { astFor('{{foo/./bar}}'); }, Error, /Invalid path: foo\/\. - 1:2/ ); shouldThrow( function() { astFor('{{foo/this/bar}}'); }, Error, /Invalid path: foo\/this - 1:2/ ); }); it('knows how to report the correct line number in errors', function() { shouldThrow( function() { astFor('hello\nmy\n{{foo}'); }, Error, /Parse error on line 3/ ); shouldThrow( function() { astFor('hello\n\nmy\n\n{{foo}'); }, Error, /Parse error on line 5/ ); }); it('knows how to report the correct line number in errors when the first character is a newline', function() { shouldThrow( function() { astFor('\n\nhello\n\nmy\n\n{{foo}'); }, Error, /Parse error on line 7/ ); }); describe('externally compiled AST', function() { it('can pass through an already-compiled AST', function() { equals( astFor({ type: 'Program', body: [{ type: 'ContentStatement', value: 'Hello' }] }), "CONTENT[ 'Hello' ]\n" ); }); }); describe('directives', function() { it('should parse block directives', function() { equals( astFor('{{#* foo}}{{/foo}}'), 'DIRECTIVE BLOCK:\n PATH:foo []\n PROGRAM:\n' ); }); it('should parse directives', function() { equals(astFor('{{* foo}}'), '{{ DIRECTIVE PATH:foo [] }}\n'); }); it('should fail if directives have inverse', function() { shouldThrow( function() { astFor('{{#* foo}}{{^}}{{/foo}}'); }, Error, /Unexpected inverse/ ); }); }); it('GH1024 - should track program location properly', function() { var p = Handlebars.parse( '\n' + ' {{#if foo}}\n' + ' {{bar}}\n' + ' {{else}} {{baz}}\n' + '\n' + ' {{/if}}\n' + ' ' ); // We really need a deep equals but for now this should be stable... equals( JSON.stringify(p.loc), JSON.stringify({ start: { line: 1, column: 0 }, end: { line: 7, column: 4 } }) ); equals( JSON.stringify(p.body[1].program.loc), JSON.stringify({ start: { line: 2, column: 13 }, end: { line: 4, column: 7 } }) ); equals( JSON.stringify(p.body[1].inverse.loc), JSON.stringify({ start: { line: 4, column: 15 }, end: { line: 6, column: 5 } }) ); }); }); handlebars.js-4.7.7/spec/partials.js000066400000000000000000000570061401244020700173600ustar00rootroot00000000000000describe('partials', function() { it('basic partials', function() { var string = 'Dudes: {{#dudes}}{{> dude}}{{/dudes}}'; var partial = '{{name}} ({{url}}) '; var hash = { dudes: [ { name: 'Yehuda', url: 'http://yehuda' }, { name: 'Alan', url: 'http://alan' } ] }; expectTemplate(string) .withInput(hash) .withPartials({ dude: partial }) .toCompileTo('Dudes: Yehuda (http://yehuda) Alan (http://alan) '); expectTemplate(string) .withInput(hash) .withPartials({ dude: partial }) .withRuntimeOptions({ data: false }) .withCompileOptions({ data: false }) .toCompileTo('Dudes: Yehuda (http://yehuda) Alan (http://alan) '); }); it('dynamic partials', function() { var string = 'Dudes: {{#dudes}}{{> (partial)}}{{/dudes}}'; var partial = '{{name}} ({{url}}) '; var hash = { dudes: [ { name: 'Yehuda', url: 'http://yehuda' }, { name: 'Alan', url: 'http://alan' } ] }; var helpers = { partial: function() { return 'dude'; } }; expectTemplate(string) .withInput(hash) .withHelpers(helpers) .withPartials({ dude: partial }) .toCompileTo('Dudes: Yehuda (http://yehuda) Alan (http://alan) '); expectTemplate(string) .withInput(hash) .withHelpers(helpers) .withPartials({ dude: partial }) .withRuntimeOptions({ data: false }) .withCompileOptions({ data: false }) .toCompileTo('Dudes: Yehuda (http://yehuda) Alan (http://alan) '); }); it('failing dynamic partials', function() { expectTemplate('Dudes: {{#dudes}}{{> (partial)}}{{/dudes}}') .withInput({ dudes: [ { name: 'Yehuda', url: 'http://yehuda' }, { name: 'Alan', url: 'http://alan' } ] }) .withHelper('partial', function() { return 'missing'; }) .withPartial('dude', '{{name}} ({{url}}) ') .toThrow(Handlebars.Exception, 'The partial missing could not be found'); }); it('partials with context', function() { expectTemplate('Dudes: {{>dude dudes}}') .withInput({ dudes: [ { name: 'Yehuda', url: 'http://yehuda' }, { name: 'Alan', url: 'http://alan' } ] }) .withPartial('dude', '{{#this}}{{name}} ({{url}}) {{/this}}') .withMessage('Partials can be passed a context') .toCompileTo('Dudes: Yehuda (http://yehuda) Alan (http://alan) '); }); it('partials with no context', function() { var partial = '{{name}} ({{url}}) '; var hash = { dudes: [ { name: 'Yehuda', url: 'http://yehuda' }, { name: 'Alan', url: 'http://alan' } ] }; expectTemplate('Dudes: {{#dudes}}{{>dude}}{{/dudes}}') .withInput(hash) .withPartial('dude', partial) .withCompileOptions({ explicitPartialContext: true }) .toCompileTo('Dudes: () () '); expectTemplate('Dudes: {{#dudes}}{{>dude name="foo"}}{{/dudes}}') .withInput(hash) .withPartial('dude', partial) .withCompileOptions({ explicitPartialContext: true }) .toCompileTo('Dudes: foo () foo () '); }); it('partials with string context', function() { expectTemplate('Dudes: {{>dude "dudes"}}') .withPartial('dude', '{{.}}') .toCompileTo('Dudes: dudes'); }); it('partials with undefined context', function() { expectTemplate('Dudes: {{>dude dudes}}') .withPartial('dude', '{{foo}} Empty') .toCompileTo('Dudes: Empty'); }); it('partials with duplicate parameters', function() { expectTemplate('Dudes: {{>dude dudes foo bar=baz}}').toThrow( Error, 'Unsupported number of partial arguments: 2 - 1:7' ); }); it('partials with parameters', function() { expectTemplate('Dudes: {{#dudes}}{{> dude others=..}}{{/dudes}}') .withInput({ foo: 'bar', dudes: [ { name: 'Yehuda', url: 'http://yehuda' }, { name: 'Alan', url: 'http://alan' } ] }) .withPartial('dude', '{{others.foo}}{{name}} ({{url}}) ') .withMessage('Basic partials output based on current context.') .toCompileTo('Dudes: barYehuda (http://yehuda) barAlan (http://alan) '); }); it('partial in a partial', function() { expectTemplate('Dudes: {{#dudes}}{{>dude}}{{/dudes}}') .withInput({ dudes: [ { name: 'Yehuda', url: 'http://yehuda' }, { name: 'Alan', url: 'http://alan' } ] }) .withPartials({ dude: '{{name}} {{> url}} ', url: '{{url}}' }) .withMessage('Partials are rendered inside of other partials') .toCompileTo( 'Dudes: Yehuda http://yehuda Alan http://alan ' ); }); it('rendering undefined partial throws an exception', function() { expectTemplate('{{> whatever}}').toThrow( Handlebars.Exception, 'The partial whatever could not be found' ); }); it('registering undefined partial throws an exception', function() { shouldThrow( function() { var undef; handlebarsEnv.registerPartial('undefined_test', undef); }, Handlebars.Exception, 'Attempting to register a partial called "undefined_test" as undefined' ); }); it('rendering template partial in vm mode throws an exception', function() { expectTemplate('{{> whatever}}').toThrow( Handlebars.Exception, 'The partial whatever could not be found' ); }); it('rendering function partial in vm mode', function() { function partial(context) { return context.name + ' (' + context.url + ') '; } expectTemplate('Dudes: {{#dudes}}{{> dude}}{{/dudes}}') .withInput({ dudes: [ { name: 'Yehuda', url: 'http://yehuda' }, { name: 'Alan', url: 'http://alan' } ] }) .withPartial('dude', partial) .withMessage('Function partials output based in VM.') .toCompileTo('Dudes: Yehuda (http://yehuda) Alan (http://alan) '); }); it('GH-14: a partial preceding a selector', function() { expectTemplate('Dudes: {{>dude}} {{anotherDude}}') .withInput({ name: 'Jeepers', anotherDude: 'Creepers' }) .withPartial('dude', '{{name}}') .withMessage('Regular selectors can follow a partial') .toCompileTo('Dudes: Jeepers Creepers'); }); it('Partials with slash paths', function() { expectTemplate('Dudes: {{> shared/dude}}') .withInput({ name: 'Jeepers', anotherDude: 'Creepers' }) .withPartial('shared/dude', '{{name}}') .withMessage('Partials can use literal paths') .toCompileTo('Dudes: Jeepers'); }); it('Partials with slash and point paths', function() { expectTemplate('Dudes: {{> shared/dude.thing}}') .withInput({ name: 'Jeepers', anotherDude: 'Creepers' }) .withPartial('shared/dude.thing', '{{name}}') .withMessage('Partials can use literal with points in paths') .toCompileTo('Dudes: Jeepers'); }); it('Global Partials', function() { handlebarsEnv.registerPartial('globalTest', '{{anotherDude}}'); expectTemplate('Dudes: {{> shared/dude}} {{> globalTest}}') .withInput({ name: 'Jeepers', anotherDude: 'Creepers' }) .withPartial('shared/dude', '{{name}}') .withMessage('Partials can use globals or passed') .toCompileTo('Dudes: Jeepers Creepers'); handlebarsEnv.unregisterPartial('globalTest'); equals(handlebarsEnv.partials.globalTest, undefined); }); it('Multiple partial registration', function() { handlebarsEnv.registerPartial({ 'shared/dude': '{{name}}', globalTest: '{{anotherDude}}' }); expectTemplate('Dudes: {{> shared/dude}} {{> globalTest}}') .withInput({ name: 'Jeepers', anotherDude: 'Creepers' }) .withPartial('notused', 'notused') // trick the test bench into running with partials enabled .withMessage('Partials can use globals or passed') .toCompileTo('Dudes: Jeepers Creepers'); }); it('Partials with integer path', function() { expectTemplate('Dudes: {{> 404}}') .withInput({ name: 'Jeepers', anotherDude: 'Creepers' }) .withPartial(404, '{{name}}') .withMessage('Partials can use literal paths') .toCompileTo('Dudes: Jeepers'); }); it('Partials with complex path', function() { expectTemplate('Dudes: {{> 404/asdf?.bar}}') .withInput({ name: 'Jeepers', anotherDude: 'Creepers' }) .withPartial('404/asdf?.bar', '{{name}}') .withMessage('Partials can use literal paths') .toCompileTo('Dudes: Jeepers'); }); it('Partials with escaped', function() { expectTemplate('Dudes: {{> [+404/asdf?.bar]}}') .withInput({ name: 'Jeepers', anotherDude: 'Creepers' }) .withPartial('+404/asdf?.bar', '{{name}}') .withMessage('Partials can use literal paths') .toCompileTo('Dudes: Jeepers'); }); it('Partials with string', function() { expectTemplate("Dudes: {{> '+404/asdf?.bar'}}") .withInput({ name: 'Jeepers', anotherDude: 'Creepers' }) .withPartial('+404/asdf?.bar', '{{name}}') .withMessage('Partials can use literal paths') .toCompileTo('Dudes: Jeepers'); }); it('should handle empty partial', function() { expectTemplate('Dudes: {{#dudes}}{{> dude}}{{/dudes}}') .withInput({ dudes: [ { name: 'Yehuda', url: 'http://yehuda' }, { name: 'Alan', url: 'http://alan' } ] }) .withPartial('dude', '') .toCompileTo('Dudes: '); }); it('throw on missing partial', function() { var compile = handlebarsEnv.compile; var compileWithPartial = CompilerContext.compileWithPartial; handlebarsEnv.compile = undefined; CompilerContext.compileWithPartial = CompilerContext.compile; expectTemplate('{{> dude}}') .withPartials({ dude: 'fail' }) .toThrow(Error, /The partial dude could not be compiled/); handlebarsEnv.compile = compile; CompilerContext.compileWithPartial = compileWithPartial; }); describe('partial blocks', function() { it('should render partial block as default', function() { expectTemplate('{{#> dude}}success{{/dude}}').toCompileTo('success'); }); it('should execute default block with proper context', function() { expectTemplate('{{#> dude context}}{{value}}{{/dude}}') .withInput({ context: { value: 'success' } }) .toCompileTo('success'); }); it('should propagate block parameters to default block', function() { expectTemplate( '{{#with context as |me|}}{{#> dude}}{{me.value}}{{/dude}}{{/with}}' ) .withInput({ context: { value: 'success' } }) .toCompileTo('success'); }); it('should not use partial block if partial exists', function() { expectTemplate('{{#> dude}}fail{{/dude}}') .withPartials({ dude: 'success' }) .toCompileTo('success'); }); it('should render block from partial', function() { expectTemplate('{{#> dude}}success{{/dude}}') .withPartials({ dude: '{{> @partial-block }}' }) .toCompileTo('success'); }); it('should be able to render the partial-block twice', function() { expectTemplate('{{#> dude}}success{{/dude}}') .withPartials({ dude: '{{> @partial-block }} {{> @partial-block }}' }) .toCompileTo('success success'); }); it('should render block from partial with context', function() { expectTemplate('{{#> dude}}{{value}}{{/dude}}') .withInput({ context: { value: 'success' } }) .withPartials({ dude: '{{#with context}}{{> @partial-block }}{{/with}}' }) .toCompileTo('success'); }); it('should be able to access the @data frame from a partial-block', function() { expectTemplate('{{#> dude}}in-block: {{@root/value}}{{/dude}}') .withInput({ value: 'success' }) .withPartials({ dude: 'before-block: {{@root/value}} {{> @partial-block }}' }) .toCompileTo('before-block: success in-block: success'); }); it('should allow the #each-helper to be used along with partial-blocks', function() { expectTemplate( '' ) .withInput({ value: ['a', 'b', 'c'] }) .withPartials({ list: '{{#each .}}{{> @partial-block}}{{/each}}' }) .toCompileTo( '' ); }); it('should render block from partial with context (twice)', function() { expectTemplate('{{#> dude}}{{value}}{{/dude}}') .withInput({ context: { value: 'success' } }) .withPartials({ dude: '{{#with context}}{{> @partial-block }} {{> @partial-block }}{{/with}}' }) .toCompileTo('success success'); }); it('should render block from partial with context', function() { expectTemplate('{{#> dude}}{{../context/value}}{{/dude}}') .withInput({ context: { value: 'success' } }) .withPartials({ dude: '{{#with context}}{{> @partial-block }}{{/with}}' }) .toCompileTo('success'); }); it('should render block from partial with block params', function() { expectTemplate( '{{#with context as |me|}}{{#> dude}}{{me.value}}{{/dude}}{{/with}}' ) .withInput({ context: { value: 'success' } }) .withPartials({ dude: '{{> @partial-block }}' }) .toCompileTo('success'); }); it('should render nested partial blocks', function() { expectTemplate('') .withInput({ value: 'success' }) .withPartials({ outer: '{{#> nested}}{{> @partial-block}}{{/nested}}', nested: '{{> @partial-block}}' }) .toCompileTo( '' ); }); it('should render nested partial blocks at different nesting levels', function() { expectTemplate('') .withInput({ value: 'success' }) .withPartials({ outer: '{{#> nested}}{{> @partial-block}}{{/nested}}{{> @partial-block}}', nested: '{{> @partial-block}}' }) .toCompileTo( '' ); }); it('should render nested partial blocks at different nesting levels (twice)', function() { expectTemplate('') .withInput({ value: 'success' }) .withPartials({ outer: '{{#> nested}}{{> @partial-block}} {{> @partial-block}}{{/nested}}{{> @partial-block}}+{{> @partial-block}}', nested: '{{> @partial-block}}' }) .toCompileTo( '' ); }); it('should render nested partial blocks (twice at each level)', function() { expectTemplate('') .withInput({ value: 'success' }) .withPartials({ outer: '{{#> nested}}{{> @partial-block}} {{> @partial-block}}{{/nested}}', nested: '{{> @partial-block}}{{> @partial-block}}' }) .toCompileTo( '' ); }); }); describe('inline partials', function() { it('should define inline partials for template', function() { expectTemplate( '{{#*inline "myPartial"}}success{{/inline}}{{> myPartial}}' ).toCompileTo('success'); }); it('should overwrite multiple partials in the same template', function() { expectTemplate( '{{#*inline "myPartial"}}fail{{/inline}}{{#*inline "myPartial"}}success{{/inline}}{{> myPartial}}' ).toCompileTo('success'); }); it('should define inline partials for block', function() { expectTemplate( '{{#with .}}{{#*inline "myPartial"}}success{{/inline}}{{> myPartial}}{{/with}}' ).toCompileTo('success'); expectTemplate( '{{#with .}}{{#*inline "myPartial"}}success{{/inline}}{{/with}}{{> myPartial}}' ).toThrow(Error, /myPartial could not/); }); it('should override global partials', function() { expectTemplate( '{{#*inline "myPartial"}}success{{/inline}}{{> myPartial}}' ) .withPartials({ myPartial: function() { return 'fail'; } }) .toCompileTo('success'); }); it('should override template partials', function() { expectTemplate( '{{#*inline "myPartial"}}fail{{/inline}}{{#with .}}{{#*inline "myPartial"}}success{{/inline}}{{> myPartial}}{{/with}}' ).toCompileTo('success'); }); it('should override partials down the entire stack', function() { expectTemplate( '{{#with .}}{{#*inline "myPartial"}}success{{/inline}}{{#with .}}{{#with .}}{{> myPartial}}{{/with}}{{/with}}{{/with}}' ).toCompileTo('success'); }); it('should define inline partials for partial call', function() { expectTemplate('{{#*inline "myPartial"}}success{{/inline}}{{> dude}}') .withPartials({ dude: '{{> myPartial }}' }) .toCompileTo('success'); }); it('should define inline partials in partial block call', function() { expectTemplate( '{{#> dude}}{{#*inline "myPartial"}}success{{/inline}}{{/dude}}' ) .withPartials({ dude: '{{> myPartial }}' }) .toCompileTo('success'); }); it('should render nested inline partials', function() { expectTemplate( '{{#*inline "outer"}}{{#>inner}}{{>@partial-block}}{{/inner}}{{/inline}}' + '{{#*inline "inner"}}{{>@partial-block}}{{/inline}}' + '{{#>outer}}{{value}}{{/outer}}' ) .withInput({ value: 'success' }) .toCompileTo('success'); }); it('should render nested inline partials with partial-blocks on different nesting levels', function() { expectTemplate( '{{#*inline "outer"}}{{#>inner}}{{>@partial-block}}{{/inner}}{{>@partial-block}}{{/inline}}' + '{{#*inline "inner"}}{{>@partial-block}}{{/inline}}' + '{{#>outer}}{{value}}{{/outer}}' ) .withInput({ value: 'success' }) .toCompileTo( 'successsuccess' ); }); it('should render nested inline partials (twice at each level)', function() { expectTemplate( '{{#*inline "outer"}}{{#>inner}}{{>@partial-block}} {{>@partial-block}}{{/inner}}{{/inline}}' + '{{#*inline "inner"}}{{>@partial-block}}{{>@partial-block}}{{/inline}}' + '{{#>outer}}{{value}}{{/outer}}' ) .withInput({ value: 'success' }) .toCompileTo( 'success successsuccess success' ); }); }); it('should pass compiler flags', function() { if (Handlebars.compile) { var env = Handlebars.create(); env.registerPartial('partial', '{{foo}}'); var template = env.compile('{{foo}} {{> partial}}', { noEscape: true }); equal(template({ foo: '<' }), '< <'); } }); describe('standalone partials', function() { it('indented partials', function() { expectTemplate('Dudes:\n{{#dudes}}\n {{>dude}}\n{{/dudes}}') .withInput({ dudes: [ { name: 'Yehuda', url: 'http://yehuda' }, { name: 'Alan', url: 'http://alan' } ] }) .withPartial('dude', '{{name}}\n') .toCompileTo('Dudes:\n Yehuda\n Alan\n'); }); it('nested indented partials', function() { expectTemplate('Dudes:\n{{#dudes}}\n {{>dude}}\n{{/dudes}}') .withInput({ dudes: [ { name: 'Yehuda', url: 'http://yehuda' }, { name: 'Alan', url: 'http://alan' } ] }) .withPartials({ dude: '{{name}}\n {{> url}}', url: '{{url}}!\n' }) .toCompileTo( 'Dudes:\n Yehuda\n http://yehuda!\n Alan\n http://alan!\n' ); }); it('prevent nested indented partials', function() { expectTemplate('Dudes:\n{{#dudes}}\n {{>dude}}\n{{/dudes}}') .withInput({ dudes: [ { name: 'Yehuda', url: 'http://yehuda' }, { name: 'Alan', url: 'http://alan' } ] }) .withPartials({ dude: '{{name}}\n {{> url}}', url: '{{url}}!\n' }) .withCompileOptions({ preventIndent: true }) .toCompileTo( 'Dudes:\n Yehuda\n http://yehuda!\n Alan\n http://alan!\n' ); }); }); describe('compat mode', function() { it('partials can access parents', function() { expectTemplate('Dudes: {{#dudes}}{{> dude}}{{/dudes}}') .withInput({ root: 'yes', dudes: [ { name: 'Yehuda', url: 'http://yehuda' }, { name: 'Alan', url: 'http://alan' } ] }) .withPartials({ dude: '{{name}} ({{url}}) {{root}} ' }) .withCompileOptions({ compat: true }) .toCompileTo( 'Dudes: Yehuda (http://yehuda) yes Alan (http://alan) yes ' ); }); it('partials can access parents with custom context', function() { expectTemplate('Dudes: {{#dudes}}{{> dude "test"}}{{/dudes}}') .withInput({ root: 'yes', dudes: [ { name: 'Yehuda', url: 'http://yehuda' }, { name: 'Alan', url: 'http://alan' } ] }) .withPartials({ dude: '{{name}} ({{url}}) {{root}} ' }) .withCompileOptions({ compat: true }) .toCompileTo( 'Dudes: Yehuda (http://yehuda) yes Alan (http://alan) yes ' ); }); it('partials can access parents without data', function() { expectTemplate('Dudes: {{#dudes}}{{> dude}}{{/dudes}}') .withInput({ root: 'yes', dudes: [ { name: 'Yehuda', url: 'http://yehuda' }, { name: 'Alan', url: 'http://alan' } ] }) .withPartials({ dude: '{{name}} ({{url}}) {{root}} ' }) .withRuntimeOptions({ data: false }) .withCompileOptions({ data: false, compat: true }) .toCompileTo( 'Dudes: Yehuda (http://yehuda) yes Alan (http://alan) yes ' ); }); it('partials inherit compat', function() { expectTemplate('Dudes: {{> dude}}') .withInput({ root: 'yes', dudes: [ { name: 'Yehuda', url: 'http://yehuda' }, { name: 'Alan', url: 'http://alan' } ] }) .withPartials({ dude: '{{#dudes}}{{name}} ({{url}}) {{root}} {{/dudes}}' }) .withCompileOptions({ compat: true }) .toCompileTo( 'Dudes: Yehuda (http://yehuda) yes Alan (http://alan) yes ' ); }); }); }); handlebars.js-4.7.7/spec/precompiler.js000066400000000000000000000301671401244020700200610ustar00rootroot00000000000000/* eslint-disable no-console */ describe('precompiler', function() { // NOP Under non-node environments if (typeof process === 'undefined') { return; } var Handlebars = require('../lib'), Precompiler = require('../dist/cjs/precompiler'), fs = require('fs'), uglify = require('uglify-js'); var log, logFunction, errorLog, errorLogFunction, precompile, minify, emptyTemplate = { path: __dirname + '/artifacts/empty.handlebars', name: 'empty', source: '' }, file, content, writeFileSync; /** * Mock the Module.prototype.require-function such that an error is thrown, when "uglify-js" is loaded. * * The function cleans up its mess when "callback" is finished * * @param {Error} loadError the error that should be thrown if uglify is loaded * @param {function} callback a callback-function to run when the mock is active. */ function mockRequireUglify(loadError, callback) { var Module = require('module'); var _resolveFilename = Module._resolveFilename; delete require.cache[require.resolve('uglify-js')]; delete require.cache[require.resolve('../dist/cjs/precompiler')]; Module._resolveFilename = function(request, mod) { if (request === 'uglify-js') { throw loadError; } return _resolveFilename.call(this, request, mod); }; try { callback(); } finally { Module._resolveFilename = _resolveFilename; delete require.cache[require.resolve('uglify-js')]; delete require.cache[require.resolve('../dist/cjs/precompiler')]; } } beforeEach(function() { precompile = Handlebars.precompile; minify = uglify.minify; writeFileSync = fs.writeFileSync; // Mock stdout and stderr logFunction = console.log; log = ''; console.log = function() { log += Array.prototype.join.call(arguments, ''); }; errorLogFunction = console.error; errorLog = ''; console.error = function() { errorLog += Array.prototype.join.call(arguments, ''); }; fs.writeFileSync = function(_file, _content) { file = _file; content = _content; }; }); afterEach(function() { Handlebars.precompile = precompile; uglify.minify = minify; fs.writeFileSync = writeFileSync; console.log = logFunction; console.error = errorLogFunction; }); it('should output version', function() { Precompiler.cli({ templates: [], version: true }); equals(log, Handlebars.VERSION); }); it('should throw if lacking templates', function() { shouldThrow( function() { Precompiler.cli({ templates: [] }); }, Handlebars.Exception, 'Must define at least one template or directory.' ); }); it('should handle empty/filtered directories', function() { Precompiler.cli({ hasDirectory: true, templates: [] }); // Success is not throwing }); it('should throw when combining simple and minimized', function() { shouldThrow( function() { Precompiler.cli({ templates: [__dirname], simple: true, min: true }); }, Handlebars.Exception, 'Unable to minimize simple output' ); }); it('should throw when combining simple and multiple templates', function() { shouldThrow( function() { Precompiler.cli({ templates: [ __dirname + '/artifacts/empty.handlebars', __dirname + '/artifacts/empty.handlebars' ], simple: true }); }, Handlebars.Exception, 'Unable to output multiple templates in simple mode' ); }); it('should throw when missing name', function() { shouldThrow( function() { Precompiler.cli({ templates: [{ source: '' }], amd: true }); }, Handlebars.Exception, 'Name missing for template' ); }); it('should throw when combining simple and directories', function() { shouldThrow( function() { Precompiler.cli({ hasDirectory: true, templates: [1], simple: true }); }, Handlebars.Exception, 'Unable to output multiple templates in simple mode' ); }); it('should output simple templates', function() { Handlebars.precompile = function() { return 'simple'; }; Precompiler.cli({ templates: [emptyTemplate], simple: true }); equal(log, 'simple\n'); }); it('should default to simple templates', function() { Handlebars.precompile = function() { return 'simple'; }; Precompiler.cli({ templates: [{ source: '' }] }); equal(log, 'simple\n'); }); it('should output amd templates', function() { Handlebars.precompile = function() { return 'amd'; }; Precompiler.cli({ templates: [emptyTemplate], amd: true }); equal(/template\(amd\)/.test(log), true); }); it('should output multiple amd', function() { Handlebars.precompile = function() { return 'amd'; }; Precompiler.cli({ templates: [emptyTemplate, emptyTemplate], amd: true, namespace: 'foo' }); equal(/templates = foo = foo \|\|/.test(log), true); equal(/return templates/.test(log), true); equal(/template\(amd\)/.test(log), true); }); it('should output amd partials', function() { Handlebars.precompile = function() { return 'amd'; }; Precompiler.cli({ templates: [emptyTemplate], amd: true, partial: true }); equal(/return Handlebars\.partials\['empty'\]/.test(log), true); equal(/template\(amd\)/.test(log), true); }); it('should output multiple amd partials', function() { Handlebars.precompile = function() { return 'amd'; }; Precompiler.cli({ templates: [emptyTemplate, emptyTemplate], amd: true, partial: true }); equal(/return Handlebars\.partials\[/.test(log), false); equal(/template\(amd\)/.test(log), true); }); it('should output commonjs templates', function() { Handlebars.precompile = function() { return 'commonjs'; }; Precompiler.cli({ templates: [emptyTemplate], commonjs: true }); equal(/template\(commonjs\)/.test(log), true); }); it('should set data flag', function() { Handlebars.precompile = function(data, options) { equal(options.data, true); return 'simple'; }; Precompiler.cli({ templates: [emptyTemplate], simple: true, data: true }); equal(log, 'simple\n'); }); it('should set known helpers', function() { Handlebars.precompile = function(data, options) { equal(options.knownHelpers.foo, true); return 'simple'; }; Precompiler.cli({ templates: [emptyTemplate], simple: true, known: 'foo' }); equal(log, 'simple\n'); }); it('should output to file system', function() { Handlebars.precompile = function() { return 'simple'; }; Precompiler.cli({ templates: [emptyTemplate], simple: true, output: 'file!' }); equal(file, 'file!'); equal(content, 'simple\n'); equal(log, ''); }); it('should output minimized templates', function() { Handlebars.precompile = function() { return 'amd'; }; uglify.minify = function() { return { code: 'min' }; }; Precompiler.cli({ templates: [emptyTemplate], min: true }); equal(log, 'min'); }); it('should omit minimization gracefully, if uglify-js is missing', function() { var error = new Error("Cannot find module 'uglify-js'"); error.code = 'MODULE_NOT_FOUND'; mockRequireUglify(error, function() { var Precompiler = require('../dist/cjs/precompiler'); Handlebars.precompile = function() { return 'amd'; }; Precompiler.cli({ templates: [emptyTemplate], min: true }); equal(/template\(amd\)/.test(log), true); equal(/\n/.test(log), true); equal(/Code minimization is disabled/.test(errorLog), true); }); }); it('should fail on errors (other than missing module) while loading uglify-js', function() { mockRequireUglify(new Error('Mock Error'), function() { shouldThrow( function() { var Precompiler = require('../dist/cjs/precompiler'); Handlebars.precompile = function() { return 'amd'; }; Precompiler.cli({ templates: [emptyTemplate], min: true }); }, Error, 'Mock Error' ); }); }); it('should output map', function() { Precompiler.cli({ templates: [emptyTemplate], map: 'foo.js.map' }); equal(file, 'foo.js.map'); equal(log.match(/sourceMappingURL=/g).length, 1); }); it('should output map', function() { Precompiler.cli({ templates: [emptyTemplate], min: true, map: 'foo.js.map' }); equal(file, 'foo.js.map'); equal(log.match(/sourceMappingURL=/g).length, 1); }); describe('#loadTemplates', function() { it('should throw on missing template', function(done) { Precompiler.loadTemplates({ files: ['foo'] }, function(err) { equal(err.message, 'Unable to open template file "foo"'); done(); }); }); it('should enumerate directories by extension', function(done) { Precompiler.loadTemplates( { files: [__dirname + '/artifacts'], extension: 'hbs' }, function(err, opts) { equal(opts.templates.length, 2); equal(opts.templates[0].name, 'example_2'); done(err); } ); }); it('should enumerate all templates by extension', function(done) { Precompiler.loadTemplates( { files: [__dirname + '/artifacts'], extension: 'handlebars' }, function(err, opts) { equal(opts.templates.length, 5); equal(opts.templates[0].name, 'bom'); equal(opts.templates[1].name, 'empty'); equal(opts.templates[2].name, 'example_1'); done(err); } ); }); it('should handle regular expression characters in extensions', function(done) { Precompiler.loadTemplates( { files: [__dirname + '/artifacts'], extension: 'hb(s' }, function(err) { // Success is not throwing done(err); } ); }); it('should handle BOM', function(done) { var opts = { files: [__dirname + '/artifacts/bom.handlebars'], extension: 'handlebars', bom: true }; Precompiler.loadTemplates(opts, function(err, opts) { equal(opts.templates[0].source, 'a'); done(err); }); }); it('should handle different root', function(done) { var opts = { files: [__dirname + '/artifacts/empty.handlebars'], simple: true, root: 'foo/' }; Precompiler.loadTemplates(opts, function(err, opts) { equal(opts.templates[0].name, __dirname + '/artifacts/empty'); done(err); }); }); it('should accept string inputs', function(done) { var opts = { string: '' }; Precompiler.loadTemplates(opts, function(err, opts) { equal(opts.templates[0].name, undefined); equal(opts.templates[0].source, ''); done(err); }); }); it('should accept string array inputs', function(done) { var opts = { string: ['', 'bar'], name: ['beep', 'boop'] }; Precompiler.loadTemplates(opts, function(err, opts) { equal(opts.templates[0].name, 'beep'); equal(opts.templates[0].source, ''); equal(opts.templates[1].name, 'boop'); equal(opts.templates[1].source, 'bar'); done(err); }); }); it('should accept stdin input', function(done) { var stdin = require('mock-stdin').stdin(); Precompiler.loadTemplates({ string: '-' }, function(err, opts) { equal(opts.templates[0].source, 'foo'); done(err); }); stdin.send('fo'); stdin.send('o'); stdin.end(); }); it('error on name missing', function(done) { var opts = { string: ['', 'bar'] }; Precompiler.loadTemplates(opts, function(err) { equal( err.message, 'Number of names did not match the number of string inputs' ); done(); }); }); it('should complete when no args are passed', function(done) { Precompiler.loadTemplates({}, function(err, opts) { equal(opts.templates.length, 0); done(err); }); }); }); }); handlebars.js-4.7.7/spec/regressions.js000066400000000000000000000363731401244020700201100ustar00rootroot00000000000000describe('Regressions', function() { it('GH-94: Cannot read property of undefined', function() { expectTemplate('{{#books}}{{title}}{{author.name}}{{/books}}') .withInput({ books: [ { title: 'The origin of species', author: { name: 'Charles Darwin' } }, { title: 'Lazarillo de Tormes' } ] }) .withMessage('Renders without an undefined property error') .toCompileTo('The origin of speciesCharles DarwinLazarillo de Tormes'); }); it("GH-150: Inverted sections print when they shouldn't", function() { var string = '{{^set}}not set{{/set}} :: {{#set}}set{{/set}}'; expectTemplate(string) .withMessage( "inverted sections run when property isn't present in context" ) .toCompileTo('not set :: '); expectTemplate(string) .withInput({ set: undefined }) .withMessage('inverted sections run when property is undefined') .toCompileTo('not set :: '); expectTemplate(string) .withInput({ set: false }) .withMessage('inverted sections run when property is false') .toCompileTo('not set :: '); expectTemplate(string) .withInput({ set: true }) .withMessage("inverted sections don't run when property is true") .toCompileTo(' :: set'); }); it('GH-158: Using array index twice, breaks the template', function() { expectTemplate('{{arr.[0]}}, {{arr.[1]}}') .withInput({ arr: [1, 2] }) .withMessage('it works as expected') .toCompileTo('1, 2'); }); it("bug reported by @fat where lambdas weren't being properly resolved", function() { var string = 'This is a slightly more complicated {{thing}}..\n' + '{{! Just ignore this business. }}\n' + 'Check this out:\n' + '{{#hasThings}}\n' + '.\n' + '{{/hasThings}}\n' + '{{^hasThings}}\n' + '\n' + 'Nothing to check out...\n' + '{{/hasThings}}'; var data = { thing: function() { return 'blah'; }, things: [ { className: 'one', word: '@fat' }, { className: 'two', word: '@dhg' }, { className: 'three', word: '@sayrer' } ], hasThings: function() { return true; } }; var output = 'This is a slightly more complicated blah..\n' + 'Check this out:\n' + '.\n'; expectTemplate(string) .withInput(data) .toCompileTo(output); }); it('GH-408: Multiple loops fail', function() { expectTemplate( '{{#.}}{{name}}{{/.}}{{#.}}{{name}}{{/.}}{{#.}}{{name}}{{/.}}' ) .withInput([ { name: 'John Doe', location: { city: 'Chicago' } }, { name: 'Jane Doe', location: { city: 'New York' } } ]) .withMessage('It should output multiple times') .toCompileTo('John DoeJane DoeJohn DoeJane DoeJohn DoeJane Doe'); }); it('GS-428: Nested if else rendering', function() { var succeedingTemplate = '{{#inverse}} {{#blk}} Unexpected {{/blk}} {{else}} {{#blk}} Expected {{/blk}} {{/inverse}}'; var failingTemplate = '{{#inverse}} {{#blk}} Unexpected {{/blk}} {{else}} {{#blk}} Expected {{/blk}} {{/inverse}}'; var helpers = { blk: function(block) { return block.fn(''); }, inverse: function(block) { return block.inverse(''); } }; expectTemplate(succeedingTemplate) .withHelpers(helpers) .toCompileTo(' Expected '); expectTemplate(failingTemplate) .withHelpers(helpers) .toCompileTo(' Expected '); }); it('GH-458: Scoped this identifier', function() { expectTemplate('{{./foo}}') .withInput({ foo: 'bar' }) .toCompileTo('bar'); }); it('GH-375: Unicode line terminators', function() { expectTemplate('\u2028').toCompileTo('\u2028'); }); it('GH-534: Object prototype aliases', function() { /* eslint-disable no-extend-native */ Object.prototype[0xd834] = true; expectTemplate('{{foo}}') .withInput({ foo: 'bar' }) .toCompileTo('bar'); delete Object.prototype[0xd834]; /* eslint-enable no-extend-native */ }); it('GH-437: Matching escaping', function() { expectTemplate('{{{a}}').toThrow(Error, /Parse error on/); expectTemplate('{{a}}}').toThrow(Error, /Parse error on/); }); it('GH-676: Using array in escaping mustache fails', function() { var data = { arr: [1, 2] }; expectTemplate('{{arr}}') .withInput(data) .withMessage('it works as expected') .toCompileTo(data.arr.toString()); }); it('Mustache man page', function() { expectTemplate( 'Hello {{name}}. You have just won ${{value}}!{{#in_ca}} Well, ${{taxed_value}}, after taxes.{{/in_ca}}' ) .withInput({ name: 'Chris', value: 10000, taxed_value: 10000 - 10000 * 0.4, in_ca: true }) .withMessage('the hello world mustache example works') .toCompileTo( 'Hello Chris. You have just won $10000! Well, $6000, after taxes.' ); }); it('GH-731: zero context rendering', function() { expectTemplate('{{#foo}} This is {{bar}} ~ {{/foo}}') .withInput({ foo: 0, bar: 'OK' }) .toCompileTo(' This is ~ '); }); it('GH-820: zero pathed rendering', function() { expectTemplate('{{foo.bar}}') .withInput({ foo: 0 }) .toCompileTo(''); }); it('GH-837: undefined values for helpers', function() { expectTemplate('{{str bar.baz}}') .withHelpers({ str: function(value) { return value + ''; } }) .toCompileTo('undefined'); }); it('GH-926: Depths and de-dupe', function() { expectTemplate( '{{#if dater}}{{#each data}}{{../name}}{{/each}}{{else}}{{#each notData}}{{../name}}{{/each}}{{/if}}' ) .withInput({ name: 'foo', data: [1], notData: [1] }) .toCompileTo('foo'); }); it('GH-1021: Each empty string key', function() { expectTemplate('{{#each data}}Key: {{@key}}\n{{/each}}') .withInput({ data: { '': 'foo', name: 'Chris', value: 10000 } }) .toCompileTo('Key: \nKey: name\nKey: value\n'); }); it('GH-1054: Should handle simple safe string responses', function() { expectTemplate('{{#wrap}}{{>partial}}{{/wrap}}') .withHelpers({ wrap: function(options) { return new Handlebars.SafeString(options.fn()); } }) .withPartials({ partial: '{{#wrap}}{{/wrap}}' }) .toCompileTo(''); }); it('GH-1065: Sparse arrays', function() { var array = []; array[1] = 'foo'; array[3] = 'bar'; expectTemplate('{{#each array}}{{@index}}{{.}}{{/each}}') .withInput({ array: array }) .toCompileTo('1foo3bar'); }); it('GH-1093: Undefined helper context', function() { expectTemplate('{{#each obj}}{{{helper}}}{{.}}{{/each}}') .withInput({ obj: { foo: undefined, bar: 'bat' } }) .withHelpers({ helper: function() { // It's valid to execute a block against an undefined context, but // helpers can not do so, so we expect to have an empty object here; for (var name in this) { if (Object.prototype.hasOwnProperty.call(this, name)) { return 'found'; } } // And to make IE happy, check for the known string as length is not enumerated. return this === 'bat' ? 'found' : 'not'; } }) .toCompileTo('notfoundbat'); }); it('should support multiple levels of inline partials', function() { expectTemplate( '{{#> layout}}{{#*inline "subcontent"}}subcontent{{/inline}}{{/layout}}' ) .withPartials({ doctype: 'doctype{{> content}}', layout: '{{#> doctype}}{{#*inline "content"}}layout{{> subcontent}}{{/inline}}{{/doctype}}' }) .toCompileTo('doctypelayoutsubcontent'); }); it('GH-1089: should support failover content in multiple levels of inline partials', function() { expectTemplate('{{#> layout}}{{/layout}}') .withPartials({ doctype: 'doctype{{> content}}', layout: '{{#> doctype}}{{#*inline "content"}}layout{{#> subcontent}}subcontent{{/subcontent}}{{/inline}}{{/doctype}}' }) .toCompileTo('doctypelayoutsubcontent'); }); it('GH-1099: should support greater than 3 nested levels of inline partials', function() { expectTemplate('{{#> layout}}Outer{{/layout}}') .withPartials({ layout: '{{#> inner}}Inner{{/inner}}{{> @partial-block }}', inner: '' }) .toCompileTo('Outer'); }); it('GH-1135 : Context handling within each iteration', function() { expectTemplate( '{{#each array}}\n' + ' 1. IF: {{#if true}}{{../name}}-{{../../name}}-{{../../../name}}{{/if}}\n' + ' 2. MYIF: {{#myif true}}{{../name}}={{../../name}}={{../../../name}}{{/myif}}\n' + '{{/each}}' ) .withInput({ array: [1], name: 'John' }) .withHelpers({ myif: function(conditional, options) { if (conditional) { return options.fn(this); } else { return options.inverse(this); } } }) .toCompileTo(' 1. IF: John--\n' + ' 2. MYIF: John==\n'); }); it('GH-1186: Support block params for existing programs', function() { expectTemplate( '{{#*inline "test"}}{{> @partial-block }}{{/inline}}' + '{{#>test }}{{#each listOne as |item|}}{{ item }}{{/each}}{{/test}}' + '{{#>test }}{{#each listTwo as |item|}}{{ item }}{{/each}}{{/test}}' ) .withInput({ listOne: ['a'], listTwo: ['b'] }) .withMessage('') .toCompileTo('ab'); }); it('GH-1319: "unless" breaks when "each" value equals "null"', function() { expectTemplate( '{{#each list}}{{#unless ./prop}}parent={{../value}} {{/unless}}{{/each}}' ) .withInput({ value: 'parent', list: [null, 'a'] }) .withMessage('') .toCompileTo('parent=parent parent=parent '); }); it('GH-1341: 4.0.7 release breaks {{#if @partial-block}} usage', function() { expectTemplate('template {{>partial}} template') .withPartials({ partialWithBlock: '{{#if @partial-block}} block {{> @partial-block}} block {{/if}}', partial: '{{#> partialWithBlock}} partial {{/partialWithBlock}}' }) .toCompileTo('template block partial block template'); }); describe('GH-1561: 4.3.x should still work with precompiled templates from 4.0.0 <= x < 4.3.0', function() { it('should compile and execute templates', function() { var newHandlebarsInstance = Handlebars.create(); registerTemplate(newHandlebarsInstance, compiledTemplateVersion7()); newHandlebarsInstance.registerHelper('loud', function(value) { return value.toUpperCase(); }); var result = newHandlebarsInstance.templates['test.hbs']({ name: 'yehuda' }); equals(result.trim(), 'YEHUDA'); }); it('should call "helperMissing" if a helper is missing', function() { var newHandlebarsInstance = Handlebars.create(); shouldThrow( function() { registerTemplate(newHandlebarsInstance, compiledTemplateVersion7()); newHandlebarsInstance.templates['test.hbs']({}); }, Handlebars.Exception, 'Missing helper: "loud"' ); }); it('should pass "options.lookupProperty" to "lookup"-helper, even with old templates', function() { var newHandlebarsInstance = Handlebars.create(); registerTemplate( newHandlebarsInstance, compiledTemplateVersion7_usingLookupHelper() ); newHandlebarsInstance.templates['test.hbs']({}); expect( newHandlebarsInstance.templates['test.hbs']({ property: 'a', test: { a: 'b' } }) ).to.equal('b'); }); function registerTemplate(Handlebars, compileTemplate) { var template = Handlebars.template, templates = (Handlebars.templates = Handlebars.templates || {}); templates['test.hbs'] = template(compileTemplate); } function compiledTemplateVersion7() { return { compiler: [7, '>= 4.0.0'], main: function(container, depth0, helpers, partials, data) { return ( container.escapeExpression( ( helpers.loud || (depth0 && depth0.loud) || helpers.helperMissing ).call( depth0 != null ? depth0 : container.nullContext || {}, depth0 != null ? depth0.name : depth0, { name: 'loud', hash: {}, data: data } ) ) + '\n\n' ); }, useData: true }; } function compiledTemplateVersion7_usingLookupHelper() { // This is the compiled version of "{{lookup test property}}" return { compiler: [7, '>= 4.0.0'], main: function(container, depth0, helpers, partials, data) { return container.escapeExpression( helpers.lookup.call( depth0 != null ? depth0 : container.nullContext || {}, depth0 != null ? depth0.test : depth0, depth0 != null ? depth0.property : depth0, { name: 'lookup', hash: {}, data: data } ) ); }, useData: true }; } }); it('should allow hash with protected array names', function() { expectTemplate('{{helpa length="foo"}}') .withInput({ array: [1], name: 'John' }) .withHelpers({ helpa: function(options) { return options.hash.length; } }) .toCompileTo('foo'); }); describe('GH-1598: Performance degradation for partials since v4.3.0', function() { // Do not run test for runs without compiler if (!Handlebars.compile) { return; } var newHandlebarsInstance; beforeEach(function() { newHandlebarsInstance = Handlebars.create(); }); afterEach(function() { sinon.restore(); }); it('should only compile global partials once', function() { var templateSpy = sinon.spy(newHandlebarsInstance, 'template'); newHandlebarsInstance.registerPartial({ dude: 'I am a partial' }); var string = 'Dudes: {{> dude}} {{> dude}}'; newHandlebarsInstance.compile(string)(); // This should compile template + partial once newHandlebarsInstance.compile(string)(); // This should only compile template equal(templateSpy.callCount, 3); sinon.restore(); }); }); describe("GH-1639: TypeError: Cannot read property 'apply' of undefined\" when handlebars version > 4.6.0 (undocumented, deprecated usage)", function() { it('should treat undefined helpers like non-existing helpers', function() { expectTemplate('{{foo}}') .withHelper('foo', undefined) .withInput({ foo: 'bar' }) .toCompileTo('bar'); }); }); }); handlebars.js-4.7.7/spec/require.js000066400000000000000000000013161401244020700172060ustar00rootroot00000000000000if (typeof require !== 'undefined' && require.extensions['.handlebars']) { describe('Require', function() { it('Load .handlebars files with require()', function() { var template = require('./artifacts/example_1'); equal(template, require('./artifacts/example_1.handlebars')); var expected = 'foo\n'; var result = template({ foo: 'foo' }); equal(result, expected); }); it('Load .hbs files with require()', function() { var template = require('./artifacts/example_2'); equal(template, require('./artifacts/example_2.hbs')); var expected = 'Hello, World!\n'; var result = template({ name: 'World' }); equal(result, expected); }); }); } handlebars.js-4.7.7/spec/runtime.js000066400000000000000000000064301401244020700172170ustar00rootroot00000000000000describe('runtime', function() { describe('#template', function() { it('should throw on invalid templates', function() { shouldThrow( function() { Handlebars.template({}); }, Error, 'Unknown template object: object' ); shouldThrow( function() { Handlebars.template(); }, Error, 'Unknown template object: undefined' ); shouldThrow( function() { Handlebars.template(''); }, Error, 'Unknown template object: string' ); }); it('should throw on version mismatch', function() { shouldThrow( function() { Handlebars.template({ main: {}, compiler: [Handlebars.COMPILER_REVISION + 1] }); }, Error, /Template was precompiled with a newer version of Handlebars than the current runtime/ ); shouldThrow( function() { Handlebars.template({ main: {}, compiler: [Handlebars.LAST_COMPATIBLE_COMPILER_REVISION - 1] }); }, Error, /Template was precompiled with an older version of Handlebars than the current runtime/ ); shouldThrow( function() { Handlebars.template({ main: {} }); }, Error, /Template was precompiled with an older version of Handlebars than the current runtime/ ); }); }); describe('#child', function() { if (!Handlebars.compile) { return; } it('should throw for depthed methods without depths', function() { shouldThrow( function() { var template = Handlebars.compile('{{#foo}}{{../bar}}{{/foo}}'); // Calling twice to hit the non-compiled case. template._setup({}); template._setup({}); template._child(1); }, Error, 'must pass parent depths' ); }); it('should throw for block param methods without params', function() { shouldThrow( function() { var template = Handlebars.compile('{{#foo as |foo|}}{{foo}}{{/foo}}'); // Calling twice to hit the non-compiled case. template._setup({}); template._setup({}); template._child(1); }, Error, 'must pass block params' ); }); it('should expose child template', function() { var template = Handlebars.compile('{{#foo}}bar{{/foo}}'); // Calling twice to hit the non-compiled case. equal(template._child(1)(), 'bar'); equal(template._child(1)(), 'bar'); }); it('should render depthed content', function() { var template = Handlebars.compile('{{#foo}}{{../bar}}{{/foo}}'); // Calling twice to hit the non-compiled case. equal(template._child(1, undefined, [], [{ bar: 'baz' }])(), 'baz'); }); }); describe('#noConflict', function() { if (!CompilerContext.browser) { return; } it('should reset on no conflict', function() { var reset = Handlebars; Handlebars.noConflict(); equal(Handlebars, 'no-conflict'); Handlebars = 'really, none'; reset.noConflict(); equal(Handlebars, 'really, none'); Handlebars = reset; }); }); }); handlebars.js-4.7.7/spec/security.js000066400000000000000000000344671401244020700174160ustar00rootroot00000000000000describe('security issues', function() { describe('GH-1495: Prevent Remote Code Execution via constructor', function() { it('should not allow constructors to be accessed', function() { expectTemplate('{{lookup (lookup this "constructor") "name"}}') .withInput({}) .toCompileTo(''); expectTemplate('{{constructor.name}}') .withInput({}) .toCompileTo(''); }); it('GH-1603: should not allow constructors to be accessed (lookup via toString)', function() { expectTemplate('{{lookup (lookup this (list "constructor")) "name"}}') .withInput({}) .withHelper('list', function(element) { return [element]; }) .toCompileTo(''); }); it('should allow the "constructor" property to be accessed if it is an "ownProperty"', function() { expectTemplate('{{constructor.name}}') .withInput({ constructor: { name: 'here we go' } }) .toCompileTo('here we go'); expectTemplate('{{lookup (lookup this "constructor") "name"}}') .withInput({ constructor: { name: 'here we go' } }) .toCompileTo('here we go'); }); it('should allow the "constructor" property to be accessed if it is an "own property"', function() { expectTemplate('{{lookup (lookup this "constructor") "name"}}') .withInput({ constructor: { name: 'here we go' } }) .toCompileTo('here we go'); }); }); describe('GH-1558: Prevent explicit call of helperMissing-helpers', function() { if (!Handlebars.compile) { return; } describe('without the option "allowExplicitCallOfHelperMissing"', function() { it('should throw an exception when calling "{{helperMissing}}" ', function() { expectTemplate('{{helperMissing}}').toThrow(Error); }); it('should throw an exception when calling "{{#helperMissing}}{{/helperMissing}}" ', function() { expectTemplate('{{#helperMissing}}{{/helperMissing}}').toThrow(Error); }); it('should throw an exception when calling "{{blockHelperMissing "abc" .}}" ', function() { var functionCalls = []; expect(function() { var template = Handlebars.compile('{{blockHelperMissing "abc" .}}'); template({ fn: function() { functionCalls.push('called'); } }); }).to.throw(Error); expect(functionCalls.length).to.equal(0); }); it('should throw an exception when calling "{{#blockHelperMissing .}}{{/blockHelperMissing}}"', function() { expectTemplate('{{#blockHelperMissing .}}{{/blockHelperMissing}}') .withInput({ fn: function() { return 'functionInData'; } }) .toThrow(Error); }); }); describe('with the option "allowCallsToHelperMissing" set to true', function() { it('should not throw an exception when calling "{{helperMissing}}" ', function() { var template = Handlebars.compile('{{helperMissing}}'); template({}, { allowCallsToHelperMissing: true }); }); it('should not throw an exception when calling "{{#helperMissing}}{{/helperMissing}}" ', function() { var template = Handlebars.compile( '{{#helperMissing}}{{/helperMissing}}' ); template({}, { allowCallsToHelperMissing: true }); }); it('should not throw an exception when calling "{{blockHelperMissing "abc" .}}" ', function() { var functionCalls = []; var template = Handlebars.compile('{{blockHelperMissing "abc" .}}'); template( { fn: function() { functionCalls.push('called'); } }, { allowCallsToHelperMissing: true } ); equals(functionCalls.length, 1); }); it('should not throw an exception when calling "{{#blockHelperMissing .}}{{/blockHelperMissing}}"', function() { var template = Handlebars.compile( '{{#blockHelperMissing true}}sdads{{/blockHelperMissing}}' ); template({}, { allowCallsToHelperMissing: true }); }); }); }); describe('GH-1563', function() { it('should not allow to access constructor after overriding via __defineGetter__', function() { if ({}.__defineGetter__ == null || {}.__lookupGetter__ == null) { return this.skip(); // Browser does not support this exploit anyway } expectTemplate( '{{__defineGetter__ "undefined" valueOf }}' + '{{#with __lookupGetter__ }}' + '{{__defineGetter__ "propertyIsEnumerable" (this.bind (this.bind 1)) }}' + '{{constructor.name}}' + '{{/with}}' ) .withInput({}) .toThrow(/Missing helper: "__defineGetter__"/); }); }); describe('GH-1595: dangerous properties', function() { var templates = [ '{{constructor}}', '{{__defineGetter__}}', '{{__defineSetter__}}', '{{__lookupGetter__}}', '{{__proto__}}', '{{lookup this "constructor"}}', '{{lookup this "__defineGetter__"}}', '{{lookup this "__defineSetter__"}}', '{{lookup this "__lookupGetter__"}}', '{{lookup this "__proto__"}}' ]; templates.forEach(function(template) { describe('access should be denied to ' + template, function() { it('by default', function() { expectTemplate(template) .withInput({}) .toCompileTo(''); }); it(' with proto-access enabled', function() { expectTemplate(template) .withInput({}) .withRuntimeOptions({ allowProtoPropertiesByDefault: true, allowProtoMethodsByDefault: true }) .toCompileTo(''); }); }); }); }); describe('GH-1631: disallow access to prototype functions', function() { function TestClass() {} TestClass.prototype.aProperty = 'propertyValue'; TestClass.prototype.aMethod = function() { return 'returnValue'; }; beforeEach(function() { handlebarsEnv.resetLoggedPropertyAccesses(); }); afterEach(function() { sinon.restore(); }); describe('control access to prototype methods via "allowedProtoMethods"', function() { checkProtoMethodAccess({}); describe('in compat mode', function() { checkProtoMethodAccess({ compat: true }); }); function checkProtoMethodAccess(compileOptions) { it('should be prohibited by default and log a warning', function() { var spy = sinon.spy(console, 'error'); expectTemplate('{{aMethod}}') .withInput(new TestClass()) .withCompileOptions(compileOptions) .toCompileTo(''); expect(spy.calledOnce).to.be.true(); expect(spy.args[0][0]).to.match(/Handlebars: Access has been denied/); }); it('should only log the warning once', function() { var spy = sinon.spy(console, 'error'); expectTemplate('{{aMethod}}') .withInput(new TestClass()) .withCompileOptions(compileOptions) .toCompileTo(''); expectTemplate('{{aMethod}}') .withInput(new TestClass()) .withCompileOptions(compileOptions) .toCompileTo(''); expect(spy.calledOnce).to.be.true(); expect(spy.args[0][0]).to.match(/Handlebars: Access has been denied/); }); it('can be allowed, which disables the warning', function() { var spy = sinon.spy(console, 'error'); expectTemplate('{{aMethod}}') .withInput(new TestClass()) .withCompileOptions(compileOptions) .withRuntimeOptions({ allowedProtoMethods: { aMethod: true } }) .toCompileTo('returnValue'); expect(spy.callCount).to.equal(0); }); it('can be turned on by default, which disables the warning', function() { var spy = sinon.spy(console, 'error'); expectTemplate('{{aMethod}}') .withInput(new TestClass()) .withCompileOptions(compileOptions) .withRuntimeOptions({ allowProtoMethodsByDefault: true }) .toCompileTo('returnValue'); expect(spy.callCount).to.equal(0); }); it('can be turned off by default, which disables the warning', function() { var spy = sinon.spy(console, 'error'); expectTemplate('{{aMethod}}') .withInput(new TestClass()) .withCompileOptions(compileOptions) .withRuntimeOptions({ allowProtoMethodsByDefault: false }) .toCompileTo(''); expect(spy.callCount).to.equal(0); }); it('can be turned off, if turned on by default', function() { expectTemplate('{{aMethod}}') .withInput(new TestClass()) .withCompileOptions(compileOptions) .withRuntimeOptions({ allowProtoMethodsByDefault: true, allowedProtoMethods: { aMethod: false } }) .toCompileTo(''); }); } it('should cause the recursive lookup by default (in "compat" mode)', function() { expectTemplate('{{#aString}}{{trim}}{{/aString}}') .withInput({ aString: ' abc ', trim: 'trim' }) .withCompileOptions({ compat: true }) .toCompileTo('trim'); }); it('should not cause the recursive lookup if allowed through options(in "compat" mode)', function() { expectTemplate('{{#aString}}{{trim}}{{/aString}}') .withInput({ aString: ' abc ', trim: 'trim' }) .withCompileOptions({ compat: true }) .withRuntimeOptions({ allowedProtoMethods: { trim: true } }) .toCompileTo('abc'); }); }); describe('control access to prototype non-methods via "allowedProtoProperties" and "allowProtoPropertiesByDefault', function() { checkProtoPropertyAccess({}); describe('in compat-mode', function() { checkProtoPropertyAccess({ compat: true }); }); describe('in strict-mode', function() { checkProtoPropertyAccess({ strict: true }); }); function checkProtoPropertyAccess(compileOptions) { it('should be prohibited by default and log a warning', function() { var spy = sinon.spy(console, 'error'); expectTemplate('{{aProperty}}') .withInput(new TestClass()) .withCompileOptions(compileOptions) .toCompileTo(''); expect(spy.calledOnce).to.be.true(); expect(spy.args[0][0]).to.match(/Handlebars: Access has been denied/); }); it('can be explicitly prohibited by default, which disables the warning', function() { var spy = sinon.spy(console, 'error'); expectTemplate('{{aProperty}}') .withInput(new TestClass()) .withCompileOptions(compileOptions) .withRuntimeOptions({ allowProtoPropertiesByDefault: false }) .toCompileTo(''); expect(spy.callCount).to.equal(0); }); it('can be turned on, which disables the warning', function() { var spy = sinon.spy(console, 'error'); expectTemplate('{{aProperty}}') .withInput(new TestClass()) .withCompileOptions(compileOptions) .withRuntimeOptions({ allowedProtoProperties: { aProperty: true } }) .toCompileTo('propertyValue'); expect(spy.callCount).to.equal(0); }); it('can be turned on by default, which disables the warning', function() { var spy = sinon.spy(console, 'error'); expectTemplate('{{aProperty}}') .withInput(new TestClass()) .withCompileOptions(compileOptions) .withRuntimeOptions({ allowProtoPropertiesByDefault: true }) .toCompileTo('propertyValue'); expect(spy.callCount).to.equal(0); }); it('can be turned off, if turned on by default', function() { expectTemplate('{{aProperty}}') .withInput(new TestClass()) .withCompileOptions(compileOptions) .withRuntimeOptions({ allowProtoPropertiesByDefault: true, allowedProtoProperties: { aProperty: false } }) .toCompileTo(''); }); } }); describe('compatibility with old runtimes, that do not provide the function "container.lookupProperty"', function() { beforeEach(function simulateRuntimeWithoutLookupProperty() { var oldTemplateMethod = handlebarsEnv.template; sinon.replace(handlebarsEnv, 'template', function(templateSpec) { templateSpec.main = wrapToAdjustContainer(templateSpec.main); return oldTemplateMethod.call(this, templateSpec); }); }); afterEach(function() { sinon.restore(); }); it('should work with simple properties', function() { expectTemplate('{{aProperty}}') .withInput({ aProperty: 'propertyValue' }) .toCompileTo('propertyValue'); }); it('should work with Array.prototype.length', function() { expectTemplate('{{anArray.length}}') .withInput({ anArray: ['a', 'b', 'c'] }) .toCompileTo('3'); }); }); }); describe('escapes template variables', function() { it('in compat mode', function() { expectTemplate("{{'a\\b'}}") .withCompileOptions({ compat: true }) .withInput({ 'a\\b': 'c' }) .toCompileTo('c'); }); it('in default mode', function() { expectTemplate("{{'a\\b'}}") .withCompileOptions() .withInput({ 'a\\b': 'c' }) .toCompileTo('c'); }); it('in default mode', function() { expectTemplate("{{'a\\b'}}") .withCompileOptions({ strict: true }) .withInput({ 'a\\b': 'c' }) .toCompileTo('c'); }); }); }); function wrapToAdjustContainer(precompiledTemplateFunction) { return function templateFunctionWrapper(container /*, more args */) { delete container.lookupProperty; return precompiledTemplateFunction.apply(this, arguments); }; } handlebars.js-4.7.7/spec/source-map.js000066400000000000000000000027351401244020700176130ustar00rootroot00000000000000try { if (typeof define !== 'function' || !define.amd) { var SourceMap = require('source-map'), SourceMapConsumer = SourceMap.SourceMapConsumer; } } catch (err) { /* NOP for in browser */ } describe('source-map', function() { if (!Handlebars.precompile || !SourceMap) { return; } it('should safely include source map info', function() { var template = Handlebars.precompile('{{hello}}', { destName: 'dest.js', srcName: 'src.hbs' }); equal(!!template.code, true); equal(!!template.map, !CompilerContext.browser); }); it('should map source properly', function() { var templateSource = ' b{{hello}} \n {{bar}}a {{#block arg hash=(subex 1 subval)}}{{/block}}', template = Handlebars.precompile(templateSource, { destName: 'dest.js', srcName: 'src.hbs' }); if (template.map) { var consumer = new SourceMapConsumer(template.map), lines = template.code.split('\n'), srcLines = templateSource.split('\n'), generated = grepLine('" b"', lines), source = grepLine(' b', srcLines); var mapped = consumer.originalPositionFor(generated); equal(mapped.line, source.line); equal(mapped.column, source.column); } }); }); function grepLine(token, lines) { for (var i = 0; i < lines.length; i++) { var column = lines[i].indexOf(token); if (column >= 0) { return { line: i + 1, column: column }; } } } handlebars.js-4.7.7/spec/spec.js000066400000000000000000000032461401244020700164700ustar00rootroot00000000000000describe('spec', function() { // NOP Under non-node environments if (typeof process === 'undefined') { return; } var _ = require('underscore'), fs = require('fs'); var specDir = __dirname + '/mustache/specs/'; var specs = _.filter(fs.readdirSync(specDir), function(name) { return /.*\.json$/.test(name); }); _.each(specs, function(name) { var spec = require(specDir + name); _.each(spec.tests, function(test) { // Our lambda implementation knowingly deviates from the optional Mustace lambda spec // We also do not support alternative delimeters if ( name === '~lambdas.json' || // We also choose to throw if paritals are not found (name === 'partials.json' && test.name === 'Failed Lookup') || // We nest the entire response from partials, not just the literals (name === 'partials.json' && test.name === 'Standalone Indentation') || /\{\{=/.test(test.template) || _.any(test.partials, function(partial) { return /\{\{=/.test(partial); }) ) { it.skip(name + ' - ' + test.name); return; } var data = _.clone(test.data); if (data.lambda) { // Blergh /* eslint-disable no-eval */ data.lambda = eval('(' + data.lambda.js + ')'); /* eslint-enable no-eval */ } it(name + ' - ' + test.name, function() { expectTemplate(test.template) .withInput(data) .withPartials(test.partials || {}) .withCompileOptions({ compat: true }) .withMessage(test.desc + ' "' + test.template + '"') .toCompileTo(test.expected); }); }); }); }); handlebars.js-4.7.7/spec/strict.js000066400000000000000000000121451401244020700170440ustar00rootroot00000000000000var Exception = Handlebars.Exception; describe('strict', function() { describe('strict mode', function() { it('should error on missing property lookup', function() { expectTemplate('{{hello}}') .withCompileOptions({ strict: true }) .toThrow(Exception, /"hello" not defined in/); }); it('should error on missing child', function() { expectTemplate('{{hello.bar}}') .withCompileOptions({ strict: true }) .withInput({ hello: { bar: 'foo' } }) .toCompileTo('foo'); expectTemplate('{{hello.bar}}') .withCompileOptions({ strict: true }) .withInput({ hello: {} }) .toThrow(Exception, /"bar" not defined in/); }); it('should handle explicit undefined', function() { expectTemplate('{{hello.bar}}') .withCompileOptions({ strict: true }) .withInput({ hello: { bar: undefined } }) .toCompileTo(''); }); it('should error on missing property lookup in known helpers mode', function() { expectTemplate('{{hello}}') .withCompileOptions({ strict: true, knownHelpersOnly: true }) .toThrow(Exception, /"hello" not defined in/); }); it('should error on missing context', function() { expectTemplate('{{hello}}') .withCompileOptions({ strict: true }) .toThrow(Error); }); it('should error on missing data lookup', function() { var xt = expectTemplate('{{@hello}}').withCompileOptions({ strict: true }); xt.toThrow(Error); xt.withRuntimeOptions({ data: { hello: 'foo' } }).toCompileTo('foo'); }); it('should not run helperMissing for helper calls', function() { expectTemplate('{{hello foo}}') .withCompileOptions({ strict: true }) .withInput({ foo: true }) .toThrow(Exception, /"hello" not defined in/); expectTemplate('{{#hello foo}}{{/hello}}') .withCompileOptions({ strict: true }) .withInput({ foo: true }) .toThrow(Exception, /"hello" not defined in/); }); it('should throw on ambiguous blocks', function() { expectTemplate('{{#hello}}{{/hello}}') .withCompileOptions({ strict: true }) .toThrow(Exception, /"hello" not defined in/); expectTemplate('{{^hello}}{{/hello}}') .withCompileOptions({ strict: true }) .toThrow(Exception, /"hello" not defined in/); expectTemplate('{{#hello.bar}}{{/hello.bar}}') .withCompileOptions({ strict: true }) .withInput({ hello: {} }) .toThrow(Exception, /"bar" not defined in/); }); it('should allow undefined parameters when passed to helpers', function() { expectTemplate('{{#unless foo}}success{{/unless}}') .withCompileOptions({ strict: true }) .toCompileTo('success'); }); it('should allow undefined hash when passed to helpers', function() { expectTemplate('{{helper value=@foo}}') .withCompileOptions({ strict: true }) .withHelpers({ helper: function(options) { equals('value' in options.hash, true); equals(options.hash.value, undefined); return 'success'; } }) .toCompileTo('success'); }); it('should show error location on missing property lookup', function() { expectTemplate('\n\n\n {{hello}}') .withCompileOptions({ strict: true }) .toThrow(Exception, '"hello" not defined in [object Object] - 4:5'); }); it('should error contains correct location properties on missing property lookup', function() { try { var template = CompilerContext.compile('\n\n\n {{hello}}', { strict: true }); template({}); } catch (error) { equals(error.lineNumber, 4); equals(error.endLineNumber, 4); equals(error.column, 5); equals(error.endColumn, 10); } }); }); describe('assume objects', function() { it('should ignore missing property', function() { expectTemplate('{{hello}}') .withCompileOptions({ assumeObjects: true }) .toCompileTo(''); }); it('should ignore missing child', function() { expectTemplate('{{hello.bar}}') .withCompileOptions({ assumeObjects: true }) .withInput({ hello: {} }) .toCompileTo(''); }); it('should error on missing object', function() { expectTemplate('{{hello.bar}}') .withCompileOptions({ assumeObjects: true }) .toThrow(Error); }); it('should error on missing context', function() { expectTemplate('{{hello}}') .withCompileOptions({ assumeObjects: true }) .withInput(undefined) .toThrow(Error); }); it('should error on missing data lookup', function() { expectTemplate('{{@hello.bar}}') .withCompileOptions({ assumeObjects: true }) .withInput(undefined) .toThrow(Error); }); it('should execute blockHelperMissing', function() { expectTemplate('{{^hello}}foo{{/hello}}') .withCompileOptions({ assumeObjects: true }) .toCompileTo('foo'); }); }); }); handlebars.js-4.7.7/spec/string-params.js000066400000000000000000000143411401244020700203230ustar00rootroot00000000000000describe('string params mode', function() { it('arguments to helpers can be retrieved from options hash in string form', function() { expectTemplate('{{wycats is.a slave.driver}}') .withCompileOptions({ stringParams: true }) .withHelpers({ wycats: function(passiveVoice, noun) { return 'HELP ME MY BOSS ' + passiveVoice + ' ' + noun; } }) .withMessage('String parameters output') .toCompileTo('HELP ME MY BOSS is.a slave.driver'); }); it('when using block form, arguments to helpers can be retrieved from options hash in string form', function() { expectTemplate('{{#wycats is.a slave.driver}}help :({{/wycats}}') .withCompileOptions({ stringParams: true }) .withHelpers({ wycats: function(passiveVoice, noun, options) { return ( 'HELP ME MY BOSS ' + passiveVoice + ' ' + noun + ': ' + options.fn(this) ); } }) .withMessage('String parameters output') .toCompileTo('HELP ME MY BOSS is.a slave.driver: help :('); }); it('when inside a block in String mode, .. passes the appropriate context in the options hash', function() { expectTemplate('{{#with dale}}{{tomdale ../need dad.joke}}{{/with}}') .withCompileOptions({ stringParams: true }) .withHelpers({ tomdale: function(desire, noun, options) { return ( 'STOP ME FROM READING HACKER NEWS I ' + options.contexts[0][desire] + ' ' + noun ); }, with: function(context, options) { return options.fn(options.contexts[0][context]); } }) .withInput({ dale: {}, need: 'need-a' }) .withMessage('Proper context variable output') .toCompileTo('STOP ME FROM READING HACKER NEWS I need-a dad.joke'); }); it('information about the types is passed along', function() { expectTemplate("{{tomdale 'need' dad.joke true false}}") .withCompileOptions({ stringParams: true }) .withHelpers({ tomdale: function(desire, noun, trueBool, falseBool, options) { equal(options.types[0], 'StringLiteral', 'the string type is passed'); equal( options.types[1], 'PathExpression', 'the expression type is passed' ); equal( options.types[2], 'BooleanLiteral', 'the expression type is passed' ); equal(desire, 'need', 'the string form is passed for strings'); equal(noun, 'dad.joke', 'the string form is passed for expressions'); equal(trueBool, true, 'raw booleans are passed through'); equal(falseBool, false, 'raw booleans are passed through'); return 'Helper called'; } }) .toCompileTo('Helper called'); }); it('hash parameters get type information', function() { expectTemplate("{{tomdale he.says desire='need' noun=dad.joke bool=true}}") .withCompileOptions({ stringParams: true }) .withHelpers({ tomdale: function(exclamation, options) { equal(exclamation, 'he.says'); equal(options.types[0], 'PathExpression'); equal(options.hashTypes.desire, 'StringLiteral'); equal(options.hashTypes.noun, 'PathExpression'); equal(options.hashTypes.bool, 'BooleanLiteral'); equal(options.hash.desire, 'need'); equal(options.hash.noun, 'dad.joke'); equal(options.hash.bool, true); return 'Helper called'; } }) .toCompileTo('Helper called'); }); it('hash parameters get context information', function() { var context = { dale: {} }; var helpers = { tomdale: function(exclamation, options) { equal(exclamation, 'he.says'); equal(options.types[0], 'PathExpression'); equal(options.contexts.length, 1); equal(options.hashContexts.noun, context); equal(options.hash.desire, 'need'); equal(options.hash.noun, 'dad.joke'); equal(options.hash.bool, true); return 'Helper called'; }, with: function(withContext, options) { return options.fn(options.contexts[0][withContext]); } }; expectTemplate( "{{#with dale}}{{tomdale he.says desire='need' noun=../dad/joke bool=true}}{{/with}}" ) .withCompileOptions({ stringParams: true }) .withHelpers(helpers) .withInput(context) .toCompileTo('Helper called'); }); it('when inside a block in String mode, .. passes the appropriate context in the options hash to a block helper', function() { expectTemplate( '{{#with dale}}{{#tomdale ../need dad.joke}}wot{{/tomdale}}{{/with}}' ) .withCompileOptions({ stringParams: true }) .withHelpers({ tomdale: function(desire, noun, options) { return ( 'STOP ME FROM READING HACKER NEWS I ' + options.contexts[0][desire] + ' ' + noun + ' ' + options.fn(this) ); }, with: function(context, options) { return options.fn(options.contexts[0][context]); } }) .withInput({ dale: {}, need: 'need-a' }) .withMessage('Proper context variable output') .toCompileTo('STOP ME FROM READING HACKER NEWS I need-a dad.joke wot'); }); it('with nested block ambiguous', function() { expectTemplate( '{{#with content}}{{#view}}{{firstName}} {{lastName}}{{/view}}{{/with}}' ) .withCompileOptions({ stringParams: true }) .withHelpers({ with: function() { return 'WITH'; }, view: function() { return 'VIEW'; } }) .toCompileTo('WITH'); }); it('should handle DATA', function() { expectTemplate('{{foo @bar}}') .withCompileOptions({ stringParams: true }) .withHelpers({ foo: function(bar, options) { equal(bar, '@bar'); equal(options.types[0], 'PathExpression'); return 'Foo!'; } }) .toCompileTo('Foo!'); }); }); handlebars.js-4.7.7/spec/subexpressions.js000066400000000000000000000165771401244020700206450ustar00rootroot00000000000000describe('subexpressions', function() { it('arg-less helper', function() { expectTemplate('{{foo (bar)}}!') .withHelpers({ foo: function(val) { return val + val; }, bar: function() { return 'LOL'; } }) .toCompileTo('LOLLOL!'); }); it('helper w args', function() { expectTemplate('{{blog (equal a b)}}') .withInput({ bar: 'LOL' }) .withHelpers({ blog: function(val) { return 'val is ' + val; }, equal: function(x, y) { return x === y; } }) .toCompileTo('val is true'); }); it('mixed paths and helpers', function() { expectTemplate('{{blog baz.bat (equal a b) baz.bar}}') .withInput({ bar: 'LOL', baz: { bat: 'foo!', bar: 'bar!' } }) .withHelpers({ blog: function(val, that, theOther) { return 'val is ' + val + ', ' + that + ' and ' + theOther; }, equal: function(x, y) { return x === y; } }) .toCompileTo('val is foo!, true and bar!'); }); it('supports much nesting', function() { expectTemplate('{{blog (equal (equal true true) true)}}') .withInput({ bar: 'LOL' }) .withHelpers({ blog: function(val) { return 'val is ' + val; }, equal: function(x, y) { return x === y; } }) .toCompileTo('val is true'); }); it('GH-800 : Complex subexpressions', function() { var context = { a: 'a', b: 'b', c: { c: 'c' }, d: 'd', e: { e: 'e' } }; var helpers = { dash: function(a, b) { return a + '-' + b; }, concat: function(a, b) { return a + b; } }; expectTemplate("{{dash 'abc' (concat a b)}}") .withInput(context) .withHelpers(helpers) .toCompileTo('abc-ab'); expectTemplate('{{dash d (concat a b)}}') .withInput(context) .withHelpers(helpers) .toCompileTo('d-ab'); expectTemplate('{{dash c.c (concat a b)}}') .withInput(context) .withHelpers(helpers) .toCompileTo('c-ab'); expectTemplate('{{dash (concat a b) c.c}}') .withInput(context) .withHelpers(helpers) .toCompileTo('ab-c'); expectTemplate('{{dash (concat a e.e) c.c}}') .withInput(context) .withHelpers(helpers) .toCompileTo('ae-c'); }); it('provides each nested helper invocation its own options hash', function() { var lastOptions = null; var helpers = { equal: function(x, y, options) { if (!options || options === lastOptions) { throw new Error('options hash was reused'); } lastOptions = options; return x === y; } }; expectTemplate('{{equal (equal true true) true}}') .withHelpers(helpers) .toCompileTo('true'); }); it('with hashes', function() { expectTemplate("{{blog (equal (equal true true) true fun='yes')}}") .withInput({ bar: 'LOL' }) .withHelpers({ blog: function(val) { return 'val is ' + val; }, equal: function(x, y) { return x === y; } }) .toCompileTo('val is true'); }); it('as hashes', function() { expectTemplate("{{blog fun=(equal (blog fun=1) 'val is 1')}}") .withHelpers({ blog: function(options) { return 'val is ' + options.hash.fun; }, equal: function(x, y) { return x === y; } }) .toCompileTo('val is true'); }); it('multiple subexpressions in a hash', function() { expectTemplate( '{{input aria-label=(t "Name") placeholder=(t "Example User")}}' ) .withHelpers({ input: function(options) { var hash = options.hash; var ariaLabel = Handlebars.Utils.escapeExpression(hash['aria-label']); var placeholder = Handlebars.Utils.escapeExpression(hash.placeholder); return new Handlebars.SafeString( '' ); }, t: function(defaultString) { return new Handlebars.SafeString(defaultString); } }) .toCompileTo(''); }); it('multiple subexpressions in a hash with context', function() { expectTemplate( '{{input aria-label=(t item.field) placeholder=(t item.placeholder)}}' ) .withInput({ item: { field: 'Name', placeholder: 'Example User' } }) .withHelpers({ input: function(options) { var hash = options.hash; var ariaLabel = Handlebars.Utils.escapeExpression(hash['aria-label']); var placeholder = Handlebars.Utils.escapeExpression(hash.placeholder); return new Handlebars.SafeString( '' ); }, t: function(defaultString) { return new Handlebars.SafeString(defaultString); } }) .toCompileTo(''); }); it('in string params mode,', function() { expectTemplate('{{snog (blorg foo x=y) yeah a=b}}') .withCompileOptions({ stringParams: true }) .withHelpers({ snog: function(a, b, options) { equals(a, 'foo'); equals( options.types.length, 2, 'string params for outer helper processed correctly' ); equals( options.types[0], 'SubExpression', 'string params for outer helper processed correctly' ); equals( options.types[1], 'PathExpression', 'string params for outer helper processed correctly' ); return a + b; }, blorg: function(a, options) { equals( options.types.length, 1, 'string params for inner helper processed correctly' ); equals( options.types[0], 'PathExpression', 'string params for inner helper processed correctly' ); return a; } }) .withInput({ foo: {}, yeah: {} }) .toCompileTo('fooyeah'); }); it('as hashes in string params mode', function() { expectTemplate('{{blog fun=(bork)}}') .withCompileOptions({ stringParams: true }) .withHelpers({ blog: function(options) { equals(options.hashTypes.fun, 'SubExpression'); return 'val is ' + options.hash.fun; }, bork: function() { return 'BORK'; } }) .toCompileTo('val is BORK'); }); it('subexpression functions on the context', function() { expectTemplate('{{foo (bar)}}!') .withInput({ bar: function() { return 'LOL'; } }) .withHelpers({ foo: function(val) { return val + val; } }) .toCompileTo('LOLLOL!'); }); it("subexpressions can't just be property lookups", function() { expectTemplate('{{foo (bar)}}!') .withInput({ bar: 'LOL' }) .withHelpers({ foo: function(val) { return val + val; } }) .toThrow(); }); }); handlebars.js-4.7.7/spec/tmp/000077500000000000000000000000001401244020700157735ustar00rootroot00000000000000handlebars.js-4.7.7/spec/tmp/.gitkeep000066400000000000000000000001361401244020700174240ustar00rootroot00000000000000This directory is ignored in .gitignore. It can be used to write temporary files during tests.handlebars.js-4.7.7/spec/tokenizer.js000066400000000000000000000501021401244020700175410ustar00rootroot00000000000000function shouldMatchTokens(result, tokens) { for (var index = 0; index < result.length; index++) { equals(result[index].name, tokens[index]); } } function shouldBeToken(result, name, text) { equals(result.name, name); equals(result.text, text); } describe('Tokenizer', function() { if (!Handlebars.Parser) { return; } function tokenize(template) { var parser = Handlebars.Parser, lexer = parser.lexer; lexer.setInput(template); var out = [], token; while ((token = lexer.lex())) { var result = parser.terminals_[token] || token; if (!result || result === 'EOF' || result === 'INVALID') { break; } out.push({ name: result, text: lexer.yytext }); } return out; } it('tokenizes a simple mustache as "OPEN ID CLOSE"', function() { var result = tokenize('{{foo}}'); shouldMatchTokens(result, ['OPEN', 'ID', 'CLOSE']); shouldBeToken(result[1], 'ID', 'foo'); }); it('supports unescaping with &', function() { var result = tokenize('{{&bar}}'); shouldMatchTokens(result, ['OPEN', 'ID', 'CLOSE']); shouldBeToken(result[0], 'OPEN', '{{&'); shouldBeToken(result[1], 'ID', 'bar'); }); it('supports unescaping with {{{', function() { var result = tokenize('{{{bar}}}'); shouldMatchTokens(result, ['OPEN_UNESCAPED', 'ID', 'CLOSE_UNESCAPED']); shouldBeToken(result[1], 'ID', 'bar'); }); it('supports escaping delimiters', function() { var result = tokenize('{{foo}} \\{{bar}} {{baz}}'); shouldMatchTokens(result, [ 'OPEN', 'ID', 'CLOSE', 'CONTENT', 'CONTENT', 'OPEN', 'ID', 'CLOSE' ]); shouldBeToken(result[3], 'CONTENT', ' '); shouldBeToken(result[4], 'CONTENT', '{{bar}} '); }); it('supports escaping multiple delimiters', function() { var result = tokenize('{{foo}} \\{{bar}} \\{{baz}}'); shouldMatchTokens(result, [ 'OPEN', 'ID', 'CLOSE', 'CONTENT', 'CONTENT', 'CONTENT' ]); shouldBeToken(result[3], 'CONTENT', ' '); shouldBeToken(result[4], 'CONTENT', '{{bar}} '); shouldBeToken(result[5], 'CONTENT', '{{baz}}'); }); it('supports escaping a triple stash', function() { var result = tokenize('{{foo}} \\{{{bar}}} {{baz}}'); shouldMatchTokens(result, [ 'OPEN', 'ID', 'CLOSE', 'CONTENT', 'CONTENT', 'OPEN', 'ID', 'CLOSE' ]); shouldBeToken(result[4], 'CONTENT', '{{{bar}}} '); }); it('supports escaping escape character', function() { var result = tokenize('{{foo}} \\\\{{bar}} {{baz}}'); shouldMatchTokens(result, [ 'OPEN', 'ID', 'CLOSE', 'CONTENT', 'OPEN', 'ID', 'CLOSE', 'CONTENT', 'OPEN', 'ID', 'CLOSE' ]); shouldBeToken(result[3], 'CONTENT', ' \\'); shouldBeToken(result[5], 'ID', 'bar'); }); it('supports escaping multiple escape characters', function() { var result = tokenize('{{foo}} \\\\{{bar}} \\\\{{baz}}'); shouldMatchTokens(result, [ 'OPEN', 'ID', 'CLOSE', 'CONTENT', 'OPEN', 'ID', 'CLOSE', 'CONTENT', 'OPEN', 'ID', 'CLOSE' ]); shouldBeToken(result[3], 'CONTENT', ' \\'); shouldBeToken(result[5], 'ID', 'bar'); shouldBeToken(result[7], 'CONTENT', ' \\'); shouldBeToken(result[9], 'ID', 'baz'); }); it('supports escaped mustaches after escaped escape characters', function() { var result = tokenize('{{foo}} \\\\{{bar}} \\{{baz}}'); shouldMatchTokens(result, [ 'OPEN', 'ID', 'CLOSE', 'CONTENT', 'OPEN', 'ID', 'CLOSE', 'CONTENT', 'CONTENT', 'CONTENT' ]); shouldBeToken(result[3], 'CONTENT', ' \\'); shouldBeToken(result[4], 'OPEN', '{{'); shouldBeToken(result[5], 'ID', 'bar'); shouldBeToken(result[7], 'CONTENT', ' '); shouldBeToken(result[8], 'CONTENT', '{{baz}}'); }); it('supports escaped escape characters after escaped mustaches', function() { var result = tokenize('{{foo}} \\{{bar}} \\\\{{baz}}'); shouldMatchTokens(result, [ 'OPEN', 'ID', 'CLOSE', 'CONTENT', 'CONTENT', 'CONTENT', 'OPEN', 'ID', 'CLOSE' ]); shouldBeToken(result[4], 'CONTENT', '{{bar}} '); shouldBeToken(result[5], 'CONTENT', '\\'); shouldBeToken(result[6], 'OPEN', '{{'); shouldBeToken(result[7], 'ID', 'baz'); }); it('supports escaped escape character on a triple stash', function() { var result = tokenize('{{foo}} \\\\{{{bar}}} {{baz}}'); shouldMatchTokens(result, [ 'OPEN', 'ID', 'CLOSE', 'CONTENT', 'OPEN_UNESCAPED', 'ID', 'CLOSE_UNESCAPED', 'CONTENT', 'OPEN', 'ID', 'CLOSE' ]); shouldBeToken(result[3], 'CONTENT', ' \\'); shouldBeToken(result[5], 'ID', 'bar'); }); it('tokenizes a simple path', function() { var result = tokenize('{{foo/bar}}'); shouldMatchTokens(result, ['OPEN', 'ID', 'SEP', 'ID', 'CLOSE']); }); it('allows dot notation', function() { var result = tokenize('{{foo.bar}}'); shouldMatchTokens(result, ['OPEN', 'ID', 'SEP', 'ID', 'CLOSE']); shouldMatchTokens(tokenize('{{foo.bar.baz}}'), [ 'OPEN', 'ID', 'SEP', 'ID', 'SEP', 'ID', 'CLOSE' ]); }); it('allows path literals with []', function() { var result = tokenize('{{foo.[bar]}}'); shouldMatchTokens(result, ['OPEN', 'ID', 'SEP', 'ID', 'CLOSE']); }); it('allows multiple path literals on a line with []', function() { var result = tokenize('{{foo.[bar]}}{{foo.[baz]}}'); shouldMatchTokens(result, [ 'OPEN', 'ID', 'SEP', 'ID', 'CLOSE', 'OPEN', 'ID', 'SEP', 'ID', 'CLOSE' ]); }); it('allows escaped literals in []', function() { var result = tokenize('{{foo.[bar\\]]}}'); shouldMatchTokens(result, ['OPEN', 'ID', 'SEP', 'ID', 'CLOSE']); }); it('tokenizes {{.}} as OPEN ID CLOSE', function() { var result = tokenize('{{.}}'); shouldMatchTokens(result, ['OPEN', 'ID', 'CLOSE']); }); it('tokenizes a path as "OPEN (ID SEP)* ID CLOSE"', function() { var result = tokenize('{{../foo/bar}}'); shouldMatchTokens(result, [ 'OPEN', 'ID', 'SEP', 'ID', 'SEP', 'ID', 'CLOSE' ]); shouldBeToken(result[1], 'ID', '..'); }); it('tokenizes a path with .. as a parent path', function() { var result = tokenize('{{../foo.bar}}'); shouldMatchTokens(result, [ 'OPEN', 'ID', 'SEP', 'ID', 'SEP', 'ID', 'CLOSE' ]); shouldBeToken(result[1], 'ID', '..'); }); it('tokenizes a path with this/foo as OPEN ID SEP ID CLOSE', function() { var result = tokenize('{{this/foo}}'); shouldMatchTokens(result, ['OPEN', 'ID', 'SEP', 'ID', 'CLOSE']); shouldBeToken(result[1], 'ID', 'this'); shouldBeToken(result[3], 'ID', 'foo'); }); it('tokenizes a simple mustache with spaces as "OPEN ID CLOSE"', function() { var result = tokenize('{{ foo }}'); shouldMatchTokens(result, ['OPEN', 'ID', 'CLOSE']); shouldBeToken(result[1], 'ID', 'foo'); }); it('tokenizes a simple mustache with line breaks as "OPEN ID ID CLOSE"', function() { var result = tokenize('{{ foo \n bar }}'); shouldMatchTokens(result, ['OPEN', 'ID', 'ID', 'CLOSE']); shouldBeToken(result[1], 'ID', 'foo'); }); it('tokenizes raw content as "CONTENT"', function() { var result = tokenize('foo {{ bar }} baz'); shouldMatchTokens(result, ['CONTENT', 'OPEN', 'ID', 'CLOSE', 'CONTENT']); shouldBeToken(result[0], 'CONTENT', 'foo '); shouldBeToken(result[4], 'CONTENT', ' baz'); }); it('tokenizes a partial as "OPEN_PARTIAL ID CLOSE"', function() { var result = tokenize('{{> foo}}'); shouldMatchTokens(result, ['OPEN_PARTIAL', 'ID', 'CLOSE']); }); it('tokenizes a partial with context as "OPEN_PARTIAL ID ID CLOSE"', function() { var result = tokenize('{{> foo bar }}'); shouldMatchTokens(result, ['OPEN_PARTIAL', 'ID', 'ID', 'CLOSE']); }); it('tokenizes a partial without spaces as "OPEN_PARTIAL ID CLOSE"', function() { var result = tokenize('{{>foo}}'); shouldMatchTokens(result, ['OPEN_PARTIAL', 'ID', 'CLOSE']); }); it('tokenizes a partial space at the }); as "OPEN_PARTIAL ID CLOSE"', function() { var result = tokenize('{{>foo }}'); shouldMatchTokens(result, ['OPEN_PARTIAL', 'ID', 'CLOSE']); }); it('tokenizes a partial space at the }); as "OPEN_PARTIAL ID CLOSE"', function() { var result = tokenize('{{>foo/bar.baz }}'); shouldMatchTokens(result, [ 'OPEN_PARTIAL', 'ID', 'SEP', 'ID', 'SEP', 'ID', 'CLOSE' ]); }); it('tokenizes partial block declarations', function() { var result = tokenize('{{#> foo}}'); shouldMatchTokens(result, ['OPEN_PARTIAL_BLOCK', 'ID', 'CLOSE']); }); it('tokenizes a comment as "COMMENT"', function() { var result = tokenize('foo {{! this is a comment }} bar {{ baz }}'); shouldMatchTokens(result, [ 'CONTENT', 'COMMENT', 'CONTENT', 'OPEN', 'ID', 'CLOSE' ]); shouldBeToken(result[1], 'COMMENT', '{{! this is a comment }}'); }); it('tokenizes a block comment as "COMMENT"', function() { var result = tokenize('foo {{!-- this is a {{comment}} --}} bar {{ baz }}'); shouldMatchTokens(result, [ 'CONTENT', 'COMMENT', 'CONTENT', 'OPEN', 'ID', 'CLOSE' ]); shouldBeToken(result[1], 'COMMENT', '{{!-- this is a {{comment}} --}}'); }); it('tokenizes a block comment with whitespace as "COMMENT"', function() { var result = tokenize( 'foo {{!-- this is a\n{{comment}}\n--}} bar {{ baz }}' ); shouldMatchTokens(result, [ 'CONTENT', 'COMMENT', 'CONTENT', 'OPEN', 'ID', 'CLOSE' ]); shouldBeToken(result[1], 'COMMENT', '{{!-- this is a\n{{comment}}\n--}}'); }); it('tokenizes open and closing blocks as OPEN_BLOCK, ID, CLOSE ..., OPEN_ENDBLOCK ID CLOSE', function() { var result = tokenize('{{#foo}}content{{/foo}}'); shouldMatchTokens(result, [ 'OPEN_BLOCK', 'ID', 'CLOSE', 'CONTENT', 'OPEN_ENDBLOCK', 'ID', 'CLOSE' ]); }); it('tokenizes directives', function() { shouldMatchTokens(tokenize('{{#*foo}}content{{/foo}}'), [ 'OPEN_BLOCK', 'ID', 'CLOSE', 'CONTENT', 'OPEN_ENDBLOCK', 'ID', 'CLOSE' ]); shouldMatchTokens(tokenize('{{*foo}}'), ['OPEN', 'ID', 'CLOSE']); }); it('tokenizes inverse sections as "INVERSE"', function() { shouldMatchTokens(tokenize('{{^}}'), ['INVERSE']); shouldMatchTokens(tokenize('{{else}}'), ['INVERSE']); shouldMatchTokens(tokenize('{{ else }}'), ['INVERSE']); }); it('tokenizes inverse sections with ID as "OPEN_INVERSE ID CLOSE"', function() { var result = tokenize('{{^foo}}'); shouldMatchTokens(result, ['OPEN_INVERSE', 'ID', 'CLOSE']); shouldBeToken(result[1], 'ID', 'foo'); }); it('tokenizes inverse sections with ID and spaces as "OPEN_INVERSE ID CLOSE"', function() { var result = tokenize('{{^ foo }}'); shouldMatchTokens(result, ['OPEN_INVERSE', 'ID', 'CLOSE']); shouldBeToken(result[1], 'ID', 'foo'); }); it('tokenizes mustaches with params as "OPEN ID ID ID CLOSE"', function() { var result = tokenize('{{ foo bar baz }}'); shouldMatchTokens(result, ['OPEN', 'ID', 'ID', 'ID', 'CLOSE']); shouldBeToken(result[1], 'ID', 'foo'); shouldBeToken(result[2], 'ID', 'bar'); shouldBeToken(result[3], 'ID', 'baz'); }); it('tokenizes mustaches with String params as "OPEN ID ID STRING CLOSE"', function() { var result = tokenize('{{ foo bar "baz" }}'); shouldMatchTokens(result, ['OPEN', 'ID', 'ID', 'STRING', 'CLOSE']); shouldBeToken(result[3], 'STRING', 'baz'); }); it('tokenizes mustaches with String params using single quotes as "OPEN ID ID STRING CLOSE"', function() { var result = tokenize("{{ foo bar 'baz' }}"); shouldMatchTokens(result, ['OPEN', 'ID', 'ID', 'STRING', 'CLOSE']); shouldBeToken(result[3], 'STRING', 'baz'); }); it('tokenizes String params with spaces inside as "STRING"', function() { var result = tokenize('{{ foo bar "baz bat" }}'); shouldMatchTokens(result, ['OPEN', 'ID', 'ID', 'STRING', 'CLOSE']); shouldBeToken(result[3], 'STRING', 'baz bat'); }); it('tokenizes String params with escapes quotes as STRING', function() { var result = tokenize('{{ foo "bar\\"baz" }}'); shouldMatchTokens(result, ['OPEN', 'ID', 'STRING', 'CLOSE']); shouldBeToken(result[2], 'STRING', 'bar"baz'); }); it('tokenizes String params using single quotes with escapes quotes as STRING', function() { var result = tokenize("{{ foo 'bar\\'baz' }}"); shouldMatchTokens(result, ['OPEN', 'ID', 'STRING', 'CLOSE']); shouldBeToken(result[2], 'STRING', "bar'baz"); }); it('tokenizes numbers', function() { var result = tokenize('{{ foo 1 }}'); shouldMatchTokens(result, ['OPEN', 'ID', 'NUMBER', 'CLOSE']); shouldBeToken(result[2], 'NUMBER', '1'); result = tokenize('{{ foo 1.1 }}'); shouldMatchTokens(result, ['OPEN', 'ID', 'NUMBER', 'CLOSE']); shouldBeToken(result[2], 'NUMBER', '1.1'); result = tokenize('{{ foo -1 }}'); shouldMatchTokens(result, ['OPEN', 'ID', 'NUMBER', 'CLOSE']); shouldBeToken(result[2], 'NUMBER', '-1'); result = tokenize('{{ foo -1.1 }}'); shouldMatchTokens(result, ['OPEN', 'ID', 'NUMBER', 'CLOSE']); shouldBeToken(result[2], 'NUMBER', '-1.1'); }); it('tokenizes booleans', function() { var result = tokenize('{{ foo true }}'); shouldMatchTokens(result, ['OPEN', 'ID', 'BOOLEAN', 'CLOSE']); shouldBeToken(result[2], 'BOOLEAN', 'true'); result = tokenize('{{ foo false }}'); shouldMatchTokens(result, ['OPEN', 'ID', 'BOOLEAN', 'CLOSE']); shouldBeToken(result[2], 'BOOLEAN', 'false'); }); it('tokenizes undefined and null', function() { var result = tokenize('{{ foo undefined null }}'); shouldMatchTokens(result, ['OPEN', 'ID', 'UNDEFINED', 'NULL', 'CLOSE']); shouldBeToken(result[2], 'UNDEFINED', 'undefined'); shouldBeToken(result[3], 'NULL', 'null'); }); it('tokenizes hash arguments', function() { var result = tokenize('{{ foo bar=baz }}'); shouldMatchTokens(result, ['OPEN', 'ID', 'ID', 'EQUALS', 'ID', 'CLOSE']); result = tokenize('{{ foo bar baz=bat }}'); shouldMatchTokens(result, [ 'OPEN', 'ID', 'ID', 'ID', 'EQUALS', 'ID', 'CLOSE' ]); result = tokenize('{{ foo bar baz=1 }}'); shouldMatchTokens(result, [ 'OPEN', 'ID', 'ID', 'ID', 'EQUALS', 'NUMBER', 'CLOSE' ]); result = tokenize('{{ foo bar baz=true }}'); shouldMatchTokens(result, [ 'OPEN', 'ID', 'ID', 'ID', 'EQUALS', 'BOOLEAN', 'CLOSE' ]); result = tokenize('{{ foo bar baz=false }}'); shouldMatchTokens(result, [ 'OPEN', 'ID', 'ID', 'ID', 'EQUALS', 'BOOLEAN', 'CLOSE' ]); result = tokenize('{{ foo bar\n baz=bat }}'); shouldMatchTokens(result, [ 'OPEN', 'ID', 'ID', 'ID', 'EQUALS', 'ID', 'CLOSE' ]); result = tokenize('{{ foo bar baz="bat" }}'); shouldMatchTokens(result, [ 'OPEN', 'ID', 'ID', 'ID', 'EQUALS', 'STRING', 'CLOSE' ]); result = tokenize('{{ foo bar baz="bat" bam=wot }}'); shouldMatchTokens(result, [ 'OPEN', 'ID', 'ID', 'ID', 'EQUALS', 'STRING', 'ID', 'EQUALS', 'ID', 'CLOSE' ]); result = tokenize('{{foo omg bar=baz bat="bam"}}'); shouldMatchTokens(result, [ 'OPEN', 'ID', 'ID', 'ID', 'EQUALS', 'ID', 'ID', 'EQUALS', 'STRING', 'CLOSE' ]); shouldBeToken(result[2], 'ID', 'omg'); }); it('tokenizes special @ identifiers', function() { var result = tokenize('{{ @foo }}'); shouldMatchTokens(result, ['OPEN', 'DATA', 'ID', 'CLOSE']); shouldBeToken(result[2], 'ID', 'foo'); result = tokenize('{{ foo @bar }}'); shouldMatchTokens(result, ['OPEN', 'ID', 'DATA', 'ID', 'CLOSE']); shouldBeToken(result[3], 'ID', 'bar'); result = tokenize('{{ foo bar=@baz }}'); shouldMatchTokens(result, [ 'OPEN', 'ID', 'ID', 'EQUALS', 'DATA', 'ID', 'CLOSE' ]); shouldBeToken(result[5], 'ID', 'baz'); }); it('does not time out in a mustache with a single } followed by EOF', function() { shouldMatchTokens(tokenize('{{foo}'), ['OPEN', 'ID']); }); it('does not time out in a mustache when invalid ID characters are used', function() { shouldMatchTokens(tokenize('{{foo & }}'), ['OPEN', 'ID']); }); it('tokenizes subexpressions', function() { var result = tokenize('{{foo (bar)}}'); shouldMatchTokens(result, [ 'OPEN', 'ID', 'OPEN_SEXPR', 'ID', 'CLOSE_SEXPR', 'CLOSE' ]); shouldBeToken(result[1], 'ID', 'foo'); shouldBeToken(result[3], 'ID', 'bar'); result = tokenize('{{foo (a-x b-y)}}'); shouldMatchTokens(result, [ 'OPEN', 'ID', 'OPEN_SEXPR', 'ID', 'ID', 'CLOSE_SEXPR', 'CLOSE' ]); shouldBeToken(result[1], 'ID', 'foo'); shouldBeToken(result[3], 'ID', 'a-x'); shouldBeToken(result[4], 'ID', 'b-y'); }); it('tokenizes nested subexpressions', function() { var result = tokenize('{{foo (bar (lol rofl)) (baz)}}'); shouldMatchTokens(result, [ 'OPEN', 'ID', 'OPEN_SEXPR', 'ID', 'OPEN_SEXPR', 'ID', 'ID', 'CLOSE_SEXPR', 'CLOSE_SEXPR', 'OPEN_SEXPR', 'ID', 'CLOSE_SEXPR', 'CLOSE' ]); shouldBeToken(result[3], 'ID', 'bar'); shouldBeToken(result[5], 'ID', 'lol'); shouldBeToken(result[6], 'ID', 'rofl'); shouldBeToken(result[10], 'ID', 'baz'); }); it('tokenizes nested subexpressions: literals', function() { var result = tokenize( '{{foo (bar (lol true) false) (baz 1) (blah \'b\') (blorg "c")}}' ); shouldMatchTokens(result, [ 'OPEN', 'ID', 'OPEN_SEXPR', 'ID', 'OPEN_SEXPR', 'ID', 'BOOLEAN', 'CLOSE_SEXPR', 'BOOLEAN', 'CLOSE_SEXPR', 'OPEN_SEXPR', 'ID', 'NUMBER', 'CLOSE_SEXPR', 'OPEN_SEXPR', 'ID', 'STRING', 'CLOSE_SEXPR', 'OPEN_SEXPR', 'ID', 'STRING', 'CLOSE_SEXPR', 'CLOSE' ]); }); it('tokenizes block params', function() { var result = tokenize('{{#foo as |bar|}}'); shouldMatchTokens(result, [ 'OPEN_BLOCK', 'ID', 'OPEN_BLOCK_PARAMS', 'ID', 'CLOSE_BLOCK_PARAMS', 'CLOSE' ]); result = tokenize('{{#foo as |bar baz|}}'); shouldMatchTokens(result, [ 'OPEN_BLOCK', 'ID', 'OPEN_BLOCK_PARAMS', 'ID', 'ID', 'CLOSE_BLOCK_PARAMS', 'CLOSE' ]); result = tokenize('{{#foo as | bar baz |}}'); shouldMatchTokens(result, [ 'OPEN_BLOCK', 'ID', 'OPEN_BLOCK_PARAMS', 'ID', 'ID', 'CLOSE_BLOCK_PARAMS', 'CLOSE' ]); result = tokenize('{{#foo as as | bar baz |}}'); shouldMatchTokens(result, [ 'OPEN_BLOCK', 'ID', 'ID', 'OPEN_BLOCK_PARAMS', 'ID', 'ID', 'CLOSE_BLOCK_PARAMS', 'CLOSE' ]); result = tokenize('{{else foo as |bar baz|}}'); shouldMatchTokens(result, [ 'OPEN_INVERSE_CHAIN', 'ID', 'OPEN_BLOCK_PARAMS', 'ID', 'ID', 'CLOSE_BLOCK_PARAMS', 'CLOSE' ]); }); it('tokenizes raw blocks', function() { var result = tokenize( '{{{{a}}}} abc {{{{/a}}}} aaa {{{{a}}}} abc {{{{/a}}}}' ); shouldMatchTokens(result, [ 'OPEN_RAW_BLOCK', 'ID', 'CLOSE_RAW_BLOCK', 'CONTENT', 'END_RAW_BLOCK', 'CONTENT', 'OPEN_RAW_BLOCK', 'ID', 'CLOSE_RAW_BLOCK', 'CONTENT', 'END_RAW_BLOCK' ]); }); }); handlebars.js-4.7.7/spec/track-ids.js000066400000000000000000000253201401244020700174140ustar00rootroot00000000000000describe('track ids', function() { var context; beforeEach(function() { context = { is: { a: 'foo' }, slave: { driver: 'bar' } }; }); it('should not include anything without the flag', function() { expectTemplate('{{wycats is.a slave.driver}}') .withHelpers({ wycats: function(passiveVoice, noun, options) { equal(options.ids, undefined); equal(options.hashIds, undefined); return 'success'; } }) .toCompileTo('success'); }); it('should include argument ids', function() { expectTemplate('{{wycats is.a slave.driver}}') .withCompileOptions({ trackIds: true }) .withHelpers({ wycats: function(passiveVoice, noun, options) { equal(options.ids[0], 'is.a'); equal(options.ids[1], 'slave.driver'); return ( 'HELP ME MY BOSS ' + options.ids[0] + ':' + passiveVoice + ' ' + options.ids[1] + ':' + noun ); } }) .withInput(context) .toCompileTo('HELP ME MY BOSS is.a:foo slave.driver:bar'); }); it('should include hash ids', function() { expectTemplate('{{wycats bat=is.a baz=slave.driver}}') .withCompileOptions({ trackIds: true }) .withHelpers({ wycats: function(options) { equal(options.hashIds.bat, 'is.a'); equal(options.hashIds.baz, 'slave.driver'); return ( 'HELP ME MY BOSS ' + options.hashIds.bat + ':' + options.hash.bat + ' ' + options.hashIds.baz + ':' + options.hash.baz ); } }) .withInput(context) .toCompileTo('HELP ME MY BOSS is.a:foo slave.driver:bar'); }); it('should note ../ and ./ references', function() { expectTemplate('{{wycats ./is.a ../slave.driver this.is.a this}}') .withCompileOptions({ trackIds: true }) .withHelpers({ wycats: function(passiveVoice, noun, thiz, thiz2, options) { equal(options.ids[0], 'is.a'); equal(options.ids[1], '../slave.driver'); equal(options.ids[2], 'is.a'); equal(options.ids[3], ''); return ( 'HELP ME MY BOSS ' + options.ids[0] + ':' + passiveVoice + ' ' + options.ids[1] + ':' + noun ); } }) .withInput(context) .toCompileTo('HELP ME MY BOSS is.a:foo ../slave.driver:undefined'); }); it('should note @data references', function() { expectTemplate('{{wycats @is.a @slave.driver}}') .withCompileOptions({ trackIds: true }) .withHelpers({ wycats: function(passiveVoice, noun, options) { equal(options.ids[0], '@is.a'); equal(options.ids[1], '@slave.driver'); return ( 'HELP ME MY BOSS ' + options.ids[0] + ':' + passiveVoice + ' ' + options.ids[1] + ':' + noun ); } }) .withRuntimeOptions({ data: context }) .toCompileTo('HELP ME MY BOSS @is.a:foo @slave.driver:bar'); }); it('should return null for constants', function() { expectTemplate('{{wycats 1 "foo" key=false}}') .withCompileOptions({ trackIds: true }) .withHelpers({ wycats: function(passiveVoice, noun, options) { equal(options.ids[0], null); equal(options.ids[1], null); equal(options.hashIds.key, null); return ( 'HELP ME MY BOSS ' + passiveVoice + ' ' + noun + ' ' + options.hash.key ); } }) .withInput(context) .toCompileTo('HELP ME MY BOSS 1 foo false'); }); it('should return true for subexpressions', function() { expectTemplate('{{wycats (sub)}}') .withCompileOptions({ trackIds: true }) .withHelpers({ sub: function() { return 1; }, wycats: function(passiveVoice, options) { equal(options.ids[0], true); return 'HELP ME MY BOSS ' + passiveVoice; } }) .withInput(context) .toCompileTo('HELP ME MY BOSS 1'); }); it('should use block param paths', function() { expectTemplate('{{#doIt as |is|}}{{wycats is.a slave.driver is}}{{/doIt}}') .withCompileOptions({ trackIds: true }) .withHelpers({ doIt: function(options) { var blockParams = [this.is]; blockParams.path = ['zomg']; return options.fn(this, { blockParams: blockParams }); }, wycats: function(passiveVoice, noun, blah, options) { equal(options.ids[0], 'zomg.a'); equal(options.ids[1], 'slave.driver'); equal(options.ids[2], 'zomg'); return ( 'HELP ME MY BOSS ' + options.ids[0] + ':' + passiveVoice + ' ' + options.ids[1] + ':' + noun ); } }) .withInput(context) .toCompileTo('HELP ME MY BOSS zomg.a:foo slave.driver:bar'); }); describe('builtin helpers', function() { var helpers = { blockParams: function(name, options) { return name + ':' + options.ids[0] + '\n'; }, wycats: function(name, options) { return name + ':' + options.data.contextPath + '\n'; } }; describe('#each', function() { it('should track contextPath for arrays', function() { expectTemplate('{{#each array}}{{wycats name}}{{/each}}') .withCompileOptions({ trackIds: true }) .withHelpers(helpers) .withInput({ array: [{ name: 'foo' }, { name: 'bar' }] }) .toCompileTo('foo:array.0\nbar:array.1\n'); }); it('should track contextPath for keys', function() { expectTemplate('{{#each object}}{{wycats name}}{{/each}}') .withCompileOptions({ trackIds: true }) .withHelpers(helpers) .withInput({ object: { foo: { name: 'foo' }, bar: { name: 'bar' } } }) .toCompileTo('foo:object.foo\nbar:object.bar\n'); }); it('should handle nesting', function() { expectTemplate( '{{#each .}}{{#each .}}{{wycats name}}{{/each}}{{/each}}' ) .withCompileOptions({ trackIds: true }) .withHelpers(helpers) .withInput({ array: [{ name: 'foo' }, { name: 'bar' }] }) .toCompileTo('foo:.array..0\nbar:.array..1\n'); }); it('should handle block params', function() { expectTemplate( '{{#each array as |value|}}{{blockParams value.name}}{{/each}}' ) .withCompileOptions({ trackIds: true }) .withHelpers(helpers) .withInput({ array: [{ name: 'foo' }, { name: 'bar' }] }) .toCompileTo('foo:array.0.name\nbar:array.1.name\n'); }); }); describe('#with', function() { it('should track contextPath', function() { expectTemplate('{{#with field}}{{wycats name}}{{/with}}') .withCompileOptions({ trackIds: true }) .withHelpers(helpers) .withInput({ field: { name: 'foo' } }) .toCompileTo('foo:field\n'); }); it('should handle nesting', function() { expectTemplate( '{{#with bat}}{{#with field}}{{wycats name}}{{/with}}{{/with}}' ) .withCompileOptions({ trackIds: true }) .withHelpers(helpers) .withInput({ bat: { field: { name: 'foo' } } }) .toCompileTo('foo:bat.field\n'); }); }); describe('#blockHelperMissing', function() { it('should track contextPath for arrays', function() { expectTemplate('{{#field}}{{wycats name}}{{/field}}') .withCompileOptions({ trackIds: true }) .withHelpers(helpers) .withInput({ field: [{ name: 'foo' }] }) .toCompileTo('foo:field.0\n'); }); it('should track contextPath for keys', function() { expectTemplate('{{#field}}{{wycats name}}{{/field}}') .withCompileOptions({ trackIds: true }) .withHelpers(helpers) .withInput({ field: { name: 'foo' } }) .toCompileTo('foo:field\n'); }); it('should handle nesting', function() { expectTemplate('{{#bat}}{{#field}}{{wycats name}}{{/field}}{{/bat}}') .withCompileOptions({ trackIds: true }) .withHelpers(helpers) .withInput({ bat: { field: { name: 'foo' } } }) .toCompileTo('foo:bat.field\n'); }); }); }); describe('partials', function() { var helpers = { blockParams: function(name, options) { return name + ':' + options.ids[0] + '\n'; }, wycats: function(name, options) { return name + ':' + options.data.contextPath + '\n'; } }; it('should pass track id for basic partial', function() { var template = CompilerContext.compile( 'Dudes: {{#dudes}}{{> dude}}{{/dudes}}', { trackIds: true } ), hash = { dudes: [ { name: 'Yehuda', url: 'http://yehuda' }, { name: 'Alan', url: 'http://alan' } ] }; var partials = { dude: CompilerContext.compile('{{wycats name}}', { trackIds: true }) }; equals( template(hash, { helpers: helpers, partials: partials }), 'Dudes: Yehuda:dudes.0\nAlan:dudes.1\n' ); }); it('should pass track id for context partial', function() { var template = CompilerContext.compile('Dudes: {{> dude dudes}}', { trackIds: true }), hash = { dudes: [ { name: 'Yehuda', url: 'http://yehuda' }, { name: 'Alan', url: 'http://alan' } ] }; var partials = { dude: CompilerContext.compile( '{{#each this}}{{wycats name}}{{/each}}', { trackIds: true } ) }; equals( template(hash, { helpers: helpers, partials: partials }), 'Dudes: Yehuda:dudes..0\nAlan:dudes..1\n' ); }); it('should invalidate context for partials with parameters', function() { var template = CompilerContext.compile( 'Dudes: {{#dudes}}{{> dude . bar="foo"}}{{/dudes}}', { trackIds: true } ), hash = { dudes: [ { name: 'Yehuda', url: 'http://yehuda' }, { name: 'Alan', url: 'http://alan' } ] }; var partials = { dude: CompilerContext.compile('{{wycats name}}', { trackIds: true }) }; equals( template(hash, { helpers: helpers, partials: partials }), 'Dudes: Yehuda:true\nAlan:true\n' ); }); }); }); handlebars.js-4.7.7/spec/umd-runtime.html000066400000000000000000000052551401244020700203360ustar00rootroot00000000000000 Mocha
handlebars.js-4.7.7/spec/umd.html000066400000000000000000000063271401244020700166560ustar00rootroot00000000000000 Mocha
handlebars.js-4.7.7/spec/utils.js000066400000000000000000000054641401244020700167020ustar00rootroot00000000000000describe('utils', function() { describe('#SafeString', function() { it('constructing a safestring from a string and checking its type', function() { var safe = new Handlebars.SafeString('testing 1, 2, 3'); if (!(safe instanceof Handlebars.SafeString)) { throw new Error('Must be instance of SafeString'); } equals( safe.toString(), 'testing 1, 2, 3', 'SafeString is equivalent to its underlying string' ); }); it('it should not escape SafeString properties', function() { var name = new Handlebars.SafeString('Sean O'Malley'); expectTemplate('{{name}}') .withInput({ name: name }) .toCompileTo('Sean O'Malley'); }); }); describe('#escapeExpression', function() { it('shouhld escape html', function() { equals( Handlebars.Utils.escapeExpression('foo<&"\'>'), 'foo<&"'>' ); equals(Handlebars.Utils.escapeExpression('foo='), 'foo='); }); it('should not escape SafeString', function() { var string = new Handlebars.SafeString('foo<&"\'>'); equals(Handlebars.Utils.escapeExpression(string), 'foo<&"\'>'); var obj = { toHTML: function() { return 'foo<&"\'>'; } }; equals(Handlebars.Utils.escapeExpression(obj), 'foo<&"\'>'); }); it('should handle falsy', function() { equals(Handlebars.Utils.escapeExpression(''), ''); equals(Handlebars.Utils.escapeExpression(undefined), ''); equals(Handlebars.Utils.escapeExpression(null), ''); equals(Handlebars.Utils.escapeExpression(false), 'false'); equals(Handlebars.Utils.escapeExpression(0), '0'); }); it('should handle empty objects', function() { equals(Handlebars.Utils.escapeExpression({}), {}.toString()); equals(Handlebars.Utils.escapeExpression([]), [].toString()); }); }); describe('#isEmpty', function() { it('should not be empty', function() { equals(Handlebars.Utils.isEmpty(undefined), true); equals(Handlebars.Utils.isEmpty(null), true); equals(Handlebars.Utils.isEmpty(false), true); equals(Handlebars.Utils.isEmpty(''), true); equals(Handlebars.Utils.isEmpty([]), true); }); it('should be empty', function() { equals(Handlebars.Utils.isEmpty(0), false); equals(Handlebars.Utils.isEmpty([1]), false); equals(Handlebars.Utils.isEmpty('foo'), false); equals(Handlebars.Utils.isEmpty({ bar: 1 }), false); }); }); describe('#extend', function() { it('should ignore prototype values', function() { function A() { this.a = 1; } A.prototype.b = 4; var b = { b: 2 }; Handlebars.Utils.extend(b, new A()); equals(b.a, 1); equals(b.b, 2); }); }); }); handlebars.js-4.7.7/spec/vendor/000077500000000000000000000000001401244020700164705ustar00rootroot00000000000000handlebars.js-4.7.7/spec/vendor/json2.js000066400000000000000000000422411401244020700200640ustar00rootroot00000000000000/* json2.js 2014-02-04 Public Domain. NO WARRANTY EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK. See http://www.JSON.org/js.html This code should be minified before deployment. See http://javascript.crockford.com/jsmin.html USE YOUR OWN COPY. IT IS EXTREMELY UNWISE TO LOAD CODE FROM SERVERS YOU DO NOT CONTROL. This file creates a global JSON object containing two methods: stringify and parse. JSON.stringify(value, replacer, space) value any JavaScript value, usually an object or array. replacer an optional parameter that determines how object values are stringified for objects. It can be a function or an array of strings. space an optional parameter that specifies the indentation of nested structures. If it is omitted, the text will be packed without extra whitespace. If it is a number, it will specify the number of spaces to indent at each level. If it is a string (such as '\t' or ' '), it contains the characters used to indent at each level. This method produces a JSON text from a JavaScript value. When an object value is found, if the object contains a toJSON method, its toJSON method will be called and the result will be stringified. A toJSON method does not serialize: it returns the value represented by the name/value pair that should be serialized, or undefined if nothing should be serialized. The toJSON method will be passed the key associated with the value, and this will be bound to the value For example, this would serialize Dates as ISO strings. Date.prototype.toJSON = function (key) { function f(n) { // Format integers to have at least two digits. return n < 10 ? '0' + n : n; } return this.getUTCFullYear() + '-' + f(this.getUTCMonth() + 1) + '-' + f(this.getUTCDate()) + 'T' + f(this.getUTCHours()) + ':' + f(this.getUTCMinutes()) + ':' + f(this.getUTCSeconds()) + 'Z'; }; You can provide an optional replacer method. It will be passed the key and value of each member, with this bound to the containing object. The value that is returned from your method will be serialized. If your method returns undefined, then the member will be excluded from the serialization. If the replacer parameter is an array of strings, then it will be used to select the members to be serialized. It filters the results such that only members with keys listed in the replacer array are stringified. Values that do not have JSON representations, such as undefined or functions, will not be serialized. Such values in objects will be dropped; in arrays they will be replaced with null. You can use a replacer function to replace those with JSON values. JSON.stringify(undefined) returns undefined. The optional space parameter produces a stringification of the value that is filled with line breaks and indentation to make it easier to read. If the space parameter is a non-empty string, then that string will be used for indentation. If the space parameter is a number, then the indentation will be that many spaces. Example: text = JSON.stringify(['e', {pluribus: 'unum'}]); // text is '["e",{"pluribus":"unum"}]' text = JSON.stringify(['e', {pluribus: 'unum'}], null, '\t'); // text is '[\n\t"e",\n\t{\n\t\t"pluribus": "unum"\n\t}\n]' text = JSON.stringify([new Date()], function (key, value) { return this[key] instanceof Date ? 'Date(' + this[key] + ')' : value; }); // text is '["Date(---current time---)"]' JSON.parse(text, reviver) This method parses a JSON text to produce an object or array. It can throw a SyntaxError exception. The optional reviver parameter is a function that can filter and transform the results. It receives each of the keys and values, and its return value is used instead of the original value. If it returns what it received, then the structure is not modified. If it returns undefined then the member is deleted. Example: // Parse the text. Values that look like ISO date strings will // be converted to Date objects. myData = JSON.parse(text, function (key, value) { var a; if (typeof value === 'string') { a = /^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2}(?:\.\d*)?)Z$/.exec(value); if (a) { return new Date(Date.UTC(+a[1], +a[2] - 1, +a[3], +a[4], +a[5], +a[6])); } } return value; }); myData = JSON.parse('["Date(09/09/2001)"]', function (key, value) { var d; if (typeof value === 'string' && value.slice(0, 5) === 'Date(' && value.slice(-1) === ')') { d = new Date(value.slice(5, -1)); if (d) { return d; } } return value; }); This is a reference implementation. You are free to copy, modify, or redistribute. */ /*jslint evil: true, regexp: true */ /*members "", "\b", "\t", "\n", "\f", "\r", "\"", JSON, "\\", apply, call, charCodeAt, getUTCDate, getUTCFullYear, getUTCHours, getUTCMinutes, getUTCMonth, getUTCSeconds, hasOwnProperty, join, lastIndex, length, parse, prototype, push, replace, slice, stringify, test, toJSON, toString, valueOf */ // Create a JSON object only if one does not already exist. We create the // methods in a closure to avoid creating global variables. if (typeof JSON !== 'object') { JSON = {}; } (function () { 'use strict'; function f(n) { // Format integers to have at least two digits. return n < 10 ? '0' + n : n; } if (typeof Date.prototype.toJSON !== 'function') { Date.prototype.toJSON = function () { 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 () { return this.valueOf(); }; } var cx, escapable, gap, indent, meta, rep; function quote(string) { // If the string contains no control characters, no quote characters, and no // backslash characters, then we can safely slap some quotes around it. // Otherwise we must also replace the offending characters with safe escape // sequences. escapable.lastIndex = 0; return escapable.test(string) ? '"' + string.replace(escapable, function (a) { var c = meta[a]; return typeof c === 'string' ? c : '\\u' + ('0000' + a.charCodeAt(0).toString(16)).slice(-4); }) + '"' : '"' + string + '"'; } function str(key, holder) { // Produce a string from holder[key]. var i, // The loop counter. k, // The member key. v, // The member value. length, mind = gap, partial, value = holder[key]; // If the value has a toJSON method, call it to obtain a replacement value. if (value && typeof value === 'object' && typeof value.toJSON === 'function') { value = value.toJSON(key); } // If we were called with a replacer function, then call the replacer to // obtain a replacement value. if (typeof rep === 'function') { value = rep.call(holder, key, value); } // What happens next depends on the value's type. switch (typeof value) { case 'string': return quote(value); case 'number': // JSON numbers must be finite. Encode non-finite numbers as null. return isFinite(value) ? String(value) : 'null'; case 'boolean': case 'null': // If the value is a boolean or null, convert it to a string. Note: // typeof null does not produce 'null'. The case is included here in // the remote chance that this gets fixed someday. return String(value); // If the type is 'object', we might be dealing with an object or an array or // null. case 'object': // Due to a specification blunder in ECMAScript, typeof null is 'object', // so watch out for that case. if (!value) { return 'null'; } // Make an array to hold the partial results of stringifying this object value. gap += indent; partial = []; // Is the value an array? if (Object.prototype.toString.apply(value) === '[object Array]') { // The value is an array. Stringify every element. Use null as a placeholder // for non-JSON values. length = value.length; for (i = 0; i < length; i += 1) { partial[i] = str(i, value) || 'null'; } // Join all of the elements together, separated with commas, and wrap them in // brackets. v = partial.length === 0 ? '[]' : gap ? '[\n' + gap + partial.join(',\n' + gap) + '\n' + mind + ']' : '[' + partial.join(',') + ']'; gap = mind; return v; } // If the replacer is an array, use it to select the members to be stringified. if (rep && typeof rep === 'object') { length = rep.length; for (i = 0; i < length; i += 1) { if (typeof rep[i] === 'string') { k = rep[i]; v = str(k, value); if (v) { partial.push(quote(k) + (gap ? ': ' : ':') + v); } } } } else { // Otherwise, iterate through all of the keys in the object. for (k in value) { if (Object.prototype.hasOwnProperty.call(value, k)) { v = str(k, value); if (v) { partial.push(quote(k) + (gap ? ': ' : ':') + v); } } } } // Join all of the member texts together, separated with commas, // and wrap them in braces. v = partial.length === 0 ? '{}' : gap ? '{\n' + gap + partial.join(',\n' + gap) + '\n' + mind + '}' : '{' + partial.join(',') + '}'; gap = mind; return v; } } // If the JSON object does not yet have a stringify method, give it one. if (typeof JSON.stringify !== 'function') { escapable = /[\\\"\x00-\x1f\x7f-\x9f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g; meta = { // table of character substitutions '\b': '\\b', '\t': '\\t', '\n': '\\n', '\f': '\\f', '\r': '\\r', '"' : '\\"', '\\': '\\\\' }; JSON.stringify = function (value, replacer, space) { // The stringify method takes a value and an optional replacer, and an optional // space parameter, and returns a JSON text. The replacer can be a function // that can replace values, or an array of strings that will select the keys. // A default replacer method can be provided. Use of the space parameter can // produce text that is more easily readable. var i; gap = ''; indent = ''; // If the space parameter is a number, make an indent string containing that // many spaces. if (typeof space === 'number') { for (i = 0; i < space; i += 1) { indent += ' '; } // If the space parameter is a string, it will be used as the indent string. } else if (typeof space === 'string') { indent = space; } // If there is a replacer, it must be a function or an array. // Otherwise, throw an error. rep = replacer; if (replacer && typeof replacer !== 'function' && (typeof replacer !== 'object' || typeof replacer.length !== 'number')) { throw new Error('JSON.stringify'); } // Make a fake root object containing our value under the key of ''. // Return the result of stringifying the value. return str('', {'': value}); }; } // If the JSON object does not yet have a parse method, give it one. if (typeof JSON.parse !== 'function') { cx = /[\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g; JSON.parse = function (text, reviver) { // The parse method takes a text and an optional reviver function, and returns // a JavaScript value if the text is a valid JSON text. var j; function walk(holder, key) { // The walk method is used to recursively walk the resulting structure so // that modifications can be made. var k, v, value = holder[key]; if (value && typeof value === 'object') { for (k in value) { if (Object.prototype.hasOwnProperty.call(value, k)) { v = walk(value, k); if (v !== undefined) { value[k] = v; } else { delete value[k]; } } } } return reviver.call(holder, key, value); } // Parsing happens in four stages. In the first stage, we replace certain // Unicode characters with escape sequences. JavaScript handles many characters // incorrectly, either silently deleting them, or treating them as line endings. text = String(text); cx.lastIndex = 0; if (cx.test(text)) { text = text.replace(cx, function (a) { return '\\u' + ('0000' + a.charCodeAt(0).toString(16)).slice(-4); }); } // In the second stage, we run the text against regular expressions that look // for non-JSON patterns. We are especially concerned with '()' and 'new' // because they can cause invocation, and '=' because it can cause mutation. // But just to be safe, we want to reject all unexpected forms. // We split the second stage into 4 regexp operations in order to work around // crippling inefficiencies in IE's and Safari's regexp engines. First we // replace the JSON backslash pairs with '@' (a non-JSON character). Second, we // replace all simple value tokens with ']' characters. Third, we delete all // open brackets that follow a colon or comma or that begin the text. Finally, // we look to see that the remaining characters are only whitespace or ']' or // ',' or ':' or '{' or '}'. If that is so, then the text is safe for eval. 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, ''))) { // In the third stage we use the eval function to compile the text into a // JavaScript structure. The '{' operator is subject to a syntactic ambiguity // in JavaScript: it can begin a block or an object literal. We wrap the text // in parens to eliminate the ambiguity. j = eval('(' + text + ')'); // In the optional fourth stage, we recursively walk the new structure, passing // each name/value pair to a reviver function for possible transformation. return typeof reviver === 'function' ? walk({'': j}, '') : j; } // If the text is not JSON parseable, then a SyntaxError is thrown. throw new SyntaxError('JSON.parse'); }; } }()); handlebars.js-4.7.7/spec/vendor/require.js000066400000000000000000002413771401244020700205200ustar00rootroot00000000000000/** vim: et:ts=4:sw=4:sts=4 * @license RequireJS 2.1.9 Copyright (c) 2010-2012, The Dojo Foundation All Rights Reserved. * Available via the MIT or new BSD license. * see: http://github.com/jrburke/requirejs for details */ //Not using strict: uneven strict support in browsers, #392, and causes //problems with requirejs.exec()/transpiler plugins that may not be strict. /*jslint regexp: true, nomen: true, sloppy: true */ /*global window, navigator, document, importScripts, setTimeout, opera */ var requirejs, require, define; (function (global) { var req, s, head, baseElement, dataMain, src, interactiveScript, currentlyAddingScript, mainScript, subPath, version = '2.1.9', commentRegExp = /(\/\*([\s\S]*?)\*\/|([^:]|^)\/\/(.*)$)/mg, cjsRequireRegExp = /[^.]\s*require\s*\(\s*["']([^'"\s]+)["']\s*\)/g, jsSuffixRegExp = /\.js$/, currDirRegExp = /^\.\//, op = Object.prototype, ostring = op.toString, hasOwn = op.hasOwnProperty, ap = Array.prototype, apsp = ap.splice, isBrowser = !!(typeof window !== 'undefined' && typeof navigator !== 'undefined' && window.document), isWebWorker = !isBrowser && typeof importScripts !== 'undefined', //PS3 indicates loaded and complete, but need to wait for complete //specifically. Sequence is 'loading', 'loaded', execution, // then 'complete'. The UA check is unfortunate, but not sure how //to feature test w/o causing perf issues. readyRegExp = isBrowser && navigator.platform === 'PLAYSTATION 3' ? /^complete$/ : /^(complete|loaded)$/, defContextName = '_', //Oh the tragedy, detecting opera. See the usage of isOpera for reason. isOpera = typeof opera !== 'undefined' && opera.toString() === '[object Opera]', contexts = {}, cfg = {}, globalDefQueue = [], useInteractive = false; function isFunction(it) { return ostring.call(it) === '[object Function]'; } function isArray(it) { return ostring.call(it) === '[object Array]'; } /** * Helper function for iterating over an array. If the func returns * a true value, it will break out of the loop. */ function each(ary, func) { if (ary) { var i; for (i = 0; i < ary.length; i += 1) { if (ary[i] && func(ary[i], i, ary)) { break; } } } } /** * Helper function for iterating over an array backwards. If the func * returns a true value, it will break out of the loop. */ function eachReverse(ary, func) { if (ary) { var i; for (i = ary.length - 1; i > -1; i -= 1) { if (ary[i] && func(ary[i], i, ary)) { break; } } } } function hasProp(obj, prop) { return hasOwn.call(obj, prop); } function getOwn(obj, prop) { return hasProp(obj, prop) && obj[prop]; } /** * Cycles over properties in an object and calls a function for each * property value. If the function returns a truthy value, then the * iteration is stopped. */ function eachProp(obj, func) { var prop; for (prop in obj) { if (hasProp(obj, prop)) { if (func(obj[prop], prop)) { break; } } } } /** * Simple function to mix in properties from source into target, * but only if target does not already have a property of the same name. */ function mixin(target, source, force, deepStringMixin) { if (source) { eachProp(source, function (value, prop) { if (force || !hasProp(target, prop)) { if (deepStringMixin && typeof value !== 'string') { if (!target[prop]) { target[prop] = {}; } mixin(target[prop], value, force, deepStringMixin); } else { target[prop] = value; } } }); } return target; } //Similar to Function.prototype.bind, but the 'this' object is specified //first, since it is easier to read/figure out what 'this' will be. function bind(obj, fn) { return function () { return fn.apply(obj, arguments); }; } function scripts() { return document.getElementsByTagName('script'); } function defaultOnError(err) { throw err; } //Allow getting a global that expressed in //dot notation, like 'a.b.c'. function getGlobal(value) { if (!value) { return value; } var g = global; each(value.split('.'), function (part) { g = g[part]; }); return g; } /** * Constructs an error with a pointer to an URL with more information. * @param {String} id the error ID that maps to an ID on a web page. * @param {String} message human readable error. * @param {Error} [err] the original error, if there is one. * * @returns {Error} */ function makeError(id, msg, err, requireModules) { var e = new Error(msg + '\nhttp://requirejs.org/docs/errors.html#' + id); e.requireType = id; e.requireModules = requireModules; if (err) { e.originalError = err; } return e; } if (typeof define !== 'undefined') { //If a define is already in play via another AMD loader, //do not overwrite. return; } if (typeof requirejs !== 'undefined') { if (isFunction(requirejs)) { //Do not overwrite and existing requirejs instance. return; } cfg = requirejs; requirejs = undefined; } //Allow for a require config object if (typeof require !== 'undefined' && !isFunction(require)) { //assume it is a config object. cfg = require; require = undefined; } function newContext(contextName) { var inCheckLoaded, Module, context, handlers, checkLoadedTimeoutId, config = { //Defaults. Do not set a default for map //config to speed up normalize(), which //will run faster if there is no default. waitSeconds: 7, baseUrl: './', paths: {}, pkgs: {}, shim: {}, config: {} }, registry = {}, //registry of just enabled modules, to speed //cycle breaking code when lots of modules //are registered, but not activated. enabledRegistry = {}, undefEvents = {}, defQueue = [], defined = {}, urlFetched = {}, requireCounter = 1, unnormalizedCounter = 1; /** * Trims the . and .. from an array of path segments. * It will keep a leading path segment if a .. will become * the first path segment, to help with module name lookups, * which act like paths, but can be remapped. But the end result, * all paths that use this function should look normalized. * NOTE: this method MODIFIES the input array. * @param {Array} ary the array of path segments. */ function trimDots(ary) { var i, part; for (i = 0; ary[i]; i += 1) { part = ary[i]; if (part === '.') { ary.splice(i, 1); i -= 1; } else if (part === '..') { if (i === 1 && (ary[2] === '..' || ary[0] === '..')) { //End of the line. Keep at least one non-dot //path segment at the front so it can be mapped //correctly to disk. Otherwise, there is likely //no path mapping for a path starting with '..'. //This can still fail, but catches the most reasonable //uses of .. break; } else if (i > 0) { ary.splice(i - 1, 2); i -= 2; } } } } /** * Given a relative module name, like ./something, normalize it to * a real name that can be mapped to a path. * @param {String} name the relative name * @param {String} baseName a real name that the name arg is relative * to. * @param {Boolean} applyMap apply the map config to the value. Should * only be done if this normalization is for a dependency ID. * @returns {String} normalized name */ function normalize(name, baseName, applyMap) { var pkgName, pkgConfig, mapValue, nameParts, i, j, nameSegment, foundMap, foundI, foundStarMap, starI, baseParts = baseName && baseName.split('/'), normalizedBaseParts = baseParts, map = config.map, starMap = map && map['*']; //Adjust any relative paths. if (name && name.charAt(0) === '.') { //If have a base name, try to normalize against it, //otherwise, assume it is a top-level require that will //be relative to baseUrl in the end. if (baseName) { if (getOwn(config.pkgs, baseName)) { //If the baseName is a package name, then just treat it as one //name to concat the name with. normalizedBaseParts = baseParts = [baseName]; } else { //Convert baseName to array, and lop off the last part, //so that . matches that 'directory' and not name of the baseName's //module. For instance, baseName of 'one/two/three', maps to //'one/two/three.js', but we want the directory, 'one/two' for //this normalization. normalizedBaseParts = baseParts.slice(0, baseParts.length - 1); } name = normalizedBaseParts.concat(name.split('/')); trimDots(name); //Some use of packages may use a . path to reference the //'main' module name, so normalize for that. pkgConfig = getOwn(config.pkgs, (pkgName = name[0])); name = name.join('/'); if (pkgConfig && name === pkgName + '/' + pkgConfig.main) { name = pkgName; } } else if (name.indexOf('./') === 0) { // No baseName, so this is ID is resolved relative // to baseUrl, pull off the leading dot. name = name.substring(2); } } //Apply map config if available. if (applyMap && map && (baseParts || starMap)) { nameParts = name.split('/'); for (i = nameParts.length; i > 0; i -= 1) { nameSegment = nameParts.slice(0, i).join('/'); if (baseParts) { //Find the longest baseName segment match in the config. //So, do joins on the biggest to smallest lengths of baseParts. for (j = baseParts.length; j > 0; j -= 1) { mapValue = getOwn(map, baseParts.slice(0, j).join('/')); //baseName segment has config, find if it has one for //this name. if (mapValue) { mapValue = getOwn(mapValue, nameSegment); if (mapValue) { //Match, update name to the new value. foundMap = mapValue; foundI = i; break; } } } } if (foundMap) { break; } //Check for a star map match, but just hold on to it, //if there is a shorter segment match later in a matching //config, then favor over this star map. if (!foundStarMap && starMap && getOwn(starMap, nameSegment)) { foundStarMap = getOwn(starMap, nameSegment); starI = i; } } if (!foundMap && foundStarMap) { foundMap = foundStarMap; foundI = starI; } if (foundMap) { nameParts.splice(0, foundI, foundMap); name = nameParts.join('/'); } } return name; } function removeScript(name) { if (isBrowser) { each(scripts(), function (scriptNode) { if (scriptNode.getAttribute('data-requiremodule') === name && scriptNode.getAttribute('data-requirecontext') === context.contextName) { scriptNode.parentNode.removeChild(scriptNode); return true; } }); } } function hasPathFallback(id) { var pathConfig = getOwn(config.paths, id); if (pathConfig && isArray(pathConfig) && pathConfig.length > 1) { //Pop off the first array value, since it failed, and //retry pathConfig.shift(); context.require.undef(id); context.require([id]); return true; } } //Turns a plugin!resource to [plugin, resource] //with the plugin being undefined if the name //did not have a plugin prefix. function splitPrefix(name) { var prefix, index = name ? name.indexOf('!') : -1; if (index > -1) { prefix = name.substring(0, index); name = name.substring(index + 1, name.length); } return [prefix, name]; } /** * Creates a module mapping that includes plugin prefix, module * name, and path. If parentModuleMap is provided it will * also normalize the name via require.normalize() * * @param {String} name the module name * @param {String} [parentModuleMap] parent module map * for the module name, used to resolve relative names. * @param {Boolean} isNormalized: is the ID already normalized. * This is true if this call is done for a define() module ID. * @param {Boolean} applyMap: apply the map config to the ID. * Should only be true if this map is for a dependency. * * @returns {Object} */ function makeModuleMap(name, parentModuleMap, isNormalized, applyMap) { var url, pluginModule, suffix, nameParts, prefix = null, parentName = parentModuleMap ? parentModuleMap.name : null, originalName = name, isDefine = true, normalizedName = ''; //If no name, then it means it is a require call, generate an //internal name. if (!name) { isDefine = false; name = '_@r' + (requireCounter += 1); } nameParts = splitPrefix(name); prefix = nameParts[0]; name = nameParts[1]; if (prefix) { prefix = normalize(prefix, parentName, applyMap); pluginModule = getOwn(defined, prefix); } //Account for relative paths if there is a base name. if (name) { if (prefix) { if (pluginModule && pluginModule.normalize) { //Plugin is loaded, use its normalize method. normalizedName = pluginModule.normalize(name, function (name) { return normalize(name, parentName, applyMap); }); } else { normalizedName = normalize(name, parentName, applyMap); } } else { //A regular module. normalizedName = normalize(name, parentName, applyMap); //Normalized name may be a plugin ID due to map config //application in normalize. The map config values must //already be normalized, so do not need to redo that part. nameParts = splitPrefix(normalizedName); prefix = nameParts[0]; normalizedName = nameParts[1]; isNormalized = true; url = context.nameToUrl(normalizedName); } } //If the id is a plugin id that cannot be determined if it needs //normalization, stamp it with a unique ID so two matching relative //ids that may conflict can be separate. suffix = prefix && !pluginModule && !isNormalized ? '_unnormalized' + (unnormalizedCounter += 1) : ''; return { prefix: prefix, name: normalizedName, parentMap: parentModuleMap, unnormalized: !!suffix, url: url, originalName: originalName, isDefine: isDefine, id: (prefix ? prefix + '!' + normalizedName : normalizedName) + suffix }; } function getModule(depMap) { var id = depMap.id, mod = getOwn(registry, id); if (!mod) { mod = registry[id] = new context.Module(depMap); } return mod; } function on(depMap, name, fn) { var id = depMap.id, mod = getOwn(registry, id); if (hasProp(defined, id) && (!mod || mod.defineEmitComplete)) { if (name === 'defined') { fn(defined[id]); } } else { mod = getModule(depMap); if (mod.error && name === 'error') { fn(mod.error); } else { mod.on(name, fn); } } } function onError(err, errback) { var ids = err.requireModules, notified = false; if (errback) { errback(err); } else { each(ids, function (id) { var mod = getOwn(registry, id); if (mod) { //Set error on module, so it skips timeout checks. mod.error = err; if (mod.events.error) { notified = true; mod.emit('error', err); } } }); if (!notified) { req.onError(err); } } } /** * Internal method to transfer globalQueue items to this context's * defQueue. */ function takeGlobalQueue() { //Push all the globalDefQueue items into the context's defQueue if (globalDefQueue.length) { //Array splice in the values since the context code has a //local var ref to defQueue, so cannot just reassign the one //on context. apsp.apply(defQueue, [defQueue.length - 1, 0].concat(globalDefQueue)); globalDefQueue = []; } } handlers = { 'require': function (mod) { if (mod.require) { return mod.require; } else { return (mod.require = context.makeRequire(mod.map)); } }, 'exports': function (mod) { mod.usingExports = true; if (mod.map.isDefine) { if (mod.exports) { return mod.exports; } else { return (mod.exports = defined[mod.map.id] = {}); } } }, 'module': function (mod) { if (mod.module) { return mod.module; } else { return (mod.module = { id: mod.map.id, uri: mod.map.url, config: function () { var c, pkg = getOwn(config.pkgs, mod.map.id); // For packages, only support config targeted // at the main module. c = pkg ? getOwn(config.config, mod.map.id + '/' + pkg.main) : getOwn(config.config, mod.map.id); return c || {}; }, exports: defined[mod.map.id] }); } } }; function cleanRegistry(id) { //Clean up machinery used for waiting modules. delete registry[id]; delete enabledRegistry[id]; } function breakCycle(mod, traced, processed) { var id = mod.map.id; if (mod.error) { mod.emit('error', mod.error); } else { traced[id] = true; each(mod.depMaps, function (depMap, i) { var depId = depMap.id, dep = getOwn(registry, depId); //Only force things that have not completed //being defined, so still in the registry, //and only if it has not been matched up //in the module already. if (dep && !mod.depMatched[i] && !processed[depId]) { if (getOwn(traced, depId)) { mod.defineDep(i, defined[depId]); mod.check(); //pass false? } else { breakCycle(dep, traced, processed); } } }); processed[id] = true; } } function checkLoaded() { var map, modId, err, usingPathFallback, waitInterval = config.waitSeconds * 1000, //It is possible to disable the wait interval by using waitSeconds of 0. expired = waitInterval && (context.startTime + waitInterval) < new Date().getTime(), noLoads = [], reqCalls = [], stillLoading = false, needCycleCheck = true; //Do not bother if this call was a result of a cycle break. if (inCheckLoaded) { return; } inCheckLoaded = true; //Figure out the state of all the modules. eachProp(enabledRegistry, function (mod) { map = mod.map; modId = map.id; //Skip things that are not enabled or in error state. if (!mod.enabled) { return; } if (!map.isDefine) { reqCalls.push(mod); } if (!mod.error) { //If the module should be executed, and it has not //been inited and time is up, remember it. if (!mod.inited && expired) { if (hasPathFallback(modId)) { usingPathFallback = true; stillLoading = true; } else { noLoads.push(modId); removeScript(modId); } } else if (!mod.inited && mod.fetched && map.isDefine) { stillLoading = true; if (!map.prefix) { //No reason to keep looking for unfinished //loading. If the only stillLoading is a //plugin resource though, keep going, //because it may be that a plugin resource //is waiting on a non-plugin cycle. return (needCycleCheck = false); } } } }); if (expired && noLoads.length) { //If wait time expired, throw error of unloaded modules. err = makeError('timeout', 'Load timeout for modules: ' + noLoads, null, noLoads); err.contextName = context.contextName; return onError(err); } //Not expired, check for a cycle. if (needCycleCheck) { each(reqCalls, function (mod) { breakCycle(mod, {}, {}); }); } //If still waiting on loads, and the waiting load is something //other than a plugin resource, or there are still outstanding //scripts, then just try back later. if ((!expired || usingPathFallback) && stillLoading) { //Something is still waiting to load. Wait for it, but only //if a timeout is not already in effect. if ((isBrowser || isWebWorker) && !checkLoadedTimeoutId) { checkLoadedTimeoutId = setTimeout(function () { checkLoadedTimeoutId = 0; checkLoaded(); }, 50); } } inCheckLoaded = false; } Module = function (map) { this.events = getOwn(undefEvents, map.id) || {}; this.map = map; this.shim = getOwn(config.shim, map.id); this.depExports = []; this.depMaps = []; this.depMatched = []; this.pluginMaps = {}; this.depCount = 0; /* this.exports this.factory this.depMaps = [], this.enabled, this.fetched */ }; Module.prototype = { init: function (depMaps, factory, errback, options) { options = options || {}; //Do not do more inits if already done. Can happen if there //are multiple define calls for the same module. That is not //a normal, common case, but it is also not unexpected. if (this.inited) { return; } this.factory = factory; if (errback) { //Register for errors on this module. this.on('error', errback); } else if (this.events.error) { //If no errback already, but there are error listeners //on this module, set up an errback to pass to the deps. errback = bind(this, function (err) { this.emit('error', err); }); } //Do a copy of the dependency array, so that //source inputs are not modified. For example //"shim" deps are passed in here directly, and //doing a direct modification of the depMaps array //would affect that config. this.depMaps = depMaps && depMaps.slice(0); this.errback = errback; //Indicate this module has be initialized this.inited = true; this.ignore = options.ignore; //Could have option to init this module in enabled mode, //or could have been previously marked as enabled. However, //the dependencies are not known until init is called. So //if enabled previously, now trigger dependencies as enabled. if (options.enabled || this.enabled) { //Enable this module and dependencies. //Will call this.check() this.enable(); } else { this.check(); } }, defineDep: function (i, depExports) { //Because of cycles, defined callback for a given //export can be called more than once. if (!this.depMatched[i]) { this.depMatched[i] = true; this.depCount -= 1; this.depExports[i] = depExports; } }, fetch: function () { if (this.fetched) { return; } this.fetched = true; context.startTime = (new Date()).getTime(); var map = this.map; //If the manager is for a plugin managed resource, //ask the plugin to load it now. if (this.shim) { context.makeRequire(this.map, { enableBuildCallback: true })(this.shim.deps || [], bind(this, function () { return map.prefix ? this.callPlugin() : this.load(); })); } else { //Regular dependency. return map.prefix ? this.callPlugin() : this.load(); } }, load: function () { var url = this.map.url; //Regular dependency. if (!urlFetched[url]) { urlFetched[url] = true; context.load(this.map.id, url); } }, /** * Checks if the module is ready to define itself, and if so, * define it. */ check: function () { if (!this.enabled || this.enabling) { return; } var err, cjsModule, id = this.map.id, depExports = this.depExports, exports = this.exports, factory = this.factory; if (!this.inited) { this.fetch(); } else if (this.error) { this.emit('error', this.error); } else if (!this.defining) { //The factory could trigger another require call //that would result in checking this module to //define itself again. If already in the process //of doing that, skip this work. this.defining = true; if (this.depCount < 1 && !this.defined) { if (isFunction(factory)) { //If there is an error listener, favor passing //to that instead of throwing an error. However, //only do it for define()'d modules. require //errbacks should not be called for failures in //their callbacks (#699). However if a global //onError is set, use that. if ((this.events.error && this.map.isDefine) || req.onError !== defaultOnError) { try { exports = context.execCb(id, factory, depExports, exports); } catch (e) { err = e; } } else { exports = context.execCb(id, factory, depExports, exports); } if (this.map.isDefine) { //If setting exports via 'module' is in play, //favor that over return value and exports. After that, //favor a non-undefined return value over exports use. cjsModule = this.module; if (cjsModule && cjsModule.exports !== undefined && //Make sure it is not already the exports value cjsModule.exports !== this.exports) { exports = cjsModule.exports; } else if (exports === undefined && this.usingExports) { //exports already set the defined value. exports = this.exports; } } if (err) { err.requireMap = this.map; err.requireModules = this.map.isDefine ? [this.map.id] : null; err.requireType = this.map.isDefine ? 'define' : 'require'; return onError((this.error = err)); } } else { //Just a literal value exports = factory; } this.exports = exports; if (this.map.isDefine && !this.ignore) { defined[id] = exports; if (req.onResourceLoad) { req.onResourceLoad(context, this.map, this.depMaps); } } //Clean up cleanRegistry(id); this.defined = true; } //Finished the define stage. Allow calling check again //to allow define notifications below in the case of a //cycle. this.defining = false; if (this.defined && !this.defineEmitted) { this.defineEmitted = true; this.emit('defined', this.exports); this.defineEmitComplete = true; } } }, callPlugin: function () { var map = this.map, id = map.id, //Map already normalized the prefix. pluginMap = makeModuleMap(map.prefix); //Mark this as a dependency for this plugin, so it //can be traced for cycles. this.depMaps.push(pluginMap); on(pluginMap, 'defined', bind(this, function (plugin) { var load, normalizedMap, normalizedMod, name = this.map.name, parentName = this.map.parentMap ? this.map.parentMap.name : null, localRequire = context.makeRequire(map.parentMap, { enableBuildCallback: true }); //If current map is not normalized, wait for that //normalized name to load instead of continuing. if (this.map.unnormalized) { //Normalize the ID if the plugin allows it. if (plugin.normalize) { name = plugin.normalize(name, function (name) { return normalize(name, parentName, true); }) || ''; } //prefix and name should already be normalized, no need //for applying map config again either. normalizedMap = makeModuleMap(map.prefix + '!' + name, this.map.parentMap); on(normalizedMap, 'defined', bind(this, function (value) { this.init([], function () { return value; }, null, { enabled: true, ignore: true }); })); normalizedMod = getOwn(registry, normalizedMap.id); if (normalizedMod) { //Mark this as a dependency for this plugin, so it //can be traced for cycles. this.depMaps.push(normalizedMap); if (this.events.error) { normalizedMod.on('error', bind(this, function (err) { this.emit('error', err); })); } normalizedMod.enable(); } return; } load = bind(this, function (value) { this.init([], function () { return value; }, null, { enabled: true }); }); load.error = bind(this, function (err) { this.inited = true; this.error = err; err.requireModules = [id]; //Remove temp unnormalized modules for this module, //since they will never be resolved otherwise now. eachProp(registry, function (mod) { if (mod.map.id.indexOf(id + '_unnormalized') === 0) { cleanRegistry(mod.map.id); } }); onError(err); }); //Allow plugins to load other code without having to know the //context or how to 'complete' the load. load.fromText = bind(this, function (text, textAlt) { /*jslint evil: true */ var moduleName = map.name, moduleMap = makeModuleMap(moduleName), hasInteractive = useInteractive; //As of 2.1.0, support just passing the text, to reinforce //fromText only being called once per resource. Still //support old style of passing moduleName but discard //that moduleName in favor of the internal ref. if (textAlt) { text = textAlt; } //Turn off interactive script matching for IE for any define //calls in the text, then turn it back on at the end. if (hasInteractive) { useInteractive = false; } //Prime the system by creating a module instance for //it. getModule(moduleMap); //Transfer any config to this other module. if (hasProp(config.config, id)) { config.config[moduleName] = config.config[id]; } try { req.exec(text); } catch (e) { return onError(makeError('fromtexteval', 'fromText eval for ' + id + ' failed: ' + e, e, [id])); } if (hasInteractive) { useInteractive = true; } //Mark this as a dependency for the plugin //resource this.depMaps.push(moduleMap); //Support anonymous modules. context.completeLoad(moduleName); //Bind the value of that module to the value for this //resource ID. localRequire([moduleName], load); }); //Use parentName here since the plugin's name is not reliable, //could be some weird string with no path that actually wants to //reference the parentName's path. plugin.load(map.name, localRequire, load, config); })); context.enable(pluginMap, this); this.pluginMaps[pluginMap.id] = pluginMap; }, enable: function () { enabledRegistry[this.map.id] = this; this.enabled = true; //Set flag mentioning that the module is enabling, //so that immediate calls to the defined callbacks //for dependencies do not trigger inadvertent load //with the depCount still being zero. this.enabling = true; //Enable each dependency each(this.depMaps, bind(this, function (depMap, i) { var id, mod, handler; if (typeof depMap === 'string') { //Dependency needs to be converted to a depMap //and wired up to this module. depMap = makeModuleMap(depMap, (this.map.isDefine ? this.map : this.map.parentMap), false, !this.skipMap); this.depMaps[i] = depMap; handler = getOwn(handlers, depMap.id); if (handler) { this.depExports[i] = handler(this); return; } this.depCount += 1; on(depMap, 'defined', bind(this, function (depExports) { this.defineDep(i, depExports); this.check(); })); if (this.errback) { on(depMap, 'error', bind(this, this.errback)); } } id = depMap.id; mod = registry[id]; //Skip special modules like 'require', 'exports', 'module' //Also, don't call enable if it is already enabled, //important in circular dependency cases. if (!hasProp(handlers, id) && mod && !mod.enabled) { context.enable(depMap, this); } })); //Enable each plugin that is used in //a dependency eachProp(this.pluginMaps, bind(this, function (pluginMap) { var mod = getOwn(registry, pluginMap.id); if (mod && !mod.enabled) { context.enable(pluginMap, this); } })); this.enabling = false; this.check(); }, on: function (name, cb) { var cbs = this.events[name]; if (!cbs) { cbs = this.events[name] = []; } cbs.push(cb); }, emit: function (name, evt) { each(this.events[name], function (cb) { cb(evt); }); if (name === 'error') { //Now that the error handler was triggered, remove //the listeners, since this broken Module instance //can stay around for a while in the registry. delete this.events[name]; } } }; function callGetModule(args) { //Skip modules already defined. if (!hasProp(defined, args[0])) { getModule(makeModuleMap(args[0], null, true)).init(args[1], args[2]); } } function removeListener(node, func, name, ieName) { //Favor detachEvent because of IE9 //issue, see attachEvent/addEventListener comment elsewhere //in this file. if (node.detachEvent && !isOpera) { //Probably IE. If not it will throw an error, which will be //useful to know. if (ieName) { node.detachEvent(ieName, func); } } else { node.removeEventListener(name, func, false); } } /** * Given an event from a script node, get the requirejs info from it, * and then removes the event listeners on the node. * @param {Event} evt * @returns {Object} */ function getScriptData(evt) { //Using currentTarget instead of target for Firefox 2.0's sake. Not //all old browsers will be supported, but this one was easy enough //to support and still makes sense. var node = evt.currentTarget || evt.srcElement; //Remove the listeners once here. removeListener(node, context.onScriptLoad, 'load', 'onreadystatechange'); removeListener(node, context.onScriptError, 'error'); return { node: node, id: node && node.getAttribute('data-requiremodule') }; } function intakeDefines() { var args; //Any defined modules in the global queue, intake them now. takeGlobalQueue(); //Make sure any remaining defQueue items get properly processed. while (defQueue.length) { args = defQueue.shift(); if (args[0] === null) { return onError(makeError('mismatch', 'Mismatched anonymous define() module: ' + args[args.length - 1])); } else { //args are id, deps, factory. Should be normalized by the //define() function. callGetModule(args); } } } context = { config: config, contextName: contextName, registry: registry, defined: defined, urlFetched: urlFetched, defQueue: defQueue, Module: Module, makeModuleMap: makeModuleMap, nextTick: req.nextTick, onError: onError, /** * Set a configuration for the context. * @param {Object} cfg config object to integrate. */ configure: function (cfg) { //Make sure the baseUrl ends in a slash. if (cfg.baseUrl) { if (cfg.baseUrl.charAt(cfg.baseUrl.length - 1) !== '/') { cfg.baseUrl += '/'; } } //Save off the paths and packages since they require special processing, //they are additive. var pkgs = config.pkgs, shim = config.shim, objs = { paths: true, config: true, map: true }; eachProp(cfg, function (value, prop) { if (objs[prop]) { if (prop === 'map') { if (!config.map) { config.map = {}; } mixin(config[prop], value, true, true); } else { mixin(config[prop], value, true); } } else { config[prop] = value; } }); //Merge shim if (cfg.shim) { eachProp(cfg.shim, function (value, id) { //Normalize the structure if (isArray(value)) { value = { deps: value }; } if ((value.exports || value.init) && !value.exportsFn) { value.exportsFn = context.makeShimExports(value); } shim[id] = value; }); config.shim = shim; } //Adjust packages if necessary. if (cfg.packages) { each(cfg.packages, function (pkgObj) { var location; pkgObj = typeof pkgObj === 'string' ? { name: pkgObj } : pkgObj; location = pkgObj.location; //Create a brand new object on pkgs, since currentPackages can //be passed in again, and config.pkgs is the internal transformed //state for all package configs. pkgs[pkgObj.name] = { name: pkgObj.name, location: location || pkgObj.name, //Remove leading dot in main, so main paths are normalized, //and remove any trailing .js, since different package //envs have different conventions: some use a module name, //some use a file name. main: (pkgObj.main || 'main') .replace(currDirRegExp, '') .replace(jsSuffixRegExp, '') }; }); //Done with modifications, assing packages back to context config config.pkgs = pkgs; } //If there are any "waiting to execute" modules in the registry, //update the maps for them, since their info, like URLs to load, //may have changed. eachProp(registry, function (mod, id) { //If module already has init called, since it is too //late to modify them, and ignore unnormalized ones //since they are transient. if (!mod.inited && !mod.map.unnormalized) { mod.map = makeModuleMap(id); } }); //If a deps array or a config callback is specified, then call //require with those args. This is useful when require is defined as a //config object before require.js is loaded. if (cfg.deps || cfg.callback) { context.require(cfg.deps || [], cfg.callback); } }, makeShimExports: function (value) { function fn() { var ret; if (value.init) { ret = value.init.apply(global, arguments); } return ret || (value.exports && getGlobal(value.exports)); } return fn; }, makeRequire: function (relMap, options) { options = options || {}; function localRequire(deps, callback, errback) { var id, map, requireMod; if (options.enableBuildCallback && callback && isFunction(callback)) { callback.__requireJsBuild = true; } if (typeof deps === 'string') { if (isFunction(callback)) { //Invalid call return onError(makeError('requireargs', 'Invalid require call'), errback); } //If require|exports|module are requested, get the //value for them from the special handlers. Caveat: //this only works while module is being defined. if (relMap && hasProp(handlers, deps)) { return handlers[deps](registry[relMap.id]); } //Synchronous access to one module. If require.get is //available (as in the Node adapter), prefer that. if (req.get) { return req.get(context, deps, relMap, localRequire); } //Normalize module name, if it contains . or .. map = makeModuleMap(deps, relMap, false, true); id = map.id; if (!hasProp(defined, id)) { return onError(makeError('notloaded', 'Module name "' + id + '" has not been loaded yet for context: ' + contextName + (relMap ? '' : '. Use require([])'))); } return defined[id]; } //Grab defines waiting in the global queue. intakeDefines(); //Mark all the dependencies as needing to be loaded. context.nextTick(function () { //Some defines could have been added since the //require call, collect them. intakeDefines(); requireMod = getModule(makeModuleMap(null, relMap)); //Store if map config should be applied to this require //call for dependencies. requireMod.skipMap = options.skipMap; requireMod.init(deps, callback, errback, { enabled: true }); checkLoaded(); }); return localRequire; } mixin(localRequire, { isBrowser: isBrowser, /** * Converts a module name + .extension into an URL path. * *Requires* the use of a module name. It does not support using * plain URLs like nameToUrl. */ toUrl: function (moduleNamePlusExt) { var ext, index = moduleNamePlusExt.lastIndexOf('.'), segment = moduleNamePlusExt.split('/')[0], isRelative = segment === '.' || segment === '..'; //Have a file extension alias, and it is not the //dots from a relative path. if (index !== -1 && (!isRelative || index > 1)) { ext = moduleNamePlusExt.substring(index, moduleNamePlusExt.length); moduleNamePlusExt = moduleNamePlusExt.substring(0, index); } return context.nameToUrl(normalize(moduleNamePlusExt, relMap && relMap.id, true), ext, true); }, defined: function (id) { return hasProp(defined, makeModuleMap(id, relMap, false, true).id); }, specified: function (id) { id = makeModuleMap(id, relMap, false, true).id; return hasProp(defined, id) || hasProp(registry, id); } }); //Only allow undef on top level require calls if (!relMap) { localRequire.undef = function (id) { //Bind any waiting define() calls to this context, //fix for #408 takeGlobalQueue(); var map = makeModuleMap(id, relMap, true), mod = getOwn(registry, id); removeScript(id); delete defined[id]; delete urlFetched[map.url]; delete undefEvents[id]; if (mod) { //Hold on to listeners in case the //module will be attempted to be reloaded //using a different config. if (mod.events.defined) { undefEvents[id] = mod.events; } cleanRegistry(id); } }; } return localRequire; }, /** * Called to enable a module if it is still in the registry * awaiting enablement. A second arg, parent, the parent module, * is passed in for context, when this method is overriden by * the optimizer. Not shown here to keep code compact. */ enable: function (depMap) { var mod = getOwn(registry, depMap.id); if (mod) { getModule(depMap).enable(); } }, /** * Internal method used by environment adapters to complete a load event. * A load event could be a script load or just a load pass from a synchronous * load call. * @param {String} moduleName the name of the module to potentially complete. */ completeLoad: function (moduleName) { var found, args, mod, shim = getOwn(config.shim, moduleName) || {}, shExports = shim.exports; takeGlobalQueue(); while (defQueue.length) { args = defQueue.shift(); if (args[0] === null) { args[0] = moduleName; //If already found an anonymous module and bound it //to this name, then this is some other anon module //waiting for its completeLoad to fire. if (found) { break; } found = true; } else if (args[0] === moduleName) { //Found matching define call for this script! found = true; } callGetModule(args); } //Do this after the cycle of callGetModule in case the result //of those calls/init calls changes the registry. mod = getOwn(registry, moduleName); if (!found && !hasProp(defined, moduleName) && mod && !mod.inited) { if (config.enforceDefine && (!shExports || !getGlobal(shExports))) { if (hasPathFallback(moduleName)) { return; } else { return onError(makeError('nodefine', 'No define call for ' + moduleName, null, [moduleName])); } } else { //A script that does not call define(), so just simulate //the call for it. callGetModule([moduleName, (shim.deps || []), shim.exportsFn]); } } checkLoaded(); }, /** * Converts a module name to a file path. Supports cases where * moduleName may actually be just an URL. * Note that it **does not** call normalize on the moduleName, * it is assumed to have already been normalized. This is an * internal API, not a public one. Use toUrl for the public API. */ nameToUrl: function (moduleName, ext, skipExt) { var paths, pkgs, pkg, pkgPath, syms, i, parentModule, url, parentPath; //If a colon is in the URL, it indicates a protocol is used and it is just //an URL to a file, or if it starts with a slash, contains a query arg (i.e. ?) //or ends with .js, then assume the user meant to use an url and not a module id. //The slash is important for protocol-less URLs as well as full paths. if (req.jsExtRegExp.test(moduleName)) { //Just a plain path, not module name lookup, so just return it. //Add extension if it is included. This is a bit wonky, only non-.js things pass //an extension, this method probably needs to be reworked. url = moduleName + (ext || ''); } else { //A module that needs to be converted to a path. paths = config.paths; pkgs = config.pkgs; syms = moduleName.split('/'); //For each module name segment, see if there is a path //registered for it. Start with most specific name //and work up from it. for (i = syms.length; i > 0; i -= 1) { parentModule = syms.slice(0, i).join('/'); pkg = getOwn(pkgs, parentModule); parentPath = getOwn(paths, parentModule); if (parentPath) { //If an array, it means there are a few choices, //Choose the one that is desired if (isArray(parentPath)) { parentPath = parentPath[0]; } syms.splice(0, i, parentPath); break; } else if (pkg) { //If module name is just the package name, then looking //for the main module. if (moduleName === pkg.name) { pkgPath = pkg.location + '/' + pkg.main; } else { pkgPath = pkg.location; } syms.splice(0, i, pkgPath); break; } } //Join the path parts together, then figure out if baseUrl is needed. url = syms.join('/'); url += (ext || (/^data\:|\?/.test(url) || skipExt ? '' : '.js')); url = (url.charAt(0) === '/' || url.match(/^[\w\+\.\-]+:/) ? '' : config.baseUrl) + url; } return config.urlArgs ? url + ((url.indexOf('?') === -1 ? '?' : '&') + config.urlArgs) : url; }, //Delegates to req.load. Broken out as a separate function to //allow overriding in the optimizer. load: function (id, url) { req.load(context, id, url); }, /** * Executes a module callback function. Broken out as a separate function * solely to allow the build system to sequence the files in the built * layer in the right sequence. * * @private */ execCb: function (name, callback, args, exports) { return callback.apply(exports, args); }, /** * callback for script loads, used to check status of loading. * * @param {Event} evt the event from the browser for the script * that was loaded. */ onScriptLoad: function (evt) { //Using currentTarget instead of target for Firefox 2.0's sake. Not //all old browsers will be supported, but this one was easy enough //to support and still makes sense. if (evt.type === 'load' || (readyRegExp.test((evt.currentTarget || evt.srcElement).readyState))) { //Reset interactive script so a script node is not held onto for //to long. interactiveScript = null; //Pull out the name of the module and the context. var data = getScriptData(evt); context.completeLoad(data.id); } }, /** * Callback for script errors. */ onScriptError: function (evt) { var data = getScriptData(evt); if (!hasPathFallback(data.id)) { return onError(makeError('scripterror', 'Script error for: ' + data.id, evt, [data.id])); } } }; context.require = context.makeRequire(); return context; } /** * Main entry point. * * If the only argument to require is a string, then the module that * is represented by that string is fetched for the appropriate context. * * If the first argument is an array, then it will be treated as an array * of dependency string names to fetch. An optional function callback can * be specified to execute when all of those dependencies are available. * * Make a local req variable to help Caja compliance (it assumes things * on a require that are not standardized), and to give a short * name for minification/local scope use. */ req = requirejs = function (deps, callback, errback, optional) { //Find the right context, use default var context, config, contextName = defContextName; // Determine if have config object in the call. if (!isArray(deps) && typeof deps !== 'string') { // deps is a config object config = deps; if (isArray(callback)) { // Adjust args if there are dependencies deps = callback; callback = errback; errback = optional; } else { deps = []; } } if (config && config.context) { contextName = config.context; } context = getOwn(contexts, contextName); if (!context) { context = contexts[contextName] = req.s.newContext(contextName); } if (config) { context.configure(config); } return context.require(deps, callback, errback); }; /** * Support require.config() to make it easier to cooperate with other * AMD loaders on globally agreed names. */ req.config = function (config) { return req(config); }; /** * Execute something after the current tick * of the event loop. Override for other envs * that have a better solution than setTimeout. * @param {Function} fn function to execute later. */ req.nextTick = typeof setTimeout !== 'undefined' ? function (fn) { setTimeout(fn, 4); } : function (fn) { fn(); }; /** * Export require as a global, but only if it does not already exist. */ if (!require) { require = req; } req.version = version; //Used to filter out dependencies that are already paths. req.jsExtRegExp = /^\/|:|\?|\.js$/; req.isBrowser = isBrowser; s = req.s = { contexts: contexts, newContext: newContext }; //Create default context. req({}); //Exports some context-sensitive methods on global require. each([ 'toUrl', 'undef', 'defined', 'specified' ], function (prop) { //Reference from contexts instead of early binding to default context, //so that during builds, the latest instance of the default context //with its config gets used. req[prop] = function () { var ctx = contexts[defContextName]; return ctx.require[prop].apply(ctx, arguments); }; }); if (isBrowser) { head = s.head = document.getElementsByTagName('head')[0]; //If BASE tag is in play, using appendChild is a problem for IE6. //When that browser dies, this can be removed. Details in this jQuery bug: //http://dev.jquery.com/ticket/2709 baseElement = document.getElementsByTagName('base')[0]; if (baseElement) { head = s.head = baseElement.parentNode; } } /** * Any errors that require explicitly generates will be passed to this * function. Intercept/override it if you want custom error handling. * @param {Error} err the error object. */ req.onError = defaultOnError; /** * Creates the node for the load command. Only used in browser envs. */ req.createNode = function (config, moduleName, url) { var node = config.xhtml ? document.createElementNS('http://www.w3.org/1999/xhtml', 'html:script') : document.createElement('script'); node.type = config.scriptType || 'text/javascript'; node.charset = 'utf-8'; node.async = true; return node; }; /** * Does the request to load a module for the browser case. * Make this a separate function to allow other environments * to override it. * * @param {Object} context the require context to find state. * @param {String} moduleName the name of the module. * @param {Object} url the URL to the module. */ req.load = function (context, moduleName, url) { var config = (context && context.config) || {}, node; if (isBrowser) { //In the browser so use a script tag node = req.createNode(config, moduleName, url); node.setAttribute('data-requirecontext', context.contextName); node.setAttribute('data-requiremodule', moduleName); //Set up load listener. Test attachEvent first because IE9 has //a subtle issue in its addEventListener and script onload firings //that do not match the behavior of all other browsers with //addEventListener support, which fire the onload event for a //script right after the script execution. See: //https://connect.microsoft.com/IE/feedback/details/648057/script-onload-event-is-not-fired-immediately-after-script-execution //UNFORTUNATELY Opera implements attachEvent but does not follow the script //script execution mode. if (node.attachEvent && //Check if node.attachEvent is artificially added by custom script or //natively supported by browser //read https://github.com/jrburke/requirejs/issues/187 //if we can NOT find [native code] then it must NOT natively supported. //in IE8, node.attachEvent does not have toString() //Note the test for "[native code" with no closing brace, see: //https://github.com/jrburke/requirejs/issues/273 !(node.attachEvent.toString && node.attachEvent.toString().indexOf('[native code') < 0) && !isOpera) { //Probably IE. IE (at least 6-8) do not fire //script onload right after executing the script, so //we cannot tie the anonymous define call to a name. //However, IE reports the script as being in 'interactive' //readyState at the time of the define call. useInteractive = true; node.attachEvent('onreadystatechange', context.onScriptLoad); //It would be great to add an error handler here to catch //404s in IE9+. However, onreadystatechange will fire before //the error handler, so that does not help. If addEventListener //is used, then IE will fire error before load, but we cannot //use that pathway given the connect.microsoft.com issue //mentioned above about not doing the 'script execute, //then fire the script load event listener before execute //next script' that other browsers do. //Best hope: IE10 fixes the issues, //and then destroys all installs of IE 6-9. //node.attachEvent('onerror', context.onScriptError); } else { node.addEventListener('load', context.onScriptLoad, false); node.addEventListener('error', context.onScriptError, false); } node.src = url; //For some cache cases in IE 6-8, the script executes before the end //of the appendChild execution, so to tie an anonymous define //call to the module name (which is stored on the node), hold on //to a reference to this node, but clear after the DOM insertion. currentlyAddingScript = node; if (baseElement) { head.insertBefore(node, baseElement); } else { head.appendChild(node); } currentlyAddingScript = null; return node; } else if (isWebWorker) { try { //In a web worker, use importScripts. This is not a very //efficient use of importScripts, importScripts will block until //its script is downloaded and evaluated. However, if web workers //are in play, the expectation that a build has been done so that //only one script needs to be loaded anyway. This may need to be //reevaluated if other use cases become common. importScripts(url); //Account for anonymous modules context.completeLoad(moduleName); } catch (e) { context.onError(makeError('importscripts', 'importScripts failed for ' + moduleName + ' at ' + url, e, [moduleName])); } } }; function getInteractiveScript() { if (interactiveScript && interactiveScript.readyState === 'interactive') { return interactiveScript; } eachReverse(scripts(), function (script) { if (script.readyState === 'interactive') { return (interactiveScript = script); } }); return interactiveScript; } //Look for a data-main script attribute, which could also adjust the baseUrl. if (isBrowser && !cfg.skipDataMain) { //Figure out baseUrl. Get it from the script tag with require.js in it. eachReverse(scripts(), function (script) { //Set the 'head' where we can append children by //using the script's parent. if (!head) { head = script.parentNode; } //Look for a data-main attribute to set main script for the page //to load. If it is there, the path to data main becomes the //baseUrl, if it is not already set. dataMain = script.getAttribute('data-main'); if (dataMain) { //Preserve dataMain in case it is a path (i.e. contains '?') mainScript = dataMain; //Set final baseUrl if there is not already an explicit one. if (!cfg.baseUrl) { //Pull off the directory of data-main for use as the //baseUrl. src = mainScript.split('/'); mainScript = src.pop(); subPath = src.length ? src.join('/') + '/' : './'; cfg.baseUrl = subPath; } //Strip off any trailing .js since mainScript is now //like a module name. mainScript = mainScript.replace(jsSuffixRegExp, ''); //If mainScript is still a path, fall back to dataMain if (req.jsExtRegExp.test(mainScript)) { mainScript = dataMain; } //Put the data-main script in the files to load. cfg.deps = cfg.deps ? cfg.deps.concat(mainScript) : [mainScript]; return true; } }); } /** * The function that handles definitions of modules. Differs from * require() in that a string for the module should be the first argument, * and the function to execute after dependencies are loaded should * return a value to define the module corresponding to the first argument's * name. */ define = function (name, deps, callback) { var node, context; //Allow for anonymous modules if (typeof name !== 'string') { //Adjust args appropriately callback = deps; deps = name; name = null; } //This module may not have dependencies if (!isArray(deps)) { callback = deps; deps = null; } //If no name, and callback is a function, then figure out if it a //CommonJS thing with dependencies. if (!deps && isFunction(callback)) { deps = []; //Remove comments from the callback string, //look for require calls, and pull them into the dependencies, //but only if there are function args. if (callback.length) { callback .toString() .replace(commentRegExp, '') .replace(cjsRequireRegExp, function (match, dep) { deps.push(dep); }); //May be a CommonJS thing even without require calls, but still //could use exports, and module. Avoid doing exports and module //work though if it just needs require. //REQUIRES the function to expect the CommonJS variables in the //order listed below. deps = (callback.length === 1 ? ['require'] : ['require', 'exports', 'module']).concat(deps); } } //If in IE 6-8 and hit an anonymous define() call, do the interactive //work. if (useInteractive) { node = currentlyAddingScript || getInteractiveScript(); if (node) { if (!name) { name = node.getAttribute('data-requiremodule'); } context = contexts[node.getAttribute('data-requirecontext')]; } } //Always save off evaluating the def call until the script onload handler. //This allows multiple modules to be in a file without prematurely //tracing dependencies, and allows for anonymous module support, //where the module name is not known until the script onload event //occurs. If no context, use the global queue, and get it processed //in the onscript load callback. (context ? context.defQueue : globalDefQueue).push([name, deps, callback]); }; define.amd = { jQuery: true }; /** * Executes the text. Normally just uses eval, but can be modified * to use a better, environment-specific call. Only used for transpiling * loader plugins, not for plain JS modules. * @param {String} text the text to execute/evaluate. */ req.exec = function (text) { /*jslint evil: true */ return eval(text); }; //Set up with config info. req(cfg); }(this)); handlebars.js-4.7.7/spec/visitor.js000066400000000000000000000117531401244020700172370ustar00rootroot00000000000000describe('Visitor', function() { if (!Handlebars.Visitor || !Handlebars.print) { return; } it('should provide coverage', function() { // Simply run the thing and make sure it does not fail and that all of the // stub methods are executed var visitor = new Handlebars.Visitor(); visitor.accept( Handlebars.parse( '{{foo}}{{#foo (bar 1 "1" true undefined null) foo=@data}}{{!comment}}{{> bar }} {{/foo}}' ) ); visitor.accept(Handlebars.parse('{{#> bar }} {{/bar}}')); visitor.accept(Handlebars.parse('{{#* bar }} {{/bar}}')); visitor.accept(Handlebars.parse('{{* bar }}')); }); it('should traverse to stubs', function() { var visitor = new Handlebars.Visitor(); visitor.StringLiteral = function(string) { equal(string.value, '2'); }; visitor.NumberLiteral = function(number) { equal(number.value, 1); }; visitor.BooleanLiteral = function(bool) { equal(bool.value, true); equal(this.parents.length, 3); equal(this.parents[0].type, 'SubExpression'); equal(this.parents[1].type, 'BlockStatement'); equal(this.parents[2].type, 'Program'); }; visitor.PathExpression = function(id) { equal(/(foo\.)?bar$/.test(id.original), true); }; visitor.ContentStatement = function(content) { equal(content.value, ' '); }; visitor.CommentStatement = function(comment) { equal(comment.value, 'comment'); }; visitor.accept( Handlebars.parse( '{{#foo.bar (foo.bar 1 "2" true) foo=@foo.bar}}{{!comment}}{{> bar }} {{/foo.bar}}' ) ); }); describe('mutating', function() { describe('fields', function() { it('should replace value', function() { var visitor = new Handlebars.Visitor(); visitor.mutating = true; visitor.StringLiteral = function(string) { return { type: 'NumberLiteral', value: 42, loc: string.loc }; }; var ast = Handlebars.parse('{{foo foo="foo"}}'); visitor.accept(ast); equals( Handlebars.print(ast), '{{ PATH:foo [] HASH{foo=NUMBER{42}} }}\n' ); }); it('should treat undefined resonse as identity', function() { var visitor = new Handlebars.Visitor(); visitor.mutating = true; var ast = Handlebars.parse('{{foo foo=42}}'); visitor.accept(ast); equals( Handlebars.print(ast), '{{ PATH:foo [] HASH{foo=NUMBER{42}} }}\n' ); }); it('should remove false responses', function() { var visitor = new Handlebars.Visitor(); visitor.mutating = true; visitor.Hash = function() { return false; }; var ast = Handlebars.parse('{{foo foo=42}}'); visitor.accept(ast); equals(Handlebars.print(ast), '{{ PATH:foo [] }}\n'); }); it('should throw when removing required values', function() { shouldThrow( function() { var visitor = new Handlebars.Visitor(); visitor.mutating = true; visitor.PathExpression = function() { return false; }; var ast = Handlebars.parse('{{foo 42}}'); visitor.accept(ast); }, Handlebars.Exception, 'MustacheStatement requires path' ); }); it('should throw when returning non-node responses', function() { shouldThrow( function() { var visitor = new Handlebars.Visitor(); visitor.mutating = true; visitor.PathExpression = function() { return {}; }; var ast = Handlebars.parse('{{foo 42}}'); visitor.accept(ast); }, Handlebars.Exception, 'Unexpected node type "undefined" found when accepting path on MustacheStatement' ); }); }); describe('arrays', function() { it('should replace value', function() { var visitor = new Handlebars.Visitor(); visitor.mutating = true; visitor.StringLiteral = function(string) { return { type: 'NumberLiteral', value: 42, loc: string.locInfo }; }; var ast = Handlebars.parse('{{foo "foo"}}'); visitor.accept(ast); equals(Handlebars.print(ast), '{{ PATH:foo [NUMBER{42}] }}\n'); }); it('should treat undefined resonse as identity', function() { var visitor = new Handlebars.Visitor(); visitor.mutating = true; var ast = Handlebars.parse('{{foo 42}}'); visitor.accept(ast); equals(Handlebars.print(ast), '{{ PATH:foo [NUMBER{42}] }}\n'); }); it('should remove false responses', function() { var visitor = new Handlebars.Visitor(); visitor.mutating = true; visitor.NumberLiteral = function() { return false; }; var ast = Handlebars.parse('{{foo 42}}'); visitor.accept(ast); equals(Handlebars.print(ast), '{{ PATH:foo [] }}\n'); }); }); }); }); handlebars.js-4.7.7/spec/whitespace-control.js000066400000000000000000000105231401244020700213440ustar00rootroot00000000000000describe('whitespace control', function() { it('should strip whitespace around mustache calls', function() { var hash = { foo: 'bar<' }; expectTemplate(' {{~foo~}} ') .withInput(hash) .toCompileTo('bar<'); expectTemplate(' {{~foo}} ') .withInput(hash) .toCompileTo('bar< '); expectTemplate(' {{foo~}} ') .withInput(hash) .toCompileTo(' bar<'); expectTemplate(' {{~&foo~}} ') .withInput(hash) .toCompileTo('bar<'); expectTemplate(' {{~{foo}~}} ') .withInput(hash) .toCompileTo('bar<'); expectTemplate('1\n{{foo~}} \n\n 23\n{{bar}}4').toCompileTo('1\n23\n4'); }); describe('blocks', function() { it('should strip whitespace around simple block calls', function() { var hash = { foo: 'bar<' }; expectTemplate(' {{~#if foo~}} bar {{~/if~}} ') .withInput(hash) .toCompileTo('bar'); expectTemplate(' {{#if foo~}} bar {{/if~}} ') .withInput(hash) .toCompileTo(' bar '); expectTemplate(' {{~#if foo}} bar {{~/if}} ') .withInput(hash) .toCompileTo(' bar '); expectTemplate(' {{#if foo}} bar {{/if}} ') .withInput(hash) .toCompileTo(' bar '); expectTemplate(' \n\n{{~#if foo~}} \n\nbar \n\n{{~/if~}}\n\n ') .withInput(hash) .toCompileTo('bar'); expectTemplate(' a\n\n{{~#if foo~}} \n\nbar \n\n{{~/if~}}\n\na ') .withInput(hash) .toCompileTo(' abara '); }); it('should strip whitespace around inverse block calls', function() { expectTemplate(' {{~^if foo~}} bar {{~/if~}} ').toCompileTo('bar'); expectTemplate(' {{^if foo~}} bar {{/if~}} ').toCompileTo(' bar '); expectTemplate(' {{~^if foo}} bar {{~/if}} ').toCompileTo(' bar '); expectTemplate(' {{^if foo}} bar {{/if}} ').toCompileTo(' bar '); expectTemplate( ' \n\n{{~^if foo~}} \n\nbar \n\n{{~/if~}}\n\n ' ).toCompileTo('bar'); }); it('should strip whitespace around complex block calls', function() { var hash = { foo: 'bar<' }; expectTemplate('{{#if foo~}} bar {{~^~}} baz {{~/if}}') .withInput(hash) .toCompileTo('bar'); expectTemplate('{{#if foo~}} bar {{^~}} baz {{/if}}') .withInput(hash) .toCompileTo('bar '); expectTemplate('{{#if foo}} bar {{~^~}} baz {{~/if}}') .withInput(hash) .toCompileTo(' bar'); expectTemplate('{{#if foo}} bar {{^~}} baz {{/if}}') .withInput(hash) .toCompileTo(' bar '); expectTemplate('{{#if foo~}} bar {{~else~}} baz {{~/if}}') .withInput(hash) .toCompileTo('bar'); expectTemplate( '\n\n{{~#if foo~}} \n\nbar \n\n{{~^~}} \n\nbaz \n\n{{~/if~}}\n\n' ) .withInput(hash) .toCompileTo('bar'); expectTemplate( '\n\n{{~#if foo~}} \n\n{{{foo}}} \n\n{{~^~}} \n\nbaz \n\n{{~/if~}}\n\n' ) .withInput(hash) .toCompileTo('bar<'); expectTemplate('{{#if foo~}} bar {{~^~}} baz {{~/if}}').toCompileTo( 'baz' ); expectTemplate('{{#if foo}} bar {{~^~}} baz {{/if}}').toCompileTo('baz '); expectTemplate('{{#if foo~}} bar {{~^}} baz {{~/if}}').toCompileTo( ' baz' ); expectTemplate('{{#if foo~}} bar {{~^}} baz {{/if}}').toCompileTo( ' baz ' ); expectTemplate('{{#if foo~}} bar {{~else~}} baz {{~/if}}').toCompileTo( 'baz' ); expectTemplate( '\n\n{{~#if foo~}} \n\nbar \n\n{{~^~}} \n\nbaz \n\n{{~/if~}}\n\n' ).toCompileTo('baz'); }); }); it('should strip whitespace around partials', function() { expectTemplate('foo {{~> dude~}} ') .withPartials({ dude: 'bar' }) .toCompileTo('foobar'); expectTemplate('foo {{> dude~}} ') .withPartials({ dude: 'bar' }) .toCompileTo('foo bar'); expectTemplate('foo {{> dude}} ') .withPartials({ dude: 'bar' }) .toCompileTo('foo bar '); expectTemplate('foo\n {{~> dude}} ') .withPartials({ dude: 'bar' }) .toCompileTo('foobar'); expectTemplate('foo\n {{> dude}} ') .withPartials({ dude: 'bar' }) .toCompileTo('foo\n bar'); }); it('should only strip whitespace once', function() { expectTemplate(' {{~foo~}} {{foo}} {{foo}} ') .withInput({ foo: 'bar' }) .toCompileTo('barbar bar '); }); }); handlebars.js-4.7.7/src/000077500000000000000000000000001401244020700150305ustar00rootroot00000000000000handlebars.js-4.7.7/src/handlebars.l000066400000000000000000000117771401244020700173250ustar00rootroot00000000000000 %x mu emu com raw %{ function strip(start, end) { return yytext = yytext.substring(start, yyleng - end + start); } %} LEFT_STRIP "~" RIGHT_STRIP "~" LOOKAHEAD [=~}\s\/.)|] LITERAL_LOOKAHEAD [~}\s)] /* ID is the inverse of control characters. Control characters ranges: [\s] Whitespace [!"#%-,\./] !, ", #, %, &, ', (, ), *, +, ,, ., /, Exceptions in range: $, - [;->@] ;, <, =, >, @, Exceptions in range: :, ? [\[-\^`] [, \, ], ^, `, Exceptions in range: _ [\{-~] {, |, }, ~ */ ID [^\s!"#%-,\.\/;->@\[-\^`\{-~]+/{LOOKAHEAD} %% [^\x00]*?/("{{") { if(yytext.slice(-2) === "\\\\") { strip(0,1); this.begin("mu"); } else if(yytext.slice(-1) === "\\") { strip(0,1); this.begin("emu"); } else { this.begin("mu"); } if(yytext) return 'CONTENT'; } [^\x00]+ return 'CONTENT'; // marks CONTENT up to the next mustache or escaped mustache [^\x00]{2,}?/("{{"|"\\{{"|"\\\\{{"|<>) { this.popState(); return 'CONTENT'; } // nested raw block will create stacked 'raw' condition "{{{{"/[^/] this.begin('raw'); return 'CONTENT'; "{{{{/"[^\s!"#%-,\.\/;->@\[-\^`\{-~]+/[=}\s\/.]"}}}}" { this.popState(); // Should be using `this.topState()` below, but it currently // returns the second top instead of the first top. Opened an // issue about it at https://github.com/zaach/jison/issues/291 if (this.conditionStack[this.conditionStack.length-1] === 'raw') { return 'CONTENT'; } else { strip(5, 9); return 'END_RAW_BLOCK'; } } [^\x00]+?/("{{{{") { return 'CONTENT'; } [\s\S]*?"--"{RIGHT_STRIP}?"}}" { this.popState(); return 'COMMENT'; } "(" return 'OPEN_SEXPR'; ")" return 'CLOSE_SEXPR'; "{{{{" { return 'OPEN_RAW_BLOCK'; } "}}}}" { this.popState(); this.begin('raw'); return 'CLOSE_RAW_BLOCK'; } "{{"{LEFT_STRIP}?">" return 'OPEN_PARTIAL'; "{{"{LEFT_STRIP}?"#>" return 'OPEN_PARTIAL_BLOCK'; "{{"{LEFT_STRIP}?"#""*"? return 'OPEN_BLOCK'; "{{"{LEFT_STRIP}?"/" return 'OPEN_ENDBLOCK'; "{{"{LEFT_STRIP}?"^"\s*{RIGHT_STRIP}?"}}" this.popState(); return 'INVERSE'; "{{"{LEFT_STRIP}?\s*"else"\s*{RIGHT_STRIP}?"}}" this.popState(); return 'INVERSE'; "{{"{LEFT_STRIP}?"^" return 'OPEN_INVERSE'; "{{"{LEFT_STRIP}?\s*"else" return 'OPEN_INVERSE_CHAIN'; "{{"{LEFT_STRIP}?"{" return 'OPEN_UNESCAPED'; "{{"{LEFT_STRIP}?"&" return 'OPEN'; "{{"{LEFT_STRIP}?"!--" { this.unput(yytext); this.popState(); this.begin('com'); } "{{"{LEFT_STRIP}?"!"[\s\S]*?"}}" { this.popState(); return 'COMMENT'; } "{{"{LEFT_STRIP}?"*"? return 'OPEN'; "=" return 'EQUALS'; ".." return 'ID'; "."/{LOOKAHEAD} return 'ID'; [\/.] return 'SEP'; \s+ // ignore whitespace "}"{RIGHT_STRIP}?"}}" this.popState(); return 'CLOSE_UNESCAPED'; {RIGHT_STRIP}?"}}" this.popState(); return 'CLOSE'; '"'("\\"["]|[^"])*'"' yytext = strip(1,2).replace(/\\"/g,'"'); return 'STRING'; "'"("\\"[']|[^'])*"'" yytext = strip(1,2).replace(/\\'/g,"'"); return 'STRING'; "@" return 'DATA'; "true"/{LITERAL_LOOKAHEAD} return 'BOOLEAN'; "false"/{LITERAL_LOOKAHEAD} return 'BOOLEAN'; "undefined"/{LITERAL_LOOKAHEAD} return 'UNDEFINED'; "null"/{LITERAL_LOOKAHEAD} return 'NULL'; \-?[0-9]+(?:\.[0-9]+)?/{LITERAL_LOOKAHEAD} return 'NUMBER'; "as"\s+"|" return 'OPEN_BLOCK_PARAMS'; "|" return 'CLOSE_BLOCK_PARAMS'; {ID} return 'ID'; '['('\\]'|[^\]])*']' yytext = yytext.replace(/\\([\\\]])/g,'$1'); return 'ID'; . return 'INVALID'; <> return 'EOF'; handlebars.js-4.7.7/src/handlebars.yy000066400000000000000000000102531401244020700175170ustar00rootroot00000000000000%start root %ebnf %% root : program EOF { return $1; } ; program : statement* -> yy.prepareProgram($1) ; statement : mustache -> $1 | block -> $1 | rawBlock -> $1 | partial -> $1 | partialBlock -> $1 | content -> $1 | COMMENT { $$ = { type: 'CommentStatement', value: yy.stripComment($1), strip: yy.stripFlags($1, $1), loc: yy.locInfo(@$) }; }; content : CONTENT { $$ = { type: 'ContentStatement', original: $1, value: $1, loc: yy.locInfo(@$) }; }; rawBlock : openRawBlock content* END_RAW_BLOCK -> yy.prepareRawBlock($1, $2, $3, @$) ; openRawBlock : OPEN_RAW_BLOCK helperName param* hash? CLOSE_RAW_BLOCK -> { path: $2, params: $3, hash: $4 } ; block : openBlock program inverseChain? closeBlock -> yy.prepareBlock($1, $2, $3, $4, false, @$) | openInverse program inverseAndProgram? closeBlock -> yy.prepareBlock($1, $2, $3, $4, true, @$) ; openBlock : OPEN_BLOCK helperName param* hash? blockParams? CLOSE -> { open: $1, path: $2, params: $3, hash: $4, blockParams: $5, strip: yy.stripFlags($1, $6) } ; openInverse : OPEN_INVERSE helperName param* hash? blockParams? CLOSE -> { path: $2, params: $3, hash: $4, blockParams: $5, strip: yy.stripFlags($1, $6) } ; openInverseChain : OPEN_INVERSE_CHAIN helperName param* hash? blockParams? CLOSE -> { path: $2, params: $3, hash: $4, blockParams: $5, strip: yy.stripFlags($1, $6) } ; inverseAndProgram : INVERSE program -> { strip: yy.stripFlags($1, $1), program: $2 } ; inverseChain : openInverseChain program inverseChain? { var inverse = yy.prepareBlock($1, $2, $3, $3, false, @$), program = yy.prepareProgram([inverse], $2.loc); program.chained = true; $$ = { strip: $1.strip, program: program, chain: true }; } | inverseAndProgram -> $1 ; closeBlock : OPEN_ENDBLOCK helperName CLOSE -> {path: $2, strip: yy.stripFlags($1, $3)} ; mustache // Parsing out the '&' escape token at AST level saves ~500 bytes after min due to the removal of one parser node. // This also allows for handler unification as all mustache node instances can utilize the same handler : OPEN helperName param* hash? CLOSE -> yy.prepareMustache($2, $3, $4, $1, yy.stripFlags($1, $5), @$) | OPEN_UNESCAPED helperName param* hash? CLOSE_UNESCAPED -> yy.prepareMustache($2, $3, $4, $1, yy.stripFlags($1, $5), @$) ; partial : OPEN_PARTIAL partialName param* hash? CLOSE { $$ = { type: 'PartialStatement', name: $2, params: $3, hash: $4, indent: '', strip: yy.stripFlags($1, $5), loc: yy.locInfo(@$) }; } ; partialBlock : openPartialBlock program closeBlock -> yy.preparePartialBlock($1, $2, $3, @$) ; openPartialBlock : OPEN_PARTIAL_BLOCK partialName param* hash? CLOSE -> { path: $2, params: $3, hash: $4, strip: yy.stripFlags($1, $5) } ; param : helperName -> $1 | sexpr -> $1 ; sexpr : OPEN_SEXPR helperName param* hash? CLOSE_SEXPR { $$ = { type: 'SubExpression', path: $2, params: $3, hash: $4, loc: yy.locInfo(@$) }; }; hash : hashSegment+ -> {type: 'Hash', pairs: $1, loc: yy.locInfo(@$)} ; hashSegment : ID EQUALS param -> {type: 'HashPair', key: yy.id($1), value: $3, loc: yy.locInfo(@$)} ; blockParams : OPEN_BLOCK_PARAMS ID+ CLOSE_BLOCK_PARAMS -> yy.id($2) ; helperName : path -> $1 | dataName -> $1 | STRING -> {type: 'StringLiteral', value: $1, original: $1, loc: yy.locInfo(@$)} | NUMBER -> {type: 'NumberLiteral', value: Number($1), original: Number($1), loc: yy.locInfo(@$)} | BOOLEAN -> {type: 'BooleanLiteral', value: $1 === 'true', original: $1 === 'true', loc: yy.locInfo(@$)} | UNDEFINED -> {type: 'UndefinedLiteral', original: undefined, value: undefined, loc: yy.locInfo(@$)} | NULL -> {type: 'NullLiteral', original: null, value: null, loc: yy.locInfo(@$)} ; partialName : helperName -> $1 | sexpr -> $1 ; dataName : DATA pathSegments -> yy.preparePath(true, $2, @$) ; path : pathSegments -> yy.preparePath(false, $1, @$) ; pathSegments : pathSegments SEP ID { $1.push({part: yy.id($3), original: $3, separator: $2}); $$ = $1; } | ID -> [{part: yy.id($1), original: $1}] ; handlebars.js-4.7.7/src/parser-prefix.js000066400000000000000000000000771401244020700201610ustar00rootroot00000000000000// File ignored in coverage tests via setting in .istanbul.yml handlebars.js-4.7.7/src/parser-suffix.js000066400000000000000000000000331401244020700201600ustar00rootroot00000000000000export default handlebars; handlebars.js-4.7.7/tasks/000077500000000000000000000000001401244020700153665ustar00rootroot00000000000000handlebars.js-4.7.7/tasks/.eslintrc.js000066400000000000000000000004571401244020700176330ustar00rootroot00000000000000module.exports = { extends: ['../.eslintrc.js'], parserOptions: { sourceType: 'module', ecmaVersion: 2017, ecmaFeatures: {} }, rules: { 'no-process-env': 'off', 'prefer-const': 'warn', 'compat/compat': 'off', 'dot-notation': ['error', { allowKeywords: true }] } }; handlebars.js-4.7.7/tasks/metrics.js000066400000000000000000000013471401244020700173770ustar00rootroot00000000000000const metrics = require('../bench'); const { createRegisterAsyncTaskFn } = require('./util/async-grunt-task'); module.exports = function(grunt) { const registerAsyncTask = createRegisterAsyncTaskFn(grunt); registerAsyncTask('metrics', function() { const onlyExecuteName = grunt.option('name'); const events = {}; const promises = Object.keys(metrics).map(async name => { if (/^_/.test(name)) { return; } if (onlyExecuteName != null && name !== onlyExecuteName) { return; } return new Promise(resolve => { metrics[name](grunt, function(data) { events[name] = data; resolve(); }); }); }); return Promise.all(promises); }); }; handlebars.js-4.7.7/tasks/parser.js000066400000000000000000000016761401244020700172320ustar00rootroot00000000000000const { execFileWithInheritedOutput } = require('./util/exec-file'); const { createRegisterAsyncTaskFn } = require('./util/async-grunt-task'); const OUTPUT_FILE = 'lib/handlebars/compiler/parser.js'; module.exports = function(grunt) { const registerAsyncTask = createRegisterAsyncTaskFn(grunt); registerAsyncTask('parser', async () => { await runJison(); combineWithPrefixAndSuffix(); grunt.log.writeln(`Parser "${OUTPUT_FILE}" created.`); }); async function runJison() { await execFileWithInheritedOutput('jison', [ '-m', 'js', 'src/handlebars.yy', 'src/handlebars.l' ]); } function combineWithPrefixAndSuffix() { const combinedParserSourceCode = grunt.file.read('src/parser-prefix.js') + grunt.file.read('handlebars.js') + grunt.file.read('src/parser-suffix.js'); grunt.file.write(OUTPUT_FILE, combinedParserSourceCode); grunt.file.delete('handlebars.js'); } }; handlebars.js-4.7.7/tasks/publish-to-aws.js000066400000000000000000000054371401244020700206130ustar00rootroot00000000000000const AWS = require('aws-sdk'); const git = require('./util/git'); const { createRegisterAsyncTaskFn } = require('./util/async-grunt-task'); const semver = require('semver'); module.exports = function(grunt) { const registerAsyncTask = createRegisterAsyncTaskFn(grunt); registerAsyncTask('publish-to-aws', async () => { grunt.log.writeln('remotes: ' + (await git.remotes())); grunt.log.writeln('branches: ' + (await git.branches())); const commitInfo = await git.commitInfo(); grunt.log.writeln('tag: ', commitInfo.tagName); const suffixes = []; // Publish the master as "latest" and with the commit-id if (commitInfo.isMaster) { suffixes.push('-latest'); suffixes.push('-' + commitInfo.headSha); } // Publish tags by their tag-name if (commitInfo.tagName != null && semver.valid(commitInfo.tagName)) { suffixes.push('-' + commitInfo.tagName); } if (suffixes.length > 0) { initSDK(); grunt.log.writeln( 'publishing file-suffixes: ' + JSON.stringify(suffixes) ); await publish(suffixes); } }); function initSDK() { const bucket = process.env.S3_BUCKET_NAME, key = process.env.S3_ACCESS_KEY_ID, secret = process.env.S3_SECRET_ACCESS_KEY; if (!bucket || !key || !secret) { throw new Error('Missing S3 config values'); } AWS.config.update({ accessKeyId: key, secretAccessKey: secret }); } async function publish(suffixes) { const publishPromises = suffixes.map(suffix => publishSuffix(suffix)); return Promise.all(publishPromises); } async function publishSuffix(suffix) { const filenames = [ 'handlebars.js', 'handlebars.min.js', 'handlebars.runtime.js', 'handlebars.runtime.min.js' ]; const publishPromises = filenames.map(async filename => { const nameInBucket = getNameInBucket(filename, suffix); const localFile = getLocalFile(filename); await uploadToBucket(localFile, nameInBucket); grunt.log.writeln( `Published ${localFile} to build server (${nameInBucket})` ); }); return Promise.all(publishPromises); } async function uploadToBucket(localFile, nameInBucket) { const bucket = process.env.S3_BUCKET_NAME; const uploadParams = { Bucket: bucket, Key: nameInBucket, Body: grunt.file.read(localFile) }; return s3PutObject(uploadParams); } }; function s3PutObject(uploadParams) { const s3 = new AWS.S3(); return new Promise((resolve, reject) => { s3.putObject(uploadParams, err => { if (err != null) { return reject(err); } resolve(); }); }); } function getNameInBucket(filename, suffix) { return filename.replace(/\.js$/, suffix + '.js'); } function getLocalFile(filename) { return 'dist/' + filename; } handlebars.js-4.7.7/tasks/task-tests/000077500000000000000000000000001401244020700174705ustar00rootroot00000000000000handlebars.js-4.7.7/tasks/task-tests/.eslintrc.js000066400000000000000000000002021401244020700217210ustar00rootroot00000000000000module.exports = { extends: '../../.eslintrc.js', env: { mocha: true }, parserOptions: { ecmaVersion: 2018 } }; handlebars.js-4.7.7/tasks/task-tests/README.md000066400000000000000000000000601401244020700207430ustar00rootroot00000000000000Use `mocha tasks/task-tests` to run these tests handlebars.js-4.7.7/tasks/task-tests/git.test.js000066400000000000000000000076451401244020700216030ustar00rootroot00000000000000const os = require('os'); const path = require('path'); const fs = require('fs-extra'); const chai = require('chai'); chai.use(require('dirty-chai')); const git = require('../util/git'); const expect = chai.expect; const tmpBaseDir = path.join(os.tmpdir(), 'handlebars-task-tests'); const tmpDir = path.join(tmpBaseDir, Date.now().toString(36)); const remoteDir = path.join(tmpDir, 'remote-repo'); const cloneDir = path.join(tmpDir, 'clone-repo'); const oldCwd = process.cwd(); describe('utils/git', function() { beforeEach(async function() { await fs.remove(tmpDir); await createRepositoryThatActsAsRemote(); process.chdir(tmpDir); await git.git('clone', 'remote-repo', 'clone-repo'); process.chdir(cloneDir); }); async function createRepositoryThatActsAsRemote() { await fs.mkdirp(remoteDir); process.chdir(remoteDir); await git.git('init'); await fs.writeFile('testfile.txt', 'Testfile'); await git.add('testfile.txt'); await git.commit('commit message'); } afterEach(function() { process.chdir(oldCwd); }); describe('the "remotes"-function', function() { it('should list all remotes', async function() { await git.git('remote', 'set-url', 'origin', 'https://test.org/test'); await git.git('remote', 'add', 'second-remote', 'https://test.org/test2'); const result = await git.remotes(); expect(result.trim().split('\n')).to.deep.equal([ 'origin\thttps://test.org/test (fetch)', 'origin\thttps://test.org/test (push)', 'second-remote\thttps://test.org/test2 (fetch)', 'second-remote\thttps://test.org/test2 (push)' ]); }); }); describe('the "branches"-function', function() { it('should list all branches', async function() { await git.git('branch', 'test'); await git.git('branch', 'test2'); const result = await git.branches(); expect(result.trim().split('\n')).to.deep.equal([ '* master', ' test', ' test2', ' remotes/origin/HEAD -> origin/master', ' remotes/origin/master' ]); }); }); describe('the "commitInfo"-function', function() { it('should list head and master sha', async function() { const result = await git.commitInfo(); expect(result.masterSha).to.equal(result.headSha); expect(result.masterSha).to.match(/^[0-9a-f]+$/); expect(result.headSha).to.match(/^[0-9a-f]+$/); }); it('should have "isMaster=true" if the master branch is checked out', async function() { const result = await git.commitInfo(); expect(result.isMaster).to.be.true(); }); it('should have "isMaster=true" if the current commit is the last commit of the master branch', async function() { await git.git('checkout', '-b', 'new-branch'); const result = await git.commitInfo(); expect(result.isMaster).to.be.true(); }); it('should have "isMaster=false" if the current commit is NOT the last commit of the master branch', async function() { await git.git('checkout', '-b', 'new-branch'); fs.writeFile('new-file.txt', 'new-file'); await git.add('new-file.txt'); await git.commit('added new file'); const result = await git.commitInfo(); expect(result.isMaster).to.be.false(); }); it('should show the current tag', async function() { await git.git('tag', 'test-tag'); const result = await git.commitInfo(); expect(result.tagName).to.be.equal('test-tag'); }); it('should show a version tag rather than standard tags', async function() { await git.git('tag', 'test-tag'); await git.git('tag', 'v1.2'); await git.git('tag', 'test-tag2'); const result = await git.commitInfo(); expect(result.tagName).to.be.equal('v1.2'); }); it('should show no tag if there is no tag', async function() { const result = await git.commitInfo(); expect(result.tagName).to.be.null(); }); }); }); handlebars.js-4.7.7/tasks/task-tests/mocha.opts000066400000000000000000000000001401244020700214540ustar00rootroot00000000000000handlebars.js-4.7.7/tasks/test-bin.js000066400000000000000000000131761401244020700174610ustar00rootroot00000000000000const childProcess = require('child_process'); const fs = require('fs'); const os = require('os'); const path = require('path'); const chai = require('chai'); chai.use(require('chai-diff')); const expect = chai.expect; const testCases = [ { binInputParameters: ['-a', 'spec/artifacts/empty.handlebars'], outputLocation: 'stdout', expectedOutputSpec: './spec/expected/empty.amd.js' }, { binInputParameters: [ '-a', '-f', 'TEST_OUTPUT', 'spec/artifacts/empty.handlebars' ], outputLocation: 'TEST_OUTPUT', expectedOutputSpec: './spec/expected/empty.amd.js' }, { binInputParameters: [ '-a', '-n', 'CustomNamespace.templates', 'spec/artifacts/empty.handlebars' ], outputLocation: 'stdout', expectedOutputSpec: './spec/expected/empty.amd.namespace.js' }, { binInputParameters: [ '-a', '--namespace', 'CustomNamespace.templates', 'spec/artifacts/empty.handlebars' ], outputLocation: 'stdout', expectedOutputSpec: './spec/expected/empty.amd.namespace.js' }, { binInputParameters: ['-a', '-s', 'spec/artifacts/empty.handlebars'], outputLocation: 'stdout', expectedOutputSpec: './spec/expected/empty.amd.simple.js' }, { binInputParameters: ['-a', '-m', 'spec/artifacts/empty.handlebars'], outputLocation: 'stdout', expectedOutputSpec: './spec/expected/empty.amd.min.js' }, { binInputParameters: [ 'spec/artifacts/known.helpers.handlebars', '-a', '-k', 'someHelper', '-k', 'anotherHelper', '-o' ], outputLocation: 'stdout', expectedOutputSpec: './spec/expected/non.empty.amd.known.helper.js' }, { binInputParameters: ['--help'], outputLocation: 'stdout', expectedOutputSpec: './spec/expected/help.menu.txt' }, { binInputParameters: ['-v'], outputLocation: 'stdout', expectedOutput: require('../package.json').version }, { binInputParameters: [ '-a', '-e', 'hbs', './spec/artifacts/non.default.extension.hbs' ], outputLocation: 'stdout', expectedOutputSpec: './spec/expected/non.default.extension.amd.js' }, { binInputParameters: [ '-a', '-p', './spec/artifacts/partial.template.handlebars' ], outputLocation: 'stdout', expectedOutputSpec: './spec/expected/partial.template.js' }, { binInputParameters: ['spec/artifacts/empty.handlebars', '-c'], outputLocation: 'stdout', expectedOutputSpec: './spec/expected/empty.common.js' }, { binInputParameters: [ 'spec/artifacts/empty.handlebars', 'spec/artifacts/empty.handlebars', '-a', '-n', 'someNameSpace' ], outputLocation: 'stdout', expectedOutputSpec: './spec/expected/namespace.amd.js' }, { binInputParameters: [ 'spec/artifacts/empty.handlebars', '-h', 'some-path/', '-a' ], outputLocation: 'stdout', expectedOutputSpec: './spec/expected/handlebar.path.amd.js' }, { binInputParameters: [ 'spec/artifacts/partial.template.handlebars', '-r', 'spec', '-a' ], outputLocation: 'stdout', expectedOutputSpec: './spec/expected/empty.root.amd.js' }, { binInputParameters: [ '-i', '
1
', '-i', '
2
', '-N', 'firstTemplate', '-N', 'secondTemplate', '-a' ], outputLocation: 'stdout', expectedOutputSpec: './spec/expected/empty.name.amd.js' }, { binInputParameters: [ '-i', '
1
', '-a', '-m', '-N', 'test', '--map', './spec/tmp/source.map.amd.txt' ], outputLocation: 'stdout', expectedOutputSpec: './spec/expected/source.map.amd.js' }, { binInputParameters: ['./spec/artifacts/bom.handlebars', '-b', '-a'], outputLocation: 'stdout', expectedOutputSpec: './spec/expected/bom.amd.js' } ]; module.exports = function(grunt) { grunt.registerTask('test:bin', function() { testCases.forEach( ({ binInputParameters, outputLocation, expectedOutputSpec, expectedOutput }) => { const stdout = executeBinHandlebars(...binInputParameters); if (!expectedOutput && expectedOutputSpec) { expectedOutput = fs.readFileSync(expectedOutputSpec, 'utf-8'); } const useStdout = outputLocation === 'stdout'; const normalizedOutput = normalizeCrlf( useStdout ? stdout : fs.readFileSync(outputLocation, 'utf-8') ); const normalizedExpectedOutput = normalizeCrlf(expectedOutput); if (!useStdout) { fs.unlinkSync(outputLocation); } expect(normalizedOutput).not.to.be.differentFrom( normalizedExpectedOutput, { relaxedSpace: true } ); } ); }); }; // helper functions function executeBinHandlebars(...args) { if (os.platform() === 'win32') { // On Windows, the executable handlebars.js file cannot be run directly const nodeJs = process.argv[0]; return execFilesSyncUtf8(nodeJs, ['./bin/handlebars'].concat(args)); } return execFilesSyncUtf8('./bin/handlebars', args); } function execFilesSyncUtf8(command, args) { const env = process.env; env.PATH = addPathToNodeJs(env.PATH); return childProcess.execFileSync(command, args, { encoding: 'utf-8', env }); } function addPathToNodeJs(pathEnvironment) { return path.dirname(process.argv0) + path.delimiter + pathEnvironment; } function normalizeCrlf(string) { if (typeof string === 'string') { return string.replace(/\r\n/g, '\n'); } return string; } handlebars.js-4.7.7/tasks/test-mocha.js000066400000000000000000000012571401244020700177750ustar00rootroot00000000000000const { execNodeJsScriptWithInheritedOutput } = require('./util/exec-file'); const { createRegisterAsyncTaskFn } = require('./util/async-grunt-task'); const nodeJs = process.argv0; module.exports = function(grunt) { const registerAsyncTask = createRegisterAsyncTaskFn(grunt); registerAsyncTask('test:mocha', async () => execNodeJsScriptWithInheritedOutput('./spec/env/runner') ); registerAsyncTask('test:cov', async () => execNodeJsScriptWithInheritedOutput('node_modules/nyc/bin/nyc', [ nodeJs, './spec/env/runner.js' ]) ); registerAsyncTask('test:min', async () => execNodeJsScriptWithInheritedOutput('./spec/env/runner', ['--min']) ); }; handlebars.js-4.7.7/tasks/util/000077500000000000000000000000001401244020700163435ustar00rootroot00000000000000handlebars.js-4.7.7/tasks/util/async-grunt-task.js000066400000000000000000000005121401244020700221110ustar00rootroot00000000000000module.exports = { createRegisterAsyncTaskFn }; function createRegisterAsyncTaskFn(grunt) { return function registerAsyncTask(name, asyncFunction) { grunt.registerTask(name, function() { asyncFunction() .catch(error => { grunt.fatal(error); }) .finally(this.async()); }); }; } handlebars.js-4.7.7/tasks/util/exec-file.js000066400000000000000000000025441401244020700205470ustar00rootroot00000000000000const childProcess = require('child_process'); const fs = require('fs'); const path = require('path'); module.exports = { execNodeJsScriptWithInheritedOutput, execFileWithInheritedOutput }; async function execNodeJsScriptWithInheritedOutput(command, args) { return new Promise((resolve, reject) => { const child = childProcess.fork(command, args, { stdio: 'inherit' }); child.on('close', code => { if (code !== 0) { reject(new Error(`Child process failed with exit-code ${code}`)); } resolve(); }); }); } async function execFileWithInheritedOutput(command, args) { return new Promise((resolve, reject) => { const resolvedCommand = preferLocalDependencies(command); const child = childProcess.spawn(resolvedCommand, args, { stdio: 'inherit' }); child.on('exit', code => { if (code !== 0) { reject(new Error(`Child process failed with exit-code ${code}`)); } resolve(); }); }); } function preferLocalDependencies(command) { const localCandidate = resolveLocalCandidate(command); if (fs.existsSync(localCandidate)) { return localCandidate; } return command; } function resolveLocalCandidate(command) { if (process.platform === 'win32') { return path.join('node_modules', '.bin', command + '.cmd'); } return path.join('node_modules', '.bin', command); } handlebars.js-4.7.7/tasks/util/git.js000066400000000000000000000033601401244020700174660ustar00rootroot00000000000000const childProcess = require('child_process'); module.exports = { async remotes() { return git('remote', '-v'); }, async branches() { return git('branch', '-a'); }, async commitInfo() { const headSha = await getHeadSha(); const masterSha = await getMasterSha(); return { headSha, masterSha, tagName: await getTagName(), isMaster: headSha === masterSha }; }, async add(path) { return git('add', '-f', path); }, async commit(message) { return git('commit', '--message', message); }, git // visible for testing }; async function getHeadSha() { const stdout = await git('rev-parse', '--short', 'HEAD'); return stdout.trim(); } async function getMasterSha() { try { const stdout = await git('rev-parse', '--short', 'origin/master'); return stdout.trim(); } catch (error) { if (/Needed a single revision/.test(error.message)) { // Master was not checked out but in this case, so we know we are not master. We can ignore this return ''; } throw error; } } async function getTagName() { const stdout = await git('tag', '-l', '--points-at', 'HEAD'); const trimmedStdout = stdout.trim(); if (trimmedStdout === '') { return null; // there is no tag } const tags = trimmedStdout.split(/\n|\r\n/); const versionTags = tags.filter(tag => /^v/.test(tag)); if (versionTags[0] != null) { return versionTags[0]; } return tags[0]; } async function git(...args) { return new Promise((resolve, reject) => childProcess.execFile('git', args, (err, stdout) => { if (err != null) { return reject( new Error(`"git ${args.join(' ')}" caused error: ${err.message}`) ); } resolve(stdout); }) ); } handlebars.js-4.7.7/tasks/version.js000066400000000000000000000032031401244020700174070ustar00rootroot00000000000000const git = require('./util/git'); const semver = require('semver'); const { createRegisterAsyncTaskFn } = require('./util/async-grunt-task'); module.exports = function(grunt) { const registerAsyncTask = createRegisterAsyncTaskFn(grunt); registerAsyncTask('version', async () => { const pkg = grunt.config('pkg'); const version = grunt.option('ver'); if (!semver.valid(version)) { throw new Error( 'Must provide a version number (Ex: --ver=1.0.0):\n\t' + version + '\n\n' ); } pkg.version = version; grunt.config('pkg', pkg); const replaceSpec = [ { path: 'lib/handlebars/base.js', regex: /const VERSION = ['"](.*)['"];/, replacement: `const VERSION = '${version}';` }, { path: 'components/bower.json', regex: /"version":.*/, replacement: `"version": "${version}",` }, { path: 'components/package.json', regex: /"version":.*/, replacement: `"version": "${version}",` }, { path: 'components/handlebars.js.nuspec', regex: /.*<\/version>/, replacement: `${version}` } ]; await Promise.all( replaceSpec.map(replaceSpec => replaceAndAdd( replaceSpec.path, replaceSpec.regex, replaceSpec.replacement ) ) ); grunt.task.run(['default']); }); async function replaceAndAdd(path, regex, value) { let content = grunt.file.read(path); content = content.replace(regex, value); grunt.file.write(path, content); await git.add(path); } }; handlebars.js-4.7.7/types/000077500000000000000000000000001401244020700154055ustar00rootroot00000000000000handlebars.js-4.7.7/types/index.d.ts000066400000000000000000000310721401244020700173110ustar00rootroot00000000000000/* These definitions were imported from https://github.com/DefinitelyTyped/DefinitelyTyped * and includes previous contributions from the DefinitelyTyped community by: * - Albert Willemsen * - Boris Yankov * - Jessica Franco * - Masahiro Wakame * - Raanan Weber * - Sergei Dorogin * - webbiesdk * - Andrew Leedham * - Nils Knappmeier * For full history prior to their migration to handlebars.js, please see: * https://github.com/DefinitelyTyped/DefinitelyTyped/commits/1ce60bdc07f10e0b076778c6c953271c072bc894/types/handlebars/index.d.ts */ // TypeScript Version: 2.3 declare namespace Handlebars { export interface TemplateDelegate { (context: T, options?: RuntimeOptions): string; } export type Template = TemplateDelegate|string; export interface RuntimeOptions { partial?: boolean; depths?: any[]; helpers?: { [name: string]: Function }; partials?: { [name: string]: HandlebarsTemplateDelegate }; decorators?: { [name: string]: Function }; data?: any; blockParams?: any[]; allowCallsToHelperMissing?: boolean; allowedProtoProperties?: { [name: string]: boolean }; allowedProtoMethods?: { [name: string]: boolean }; allowProtoPropertiesByDefault?: boolean; allowProtoMethodsByDefault?: boolean; } export interface HelperOptions { fn: TemplateDelegate; inverse: TemplateDelegate; hash: any; data?: any; } export interface HelperDelegate { (context?: any, arg1?: any, arg2?: any, arg3?: any, arg4?: any, arg5?: any, options?: HelperOptions): any; } export interface HelperDeclareSpec { [key: string]: HelperDelegate; } export interface ParseOptions { srcName?: string; ignoreStandalone?: boolean; } export function registerHelper(name: string, fn: HelperDelegate): void; export function registerHelper(name: HelperDeclareSpec): void; export function unregisterHelper(name: string): void; export function registerPartial(name: string, fn: Template): void; export function registerPartial(spec: { [name: string]: HandlebarsTemplateDelegate }): void; export function unregisterPartial(name: string): void; // TODO: replace Function with actual signature export function registerDecorator(name: string, fn: Function): void; export function unregisterDecorator(name: string): void; export function K(): void; export function createFrame(object: any): any; export function blockParams(obj: any[], ids: any[]): any[]; export function log(level: number, obj: any): void; export function parse(input: string, options?: ParseOptions): hbs.AST.Program; export function parseWithoutProcessing(input: string, options?: ParseOptions): hbs.AST.Program; export function compile(input: any, options?: CompileOptions): HandlebarsTemplateDelegate; export function precompile(input: any, options?: PrecompileOptions): TemplateSpecification; export function template(precompilation: TemplateSpecification): HandlebarsTemplateDelegate; export function create(): typeof Handlebars; export const escapeExpression: typeof Utils.escapeExpression; //export const Utils: typeof hbs.Utils; export const logger: Logger; export const templates: HandlebarsTemplates; export const helpers: { [name: string]: HelperDelegate }; export const partials: { [name: string]: any }; // TODO: replace Function with actual signature export const decorators: { [name: string]: Function }; export const VERSION: string; export function noConflict(): typeof Handlebars; export class Exception { constructor(message: string, node?: hbs.AST.Node); description: string; fileName: string; lineNumber?: any; endLineNumber?: any; message: string; name: string; number: number; stack?: string; column?: any; endColumn?: any; } export class SafeString { constructor(str: string); toString(): string; toHTML(): string; } export namespace Utils { export function escapeExpression(str: string): string; export function createFrame(object: any): any; export function blockParams(obj: any[], ids: any[]): any[]; export function isEmpty(obj: any) : boolean; export function extend(obj: any, ...source: any[]): any; export function toString(obj: any): string; export function isArray(obj: any): boolean; export function isFunction(obj: any): boolean; } export namespace AST { export const helpers: hbs.AST.helpers; } interface ICompiler { accept(node: hbs.AST.Node): void; Program(program: hbs.AST.Program): void; BlockStatement(block: hbs.AST.BlockStatement): void; PartialStatement(partial: hbs.AST.PartialStatement): void; PartialBlockStatement(partial: hbs.AST.PartialBlockStatement): void; DecoratorBlock(decorator: hbs.AST.DecoratorBlock): void; Decorator(decorator: hbs.AST.Decorator): void; MustacheStatement(mustache: hbs.AST.MustacheStatement): void; ContentStatement(content: hbs.AST.ContentStatement): void; CommentStatement(comment?: hbs.AST.CommentStatement): void; SubExpression(sexpr: hbs.AST.SubExpression): void; PathExpression(path: hbs.AST.PathExpression): void; StringLiteral(str: hbs.AST.StringLiteral): void; NumberLiteral(num: hbs.AST.NumberLiteral): void; BooleanLiteral(bool: hbs.AST.BooleanLiteral): void; UndefinedLiteral(): void; NullLiteral(): void; Hash(hash: hbs.AST.Hash): void; } export class Visitor implements ICompiler { accept(node: hbs.AST.Node): void; acceptKey(node: hbs.AST.Node, name: string): void; acceptArray(arr: hbs.AST.Expression[]): void; Program(program: hbs.AST.Program): void; BlockStatement(block: hbs.AST.BlockStatement): void; PartialStatement(partial: hbs.AST.PartialStatement): void; PartialBlockStatement(partial: hbs.AST.PartialBlockStatement): void; DecoratorBlock(decorator: hbs.AST.DecoratorBlock): void; Decorator(decorator: hbs.AST.Decorator): void; MustacheStatement(mustache: hbs.AST.MustacheStatement): void; ContentStatement(content: hbs.AST.ContentStatement): void; CommentStatement(comment?: hbs.AST.CommentStatement): void; SubExpression(sexpr: hbs.AST.SubExpression): void; PathExpression(path: hbs.AST.PathExpression): void; StringLiteral(str: hbs.AST.StringLiteral): void; NumberLiteral(num: hbs.AST.NumberLiteral): void; BooleanLiteral(bool: hbs.AST.BooleanLiteral): void; UndefinedLiteral(): void; NullLiteral(): void; Hash(hash: hbs.AST.Hash): void; } export interface ResolvePartialOptions { name: string; helpers?: { [name: string]: Function }; partials?: { [name: string]: HandlebarsTemplateDelegate }; decorators?: { [name: string]: Function }; data?: any; } export namespace VM { /** * @deprecated */ export function resolvePartial(partial: HandlebarsTemplateDelegate | undefined, context: any, options: ResolvePartialOptions): HandlebarsTemplateDelegate; } } /** * Implement this interface on your MVW/MVVM/MVC views such as Backbone.View **/ interface HandlebarsTemplatable { template: HandlebarsTemplateDelegate; } // NOTE: for backward compatibility of this typing type HandlebarsTemplateDelegate = Handlebars.TemplateDelegate; interface HandlebarsTemplates { [index: string]: HandlebarsTemplateDelegate; } interface TemplateSpecification { } // for backward compatibility of this typing type RuntimeOptions = Handlebars.RuntimeOptions; interface CompileOptions { data?: boolean; compat?: boolean; knownHelpers?: KnownHelpers; knownHelpersOnly?: boolean; noEscape?: boolean; strict?: boolean; assumeObjects?: boolean; preventIndent?: boolean; ignoreStandalone?: boolean; explicitPartialContext?: boolean; } type KnownHelpers = { [name in BuiltinHelperName | CustomHelperName]: boolean; }; type BuiltinHelperName = "helperMissing"| "blockHelperMissing"| "each"| "if"| "unless"| "with"| "log"| "lookup"; type CustomHelperName = string; interface PrecompileOptions extends CompileOptions { srcName?: string; destName?: string; } declare namespace hbs { // for backward compatibility of this typing type SafeString = Handlebars.SafeString; type Utils = typeof Handlebars.Utils; } interface Logger { DEBUG: number; INFO: number; WARN: number; ERROR: number; level: number; methodMap: { [level: number]: string }; log(level: number, obj: string): void; } type CompilerInfo = [number/* revision */, string /* versions */]; declare namespace hbs { namespace AST { interface Node { type: string; loc: SourceLocation; } interface SourceLocation { source: string; start: Position; end: Position; } interface Position { line: number; column: number; } interface Program extends Node { body: Statement[]; blockParams: string[]; } interface Statement extends Node {} interface MustacheStatement extends Statement { type: 'MustacheStatement'; path: PathExpression | Literal; params: Expression[]; hash: Hash; escaped: boolean; strip: StripFlags; } interface Decorator extends MustacheStatement { } interface BlockStatement extends Statement { type: 'BlockStatement'; path: PathExpression; params: Expression[]; hash: Hash; program: Program; inverse: Program; openStrip: StripFlags; inverseStrip: StripFlags; closeStrip: StripFlags; } interface DecoratorBlock extends BlockStatement { } interface PartialStatement extends Statement { type: 'PartialStatement'; name: PathExpression | SubExpression; params: Expression[]; hash: Hash; indent: string; strip: StripFlags; } interface PartialBlockStatement extends Statement { type: 'PartialBlockStatement'; name: PathExpression | SubExpression; params: Expression[]; hash: Hash; program: Program; openStrip: StripFlags; closeStrip: StripFlags; } interface ContentStatement extends Statement { type: 'ContentStatement'; value: string; original: StripFlags; } interface CommentStatement extends Statement { type: 'CommentStatement'; value: string; strip: StripFlags; } interface Expression extends Node {} interface SubExpression extends Expression { type: 'SubExpression'; path: PathExpression; params: Expression[]; hash: Hash; } interface PathExpression extends Expression { type: 'PathExpression'; data: boolean; depth: number; parts: string[]; original: string; } interface Literal extends Expression {} interface StringLiteral extends Literal { type: 'StringLiteral'; value: string; original: string; } interface BooleanLiteral extends Literal { type: 'BooleanLiteral'; value: boolean; original: boolean; } interface NumberLiteral extends Literal { type: 'NumberLiteral'; value: number; original: number; } interface UndefinedLiteral extends Literal { type: 'UndefinedLiteral'; } interface NullLiteral extends Literal { type: 'NullLiteral'; } interface Hash extends Node { type: 'Hash'; pairs: HashPair[]; } interface HashPair extends Node { type: 'HashPair'; key: string; value: Expression; } interface StripFlags { open: boolean; close: boolean; } interface helpers { helperExpression(node: Node): boolean; scopeId(path: PathExpression): boolean; simpleId(path: PathExpression): boolean; } } } declare module "handlebars" { export = Handlebars; } declare module "handlebars/runtime" { export = Handlebars; } handlebars.js-4.7.7/types/test.ts000066400000000000000000000207131401244020700167370ustar00rootroot00000000000000/* These test cases were imported from https://github.com/DefinitelyTyped/DefinitelyTyped * and includes previous contributions from the DefinitelyTyped community. * For full history prior to their migration to handlebars.js, please see: * https://github.com/DefinitelyTyped/DefinitelyTyped/commits/1ce60bdc07f10e0b076778c6c953271c072bc894/types/handlebars/handlebars-tests.ts */ import * as Handlebars from 'handlebars'; const context = { author: { firstName: 'Alan', lastName: 'Johnson' }, body: 'I Love Handlebars', comments: [{ author: { firstName: 'Yehuda', lastName: 'Katz' }, body: 'Me too!' }] }; Handlebars.registerHelper('fullName', (person: typeof context.author) => { return person.firstName + ' ' + person.lastName; }); Handlebars.registerHelper('agree_button', function(this: any) { return new Handlebars.SafeString( '' ); }); const source1 = '

Hello, my name is {{name}}. I am from {{hometown}}. I have ' + '{{kids.length}} kids:

' + '
    {{#kids}}
  • {{name}} is {{age}}
  • {{/kids}}
'; const template1 = Handlebars.compile(source1); template1({ name: "Alan", hometown: "Somewhere, TX", kids: [{name: "Jimmy", age: 12}, {name: "Sally", age: 4}]}); Handlebars.registerHelper('link_to', (context: typeof post) => { return '' + context.body + ''; }); const post = { url: "/hello-world", body: "Hello World!" }; const context2 = { posts: [post] }; const source2 = '
    {{#posts}}
  • {{{link_to this}}}
  • {{/posts}}
'; const template2: HandlebarsTemplateDelegate<{ posts: { url: string, body: string }[] }> = Handlebars.compile(source2); template2(context2); Handlebars.registerHelper('link_to', (title: string, context: typeof post) => { return '' + title + '!'; }); const context3 = { posts: [{url: '/hello-world', body: 'Hello World!'}] }; const source3 = '
    {{#posts}}
  • {{{link_to "Post" this}}}
  • {{/posts}}
'; const template3 = Handlebars.compile(source3); template3(context3); const source4 = '
    {{#people}}
  • {{#link}}{{name}}{{/link}}
  • {{/people}}
'; Handlebars.registerHelper('link', function(this: any, context: any) { return '' + context.fn(this) + ''; }); const template4 = Handlebars.compile<{ people: { name: string, id: number }[] }>(source4); const data2 = { 'people': [ { 'name': 'Alan', 'id': 1 }, { 'name': 'Yehuda', 'id': 2 } ]}; template4(data2); const source5 = '
    {{#people}}
  • {{> link}}
  • {{/people}}
'; Handlebars.registerPartial('link', '{{name}}'); const template5 = Handlebars.compile(source5); const data3 = { 'people': [ { 'name': 'Alan', 'id': 1 }, { 'name': 'Yehuda', 'id': 2 } ]}; template5(data3); const source6 = '{{#list nav}}{{title}}{{/list}}'; const template6 = Handlebars.compile(source6); Handlebars.registerHelper('list', (context, options: Handlebars.HelperOptions) => { let ret = "
    "; for(let i=0, j=context.length; i" + options.fn(context[i]) + ""; } return ret + "
"; }); template6([{url:"", title:""}]); const escapedExpression = Handlebars.Utils.escapeExpression(''); Handlebars.helpers !== undefined; const parsedTmpl = Handlebars.parse('

Hello, my name is {{name}}.

', { srcName: "/foo/bar/baz.hbs", ignoreStandalone: true }); const parsedTmplWithoutOptions = Handlebars.parse('

Hello, my name is {{name}}.

'); // Custom partial resolution. const originalResolvePartial = Handlebars.VM.resolvePartial; Handlebars.VM.resolvePartial = (partial: HandlebarsTemplateDelegate | undefined, context: any, options: Handlebars.ResolvePartialOptions): HandlebarsTemplateDelegate => { const name = options.name.replace(/my/,'your'); // transform name. options.name = name; return originalResolvePartial(partial, context, options); }; // #1544, allow custom helpers in knownHelpers Handlebars.compile('test', { knownHelpers: { each: true, customHelper: true } }); Handlebars.compile('test')({},{allowCallsToHelperMissing: true}); Handlebars.compile('test')({},{}); const allthings = {} as hbs.AST.MustacheStatement | hbs.AST.BlockStatement | hbs.AST.PartialStatement | hbs.AST.PartialBlockStatement | hbs.AST.ContentStatement | hbs.AST.CommentStatement | hbs.AST.SubExpression | hbs.AST.PathExpression | hbs.AST.StringLiteral | hbs.AST.BooleanLiteral | hbs.AST.NumberLiteral | hbs.AST.UndefinedLiteral | hbs.AST.NullLiteral | hbs.AST.Hash | hbs.AST.HashPair; switch(allthings.type) { case "MustacheStatement": let mustacheStatement: hbs.AST.MustacheStatement; mustacheStatement = allthings; break; case "BlockStatement": let blockStatement: hbs.AST.BlockStatement; blockStatement = allthings; break; case "PartialStatement": let partialStatement: hbs.AST.PartialStatement; partialStatement = allthings; break; case "PartialBlockStatement": let partialBlockStatement: hbs.AST.PartialBlockStatement; partialBlockStatement = allthings; break; case "ContentStatement": let ContentStatement: hbs.AST.ContentStatement; ContentStatement = allthings; break; case "CommentStatement": let CommentStatement: hbs.AST.CommentStatement; CommentStatement = allthings; break; case "SubExpression": let SubExpression: hbs.AST.SubExpression; SubExpression = allthings; break; case "PathExpression": let PathExpression: hbs.AST.PathExpression; PathExpression = allthings; break; case "StringLiteral": let StringLiteral: hbs.AST.StringLiteral; StringLiteral = allthings; break; case "BooleanLiteral": let BooleanLiteral: hbs.AST.BooleanLiteral; BooleanLiteral = allthings; break; case "NumberLiteral": let NumberLiteral: hbs.AST.NumberLiteral; NumberLiteral = allthings; break; case "UndefinedLiteral": let UndefinedLiteral: hbs.AST.UndefinedLiteral; UndefinedLiteral = allthings; break; case "NullLiteral": let NullLiteral: hbs.AST.NullLiteral; NullLiteral = allthings; break; case "Hash": let Hash: hbs.AST.Hash; Hash = allthings; break; case "HashPair": let HashPair: hbs.AST.HashPair; HashPair = allthings; break; default: break; } function testParseWithoutProcessing() { const parsedTemplate: hbs.AST.Program = Handlebars.parseWithoutProcessing('

Hello, my name is {{name}}.

', { srcName: "/foo/bar/baz.hbs", }); const parsedTemplateWithoutOptions: hbs.AST.Program = Handlebars.parseWithoutProcessing('

Hello, my name is {{name}}.

'); } function testExceptionTypings() { // Test exception constructor with a single argument - message. let exception: Handlebars.Exception = new Handlebars.Exception('message'); // Fields let message: string = exception.message; let lineNumber: number = exception.lineNumber; let column: number = exception.column; let endLineNumber: number = exception.endLineNumber; let endColumn: number = exception.endColumn; let description = exception.description; let name: string = exception.name; let fileName: string = exception.fileName; let stack: string | undefined = exception.stack; } function testExceptionWithNodeTypings() { // Test exception constructor with both arguments. const exception: Handlebars.Exception = new Handlebars.Exception('message', { type: 'MustacheStatement', loc: { source: 'source', start: { line: 1, column: 5 }, end: { line: 10, column: 2 } } }); // Fields let message: string = exception.message; let lineNumber: number = exception.lineNumber; let column: number = exception.column; let endLineNumber: number = exception.endLineNumber; let endColumn: number = exception.endColumn; let description = exception.description; let name: string = exception.name; let fileName: string = exception.fileName; let stack: string | undefined = exception.stack; } function testProtoAccessControlControlOptions() { Handlebars.compile('test')( {}, { allowedProtoMethods: { allowedMethod: true, forbiddenMethod: false }, allowedProtoProperties: { allowedProperty: true, forbiddenProperty: false }, allowProtoMethodsByDefault: true, allowProtoPropertiesByDefault: false, } ); } function testHandlebarsVersion() { let version: string = Handlebars.VERSION; } handlebars.js-4.7.7/types/tsconfig.json000066400000000000000000000004541401244020700201170ustar00rootroot00000000000000{ "compilerOptions": { "module": "commonjs", "lib": ["es6"], "noImplicitAny": true, "noImplicitThis": true, "strictNullChecks": true, "strictFunctionTypes": true, "noEmit": true, "baseUrl": ".", "types": [], "paths": { "handlebars": ["."] } } } handlebars.js-4.7.7/types/tslint.json000066400000000000000000000047241401244020700176240ustar00rootroot00000000000000{ "extends": "dtslint/dtslint.json", "rules": { "adjacent-overload-signatures": false, "array-type": false, "arrow-return-shorthand": false, "ban-types": false, "callable-types": false, "comment-format": false, "dt-header": false, "eofline": false, "export-just-namespace": false, "import-spacing": false, "interface-name": false, "interface-over-type-literal": false, "jsdoc-format": false, "max-line-length": false, "member-access": false, "new-parens": false, "no-any-union": false, "no-boolean-literal-compare": false, "no-conditional-assignment": false, "no-consecutive-blank-lines": false, "no-construct": false, "no-declare-current-package": false, "no-duplicate-imports": false, "no-duplicate-variable": false, "no-empty-interface": false, "no-for-in-array": false, "no-inferrable-types": false, "no-internal-module": false, "no-irregular-whitespace": false, "no-mergeable-namespace": false, "no-misused-new": false, "no-namespace": false, "no-object-literal-type-assertion": false, "no-padding": false, "no-redundant-jsdoc": false, "no-redundant-jsdoc-2": false, "no-redundant-undefined": false, "no-reference-import": false, "no-relative-import-in-test": false, "no-self-import": false, "no-single-declare-module": false, "no-string-throw": false, "no-unnecessary-callback-wrapper": false, "no-unnecessary-class": false, "no-unnecessary-generics": false, "no-unnecessary-qualifier": false, "no-unnecessary-type-assertion": false, "no-useless-files": false, "no-var-keyword": false, "no-var-requires": false, "no-void-expression": false, "no-trailing-whitespace": false, "object-literal-key-quotes": false, "object-literal-shorthand": false, "one-line": false, "one-variable-per-declaration": false, "only-arrow-functions": false, "prefer-conditional-expression": false, "prefer-const": false, "prefer-declare-function": false, "prefer-for-of": false, "prefer-method-signature": false, "prefer-template": false, "radix": false, "semicolon": false, "space-before-function-paren": false, "space-within-parens": false, "strict-export-declare-modifiers": false, "trim-file": false, "triple-equals": false, "typedef-whitespace": false, "unified-signatures": false, "void-return": false, "whitespace": false } }