`):
+ *
+ * ```javascript
+ * var hljs = require('highlight.js') // https://highlightjs.org/
+ *
+ * // Actual default values
+ * var md = require('markdown-it')({
+ * highlight: function (str, lang) {
+ * if (lang && hljs.getLanguage(lang)) {
+ * try {
+ * return '' +
+ * hljs.highlight(str, { language: lang, ignoreIllegals: true }).value +
+ * ' ';
+ * } catch (__) {}
+ * }
+ *
+ * return '' + md.utils.escapeHtml(str) + ' ';
+ * }
+ * });
+ * ```
+ *
+ **/ function MarkdownIt(presetName, options) {
+ if (!(this instanceof MarkdownIt)) {
+ return new MarkdownIt(presetName, options);
+ }
+ if (!options) {
+ if (!isString$1(presetName)) {
+ options = presetName || {};
+ presetName = "default";
+ }
+ }
+ /**
+ * MarkdownIt#inline -> ParserInline
+ *
+ * Instance of [[ParserInline]]. You may need it to add new rules when
+ * writing plugins. For simple rules control use [[MarkdownIt.disable]] and
+ * [[MarkdownIt.enable]].
+ **/ this.inline = new ParserInline;
+ /**
+ * MarkdownIt#block -> ParserBlock
+ *
+ * Instance of [[ParserBlock]]. You may need it to add new rules when
+ * writing plugins. For simple rules control use [[MarkdownIt.disable]] and
+ * [[MarkdownIt.enable]].
+ **/ this.block = new ParserBlock;
+ /**
+ * MarkdownIt#core -> Core
+ *
+ * Instance of [[Core]] chain executor. You may need it to add new rules when
+ * writing plugins. For simple rules control use [[MarkdownIt.disable]] and
+ * [[MarkdownIt.enable]].
+ **/ this.core = new Core;
+ /**
+ * MarkdownIt#renderer -> Renderer
+ *
+ * Instance of [[Renderer]]. Use it to modify output look. Or to add rendering
+ * rules for new token types, generated by plugins.
+ *
+ * ##### Example
+ *
+ * ```javascript
+ * var md = require('markdown-it')();
+ *
+ * function myToken(tokens, idx, options, env, self) {
+ * //...
+ * return result;
+ * };
+ *
+ * md.renderer.rules['my_token'] = myToken
+ * ```
+ *
+ * See [[Renderer]] docs and [source code](https://github.com/markdown-it/markdown-it/blob/master/lib/renderer.mjs).
+ **/ this.renderer = new Renderer;
+ /**
+ * MarkdownIt#linkify -> LinkifyIt
+ *
+ * [linkify-it](https://github.com/markdown-it/linkify-it) instance.
+ * Used by [linkify](https://github.com/markdown-it/markdown-it/blob/master/lib/rules_core/linkify.mjs)
+ * rule.
+ **/ this.linkify = new LinkifyIt;
+ /**
+ * MarkdownIt#validateLink(url) -> Boolean
+ *
+ * Link validation function. CommonMark allows too much in links. By default
+ * we disable `javascript:`, `vbscript:`, `file:` schemas, and almost all `data:...` schemas
+ * except some embedded image types.
+ *
+ * You can change this behaviour:
+ *
+ * ```javascript
+ * var md = require('markdown-it')();
+ * // enable everything
+ * md.validateLink = function () { return true; }
+ * ```
+ **/ this.validateLink = validateLink;
+ /**
+ * MarkdownIt#normalizeLink(url) -> String
+ *
+ * Function used to encode link url to a machine-readable format,
+ * which includes url-encoding, punycode, etc.
+ **/ this.normalizeLink = normalizeLink;
+ /**
+ * MarkdownIt#normalizeLinkText(url) -> String
+ *
+ * Function used to decode link url to a human-readable format`
+ **/ this.normalizeLinkText = normalizeLinkText;
+ // Expose utils & helpers for easy acces from plugins
+ /**
+ * MarkdownIt#utils -> utils
+ *
+ * Assorted utility functions, useful to write plugins. See details
+ * [here](https://github.com/markdown-it/markdown-it/blob/master/lib/common/utils.mjs).
+ **/ this.utils = utils;
+ /**
+ * MarkdownIt#helpers -> helpers
+ *
+ * Link components parser functions, useful to write plugins. See details
+ * [here](https://github.com/markdown-it/markdown-it/blob/master/lib/helpers).
+ **/ this.helpers = assign$1({}, helpers);
+ this.options = {};
+ this.configure(presetName);
+ if (options) {
+ this.set(options);
+ }
+ }
+ /** chainable
+ * MarkdownIt.set(options)
+ *
+ * Set parser options (in the same format as in constructor). Probably, you
+ * will never need it, but you can change options after constructor call.
+ *
+ * ##### Example
+ *
+ * ```javascript
+ * var md = require('markdown-it')()
+ * .set({ html: true, breaks: true })
+ * .set({ typographer, true });
+ * ```
+ *
+ * __Note:__ To achieve the best possible performance, don't modify a
+ * `markdown-it` instance options on the fly. If you need multiple configurations
+ * it's best to create multiple instances and initialize each with separate
+ * config.
+ **/ MarkdownIt.prototype.set = function(options) {
+ assign$1(this.options, options);
+ return this;
+ };
+ /** chainable, internal
+ * MarkdownIt.configure(presets)
+ *
+ * Batch load of all options and compenent settings. This is internal method,
+ * and you probably will not need it. But if you will - see available presets
+ * and data structure [here](https://github.com/markdown-it/markdown-it/tree/master/lib/presets)
+ *
+ * We strongly recommend to use presets instead of direct config loads. That
+ * will give better compatibility with next versions.
+ **/ MarkdownIt.prototype.configure = function(presets) {
+ const self = this;
+ if (isString$1(presets)) {
+ const presetName = presets;
+ presets = config[presetName];
+ if (!presets) {
+ throw new Error('Wrong `markdown-it` preset "' + presetName + '", check name');
+ }
+ }
+ if (!presets) {
+ throw new Error("Wrong `markdown-it` preset, can't be empty");
+ }
+ if (presets.options) {
+ self.set(presets.options);
+ }
+ if (presets.components) {
+ Object.keys(presets.components).forEach((function(name) {
+ if (presets.components[name].rules) {
+ self[name].ruler.enableOnly(presets.components[name].rules);
+ }
+ if (presets.components[name].rules2) {
+ self[name].ruler2.enableOnly(presets.components[name].rules2);
+ }
+ }));
+ }
+ return this;
+ };
+ /** chainable
+ * MarkdownIt.enable(list, ignoreInvalid)
+ * - list (String|Array): rule name or list of rule names to enable
+ * - ignoreInvalid (Boolean): set `true` to ignore errors when rule not found.
+ *
+ * Enable list or rules. It will automatically find appropriate components,
+ * containing rules with given names. If rule not found, and `ignoreInvalid`
+ * not set - throws exception.
+ *
+ * ##### Example
+ *
+ * ```javascript
+ * var md = require('markdown-it')()
+ * .enable(['sub', 'sup'])
+ * .disable('smartquotes');
+ * ```
+ **/ MarkdownIt.prototype.enable = function(list, ignoreInvalid) {
+ let result = [];
+ if (!Array.isArray(list)) {
+ list = [ list ];
+ }
+ [ "core", "block", "inline" ].forEach((function(chain) {
+ result = result.concat(this[chain].ruler.enable(list, true));
+ }), this);
+ result = result.concat(this.inline.ruler2.enable(list, true));
+ const missed = list.filter((function(name) {
+ return result.indexOf(name) < 0;
+ }));
+ if (missed.length && !ignoreInvalid) {
+ throw new Error("MarkdownIt. Failed to enable unknown rule(s): " + missed);
+ }
+ return this;
+ };
+ /** chainable
+ * MarkdownIt.disable(list, ignoreInvalid)
+ * - list (String|Array): rule name or list of rule names to disable.
+ * - ignoreInvalid (Boolean): set `true` to ignore errors when rule not found.
+ *
+ * The same as [[MarkdownIt.enable]], but turn specified rules off.
+ **/ MarkdownIt.prototype.disable = function(list, ignoreInvalid) {
+ let result = [];
+ if (!Array.isArray(list)) {
+ list = [ list ];
+ }
+ [ "core", "block", "inline" ].forEach((function(chain) {
+ result = result.concat(this[chain].ruler.disable(list, true));
+ }), this);
+ result = result.concat(this.inline.ruler2.disable(list, true));
+ const missed = list.filter((function(name) {
+ return result.indexOf(name) < 0;
+ }));
+ if (missed.length && !ignoreInvalid) {
+ throw new Error("MarkdownIt. Failed to disable unknown rule(s): " + missed);
+ }
+ return this;
+ };
+ /** chainable
+ * MarkdownIt.use(plugin, params)
+ *
+ * Load specified plugin with given params into current parser instance.
+ * It's just a sugar to call `plugin(md, params)` with curring.
+ *
+ * ##### Example
+ *
+ * ```javascript
+ * var iterator = require('markdown-it-for-inline');
+ * var md = require('markdown-it')()
+ * .use(iterator, 'foo_replace', 'text', function (tokens, idx) {
+ * tokens[idx].content = tokens[idx].content.replace(/foo/g, 'bar');
+ * });
+ * ```
+ **/ MarkdownIt.prototype.use = function(plugin /*, params, ... */) {
+ const args = [ this ].concat(Array.prototype.slice.call(arguments, 1));
+ plugin.apply(plugin, args);
+ return this;
+ };
+ /** internal
+ * MarkdownIt.parse(src, env) -> Array
+ * - src (String): source string
+ * - env (Object): environment sandbox
+ *
+ * Parse input string and return list of block tokens (special token type
+ * "inline" will contain list of inline tokens). You should not call this
+ * method directly, until you write custom renderer (for example, to produce
+ * AST).
+ *
+ * `env` is used to pass data between "distributed" rules and return additional
+ * metadata like reference info, needed for the renderer. It also can be used to
+ * inject data in specific cases. Usually, you will be ok to pass `{}`,
+ * and then pass updated object to renderer.
+ **/ MarkdownIt.prototype.parse = function(src, env) {
+ if (typeof src !== "string") {
+ throw new Error("Input data should be a String");
+ }
+ const state = new this.core.State(src, this, env);
+ this.core.process(state);
+ return state.tokens;
+ };
+ /**
+ * MarkdownIt.render(src [, env]) -> String
+ * - src (String): source string
+ * - env (Object): environment sandbox
+ *
+ * Render markdown string into html. It does all magic for you :).
+ *
+ * `env` can be used to inject additional metadata (`{}` by default).
+ * But you will not need it with high probability. See also comment
+ * in [[MarkdownIt.parse]].
+ **/ MarkdownIt.prototype.render = function(src, env) {
+ env = env || {};
+ return this.renderer.render(this.parse(src, env), this.options, env);
+ };
+ /** internal
+ * MarkdownIt.parseInline(src, env) -> Array
+ * - src (String): source string
+ * - env (Object): environment sandbox
+ *
+ * The same as [[MarkdownIt.parse]] but skip all block rules. It returns the
+ * block tokens list with the single `inline` element, containing parsed inline
+ * tokens in `children` property. Also updates `env` object.
+ **/ MarkdownIt.prototype.parseInline = function(src, env) {
+ const state = new this.core.State(src, this, env);
+ state.inlineMode = true;
+ this.core.process(state);
+ return state.tokens;
+ };
+ /**
+ * MarkdownIt.renderInline(src [, env]) -> String
+ * - src (String): source string
+ * - env (Object): environment sandbox
+ *
+ * Similar to [[MarkdownIt.render]] but for single paragraph content. Result
+ * will NOT be wrapped into `` tags.
+ **/ MarkdownIt.prototype.renderInline = function(src, env) {
+ env = env || {};
+ return this.renderer.render(this.parseInline(src, env), this.options, env);
+ };
+ return MarkdownIt;
+}));
diff --git a/AdminPanel/client/src/pages/AiIntegration/ai/vendor/select2-4.0.6-rc.1/LICENSE.md b/AdminPanel/client/src/pages/AiIntegration/ai/vendor/select2-4.0.6-rc.1/LICENSE.md
new file mode 100644
index 0000000000..8cb8a2b12c
--- /dev/null
+++ b/AdminPanel/client/src/pages/AiIntegration/ai/vendor/select2-4.0.6-rc.1/LICENSE.md
@@ -0,0 +1,21 @@
+The MIT License (MIT)
+
+Copyright (c) 2012-2017 Kevin Brown, Igor Vaynberg, and Select2 contributors
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
diff --git a/AdminPanel/client/src/pages/AiIntegration/ai/vendor/select2-4.0.6-rc.1/README.md b/AdminPanel/client/src/pages/AiIntegration/ai/vendor/select2-4.0.6-rc.1/README.md
new file mode 100644
index 0000000000..6ee975d6ee
--- /dev/null
+++ b/AdminPanel/client/src/pages/AiIntegration/ai/vendor/select2-4.0.6-rc.1/README.md
@@ -0,0 +1,123 @@
+Select2
+=======
+[![Build Status][travis-ci-image]][travis-ci-status]
+
+Select2 is a jQuery-based replacement for select boxes. It supports searching,
+remote data sets, and pagination of results.
+
+To get started, checkout examples and documentation at
+https://select2.org/
+
+Use cases
+---------
+* Enhancing native selects with search.
+* Enhancing native selects with a better multi-select interface.
+* Loading data from JavaScript: easily load items via AJAX and have them
+ searchable.
+* Nesting optgroups: native selects only support one level of nesting. Select2
+ does not have this restriction.
+* Tagging: ability to add new items on the fly.
+* Working with large, remote datasets: ability to partially load a dataset based
+ on the search term.
+* Paging of large datasets: easy support for loading more pages when the results
+ are scrolled to the end.
+* Templating: support for custom rendering of results and selections.
+
+Browser compatibility
+---------------------
+* IE 8+
+* Chrome 8+
+* Firefox 10+
+* Safari 3+
+* Opera 10.6+
+
+Select2 is automatically tested on the following browsers.
+
+[![Sauce Labs Test Status][saucelabs-matrix]][saucelabs-status]
+
+Usage
+-----
+You can source Select2 directly from a CDN like [JSDliver][jsdelivr] or
+[CDNJS][cdnjs], [download it from this GitHub repo][releases], or use one of
+the integrations below.
+
+Integrations
+------------
+Third party developers have created plugins for platforms which allow Select2 to be integrated more natively and quickly. For many platforms, additional plugins are not required because Select2 acts as a standard `` box.
+
+Plugins
+
+* [Django]
+ - [django-autocomplete-light]
+ - [django-easy-select2]
+ - [django-select2]
+* [Meteor] - [meteor-select2]
+* [Ruby on Rails][ruby-on-rails] - [select2-rails]
+* [Wicket] - [wicketstuff-select2]
+* [Yii 2][yii2] - [yii2-widget-select2]
+
+Themes
+
+- [Bootstrap 3][bootstrap3] - [select2-bootstrap-theme]
+- [Flat UI][flat-ui] - [select2-flat-theme]
+- [Metro UI][metro-ui] - [select2-metro]
+
+Missing an integration? Modify this `README` and make a pull request back here to Select2 on GitHub.
+
+Internationalization (i18n)
+---------------------------
+Select2 supports multiple languages by simply including the right language JS
+file (`dist/js/i18n/it.js`, `dist/js/i18n/nl.js`, etc.) after
+`dist/js/select2.js`.
+
+Missing a language? Just copy `src/js/select2/i18n/en.js`, translate it, and
+make a pull request back to Select2 here on GitHub.
+
+Documentation
+-------------
+The documentation for Select2 is available
+[through GitHub Pages][documentation] and is located within this repository
+in the [`docs` folder][documentation-folder].
+
+Community
+---------
+You can find out about the different ways to get in touch with the Select2
+community at the [Select2 community page][community].
+
+Copyright and license
+---------------------
+The license is available within the repository in the [LICENSE][license] file.
+
+[cdnjs]: http://www.cdnjs.com/libraries/select2
+[community]: https://select2.org/getting-help
+[documentation]: https://select2.org
+[documentation-folder]: https://github.com/select2/select2/tree/master/docs
+[freenode]: https://freenode.net/
+[jsdelivr]: http://www.jsdelivr.com/#!select2
+[license]: LICENSE.md
+[releases]: https://github.com/select2/select2/releases
+[saucelabs-matrix]: https://saucelabs.com/browser-matrix/select2.svg
+[saucelabs-status]: https://saucelabs.com/u/select2
+[travis-ci-image]: https://img.shields.io/travis/select2/select2/master.svg
+[travis-ci-status]: https://travis-ci.org/select2/select2
+
+[bootstrap3]: https://getbootstrap.com/
+[django]: https://www.djangoproject.com/
+[django-autocomplete-light]: https://github.com/yourlabs/django-autocomplete-light
+[django-easy-select2]: https://github.com/asyncee/django-easy-select2
+[django-select2]: https://github.com/applegrew/django-select2
+[flat-ui]: http://designmodo.github.io/Flat-UI/
+[meteor]: https://www.meteor.com/
+[meteor-select2]: https://github.com/nate-strauser/meteor-select2
+[metro-ui]: http://metroui.org.ua/
+[select2-metro]: http://metroui.org.ua/select2.html
+[ruby-on-rails]: http://rubyonrails.org/
+[select2-bootstrap-theme]: https://github.com/select2/select2-bootstrap-theme
+[select2-flat-theme]: https://github.com/techhysahil/select2-Flat_Theme
+[select2-rails]: https://github.com/argerim/select2-rails
+[vue.js]: http://vuejs.org/
+[select2-vue]: http://vuejs.org/examples/select2.html
+[wicket]: https://wicket.apache.org/
+[wicketstuff-select2]: https://github.com/wicketstuff/core/tree/master/select2-parent
+[yii2]: http://www.yiiframework.com/
+[yii2-widget-select2]: https://github.com/kartik-v/yii2-widget-select2
diff --git a/AdminPanel/client/src/pages/AiIntegration/ai/vendor/select2-4.0.6-rc.1/dist/css/select2.css b/AdminPanel/client/src/pages/AiIntegration/ai/vendor/select2-4.0.6-rc.1/dist/css/select2.css
new file mode 100644
index 0000000000..24f03b181e
--- /dev/null
+++ b/AdminPanel/client/src/pages/AiIntegration/ai/vendor/select2-4.0.6-rc.1/dist/css/select2.css
@@ -0,0 +1,489 @@
+.select2-container {
+ box-sizing: border-box;
+ display: inline-block;
+ margin: 0;
+ position: relative;
+ vertical-align: middle; }
+ .select2-container .select2-selection--single {
+ box-sizing: border-box;
+ cursor: pointer;
+ display: block;
+ height: 22px;
+ user-select: none;
+ -webkit-user-select: none; }
+ .select2-container .select2-selection--single .select2-selection__rendered {
+ font-size: 12px;
+ display: block;
+ padding-left: 8px;
+ padding-right: 20px;
+ overflow: hidden;
+ text-overflow: ellipsis;
+ white-space: nowrap; }
+ .select2-container .select2-selection--single .select2-selection__clear {
+ position: relative; }
+ .select2-container[dir="rtl"] .select2-selection--single .select2-selection__rendered {
+ padding-right: 8px;
+ padding-left: 20px; }
+ .select2-container .select2-selection--multiple {
+ box-sizing: border-box;
+ cursor: pointer;
+ display: block;
+ min-height: 32px;
+ user-select: none;
+ -webkit-user-select: none; }
+ .select2-container .select2-selection--multiple .select2-selection__rendered {
+ display: inline-block;
+ overflow: hidden;
+ padding-left: 8px;
+ text-overflow: ellipsis;
+ white-space: nowrap; }
+ .select2-container .select2-search--inline {
+ float: left; }
+ .select2-container .select2-search--inline .select2-search__field {
+ box-sizing: border-box;
+ border: none;
+ font-size: 100%;
+ margin-top: 5px;
+ padding: 0; }
+ .select2-container .select2-search--inline .select2-search__field::-webkit-search-cancel-button {
+ -webkit-appearance: none; }
+
+.select2-dropdown {
+ background-color: white;
+ border: 1px solid #aaa;
+ border-radius: 2px;
+ box-sizing: border-box;
+ display: block;
+ position: absolute;
+ left: -100000px;
+ width: 100%;
+ z-index: 1051; }
+
+.select2-results {
+ display: block; }
+
+.select2-results__options {
+ font-size: 12px;
+ list-style: none;
+ margin: 0;
+ padding: 0; }
+
+.select2-results__option {
+ padding: 6px;
+ user-select: none;
+ -webkit-user-select: none; }
+ .select2-results__option[aria-selected] {
+ cursor: pointer; }
+
+.select2-container--open .select2-dropdown {
+ left: 0; }
+
+.select2-container--open .select2-dropdown--above {
+ border-bottom: none;
+ border-bottom-left-radius: 0;
+ border-bottom-right-radius: 0; }
+
+.select2-container--open .select2-dropdown--below {
+ border-top: none;
+ border-top-left-radius: 0;
+ border-top-right-radius: 0; }
+
+.select2-search--dropdown {
+ display: block;
+ padding: 4px; }
+ .select2-search--dropdown .select2-search__field {
+ padding: 4px;
+ width: 100%;
+ box-sizing: border-box; }
+ .select2-search--dropdown .select2-search__field::-webkit-search-cancel-button {
+ -webkit-appearance: none; }
+ .select2-search--dropdown.select2-search--hide {
+ display: none; }
+
+.select2-close-mask {
+ border: 0;
+ margin: 0;
+ padding: 0;
+ display: block;
+ position: fixed;
+ left: 0;
+ top: 0;
+ min-height: 100%;
+ min-width: 100%;
+ height: auto;
+ width: auto;
+ opacity: 0;
+ z-index: 99;
+ background-color: #fff;
+ filter: alpha(opacity=0); }
+
+.select2-hidden-accessible {
+ border: 0 !important;
+ clip: rect(0 0 0 0) !important;
+ -webkit-clip-path: inset(50%) !important;
+ clip-path: inset(50%) !important;
+ height: 1px !important;
+ overflow: hidden !important;
+ padding: 0 !important;
+ position: absolute !important;
+ width: 1px !important;
+ white-space: nowrap !important; }
+
+.select2-container--default .select2-selection--single {
+ outline: none;
+ background-color: #fff;
+ border: 1px solid #aaa;
+ border-radius: 2px; }
+ .select2-container--default .select2-selection--single .select2-selection__rendered {
+ font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
+ color: #444;
+ line-height: 22px; }
+ .select2-container--default .select2-selection--single .select2-selection__clear {
+ cursor: pointer;
+ float: right;
+ font-weight: bold; }
+ .select2-container--default .select2-selection--single .select2-selection__placeholder {
+ color: #999; }
+ .select2-container--default .select2-selection--single .select2-selection__arrow {
+ height: 20px;
+ position: absolute;
+ top: 1px;
+ right: 1px;
+ width: 20px; }
+ .select2-container--default .select2-selection--single .select2-selection__arrow b {
+ border-color: #888 transparent transparent transparent;
+ border-style: solid;
+ border-width: 5px 4px 0 4px;
+ height: 0;
+ left: 50%;
+ margin-left: -4px;
+ margin-top: -2px;
+ position: absolute;
+ top: 50%;
+ width: 0; }
+
+.select2-container--default[dir="rtl"] .select2-selection--single .select2-selection__clear {
+ float: left; }
+
+.select2-container--default[dir="rtl"] .select2-selection--single .select2-selection__arrow {
+ left: 1px;
+ right: auto; }
+
+.select2-container--default.select2-container--disabled .select2-selection--single {
+ background-color: #eee;
+ cursor: default; }
+ .select2-container--default.select2-container--disabled .select2-selection--single .select2-selection__clear {
+ display: none; }
+
+.select2-container--default.select2-container--open .select2-selection--single .select2-selection__arrow b {
+ border-color: transparent transparent #888 transparent;
+ border-width: 0 4px 5px 4px; }
+
+.select2-container--default .select2-selection--multiple {
+ background-color: white;
+ border: 1px solid #aaa;
+ border-radius: 2px;
+ cursor: text; }
+ .select2-container--default .select2-selection--multiple .select2-selection__rendered {
+ box-sizing: border-box;
+ list-style: none;
+ margin: 0;
+ padding: 0 5px;
+ width: 100%; }
+ .select2-container--default .select2-selection--multiple .select2-selection__rendered li {
+ list-style: none; }
+ .select2-container--default .select2-selection--multiple .select2-selection__placeholder {
+ color: #999;
+ margin-top: 5px;
+ float: left; }
+ .select2-container--default .select2-selection--multiple .select2-selection__clear {
+ cursor: pointer;
+ float: right;
+ font-weight: bold;
+ margin-top: 5px;
+ margin-right: 10px; }
+ .select2-container--default .select2-selection--multiple .select2-selection__choice {
+ background-color: #e4e4e4;
+ border: 1px solid #aaa;
+ border-radius: 2px;
+ cursor: default;
+ float: left;
+ margin-right: 5px;
+ margin-top: 5px;
+ padding: 0 5px; }
+ .select2-container--default .select2-selection--multiple .select2-selection__choice__remove {
+ color: #999;
+ cursor: pointer;
+ display: inline-block;
+ font-weight: bold;
+ margin-right: 2px; }
+ .select2-container--default .select2-selection--multiple .select2-selection__choice__remove:hover {
+ color: #333; }
+
+.select2-container--default[dir="rtl"] .select2-selection--multiple .select2-selection__choice, .select2-container--default[dir="rtl"] .select2-selection--multiple .select2-selection__placeholder, .select2-container--default[dir="rtl"] .select2-selection--multiple .select2-search--inline {
+ float: right; }
+
+.select2-container--default[dir="rtl"] .select2-selection--multiple .select2-selection__choice {
+ margin-left: 5px;
+ margin-right: auto; }
+
+.select2-container--default[dir="rtl"] .select2-selection--multiple .select2-selection__choice__remove {
+ margin-left: 2px;
+ margin-right: auto; }
+
+.select2-container--default.select2-container--focus .select2-selection--multiple {
+ border: solid black 1px;
+ outline: 0; }
+
+.select2-container--default.select2-container--disabled .select2-selection--multiple {
+ background-color: #eee;
+ cursor: default; }
+
+.select2-container--default.select2-container--disabled .select2-selection__choice__remove {
+ display: none; }
+
+.select2-container--default.select2-container--open.select2-container--above .select2-selection--single, .select2-container--default.select2-container--open.select2-container--above .select2-selection--multiple {
+ border-top-left-radius: 0;
+ border-top-right-radius: 0; }
+
+.select2-container--default.select2-container--open.select2-container--below .select2-selection--single, .select2-container--default.select2-container--open.select2-container--below .select2-selection--multiple {
+ border-bottom-left-radius: 0;
+ border-bottom-right-radius: 0; }
+
+.select2-container--default .select2-search--dropdown .select2-search__field {
+ outline-color: #7d858c;
+ border: 1px solid #aaa; }
+
+.select2-container--default .select2-search--inline .select2-search__field {
+ background: transparent;
+ border: none;
+ outline: 0;
+ box-shadow: none;
+ -webkit-appearance: textfield; }
+
+.select2-container--default .select2-results > .select2-results__options {
+ font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
+ max-height: 200px;
+ overflow-y: auto; }
+
+.select2-container--default .select2-results__option[role=group] {
+ padding: 0; }
+
+.select2-container--default .select2-results__option[aria-disabled=true] {
+ color: #999; }
+
+.select2-container--default .select2-results__option[aria-selected=true] {
+ background-color: #7d858c; }
+
+.select2-container--default .select2-results__option .select2-results__option {
+ padding-left: 1em; }
+ .select2-container--default .select2-results__option .select2-results__option .select2-results__group {
+ padding-left: 0; }
+ .select2-container--default .select2-results__option .select2-results__option .select2-results__option {
+ margin-left: -1em;
+ padding-left: 2em; }
+ .select2-container--default .select2-results__option .select2-results__option .select2-results__option .select2-results__option {
+ margin-left: -2em;
+ padding-left: 3em; }
+ .select2-container--default .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option {
+ margin-left: -3em;
+ padding-left: 4em; }
+ .select2-container--default .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option {
+ margin-left: -4em;
+ padding-left: 5em; }
+ .select2-container--default .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option {
+ margin-left: -5em;
+ padding-left: 6em; }
+
+.select2-container--default .select2-results__option--highlighted[aria-selected] {
+ background-color: rgba(200, 200, 200, 0.5);}
+
+.select2-container--default .select2-results__group {
+ cursor: default;
+ display: block;
+ padding: 6px; }
+
+.select2-container--classic .select2-selection--single {
+ background-color: #f7f7f7;
+ border: 1px solid #aaa;
+ border-radius: 2px;
+ outline: 0;
+ background-image: -webkit-linear-gradient(top, white 50%, #eeeeee 100%);
+ background-image: -o-linear-gradient(top, white 50%, #eeeeee 100%);
+ background-image: linear-gradient(to bottom, white 50%, #eeeeee 100%);
+ background-repeat: repeat-x;
+ filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#FFFFFFFF', endColorstr='#FFEEEEEE', GradientType=0); }
+ .select2-container--classic .select2-selection--single:focus {
+ border: 1px solid #5897fb; }
+ .select2-container--classic .select2-selection--single .select2-selection__rendered {
+ color: #444;
+ line-height: 22px; }
+ .select2-container--classic .select2-selection--single .select2-selection__clear {
+ cursor: pointer;
+ float: right;
+ font-weight: bold;
+ margin-right: 10px; }
+ .select2-container--classic .select2-selection--single .select2-selection__placeholder {
+ color: #999; }
+ .select2-container--classic .select2-selection--single .select2-selection__arrow {
+ background-color: #ddd;
+ border: none;
+ border-left: 1px solid #aaa;
+ border-top-right-radius: 2px;
+ border-bottom-right-radius: 2px;
+ height: 20px;
+ position: absolute;
+ top: 1px;
+ right: 1px;
+ width: 20px;
+ background-image: -webkit-linear-gradient(top, #eeeeee 50%, #cccccc 100%);
+ background-image: -o-linear-gradient(top, #eeeeee 50%, #cccccc 100%);
+ background-image: linear-gradient(to bottom, #eeeeee 50%, #cccccc 100%);
+ background-repeat: repeat-x;
+ filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#FFEEEEEE', endColorstr='#FFCCCCCC', GradientType=0); }
+ .select2-container--classic .select2-selection--single .select2-selection__arrow b {
+ border-color: #888 transparent transparent transparent;
+ border-style: solid;
+ border-width: 5px 4px 0 4px;
+ height: 0;
+ left: 50%;
+ margin-left: -4px;
+ margin-top: -2px;
+ position: absolute;
+ top: 50%;
+ width: 0; }
+
+.select2-container--classic[dir="rtl"] .select2-selection--single .select2-selection__clear {
+ float: left; }
+
+.select2-container--classic[dir="rtl"] .select2-selection--single .select2-selection__arrow {
+ border: none;
+ border-right: 1px solid #aaa;
+ border-radius: 0;
+ border-top-left-radius: 2px;
+ border-bottom-left-radius: 2px;
+ left: 1px;
+ right: auto; }
+
+.select2-container--classic.select2-container--open .select2-selection--single {
+ border: 1px solid #5897fb; }
+ .select2-container--classic.select2-container--open .select2-selection--single .select2-selection__arrow {
+ background: transparent;
+ border: none; }
+ .select2-container--classic.select2-container--open .select2-selection--single .select2-selection__arrow b {
+ border-color: transparent transparent #888 transparent;
+ border-width: 0 4px 5px 4px; }
+
+.select2-container--classic.select2-container--open.select2-container--above .select2-selection--single {
+ border-top: none;
+ border-top-left-radius: 0;
+ border-top-right-radius: 0;
+ background-image: -webkit-linear-gradient(top, white 0%, #eeeeee 50%);
+ background-image: -o-linear-gradient(top, white 0%, #eeeeee 50%);
+ background-image: linear-gradient(to bottom, white 0%, #eeeeee 50%);
+ background-repeat: repeat-x;
+ filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#FFFFFFFF', endColorstr='#FFEEEEEE', GradientType=0); }
+
+.select2-container--classic.select2-container--open.select2-container--below .select2-selection--single {
+ border-bottom: none;
+ border-bottom-left-radius: 0;
+ border-bottom-right-radius: 0;
+ background-image: -webkit-linear-gradient(top, #eeeeee 50%, white 100%);
+ background-image: -o-linear-gradient(top, #eeeeee 50%, white 100%);
+ background-image: linear-gradient(to bottom, #eeeeee 50%, white 100%);
+ background-repeat: repeat-x;
+ filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#FFEEEEEE', endColorstr='#FFFFFFFF', GradientType=0); }
+
+.select2-container--classic .select2-selection--multiple {
+ background-color: white;
+ border: 1px solid #aaa;
+ border-radius: 2px;
+ cursor: text;
+ outline: 0; }
+ .select2-container--classic .select2-selection--multiple:focus {
+ border: 1px solid #5897fb; }
+ .select2-container--classic .select2-selection--multiple .select2-selection__rendered {
+ list-style: none;
+ margin: 0;
+ padding: 0 5px; }
+ .select2-container--classic .select2-selection--multiple .select2-selection__clear {
+ display: none; }
+ .select2-container--classic .select2-selection--multiple .select2-selection__choice {
+ background-color: #e4e4e4;
+ border: 1px solid #aaa;
+ border-radius: 2px;
+ cursor: default;
+ float: left;
+ margin-right: 5px;
+ margin-top: 5px;
+ padding: 0 5px; }
+ .select2-container--classic .select2-selection--multiple .select2-selection__choice__remove {
+ color: #888;
+ cursor: pointer;
+ display: inline-block;
+ font-weight: bold;
+ margin-right: 2px; }
+ .select2-container--classic .select2-selection--multiple .select2-selection__choice__remove:hover {
+ color: #555; }
+
+.select2-container--classic[dir="rtl"] .select2-selection--multiple .select2-selection__choice {
+ float: right;
+ margin-left: 5px;
+ margin-right: auto; }
+
+.select2-container--classic[dir="rtl"] .select2-selection--multiple .select2-selection__choice__remove {
+ margin-left: 2px;
+ margin-right: auto; }
+
+.select2-container--classic.select2-container--open .select2-selection--multiple {
+ border: 1px solid #5897fb; }
+
+.select2-container--classic.select2-container--open.select2-container--above .select2-selection--multiple {
+ border-top: none;
+ border-top-left-radius: 0;
+ border-top-right-radius: 0; }
+
+.select2-container--classic.select2-container--open.select2-container--below .select2-selection--multiple {
+ border-bottom: none;
+ border-bottom-left-radius: 0;
+ border-bottom-right-radius: 0; }
+
+.select2-container--classic .select2-search--dropdown .select2-search__field {
+ border: 1px solid #aaa;
+ outline: 0; }
+
+.select2-container--classic .select2-search--inline .select2-search__field {
+ outline: 0;
+ box-shadow: none; }
+
+.select2-container--classic .select2-dropdown {
+ background-color: white;
+ border: 1px solid transparent; }
+
+.select2-container--classic .select2-dropdown--above {
+ border-bottom: none; }
+
+.select2-container--classic .select2-dropdown--below {
+ border-top: none; }
+
+.select2-container--classic .select2-results > .select2-results__options {
+ max-height: 200px;
+ overflow-y: auto; }
+
+.select2-container--classic .select2-results__option[role=group] {
+ padding: 0; }
+
+.select2-container--classic .select2-results__option[aria-disabled=true] {
+ color: grey; }
+
+.select2-container--classic .select2-results__option--highlighted[aria-selected] {
+ background-color: #3875d7;
+ color: white; }
+
+.select2-container--classic .select2-results__group {
+ cursor: default;
+ display: block;
+ padding: 6px; }
+
+.select2-container--classic.select2-container--open .select2-dropdown {
+ border-color: #5897fb; }
diff --git a/AdminPanel/client/src/pages/AiIntegration/ai/vendor/select2-4.0.6-rc.1/dist/css/select2.min.css b/AdminPanel/client/src/pages/AiIntegration/ai/vendor/select2-4.0.6-rc.1/dist/css/select2.min.css
new file mode 100644
index 0000000000..60d599044a
--- /dev/null
+++ b/AdminPanel/client/src/pages/AiIntegration/ai/vendor/select2-4.0.6-rc.1/dist/css/select2.min.css
@@ -0,0 +1 @@
+.select2-container{box-sizing:border-box;display:inline-block;margin:0;position:relative;vertical-align:middle}.select2-container .select2-selection--single{box-sizing:border-box;cursor:pointer;display:block;height:28px;user-select:none;-webkit-user-select:none}.select2-container .select2-selection--single .select2-selection__rendered{display:block;padding-left:8px;padding-right:20px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.select2-container .select2-selection--single .select2-selection__clear{position:relative}.select2-container[dir="rtl"] .select2-selection--single .select2-selection__rendered{padding-right:8px;padding-left:20px}.select2-container .select2-selection--multiple{box-sizing:border-box;cursor:pointer;display:block;min-height:32px;user-select:none;-webkit-user-select:none}.select2-container .select2-selection--multiple .select2-selection__rendered{display:inline-block;overflow:hidden;padding-left:8px;text-overflow:ellipsis;white-space:nowrap}.select2-container .select2-search--inline{float:left}.select2-container .select2-search--inline .select2-search__field{box-sizing:border-box;border:none;font-size:100%;margin-top:5px;padding:0}.select2-container .select2-search--inline .select2-search__field::-webkit-search-cancel-button{-webkit-appearance:none}.select2-dropdown{background-color:white;border:1px solid #aaa;border-radius:4px;box-sizing:border-box;display:block;position:absolute;left:-100000px;width:100%;z-index:1051}.select2-results{display:block}.select2-results__options{list-style:none;margin:0;padding:0}.select2-results__option{padding:6px;user-select:none;-webkit-user-select:none}.select2-results__option[aria-selected]{cursor:pointer}.select2-container--open .select2-dropdown{left:0}.select2-container--open .select2-dropdown--above{border-bottom:none;border-bottom-left-radius:0;border-bottom-right-radius:0}.select2-container--open .select2-dropdown--below{border-top:none;border-top-left-radius:0;border-top-right-radius:0}.select2-search--dropdown{display:block;padding:4px}.select2-search--dropdown .select2-search__field{padding:4px;width:100%;box-sizing:border-box}.select2-search--dropdown .select2-search__field::-webkit-search-cancel-button{-webkit-appearance:none}.select2-search--dropdown.select2-search--hide{display:none}.select2-close-mask{border:0;margin:0;padding:0;display:block;position:fixed;left:0;top:0;min-height:100%;min-width:100%;height:auto;width:auto;opacity:0;z-index:99;background-color:#fff;filter:alpha(opacity=0)}.select2-hidden-accessible{border:0 !important;clip:rect(0 0 0 0) !important;-webkit-clip-path:inset(50%) !important;clip-path:inset(50%) !important;height:1px !important;overflow:hidden !important;padding:0 !important;position:absolute !important;width:1px !important;white-space:nowrap !important}.select2-container--default .select2-selection--single{background-color:#fff;border:1px solid #aaa;border-radius:4px}.select2-container--default .select2-selection--single .select2-selection__rendered{color:#444;line-height:28px}.select2-container--default .select2-selection--single .select2-selection__clear{cursor:pointer;float:right;font-weight:bold}.select2-container--default .select2-selection--single .select2-selection__placeholder{color:#999}.select2-container--default .select2-selection--single .select2-selection__arrow{height:26px;position:absolute;top:1px;right:1px;width:20px}.select2-container--default .select2-selection--single .select2-selection__arrow b{border-color:#888 transparent transparent transparent;border-style:solid;border-width:5px 4px 0 4px;height:0;left:50%;margin-left:-4px;margin-top:-2px;position:absolute;top:50%;width:0}.select2-container--default[dir="rtl"] .select2-selection--single .select2-selection__clear{float:left}.select2-container--default[dir="rtl"] .select2-selection--single .select2-selection__arrow{left:1px;right:auto}.select2-container--default.select2-container--disabled .select2-selection--single{background-color:#eee;cursor:default}.select2-container--default.select2-container--disabled .select2-selection--single .select2-selection__clear{display:none}.select2-container--default.select2-container--open .select2-selection--single .select2-selection__arrow b{border-color:transparent transparent #888 transparent;border-width:0 4px 5px 4px}.select2-container--default .select2-selection--multiple{background-color:white;border:1px solid #aaa;border-radius:4px;cursor:text}.select2-container--default .select2-selection--multiple .select2-selection__rendered{box-sizing:border-box;list-style:none;margin:0;padding:0 5px;width:100%}.select2-container--default .select2-selection--multiple .select2-selection__rendered li{list-style:none}.select2-container--default .select2-selection--multiple .select2-selection__placeholder{color:#999;margin-top:5px;float:left}.select2-container--default .select2-selection--multiple .select2-selection__clear{cursor:pointer;float:right;font-weight:bold;margin-top:5px;margin-right:10px}.select2-container--default .select2-selection--multiple .select2-selection__choice{background-color:#e4e4e4;border:1px solid #aaa;border-radius:4px;cursor:default;float:left;margin-right:5px;margin-top:5px;padding:0 5px}.select2-container--default .select2-selection--multiple .select2-selection__choice__remove{color:#999;cursor:pointer;display:inline-block;font-weight:bold;margin-right:2px}.select2-container--default .select2-selection--multiple .select2-selection__choice__remove:hover{color:#333}.select2-container--default[dir="rtl"] .select2-selection--multiple .select2-selection__choice,.select2-container--default[dir="rtl"] .select2-selection--multiple .select2-selection__placeholder,.select2-container--default[dir="rtl"] .select2-selection--multiple .select2-search--inline{float:right}.select2-container--default[dir="rtl"] .select2-selection--multiple .select2-selection__choice{margin-left:5px;margin-right:auto}.select2-container--default[dir="rtl"] .select2-selection--multiple .select2-selection__choice__remove{margin-left:2px;margin-right:auto}.select2-container--default.select2-container--focus .select2-selection--multiple{border:solid black 1px;outline:0}.select2-container--default.select2-container--disabled .select2-selection--multiple{background-color:#eee;cursor:default}.select2-container--default.select2-container--disabled .select2-selection__choice__remove{display:none}.select2-container--default.select2-container--open.select2-container--above .select2-selection--single,.select2-container--default.select2-container--open.select2-container--above .select2-selection--multiple{border-top-left-radius:0;border-top-right-radius:0}.select2-container--default.select2-container--open.select2-container--below .select2-selection--single,.select2-container--default.select2-container--open.select2-container--below .select2-selection--multiple{border-bottom-left-radius:0;border-bottom-right-radius:0}.select2-container--default .select2-search--dropdown .select2-search__field{border:1px solid #aaa}.select2-container--default .select2-search--inline .select2-search__field{background:transparent;border:none;outline:0;box-shadow:none;-webkit-appearance:textfield}.select2-container--default .select2-results>.select2-results__options{max-height:200px;overflow-y:auto}.select2-container--default .select2-results__option[role=group]{padding:0}.select2-container--default .select2-results__option[aria-disabled=true]{color:#999}.select2-container--default .select2-results__option[aria-selected=true]{background-color:#ddd}.select2-container--default .select2-results__option .select2-results__option{padding-left:1em}.select2-container--default .select2-results__option .select2-results__option .select2-results__group{padding-left:0}.select2-container--default .select2-results__option .select2-results__option .select2-results__option{margin-left:-1em;padding-left:2em}.select2-container--default .select2-results__option .select2-results__option .select2-results__option .select2-results__option{margin-left:-2em;padding-left:3em}.select2-container--default .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option{margin-left:-3em;padding-left:4em}.select2-container--default .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option{margin-left:-4em;padding-left:5em}.select2-container--default .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option{margin-left:-5em;padding-left:6em}.select2-container--default .select2-results__option--highlighted[aria-selected]{background-color:#5897fb;color:white}.select2-container--default .select2-results__group{cursor:default;display:block;padding:6px}.select2-container--classic .select2-selection--single{background-color:#f7f7f7;border:1px solid #aaa;border-radius:4px;outline:0;background-image:-webkit-linear-gradient(top, #fff 50%, #eee 100%);background-image:-o-linear-gradient(top, #fff 50%, #eee 100%);background-image:linear-gradient(to bottom, #fff 50%, #eee 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#FFFFFFFF', endColorstr='#FFEEEEEE', GradientType=0)}.select2-container--classic .select2-selection--single:focus{border:1px solid #5897fb}.select2-container--classic .select2-selection--single .select2-selection__rendered{color:#444;line-height:28px}.select2-container--classic .select2-selection--single .select2-selection__clear{cursor:pointer;float:right;font-weight:bold;margin-right:10px}.select2-container--classic .select2-selection--single .select2-selection__placeholder{color:#999}.select2-container--classic .select2-selection--single .select2-selection__arrow{background-color:#ddd;border:none;border-left:1px solid #aaa;border-top-right-radius:4px;border-bottom-right-radius:4px;height:26px;position:absolute;top:1px;right:1px;width:20px;background-image:-webkit-linear-gradient(top, #eee 50%, #ccc 100%);background-image:-o-linear-gradient(top, #eee 50%, #ccc 100%);background-image:linear-gradient(to bottom, #eee 50%, #ccc 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#FFEEEEEE', endColorstr='#FFCCCCCC', GradientType=0)}.select2-container--classic .select2-selection--single .select2-selection__arrow b{border-color:#888 transparent transparent transparent;border-style:solid;border-width:5px 4px 0 4px;height:0;left:50%;margin-left:-4px;margin-top:-2px;position:absolute;top:50%;width:0}.select2-container--classic[dir="rtl"] .select2-selection--single .select2-selection__clear{float:left}.select2-container--classic[dir="rtl"] .select2-selection--single .select2-selection__arrow{border:none;border-right:1px solid #aaa;border-radius:0;border-top-left-radius:4px;border-bottom-left-radius:4px;left:1px;right:auto}.select2-container--classic.select2-container--open .select2-selection--single{border:1px solid #5897fb}.select2-container--classic.select2-container--open .select2-selection--single .select2-selection__arrow{background:transparent;border:none}.select2-container--classic.select2-container--open .select2-selection--single .select2-selection__arrow b{border-color:transparent transparent #888 transparent;border-width:0 4px 5px 4px}.select2-container--classic.select2-container--open.select2-container--above .select2-selection--single{border-top:none;border-top-left-radius:0;border-top-right-radius:0;background-image:-webkit-linear-gradient(top, #fff 0%, #eee 50%);background-image:-o-linear-gradient(top, #fff 0%, #eee 50%);background-image:linear-gradient(to bottom, #fff 0%, #eee 50%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#FFFFFFFF', endColorstr='#FFEEEEEE', GradientType=0)}.select2-container--classic.select2-container--open.select2-container--below .select2-selection--single{border-bottom:none;border-bottom-left-radius:0;border-bottom-right-radius:0;background-image:-webkit-linear-gradient(top, #eee 50%, #fff 100%);background-image:-o-linear-gradient(top, #eee 50%, #fff 100%);background-image:linear-gradient(to bottom, #eee 50%, #fff 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#FFEEEEEE', endColorstr='#FFFFFFFF', GradientType=0)}.select2-container--classic .select2-selection--multiple{background-color:white;border:1px solid #aaa;border-radius:4px;cursor:text;outline:0}.select2-container--classic .select2-selection--multiple:focus{border:1px solid #5897fb}.select2-container--classic .select2-selection--multiple .select2-selection__rendered{list-style:none;margin:0;padding:0 5px}.select2-container--classic .select2-selection--multiple .select2-selection__clear{display:none}.select2-container--classic .select2-selection--multiple .select2-selection__choice{background-color:#e4e4e4;border:1px solid #aaa;border-radius:4px;cursor:default;float:left;margin-right:5px;margin-top:5px;padding:0 5px}.select2-container--classic .select2-selection--multiple .select2-selection__choice__remove{color:#888;cursor:pointer;display:inline-block;font-weight:bold;margin-right:2px}.select2-container--classic .select2-selection--multiple .select2-selection__choice__remove:hover{color:#555}.select2-container--classic[dir="rtl"] .select2-selection--multiple .select2-selection__choice{float:right;margin-left:5px;margin-right:auto}.select2-container--classic[dir="rtl"] .select2-selection--multiple .select2-selection__choice__remove{margin-left:2px;margin-right:auto}.select2-container--classic.select2-container--open .select2-selection--multiple{border:1px solid #5897fb}.select2-container--classic.select2-container--open.select2-container--above .select2-selection--multiple{border-top:none;border-top-left-radius:0;border-top-right-radius:0}.select2-container--classic.select2-container--open.select2-container--below .select2-selection--multiple{border-bottom:none;border-bottom-left-radius:0;border-bottom-right-radius:0}.select2-container--classic .select2-search--dropdown .select2-search__field{border:1px solid #aaa;outline:0}.select2-container--classic .select2-search--inline .select2-search__field{outline:0;box-shadow:none}.select2-container--classic .select2-dropdown{background-color:#fff;border:1px solid transparent}.select2-container--classic .select2-dropdown--above{border-bottom:none}.select2-container--classic .select2-dropdown--below{border-top:none}.select2-container--classic .select2-results>.select2-results__options{max-height:200px;overflow-y:auto}.select2-container--classic .select2-results__option[role=group]{padding:0}.select2-container--classic .select2-results__option[aria-disabled=true]{color:grey}.select2-container--classic .select2-results__option--highlighted[aria-selected]{background-color:#3875d7;color:#fff}.select2-container--classic .select2-results__group{cursor:default;display:block;padding:6px}.select2-container--classic.select2-container--open .select2-dropdown{border-color:#5897fb}
diff --git a/AdminPanel/client/src/pages/AiIntegration/ai/vendor/select2-4.0.6-rc.1/dist/js/select2.full.js b/AdminPanel/client/src/pages/AiIntegration/ai/vendor/select2-4.0.6-rc.1/dist/js/select2.full.js
new file mode 100644
index 0000000000..0e897849c0
--- /dev/null
+++ b/AdminPanel/client/src/pages/AiIntegration/ai/vendor/select2-4.0.6-rc.1/dist/js/select2.full.js
@@ -0,0 +1,6559 @@
+/*!
+ * Select2 4.0.6-rc.1
+ * https://select2.github.io
+ *
+ * Released under the MIT license
+ * https://github.com/select2/select2/blob/master/LICENSE.md
+ */
+;(function (factory) {
+ if (typeof define === 'function' && define.amd) {
+ // AMD. Register as an anonymous module.
+ define(['jquery'], factory);
+ } else if (typeof module === 'object' && module.exports) {
+ // Node/CommonJS
+ module.exports = function (root, jQuery) {
+ if (jQuery === undefined) {
+ // require('jQuery') returns a factory that requires window to
+ // build a jQuery instance, we normalize how we use modules
+ // that require this pattern but the window provided is a noop
+ // if it's defined (how jquery works)
+ if (typeof window !== 'undefined') {
+ jQuery = require('jquery');
+ }
+ else {
+ jQuery = require('jquery')(root);
+ }
+ }
+ factory(jQuery);
+ return jQuery;
+ };
+ } else {
+ // Browser globals
+ factory(jQuery);
+ }
+} (function (jQuery) {
+ // This is needed so we can catch the AMD loader configuration and use it
+ // The inner file should be wrapped (by `banner.start.js`) in a function that
+ // returns the AMD loader references.
+ var S2 =(function () {
+ // Restore the Select2 AMD loader so it can be used
+ // Needed mostly in the language files, where the loader is not inserted
+ if (jQuery && jQuery.fn && jQuery.fn.select2 && jQuery.fn.select2.amd) {
+ var S2 = jQuery.fn.select2.amd;
+ }
+var S2;(function () { if (!S2 || !S2.requirejs) {
+if (!S2) { S2 = {}; } else { require = S2; }
+/**
+ * @license almond 0.3.3 Copyright jQuery Foundation and other contributors.
+ * Released under MIT license, http://github.com/requirejs/almond/LICENSE
+ */
+//Going sloppy to avoid 'use strict' string cost, but strict practices should
+//be followed.
+/*global setTimeout: false */
+
+var requirejs, require, define;
+(function (undef) {
+ var main, req, makeMap, handlers,
+ defined = {},
+ waiting = {},
+ config = {},
+ defining = {},
+ hasOwn = Object.prototype.hasOwnProperty,
+ aps = [].slice,
+ jsSuffixRegExp = /\.js$/;
+
+ function hasProp(obj, prop) {
+ return hasOwn.call(obj, prop);
+ }
+
+ /**
+ * 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.
+ * @returns {String} normalized name
+ */
+ function normalize(name, baseName) {
+ var nameParts, nameSegment, mapValue, foundMap, lastIndex,
+ foundI, foundStarMap, starI, i, j, part, normalizedBaseParts,
+ baseParts = baseName && baseName.split("/"),
+ map = config.map,
+ starMap = (map && map['*']) || {};
+
+ //Adjust any relative paths.
+ if (name) {
+ name = name.split('/');
+ lastIndex = name.length - 1;
+
+ // If wanting node ID compatibility, strip .js from end
+ // of IDs. Have to do this here, and not in nameToUrl
+ // because node allows either .js or non .js to map
+ // to same file.
+ if (config.nodeIdCompat && jsSuffixRegExp.test(name[lastIndex])) {
+ name[lastIndex] = name[lastIndex].replace(jsSuffixRegExp, '');
+ }
+
+ // Starts with a '.' so need the baseName
+ if (name[0].charAt(0) === '.' && baseParts) {
+ //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);
+ }
+
+ //start trimDots
+ for (i = 0; i < name.length; i++) {
+ part = name[i];
+ if (part === '.') {
+ name.splice(i, 1);
+ i -= 1;
+ } else if (part === '..') {
+ // If at the start, or previous value is still ..,
+ // keep them so that when converted to a path it may
+ // still work when converted to a path, even though
+ // as an ID it is less than ideal. In larger point
+ // releases, may be better to just kick out an error.
+ if (i === 0 || (i === 1 && name[2] === '..') || name[i - 1] === '..') {
+ continue;
+ } else if (i > 0) {
+ name.splice(i - 1, 2);
+ i -= 2;
+ }
+ }
+ }
+ //end trimDots
+
+ name = name.join('/');
+ }
+
+ //Apply map config if available.
+ if ((baseParts || starMap) && map) {
+ 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 = map[baseParts.slice(0, j).join('/')];
+
+ //baseName segment has config, find if it has one for
+ //this name.
+ if (mapValue) {
+ mapValue = 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 && starMap[nameSegment]) {
+ foundStarMap = starMap[nameSegment];
+ starI = i;
+ }
+ }
+
+ if (!foundMap && foundStarMap) {
+ foundMap = foundStarMap;
+ foundI = starI;
+ }
+
+ if (foundMap) {
+ nameParts.splice(0, foundI, foundMap);
+ name = nameParts.join('/');
+ }
+ }
+
+ return name;
+ }
+
+ function makeRequire(relName, forceSync) {
+ return function () {
+ //A version of a require function that passes a moduleName
+ //value for items that may need to
+ //look up paths relative to the moduleName
+ var args = aps.call(arguments, 0);
+
+ //If first arg is not require('string'), and there is only
+ //one arg, it is the array form without a callback. Insert
+ //a null so that the following concat is correct.
+ if (typeof args[0] !== 'string' && args.length === 1) {
+ args.push(null);
+ }
+ return req.apply(undef, args.concat([relName, forceSync]));
+ };
+ }
+
+ function makeNormalize(relName) {
+ return function (name) {
+ return normalize(name, relName);
+ };
+ }
+
+ function makeLoad(depName) {
+ return function (value) {
+ defined[depName] = value;
+ };
+ }
+
+ function callDep(name) {
+ if (hasProp(waiting, name)) {
+ var args = waiting[name];
+ delete waiting[name];
+ defining[name] = true;
+ main.apply(undef, args);
+ }
+
+ if (!hasProp(defined, name) && !hasProp(defining, name)) {
+ throw new Error('No ' + name);
+ }
+ return defined[name];
+ }
+
+ //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 parts array for a relName where first part is plugin ID,
+ //second part is resource ID. Assumes relName has already been normalized.
+ function makeRelParts(relName) {
+ return relName ? splitPrefix(relName) : [];
+ }
+
+ /**
+ * Makes a name map, normalizing the name, and using a plugin
+ * for normalization if necessary. Grabs a ref to plugin
+ * too, as an optimization.
+ */
+ makeMap = function (name, relParts) {
+ var plugin,
+ parts = splitPrefix(name),
+ prefix = parts[0],
+ relResourceName = relParts[1];
+
+ name = parts[1];
+
+ if (prefix) {
+ prefix = normalize(prefix, relResourceName);
+ plugin = callDep(prefix);
+ }
+
+ //Normalize according
+ if (prefix) {
+ if (plugin && plugin.normalize) {
+ name = plugin.normalize(name, makeNormalize(relResourceName));
+ } else {
+ name = normalize(name, relResourceName);
+ }
+ } else {
+ name = normalize(name, relResourceName);
+ parts = splitPrefix(name);
+ prefix = parts[0];
+ name = parts[1];
+ if (prefix) {
+ plugin = callDep(prefix);
+ }
+ }
+
+ //Using ridiculous property names for space reasons
+ return {
+ f: prefix ? prefix + '!' + name : name, //fullName
+ n: name,
+ pr: prefix,
+ p: plugin
+ };
+ };
+
+ function makeConfig(name) {
+ return function () {
+ return (config && config.config && config.config[name]) || {};
+ };
+ }
+
+ handlers = {
+ require: function (name) {
+ return makeRequire(name);
+ },
+ exports: function (name) {
+ var e = defined[name];
+ if (typeof e !== 'undefined') {
+ return e;
+ } else {
+ return (defined[name] = {});
+ }
+ },
+ module: function (name) {
+ return {
+ id: name,
+ uri: '',
+ exports: defined[name],
+ config: makeConfig(name)
+ };
+ }
+ };
+
+ main = function (name, deps, callback, relName) {
+ var cjsModule, depName, ret, map, i, relParts,
+ args = [],
+ callbackType = typeof callback,
+ usingExports;
+
+ //Use name if no relName
+ relName = relName || name;
+ relParts = makeRelParts(relName);
+
+ //Call the callback to define the module, if necessary.
+ if (callbackType === 'undefined' || callbackType === 'function') {
+ //Pull out the defined dependencies and pass the ordered
+ //values to the callback.
+ //Default to [require, exports, module] if no deps
+ deps = !deps.length && callback.length ? ['require', 'exports', 'module'] : deps;
+ for (i = 0; i < deps.length; i += 1) {
+ map = makeMap(deps[i], relParts);
+ depName = map.f;
+
+ //Fast path CommonJS standard dependencies.
+ if (depName === "require") {
+ args[i] = handlers.require(name);
+ } else if (depName === "exports") {
+ //CommonJS module spec 1.1
+ args[i] = handlers.exports(name);
+ usingExports = true;
+ } else if (depName === "module") {
+ //CommonJS module spec 1.1
+ cjsModule = args[i] = handlers.module(name);
+ } else if (hasProp(defined, depName) ||
+ hasProp(waiting, depName) ||
+ hasProp(defining, depName)) {
+ args[i] = callDep(depName);
+ } else if (map.p) {
+ map.p.load(map.n, makeRequire(relName, true), makeLoad(depName), {});
+ args[i] = defined[depName];
+ } else {
+ throw new Error(name + ' missing ' + depName);
+ }
+ }
+
+ ret = callback ? callback.apply(defined[name], args) : undefined;
+
+ if (name) {
+ //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.
+ if (cjsModule && cjsModule.exports !== undef &&
+ cjsModule.exports !== defined[name]) {
+ defined[name] = cjsModule.exports;
+ } else if (ret !== undef || !usingExports) {
+ //Use the return value from the function.
+ defined[name] = ret;
+ }
+ }
+ } else if (name) {
+ //May just be an object definition for the module. Only
+ //worry about defining if have a module name.
+ defined[name] = callback;
+ }
+ };
+
+ requirejs = require = req = function (deps, callback, relName, forceSync, alt) {
+ if (typeof deps === "string") {
+ if (handlers[deps]) {
+ //callback in this case is really relName
+ return handlers[deps](callback);
+ }
+ //Just return the module wanted. In this scenario, the
+ //deps arg is the module name, and second arg (if passed)
+ //is just the relName.
+ //Normalize module name, if it contains . or ..
+ return callDep(makeMap(deps, makeRelParts(callback)).f);
+ } else if (!deps.splice) {
+ //deps is a config object, not an array.
+ config = deps;
+ if (config.deps) {
+ req(config.deps, config.callback);
+ }
+ if (!callback) {
+ return;
+ }
+
+ if (callback.splice) {
+ //callback is an array, which means it is a dependency list.
+ //Adjust args if there are dependencies
+ deps = callback;
+ callback = relName;
+ relName = null;
+ } else {
+ deps = undef;
+ }
+ }
+
+ //Support require(['a'])
+ callback = callback || function () {};
+
+ //If relName is a function, it is an errback handler,
+ //so remove it.
+ if (typeof relName === 'function') {
+ relName = forceSync;
+ forceSync = alt;
+ }
+
+ //Simulate async callback;
+ if (forceSync) {
+ main(undef, deps, callback, relName);
+ } else {
+ //Using a non-zero value because of concern for what old browsers
+ //do, and latest browsers "upgrade" to 4 if lower value is used:
+ //http://www.whatwg.org/specs/web-apps/current-work/multipage/timers.html#dom-windowtimers-settimeout:
+ //If want a value immediately, use require('id') instead -- something
+ //that works in almond on the global level, but not guaranteed and
+ //unlikely to work in other AMD implementations.
+ setTimeout(function () {
+ main(undef, deps, callback, relName);
+ }, 4);
+ }
+
+ return req;
+ };
+
+ /**
+ * Just drops the config on the floor, but returns req in case
+ * the config return value is used.
+ */
+ req.config = function (cfg) {
+ return req(cfg);
+ };
+
+ /**
+ * Expose module registry for debugging and tooling
+ */
+ requirejs._defined = defined;
+
+ define = function (name, deps, callback) {
+ if (typeof name !== 'string') {
+ throw new Error('See almond README: incorrect module build, no module name');
+ }
+
+ //This module may not have dependencies
+ if (!deps.splice) {
+ //deps is not an array, so probably means
+ //an object literal or factory function for
+ //the value. Adjust args.
+ callback = deps;
+ deps = [];
+ }
+
+ if (!hasProp(defined, name) && !hasProp(waiting, name)) {
+ waiting[name] = [name, deps, callback];
+ }
+ };
+
+ define.amd = {
+ jQuery: true
+ };
+}());
+
+S2.requirejs = requirejs;S2.require = require;S2.define = define;
+}
+}());
+S2.define("almond", function(){});
+
+/* global jQuery:false, $:false */
+S2.define('jquery',[],function () {
+ var _$ = jQuery || $;
+
+ if (_$ == null && console && console.error) {
+ console.error(
+ 'Select2: An instance of jQuery or a jQuery-compatible library was not ' +
+ 'found. Make sure that you are including jQuery before Select2 on your ' +
+ 'web page.'
+ );
+ }
+
+ return _$;
+});
+
+S2.define('select2/utils',[
+ 'jquery'
+], function ($) {
+ var Utils = {};
+
+ Utils.Extend = function (ChildClass, SuperClass) {
+ var __hasProp = {}.hasOwnProperty;
+
+ function BaseConstructor () {
+ this.constructor = ChildClass;
+ }
+
+ for (var key in SuperClass) {
+ if (__hasProp.call(SuperClass, key)) {
+ ChildClass[key] = SuperClass[key];
+ }
+ }
+
+ BaseConstructor.prototype = SuperClass.prototype;
+ ChildClass.prototype = new BaseConstructor();
+ ChildClass.__super__ = SuperClass.prototype;
+
+ return ChildClass;
+ };
+
+ function getMethods (theClass) {
+ var proto = theClass.prototype;
+
+ var methods = [];
+
+ for (var methodName in proto) {
+ var m = proto[methodName];
+
+ if (typeof m !== 'function') {
+ continue;
+ }
+
+ if (methodName === 'constructor') {
+ continue;
+ }
+
+ methods.push(methodName);
+ }
+
+ return methods;
+ }
+
+ Utils.Decorate = function (SuperClass, DecoratorClass) {
+ var decoratedMethods = getMethods(DecoratorClass);
+ var superMethods = getMethods(SuperClass);
+
+ function DecoratedClass () {
+ var unshift = Array.prototype.unshift;
+
+ var argCount = DecoratorClass.prototype.constructor.length;
+
+ var calledConstructor = SuperClass.prototype.constructor;
+
+ if (argCount > 0) {
+ unshift.call(arguments, SuperClass.prototype.constructor);
+
+ calledConstructor = DecoratorClass.prototype.constructor;
+ }
+
+ calledConstructor.apply(this, arguments);
+ }
+
+ DecoratorClass.displayName = SuperClass.displayName;
+
+ function ctr () {
+ this.constructor = DecoratedClass;
+ }
+
+ DecoratedClass.prototype = new ctr();
+
+ for (var m = 0; m < superMethods.length; m++) {
+ var superMethod = superMethods[m];
+
+ DecoratedClass.prototype[superMethod] =
+ SuperClass.prototype[superMethod];
+ }
+
+ var calledMethod = function (methodName) {
+ // Stub out the original method if it's not decorating an actual method
+ var originalMethod = function () {};
+
+ if (methodName in DecoratedClass.prototype) {
+ originalMethod = DecoratedClass.prototype[methodName];
+ }
+
+ var decoratedMethod = DecoratorClass.prototype[methodName];
+
+ return function () {
+ var unshift = Array.prototype.unshift;
+
+ unshift.call(arguments, originalMethod);
+
+ return decoratedMethod.apply(this, arguments);
+ };
+ };
+
+ for (var d = 0; d < decoratedMethods.length; d++) {
+ var decoratedMethod = decoratedMethods[d];
+
+ DecoratedClass.prototype[decoratedMethod] = calledMethod(decoratedMethod);
+ }
+
+ return DecoratedClass;
+ };
+
+ var Observable = function () {
+ this.listeners = {};
+ };
+
+ Observable.prototype.on = function (event, callback) {
+ this.listeners = this.listeners || {};
+
+ if (event in this.listeners) {
+ this.listeners[event].push(callback);
+ } else {
+ this.listeners[event] = [callback];
+ }
+ };
+
+ Observable.prototype.trigger = function (event) {
+ var slice = Array.prototype.slice;
+ var params = slice.call(arguments, 1);
+
+ this.listeners = this.listeners || {};
+
+ // Params should always come in as an array
+ if (params == null) {
+ params = [];
+ }
+
+ // If there are no arguments to the event, use a temporary object
+ if (params.length === 0) {
+ params.push({});
+ }
+
+ // Set the `_type` of the first object to the event
+ params[0]._type = event;
+
+ if (event in this.listeners) {
+ this.invoke(this.listeners[event], slice.call(arguments, 1));
+ }
+
+ if ('*' in this.listeners) {
+ this.invoke(this.listeners['*'], arguments);
+ }
+ };
+
+ Observable.prototype.invoke = function (listeners, params) {
+ for (var i = 0, len = listeners.length; i < len; i++) {
+ listeners[i].apply(this, params);
+ }
+ };
+
+ Utils.Observable = Observable;
+
+ Utils.generateChars = function (length) {
+ var chars = '';
+
+ for (var i = 0; i < length; i++) {
+ var randomChar = Math.floor(Math.random() * 36);
+ chars += randomChar.toString(36);
+ }
+
+ return chars;
+ };
+
+ Utils.bind = function (func, context) {
+ return function () {
+ func.apply(context, arguments);
+ };
+ };
+
+ Utils._convertData = function (data) {
+ for (var originalKey in data) {
+ var keys = originalKey.split('-');
+
+ var dataLevel = data;
+
+ if (keys.length === 1) {
+ continue;
+ }
+
+ for (var k = 0; k < keys.length; k++) {
+ var key = keys[k];
+
+ // Lowercase the first letter
+ // By default, dash-separated becomes camelCase
+ key = key.substring(0, 1).toLowerCase() + key.substring(1);
+
+ if (!(key in dataLevel)) {
+ dataLevel[key] = {};
+ }
+
+ if (k == keys.length - 1) {
+ dataLevel[key] = data[originalKey];
+ }
+
+ dataLevel = dataLevel[key];
+ }
+
+ delete data[originalKey];
+ }
+
+ return data;
+ };
+
+ Utils.hasScroll = function (index, el) {
+ // Adapted from the function created by @ShadowScripter
+ // and adapted by @BillBarry on the Stack Exchange Code Review website.
+ // The original code can be found at
+ // http://codereview.stackexchange.com/q/13338
+ // and was designed to be used with the Sizzle selector engine.
+
+ var $el = $(el);
+ var overflowX = el.style.overflowX;
+ var overflowY = el.style.overflowY;
+
+ //Check both x and y declarations
+ if (overflowX === overflowY &&
+ (overflowY === 'hidden' || overflowY === 'visible')) {
+ return false;
+ }
+
+ if (overflowX === 'scroll' || overflowY === 'scroll') {
+ return true;
+ }
+
+ return ($el.innerHeight() < el.scrollHeight ||
+ $el.innerWidth() < el.scrollWidth);
+ };
+
+ Utils.escapeMarkup = function (markup) {
+ var replaceMap = {
+ '\\': '\',
+ '&': '&',
+ '<': '<',
+ '>': '>',
+ '"': '"',
+ '\'': ''',
+ '/': '/'
+ };
+
+ // Do not try to escape the markup if it's not a string
+ if (typeof markup !== 'string') {
+ return markup;
+ }
+
+ return String(markup).replace(/[&<>"'\/\\]/g, function (match) {
+ return replaceMap[match];
+ });
+ };
+
+ // Append an array of jQuery nodes to a given element.
+ Utils.appendMany = function ($element, $nodes) {
+ // jQuery 1.7.x does not support $.fn.append() with an array
+ // Fall back to a jQuery object collection using $.fn.add()
+ if ($.fn.jquery.substr(0, 3) === '1.7') {
+ var $jqNodes = $();
+
+ $.map($nodes, function (node) {
+ $jqNodes = $jqNodes.add(node);
+ });
+
+ $nodes = $jqNodes;
+ }
+
+ $element.append($nodes);
+ };
+
+ // Cache objects in Utils.__cache instead of $.data (see #4346)
+ Utils.__cache = {};
+
+ var id = 0;
+ Utils.GetUniqueElementId = function (element) {
+ // Get a unique element Id. If element has no id,
+ // creates a new unique number, stores it in the id
+ // attribute and returns the new id.
+ // If an id already exists, it simply returns it.
+
+ var select2Id = element.getAttribute('data-select2-id');
+ if (select2Id == null) {
+ // If element has id, use it.
+ if (element.id) {
+ select2Id = element.id;
+ element.setAttribute('data-select2-id', select2Id);
+ } else {
+ element.setAttribute('data-select2-id', ++id);
+ select2Id = id.toString();
+ }
+ }
+ return select2Id;
+ };
+
+ Utils.StoreData = function (element, name, value) {
+ // Stores an item in the cache for a specified element.
+ // name is the cache key.
+ var id = Utils.GetUniqueElementId(element);
+ if (!Utils.__cache[id]) {
+ Utils.__cache[id] = {};
+ }
+
+ Utils.__cache[id][name] = value;
+ };
+
+ Utils.GetData = function (element, name) {
+ // Retrieves a value from the cache by its key (name)
+ // name is optional. If no name specified, return
+ // all cache items for the specified element.
+ // and for a specified element.
+ var id = Utils.GetUniqueElementId(element);
+ if (name) {
+ if (Utils.__cache[id]) {
+ return Utils.__cache[id][name] != null ?
+ Utils.__cache[id][name]:
+ $(element).data(name); // Fallback to HTML5 data attribs.
+ }
+ return $(element).data(name); // Fallback to HTML5 data attribs.
+ } else {
+ return Utils.__cache[id];
+ }
+ };
+
+ Utils.RemoveData = function (element) {
+ // Removes all cached items for a specified element.
+ var id = Utils.GetUniqueElementId(element);
+ if (Utils.__cache[id] != null) {
+ delete Utils.__cache[id];
+ }
+ };
+
+ return Utils;
+});
+
+S2.define('select2/results',[
+ 'jquery',
+ './utils'
+], function ($, Utils) {
+ function Results ($element, options, dataAdapter) {
+ this.$element = $element;
+ this.data = dataAdapter;
+ this.options = options;
+
+ Results.__super__.constructor.call(this);
+ }
+
+ Utils.Extend(Results, Utils.Observable);
+
+ Results.prototype.render = function () {
+ var $results = $(
+ ''
+ );
+
+ if (this.options.get('multiple')) {
+ $results.attr('aria-multiselectable', 'true');
+ }
+
+ this.$results = $results;
+
+ return $results;
+ };
+
+ Results.prototype.clear = function () {
+ this.$results.empty();
+ };
+
+ Results.prototype.displayMessage = function (params) {
+ var escapeMarkup = this.options.get('escapeMarkup');
+
+ this.clear();
+ this.hideLoading();
+
+ var $message = $(
+ ' '
+ );
+
+ var message = this.options.get('translations').get(params.message);
+
+ $message.append(
+ escapeMarkup(
+ message(params.args)
+ )
+ );
+
+ $message[0].className += ' select2-results__message';
+
+ this.$results.append($message);
+ };
+
+ Results.prototype.hideMessages = function () {
+ this.$results.find('.select2-results__message').remove();
+ };
+
+ Results.prototype.append = function (data) {
+ this.hideLoading();
+
+ var $options = [];
+
+ if (data.results == null || data.results.length === 0) {
+ if (this.$results.children().length === 0) {
+ this.trigger('results:message', {
+ message: 'noResults'
+ });
+ }
+
+ return;
+ }
+
+ data.results = this.sort(data.results);
+
+ for (var d = 0; d < data.results.length; d++) {
+ var item = data.results[d];
+
+ var $option = this.option(item);
+
+ $options.push($option);
+ }
+
+ this.$results.append($options);
+ };
+
+ Results.prototype.position = function ($results, $dropdown) {
+ var $resultsContainer = $dropdown.find('.select2-results');
+ $resultsContainer.append($results);
+ };
+
+ Results.prototype.sort = function (data) {
+ var sorter = this.options.get('sorter');
+
+ return sorter(data);
+ };
+
+ Results.prototype.highlightFirstItem = function () {
+ var $options = this.$results
+ .find('.select2-results__option[aria-selected]');
+
+ var $selected = $options.filter('[aria-selected=true]');
+
+ // Check if there are any selected options
+ if ($selected.length > 0) {
+ // If there are selected options, highlight the first
+ $selected.first().trigger('mouseenter');
+ } else {
+ // If there are no selected options, highlight the first option
+ // in the dropdown
+ $options.first().trigger('mouseenter');
+ }
+
+ this.ensureHighlightVisible();
+ };
+
+ Results.prototype.setClasses = function () {
+ var self = this;
+
+ this.data.current(function (selected) {
+ var selectedIds = $.map(selected, function (s) {
+ return s.id.toString();
+ });
+
+ var $options = self.$results
+ .find('.select2-results__option[aria-selected]');
+
+ $options.each(function () {
+ var $option = $(this);
+
+ var item = Utils.GetData(this, 'data');
+
+ // id needs to be converted to a string when comparing
+ var id = '' + item.id;
+
+ if ((item.element != null && item.element.selected) ||
+ (item.element == null && $.inArray(id, selectedIds) > -1)) {
+ $option.attr('aria-selected', 'true');
+ } else {
+ $option.attr('aria-selected', 'false');
+ }
+ });
+
+ });
+ };
+
+ Results.prototype.showLoading = function (params) {
+ this.hideLoading();
+
+ var loadingMore = this.options.get('translations').get('searching');
+
+ var loading = {
+ disabled: true,
+ loading: true,
+ text: loadingMore(params)
+ };
+ var $loading = this.option(loading);
+ $loading.className += ' loading-results';
+
+ this.$results.prepend($loading);
+ };
+
+ Results.prototype.hideLoading = function () {
+ this.$results.find('.loading-results').remove();
+ };
+
+ Results.prototype.option = function (data) {
+ var option = document.createElement('li');
+ option.className = 'select2-results__option';
+
+ var attrs = {
+ 'role': 'treeitem',
+ 'aria-selected': 'false'
+ };
+
+ if (data.disabled) {
+ delete attrs['aria-selected'];
+ attrs['aria-disabled'] = 'true';
+ }
+
+ if (data.id == null) {
+ delete attrs['aria-selected'];
+ }
+
+ if (data._resultId != null) {
+ option.id = data._resultId;
+ }
+
+ if (data.title) {
+ option.title = data.title;
+ }
+
+ if (data.children) {
+ attrs.role = 'group';
+ attrs['aria-label'] = data.text;
+ delete attrs['aria-selected'];
+ }
+
+ for (var attr in attrs) {
+ var val = attrs[attr];
+
+ option.setAttribute(attr, val);
+ }
+
+ if (data.children) {
+ var $option = $(option);
+
+ var label = document.createElement('strong');
+ label.className = 'select2-results__group';
+
+ var $label = $(label);
+ this.template(data, label);
+
+ var $children = [];
+
+ for (var c = 0; c < data.children.length; c++) {
+ var child = data.children[c];
+
+ var $child = this.option(child);
+
+ $children.push($child);
+ }
+
+ var $childrenContainer = $('', {
+ 'class': 'select2-results__options select2-results__options--nested'
+ });
+
+ $childrenContainer.append($children);
+
+ $option.append(label);
+ $option.append($childrenContainer);
+ } else {
+ this.template(data, option);
+ }
+
+ Utils.StoreData(option, 'data', data);
+
+ return option;
+ };
+
+ Results.prototype.bind = function (container, $container) {
+ var self = this;
+
+ var id = container.id + '-results';
+
+ this.$results.attr('id', id);
+
+ container.on('results:all', function (params) {
+ self.clear();
+ self.append(params.data);
+
+ if (container.isOpen()) {
+ self.setClasses();
+ self.highlightFirstItem();
+ }
+ });
+
+ container.on('results:append', function (params) {
+ self.append(params.data);
+
+ if (container.isOpen()) {
+ self.setClasses();
+ }
+ });
+
+ container.on('query', function (params) {
+ self.hideMessages();
+ self.showLoading(params);
+ });
+
+ container.on('select', function () {
+ if (!container.isOpen()) {
+ return;
+ }
+
+ self.setClasses();
+ self.highlightFirstItem();
+ });
+
+ container.on('unselect', function () {
+ if (!container.isOpen()) {
+ return;
+ }
+
+ self.setClasses();
+ self.highlightFirstItem();
+ });
+
+ container.on('open', function () {
+ // When the dropdown is open, aria-expended="true"
+ self.$results.attr('aria-expanded', 'true');
+ self.$results.attr('aria-hidden', 'false');
+
+ self.setClasses();
+ self.ensureHighlightVisible();
+ });
+
+ container.on('close', function () {
+ // When the dropdown is closed, aria-expended="false"
+ self.$results.attr('aria-expanded', 'false');
+ self.$results.attr('aria-hidden', 'true');
+ self.$results.removeAttr('aria-activedescendant');
+ });
+
+ container.on('results:toggle', function () {
+ var $highlighted = self.getHighlightedResults();
+
+ if ($highlighted.length === 0) {
+ return;
+ }
+
+ $highlighted.trigger('mouseup');
+ });
+
+ container.on('results:select', function () {
+ var $highlighted = self.getHighlightedResults();
+
+ if ($highlighted.length === 0) {
+ return;
+ }
+
+ var data = Utils.GetData($highlighted[0], 'data');
+
+ if ($highlighted.attr('aria-selected') == 'true') {
+ self.trigger('close', {});
+ } else {
+ self.trigger('select', {
+ data: data
+ });
+ }
+ });
+
+ container.on('results:previous', function () {
+ var $highlighted = self.getHighlightedResults();
+
+ var $options = self.$results.find('[aria-selected]');
+
+ var currentIndex = $options.index($highlighted);
+
+ // If we are already at te top, don't move further
+ // If no options, currentIndex will be -1
+ if (currentIndex <= 0) {
+ return;
+ }
+
+ var nextIndex = currentIndex - 1;
+
+ // If none are highlighted, highlight the first
+ if ($highlighted.length === 0) {
+ nextIndex = 0;
+ }
+
+ var $next = $options.eq(nextIndex);
+
+ $next.trigger('mouseenter');
+
+ var currentOffset = self.$results.offset().top;
+ var nextTop = $next.offset().top;
+ var nextOffset = self.$results.scrollTop() + (nextTop - currentOffset);
+
+ if (nextIndex === 0) {
+ self.$results.scrollTop(0);
+ } else if (nextTop - currentOffset < 0) {
+ self.$results.scrollTop(nextOffset);
+ }
+ });
+
+ container.on('results:next', function () {
+ var $highlighted = self.getHighlightedResults();
+
+ var $options = self.$results.find('[aria-selected]');
+
+ var currentIndex = $options.index($highlighted);
+
+ var nextIndex = currentIndex + 1;
+
+ // If we are at the last option, stay there
+ if (nextIndex >= $options.length) {
+ return;
+ }
+
+ var $next = $options.eq(nextIndex);
+
+ $next.trigger('mouseenter');
+
+ var currentOffset = self.$results.offset().top +
+ self.$results.outerHeight(false);
+ var nextBottom = $next.offset().top + $next.outerHeight(false);
+ var nextOffset = self.$results.scrollTop() + nextBottom - currentOffset;
+
+ if (nextIndex === 0) {
+ self.$results.scrollTop(0);
+ } else if (nextBottom > currentOffset) {
+ self.$results.scrollTop(nextOffset);
+ }
+ });
+
+ container.on('results:focus', function (params) {
+ params.element.addClass('select2-results__option--highlighted');
+ });
+
+ container.on('results:message', function (params) {
+ self.displayMessage(params);
+ });
+
+ if ($.fn.mousewheel) {
+ this.$results.on('mousewheel', function (e) {
+ var top = self.$results.scrollTop();
+
+ var bottom = self.$results.get(0).scrollHeight - top + e.deltaY;
+
+ var isAtTop = e.deltaY > 0 && top - e.deltaY <= 0;
+ var isAtBottom = e.deltaY < 0 && bottom <= self.$results.height();
+
+ if (isAtTop) {
+ self.$results.scrollTop(0);
+
+ e.preventDefault();
+ e.stopPropagation();
+ } else if (isAtBottom) {
+ self.$results.scrollTop(
+ self.$results.get(0).scrollHeight - self.$results.height()
+ );
+
+ e.preventDefault();
+ e.stopPropagation();
+ }
+ });
+ }
+
+ this.$results.on('mouseup', '.select2-results__option[aria-selected]',
+ function (evt) {
+ var $this = $(this);
+
+ var data = Utils.GetData(this, 'data');
+
+ if ($this.attr('aria-selected') === 'true') {
+ if (self.options.get('multiple')) {
+ self.trigger('unselect', {
+ originalEvent: evt,
+ data: data
+ });
+ } else {
+ self.trigger('close', {});
+ }
+
+ return;
+ }
+
+ self.trigger('select', {
+ originalEvent: evt,
+ data: data
+ });
+ });
+
+ this.$results.on('mouseenter', '.select2-results__option[aria-selected]',
+ function (evt) {
+ var data = Utils.GetData(this, 'data');
+
+ self.getHighlightedResults()
+ .removeClass('select2-results__option--highlighted');
+
+ self.trigger('results:focus', {
+ data: data,
+ element: $(this)
+ });
+ });
+ };
+
+ Results.prototype.getHighlightedResults = function () {
+ var $highlighted = this.$results
+ .find('.select2-results__option--highlighted');
+
+ return $highlighted;
+ };
+
+ Results.prototype.destroy = function () {
+ this.$results.remove();
+ };
+
+ Results.prototype.ensureHighlightVisible = function () {
+ var $highlighted = this.getHighlightedResults();
+
+ if ($highlighted.length === 0) {
+ return;
+ }
+
+ var $options = this.$results.find('[aria-selected]');
+
+ var currentIndex = $options.index($highlighted);
+
+ var currentOffset = this.$results.offset().top;
+ var nextTop = $highlighted.offset().top;
+ var nextOffset = this.$results.scrollTop() + (nextTop - currentOffset);
+
+ var offsetDelta = nextTop - currentOffset;
+ nextOffset -= $highlighted.outerHeight(false) * 2;
+
+ if (currentIndex <= 2) {
+ this.$results.scrollTop(0);
+ } else if (offsetDelta > this.$results.outerHeight() || offsetDelta < 0) {
+ this.$results.scrollTop(nextOffset);
+ }
+ };
+
+ Results.prototype.template = function (result, container) {
+ var template = this.options.get('templateResult');
+ var escapeMarkup = this.options.get('escapeMarkup');
+
+ var content = template(result, container);
+
+ if (content == null) {
+ container.style.display = 'none';
+ } else if (typeof content === 'string') {
+ container.innerHTML = escapeMarkup(content);
+ } else {
+ $(container).append(content);
+ }
+ };
+
+ return Results;
+});
+
+S2.define('select2/keys',[
+
+], function () {
+ var KEYS = {
+ BACKSPACE: 8,
+ TAB: 9,
+ ENTER: 13,
+ SHIFT: 16,
+ CTRL: 17,
+ ALT: 18,
+ ESC: 27,
+ SPACE: 32,
+ PAGE_UP: 33,
+ PAGE_DOWN: 34,
+ END: 35,
+ HOME: 36,
+ LEFT: 37,
+ UP: 38,
+ RIGHT: 39,
+ DOWN: 40,
+ DELETE: 46
+ };
+
+ return KEYS;
+});
+
+S2.define('select2/selection/base',[
+ 'jquery',
+ '../utils',
+ '../keys'
+], function ($, Utils, KEYS) {
+ function BaseSelection ($element, options) {
+ this.$element = $element;
+ this.options = options;
+
+ BaseSelection.__super__.constructor.call(this);
+ }
+
+ Utils.Extend(BaseSelection, Utils.Observable);
+
+ BaseSelection.prototype.render = function () {
+ var $selection = $(
+ '' +
+ ' '
+ );
+
+ this._tabindex = 0;
+
+ if (Utils.GetData(this.$element[0], 'old-tabindex') != null) {
+ this._tabindex = Utils.GetData(this.$element[0], 'old-tabindex');
+ } else if (this.$element.attr('tabindex') != null) {
+ this._tabindex = this.$element.attr('tabindex');
+ }
+
+ $selection.attr('title', this.$element.attr('title'));
+ $selection.attr('tabindex', this._tabindex);
+
+ this.$selection = $selection;
+
+ return $selection;
+ };
+
+ BaseSelection.prototype.bind = function (container, $container) {
+ var self = this;
+
+ var id = container.id + '-container';
+ var resultsId = container.id + '-results';
+
+ this.container = container;
+
+ this.$selection.on('focus', function (evt) {
+ self.trigger('focus', evt);
+ });
+
+ this.$selection.on('blur', function (evt) {
+ self._handleBlur(evt);
+ });
+
+ this.$selection.on('keydown', function (evt) {
+ self.trigger('keypress', evt);
+
+ if (evt.which === KEYS.SPACE) {
+ evt.preventDefault();
+ }
+ });
+
+ container.on('results:focus', function (params) {
+ self.$selection.attr('aria-activedescendant', params.data._resultId);
+ });
+
+ container.on('selection:update', function (params) {
+ self.update(params.data);
+ });
+
+ container.on('open', function () {
+ // When the dropdown is open, aria-expanded="true"
+ self.$selection.attr('aria-expanded', 'true');
+ self.$selection.attr('aria-owns', resultsId);
+
+ self._attachCloseHandler(container);
+ });
+
+ container.on('close', function () {
+ // When the dropdown is closed, aria-expanded="false"
+ self.$selection.attr('aria-expanded', 'false');
+ self.$selection.removeAttr('aria-activedescendant');
+ self.$selection.removeAttr('aria-owns');
+
+ self.$selection.focus();
+ window.setTimeout(function () {
+ self.$selection.focus();
+ }, 0);
+
+ self._detachCloseHandler(container);
+ });
+
+ container.on('enable', function () {
+ self.$selection.attr('tabindex', self._tabindex);
+ });
+
+ container.on('disable', function () {
+ self.$selection.attr('tabindex', '-1');
+ });
+ };
+
+ BaseSelection.prototype._handleBlur = function (evt) {
+ var self = this;
+
+ // This needs to be delayed as the active element is the body when the tab
+ // key is pressed, possibly along with others.
+ window.setTimeout(function () {
+ // Don't trigger `blur` if the focus is still in the selection
+ if (
+ (document.activeElement == self.$selection[0]) ||
+ ($.contains(self.$selection[0], document.activeElement))
+ ) {
+ return;
+ }
+
+ self.trigger('blur', evt);
+ }, 1);
+ };
+
+ BaseSelection.prototype._attachCloseHandler = function (container) {
+ var self = this;
+
+ $(document.body).on('mousedown.select2.' + container.id, function (e) {
+ var $target = $(e.target);
+
+ var $select = $target.closest('.select2');
+
+ var $all = $('.select2.select2-container--open');
+
+ $all.each(function () {
+ var $this = $(this);
+
+ if (this == $select[0]) {
+ return;
+ }
+
+ var $element = Utils.GetData(this, 'element');
+
+ $element.select2('close');
+ });
+ });
+ };
+
+ BaseSelection.prototype._detachCloseHandler = function (container) {
+ $(document.body).off('mousedown.select2.' + container.id);
+ };
+
+ BaseSelection.prototype.position = function ($selection, $container) {
+ var $selectionContainer = $container.find('.selection');
+ $selectionContainer.append($selection);
+ };
+
+ BaseSelection.prototype.destroy = function () {
+ this._detachCloseHandler(this.container);
+ };
+
+ BaseSelection.prototype.update = function (data) {
+ throw new Error('The `update` method must be defined in child classes.');
+ };
+
+ return BaseSelection;
+});
+
+S2.define('select2/selection/single',[
+ 'jquery',
+ './base',
+ '../utils',
+ '../keys'
+], function ($, BaseSelection, Utils, KEYS) {
+ function SingleSelection () {
+ SingleSelection.__super__.constructor.apply(this, arguments);
+ }
+
+ Utils.Extend(SingleSelection, BaseSelection);
+
+ SingleSelection.prototype.render = function () {
+ var $selection = SingleSelection.__super__.render.call(this);
+
+ $selection.addClass('select2-selection--single');
+
+ $selection.html(
+ ' ' +
+ '' +
+ ' ' +
+ ' '
+ );
+
+ return $selection;
+ };
+
+ SingleSelection.prototype.bind = function (container, $container) {
+ var self = this;
+
+ SingleSelection.__super__.bind.apply(this, arguments);
+
+ var id = container.id + '-container';
+
+ this.$selection.find('.select2-selection__rendered')
+ .attr('id', id)
+ .attr('role', 'textbox')
+ .attr('aria-readonly', 'true');
+ this.$selection.attr('aria-labelledby', id);
+
+ this.$selection.on('mousedown', function (evt) {
+ // Only respond to left clicks
+ if (evt.which !== 1) {
+ return;
+ }
+
+ self.trigger('toggle', {
+ originalEvent: evt
+ });
+ });
+
+ this.$selection.on('focus', function (evt) {
+ // User focuses on the container
+ });
+
+ this.$selection.on('blur', function (evt) {
+ // User exits the container
+ });
+
+ container.on('focus', function (evt) {
+ if (!container.isOpen()) {
+ self.$selection.focus();
+ }
+ });
+ };
+
+ SingleSelection.prototype.clear = function () {
+ var $rendered = this.$selection.find('.select2-selection__rendered');
+ $rendered.empty();
+ $rendered.removeAttr('title'); // clear tooltip on empty
+ };
+
+ SingleSelection.prototype.display = function (data, container) {
+ var template = this.options.get('templateSelection');
+ var escapeMarkup = this.options.get('escapeMarkup');
+
+ return escapeMarkup(template(data, container));
+ };
+
+ SingleSelection.prototype.selectionContainer = function () {
+ return $(' ');
+ };
+
+ SingleSelection.prototype.update = function (data) {
+ if (data.length === 0) {
+ this.clear();
+ return;
+ }
+
+ var selection = data[0];
+
+ var $rendered = this.$selection.find('.select2-selection__rendered');
+ var formatted = this.display(selection, $rendered);
+
+ $rendered.empty().append(formatted);
+ $rendered.attr('title', selection.title || selection.text);
+ };
+
+ return SingleSelection;
+});
+
+S2.define('select2/selection/multiple',[
+ 'jquery',
+ './base',
+ '../utils'
+], function ($, BaseSelection, Utils) {
+ function MultipleSelection ($element, options) {
+ MultipleSelection.__super__.constructor.apply(this, arguments);
+ }
+
+ Utils.Extend(MultipleSelection, BaseSelection);
+
+ MultipleSelection.prototype.render = function () {
+ var $selection = MultipleSelection.__super__.render.call(this);
+
+ $selection.addClass('select2-selection--multiple');
+
+ $selection.html(
+ ''
+ );
+
+ return $selection;
+ };
+
+ MultipleSelection.prototype.bind = function (container, $container) {
+ var self = this;
+
+ MultipleSelection.__super__.bind.apply(this, arguments);
+
+ this.$selection.on('click', function (evt) {
+ self.trigger('toggle', {
+ originalEvent: evt
+ });
+ });
+
+ this.$selection.on(
+ 'click',
+ '.select2-selection__choice__remove',
+ function (evt) {
+ // Ignore the event if it is disabled
+ if (self.options.get('disabled')) {
+ return;
+ }
+
+ var $remove = $(this);
+ var $selection = $remove.parent();
+
+ var data = Utils.GetData($selection[0], 'data');
+
+ self.trigger('unselect', {
+ originalEvent: evt,
+ data: data
+ });
+ }
+ );
+ };
+
+ MultipleSelection.prototype.clear = function () {
+ var $rendered = this.$selection.find('.select2-selection__rendered');
+ $rendered.empty();
+ $rendered.removeAttr('title');
+ };
+
+ MultipleSelection.prototype.display = function (data, container) {
+ var template = this.options.get('templateSelection');
+ var escapeMarkup = this.options.get('escapeMarkup');
+
+ return escapeMarkup(template(data, container));
+ };
+
+ MultipleSelection.prototype.selectionContainer = function () {
+ var $container = $(
+ '' +
+ '' +
+ '×' +
+ ' ' +
+ ' '
+ );
+
+ return $container;
+ };
+
+ MultipleSelection.prototype.update = function (data) {
+ this.clear();
+
+ if (data.length === 0) {
+ return;
+ }
+
+ var $selections = [];
+
+ for (var d = 0; d < data.length; d++) {
+ var selection = data[d];
+
+ var $selection = this.selectionContainer();
+ var formatted = this.display(selection, $selection);
+
+ $selection.append(formatted);
+ $selection.attr('title', selection.title || selection.text);
+
+ Utils.StoreData($selection[0], 'data', selection);
+
+ $selections.push($selection);
+ }
+
+ var $rendered = this.$selection.find('.select2-selection__rendered');
+
+ Utils.appendMany($rendered, $selections);
+ };
+
+ return MultipleSelection;
+});
+
+S2.define('select2/selection/placeholder',[
+ '../utils'
+], function (Utils) {
+ function Placeholder (decorated, $element, options) {
+ this.placeholder = this.normalizePlaceholder(options.get('placeholder'));
+
+ decorated.call(this, $element, options);
+ }
+
+ Placeholder.prototype.normalizePlaceholder = function (_, placeholder) {
+ if (typeof placeholder === 'string') {
+ placeholder = {
+ id: '',
+ text: placeholder
+ };
+ }
+
+ return placeholder;
+ };
+
+ Placeholder.prototype.createPlaceholder = function (decorated, placeholder) {
+ var $placeholder = this.selectionContainer();
+
+ $placeholder.html(this.display(placeholder));
+ $placeholder.addClass('select2-selection__placeholder')
+ .removeClass('select2-selection__choice');
+
+ return $placeholder;
+ };
+
+ Placeholder.prototype.update = function (decorated, data) {
+ var singlePlaceholder = (
+ data.length == 1 && data[0].id != this.placeholder.id
+ );
+ var multipleSelections = data.length > 1;
+
+ if (multipleSelections || singlePlaceholder) {
+ return decorated.call(this, data);
+ }
+
+ this.clear();
+
+ var $placeholder = this.createPlaceholder(this.placeholder);
+
+ this.$selection.find('.select2-selection__rendered').append($placeholder);
+ };
+
+ return Placeholder;
+});
+
+S2.define('select2/selection/allowClear',[
+ 'jquery',
+ '../keys',
+ '../utils'
+], function ($, KEYS, Utils) {
+ function AllowClear () { }
+
+ AllowClear.prototype.bind = function (decorated, container, $container) {
+ var self = this;
+
+ decorated.call(this, container, $container);
+
+ if (this.placeholder == null) {
+ if (this.options.get('debug') && window.console && console.error) {
+ console.error(
+ 'Select2: The `allowClear` option should be used in combination ' +
+ 'with the `placeholder` option.'
+ );
+ }
+ }
+
+ this.$selection.on('mousedown', '.select2-selection__clear',
+ function (evt) {
+ self._handleClear(evt);
+ });
+
+ container.on('keypress', function (evt) {
+ self._handleKeyboardClear(evt, container);
+ });
+ };
+
+ AllowClear.prototype._handleClear = function (_, evt) {
+ // Ignore the event if it is disabled
+ if (this.options.get('disabled')) {
+ return;
+ }
+
+ var $clear = this.$selection.find('.select2-selection__clear');
+
+ // Ignore the event if nothing has been selected
+ if ($clear.length === 0) {
+ return;
+ }
+
+ evt.stopPropagation();
+
+ var data = Utils.GetData($clear[0], 'data');
+
+ var previousVal = this.$element.val();
+ this.$element.val(this.placeholder.id);
+
+ var unselectData = {
+ data: data
+ };
+ this.trigger('clear', unselectData);
+ if (unselectData.prevented) {
+ this.$element.val(previousVal);
+ return;
+ }
+
+ for (var d = 0; d < data.length; d++) {
+ unselectData = {
+ data: data[d]
+ };
+
+ // Trigger the `unselect` event, so people can prevent it from being
+ // cleared.
+ this.trigger('unselect', unselectData);
+
+ // If the event was prevented, don't clear it out.
+ if (unselectData.prevented) {
+ this.$element.val(previousVal);
+ return;
+ }
+ }
+
+ this.$element.trigger('change');
+
+ this.trigger('toggle', {});
+ };
+
+ AllowClear.prototype._handleKeyboardClear = function (_, evt, container) {
+ if (container.isOpen()) {
+ return;
+ }
+
+ if (evt.which == KEYS.DELETE || evt.which == KEYS.BACKSPACE) {
+ this._handleClear(evt);
+ }
+ };
+
+ AllowClear.prototype.update = function (decorated, data) {
+ decorated.call(this, data);
+
+ if (this.$selection.find('.select2-selection__placeholder').length > 0 ||
+ data.length === 0) {
+ return;
+ }
+
+ var $remove = $(
+ '' +
+ '×' +
+ ' '
+ );
+ Utils.StoreData($remove[0], 'data', data);
+
+ this.$selection.find('.select2-selection__rendered').prepend($remove);
+ };
+
+ return AllowClear;
+});
+
+S2.define('select2/selection/search',[
+ 'jquery',
+ '../utils',
+ '../keys'
+], function ($, Utils, KEYS) {
+ function Search (decorated, $element, options) {
+ decorated.call(this, $element, options);
+ }
+
+ Search.prototype.render = function (decorated) {
+ var $search = $(
+ '' +
+ ' ' +
+ ' '
+ );
+
+ this.$searchContainer = $search;
+ this.$search = $search.find('input');
+
+ var $rendered = decorated.call(this);
+
+ this._transferTabIndex();
+
+ return $rendered;
+ };
+
+ Search.prototype.bind = function (decorated, container, $container) {
+ var self = this;
+
+ decorated.call(this, container, $container);
+
+ container.on('open', function () {
+ self.$search.trigger('focus');
+ });
+
+ container.on('close', function () {
+ self.$search.val('');
+ self.$search.removeAttr('aria-activedescendant');
+ self.$search.trigger('focus');
+ });
+
+ container.on('enable', function () {
+ self.$search.prop('disabled', false);
+
+ self._transferTabIndex();
+ });
+
+ container.on('disable', function () {
+ self.$search.prop('disabled', true);
+ });
+
+ container.on('focus', function (evt) {
+ self.$search.trigger('focus');
+ });
+
+ container.on('results:focus', function (params) {
+ self.$search.attr('aria-activedescendant', params.id);
+ });
+
+ this.$selection.on('focusin', '.select2-search--inline', function (evt) {
+ self.trigger('focus', evt);
+ });
+
+ this.$selection.on('focusout', '.select2-search--inline', function (evt) {
+ self._handleBlur(evt);
+ });
+
+ this.$selection.on('keydown', '.select2-search--inline', function (evt) {
+ evt.stopPropagation();
+
+ self.trigger('keypress', evt);
+
+ self._keyUpPrevented = evt.isDefaultPrevented();
+
+ var key = evt.which;
+
+ if (key === KEYS.BACKSPACE && self.$search.val() === '') {
+ var $previousChoice = self.$searchContainer
+ .prev('.select2-selection__choice');
+
+ if ($previousChoice.length > 0) {
+ var item = Utils.GetData($previousChoice[0], 'data');
+
+ self.searchRemoveChoice(item);
+
+ evt.preventDefault();
+ }
+ }
+ });
+
+ // Try to detect the IE version should the `documentMode` property that
+ // is stored on the document. This is only implemented in IE and is
+ // slightly cleaner than doing a user agent check.
+ // This property is not available in Edge, but Edge also doesn't have
+ // this bug.
+ var msie = document.documentMode;
+ var disableInputEvents = msie && msie <= 11;
+
+ // Workaround for browsers which do not support the `input` event
+ // This will prevent double-triggering of events for browsers which support
+ // both the `keyup` and `input` events.
+ this.$selection.on(
+ 'input.searchcheck',
+ '.select2-search--inline',
+ function (evt) {
+ // IE will trigger the `input` event when a placeholder is used on a
+ // search box. To get around this issue, we are forced to ignore all
+ // `input` events in IE and keep using `keyup`.
+ if (disableInputEvents) {
+ self.$selection.off('input.search input.searchcheck');
+ return;
+ }
+
+ // Unbind the duplicated `keyup` event
+ self.$selection.off('keyup.search');
+ }
+ );
+
+ this.$selection.on(
+ 'keyup.search input.search',
+ '.select2-search--inline',
+ function (evt) {
+ // IE will trigger the `input` event when a placeholder is used on a
+ // search box. To get around this issue, we are forced to ignore all
+ // `input` events in IE and keep using `keyup`.
+ if (disableInputEvents && evt.type === 'input') {
+ self.$selection.off('input.search input.searchcheck');
+ return;
+ }
+
+ var key = evt.which;
+
+ // We can freely ignore events from modifier keys
+ if (key == KEYS.SHIFT || key == KEYS.CTRL || key == KEYS.ALT) {
+ return;
+ }
+
+ // Tabbing will be handled during the `keydown` phase
+ if (key == KEYS.TAB) {
+ return;
+ }
+
+ self.handleSearch(evt);
+ }
+ );
+ };
+
+ /**
+ * This method will transfer the tabindex attribute from the rendered
+ * selection to the search box. This allows for the search box to be used as
+ * the primary focus instead of the selection container.
+ *
+ * @private
+ */
+ Search.prototype._transferTabIndex = function (decorated) {
+ this.$search.attr('tabindex', this.$selection.attr('tabindex'));
+ this.$selection.attr('tabindex', '-1');
+ };
+
+ Search.prototype.createPlaceholder = function (decorated, placeholder) {
+ this.$search.attr('placeholder', placeholder.text);
+ };
+
+ Search.prototype.update = function (decorated, data) {
+ var searchHadFocus = this.$search[0] == document.activeElement;
+
+ this.$search.attr('placeholder', '');
+
+ decorated.call(this, data);
+
+ this.$selection.find('.select2-selection__rendered')
+ .append(this.$searchContainer);
+
+ this.resizeSearch();
+ if (searchHadFocus) {
+ var isTagInput = this.$element.find('[data-select2-tag]').length;
+ if (isTagInput) {
+ // fix IE11 bug where tag input lost focus
+ this.$element.focus();
+ } else {
+ this.$search.focus();
+ }
+ }
+ };
+
+ Search.prototype.handleSearch = function () {
+ this.resizeSearch();
+
+ if (!this._keyUpPrevented) {
+ var input = this.$search.val();
+
+ this.trigger('query', {
+ term: input
+ });
+ }
+
+ this._keyUpPrevented = false;
+ };
+
+ Search.prototype.searchRemoveChoice = function (decorated, item) {
+ this.trigger('unselect', {
+ data: item
+ });
+
+ this.$search.val(item.text);
+ this.handleSearch();
+ };
+
+ Search.prototype.resizeSearch = function () {
+ this.$search.css('width', '25px');
+
+ var width = '';
+
+ if (this.$search.attr('placeholder') !== '') {
+ width = this.$selection.find('.select2-selection__rendered').innerWidth();
+ } else {
+ var minimumWidth = this.$search.val().length + 1;
+
+ width = (minimumWidth * 0.75) + 'em';
+ }
+
+ this.$search.css('width', width);
+ };
+
+ return Search;
+});
+
+S2.define('select2/selection/eventRelay',[
+ 'jquery'
+], function ($) {
+ function EventRelay () { }
+
+ EventRelay.prototype.bind = function (decorated, container, $container) {
+ var self = this;
+ var relayEvents = [
+ 'open', 'opening',
+ 'close', 'closing',
+ 'select', 'selecting',
+ 'unselect', 'unselecting',
+ 'clear', 'clearing'
+ ];
+
+ var preventableEvents = [
+ 'opening', 'closing', 'selecting', 'unselecting', 'clearing'
+ ];
+
+ decorated.call(this, container, $container);
+
+ container.on('*', function (name, params) {
+ // Ignore events that should not be relayed
+ if ($.inArray(name, relayEvents) === -1) {
+ return;
+ }
+
+ // The parameters should always be an object
+ params = params || {};
+
+ // Generate the jQuery event for the Select2 event
+ var evt = $.Event('select2:' + name, {
+ params: params
+ });
+
+ self.$element.trigger(evt);
+
+ // Only handle preventable events if it was one
+ if ($.inArray(name, preventableEvents) === -1) {
+ return;
+ }
+
+ params.prevented = evt.isDefaultPrevented();
+ });
+ };
+
+ return EventRelay;
+});
+
+S2.define('select2/translation',[
+ 'jquery',
+ 'require'
+], function ($, require) {
+ function Translation (dict) {
+ this.dict = dict || {};
+ }
+
+ Translation.prototype.all = function () {
+ return this.dict;
+ };
+
+ Translation.prototype.get = function (key) {
+ return this.dict[key];
+ };
+
+ Translation.prototype.extend = function (translation) {
+ this.dict = $.extend({}, translation.all(), this.dict);
+ };
+
+ // Static functions
+
+ Translation._cache = {};
+
+ Translation.loadPath = function (path) {
+ if (!(path in Translation._cache)) {
+ var translations = require(path);
+
+ Translation._cache[path] = translations;
+ }
+
+ return new Translation(Translation._cache[path]);
+ };
+
+ return Translation;
+});
+
+S2.define('select2/diacritics',[
+
+], function () {
+ var diacritics = {
+ '\u24B6': 'A',
+ '\uFF21': 'A',
+ '\u00C0': 'A',
+ '\u00C1': 'A',
+ '\u00C2': 'A',
+ '\u1EA6': 'A',
+ '\u1EA4': 'A',
+ '\u1EAA': 'A',
+ '\u1EA8': 'A',
+ '\u00C3': 'A',
+ '\u0100': 'A',
+ '\u0102': 'A',
+ '\u1EB0': 'A',
+ '\u1EAE': 'A',
+ '\u1EB4': 'A',
+ '\u1EB2': 'A',
+ '\u0226': 'A',
+ '\u01E0': 'A',
+ '\u00C4': 'A',
+ '\u01DE': 'A',
+ '\u1EA2': 'A',
+ '\u00C5': 'A',
+ '\u01FA': 'A',
+ '\u01CD': 'A',
+ '\u0200': 'A',
+ '\u0202': 'A',
+ '\u1EA0': 'A',
+ '\u1EAC': 'A',
+ '\u1EB6': 'A',
+ '\u1E00': 'A',
+ '\u0104': 'A',
+ '\u023A': 'A',
+ '\u2C6F': 'A',
+ '\uA732': 'AA',
+ '\u00C6': 'AE',
+ '\u01FC': 'AE',
+ '\u01E2': 'AE',
+ '\uA734': 'AO',
+ '\uA736': 'AU',
+ '\uA738': 'AV',
+ '\uA73A': 'AV',
+ '\uA73C': 'AY',
+ '\u24B7': 'B',
+ '\uFF22': 'B',
+ '\u1E02': 'B',
+ '\u1E04': 'B',
+ '\u1E06': 'B',
+ '\u0243': 'B',
+ '\u0182': 'B',
+ '\u0181': 'B',
+ '\u24B8': 'C',
+ '\uFF23': 'C',
+ '\u0106': 'C',
+ '\u0108': 'C',
+ '\u010A': 'C',
+ '\u010C': 'C',
+ '\u00C7': 'C',
+ '\u1E08': 'C',
+ '\u0187': 'C',
+ '\u023B': 'C',
+ '\uA73E': 'C',
+ '\u24B9': 'D',
+ '\uFF24': 'D',
+ '\u1E0A': 'D',
+ '\u010E': 'D',
+ '\u1E0C': 'D',
+ '\u1E10': 'D',
+ '\u1E12': 'D',
+ '\u1E0E': 'D',
+ '\u0110': 'D',
+ '\u018B': 'D',
+ '\u018A': 'D',
+ '\u0189': 'D',
+ '\uA779': 'D',
+ '\u01F1': 'DZ',
+ '\u01C4': 'DZ',
+ '\u01F2': 'Dz',
+ '\u01C5': 'Dz',
+ '\u24BA': 'E',
+ '\uFF25': 'E',
+ '\u00C8': 'E',
+ '\u00C9': 'E',
+ '\u00CA': 'E',
+ '\u1EC0': 'E',
+ '\u1EBE': 'E',
+ '\u1EC4': 'E',
+ '\u1EC2': 'E',
+ '\u1EBC': 'E',
+ '\u0112': 'E',
+ '\u1E14': 'E',
+ '\u1E16': 'E',
+ '\u0114': 'E',
+ '\u0116': 'E',
+ '\u00CB': 'E',
+ '\u1EBA': 'E',
+ '\u011A': 'E',
+ '\u0204': 'E',
+ '\u0206': 'E',
+ '\u1EB8': 'E',
+ '\u1EC6': 'E',
+ '\u0228': 'E',
+ '\u1E1C': 'E',
+ '\u0118': 'E',
+ '\u1E18': 'E',
+ '\u1E1A': 'E',
+ '\u0190': 'E',
+ '\u018E': 'E',
+ '\u24BB': 'F',
+ '\uFF26': 'F',
+ '\u1E1E': 'F',
+ '\u0191': 'F',
+ '\uA77B': 'F',
+ '\u24BC': 'G',
+ '\uFF27': 'G',
+ '\u01F4': 'G',
+ '\u011C': 'G',
+ '\u1E20': 'G',
+ '\u011E': 'G',
+ '\u0120': 'G',
+ '\u01E6': 'G',
+ '\u0122': 'G',
+ '\u01E4': 'G',
+ '\u0193': 'G',
+ '\uA7A0': 'G',
+ '\uA77D': 'G',
+ '\uA77E': 'G',
+ '\u24BD': 'H',
+ '\uFF28': 'H',
+ '\u0124': 'H',
+ '\u1E22': 'H',
+ '\u1E26': 'H',
+ '\u021E': 'H',
+ '\u1E24': 'H',
+ '\u1E28': 'H',
+ '\u1E2A': 'H',
+ '\u0126': 'H',
+ '\u2C67': 'H',
+ '\u2C75': 'H',
+ '\uA78D': 'H',
+ '\u24BE': 'I',
+ '\uFF29': 'I',
+ '\u00CC': 'I',
+ '\u00CD': 'I',
+ '\u00CE': 'I',
+ '\u0128': 'I',
+ '\u012A': 'I',
+ '\u012C': 'I',
+ '\u0130': 'I',
+ '\u00CF': 'I',
+ '\u1E2E': 'I',
+ '\u1EC8': 'I',
+ '\u01CF': 'I',
+ '\u0208': 'I',
+ '\u020A': 'I',
+ '\u1ECA': 'I',
+ '\u012E': 'I',
+ '\u1E2C': 'I',
+ '\u0197': 'I',
+ '\u24BF': 'J',
+ '\uFF2A': 'J',
+ '\u0134': 'J',
+ '\u0248': 'J',
+ '\u24C0': 'K',
+ '\uFF2B': 'K',
+ '\u1E30': 'K',
+ '\u01E8': 'K',
+ '\u1E32': 'K',
+ '\u0136': 'K',
+ '\u1E34': 'K',
+ '\u0198': 'K',
+ '\u2C69': 'K',
+ '\uA740': 'K',
+ '\uA742': 'K',
+ '\uA744': 'K',
+ '\uA7A2': 'K',
+ '\u24C1': 'L',
+ '\uFF2C': 'L',
+ '\u013F': 'L',
+ '\u0139': 'L',
+ '\u013D': 'L',
+ '\u1E36': 'L',
+ '\u1E38': 'L',
+ '\u013B': 'L',
+ '\u1E3C': 'L',
+ '\u1E3A': 'L',
+ '\u0141': 'L',
+ '\u023D': 'L',
+ '\u2C62': 'L',
+ '\u2C60': 'L',
+ '\uA748': 'L',
+ '\uA746': 'L',
+ '\uA780': 'L',
+ '\u01C7': 'LJ',
+ '\u01C8': 'Lj',
+ '\u24C2': 'M',
+ '\uFF2D': 'M',
+ '\u1E3E': 'M',
+ '\u1E40': 'M',
+ '\u1E42': 'M',
+ '\u2C6E': 'M',
+ '\u019C': 'M',
+ '\u24C3': 'N',
+ '\uFF2E': 'N',
+ '\u01F8': 'N',
+ '\u0143': 'N',
+ '\u00D1': 'N',
+ '\u1E44': 'N',
+ '\u0147': 'N',
+ '\u1E46': 'N',
+ '\u0145': 'N',
+ '\u1E4A': 'N',
+ '\u1E48': 'N',
+ '\u0220': 'N',
+ '\u019D': 'N',
+ '\uA790': 'N',
+ '\uA7A4': 'N',
+ '\u01CA': 'NJ',
+ '\u01CB': 'Nj',
+ '\u24C4': 'O',
+ '\uFF2F': 'O',
+ '\u00D2': 'O',
+ '\u00D3': 'O',
+ '\u00D4': 'O',
+ '\u1ED2': 'O',
+ '\u1ED0': 'O',
+ '\u1ED6': 'O',
+ '\u1ED4': 'O',
+ '\u00D5': 'O',
+ '\u1E4C': 'O',
+ '\u022C': 'O',
+ '\u1E4E': 'O',
+ '\u014C': 'O',
+ '\u1E50': 'O',
+ '\u1E52': 'O',
+ '\u014E': 'O',
+ '\u022E': 'O',
+ '\u0230': 'O',
+ '\u00D6': 'O',
+ '\u022A': 'O',
+ '\u1ECE': 'O',
+ '\u0150': 'O',
+ '\u01D1': 'O',
+ '\u020C': 'O',
+ '\u020E': 'O',
+ '\u01A0': 'O',
+ '\u1EDC': 'O',
+ '\u1EDA': 'O',
+ '\u1EE0': 'O',
+ '\u1EDE': 'O',
+ '\u1EE2': 'O',
+ '\u1ECC': 'O',
+ '\u1ED8': 'O',
+ '\u01EA': 'O',
+ '\u01EC': 'O',
+ '\u00D8': 'O',
+ '\u01FE': 'O',
+ '\u0186': 'O',
+ '\u019F': 'O',
+ '\uA74A': 'O',
+ '\uA74C': 'O',
+ '\u01A2': 'OI',
+ '\uA74E': 'OO',
+ '\u0222': 'OU',
+ '\u24C5': 'P',
+ '\uFF30': 'P',
+ '\u1E54': 'P',
+ '\u1E56': 'P',
+ '\u01A4': 'P',
+ '\u2C63': 'P',
+ '\uA750': 'P',
+ '\uA752': 'P',
+ '\uA754': 'P',
+ '\u24C6': 'Q',
+ '\uFF31': 'Q',
+ '\uA756': 'Q',
+ '\uA758': 'Q',
+ '\u024A': 'Q',
+ '\u24C7': 'R',
+ '\uFF32': 'R',
+ '\u0154': 'R',
+ '\u1E58': 'R',
+ '\u0158': 'R',
+ '\u0210': 'R',
+ '\u0212': 'R',
+ '\u1E5A': 'R',
+ '\u1E5C': 'R',
+ '\u0156': 'R',
+ '\u1E5E': 'R',
+ '\u024C': 'R',
+ '\u2C64': 'R',
+ '\uA75A': 'R',
+ '\uA7A6': 'R',
+ '\uA782': 'R',
+ '\u24C8': 'S',
+ '\uFF33': 'S',
+ '\u1E9E': 'S',
+ '\u015A': 'S',
+ '\u1E64': 'S',
+ '\u015C': 'S',
+ '\u1E60': 'S',
+ '\u0160': 'S',
+ '\u1E66': 'S',
+ '\u1E62': 'S',
+ '\u1E68': 'S',
+ '\u0218': 'S',
+ '\u015E': 'S',
+ '\u2C7E': 'S',
+ '\uA7A8': 'S',
+ '\uA784': 'S',
+ '\u24C9': 'T',
+ '\uFF34': 'T',
+ '\u1E6A': 'T',
+ '\u0164': 'T',
+ '\u1E6C': 'T',
+ '\u021A': 'T',
+ '\u0162': 'T',
+ '\u1E70': 'T',
+ '\u1E6E': 'T',
+ '\u0166': 'T',
+ '\u01AC': 'T',
+ '\u01AE': 'T',
+ '\u023E': 'T',
+ '\uA786': 'T',
+ '\uA728': 'TZ',
+ '\u24CA': 'U',
+ '\uFF35': 'U',
+ '\u00D9': 'U',
+ '\u00DA': 'U',
+ '\u00DB': 'U',
+ '\u0168': 'U',
+ '\u1E78': 'U',
+ '\u016A': 'U',
+ '\u1E7A': 'U',
+ '\u016C': 'U',
+ '\u00DC': 'U',
+ '\u01DB': 'U',
+ '\u01D7': 'U',
+ '\u01D5': 'U',
+ '\u01D9': 'U',
+ '\u1EE6': 'U',
+ '\u016E': 'U',
+ '\u0170': 'U',
+ '\u01D3': 'U',
+ '\u0214': 'U',
+ '\u0216': 'U',
+ '\u01AF': 'U',
+ '\u1EEA': 'U',
+ '\u1EE8': 'U',
+ '\u1EEE': 'U',
+ '\u1EEC': 'U',
+ '\u1EF0': 'U',
+ '\u1EE4': 'U',
+ '\u1E72': 'U',
+ '\u0172': 'U',
+ '\u1E76': 'U',
+ '\u1E74': 'U',
+ '\u0244': 'U',
+ '\u24CB': 'V',
+ '\uFF36': 'V',
+ '\u1E7C': 'V',
+ '\u1E7E': 'V',
+ '\u01B2': 'V',
+ '\uA75E': 'V',
+ '\u0245': 'V',
+ '\uA760': 'VY',
+ '\u24CC': 'W',
+ '\uFF37': 'W',
+ '\u1E80': 'W',
+ '\u1E82': 'W',
+ '\u0174': 'W',
+ '\u1E86': 'W',
+ '\u1E84': 'W',
+ '\u1E88': 'W',
+ '\u2C72': 'W',
+ '\u24CD': 'X',
+ '\uFF38': 'X',
+ '\u1E8A': 'X',
+ '\u1E8C': 'X',
+ '\u24CE': 'Y',
+ '\uFF39': 'Y',
+ '\u1EF2': 'Y',
+ '\u00DD': 'Y',
+ '\u0176': 'Y',
+ '\u1EF8': 'Y',
+ '\u0232': 'Y',
+ '\u1E8E': 'Y',
+ '\u0178': 'Y',
+ '\u1EF6': 'Y',
+ '\u1EF4': 'Y',
+ '\u01B3': 'Y',
+ '\u024E': 'Y',
+ '\u1EFE': 'Y',
+ '\u24CF': 'Z',
+ '\uFF3A': 'Z',
+ '\u0179': 'Z',
+ '\u1E90': 'Z',
+ '\u017B': 'Z',
+ '\u017D': 'Z',
+ '\u1E92': 'Z',
+ '\u1E94': 'Z',
+ '\u01B5': 'Z',
+ '\u0224': 'Z',
+ '\u2C7F': 'Z',
+ '\u2C6B': 'Z',
+ '\uA762': 'Z',
+ '\u24D0': 'a',
+ '\uFF41': 'a',
+ '\u1E9A': 'a',
+ '\u00E0': 'a',
+ '\u00E1': 'a',
+ '\u00E2': 'a',
+ '\u1EA7': 'a',
+ '\u1EA5': 'a',
+ '\u1EAB': 'a',
+ '\u1EA9': 'a',
+ '\u00E3': 'a',
+ '\u0101': 'a',
+ '\u0103': 'a',
+ '\u1EB1': 'a',
+ '\u1EAF': 'a',
+ '\u1EB5': 'a',
+ '\u1EB3': 'a',
+ '\u0227': 'a',
+ '\u01E1': 'a',
+ '\u00E4': 'a',
+ '\u01DF': 'a',
+ '\u1EA3': 'a',
+ '\u00E5': 'a',
+ '\u01FB': 'a',
+ '\u01CE': 'a',
+ '\u0201': 'a',
+ '\u0203': 'a',
+ '\u1EA1': 'a',
+ '\u1EAD': 'a',
+ '\u1EB7': 'a',
+ '\u1E01': 'a',
+ '\u0105': 'a',
+ '\u2C65': 'a',
+ '\u0250': 'a',
+ '\uA733': 'aa',
+ '\u00E6': 'ae',
+ '\u01FD': 'ae',
+ '\u01E3': 'ae',
+ '\uA735': 'ao',
+ '\uA737': 'au',
+ '\uA739': 'av',
+ '\uA73B': 'av',
+ '\uA73D': 'ay',
+ '\u24D1': 'b',
+ '\uFF42': 'b',
+ '\u1E03': 'b',
+ '\u1E05': 'b',
+ '\u1E07': 'b',
+ '\u0180': 'b',
+ '\u0183': 'b',
+ '\u0253': 'b',
+ '\u24D2': 'c',
+ '\uFF43': 'c',
+ '\u0107': 'c',
+ '\u0109': 'c',
+ '\u010B': 'c',
+ '\u010D': 'c',
+ '\u00E7': 'c',
+ '\u1E09': 'c',
+ '\u0188': 'c',
+ '\u023C': 'c',
+ '\uA73F': 'c',
+ '\u2184': 'c',
+ '\u24D3': 'd',
+ '\uFF44': 'd',
+ '\u1E0B': 'd',
+ '\u010F': 'd',
+ '\u1E0D': 'd',
+ '\u1E11': 'd',
+ '\u1E13': 'd',
+ '\u1E0F': 'd',
+ '\u0111': 'd',
+ '\u018C': 'd',
+ '\u0256': 'd',
+ '\u0257': 'd',
+ '\uA77A': 'd',
+ '\u01F3': 'dz',
+ '\u01C6': 'dz',
+ '\u24D4': 'e',
+ '\uFF45': 'e',
+ '\u00E8': 'e',
+ '\u00E9': 'e',
+ '\u00EA': 'e',
+ '\u1EC1': 'e',
+ '\u1EBF': 'e',
+ '\u1EC5': 'e',
+ '\u1EC3': 'e',
+ '\u1EBD': 'e',
+ '\u0113': 'e',
+ '\u1E15': 'e',
+ '\u1E17': 'e',
+ '\u0115': 'e',
+ '\u0117': 'e',
+ '\u00EB': 'e',
+ '\u1EBB': 'e',
+ '\u011B': 'e',
+ '\u0205': 'e',
+ '\u0207': 'e',
+ '\u1EB9': 'e',
+ '\u1EC7': 'e',
+ '\u0229': 'e',
+ '\u1E1D': 'e',
+ '\u0119': 'e',
+ '\u1E19': 'e',
+ '\u1E1B': 'e',
+ '\u0247': 'e',
+ '\u025B': 'e',
+ '\u01DD': 'e',
+ '\u24D5': 'f',
+ '\uFF46': 'f',
+ '\u1E1F': 'f',
+ '\u0192': 'f',
+ '\uA77C': 'f',
+ '\u24D6': 'g',
+ '\uFF47': 'g',
+ '\u01F5': 'g',
+ '\u011D': 'g',
+ '\u1E21': 'g',
+ '\u011F': 'g',
+ '\u0121': 'g',
+ '\u01E7': 'g',
+ '\u0123': 'g',
+ '\u01E5': 'g',
+ '\u0260': 'g',
+ '\uA7A1': 'g',
+ '\u1D79': 'g',
+ '\uA77F': 'g',
+ '\u24D7': 'h',
+ '\uFF48': 'h',
+ '\u0125': 'h',
+ '\u1E23': 'h',
+ '\u1E27': 'h',
+ '\u021F': 'h',
+ '\u1E25': 'h',
+ '\u1E29': 'h',
+ '\u1E2B': 'h',
+ '\u1E96': 'h',
+ '\u0127': 'h',
+ '\u2C68': 'h',
+ '\u2C76': 'h',
+ '\u0265': 'h',
+ '\u0195': 'hv',
+ '\u24D8': 'i',
+ '\uFF49': 'i',
+ '\u00EC': 'i',
+ '\u00ED': 'i',
+ '\u00EE': 'i',
+ '\u0129': 'i',
+ '\u012B': 'i',
+ '\u012D': 'i',
+ '\u00EF': 'i',
+ '\u1E2F': 'i',
+ '\u1EC9': 'i',
+ '\u01D0': 'i',
+ '\u0209': 'i',
+ '\u020B': 'i',
+ '\u1ECB': 'i',
+ '\u012F': 'i',
+ '\u1E2D': 'i',
+ '\u0268': 'i',
+ '\u0131': 'i',
+ '\u24D9': 'j',
+ '\uFF4A': 'j',
+ '\u0135': 'j',
+ '\u01F0': 'j',
+ '\u0249': 'j',
+ '\u24DA': 'k',
+ '\uFF4B': 'k',
+ '\u1E31': 'k',
+ '\u01E9': 'k',
+ '\u1E33': 'k',
+ '\u0137': 'k',
+ '\u1E35': 'k',
+ '\u0199': 'k',
+ '\u2C6A': 'k',
+ '\uA741': 'k',
+ '\uA743': 'k',
+ '\uA745': 'k',
+ '\uA7A3': 'k',
+ '\u24DB': 'l',
+ '\uFF4C': 'l',
+ '\u0140': 'l',
+ '\u013A': 'l',
+ '\u013E': 'l',
+ '\u1E37': 'l',
+ '\u1E39': 'l',
+ '\u013C': 'l',
+ '\u1E3D': 'l',
+ '\u1E3B': 'l',
+ '\u017F': 'l',
+ '\u0142': 'l',
+ '\u019A': 'l',
+ '\u026B': 'l',
+ '\u2C61': 'l',
+ '\uA749': 'l',
+ '\uA781': 'l',
+ '\uA747': 'l',
+ '\u01C9': 'lj',
+ '\u24DC': 'm',
+ '\uFF4D': 'm',
+ '\u1E3F': 'm',
+ '\u1E41': 'm',
+ '\u1E43': 'm',
+ '\u0271': 'm',
+ '\u026F': 'm',
+ '\u24DD': 'n',
+ '\uFF4E': 'n',
+ '\u01F9': 'n',
+ '\u0144': 'n',
+ '\u00F1': 'n',
+ '\u1E45': 'n',
+ '\u0148': 'n',
+ '\u1E47': 'n',
+ '\u0146': 'n',
+ '\u1E4B': 'n',
+ '\u1E49': 'n',
+ '\u019E': 'n',
+ '\u0272': 'n',
+ '\u0149': 'n',
+ '\uA791': 'n',
+ '\uA7A5': 'n',
+ '\u01CC': 'nj',
+ '\u24DE': 'o',
+ '\uFF4F': 'o',
+ '\u00F2': 'o',
+ '\u00F3': 'o',
+ '\u00F4': 'o',
+ '\u1ED3': 'o',
+ '\u1ED1': 'o',
+ '\u1ED7': 'o',
+ '\u1ED5': 'o',
+ '\u00F5': 'o',
+ '\u1E4D': 'o',
+ '\u022D': 'o',
+ '\u1E4F': 'o',
+ '\u014D': 'o',
+ '\u1E51': 'o',
+ '\u1E53': 'o',
+ '\u014F': 'o',
+ '\u022F': 'o',
+ '\u0231': 'o',
+ '\u00F6': 'o',
+ '\u022B': 'o',
+ '\u1ECF': 'o',
+ '\u0151': 'o',
+ '\u01D2': 'o',
+ '\u020D': 'o',
+ '\u020F': 'o',
+ '\u01A1': 'o',
+ '\u1EDD': 'o',
+ '\u1EDB': 'o',
+ '\u1EE1': 'o',
+ '\u1EDF': 'o',
+ '\u1EE3': 'o',
+ '\u1ECD': 'o',
+ '\u1ED9': 'o',
+ '\u01EB': 'o',
+ '\u01ED': 'o',
+ '\u00F8': 'o',
+ '\u01FF': 'o',
+ '\u0254': 'o',
+ '\uA74B': 'o',
+ '\uA74D': 'o',
+ '\u0275': 'o',
+ '\u01A3': 'oi',
+ '\u0223': 'ou',
+ '\uA74F': 'oo',
+ '\u24DF': 'p',
+ '\uFF50': 'p',
+ '\u1E55': 'p',
+ '\u1E57': 'p',
+ '\u01A5': 'p',
+ '\u1D7D': 'p',
+ '\uA751': 'p',
+ '\uA753': 'p',
+ '\uA755': 'p',
+ '\u24E0': 'q',
+ '\uFF51': 'q',
+ '\u024B': 'q',
+ '\uA757': 'q',
+ '\uA759': 'q',
+ '\u24E1': 'r',
+ '\uFF52': 'r',
+ '\u0155': 'r',
+ '\u1E59': 'r',
+ '\u0159': 'r',
+ '\u0211': 'r',
+ '\u0213': 'r',
+ '\u1E5B': 'r',
+ '\u1E5D': 'r',
+ '\u0157': 'r',
+ '\u1E5F': 'r',
+ '\u024D': 'r',
+ '\u027D': 'r',
+ '\uA75B': 'r',
+ '\uA7A7': 'r',
+ '\uA783': 'r',
+ '\u24E2': 's',
+ '\uFF53': 's',
+ '\u00DF': 's',
+ '\u015B': 's',
+ '\u1E65': 's',
+ '\u015D': 's',
+ '\u1E61': 's',
+ '\u0161': 's',
+ '\u1E67': 's',
+ '\u1E63': 's',
+ '\u1E69': 's',
+ '\u0219': 's',
+ '\u015F': 's',
+ '\u023F': 's',
+ '\uA7A9': 's',
+ '\uA785': 's',
+ '\u1E9B': 's',
+ '\u24E3': 't',
+ '\uFF54': 't',
+ '\u1E6B': 't',
+ '\u1E97': 't',
+ '\u0165': 't',
+ '\u1E6D': 't',
+ '\u021B': 't',
+ '\u0163': 't',
+ '\u1E71': 't',
+ '\u1E6F': 't',
+ '\u0167': 't',
+ '\u01AD': 't',
+ '\u0288': 't',
+ '\u2C66': 't',
+ '\uA787': 't',
+ '\uA729': 'tz',
+ '\u24E4': 'u',
+ '\uFF55': 'u',
+ '\u00F9': 'u',
+ '\u00FA': 'u',
+ '\u00FB': 'u',
+ '\u0169': 'u',
+ '\u1E79': 'u',
+ '\u016B': 'u',
+ '\u1E7B': 'u',
+ '\u016D': 'u',
+ '\u00FC': 'u',
+ '\u01DC': 'u',
+ '\u01D8': 'u',
+ '\u01D6': 'u',
+ '\u01DA': 'u',
+ '\u1EE7': 'u',
+ '\u016F': 'u',
+ '\u0171': 'u',
+ '\u01D4': 'u',
+ '\u0215': 'u',
+ '\u0217': 'u',
+ '\u01B0': 'u',
+ '\u1EEB': 'u',
+ '\u1EE9': 'u',
+ '\u1EEF': 'u',
+ '\u1EED': 'u',
+ '\u1EF1': 'u',
+ '\u1EE5': 'u',
+ '\u1E73': 'u',
+ '\u0173': 'u',
+ '\u1E77': 'u',
+ '\u1E75': 'u',
+ '\u0289': 'u',
+ '\u24E5': 'v',
+ '\uFF56': 'v',
+ '\u1E7D': 'v',
+ '\u1E7F': 'v',
+ '\u028B': 'v',
+ '\uA75F': 'v',
+ '\u028C': 'v',
+ '\uA761': 'vy',
+ '\u24E6': 'w',
+ '\uFF57': 'w',
+ '\u1E81': 'w',
+ '\u1E83': 'w',
+ '\u0175': 'w',
+ '\u1E87': 'w',
+ '\u1E85': 'w',
+ '\u1E98': 'w',
+ '\u1E89': 'w',
+ '\u2C73': 'w',
+ '\u24E7': 'x',
+ '\uFF58': 'x',
+ '\u1E8B': 'x',
+ '\u1E8D': 'x',
+ '\u24E8': 'y',
+ '\uFF59': 'y',
+ '\u1EF3': 'y',
+ '\u00FD': 'y',
+ '\u0177': 'y',
+ '\u1EF9': 'y',
+ '\u0233': 'y',
+ '\u1E8F': 'y',
+ '\u00FF': 'y',
+ '\u1EF7': 'y',
+ '\u1E99': 'y',
+ '\u1EF5': 'y',
+ '\u01B4': 'y',
+ '\u024F': 'y',
+ '\u1EFF': 'y',
+ '\u24E9': 'z',
+ '\uFF5A': 'z',
+ '\u017A': 'z',
+ '\u1E91': 'z',
+ '\u017C': 'z',
+ '\u017E': 'z',
+ '\u1E93': 'z',
+ '\u1E95': 'z',
+ '\u01B6': 'z',
+ '\u0225': 'z',
+ '\u0240': 'z',
+ '\u2C6C': 'z',
+ '\uA763': 'z',
+ '\u0386': '\u0391',
+ '\u0388': '\u0395',
+ '\u0389': '\u0397',
+ '\u038A': '\u0399',
+ '\u03AA': '\u0399',
+ '\u038C': '\u039F',
+ '\u038E': '\u03A5',
+ '\u03AB': '\u03A5',
+ '\u038F': '\u03A9',
+ '\u03AC': '\u03B1',
+ '\u03AD': '\u03B5',
+ '\u03AE': '\u03B7',
+ '\u03AF': '\u03B9',
+ '\u03CA': '\u03B9',
+ '\u0390': '\u03B9',
+ '\u03CC': '\u03BF',
+ '\u03CD': '\u03C5',
+ '\u03CB': '\u03C5',
+ '\u03B0': '\u03C5',
+ '\u03C9': '\u03C9',
+ '\u03C2': '\u03C3'
+ };
+
+ return diacritics;
+});
+
+S2.define('select2/data/base',[
+ '../utils'
+], function (Utils) {
+ function BaseAdapter ($element, options) {
+ BaseAdapter.__super__.constructor.call(this);
+ }
+
+ Utils.Extend(BaseAdapter, Utils.Observable);
+
+ BaseAdapter.prototype.current = function (callback) {
+ throw new Error('The `current` method must be defined in child classes.');
+ };
+
+ BaseAdapter.prototype.query = function (params, callback) {
+ throw new Error('The `query` method must be defined in child classes.');
+ };
+
+ BaseAdapter.prototype.bind = function (container, $container) {
+ // Can be implemented in subclasses
+ };
+
+ BaseAdapter.prototype.destroy = function () {
+ // Can be implemented in subclasses
+ };
+
+ BaseAdapter.prototype.generateResultId = function (container, data) {
+ var id = container.id + '-result-';
+
+ id += Utils.generateChars(4);
+
+ if (data.id != null) {
+ id += '-' + data.id.toString();
+ } else {
+ id += '-' + Utils.generateChars(4);
+ }
+ return id;
+ };
+
+ return BaseAdapter;
+});
+
+S2.define('select2/data/select',[
+ './base',
+ '../utils',
+ 'jquery'
+], function (BaseAdapter, Utils, $) {
+ function SelectAdapter ($element, options) {
+ this.$element = $element;
+ this.options = options;
+
+ SelectAdapter.__super__.constructor.call(this);
+ }
+
+ Utils.Extend(SelectAdapter, BaseAdapter);
+
+ SelectAdapter.prototype.current = function (callback) {
+ var data = [];
+ var self = this;
+
+ this.$element.find(':selected').each(function () {
+ var $option = $(this);
+
+ var option = self.item($option);
+
+ data.push(option);
+ });
+
+ callback(data);
+ };
+
+ SelectAdapter.prototype.select = function (data) {
+ var self = this;
+
+ data.selected = true;
+
+ // If data.element is a DOM node, use it instead
+ if ($(data.element).is('option')) {
+ data.element.selected = true;
+
+ this.$element.trigger('change');
+
+ return;
+ }
+
+ if (this.$element.prop('multiple')) {
+ this.current(function (currentData) {
+ var val = [];
+
+ data = [data];
+ data.push.apply(data, currentData);
+
+ for (var d = 0; d < data.length; d++) {
+ var id = data[d].id;
+
+ if ($.inArray(id, val) === -1) {
+ val.push(id);
+ }
+ }
+
+ self.$element.val(val);
+ self.$element.trigger('change');
+ });
+ } else {
+ var val = data.id;
+
+ this.$element.val(val);
+ this.$element.trigger('change');
+ }
+ };
+
+ SelectAdapter.prototype.unselect = function (data) {
+ var self = this;
+
+ if (!this.$element.prop('multiple')) {
+ return;
+ }
+
+ data.selected = false;
+
+ if ($(data.element).is('option')) {
+ data.element.selected = false;
+
+ this.$element.trigger('change');
+
+ return;
+ }
+
+ this.current(function (currentData) {
+ var val = [];
+
+ for (var d = 0; d < currentData.length; d++) {
+ var id = currentData[d].id;
+
+ if (id !== data.id && $.inArray(id, val) === -1) {
+ val.push(id);
+ }
+ }
+
+ self.$element.val(val);
+
+ self.$element.trigger('change');
+ });
+ };
+
+ SelectAdapter.prototype.bind = function (container, $container) {
+ var self = this;
+
+ this.container = container;
+
+ container.on('select', function (params) {
+ self.select(params.data);
+ });
+
+ container.on('unselect', function (params) {
+ self.unselect(params.data);
+ });
+ };
+
+ SelectAdapter.prototype.destroy = function () {
+ // Remove anything added to child elements
+ this.$element.find('*').each(function () {
+ // Remove any custom data set by Select2
+ Utils.RemoveData(this);
+ });
+ };
+
+ SelectAdapter.prototype.query = function (params, callback) {
+ var data = [];
+ var self = this;
+
+ var $options = this.$element.children();
+
+ $options.each(function () {
+ var $option = $(this);
+
+ if (!$option.is('option') && !$option.is('optgroup')) {
+ return;
+ }
+
+ var option = self.item($option);
+
+ var matches = self.matches(params, option);
+
+ if (matches !== null) {
+ data.push(matches);
+ }
+ });
+
+ callback({
+ results: data
+ });
+ };
+
+ SelectAdapter.prototype.addOptions = function ($options) {
+ Utils.appendMany(this.$element, $options);
+ };
+
+ SelectAdapter.prototype.option = function (data) {
+ var option;
+
+ if (data.children) {
+ option = document.createElement('optgroup');
+ option.label = data.text;
+ } else {
+ option = document.createElement('option');
+
+ if (option.textContent !== undefined) {
+ option.textContent = data.text;
+ } else {
+ option.innerText = data.text;
+ }
+ }
+
+ if (data.id !== undefined) {
+ option.value = data.id;
+ }
+
+ if (data.disabled) {
+ option.disabled = true;
+ }
+
+ if (data.selected) {
+ option.selected = true;
+ }
+
+ if (data.title) {
+ option.title = data.title;
+ }
+
+ var $option = $(option);
+
+ var normalizedData = this._normalizeItem(data);
+ normalizedData.element = option;
+
+ // Override the option's data with the combined data
+ Utils.StoreData(option, 'data', normalizedData);
+
+ return $option;
+ };
+
+ SelectAdapter.prototype.item = function ($option) {
+ var data = {};
+
+ data = Utils.GetData($option[0], 'data');
+
+ if (data != null) {
+ return data;
+ }
+
+ if ($option.is('option')) {
+ data = {
+ id: $option.val(),
+ text: $option.text(),
+ disabled: $option.prop('disabled'),
+ selected: $option.prop('selected'),
+ title: $option.prop('title')
+ };
+ } else if ($option.is('optgroup')) {
+ data = {
+ text: $option.prop('label'),
+ children: [],
+ title: $option.prop('title')
+ };
+
+ var $children = $option.children('option');
+ var children = [];
+
+ for (var c = 0; c < $children.length; c++) {
+ var $child = $($children[c]);
+
+ var child = this.item($child);
+
+ children.push(child);
+ }
+
+ data.children = children;
+ }
+
+ data = this._normalizeItem(data);
+ data.element = $option[0];
+
+ Utils.StoreData($option[0], 'data', data);
+
+ return data;
+ };
+
+ SelectAdapter.prototype._normalizeItem = function (item) {
+ if (item !== Object(item)) {
+ item = {
+ id: item,
+ text: item
+ };
+ }
+
+ item = $.extend({}, {
+ text: ''
+ }, item);
+
+ var defaults = {
+ selected: false,
+ disabled: false
+ };
+
+ if (item.id != null) {
+ item.id = item.id.toString();
+ }
+
+ if (item.text != null) {
+ item.text = item.text.toString();
+ }
+
+ if (item._resultId == null && item.id && this.container != null) {
+ item._resultId = this.generateResultId(this.container, item);
+ }
+
+ return $.extend({}, defaults, item);
+ };
+
+ SelectAdapter.prototype.matches = function (params, data) {
+ var matcher = this.options.get('matcher');
+
+ return matcher(params, data);
+ };
+
+ return SelectAdapter;
+});
+
+S2.define('select2/data/array',[
+ './select',
+ '../utils',
+ 'jquery'
+], function (SelectAdapter, Utils, $) {
+ function ArrayAdapter ($element, options) {
+ var data = options.get('data') || [];
+
+ ArrayAdapter.__super__.constructor.call(this, $element, options);
+
+ this.addOptions(this.convertToOptions(data));
+ }
+
+ Utils.Extend(ArrayAdapter, SelectAdapter);
+
+ ArrayAdapter.prototype.select = function (data) {
+ var $option = this.$element.find('option').filter(function (i, elm) {
+ return elm.value == data.id.toString();
+ });
+
+ if ($option.length === 0) {
+ $option = this.option(data);
+
+ this.addOptions($option);
+ }
+
+ ArrayAdapter.__super__.select.call(this, data);
+ };
+
+ ArrayAdapter.prototype.convertToOptions = function (data) {
+ var self = this;
+
+ var $existing = this.$element.find('option');
+ var existingIds = $existing.map(function () {
+ return self.item($(this)).id;
+ }).get();
+
+ var $options = [];
+
+ // Filter out all items except for the one passed in the argument
+ function onlyItem (item) {
+ return function () {
+ return $(this).val() == item.id;
+ };
+ }
+
+ for (var d = 0; d < data.length; d++) {
+ var item = this._normalizeItem(data[d]);
+
+ // Skip items which were pre-loaded, only merge the data
+ if ($.inArray(item.id, existingIds) >= 0) {
+ var $existingOption = $existing.filter(onlyItem(item));
+
+ var existingData = this.item($existingOption);
+ var newData = $.extend(true, {}, item, existingData);
+
+ var $newOption = this.option(newData);
+
+ $existingOption.replaceWith($newOption);
+
+ continue;
+ }
+
+ var $option = this.option(item);
+
+ if (item.children) {
+ var $children = this.convertToOptions(item.children);
+
+ Utils.appendMany($option, $children);
+ }
+
+ $options.push($option);
+ }
+
+ return $options;
+ };
+
+ return ArrayAdapter;
+});
+
+S2.define('select2/data/ajax',[
+ './array',
+ '../utils',
+ 'jquery'
+], function (ArrayAdapter, Utils, $) {
+ function AjaxAdapter ($element, options) {
+ this.ajaxOptions = this._applyDefaults(options.get('ajax'));
+
+ if (this.ajaxOptions.processResults != null) {
+ this.processResults = this.ajaxOptions.processResults;
+ }
+
+ AjaxAdapter.__super__.constructor.call(this, $element, options);
+ }
+
+ Utils.Extend(AjaxAdapter, ArrayAdapter);
+
+ AjaxAdapter.prototype._applyDefaults = function (options) {
+ var defaults = {
+ data: function (params) {
+ return $.extend({}, params, {
+ q: params.term
+ });
+ },
+ transport: function (params, success, failure) {
+ var $request = $.ajax(params);
+
+ $request.then(success);
+ $request.fail(failure);
+
+ return $request;
+ }
+ };
+
+ return $.extend({}, defaults, options, true);
+ };
+
+ AjaxAdapter.prototype.processResults = function (results) {
+ return results;
+ };
+
+ AjaxAdapter.prototype.query = function (params, callback) {
+ var matches = [];
+ var self = this;
+
+ if (this._request != null) {
+ // JSONP requests cannot always be aborted
+ if ($.isFunction(this._request.abort)) {
+ this._request.abort();
+ }
+
+ this._request = null;
+ }
+
+ var options = $.extend({
+ type: 'GET'
+ }, this.ajaxOptions);
+
+ if (typeof options.url === 'function') {
+ options.url = options.url.call(this.$element, params);
+ }
+
+ if (typeof options.data === 'function') {
+ options.data = options.data.call(this.$element, params);
+ }
+
+ function request () {
+ var $request = options.transport(options, function (data) {
+ var results = self.processResults(data, params);
+
+ if (self.options.get('debug') && window.console && console.error) {
+ // Check to make sure that the response included a `results` key.
+ if (!results || !results.results || !$.isArray(results.results)) {
+ console.error(
+ 'Select2: The AJAX results did not return an array in the ' +
+ '`results` key of the response.'
+ );
+ }
+ }
+
+ callback(results);
+ }, function () {
+ // Attempt to detect if a request was aborted
+ // Only works if the transport exposes a status property
+ if ('status' in $request &&
+ ($request.status === 0 || $request.status === '0')) {
+ return;
+ }
+
+ self.trigger('results:message', {
+ message: 'errorLoading'
+ });
+ });
+
+ self._request = $request;
+ }
+
+ if (this.ajaxOptions.delay && params.term != null) {
+ if (this._queryTimeout) {
+ window.clearTimeout(this._queryTimeout);
+ }
+
+ this._queryTimeout = window.setTimeout(request, this.ajaxOptions.delay);
+ } else {
+ request();
+ }
+ };
+
+ return AjaxAdapter;
+});
+
+S2.define('select2/data/tags',[
+ 'jquery'
+], function ($) {
+ function Tags (decorated, $element, options) {
+ var tags = options.get('tags');
+
+ var createTag = options.get('createTag');
+
+ if (createTag !== undefined) {
+ this.createTag = createTag;
+ }
+
+ var insertTag = options.get('insertTag');
+
+ if (insertTag !== undefined) {
+ this.insertTag = insertTag;
+ }
+
+ decorated.call(this, $element, options);
+
+ if ($.isArray(tags)) {
+ for (var t = 0; t < tags.length; t++) {
+ var tag = tags[t];
+ var item = this._normalizeItem(tag);
+
+ var $option = this.option(item);
+
+ this.$element.append($option);
+ }
+ }
+ }
+
+ Tags.prototype.query = function (decorated, params, callback) {
+ var self = this;
+
+ this._removeOldTags();
+
+ if (params.term == null || params.page != null) {
+ decorated.call(this, params, callback);
+ return;
+ }
+
+ function wrapper (obj, child) {
+ var data = obj.results;
+
+ for (var i = 0; i < data.length; i++) {
+ var option = data[i];
+
+ var checkChildren = (
+ option.children != null &&
+ !wrapper({
+ results: option.children
+ }, true)
+ );
+
+ var optionText = (option.text || '').toUpperCase();
+ var paramsTerm = (params.term || '').toUpperCase();
+
+ var checkText = optionText === paramsTerm;
+
+ if (checkText || checkChildren) {
+ if (child) {
+ return false;
+ }
+
+ obj.data = data;
+ callback(obj);
+
+ return;
+ }
+ }
+
+ if (child) {
+ return true;
+ }
+
+ var tag = self.createTag(params);
+
+ if (tag != null) {
+ var $option = self.option(tag);
+ $option.attr('data-select2-tag', true);
+
+ self.addOptions([$option]);
+
+ self.insertTag(data, tag);
+ }
+
+ obj.results = data;
+
+ callback(obj);
+ }
+
+ decorated.call(this, params, wrapper);
+ };
+
+ Tags.prototype.createTag = function (decorated, params) {
+ var term = $.trim(params.term);
+
+ if (term === '') {
+ return null;
+ }
+
+ return {
+ id: term,
+ text: term
+ };
+ };
+
+ Tags.prototype.insertTag = function (_, data, tag) {
+ data.unshift(tag);
+ };
+
+ Tags.prototype._removeOldTags = function (_) {
+ var tag = this._lastTag;
+
+ var $options = this.$element.find('option[data-select2-tag]');
+
+ $options.each(function () {
+ if (this.selected) {
+ return;
+ }
+
+ $(this).remove();
+ });
+ };
+
+ return Tags;
+});
+
+S2.define('select2/data/tokenizer',[
+ 'jquery'
+], function ($) {
+ function Tokenizer (decorated, $element, options) {
+ var tokenizer = options.get('tokenizer');
+
+ if (tokenizer !== undefined) {
+ this.tokenizer = tokenizer;
+ }
+
+ decorated.call(this, $element, options);
+ }
+
+ Tokenizer.prototype.bind = function (decorated, container, $container) {
+ decorated.call(this, container, $container);
+
+ this.$search = container.dropdown.$search || container.selection.$search ||
+ $container.find('.select2-search__field');
+ };
+
+ Tokenizer.prototype.query = function (decorated, params, callback) {
+ var self = this;
+
+ function createAndSelect (data) {
+ // Normalize the data object so we can use it for checks
+ var item = self._normalizeItem(data);
+
+ // Check if the data object already exists as a tag
+ // Select it if it doesn't
+ var $existingOptions = self.$element.find('option').filter(function () {
+ return $(this).val() === item.id;
+ });
+
+ // If an existing option wasn't found for it, create the option
+ if (!$existingOptions.length) {
+ var $option = self.option(item);
+ $option.attr('data-select2-tag', true);
+
+ self._removeOldTags();
+ self.addOptions([$option]);
+ }
+
+ // Select the item, now that we know there is an option for it
+ select(item);
+ }
+
+ function select (data) {
+ self.trigger('select', {
+ data: data
+ });
+ }
+
+ params.term = params.term || '';
+
+ var tokenData = this.tokenizer(params, this.options, createAndSelect);
+
+ if (tokenData.term !== params.term) {
+ // Replace the search term if we have the search box
+ if (this.$search.length) {
+ this.$search.val(tokenData.term);
+ this.$search.focus();
+ }
+
+ params.term = tokenData.term;
+ }
+
+ decorated.call(this, params, callback);
+ };
+
+ Tokenizer.prototype.tokenizer = function (_, params, options, callback) {
+ var separators = options.get('tokenSeparators') || [];
+ var term = params.term;
+ var i = 0;
+
+ var createTag = this.createTag || function (params) {
+ return {
+ id: params.term,
+ text: params.term
+ };
+ };
+
+ while (i < term.length) {
+ var termChar = term[i];
+
+ if ($.inArray(termChar, separators) === -1) {
+ i++;
+
+ continue;
+ }
+
+ var part = term.substr(0, i);
+ var partParams = $.extend({}, params, {
+ term: part
+ });
+
+ var data = createTag(partParams);
+
+ if (data == null) {
+ i++;
+ continue;
+ }
+
+ callback(data);
+
+ // Reset the term to not include the tokenized portion
+ term = term.substr(i + 1) || '';
+ i = 0;
+ }
+
+ return {
+ term: term
+ };
+ };
+
+ return Tokenizer;
+});
+
+S2.define('select2/data/minimumInputLength',[
+
+], function () {
+ function MinimumInputLength (decorated, $e, options) {
+ this.minimumInputLength = options.get('minimumInputLength');
+
+ decorated.call(this, $e, options);
+ }
+
+ MinimumInputLength.prototype.query = function (decorated, params, callback) {
+ params.term = params.term || '';
+
+ if (params.term.length < this.minimumInputLength) {
+ this.trigger('results:message', {
+ message: 'inputTooShort',
+ args: {
+ minimum: this.minimumInputLength,
+ input: params.term,
+ params: params
+ }
+ });
+
+ return;
+ }
+
+ decorated.call(this, params, callback);
+ };
+
+ return MinimumInputLength;
+});
+
+S2.define('select2/data/maximumInputLength',[
+
+], function () {
+ function MaximumInputLength (decorated, $e, options) {
+ this.maximumInputLength = options.get('maximumInputLength');
+
+ decorated.call(this, $e, options);
+ }
+
+ MaximumInputLength.prototype.query = function (decorated, params, callback) {
+ params.term = params.term || '';
+
+ if (this.maximumInputLength > 0 &&
+ params.term.length > this.maximumInputLength) {
+ this.trigger('results:message', {
+ message: 'inputTooLong',
+ args: {
+ maximum: this.maximumInputLength,
+ input: params.term,
+ params: params
+ }
+ });
+
+ return;
+ }
+
+ decorated.call(this, params, callback);
+ };
+
+ return MaximumInputLength;
+});
+
+S2.define('select2/data/maximumSelectionLength',[
+
+], function (){
+ function MaximumSelectionLength (decorated, $e, options) {
+ this.maximumSelectionLength = options.get('maximumSelectionLength');
+
+ decorated.call(this, $e, options);
+ }
+
+ MaximumSelectionLength.prototype.query =
+ function (decorated, params, callback) {
+ var self = this;
+
+ this.current(function (currentData) {
+ var count = currentData != null ? currentData.length : 0;
+ if (self.maximumSelectionLength > 0 &&
+ count >= self.maximumSelectionLength) {
+ self.trigger('results:message', {
+ message: 'maximumSelected',
+ args: {
+ maximum: self.maximumSelectionLength
+ }
+ });
+ return;
+ }
+ decorated.call(self, params, callback);
+ });
+ };
+
+ return MaximumSelectionLength;
+});
+
+S2.define('select2/dropdown',[
+ 'jquery',
+ './utils'
+], function ($, Utils) {
+ function Dropdown ($element, options) {
+ this.$element = $element;
+ this.options = options;
+
+ Dropdown.__super__.constructor.call(this);
+ }
+
+ Utils.Extend(Dropdown, Utils.Observable);
+
+ Dropdown.prototype.render = function () {
+ var $dropdown = $(
+ '' +
+ ' ' +
+ ' '
+ );
+
+ $dropdown.attr('dir', this.options.get('dir'));
+
+ this.$dropdown = $dropdown;
+
+ return $dropdown;
+ };
+
+ Dropdown.prototype.bind = function () {
+ // Should be implemented in subclasses
+ };
+
+ Dropdown.prototype.position = function ($dropdown, $container) {
+ // Should be implmented in subclasses
+ };
+
+ Dropdown.prototype.destroy = function () {
+ // Remove the dropdown from the DOM
+ this.$dropdown.remove();
+ };
+
+ return Dropdown;
+});
+
+S2.define('select2/dropdown/search',[
+ 'jquery',
+ '../utils'
+], function ($, Utils) {
+ function Search () { }
+
+ Search.prototype.render = function (decorated) {
+ var $rendered = decorated.call(this);
+
+ var $search = $(
+ '' +
+ ' ' +
+ ' '
+ );
+
+ this.$searchContainer = $search;
+ this.$search = $search.find('input');
+
+ $rendered.prepend($search);
+
+ return $rendered;
+ };
+
+ Search.prototype.bind = function (decorated, container, $container) {
+ var self = this;
+
+ decorated.call(this, container, $container);
+
+ this.$search.on('keydown', function (evt) {
+ self.trigger('keypress', evt);
+
+ self._keyUpPrevented = evt.isDefaultPrevented();
+ });
+
+ // Workaround for browsers which do not support the `input` event
+ // This will prevent double-triggering of events for browsers which support
+ // both the `keyup` and `input` events.
+ this.$search.on('input', function (evt) {
+ // Unbind the duplicated `keyup` event
+ $(this).off('keyup');
+ });
+
+ this.$search.on('keyup input', function (evt) {
+ self.handleSearch(evt);
+ });
+
+ container.on('open', function () {
+ self.$search.attr('tabindex', 0);
+
+ self.$search.focus();
+
+ window.setTimeout(function () {
+ self.$search.focus();
+ }, 0);
+ });
+
+ container.on('close', function () {
+ self.$search.attr('tabindex', -1);
+
+ self.$search.val('');
+ self.$search.blur();
+ });
+
+ container.on('focus', function () {
+ if (!container.isOpen()) {
+ self.$search.focus();
+ }
+ });
+
+ container.on('results:all', function (params) {
+ if (params.query.term == null || params.query.term === '') {
+ var showSearch = self.showSearch(params);
+
+ if (showSearch) {
+ self.$searchContainer.removeClass('select2-search--hide');
+ } else {
+ self.$searchContainer.addClass('select2-search--hide');
+ }
+ }
+ });
+ };
+
+ Search.prototype.handleSearch = function (evt) {
+ if (!this._keyUpPrevented) {
+ var input = this.$search.val();
+
+ this.trigger('query', {
+ term: input
+ });
+ }
+
+ this._keyUpPrevented = false;
+ };
+
+ Search.prototype.showSearch = function (_, params) {
+ return true;
+ };
+
+ return Search;
+});
+
+S2.define('select2/dropdown/hidePlaceholder',[
+
+], function () {
+ function HidePlaceholder (decorated, $element, options, dataAdapter) {
+ this.placeholder = this.normalizePlaceholder(options.get('placeholder'));
+
+ decorated.call(this, $element, options, dataAdapter);
+ }
+
+ HidePlaceholder.prototype.append = function (decorated, data) {
+ data.results = this.removePlaceholder(data.results);
+
+ decorated.call(this, data);
+ };
+
+ HidePlaceholder.prototype.normalizePlaceholder = function (_, placeholder) {
+ if (typeof placeholder === 'string') {
+ placeholder = {
+ id: '',
+ text: placeholder
+ };
+ }
+
+ return placeholder;
+ };
+
+ HidePlaceholder.prototype.removePlaceholder = function (_, data) {
+ var modifiedData = data.slice(0);
+
+ for (var d = data.length - 1; d >= 0; d--) {
+ var item = data[d];
+
+ if (this.placeholder.id === item.id) {
+ modifiedData.splice(d, 1);
+ }
+ }
+
+ return modifiedData;
+ };
+
+ return HidePlaceholder;
+});
+
+S2.define('select2/dropdown/infiniteScroll',[
+ 'jquery'
+], function ($) {
+ function InfiniteScroll (decorated, $element, options, dataAdapter) {
+ this.lastParams = {};
+
+ decorated.call(this, $element, options, dataAdapter);
+
+ this.$loadingMore = this.createLoadingMore();
+ this.loading = false;
+ }
+
+ InfiniteScroll.prototype.append = function (decorated, data) {
+ this.$loadingMore.remove();
+ this.loading = false;
+
+ decorated.call(this, data);
+
+ if (this.showLoadingMore(data)) {
+ this.$results.append(this.$loadingMore);
+ }
+ };
+
+ InfiniteScroll.prototype.bind = function (decorated, container, $container) {
+ var self = this;
+
+ decorated.call(this, container, $container);
+
+ container.on('query', function (params) {
+ self.lastParams = params;
+ self.loading = true;
+ });
+
+ container.on('query:append', function (params) {
+ self.lastParams = params;
+ self.loading = true;
+ });
+
+ this.$results.on('scroll', function () {
+ var isLoadMoreVisible = $.contains(
+ document.documentElement,
+ self.$loadingMore[0]
+ );
+
+ if (self.loading || !isLoadMoreVisible) {
+ return;
+ }
+
+ var currentOffset = self.$results.offset().top +
+ self.$results.outerHeight(false);
+ var loadingMoreOffset = self.$loadingMore.offset().top +
+ self.$loadingMore.outerHeight(false);
+
+ if (currentOffset + 50 >= loadingMoreOffset) {
+ self.loadMore();
+ }
+ });
+ };
+
+ InfiniteScroll.prototype.loadMore = function () {
+ this.loading = true;
+
+ var params = $.extend({}, {page: 1}, this.lastParams);
+
+ params.page++;
+
+ this.trigger('query:append', params);
+ };
+
+ InfiniteScroll.prototype.showLoadingMore = function (_, data) {
+ return data.pagination && data.pagination.more;
+ };
+
+ InfiniteScroll.prototype.createLoadingMore = function () {
+ var $option = $(
+ ' '
+ );
+
+ var message = this.options.get('translations').get('loadingMore');
+
+ $option.html(message(this.lastParams));
+
+ return $option;
+ };
+
+ return InfiniteScroll;
+});
+
+S2.define('select2/dropdown/attachBody',[
+ 'jquery',
+ '../utils'
+], function ($, Utils) {
+ function AttachBody (decorated, $element, options) {
+ this.$dropdownParent = options.get('dropdownParent') || $(document.body);
+
+ decorated.call(this, $element, options);
+ }
+
+ AttachBody.prototype.bind = function (decorated, container, $container) {
+ var self = this;
+
+ var setupResultsEvents = false;
+
+ decorated.call(this, container, $container);
+
+ container.on('open', function () {
+ self._showDropdown();
+ self._attachPositioningHandler(container);
+
+ if (!setupResultsEvents) {
+ setupResultsEvents = true;
+
+ container.on('results:all', function () {
+ self._positionDropdown();
+ self._resizeDropdown();
+ });
+
+ container.on('results:append', function () {
+ self._positionDropdown();
+ self._resizeDropdown();
+ });
+ }
+ });
+
+ container.on('close', function () {
+ self._hideDropdown();
+ self._detachPositioningHandler(container);
+ });
+
+ this.$dropdownContainer.on('mousedown', function (evt) {
+ evt.stopPropagation();
+ });
+ };
+
+ AttachBody.prototype.destroy = function (decorated) {
+ decorated.call(this);
+
+ this.$dropdownContainer.remove();
+ };
+
+ AttachBody.prototype.position = function (decorated, $dropdown, $container) {
+ // Clone all of the container classes
+ $dropdown.attr('class', $container.attr('class'));
+
+ $dropdown.removeClass('select2');
+ $dropdown.addClass('select2-container--open');
+
+ $dropdown.css({
+ position: 'absolute',
+ top: -999999
+ });
+
+ this.$container = $container;
+ };
+
+ AttachBody.prototype.render = function (decorated) {
+ var $container = $(' ');
+
+ var $dropdown = decorated.call(this);
+ $container.append($dropdown);
+
+ this.$dropdownContainer = $container;
+
+ return $container;
+ };
+
+ AttachBody.prototype._hideDropdown = function (decorated) {
+ this.$dropdownContainer.detach();
+ };
+
+ AttachBody.prototype._attachPositioningHandler =
+ function (decorated, container) {
+ var self = this;
+
+ var scrollEvent = 'scroll.select2.' + container.id;
+ var resizeEvent = 'resize.select2.' + container.id;
+ var orientationEvent = 'orientationchange.select2.' + container.id;
+
+ var $watchers = this.$container.parents().filter(Utils.hasScroll);
+ $watchers.each(function () {
+ Utils.StoreData(this, 'select2-scroll-position', {
+ x: $(this).scrollLeft(),
+ y: $(this).scrollTop()
+ });
+ });
+
+ $watchers.on(scrollEvent, function (ev) {
+ var position = Utils.GetData(this, 'select2-scroll-position');
+ $(this).scrollTop(position.y);
+ });
+
+ $(window).on(scrollEvent + ' ' + resizeEvent + ' ' + orientationEvent,
+ function (e) {
+ self._positionDropdown();
+ self._resizeDropdown();
+ });
+ };
+
+ AttachBody.prototype._detachPositioningHandler =
+ function (decorated, container) {
+ var scrollEvent = 'scroll.select2.' + container.id;
+ var resizeEvent = 'resize.select2.' + container.id;
+ var orientationEvent = 'orientationchange.select2.' + container.id;
+
+ var $watchers = this.$container.parents().filter(Utils.hasScroll);
+ $watchers.off(scrollEvent);
+
+ $(window).off(scrollEvent + ' ' + resizeEvent + ' ' + orientationEvent);
+ };
+
+ AttachBody.prototype._positionDropdown = function () {
+ var $window = $(window);
+
+ var isCurrentlyAbove = this.$dropdown.hasClass('select2-dropdown--above');
+ var isCurrentlyBelow = this.$dropdown.hasClass('select2-dropdown--below');
+
+ var newDirection = null;
+
+ var offset = this.$container.offset();
+
+ offset.bottom = offset.top + this.$container.outerHeight(false);
+
+ var container = {
+ height: this.$container.outerHeight(false)
+ };
+
+ container.top = offset.top;
+ container.bottom = offset.top + container.height;
+
+ var dropdown = {
+ height: this.$dropdown.outerHeight(false)
+ };
+
+ var viewport = {
+ top: $window.scrollTop(),
+ bottom: $window.scrollTop() + $window.height()
+ };
+
+ var enoughRoomAbove = viewport.top < (offset.top - dropdown.height);
+ var enoughRoomBelow = viewport.bottom > (offset.bottom + dropdown.height);
+
+ var css = {
+ left: offset.left,
+ top: container.bottom
+ };
+
+ // Determine what the parent element is to use for calciulating the offset
+ var $offsetParent = this.$dropdownParent;
+
+ // For statically positoned elements, we need to get the element
+ // that is determining the offset
+ if ($offsetParent.css('position') === 'static') {
+ $offsetParent = $offsetParent.offsetParent();
+ }
+
+ var parentOffset = $offsetParent.offset();
+
+ css.top -= parentOffset.top;
+ css.left -= parentOffset.left;
+
+ if (!isCurrentlyAbove && !isCurrentlyBelow) {
+ newDirection = 'below';
+ }
+
+ if (!enoughRoomBelow && enoughRoomAbove && !isCurrentlyAbove) {
+ newDirection = 'above';
+ } else if (!enoughRoomAbove && enoughRoomBelow && isCurrentlyAbove) {
+ newDirection = 'below';
+ }
+
+ if (newDirection == 'above' ||
+ (isCurrentlyAbove && newDirection !== 'below')) {
+ css.top = container.top - parentOffset.top - dropdown.height;
+ }
+
+ if (newDirection != null) {
+ this.$dropdown
+ .removeClass('select2-dropdown--below select2-dropdown--above')
+ .addClass('select2-dropdown--' + newDirection);
+ this.$container
+ .removeClass('select2-container--below select2-container--above')
+ .addClass('select2-container--' + newDirection);
+ }
+
+ this.$dropdownContainer.css(css);
+ };
+
+ AttachBody.prototype._resizeDropdown = function () {
+ var css = {
+ width: this.$container.outerWidth(false) + 'px'
+ };
+
+ if (this.options.get('dropdownAutoWidth')) {
+ css.minWidth = css.width;
+ css.position = 'relative';
+ css.width = 'auto';
+ }
+
+ this.$dropdown.css(css);
+ };
+
+ AttachBody.prototype._showDropdown = function (decorated) {
+ this.$dropdownContainer.appendTo(this.$dropdownParent);
+
+ this._positionDropdown();
+ this._resizeDropdown();
+ };
+
+ return AttachBody;
+});
+
+S2.define('select2/dropdown/minimumResultsForSearch',[
+
+], function () {
+ function countResults (data) {
+ var count = 0;
+
+ for (var d = 0; d < data.length; d++) {
+ var item = data[d];
+
+ if (item.children) {
+ count += countResults(item.children);
+ } else {
+ count++;
+ }
+ }
+
+ return count;
+ }
+
+ function MinimumResultsForSearch (decorated, $element, options, dataAdapter) {
+ this.minimumResultsForSearch = options.get('minimumResultsForSearch');
+
+ if (this.minimumResultsForSearch < 0) {
+ this.minimumResultsForSearch = Infinity;
+ }
+
+ decorated.call(this, $element, options, dataAdapter);
+ }
+
+ MinimumResultsForSearch.prototype.showSearch = function (decorated, params) {
+ if (countResults(params.data.results) < this.minimumResultsForSearch) {
+ return false;
+ }
+
+ return decorated.call(this, params);
+ };
+
+ return MinimumResultsForSearch;
+});
+
+S2.define('select2/dropdown/selectOnClose',[
+ '../utils'
+], function (Utils) {
+ function SelectOnClose () { }
+
+ SelectOnClose.prototype.bind = function (decorated, container, $container) {
+ var self = this;
+
+ decorated.call(this, container, $container);
+
+ container.on('close', function (params) {
+ self._handleSelectOnClose(params);
+ });
+ };
+
+ SelectOnClose.prototype._handleSelectOnClose = function (_, params) {
+ if (params && params.originalSelect2Event != null) {
+ var event = params.originalSelect2Event;
+
+ // Don't select an item if the close event was triggered from a select or
+ // unselect event
+ if (event._type === 'select' || event._type === 'unselect') {
+ return;
+ }
+ }
+
+ var $highlightedResults = this.getHighlightedResults();
+
+ // Only select highlighted results
+ if ($highlightedResults.length < 1) {
+ return;
+ }
+
+ var data = Utils.GetData($highlightedResults[0], 'data');
+
+ // Don't re-select already selected resulte
+ if (
+ (data.element != null && data.element.selected) ||
+ (data.element == null && data.selected)
+ ) {
+ return;
+ }
+
+ this.trigger('select', {
+ data: data
+ });
+ };
+
+ return SelectOnClose;
+});
+
+S2.define('select2/dropdown/closeOnSelect',[
+
+], function () {
+ function CloseOnSelect () { }
+
+ CloseOnSelect.prototype.bind = function (decorated, container, $container) {
+ var self = this;
+
+ decorated.call(this, container, $container);
+
+ container.on('select', function (evt) {
+ self._selectTriggered(evt);
+ });
+
+ container.on('unselect', function (evt) {
+ self._selectTriggered(evt);
+ });
+ };
+
+ CloseOnSelect.prototype._selectTriggered = function (_, evt) {
+ var originalEvent = evt.originalEvent;
+
+ // Don't close if the control key is being held
+ if (originalEvent && originalEvent.ctrlKey) {
+ return;
+ }
+
+ this.trigger('close', {
+ originalEvent: originalEvent,
+ originalSelect2Event: evt
+ });
+ };
+
+ return CloseOnSelect;
+});
+
+S2.define('select2/i18n/en',[],function () {
+ // English
+ return {
+ errorLoading: function () {
+ return 'The results could not be loaded.';
+ },
+ inputTooLong: function (args) {
+ var overChars = args.input.length - args.maximum;
+
+ var message = 'Please delete ' + overChars + ' character';
+
+ if (overChars != 1) {
+ message += 's';
+ }
+
+ return message;
+ },
+ inputTooShort: function (args) {
+ var remainingChars = args.minimum - args.input.length;
+
+ var message = 'Please enter ' + remainingChars + ' or more characters';
+
+ return message;
+ },
+ loadingMore: function () {
+ return 'Loading more results…';
+ },
+ maximumSelected: function (args) {
+ var message = 'You can only select ' + args.maximum + ' item';
+
+ if (args.maximum != 1) {
+ message += 's';
+ }
+
+ return message;
+ },
+ noResults: function () {
+ return 'No results found';
+ },
+ searching: function () {
+ return 'Searching…';
+ }
+ };
+});
+
+S2.define('select2/defaults',[
+ 'jquery',
+ 'require',
+
+ './results',
+
+ './selection/single',
+ './selection/multiple',
+ './selection/placeholder',
+ './selection/allowClear',
+ './selection/search',
+ './selection/eventRelay',
+
+ './utils',
+ './translation',
+ './diacritics',
+
+ './data/select',
+ './data/array',
+ './data/ajax',
+ './data/tags',
+ './data/tokenizer',
+ './data/minimumInputLength',
+ './data/maximumInputLength',
+ './data/maximumSelectionLength',
+
+ './dropdown',
+ './dropdown/search',
+ './dropdown/hidePlaceholder',
+ './dropdown/infiniteScroll',
+ './dropdown/attachBody',
+ './dropdown/minimumResultsForSearch',
+ './dropdown/selectOnClose',
+ './dropdown/closeOnSelect',
+
+ './i18n/en'
+], function ($, require,
+
+ ResultsList,
+
+ SingleSelection, MultipleSelection, Placeholder, AllowClear,
+ SelectionSearch, EventRelay,
+
+ Utils, Translation, DIACRITICS,
+
+ SelectData, ArrayData, AjaxData, Tags, Tokenizer,
+ MinimumInputLength, MaximumInputLength, MaximumSelectionLength,
+
+ Dropdown, DropdownSearch, HidePlaceholder, InfiniteScroll,
+ AttachBody, MinimumResultsForSearch, SelectOnClose, CloseOnSelect,
+
+ EnglishTranslation) {
+ function Defaults () {
+ this.reset();
+ }
+
+ Defaults.prototype.apply = function (options) {
+ options = $.extend(true, {}, this.defaults, options);
+
+ if (options.dataAdapter == null) {
+ if (options.ajax != null) {
+ options.dataAdapter = AjaxData;
+ } else if (options.data != null) {
+ options.dataAdapter = ArrayData;
+ } else {
+ options.dataAdapter = SelectData;
+ }
+
+ if (options.minimumInputLength > 0) {
+ options.dataAdapter = Utils.Decorate(
+ options.dataAdapter,
+ MinimumInputLength
+ );
+ }
+
+ if (options.maximumInputLength > 0) {
+ options.dataAdapter = Utils.Decorate(
+ options.dataAdapter,
+ MaximumInputLength
+ );
+ }
+
+ if (options.maximumSelectionLength > 0) {
+ options.dataAdapter = Utils.Decorate(
+ options.dataAdapter,
+ MaximumSelectionLength
+ );
+ }
+
+ if (options.tags) {
+ options.dataAdapter = Utils.Decorate(options.dataAdapter, Tags);
+ }
+
+ if (options.tokenSeparators != null || options.tokenizer != null) {
+ options.dataAdapter = Utils.Decorate(
+ options.dataAdapter,
+ Tokenizer
+ );
+ }
+
+ if (options.query != null) {
+ var Query = require(options.amdBase + 'compat/query');
+
+ options.dataAdapter = Utils.Decorate(
+ options.dataAdapter,
+ Query
+ );
+ }
+
+ if (options.initSelection != null) {
+ var InitSelection = require(options.amdBase + 'compat/initSelection');
+
+ options.dataAdapter = Utils.Decorate(
+ options.dataAdapter,
+ InitSelection
+ );
+ }
+ }
+
+ if (options.resultsAdapter == null) {
+ options.resultsAdapter = ResultsList;
+
+ if (options.ajax != null) {
+ options.resultsAdapter = Utils.Decorate(
+ options.resultsAdapter,
+ InfiniteScroll
+ );
+ }
+
+ if (options.placeholder != null) {
+ options.resultsAdapter = Utils.Decorate(
+ options.resultsAdapter,
+ HidePlaceholder
+ );
+ }
+
+ if (options.selectOnClose) {
+ options.resultsAdapter = Utils.Decorate(
+ options.resultsAdapter,
+ SelectOnClose
+ );
+ }
+ }
+
+ if (options.dropdownAdapter == null) {
+ if (options.multiple) {
+ options.dropdownAdapter = Dropdown;
+ } else {
+ var SearchableDropdown = Utils.Decorate(Dropdown, DropdownSearch);
+
+ options.dropdownAdapter = SearchableDropdown;
+ }
+
+ if (options.minimumResultsForSearch !== 0) {
+ options.dropdownAdapter = Utils.Decorate(
+ options.dropdownAdapter,
+ MinimumResultsForSearch
+ );
+ }
+
+ if (options.closeOnSelect) {
+ options.dropdownAdapter = Utils.Decorate(
+ options.dropdownAdapter,
+ CloseOnSelect
+ );
+ }
+
+ if (
+ options.dropdownCssClass != null ||
+ options.dropdownCss != null ||
+ options.adaptDropdownCssClass != null
+ ) {
+ var DropdownCSS = require(options.amdBase + 'compat/dropdownCss');
+
+ options.dropdownAdapter = Utils.Decorate(
+ options.dropdownAdapter,
+ DropdownCSS
+ );
+ }
+
+ options.dropdownAdapter = Utils.Decorate(
+ options.dropdownAdapter,
+ AttachBody
+ );
+ }
+
+ if (options.selectionAdapter == null) {
+ if (options.multiple) {
+ options.selectionAdapter = MultipleSelection;
+ } else {
+ options.selectionAdapter = SingleSelection;
+ }
+
+ // Add the placeholder mixin if a placeholder was specified
+ if (options.placeholder != null) {
+ options.selectionAdapter = Utils.Decorate(
+ options.selectionAdapter,
+ Placeholder
+ );
+ }
+
+ if (options.allowClear) {
+ options.selectionAdapter = Utils.Decorate(
+ options.selectionAdapter,
+ AllowClear
+ );
+ }
+
+ if (options.multiple) {
+ options.selectionAdapter = Utils.Decorate(
+ options.selectionAdapter,
+ SelectionSearch
+ );
+ }
+
+ if (
+ options.containerCssClass != null ||
+ options.containerCss != null ||
+ options.adaptContainerCssClass != null
+ ) {
+ var ContainerCSS = require(options.amdBase + 'compat/containerCss');
+
+ options.selectionAdapter = Utils.Decorate(
+ options.selectionAdapter,
+ ContainerCSS
+ );
+ }
+
+ options.selectionAdapter = Utils.Decorate(
+ options.selectionAdapter,
+ EventRelay
+ );
+ }
+
+ if (typeof options.language === 'string') {
+ // Check if the language is specified with a region
+ if (options.language.indexOf('-') > 0) {
+ // Extract the region information if it is included
+ var languageParts = options.language.split('-');
+ var baseLanguage = languageParts[0];
+
+ options.language = [options.language, baseLanguage];
+ } else {
+ options.language = [options.language];
+ }
+ }
+
+ if ($.isArray(options.language)) {
+ var languages = new Translation();
+ options.language.push('en');
+
+ var languageNames = options.language;
+
+ for (var l = 0; l < languageNames.length; l++) {
+ var name = languageNames[l];
+ var language = {};
+
+ try {
+ // Try to load it with the original name
+ language = Translation.loadPath(name);
+ } catch (e) {
+ try {
+ // If we couldn't load it, check if it wasn't the full path
+ name = this.defaults.amdLanguageBase + name;
+ language = Translation.loadPath(name);
+ } catch (ex) {
+ // The translation could not be loaded at all. Sometimes this is
+ // because of a configuration problem, other times this can be
+ // because of how Select2 helps load all possible translation files.
+ if (options.debug && window.console && console.warn) {
+ console.warn(
+ 'Select2: The language file for "' + name + '" could not be ' +
+ 'automatically loaded. A fallback will be used instead.'
+ );
+ }
+
+ continue;
+ }
+ }
+
+ languages.extend(language);
+ }
+
+ options.translations = languages;
+ } else {
+ var baseTranslation = Translation.loadPath(
+ this.defaults.amdLanguageBase + 'en'
+ );
+ var customTranslation = new Translation(options.language);
+
+ customTranslation.extend(baseTranslation);
+
+ options.translations = customTranslation;
+ }
+
+ return options;
+ };
+
+ Defaults.prototype.reset = function () {
+ function stripDiacritics (text) {
+ // Used 'uni range + named function' from http://jsperf.com/diacritics/18
+ function match(a) {
+ return DIACRITICS[a] || a;
+ }
+
+ return text.replace(/[^\u0000-\u007E]/g, match);
+ }
+
+ function matcher (params, data) {
+ // Always return the object if there is nothing to compare
+ if ($.trim(params.term) === '') {
+ return data;
+ }
+
+ // Do a recursive check for options with children
+ if (data.children && data.children.length > 0) {
+ // Clone the data object if there are children
+ // This is required as we modify the object to remove any non-matches
+ var match = $.extend(true, {}, data);
+
+ // Check each child of the option
+ for (var c = data.children.length - 1; c >= 0; c--) {
+ var child = data.children[c];
+
+ var matches = matcher(params, child);
+
+ // If there wasn't a match, remove the object in the array
+ if (matches == null) {
+ match.children.splice(c, 1);
+ }
+ }
+
+ // If any children matched, return the new object
+ if (match.children.length > 0) {
+ return match;
+ }
+
+ // If there were no matching children, check just the plain object
+ return matcher(params, match);
+ }
+
+ var original = stripDiacritics(data.text).toUpperCase();
+ var term = stripDiacritics(params.term).toUpperCase();
+
+ // Check if the text contains the term
+ if (original.indexOf(term) > -1) {
+ return data;
+ }
+
+ // If it doesn't contain the term, don't return anything
+ return null;
+ }
+
+ this.defaults = {
+ amdBase: './',
+ amdLanguageBase: './i18n/',
+ closeOnSelect: true,
+ debug: false,
+ dropdownAutoWidth: false,
+ escapeMarkup: Utils.escapeMarkup,
+ language: EnglishTranslation,
+ matcher: matcher,
+ minimumInputLength: 0,
+ maximumInputLength: 0,
+ maximumSelectionLength: 0,
+ minimumResultsForSearch: 0,
+ selectOnClose: false,
+ sorter: function (data) {
+ return data;
+ },
+ templateResult: function (result) {
+ return result.text;
+ },
+ templateSelection: function (selection) {
+ return selection.text;
+ },
+ theme: 'default',
+ width: 'resolve'
+ };
+ };
+
+ Defaults.prototype.set = function (key, value) {
+ var camelKey = $.camelCase(key);
+
+ var data = {};
+ data[camelKey] = value;
+
+ var convertedData = Utils._convertData(data);
+
+ $.extend(true, this.defaults, convertedData);
+ };
+
+ var defaults = new Defaults();
+
+ return defaults;
+});
+
+S2.define('select2/options',[
+ 'require',
+ 'jquery',
+ './defaults',
+ './utils'
+], function (require, $, Defaults, Utils) {
+ function Options (options, $element) {
+ this.options = options;
+
+ if ($element != null) {
+ this.fromElement($element);
+ }
+
+ this.options = Defaults.apply(this.options);
+
+ if ($element && $element.is('input')) {
+ var InputCompat = require(this.get('amdBase') + 'compat/inputData');
+
+ this.options.dataAdapter = Utils.Decorate(
+ this.options.dataAdapter,
+ InputCompat
+ );
+ }
+ }
+
+ Options.prototype.fromElement = function ($e) {
+ var excludedData = ['select2'];
+
+ if (this.options.multiple == null) {
+ this.options.multiple = $e.prop('multiple');
+ }
+
+ if (this.options.disabled == null) {
+ this.options.disabled = $e.prop('disabled');
+ }
+
+ if (this.options.language == null) {
+ if ($e.prop('lang')) {
+ this.options.language = $e.prop('lang').toLowerCase();
+ } else if ($e.closest('[lang]').prop('lang')) {
+ this.options.language = $e.closest('[lang]').prop('lang');
+ }
+ }
+
+ if (this.options.dir == null) {
+ if ($e.prop('dir')) {
+ this.options.dir = $e.prop('dir');
+ } else if ($e.closest('[dir]').prop('dir')) {
+ this.options.dir = $e.closest('[dir]').prop('dir');
+ } else {
+ this.options.dir = 'ltr';
+ }
+ }
+
+ $e.prop('disabled', this.options.disabled);
+ $e.prop('multiple', this.options.multiple);
+
+ if (Utils.GetData($e[0], 'select2Tags')) {
+ if (this.options.debug && window.console && console.warn) {
+ console.warn(
+ 'Select2: The `data-select2-tags` attribute has been changed to ' +
+ 'use the `data-data` and `data-tags="true"` attributes and will be ' +
+ 'removed in future versions of Select2.'
+ );
+ }
+
+ Utils.StoreData($e[0], 'data', Utils.GetData($e[0], 'select2Tags'));
+ Utils.StoreData($e[0], 'tags', true);
+ }
+
+ if (Utils.GetData($e[0], 'ajaxUrl')) {
+ if (this.options.debug && window.console && console.warn) {
+ console.warn(
+ 'Select2: The `data-ajax-url` attribute has been changed to ' +
+ '`data-ajax--url` and support for the old attribute will be removed' +
+ ' in future versions of Select2.'
+ );
+ }
+
+ $e.attr('ajax--url', Utils.GetData($e[0], 'ajaxUrl'));
+ Utils.StoreData($e[0], 'ajax-Url', Utils.GetData($e[0], 'ajaxUrl'));
+
+ }
+
+ var dataset = {};
+
+ // Prefer the element's `dataset` attribute if it exists
+ // jQuery 1.x does not correctly handle data attributes with multiple dashes
+ if ($.fn.jquery && $.fn.jquery.substr(0, 2) == '1.' && $e[0].dataset) {
+ dataset = $.extend(true, {}, $e[0].dataset, Utils.GetData($e[0]));
+ } else {
+ dataset = Utils.GetData($e[0]);
+ }
+
+ var data = $.extend(true, {}, dataset);
+
+ data = Utils._convertData(data);
+
+ for (var key in data) {
+ if ($.inArray(key, excludedData) > -1) {
+ continue;
+ }
+
+ if ($.isPlainObject(this.options[key])) {
+ $.extend(this.options[key], data[key]);
+ } else {
+ this.options[key] = data[key];
+ }
+ }
+
+ return this;
+ };
+
+ Options.prototype.get = function (key) {
+ return this.options[key];
+ };
+
+ Options.prototype.set = function (key, val) {
+ this.options[key] = val;
+ };
+
+ return Options;
+});
+
+S2.define('select2/core',[
+ 'jquery',
+ './options',
+ './utils',
+ './keys'
+], function ($, Options, Utils, KEYS) {
+ var Select2 = function ($element, options) {
+ if (Utils.GetData($element[0], 'select2') != null) {
+ Utils.GetData($element[0], 'select2').destroy();
+ }
+
+ this.$element = $element;
+
+ this.id = this._generateId($element);
+
+ options = options || {};
+
+ this.options = new Options(options, $element);
+
+ Select2.__super__.constructor.call(this);
+
+ // Set up the tabindex
+
+ var tabindex = $element.attr('tabindex') || 0;
+ Utils.StoreData($element[0], 'old-tabindex', tabindex);
+ $element.attr('tabindex', '-1');
+
+ // Set up containers and adapters
+
+ var DataAdapter = this.options.get('dataAdapter');
+ this.dataAdapter = new DataAdapter($element, this.options);
+
+ var $container = this.render();
+
+ this._placeContainer($container);
+
+ var SelectionAdapter = this.options.get('selectionAdapter');
+ this.selection = new SelectionAdapter($element, this.options);
+ this.$selection = this.selection.render();
+
+ this.selection.position(this.$selection, $container);
+
+ var DropdownAdapter = this.options.get('dropdownAdapter');
+ this.dropdown = new DropdownAdapter($element, this.options);
+ this.$dropdown = this.dropdown.render();
+
+ this.dropdown.position(this.$dropdown, $container);
+
+ var ResultsAdapter = this.options.get('resultsAdapter');
+ this.results = new ResultsAdapter($element, this.options, this.dataAdapter);
+ this.$results = this.results.render();
+
+ this.results.position(this.$results, this.$dropdown);
+
+ // Bind events
+
+ var self = this;
+
+ // Bind the container to all of the adapters
+ this._bindAdapters();
+
+ // Register any DOM event handlers
+ this._registerDomEvents();
+
+ // Register any internal event handlers
+ this._registerDataEvents();
+ this._registerSelectionEvents();
+ this._registerDropdownEvents();
+ this._registerResultsEvents();
+ this._registerEvents();
+
+ // Set the initial state
+ this.dataAdapter.current(function (initialData) {
+ self.trigger('selection:update', {
+ data: initialData
+ });
+ });
+
+ // Hide the original select
+ $element.addClass('select2-hidden-accessible');
+ $element.attr('aria-hidden', 'true');
+
+ // Synchronize any monitored attributes
+ this._syncAttributes();
+
+ Utils.StoreData($element[0], 'select2', this);
+
+ // Ensure backwards compatibility with $element.data('select2').
+ $element.data('select2', this);
+ };
+
+ Utils.Extend(Select2, Utils.Observable);
+
+ Select2.prototype._generateId = function ($element) {
+ var id = '';
+
+ if ($element.attr('id') != null) {
+ id = $element.attr('id');
+ } else if ($element.attr('name') != null) {
+ id = $element.attr('name') + '-' + Utils.generateChars(2);
+ } else {
+ id = Utils.generateChars(4);
+ }
+
+ id = id.replace(/(:|\.|\[|\]|,)/g, '');
+ id = 'select2-' + id;
+
+ return id;
+ };
+
+ Select2.prototype._placeContainer = function ($container) {
+ $container.insertAfter(this.$element);
+
+ var width = this._resolveWidth(this.$element, this.options.get('width'));
+
+ if (width != null) {
+ $container.css('width', width);
+ }
+ };
+
+ Select2.prototype._resolveWidth = function ($element, method) {
+ var WIDTH = /^width:(([-+]?([0-9]*\.)?[0-9]+)(px|em|ex|%|in|cm|mm|pt|pc))/i;
+
+ if (method == 'resolve') {
+ var styleWidth = this._resolveWidth($element, 'style');
+
+ if (styleWidth != null) {
+ return styleWidth;
+ }
+
+ return this._resolveWidth($element, 'element');
+ }
+
+ if (method == 'element') {
+ var elementWidth = $element.outerWidth(false);
+
+ if (elementWidth <= 0) {
+ return 'auto';
+ }
+
+ return elementWidth + 'px';
+ }
+
+ if (method == 'style') {
+ var style = $element.attr('style');
+
+ if (typeof(style) !== 'string') {
+ return null;
+ }
+
+ var attrs = style.split(';');
+
+ for (var i = 0, l = attrs.length; i < l; i = i + 1) {
+ var attr = attrs[i].replace(/\s/g, '');
+ var matches = attr.match(WIDTH);
+
+ if (matches !== null && matches.length >= 1) {
+ return matches[1];
+ }
+ }
+
+ return null;
+ }
+
+ return method;
+ };
+
+ Select2.prototype._bindAdapters = function () {
+ this.dataAdapter.bind(this, this.$container);
+ this.selection.bind(this, this.$container);
+
+ this.dropdown.bind(this, this.$container);
+ this.results.bind(this, this.$container);
+ };
+
+ Select2.prototype._registerDomEvents = function () {
+ var self = this;
+
+ this.$element.on('change.select2', function () {
+ self.dataAdapter.current(function (data) {
+ self.trigger('selection:update', {
+ data: data
+ });
+ });
+ });
+
+ this.$element.on('focus.select2', function (evt) {
+ self.trigger('focus', evt);
+ });
+
+ this._syncA = Utils.bind(this._syncAttributes, this);
+ this._syncS = Utils.bind(this._syncSubtree, this);
+
+ if (this.$element[0].attachEvent) {
+ this.$element[0].attachEvent('onpropertychange', this._syncA);
+ }
+
+ var observer = window.MutationObserver ||
+ window.WebKitMutationObserver ||
+ window.MozMutationObserver
+ ;
+
+ if (observer != null) {
+ this._observer = new observer(function (mutations) {
+ $.each(mutations, self._syncA);
+ $.each(mutations, self._syncS);
+ });
+ this._observer.observe(this.$element[0], {
+ attributes: true,
+ childList: true,
+ subtree: false
+ });
+ } else if (this.$element[0].addEventListener) {
+ this.$element[0].addEventListener(
+ 'DOMAttrModified',
+ self._syncA,
+ false
+ );
+ this.$element[0].addEventListener(
+ 'DOMNodeInserted',
+ self._syncS,
+ false
+ );
+ this.$element[0].addEventListener(
+ 'DOMNodeRemoved',
+ self._syncS,
+ false
+ );
+ }
+ };
+
+ Select2.prototype._registerDataEvents = function () {
+ var self = this;
+
+ this.dataAdapter.on('*', function (name, params) {
+ self.trigger(name, params);
+ });
+ };
+
+ Select2.prototype._registerSelectionEvents = function () {
+ var self = this;
+ var nonRelayEvents = ['toggle', 'focus'];
+
+ this.selection.on('toggle', function () {
+ self.toggleDropdown();
+ });
+
+ this.selection.on('focus', function (params) {
+ self.focus(params);
+ });
+
+ this.selection.on('*', function (name, params) {
+ if ($.inArray(name, nonRelayEvents) !== -1) {
+ return;
+ }
+
+ self.trigger(name, params);
+ });
+ };
+
+ Select2.prototype._registerDropdownEvents = function () {
+ var self = this;
+
+ this.dropdown.on('*', function (name, params) {
+ self.trigger(name, params);
+ });
+ };
+
+ Select2.prototype._registerResultsEvents = function () {
+ var self = this;
+
+ this.results.on('*', function (name, params) {
+ self.trigger(name, params);
+ });
+ };
+
+ Select2.prototype._registerEvents = function () {
+ var self = this;
+
+ this.on('open', function () {
+ self.$container.addClass('select2-container--open');
+ });
+
+ this.on('close', function () {
+ self.$container.removeClass('select2-container--open');
+ });
+
+ this.on('enable', function () {
+ self.$container.removeClass('select2-container--disabled');
+ });
+
+ this.on('disable', function () {
+ self.$container.addClass('select2-container--disabled');
+ });
+
+ this.on('blur', function () {
+ self.$container.removeClass('select2-container--focus');
+ });
+
+ this.on('query', function (params) {
+ if (!self.isOpen()) {
+ self.trigger('open', {});
+ }
+
+ this.dataAdapter.query(params, function (data) {
+ self.trigger('results:all', {
+ data: data,
+ query: params
+ });
+ });
+ });
+
+ this.on('query:append', function (params) {
+ this.dataAdapter.query(params, function (data) {
+ self.trigger('results:append', {
+ data: data,
+ query: params
+ });
+ });
+ });
+
+ this.on('keypress', function (evt) {
+ var key = evt.which;
+
+ if (self.isOpen()) {
+ if (key === KEYS.ESC || key === KEYS.TAB ||
+ (key === KEYS.UP && evt.altKey)) {
+ self.close();
+
+ evt.preventDefault();
+ } else if (key === KEYS.ENTER) {
+ self.trigger('results:select', {});
+
+ evt.preventDefault();
+ } else if ((key === KEYS.SPACE && evt.ctrlKey)) {
+ self.trigger('results:toggle', {});
+
+ evt.preventDefault();
+ } else if (key === KEYS.UP) {
+ self.trigger('results:previous', {});
+
+ evt.preventDefault();
+ } else if (key === KEYS.DOWN) {
+ self.trigger('results:next', {});
+
+ evt.preventDefault();
+ }
+ } else {
+ if (key === KEYS.ENTER || key === KEYS.SPACE ||
+ (key === KEYS.DOWN && evt.altKey)) {
+ self.open();
+
+ evt.preventDefault();
+ }
+ }
+ });
+ };
+
+ Select2.prototype._syncAttributes = function () {
+ this.options.set('disabled', this.$element.prop('disabled'));
+
+ if (this.options.get('disabled')) {
+ if (this.isOpen()) {
+ this.close();
+ }
+
+ this.trigger('disable', {});
+ } else {
+ this.trigger('enable', {});
+ }
+ };
+
+ Select2.prototype._syncSubtree = function (evt, mutations) {
+ var changed = false;
+ var self = this;
+
+ // Ignore any mutation events raised for elements that aren't options or
+ // optgroups. This handles the case when the select element is destroyed
+ if (
+ evt && evt.target && (
+ evt.target.nodeName !== 'OPTION' && evt.target.nodeName !== 'OPTGROUP'
+ )
+ ) {
+ return;
+ }
+
+ if (!mutations) {
+ // If mutation events aren't supported, then we can only assume that the
+ // change affected the selections
+ changed = true;
+ } else if (mutations.addedNodes && mutations.addedNodes.length > 0) {
+ for (var n = 0; n < mutations.addedNodes.length; n++) {
+ var node = mutations.addedNodes[n];
+
+ if (node.selected) {
+ changed = true;
+ }
+ }
+ } else if (mutations.removedNodes && mutations.removedNodes.length > 0) {
+ changed = true;
+ }
+
+ // Only re-pull the data if we think there is a change
+ if (changed) {
+ this.dataAdapter.current(function (currentData) {
+ self.trigger('selection:update', {
+ data: currentData
+ });
+ });
+ }
+ };
+
+ /**
+ * Override the trigger method to automatically trigger pre-events when
+ * there are events that can be prevented.
+ */
+ Select2.prototype.trigger = function (name, args) {
+ var actualTrigger = Select2.__super__.trigger;
+ var preTriggerMap = {
+ 'open': 'opening',
+ 'close': 'closing',
+ 'select': 'selecting',
+ 'unselect': 'unselecting',
+ 'clear': 'clearing'
+ };
+
+ if (args === undefined) {
+ args = {};
+ }
+
+ if (name in preTriggerMap) {
+ var preTriggerName = preTriggerMap[name];
+ var preTriggerArgs = {
+ prevented: false,
+ name: name,
+ args: args
+ };
+
+ actualTrigger.call(this, preTriggerName, preTriggerArgs);
+
+ if (preTriggerArgs.prevented) {
+ args.prevented = true;
+
+ return;
+ }
+ }
+
+ actualTrigger.call(this, name, args);
+ };
+
+ Select2.prototype.toggleDropdown = function () {
+ if (this.options.get('disabled')) {
+ return;
+ }
+
+ if (this.isOpen()) {
+ this.close();
+ } else {
+ this.open();
+ }
+ };
+
+ Select2.prototype.open = function () {
+ if (this.isOpen()) {
+ return;
+ }
+
+ this.trigger('query', {});
+ };
+
+ Select2.prototype.close = function () {
+ if (!this.isOpen()) {
+ return;
+ }
+
+ this.trigger('close', {});
+ };
+
+ Select2.prototype.isOpen = function () {
+ return this.$container.hasClass('select2-container--open');
+ };
+
+ Select2.prototype.hasFocus = function () {
+ return this.$container.hasClass('select2-container--focus');
+ };
+
+ Select2.prototype.focus = function (data) {
+ // No need to re-trigger focus events if we are already focused
+ if (this.hasFocus()) {
+ return;
+ }
+
+ this.$container.addClass('select2-container--focus');
+ this.trigger('focus', {});
+ };
+
+ Select2.prototype.enable = function (args) {
+ if (this.options.get('debug') && window.console && console.warn) {
+ console.warn(
+ 'Select2: The `select2("enable")` method has been deprecated and will' +
+ ' be removed in later Select2 versions. Use $element.prop("disabled")' +
+ ' instead.'
+ );
+ }
+
+ if (args == null || args.length === 0) {
+ args = [true];
+ }
+
+ var disabled = !args[0];
+
+ this.$element.prop('disabled', disabled);
+ };
+
+ Select2.prototype.data = function () {
+ if (this.options.get('debug') &&
+ arguments.length > 0 && window.console && console.warn) {
+ console.warn(
+ 'Select2: Data can no longer be set using `select2("data")`. You ' +
+ 'should consider setting the value instead using `$element.val()`.'
+ );
+ }
+
+ var data = [];
+
+ this.dataAdapter.current(function (currentData) {
+ data = currentData;
+ });
+
+ return data;
+ };
+
+ Select2.prototype.val = function (args) {
+ if (this.options.get('debug') && window.console && console.warn) {
+ console.warn(
+ 'Select2: The `select2("val")` method has been deprecated and will be' +
+ ' removed in later Select2 versions. Use $element.val() instead.'
+ );
+ }
+
+ if (args == null || args.length === 0) {
+ return this.$element.val();
+ }
+
+ var newVal = args[0];
+
+ if ($.isArray(newVal)) {
+ newVal = $.map(newVal, function (obj) {
+ return obj.toString();
+ });
+ }
+
+ this.$element.val(newVal).trigger('change');
+ };
+
+ Select2.prototype.destroy = function () {
+ this.$container.remove();
+
+ if (this.$element[0].detachEvent) {
+ this.$element[0].detachEvent('onpropertychange', this._syncA);
+ }
+
+ if (this._observer != null) {
+ this._observer.disconnect();
+ this._observer = null;
+ } else if (this.$element[0].removeEventListener) {
+ this.$element[0]
+ .removeEventListener('DOMAttrModified', this._syncA, false);
+ this.$element[0]
+ .removeEventListener('DOMNodeInserted', this._syncS, false);
+ this.$element[0]
+ .removeEventListener('DOMNodeRemoved', this._syncS, false);
+ }
+
+ this._syncA = null;
+ this._syncS = null;
+
+ this.$element.off('.select2');
+ this.$element.attr('tabindex',
+ Utils.GetData(this.$element[0], 'old-tabindex'));
+
+ this.$element.removeClass('select2-hidden-accessible');
+ this.$element.attr('aria-hidden', 'false');
+ Utils.RemoveData(this.$element[0]);
+ this.$element.removeData('select2');
+
+ this.dataAdapter.destroy();
+ this.selection.destroy();
+ this.dropdown.destroy();
+ this.results.destroy();
+
+ this.dataAdapter = null;
+ this.selection = null;
+ this.dropdown = null;
+ this.results = null;
+ };
+
+ Select2.prototype.render = function () {
+ var $container = $(
+ '' +
+ ' ' +
+ ' ' +
+ ' '
+ );
+
+ $container.attr('dir', this.options.get('dir'));
+
+ this.$container = $container;
+
+ this.$container.addClass('select2-container--' + this.options.get('theme'));
+
+ Utils.StoreData($container[0], 'element', this.$element);
+
+ return $container;
+ };
+
+ return Select2;
+});
+
+S2.define('select2/compat/utils',[
+ 'jquery'
+], function ($) {
+ function syncCssClasses ($dest, $src, adapter) {
+ var classes, replacements = [], adapted;
+
+ classes = $.trim($dest.attr('class'));
+
+ if (classes) {
+ classes = '' + classes; // for IE which returns object
+
+ $(classes.split(/\s+/)).each(function () {
+ // Save all Select2 classes
+ if (this.indexOf('select2-') === 0) {
+ replacements.push(this);
+ }
+ });
+ }
+
+ classes = $.trim($src.attr('class'));
+
+ if (classes) {
+ classes = '' + classes; // for IE which returns object
+
+ $(classes.split(/\s+/)).each(function () {
+ // Only adapt non-Select2 classes
+ if (this.indexOf('select2-') !== 0) {
+ adapted = adapter(this);
+
+ if (adapted != null) {
+ replacements.push(adapted);
+ }
+ }
+ });
+ }
+
+ $dest.attr('class', replacements.join(' '));
+ }
+
+ return {
+ syncCssClasses: syncCssClasses
+ };
+});
+
+S2.define('select2/compat/containerCss',[
+ 'jquery',
+ './utils'
+], function ($, CompatUtils) {
+ // No-op CSS adapter that discards all classes by default
+ function _containerAdapter (clazz) {
+ return null;
+ }
+
+ function ContainerCSS () { }
+
+ ContainerCSS.prototype.render = function (decorated) {
+ var $container = decorated.call(this);
+
+ var containerCssClass = this.options.get('containerCssClass') || '';
+
+ if ($.isFunction(containerCssClass)) {
+ containerCssClass = containerCssClass(this.$element);
+ }
+
+ var containerCssAdapter = this.options.get('adaptContainerCssClass');
+ containerCssAdapter = containerCssAdapter || _containerAdapter;
+
+ if (containerCssClass.indexOf(':all:') !== -1) {
+ containerCssClass = containerCssClass.replace(':all:', '');
+
+ var _cssAdapter = containerCssAdapter;
+
+ containerCssAdapter = function (clazz) {
+ var adapted = _cssAdapter(clazz);
+
+ if (adapted != null) {
+ // Append the old one along with the adapted one
+ return adapted + ' ' + clazz;
+ }
+
+ return clazz;
+ };
+ }
+
+ var containerCss = this.options.get('containerCss') || {};
+
+ if ($.isFunction(containerCss)) {
+ containerCss = containerCss(this.$element);
+ }
+
+ CompatUtils.syncCssClasses($container, this.$element, containerCssAdapter);
+
+ $container.css(containerCss);
+ $container.addClass(containerCssClass);
+
+ return $container;
+ };
+
+ return ContainerCSS;
+});
+
+S2.define('select2/compat/dropdownCss',[
+ 'jquery',
+ './utils'
+], function ($, CompatUtils) {
+ // No-op CSS adapter that discards all classes by default
+ function _dropdownAdapter (clazz) {
+ return null;
+ }
+
+ function DropdownCSS () { }
+
+ DropdownCSS.prototype.render = function (decorated) {
+ var $dropdown = decorated.call(this);
+
+ var dropdownCssClass = this.options.get('dropdownCssClass') || '';
+
+ if ($.isFunction(dropdownCssClass)) {
+ dropdownCssClass = dropdownCssClass(this.$element);
+ }
+
+ var dropdownCssAdapter = this.options.get('adaptDropdownCssClass');
+ dropdownCssAdapter = dropdownCssAdapter || _dropdownAdapter;
+
+ if (dropdownCssClass.indexOf(':all:') !== -1) {
+ dropdownCssClass = dropdownCssClass.replace(':all:', '');
+
+ var _cssAdapter = dropdownCssAdapter;
+
+ dropdownCssAdapter = function (clazz) {
+ var adapted = _cssAdapter(clazz);
+
+ if (adapted != null) {
+ // Append the old one along with the adapted one
+ return adapted + ' ' + clazz;
+ }
+
+ return clazz;
+ };
+ }
+
+ var dropdownCss = this.options.get('dropdownCss') || {};
+
+ if ($.isFunction(dropdownCss)) {
+ dropdownCss = dropdownCss(this.$element);
+ }
+
+ CompatUtils.syncCssClasses($dropdown, this.$element, dropdownCssAdapter);
+
+ $dropdown.css(dropdownCss);
+ $dropdown.addClass(dropdownCssClass);
+
+ return $dropdown;
+ };
+
+ return DropdownCSS;
+});
+
+S2.define('select2/compat/initSelection',[
+ 'jquery'
+], function ($) {
+ function InitSelection (decorated, $element, options) {
+ if (options.get('debug') && window.console && console.warn) {
+ console.warn(
+ 'Select2: The `initSelection` option has been deprecated in favor' +
+ ' of a custom data adapter that overrides the `current` method. ' +
+ 'This method is now called multiple times instead of a single ' +
+ 'time when the instance is initialized. Support will be removed ' +
+ 'for the `initSelection` option in future versions of Select2'
+ );
+ }
+
+ this.initSelection = options.get('initSelection');
+ this._isInitialized = false;
+
+ decorated.call(this, $element, options);
+ }
+
+ InitSelection.prototype.current = function (decorated, callback) {
+ var self = this;
+
+ if (this._isInitialized) {
+ decorated.call(this, callback);
+
+ return;
+ }
+
+ this.initSelection.call(null, this.$element, function (data) {
+ self._isInitialized = true;
+
+ if (!$.isArray(data)) {
+ data = [data];
+ }
+
+ callback(data);
+ });
+ };
+
+ return InitSelection;
+});
+
+S2.define('select2/compat/inputData',[
+ 'jquery',
+ '../utils'
+], function ($, Utils) {
+ function InputData (decorated, $element, options) {
+ this._currentData = [];
+ this._valueSeparator = options.get('valueSeparator') || ',';
+
+ if ($element.prop('type') === 'hidden') {
+ if (options.get('debug') && console && console.warn) {
+ console.warn(
+ 'Select2: Using a hidden input with Select2 is no longer ' +
+ 'supported and may stop working in the future. It is recommended ' +
+ 'to use a `` element instead.'
+ );
+ }
+ }
+
+ decorated.call(this, $element, options);
+ }
+
+ InputData.prototype.current = function (_, callback) {
+ function getSelected (data, selectedIds) {
+ var selected = [];
+
+ if (data.selected || $.inArray(data.id, selectedIds) !== -1) {
+ data.selected = true;
+ selected.push(data);
+ } else {
+ data.selected = false;
+ }
+
+ if (data.children) {
+ selected.push.apply(selected, getSelected(data.children, selectedIds));
+ }
+
+ return selected;
+ }
+
+ var selected = [];
+
+ for (var d = 0; d < this._currentData.length; d++) {
+ var data = this._currentData[d];
+
+ selected.push.apply(
+ selected,
+ getSelected(
+ data,
+ this.$element.val().split(
+ this._valueSeparator
+ )
+ )
+ );
+ }
+
+ callback(selected);
+ };
+
+ InputData.prototype.select = function (_, data) {
+ if (!this.options.get('multiple')) {
+ this.current(function (allData) {
+ $.map(allData, function (data) {
+ data.selected = false;
+ });
+ });
+
+ this.$element.val(data.id);
+ this.$element.trigger('change');
+ } else {
+ var value = this.$element.val();
+ value += this._valueSeparator + data.id;
+
+ this.$element.val(value);
+ this.$element.trigger('change');
+ }
+ };
+
+ InputData.prototype.unselect = function (_, data) {
+ var self = this;
+
+ data.selected = false;
+
+ this.current(function (allData) {
+ var values = [];
+
+ for (var d = 0; d < allData.length; d++) {
+ var item = allData[d];
+
+ if (data.id == item.id) {
+ continue;
+ }
+
+ values.push(item.id);
+ }
+
+ self.$element.val(values.join(self._valueSeparator));
+ self.$element.trigger('change');
+ });
+ };
+
+ InputData.prototype.query = function (_, params, callback) {
+ var results = [];
+
+ for (var d = 0; d < this._currentData.length; d++) {
+ var data = this._currentData[d];
+
+ var matches = this.matches(params, data);
+
+ if (matches !== null) {
+ results.push(matches);
+ }
+ }
+
+ callback({
+ results: results
+ });
+ };
+
+ InputData.prototype.addOptions = function (_, $options) {
+ var options = $.map($options, function ($option) {
+ return Utils.GetData($option[0], 'data');
+ });
+
+ this._currentData.push.apply(this._currentData, options);
+ };
+
+ return InputData;
+});
+
+S2.define('select2/compat/matcher',[
+ 'jquery'
+], function ($) {
+ function oldMatcher (matcher) {
+ function wrappedMatcher (params, data) {
+ var match = $.extend(true, {}, data);
+
+ if (params.term == null || $.trim(params.term) === '') {
+ return match;
+ }
+
+ if (data.children) {
+ for (var c = data.children.length - 1; c >= 0; c--) {
+ var child = data.children[c];
+
+ // Check if the child object matches
+ // The old matcher returned a boolean true or false
+ var doesMatch = matcher(params.term, child.text, child);
+
+ // If the child didn't match, pop it off
+ if (!doesMatch) {
+ match.children.splice(c, 1);
+ }
+ }
+
+ if (match.children.length > 0) {
+ return match;
+ }
+ }
+
+ if (matcher(params.term, data.text, data)) {
+ return match;
+ }
+
+ return null;
+ }
+
+ return wrappedMatcher;
+ }
+
+ return oldMatcher;
+});
+
+S2.define('select2/compat/query',[
+
+], function () {
+ function Query (decorated, $element, options) {
+ if (options.get('debug') && window.console && console.warn) {
+ console.warn(
+ 'Select2: The `query` option has been deprecated in favor of a ' +
+ 'custom data adapter that overrides the `query` method. Support ' +
+ 'will be removed for the `query` option in future versions of ' +
+ 'Select2.'
+ );
+ }
+
+ decorated.call(this, $element, options);
+ }
+
+ Query.prototype.query = function (_, params, callback) {
+ params.callback = callback;
+
+ var query = this.options.get('query');
+
+ query.call(null, params);
+ };
+
+ return Query;
+});
+
+S2.define('select2/dropdown/attachContainer',[
+
+], function () {
+ function AttachContainer (decorated, $element, options) {
+ decorated.call(this, $element, options);
+ }
+
+ AttachContainer.prototype.position =
+ function (decorated, $dropdown, $container) {
+ var $dropdownContainer = $container.find('.dropdown-wrapper');
+ $dropdownContainer.append($dropdown);
+
+ $dropdown.addClass('select2-dropdown--below');
+ $container.addClass('select2-container--below');
+ };
+
+ return AttachContainer;
+});
+
+S2.define('select2/dropdown/stopPropagation',[
+
+], function () {
+ function StopPropagation () { }
+
+ StopPropagation.prototype.bind = function (decorated, container, $container) {
+ decorated.call(this, container, $container);
+
+ var stoppedEvents = [
+ 'blur',
+ 'change',
+ 'click',
+ 'dblclick',
+ 'focus',
+ 'focusin',
+ 'focusout',
+ 'input',
+ 'keydown',
+ 'keyup',
+ 'keypress',
+ 'mousedown',
+ 'mouseenter',
+ 'mouseleave',
+ 'mousemove',
+ 'mouseover',
+ 'mouseup',
+ 'search',
+ 'touchend',
+ 'touchstart'
+ ];
+
+ this.$dropdown.on(stoppedEvents.join(' '), function (evt) {
+ evt.stopPropagation();
+ });
+ };
+
+ return StopPropagation;
+});
+
+S2.define('select2/selection/stopPropagation',[
+
+], function () {
+ function StopPropagation () { }
+
+ StopPropagation.prototype.bind = function (decorated, container, $container) {
+ decorated.call(this, container, $container);
+
+ var stoppedEvents = [
+ 'blur',
+ 'change',
+ 'click',
+ 'dblclick',
+ 'focus',
+ 'focusin',
+ 'focusout',
+ 'input',
+ 'keydown',
+ 'keyup',
+ 'keypress',
+ 'mousedown',
+ 'mouseenter',
+ 'mouseleave',
+ 'mousemove',
+ 'mouseover',
+ 'mouseup',
+ 'search',
+ 'touchend',
+ 'touchstart'
+ ];
+
+ this.$selection.on(stoppedEvents.join(' '), function (evt) {
+ evt.stopPropagation();
+ });
+ };
+
+ return StopPropagation;
+});
+
+/*!
+ * jQuery Mousewheel 3.1.13
+ *
+ * Copyright jQuery Foundation and other contributors
+ * Released under the MIT license
+ * http://jquery.org/license
+ */
+
+(function (factory) {
+ if ( typeof S2.define === 'function' && S2.define.amd ) {
+ // AMD. Register as an anonymous module.
+ S2.define('jquery-mousewheel',['jquery'], factory);
+ } else if (typeof exports === 'object') {
+ // Node/CommonJS style for Browserify
+ module.exports = factory;
+ } else {
+ // Browser globals
+ factory(jQuery);
+ }
+}(function ($) {
+
+ var toFix = ['wheel', 'mousewheel', 'DOMMouseScroll', 'MozMousePixelScroll'],
+ toBind = ( 'onwheel' in document || document.documentMode >= 9 ) ?
+ ['wheel'] : ['mousewheel', 'DomMouseScroll', 'MozMousePixelScroll'],
+ slice = Array.prototype.slice,
+ nullLowestDeltaTimeout, lowestDelta;
+
+ if ( $.event.fixHooks ) {
+ for ( var i = toFix.length; i; ) {
+ $.event.fixHooks[ toFix[--i] ] = $.event.mouseHooks;
+ }
+ }
+
+ var special = $.event.special.mousewheel = {
+ version: '3.1.12',
+
+ setup: function() {
+ if ( this.addEventListener ) {
+ for ( var i = toBind.length; i; ) {
+ this.addEventListener( toBind[--i], handler, false );
+ }
+ } else {
+ this.onmousewheel = handler;
+ }
+ // Store the line height and page height for this particular element
+ $.data(this, 'mousewheel-line-height', special.getLineHeight(this));
+ $.data(this, 'mousewheel-page-height', special.getPageHeight(this));
+ },
+
+ teardown: function() {
+ if ( this.removeEventListener ) {
+ for ( var i = toBind.length; i; ) {
+ this.removeEventListener( toBind[--i], handler, false );
+ }
+ } else {
+ this.onmousewheel = null;
+ }
+ // Clean up the data we added to the element
+ $.removeData(this, 'mousewheel-line-height');
+ $.removeData(this, 'mousewheel-page-height');
+ },
+
+ getLineHeight: function(elem) {
+ var $elem = $(elem),
+ $parent = $elem['offsetParent' in $.fn ? 'offsetParent' : 'parent']();
+ if (!$parent.length) {
+ $parent = $('body');
+ }
+ return parseInt($parent.css('fontSize'), 10) || parseInt($elem.css('fontSize'), 10) || 16;
+ },
+
+ getPageHeight: function(elem) {
+ return $(elem).height();
+ },
+
+ settings: {
+ adjustOldDeltas: true, // see shouldAdjustOldDeltas() below
+ normalizeOffset: true // calls getBoundingClientRect for each event
+ }
+ };
+
+ $.fn.extend({
+ mousewheel: function(fn) {
+ return fn ? this.bind('mousewheel', fn) : this.trigger('mousewheel');
+ },
+
+ unmousewheel: function(fn) {
+ return this.unbind('mousewheel', fn);
+ }
+ });
+
+
+ function handler(event) {
+ var orgEvent = event || window.event,
+ args = slice.call(arguments, 1),
+ delta = 0,
+ deltaX = 0,
+ deltaY = 0,
+ absDelta = 0,
+ offsetX = 0,
+ offsetY = 0;
+ event = $.event.fix(orgEvent);
+ event.type = 'mousewheel';
+
+ // Old school scrollwheel delta
+ if ( 'detail' in orgEvent ) { deltaY = orgEvent.detail * -1; }
+ if ( 'wheelDelta' in orgEvent ) { deltaY = orgEvent.wheelDelta; }
+ if ( 'wheelDeltaY' in orgEvent ) { deltaY = orgEvent.wheelDeltaY; }
+ if ( 'wheelDeltaX' in orgEvent ) { deltaX = orgEvent.wheelDeltaX * -1; }
+
+ // Firefox < 17 horizontal scrolling related to DOMMouseScroll event
+ if ( 'axis' in orgEvent && orgEvent.axis === orgEvent.HORIZONTAL_AXIS ) {
+ deltaX = deltaY * -1;
+ deltaY = 0;
+ }
+
+ // Set delta to be deltaY or deltaX if deltaY is 0 for backwards compatabilitiy
+ delta = deltaY === 0 ? deltaX : deltaY;
+
+ // New school wheel delta (wheel event)
+ if ( 'deltaY' in orgEvent ) {
+ deltaY = orgEvent.deltaY * -1;
+ delta = deltaY;
+ }
+ if ( 'deltaX' in orgEvent ) {
+ deltaX = orgEvent.deltaX;
+ if ( deltaY === 0 ) { delta = deltaX * -1; }
+ }
+
+ // No change actually happened, no reason to go any further
+ if ( deltaY === 0 && deltaX === 0 ) { return; }
+
+ // Need to convert lines and pages to pixels if we aren't already in pixels
+ // There are three delta modes:
+ // * deltaMode 0 is by pixels, nothing to do
+ // * deltaMode 1 is by lines
+ // * deltaMode 2 is by pages
+ if ( orgEvent.deltaMode === 1 ) {
+ var lineHeight = $.data(this, 'mousewheel-line-height');
+ delta *= lineHeight;
+ deltaY *= lineHeight;
+ deltaX *= lineHeight;
+ } else if ( orgEvent.deltaMode === 2 ) {
+ var pageHeight = $.data(this, 'mousewheel-page-height');
+ delta *= pageHeight;
+ deltaY *= pageHeight;
+ deltaX *= pageHeight;
+ }
+
+ // Store lowest absolute delta to normalize the delta values
+ absDelta = Math.max( Math.abs(deltaY), Math.abs(deltaX) );
+
+ if ( !lowestDelta || absDelta < lowestDelta ) {
+ lowestDelta = absDelta;
+
+ // Adjust older deltas if necessary
+ if ( shouldAdjustOldDeltas(orgEvent, absDelta) ) {
+ lowestDelta /= 40;
+ }
+ }
+
+ // Adjust older deltas if necessary
+ if ( shouldAdjustOldDeltas(orgEvent, absDelta) ) {
+ // Divide all the things by 40!
+ delta /= 40;
+ deltaX /= 40;
+ deltaY /= 40;
+ }
+
+ // Get a whole, normalized value for the deltas
+ delta = Math[ delta >= 1 ? 'floor' : 'ceil' ](delta / lowestDelta);
+ deltaX = Math[ deltaX >= 1 ? 'floor' : 'ceil' ](deltaX / lowestDelta);
+ deltaY = Math[ deltaY >= 1 ? 'floor' : 'ceil' ](deltaY / lowestDelta);
+
+ // Normalise offsetX and offsetY properties
+ if ( special.settings.normalizeOffset && this.getBoundingClientRect ) {
+ var boundingRect = this.getBoundingClientRect();
+ offsetX = event.clientX - boundingRect.left;
+ offsetY = event.clientY - boundingRect.top;
+ }
+
+ // Add information to the event object
+ event.deltaX = deltaX;
+ event.deltaY = deltaY;
+ event.deltaFactor = lowestDelta;
+ event.offsetX = offsetX;
+ event.offsetY = offsetY;
+ // Go ahead and set deltaMode to 0 since we converted to pixels
+ // Although this is a little odd since we overwrite the deltaX/Y
+ // properties with normalized deltas.
+ event.deltaMode = 0;
+
+ // Add event and delta to the front of the arguments
+ args.unshift(event, delta, deltaX, deltaY);
+
+ // Clearout lowestDelta after sometime to better
+ // handle multiple device types that give different
+ // a different lowestDelta
+ // Ex: trackpad = 3 and mouse wheel = 120
+ if (nullLowestDeltaTimeout) { clearTimeout(nullLowestDeltaTimeout); }
+ nullLowestDeltaTimeout = setTimeout(nullLowestDelta, 200);
+
+ return ($.event.dispatch || $.event.handle).apply(this, args);
+ }
+
+ function nullLowestDelta() {
+ lowestDelta = null;
+ }
+
+ function shouldAdjustOldDeltas(orgEvent, absDelta) {
+ // If this is an older event and the delta is divisable by 120,
+ // then we are assuming that the browser is treating this as an
+ // older mouse wheel event and that we should divide the deltas
+ // by 40 to try and get a more usable deltaFactor.
+ // Side note, this actually impacts the reported scroll distance
+ // in older browsers and can cause scrolling to be slower than native.
+ // Turn this off by setting $.event.special.mousewheel.settings.adjustOldDeltas to false.
+ return special.settings.adjustOldDeltas && orgEvent.type === 'mousewheel' && absDelta % 120 === 0;
+ }
+
+}));
+
+S2.define('jquery.select2',[
+ 'jquery',
+ 'jquery-mousewheel',
+
+ './select2/core',
+ './select2/defaults',
+ './select2/utils'
+], function ($, _, Select2, Defaults, Utils) {
+ if ($.fn.select2 == null) {
+ // All methods that should return the element
+ var thisMethods = ['open', 'close', 'destroy'];
+
+ $.fn.select2 = function (options) {
+ options = options || {};
+
+ if (typeof options === 'object') {
+ this.each(function () {
+ var instanceOptions = $.extend(true, {}, options);
+
+ var instance = new Select2($(this), instanceOptions);
+ });
+
+ return this;
+ } else if (typeof options === 'string') {
+ var ret;
+ var args = Array.prototype.slice.call(arguments, 1);
+
+ this.each(function () {
+ var instance = Utils.GetData(this, 'select2');
+
+ if (instance == null && window.console && console.error) {
+ console.error(
+ 'The select2(\'' + options + '\') method was called on an ' +
+ 'element that is not using Select2.'
+ );
+ }
+
+ ret = instance[options].apply(instance, args);
+ });
+
+ // Check if we should be returning `this`
+ if ($.inArray(options, thisMethods) > -1) {
+ return this;
+ }
+
+ return ret;
+ } else {
+ throw new Error('Invalid arguments for Select2: ' + options);
+ }
+ };
+ }
+
+ if ($.fn.select2.defaults == null) {
+ $.fn.select2.defaults = Defaults;
+ }
+
+ return Select2;
+});
+
+ // Return the AMD loader configuration so it can be used outside of this file
+ return {
+ define: S2.define,
+ require: S2.require
+ };
+}());
+
+ // Autoload the jQuery bindings
+ // We know that all of the modules exist above this, so we're safe
+ var select2 = S2.require('jquery.select2');
+
+ // Hold the AMD module references on the jQuery function that was just loaded
+ // This allows Select2 to use the internal loader outside of this file, such
+ // as in the language files.
+ jQuery.fn.select2.amd = S2;
+
+ // Return the Select2 instance for anyone who is importing it.
+ return select2;
+}));
diff --git a/AdminPanel/client/src/pages/AiIntegration/ai/vendor/select2-4.0.6-rc.1/dist/js/select2.full.min.js b/AdminPanel/client/src/pages/AiIntegration/ai/vendor/select2-4.0.6-rc.1/dist/js/select2.full.min.js
new file mode 100644
index 0000000000..b64efebe76
--- /dev/null
+++ b/AdminPanel/client/src/pages/AiIntegration/ai/vendor/select2-4.0.6-rc.1/dist/js/select2.full.min.js
@@ -0,0 +1 @@
+/*! Select2 4.0.6-rc.1 | https://github.com/select2/select2/blob/master/LICENSE.md */!function(a){"function"==typeof define&&define.amd?define(["jquery"],a):"object"==typeof module&&module.exports?module.exports=function(b,c){return void 0===c&&(c="undefined"!=typeof window?require("jquery"):require("jquery")(b)),a(c),c}:a(jQuery)}(function(a){var b=function(){if(a&&a.fn&&a.fn.select2&&a.fn.select2.amd)var b=a.fn.select2.amd;var b;return function(){if(!b||!b.requirejs){b?c=b:b={};var a,c,d;!function(b){function e(a,b){return v.call(a,b)}function f(a,b){var c,d,e,f,g,h,i,j,k,l,m,n,o=b&&b.split("/"),p=t.map,q=p&&p["*"]||{};if(a){for(a=a.split("/"),g=a.length-1,t.nodeIdCompat&&x.test(a[g])&&(a[g]=a[g].replace(x,"")),"."===a[0].charAt(0)&&o&&(n=o.slice(0,o.length-1),a=n.concat(a)),k=0;k0&&(a.splice(k-1,2),k-=2)}a=a.join("/")}if((o||q)&&p){for(c=a.split("/"),k=c.length;k>0;k-=1){if(d=c.slice(0,k).join("/"),o)for(l=o.length;l>0;l-=1)if((e=p[o.slice(0,l).join("/")])&&(e=e[d])){f=e,h=k;break}if(f)break;!i&&q&&q[d]&&(i=q[d],j=k)}!f&&i&&(f=i,h=j),f&&(c.splice(0,h,f),a=c.join("/"))}return a}function g(a,c){return function(){var d=w.call(arguments,0);return"string"!=typeof d[0]&&1===d.length&&d.push(null),o.apply(b,d.concat([a,c]))}}function h(a){return function(b){return f(b,a)}}function i(a){return function(b){r[a]=b}}function j(a){if(e(s,a)){var c=s[a];delete s[a],u[a]=!0,n.apply(b,c)}if(!e(r,a)&&!e(u,a))throw new Error("No "+a);return r[a]}function k(a){var b,c=a?a.indexOf("!"):-1;return c>-1&&(b=a.substring(0,c),a=a.substring(c+1,a.length)),[b,a]}function l(a){return a?k(a):[]}function m(a){return function(){return t&&t.config&&t.config[a]||{}}}var n,o,p,q,r={},s={},t={},u={},v=Object.prototype.hasOwnProperty,w=[].slice,x=/\.js$/;p=function(a,b){var c,d=k(a),e=d[0],g=b[1];return a=d[1],e&&(e=f(e,g),c=j(e)),e?a=c&&c.normalize?c.normalize(a,h(g)):f(a,g):(a=f(a,g),d=k(a),e=d[0],a=d[1],e&&(c=j(e))),{f:e?e+"!"+a:a,n:a,pr:e,p:c}},q={require:function(a){return g(a)},exports:function(a){var b=r[a];return void 0!==b?b:r[a]={}},module:function(a){return{id:a,uri:"",exports:r[a],config:m(a)}}},n=function(a,c,d,f){var h,k,m,n,o,t,v,w=[],x=typeof d;if(f=f||a,t=l(f),"undefined"===x||"function"===x){for(c=!c.length&&d.length?["require","exports","module"]:c,o=0;o0&&(b.call(arguments,a.prototype.constructor),e=c.prototype.constructor),e.apply(this,arguments)}function e(){this.constructor=d}var f=b(c),g=b(a);c.displayName=a.displayName,d.prototype=new e;for(var h=0;h":">",'"':""","'":"'","/":"/"};return"string"!=typeof a?a:String(a).replace(/[&<>"'\/\\]/g,function(a){return b[a]})},c.appendMany=function(b,c){if("1.7"===a.fn.jquery.substr(0,3)){var d=a();a.map(c,function(a){d=d.add(a)}),c=d}b.append(c)},c.__cache={};var e=0;return c.GetUniqueElementId=function(a){var b=a.getAttribute("data-select2-id");return null==b&&(a.id?(b=a.id,a.setAttribute("data-select2-id",b)):(a.setAttribute("data-select2-id",++e),b=e.toString())),b},c.StoreData=function(a,b,d){var e=c.GetUniqueElementId(a);c.__cache[e]||(c.__cache[e]={}),c.__cache[e][b]=d},c.GetData=function(b,d){var e=c.GetUniqueElementId(b);return d?c.__cache[e]&&null!=c.__cache[e][d]?c.__cache[e][d]:a(b).data(d):c.__cache[e]},c.RemoveData=function(a){var b=c.GetUniqueElementId(a);null!=c.__cache[b]&&delete c.__cache[b]},c}),b.define("select2/results",["jquery","./utils"],function(a,b){function c(a,b,d){this.$element=a,this.data=d,this.options=b,c.__super__.constructor.call(this)}return b.Extend(c,b.Observable),c.prototype.render=function(){var b=a('');return this.options.get("multiple")&&b.attr("aria-multiselectable","true"),this.$results=b,b},c.prototype.clear=function(){this.$results.empty()},c.prototype.displayMessage=function(b){var c=this.options.get("escapeMarkup");this.clear(),this.hideLoading();var d=a(' '),e=this.options.get("translations").get(b.message);d.append(c(e(b.args))),d[0].className+=" select2-results__message",this.$results.append(d)},c.prototype.hideMessages=function(){this.$results.find(".select2-results__message").remove()},c.prototype.append=function(a){this.hideLoading();var b=[];if(null==a.results||0===a.results.length)return void(0===this.$results.children().length&&this.trigger("results:message",{message:"noResults"}));a.results=this.sort(a.results);for(var c=0;c0?b.first().trigger("mouseenter"):a.first().trigger("mouseenter"),this.ensureHighlightVisible()},c.prototype.setClasses=function(){var c=this;this.data.current(function(d){var e=a.map(d,function(a){return a.id.toString()});c.$results.find(".select2-results__option[aria-selected]").each(function(){var c=a(this),d=b.GetData(this,"data"),f=""+d.id;null!=d.element&&d.element.selected||null==d.element&&a.inArray(f,e)>-1?c.attr("aria-selected","true"):c.attr("aria-selected","false")})})},c.prototype.showLoading=function(a){this.hideLoading();var b=this.options.get("translations").get("searching"),c={disabled:!0,loading:!0,text:b(a)},d=this.option(c);d.className+=" loading-results",this.$results.prepend(d)},c.prototype.hideLoading=function(){this.$results.find(".loading-results").remove()},c.prototype.option=function(c){var d=document.createElement("li");d.className="select2-results__option";var e={role:"treeitem","aria-selected":"false"};c.disabled&&(delete e["aria-selected"],e["aria-disabled"]="true"),null==c.id&&delete e["aria-selected"],null!=c._resultId&&(d.id=c._resultId),c.title&&(d.title=c.title),c.children&&(e.role="group",e["aria-label"]=c.text,delete e["aria-selected"]);for(var f in e){var g=e[f];d.setAttribute(f,g)}if(c.children){var h=a(d),i=document.createElement("strong");i.className="select2-results__group";a(i);this.template(c,i);for(var j=[],k=0;k",{class:"select2-results__options select2-results__options--nested"});n.append(j),h.append(i),h.append(n)}else this.template(c,d);return b.StoreData(d,"data",c),d},c.prototype.bind=function(c,d){var e=this,f=c.id+"-results";this.$results.attr("id",f),c.on("results:all",function(a){e.clear(),e.append(a.data),c.isOpen()&&(e.setClasses(),e.highlightFirstItem())}),c.on("results:append",function(a){e.append(a.data),c.isOpen()&&e.setClasses()}),c.on("query",function(a){e.hideMessages(),e.showLoading(a)}),c.on("select",function(){c.isOpen()&&(e.setClasses(),e.highlightFirstItem())}),c.on("unselect",function(){c.isOpen()&&(e.setClasses(),e.highlightFirstItem())}),c.on("open",function(){e.$results.attr("aria-expanded","true"),e.$results.attr("aria-hidden","false"),e.setClasses(),e.ensureHighlightVisible()}),c.on("close",function(){e.$results.attr("aria-expanded","false"),e.$results.attr("aria-hidden","true"),e.$results.removeAttr("aria-activedescendant")}),c.on("results:toggle",function(){var a=e.getHighlightedResults();0!==a.length&&a.trigger("mouseup")}),c.on("results:select",function(){var a=e.getHighlightedResults();if(0!==a.length){var c=b.GetData(a[0],"data");"true"==a.attr("aria-selected")?e.trigger("close",{}):e.trigger("select",{data:c})}}),c.on("results:previous",function(){var a=e.getHighlightedResults(),b=e.$results.find("[aria-selected]"),c=b.index(a);if(!(c<=0)){var d=c-1;0===a.length&&(d=0);var f=b.eq(d);f.trigger("mouseenter");var g=e.$results.offset().top,h=f.offset().top,i=e.$results.scrollTop()+(h-g);0===d?e.$results.scrollTop(0):h-g<0&&e.$results.scrollTop(i)}}),c.on("results:next",function(){var a=e.getHighlightedResults(),b=e.$results.find("[aria-selected]"),c=b.index(a),d=c+1;if(!(d>=b.length)){var f=b.eq(d);f.trigger("mouseenter");var g=e.$results.offset().top+e.$results.outerHeight(!1),h=f.offset().top+f.outerHeight(!1),i=e.$results.scrollTop()+h-g;0===d?e.$results.scrollTop(0):h>g&&e.$results.scrollTop(i)}}),c.on("results:focus",function(a){a.element.addClass("select2-results__option--highlighted")}),c.on("results:message",function(a){e.displayMessage(a)}),a.fn.mousewheel&&this.$results.on("mousewheel",function(a){var b=e.$results.scrollTop(),c=e.$results.get(0).scrollHeight-b+a.deltaY,d=a.deltaY>0&&b-a.deltaY<=0,f=a.deltaY<0&&c<=e.$results.height();d?(e.$results.scrollTop(0),a.preventDefault(),a.stopPropagation()):f&&(e.$results.scrollTop(e.$results.get(0).scrollHeight-e.$results.height()),a.preventDefault(),a.stopPropagation())}),this.$results.on("mouseup",".select2-results__option[aria-selected]",function(c){var d=a(this),f=b.GetData(this,"data");if("true"===d.attr("aria-selected"))return void(e.options.get("multiple")?e.trigger("unselect",{originalEvent:c,data:f}):e.trigger("close",{}));e.trigger("select",{originalEvent:c,data:f})}),this.$results.on("mouseenter",".select2-results__option[aria-selected]",function(c){var d=b.GetData(this,"data");e.getHighlightedResults().removeClass("select2-results__option--highlighted"),e.trigger("results:focus",{data:d,element:a(this)})})},c.prototype.getHighlightedResults=function(){return this.$results.find(".select2-results__option--highlighted")},c.prototype.destroy=function(){this.$results.remove()},c.prototype.ensureHighlightVisible=function(){var a=this.getHighlightedResults();if(0!==a.length){var b=this.$results.find("[aria-selected]"),c=b.index(a),d=this.$results.offset().top,e=a.offset().top,f=this.$results.scrollTop()+(e-d),g=e-d;f-=2*a.outerHeight(!1),c<=2?this.$results.scrollTop(0):(g>this.$results.outerHeight()||g<0)&&this.$results.scrollTop(f)}},c.prototype.template=function(b,c){var d=this.options.get("templateResult"),e=this.options.get("escapeMarkup"),f=d(b,c);null==f?c.style.display="none":"string"==typeof f?c.innerHTML=e(f):a(c).append(f)},c}),b.define("select2/keys",[],function(){return{BACKSPACE:8,TAB:9,ENTER:13,SHIFT:16,CTRL:17,ALT:18,ESC:27,SPACE:32,PAGE_UP:33,PAGE_DOWN:34,END:35,HOME:36,LEFT:37,UP:38,RIGHT:39,DOWN:40,DELETE:46}}),b.define("select2/selection/base",["jquery","../utils","../keys"],function(a,b,c){function d(a,b){this.$element=a,this.options=b,d.__super__.constructor.call(this)}return b.Extend(d,b.Observable),d.prototype.render=function(){var c=a(' ');return this._tabindex=0,null!=b.GetData(this.$element[0],"old-tabindex")?this._tabindex=b.GetData(this.$element[0],"old-tabindex"):null!=this.$element.attr("tabindex")&&(this._tabindex=this.$element.attr("tabindex")),c.attr("title",this.$element.attr("title")),c.attr("tabindex",this._tabindex),this.$selection=c,c},d.prototype.bind=function(a,b){var d=this,e=(a.id,a.id+"-results");this.container=a,this.$selection.on("focus",function(a){d.trigger("focus",a)}),this.$selection.on("blur",function(a){d._handleBlur(a)}),this.$selection.on("keydown",function(a){d.trigger("keypress",a),a.which===c.SPACE&&a.preventDefault()}),a.on("results:focus",function(a){d.$selection.attr("aria-activedescendant",a.data._resultId)}),a.on("selection:update",function(a){d.update(a.data)}),a.on("open",function(){d.$selection.attr("aria-expanded","true"),d.$selection.attr("aria-owns",e),d._attachCloseHandler(a)}),a.on("close",function(){d.$selection.attr("aria-expanded","false"),d.$selection.removeAttr("aria-activedescendant"),d.$selection.removeAttr("aria-owns"),d.$selection.focus(),window.setTimeout(function(){d.$selection.focus()},0),d._detachCloseHandler(a)}),a.on("enable",function(){d.$selection.attr("tabindex",d._tabindex)}),a.on("disable",function(){d.$selection.attr("tabindex","-1")})},d.prototype._handleBlur=function(b){var c=this;window.setTimeout(function(){document.activeElement==c.$selection[0]||a.contains(c.$selection[0],document.activeElement)||c.trigger("blur",b)},1)},d.prototype._attachCloseHandler=function(c){a(document.body).on("mousedown.select2."+c.id,function(c){var d=a(c.target),e=d.closest(".select2");a(".select2.select2-container--open").each(function(){a(this),this!=e[0]&&b.GetData(this,"element").select2("close")})})},d.prototype._detachCloseHandler=function(b){a(document.body).off("mousedown.select2."+b.id)},d.prototype.position=function(a,b){b.find(".selection").append(a)},d.prototype.destroy=function(){this._detachCloseHandler(this.container)},d.prototype.update=function(a){throw new Error("The `update` method must be defined in child classes.")},d}),b.define("select2/selection/single",["jquery","./base","../utils","../keys"],function(a,b,c,d){function e(){e.__super__.constructor.apply(this,arguments)}return c.Extend(e,b),e.prototype.render=function(){var a=e.__super__.render.call(this);return a.addClass("select2-selection--single"),a.html(' '),a},e.prototype.bind=function(a,b){var c=this;e.__super__.bind.apply(this,arguments);var d=a.id+"-container";this.$selection.find(".select2-selection__rendered").attr("id",d).attr("role","textbox").attr("aria-readonly","true"),this.$selection.attr("aria-labelledby",d),this.$selection.on("mousedown",function(a){1===a.which&&c.trigger("toggle",{originalEvent:a})}),this.$selection.on("focus",function(a){}),this.$selection.on("blur",function(a){}),a.on("focus",function(b){a.isOpen()||c.$selection.focus()})},e.prototype.clear=function(){var a=this.$selection.find(".select2-selection__rendered");a.empty(),a.removeAttr("title")},e.prototype.display=function(a,b){var c=this.options.get("templateSelection");return this.options.get("escapeMarkup")(c(a,b))},e.prototype.selectionContainer=function(){return a(" ")},e.prototype.update=function(a){if(0===a.length)return void this.clear();var b=a[0],c=this.$selection.find(".select2-selection__rendered"),d=this.display(b,c);c.empty().append(d),c.attr("title",b.title||b.text)},e}),b.define("select2/selection/multiple",["jquery","./base","../utils"],function(a,b,c){function d(a,b){d.__super__.constructor.apply(this,arguments)}return c.Extend(d,b),d.prototype.render=function(){var a=d.__super__.render.call(this);return a.addClass("select2-selection--multiple"),a.html(''),a},d.prototype.bind=function(b,e){var f=this;d.__super__.bind.apply(this,arguments),this.$selection.on("click",function(a){f.trigger("toggle",{originalEvent:a})}),this.$selection.on("click",".select2-selection__choice__remove",function(b){if(!f.options.get("disabled")){var d=a(this),e=d.parent(),g=c.GetData(e[0],"data");f.trigger("unselect",{originalEvent:b,data:g})}})},d.prototype.clear=function(){var a=this.$selection.find(".select2-selection__rendered");a.empty(),a.removeAttr("title")},d.prototype.display=function(a,b){var c=this.options.get("templateSelection");return this.options.get("escapeMarkup")(c(a,b))},d.prototype.selectionContainer=function(){return a('× ')},d.prototype.update=function(a){if(this.clear(),0!==a.length){for(var b=[],d=0;d1||c)return a.call(this,b);this.clear();var d=this.createPlaceholder(this.placeholder);this.$selection.find(".select2-selection__rendered").append(d)},b}),b.define("select2/selection/allowClear",["jquery","../keys","../utils"],function(a,b,c){function d(){}return d.prototype.bind=function(a,b,c){var d=this;a.call(this,b,c),null==this.placeholder&&this.options.get("debug")&&window.console&&console.error&&console.error("Select2: The `allowClear` option should be used in combination with the `placeholder` option."),this.$selection.on("mousedown",".select2-selection__clear",function(a){d._handleClear(a)}),b.on("keypress",function(a){d._handleKeyboardClear(a,b)})},d.prototype._handleClear=function(a,b){if(!this.options.get("disabled")){var d=this.$selection.find(".select2-selection__clear");if(0!==d.length){b.stopPropagation();var e=c.GetData(d[0],"data"),f=this.$element.val();this.$element.val(this.placeholder.id);var g={data:e};if(this.trigger("clear",g),g.prevented)return void this.$element.val(f);for(var h=0;h0||0===d.length)){var e=a('× ');c.StoreData(e[0],"data",d),this.$selection.find(".select2-selection__rendered").prepend(e)}},d}),b.define("select2/selection/search",["jquery","../utils","../keys"],function(a,b,c){function d(a,b,c){a.call(this,b,c)}return d.prototype.render=function(b){var c=a(' ');this.$searchContainer=c,this.$search=c.find("input");var d=b.call(this);return this._transferTabIndex(),d},d.prototype.bind=function(a,d,e){var f=this;a.call(this,d,e),d.on("open",function(){f.$search.trigger("focus")}),d.on("close",function(){f.$search.val(""),f.$search.removeAttr("aria-activedescendant"),f.$search.trigger("focus")}),d.on("enable",function(){f.$search.prop("disabled",!1),f._transferTabIndex()}),d.on("disable",function(){f.$search.prop("disabled",!0)}),d.on("focus",function(a){f.$search.trigger("focus")}),d.on("results:focus",function(a){f.$search.attr("aria-activedescendant",a.id)}),this.$selection.on("focusin",".select2-search--inline",function(a){f.trigger("focus",a)}),this.$selection.on("focusout",".select2-search--inline",function(a){f._handleBlur(a)}),this.$selection.on("keydown",".select2-search--inline",function(a){if(a.stopPropagation(),f.trigger("keypress",a),f._keyUpPrevented=a.isDefaultPrevented(),a.which===c.BACKSPACE&&""===f.$search.val()){var d=f.$searchContainer.prev(".select2-selection__choice");if(d.length>0){var e=b.GetData(d[0],"data");f.searchRemoveChoice(e),a.preventDefault()}}});var g=document.documentMode,h=g&&g<=11;this.$selection.on("input.searchcheck",".select2-search--inline",function(a){if(h)return void f.$selection.off("input.search input.searchcheck");f.$selection.off("keyup.search")}),this.$selection.on("keyup.search input.search",".select2-search--inline",function(a){if(h&&"input"===a.type)return void f.$selection.off("input.search input.searchcheck");var b=a.which;b!=c.SHIFT&&b!=c.CTRL&&b!=c.ALT&&b!=c.TAB&&f.handleSearch(a)})},d.prototype._transferTabIndex=function(a){this.$search.attr("tabindex",this.$selection.attr("tabindex")),this.$selection.attr("tabindex","-1")},d.prototype.createPlaceholder=function(a,b){this.$search.attr("placeholder",b.text)},d.prototype.update=function(a,b){var c=this.$search[0]==document.activeElement;if(this.$search.attr("placeholder",""),a.call(this,b),this.$selection.find(".select2-selection__rendered").append(this.$searchContainer),this.resizeSearch(),c){this.$element.find("[data-select2-tag]").length?this.$element.focus():this.$search.focus()}},d.prototype.handleSearch=function(){if(this.resizeSearch(),!this._keyUpPrevented){var a=this.$search.val();this.trigger("query",{term:a})}this._keyUpPrevented=!1},d.prototype.searchRemoveChoice=function(a,b){this.trigger("unselect",{data:b}),this.$search.val(b.text),this.handleSearch()},d.prototype.resizeSearch=function(){this.$search.css("width","25px");var a="";if(""!==this.$search.attr("placeholder"))a=this.$selection.find(".select2-selection__rendered").innerWidth();else{a=.75*(this.$search.val().length+1)+"em"}this.$search.css("width",a)},d}),b.define("select2/selection/eventRelay",["jquery"],function(a){function b(){}return b.prototype.bind=function(b,c,d){var e=this,f=["open","opening","close","closing","select","selecting","unselect","unselecting","clear","clearing"],g=["opening","closing","selecting","unselecting","clearing"];b.call(this,c,d),c.on("*",function(b,c){if(-1!==a.inArray(b,f)){c=c||{};var d=a.Event("select2:"+b,{params:c});e.$element.trigger(d),-1!==a.inArray(b,g)&&(c.prevented=d.isDefaultPrevented())}})},b}),b.define("select2/translation",["jquery","require"],function(a,b){function c(a){this.dict=a||{}}return c.prototype.all=function(){return this.dict},c.prototype.get=function(a){return this.dict[a]},c.prototype.extend=function(b){this.dict=a.extend({},b.all(),this.dict)},c._cache={},c.loadPath=function(a){if(!(a in c._cache)){var d=b(a);c._cache[a]=d}return new c(c._cache[a])},c}),b.define("select2/diacritics",[],function(){return{"Ⓐ":"A","A":"A","À":"A","Á":"A","Â":"A","Ầ":"A","Ấ":"A","Ẫ":"A","Ẩ":"A","Ã":"A","Ā":"A","Ă":"A","Ằ":"A","Ắ":"A","Ẵ":"A","Ẳ":"A","Ȧ":"A","Ǡ":"A","Ä":"A","Ǟ":"A","Ả":"A","Å":"A","Ǻ":"A","Ǎ":"A","Ȁ":"A","Ȃ":"A","Ạ":"A","Ậ":"A","Ặ":"A","Ḁ":"A","Ą":"A","Ⱥ":"A","Ɐ":"A","Ꜳ":"AA","Æ":"AE","Ǽ":"AE","Ǣ":"AE","Ꜵ":"AO","Ꜷ":"AU","Ꜹ":"AV","Ꜻ":"AV","Ꜽ":"AY","Ⓑ":"B","B":"B","Ḃ":"B","Ḅ":"B","Ḇ":"B","Ƀ":"B","Ƃ":"B","Ɓ":"B","Ⓒ":"C","C":"C","Ć":"C","Ĉ":"C","Ċ":"C","Č":"C","Ç":"C","Ḉ":"C","Ƈ":"C","Ȼ":"C","Ꜿ":"C","Ⓓ":"D","D":"D","Ḋ":"D","Ď":"D","Ḍ":"D","Ḑ":"D","Ḓ":"D","Ḏ":"D","Đ":"D","Ƌ":"D","Ɗ":"D","Ɖ":"D","Ꝺ":"D","DZ":"DZ","DŽ":"DZ","Dz":"Dz","Dž":"Dz","Ⓔ":"E","E":"E","È":"E","É":"E","Ê":"E","Ề":"E","Ế":"E","Ễ":"E","Ể":"E","Ẽ":"E","Ē":"E","Ḕ":"E","Ḗ":"E","Ĕ":"E","Ė":"E","Ë":"E","Ẻ":"E","Ě":"E","Ȅ":"E","Ȇ":"E","Ẹ":"E","Ệ":"E","Ȩ":"E","Ḝ":"E","Ę":"E","Ḙ":"E","Ḛ":"E","Ɛ":"E","Ǝ":"E","Ⓕ":"F","F":"F","Ḟ":"F","Ƒ":"F","Ꝼ":"F","Ⓖ":"G","G":"G","Ǵ":"G","Ĝ":"G","Ḡ":"G","Ğ":"G","Ġ":"G","Ǧ":"G","Ģ":"G","Ǥ":"G","Ɠ":"G","Ꞡ":"G","Ᵹ":"G","Ꝿ":"G","Ⓗ":"H","H":"H","Ĥ":"H","Ḣ":"H","Ḧ":"H","Ȟ":"H","Ḥ":"H","Ḩ":"H","Ḫ":"H","Ħ":"H","Ⱨ":"H","Ⱶ":"H","Ɥ":"H","Ⓘ":"I","I":"I","Ì":"I","Í":"I","Î":"I","Ĩ":"I","Ī":"I","Ĭ":"I","İ":"I","Ï":"I","Ḯ":"I","Ỉ":"I","Ǐ":"I","Ȉ":"I","Ȋ":"I","Ị":"I","Į":"I","Ḭ":"I","Ɨ":"I","Ⓙ":"J","J":"J","Ĵ":"J","Ɉ":"J","Ⓚ":"K","K":"K","Ḱ":"K","Ǩ":"K","Ḳ":"K","Ķ":"K","Ḵ":"K","Ƙ":"K","Ⱪ":"K","Ꝁ":"K","Ꝃ":"K","Ꝅ":"K","Ꞣ":"K","Ⓛ":"L","L":"L","Ŀ":"L","Ĺ":"L","Ľ":"L","Ḷ":"L","Ḹ":"L","Ļ":"L","Ḽ":"L","Ḻ":"L","Ł":"L","Ƚ":"L","Ɫ":"L","Ⱡ":"L","Ꝉ":"L","Ꝇ":"L","Ꞁ":"L","LJ":"LJ","Lj":"Lj","Ⓜ":"M","M":"M","Ḿ":"M","Ṁ":"M","Ṃ":"M","Ɱ":"M","Ɯ":"M","Ⓝ":"N","N":"N","Ǹ":"N","Ń":"N","Ñ":"N","Ṅ":"N","Ň":"N","Ṇ":"N","Ņ":"N","Ṋ":"N","Ṉ":"N","Ƞ":"N","Ɲ":"N","Ꞑ":"N","Ꞥ":"N","NJ":"NJ","Nj":"Nj","Ⓞ":"O","O":"O","Ò":"O","Ó":"O","Ô":"O","Ồ":"O","Ố":"O","Ỗ":"O","Ổ":"O","Õ":"O","Ṍ":"O","Ȭ":"O","Ṏ":"O","Ō":"O","Ṑ":"O","Ṓ":"O","Ŏ":"O","Ȯ":"O","Ȱ":"O","Ö":"O","Ȫ":"O","Ỏ":"O","Ő":"O","Ǒ":"O","Ȍ":"O","Ȏ":"O","Ơ":"O","Ờ":"O","Ớ":"O","Ỡ":"O","Ở":"O","Ợ":"O","Ọ":"O","Ộ":"O","Ǫ":"O","Ǭ":"O","Ø":"O","Ǿ":"O","Ɔ":"O","Ɵ":"O","Ꝋ":"O","Ꝍ":"O","Ƣ":"OI","Ꝏ":"OO","Ȣ":"OU","Ⓟ":"P","P":"P","Ṕ":"P","Ṗ":"P","Ƥ":"P","Ᵽ":"P","Ꝑ":"P","Ꝓ":"P","Ꝕ":"P","Ⓠ":"Q","Q":"Q","Ꝗ":"Q","Ꝙ":"Q","Ɋ":"Q","Ⓡ":"R","R":"R","Ŕ":"R","Ṙ":"R","Ř":"R","Ȑ":"R","Ȓ":"R","Ṛ":"R","Ṝ":"R","Ŗ":"R","Ṟ":"R","Ɍ":"R","Ɽ":"R","Ꝛ":"R","Ꞧ":"R","Ꞃ":"R","Ⓢ":"S","S":"S","ẞ":"S","Ś":"S","Ṥ":"S","Ŝ":"S","Ṡ":"S","Š":"S","Ṧ":"S","Ṣ":"S","Ṩ":"S","Ș":"S","Ş":"S","Ȿ":"S","Ꞩ":"S","Ꞅ":"S","Ⓣ":"T","T":"T","Ṫ":"T","Ť":"T","Ṭ":"T","Ț":"T","Ţ":"T","Ṱ":"T","Ṯ":"T","Ŧ":"T","Ƭ":"T","Ʈ":"T","Ⱦ":"T","Ꞇ":"T","Ꜩ":"TZ","Ⓤ":"U","U":"U","Ù":"U","Ú":"U","Û":"U","Ũ":"U","Ṹ":"U","Ū":"U","Ṻ":"U","Ŭ":"U","Ü":"U","Ǜ":"U","Ǘ":"U","Ǖ":"U","Ǚ":"U","Ủ":"U","Ů":"U","Ű":"U","Ǔ":"U","Ȕ":"U","Ȗ":"U","Ư":"U","Ừ":"U","Ứ":"U","Ữ":"U","Ử":"U","Ự":"U","Ụ":"U","Ṳ":"U","Ų":"U","Ṷ":"U","Ṵ":"U","Ʉ":"U","Ⓥ":"V","V":"V","Ṽ":"V","Ṿ":"V","Ʋ":"V","Ꝟ":"V","Ʌ":"V","Ꝡ":"VY","Ⓦ":"W","W":"W","Ẁ":"W","Ẃ":"W","Ŵ":"W","Ẇ":"W","Ẅ":"W","Ẉ":"W","Ⱳ":"W","Ⓧ":"X","X":"X","Ẋ":"X","Ẍ":"X","Ⓨ":"Y","Y":"Y","Ỳ":"Y","Ý":"Y","Ŷ":"Y","Ỹ":"Y","Ȳ":"Y","Ẏ":"Y","Ÿ":"Y","Ỷ":"Y","Ỵ":"Y","Ƴ":"Y","Ɏ":"Y","Ỿ":"Y","Ⓩ":"Z","Z":"Z","Ź":"Z","Ẑ":"Z","Ż":"Z","Ž":"Z","Ẓ":"Z","Ẕ":"Z","Ƶ":"Z","Ȥ":"Z","Ɀ":"Z","Ⱬ":"Z","Ꝣ":"Z","ⓐ":"a","a":"a","ẚ":"a","à":"a","á":"a","â":"a","ầ":"a","ấ":"a","ẫ":"a","ẩ":"a","ã":"a","ā":"a","ă":"a","ằ":"a","ắ":"a","ẵ":"a","ẳ":"a","ȧ":"a","ǡ":"a","ä":"a","ǟ":"a","ả":"a","å":"a","ǻ":"a","ǎ":"a","ȁ":"a","ȃ":"a","ạ":"a","ậ":"a","ặ":"a","ḁ":"a","ą":"a","ⱥ":"a","ɐ":"a","ꜳ":"aa","æ":"ae","ǽ":"ae","ǣ":"ae","ꜵ":"ao","ꜷ":"au","ꜹ":"av","ꜻ":"av","ꜽ":"ay","ⓑ":"b","b":"b","ḃ":"b","ḅ":"b","ḇ":"b","ƀ":"b","ƃ":"b","ɓ":"b","ⓒ":"c","c":"c","ć":"c","ĉ":"c","ċ":"c","č":"c","ç":"c","ḉ":"c","ƈ":"c","ȼ":"c","ꜿ":"c","ↄ":"c","ⓓ":"d","d":"d","ḋ":"d","ď":"d","ḍ":"d","ḑ":"d","ḓ":"d","ḏ":"d","đ":"d","ƌ":"d","ɖ":"d","ɗ":"d","ꝺ":"d","dz":"dz","dž":"dz","ⓔ":"e","e":"e","è":"e","é":"e","ê":"e","ề":"e","ế":"e","ễ":"e","ể":"e","ẽ":"e","ē":"e","ḕ":"e","ḗ":"e","ĕ":"e","ė":"e","ë":"e","ẻ":"e","ě":"e","ȅ":"e","ȇ":"e","ẹ":"e","ệ":"e","ȩ":"e","ḝ":"e","ę":"e","ḙ":"e","ḛ":"e","ɇ":"e","ɛ":"e","ǝ":"e","ⓕ":"f","f":"f","ḟ":"f","ƒ":"f","ꝼ":"f","ⓖ":"g","g":"g","ǵ":"g","ĝ":"g","ḡ":"g","ğ":"g","ġ":"g","ǧ":"g","ģ":"g","ǥ":"g","ɠ":"g","ꞡ":"g","ᵹ":"g","ꝿ":"g","ⓗ":"h","h":"h","ĥ":"h","ḣ":"h","ḧ":"h","ȟ":"h","ḥ":"h","ḩ":"h","ḫ":"h","ẖ":"h","ħ":"h","ⱨ":"h","ⱶ":"h","ɥ":"h","ƕ":"hv","ⓘ":"i","i":"i","ì":"i","í":"i","î":"i","ĩ":"i","ī":"i","ĭ":"i","ï":"i","ḯ":"i","ỉ":"i","ǐ":"i","ȉ":"i","ȋ":"i","ị":"i","į":"i","ḭ":"i","ɨ":"i","ı":"i","ⓙ":"j","j":"j","ĵ":"j","ǰ":"j","ɉ":"j","ⓚ":"k","k":"k","ḱ":"k","ǩ":"k","ḳ":"k","ķ":"k","ḵ":"k","ƙ":"k","ⱪ":"k","ꝁ":"k","ꝃ":"k","ꝅ":"k","ꞣ":"k","ⓛ":"l","l":"l","ŀ":"l","ĺ":"l","ľ":"l","ḷ":"l","ḹ":"l","ļ":"l","ḽ":"l","ḻ":"l","ſ":"l","ł":"l","ƚ":"l","ɫ":"l","ⱡ":"l","ꝉ":"l","ꞁ":"l","ꝇ":"l","lj":"lj","ⓜ":"m","m":"m","ḿ":"m","ṁ":"m","ṃ":"m","ɱ":"m","ɯ":"m","ⓝ":"n","n":"n","ǹ":"n","ń":"n","ñ":"n","ṅ":"n","ň":"n","ṇ":"n","ņ":"n","ṋ":"n","ṉ":"n","ƞ":"n","ɲ":"n","ʼn":"n","ꞑ":"n","ꞥ":"n","nj":"nj","ⓞ":"o","o":"o","ò":"o","ó":"o","ô":"o","ồ":"o","ố":"o","ỗ":"o","ổ":"o","õ":"o","ṍ":"o","ȭ":"o","ṏ":"o","ō":"o","ṑ":"o","ṓ":"o","ŏ":"o","ȯ":"o","ȱ":"o","ö":"o","ȫ":"o","ỏ":"o","ő":"o","ǒ":"o","ȍ":"o","ȏ":"o","ơ":"o","ờ":"o","ớ":"o","ỡ":"o","ở":"o","ợ":"o","ọ":"o","ộ":"o","ǫ":"o","ǭ":"o","ø":"o","ǿ":"o","ɔ":"o","ꝋ":"o","ꝍ":"o","ɵ":"o","ƣ":"oi","ȣ":"ou","ꝏ":"oo","ⓟ":"p","p":"p","ṕ":"p","ṗ":"p","ƥ":"p","ᵽ":"p","ꝑ":"p","ꝓ":"p","ꝕ":"p","ⓠ":"q","q":"q","ɋ":"q","ꝗ":"q","ꝙ":"q","ⓡ":"r","r":"r","ŕ":"r","ṙ":"r","ř":"r","ȑ":"r","ȓ":"r","ṛ":"r","ṝ":"r","ŗ":"r","ṟ":"r","ɍ":"r","ɽ":"r","ꝛ":"r","ꞧ":"r","ꞃ":"r","ⓢ":"s","s":"s","ß":"s","ś":"s","ṥ":"s","ŝ":"s","ṡ":"s","š":"s","ṧ":"s","ṣ":"s","ṩ":"s","ș":"s","ş":"s","ȿ":"s","ꞩ":"s","ꞅ":"s","ẛ":"s","ⓣ":"t","t":"t","ṫ":"t","ẗ":"t","ť":"t","ṭ":"t","ț":"t","ţ":"t","ṱ":"t","ṯ":"t","ŧ":"t","ƭ":"t","ʈ":"t","ⱦ":"t","ꞇ":"t","ꜩ":"tz","ⓤ":"u","u":"u","ù":"u","ú":"u","û":"u","ũ":"u","ṹ":"u","ū":"u","ṻ":"u","ŭ":"u","ü":"u","ǜ":"u","ǘ":"u","ǖ":"u","ǚ":"u","ủ":"u","ů":"u","ű":"u","ǔ":"u","ȕ":"u","ȗ":"u","ư":"u","ừ":"u","ứ":"u","ữ":"u","ử":"u","ự":"u","ụ":"u","ṳ":"u","ų":"u","ṷ":"u","ṵ":"u","ʉ":"u","ⓥ":"v","v":"v","ṽ":"v","ṿ":"v","ʋ":"v","ꝟ":"v","ʌ":"v","ꝡ":"vy","ⓦ":"w","w":"w","ẁ":"w","ẃ":"w","ŵ":"w","ẇ":"w","ẅ":"w","ẘ":"w","ẉ":"w","ⱳ":"w","ⓧ":"x","x":"x","ẋ":"x","ẍ":"x","ⓨ":"y","y":"y","ỳ":"y","ý":"y","ŷ":"y","ỹ":"y","ȳ":"y","ẏ":"y","ÿ":"y","ỷ":"y","ẙ":"y","ỵ":"y","ƴ":"y","ɏ":"y","ỿ":"y","ⓩ":"z","z":"z","ź":"z","ẑ":"z","ż":"z","ž":"z","ẓ":"z","ẕ":"z","ƶ":"z","ȥ":"z","ɀ":"z","ⱬ":"z","ꝣ":"z","Ά":"Α","Έ":"Ε","Ή":"Η","Ί":"Ι","Ϊ":"Ι","Ό":"Ο","Ύ":"Υ","Ϋ":"Υ","Ώ":"Ω","ά":"α","έ":"ε","ή":"η","ί":"ι","ϊ":"ι","ΐ":"ι","ό":"ο","ύ":"υ","ϋ":"υ","ΰ":"υ","ω":"ω","ς":"σ"}}),b.define("select2/data/base",["../utils"],function(a){function b(a,c){b.__super__.constructor.call(this)}return a.Extend(b,a.Observable),b.prototype.current=function(a){throw new Error("The `current` method must be defined in child classes.")},b.prototype.query=function(a,b){throw new Error("The `query` method must be defined in child classes.")},b.prototype.bind=function(a,b){},b.prototype.destroy=function(){},b.prototype.generateResultId=function(b,c){var d=b.id+"-result-";return d+=a.generateChars(4),null!=c.id?d+="-"+c.id.toString():d+="-"+a.generateChars(4),d},b}),b.define("select2/data/select",["./base","../utils","jquery"],function(a,b,c){function d(a,b){this.$element=a,this.options=b,d.__super__.constructor.call(this)}return b.Extend(d,a),d.prototype.current=function(a){var b=[],d=this;this.$element.find(":selected").each(function(){var a=c(this),e=d.item(a);b.push(e)}),a(b)},d.prototype.select=function(a){var b=this;if(a.selected=!0,c(a.element).is("option"))return a.element.selected=!0,void this.$element.trigger("change");if(this.$element.prop("multiple"))this.current(function(d){var e=[];a=[a],a.push.apply(a,d);for(var f=0;f=0){var k=f.filter(d(j)),l=this.item(k),m=c.extend(!0,{},j,l),n=this.option(m);k.replaceWith(n)}else{var o=this.option(j);if(j.children){var p=this.convertToOptions(j.children);b.appendMany(o,p)}h.push(o)}}return h},d}),b.define("select2/data/ajax",["./array","../utils","jquery"],function(a,b,c){function d(a,b){this.ajaxOptions=this._applyDefaults(b.get("ajax")),null!=this.ajaxOptions.processResults&&(this.processResults=this.ajaxOptions.processResults),d.__super__.constructor.call(this,a,b)}return b.Extend(d,a),d.prototype._applyDefaults=function(a){var b={data:function(a){return c.extend({},a,{q:a.term})},transport:function(a,b,d){var e=c.ajax(a);return e.then(b),e.fail(d),e}};return c.extend({},b,a,!0)},d.prototype.processResults=function(a){return a},d.prototype.query=function(a,b){function d(){var d=f.transport(f,function(d){var f=e.processResults(d,a);e.options.get("debug")&&window.console&&console.error&&(f&&f.results&&c.isArray(f.results)||console.error("Select2: The AJAX results did not return an array in the `results` key of the response.")),b(f)},function(){"status"in d&&(0===d.status||"0"===d.status)||e.trigger("results:message",{message:"errorLoading"})});e._request=d}var e=this;null!=this._request&&(c.isFunction(this._request.abort)&&this._request.abort(),this._request=null);var f=c.extend({type:"GET"},this.ajaxOptions);"function"==typeof f.url&&(f.url=f.url.call(this.$element,a)),"function"==typeof f.data&&(f.data=f.data.call(this.$element,a)),this.ajaxOptions.delay&&null!=a.term?(this._queryTimeout&&window.clearTimeout(this._queryTimeout),this._queryTimeout=window.setTimeout(d,this.ajaxOptions.delay)):d()},d}),b.define("select2/data/tags",["jquery"],function(a){function b(b,c,d){var e=d.get("tags"),f=d.get("createTag");void 0!==f&&(this.createTag=f);var g=d.get("insertTag");if(void 0!==g&&(this.insertTag=g),b.call(this,c,d),a.isArray(e))for(var h=0;h0&&b.term.length>this.maximumInputLength)return void this.trigger("results:message",{message:"inputTooLong",args:{maximum:this.maximumInputLength,input:b.term,params:b}});a.call(this,b,c)},a}),b.define("select2/data/maximumSelectionLength",[],function(){function a(a,b,c){this.maximumSelectionLength=c.get("maximumSelectionLength"),a.call(this,b,c)}return a.prototype.query=function(a,b,c){var d=this;this.current(function(e){var f=null!=e?e.length:0;if(d.maximumSelectionLength>0&&f>=d.maximumSelectionLength)return void d.trigger("results:message",{message:"maximumSelected",args:{maximum:d.maximumSelectionLength}});a.call(d,b,c)})},a}),b.define("select2/dropdown",["jquery","./utils"],function(a,b){function c(a,b){this.$element=a,this.options=b,c.__super__.constructor.call(this)}return b.Extend(c,b.Observable),c.prototype.render=function(){var b=a(' ');return b.attr("dir",this.options.get("dir")),this.$dropdown=b,b},c.prototype.bind=function(){},c.prototype.position=function(a,b){},c.prototype.destroy=function(){this.$dropdown.remove()},c}),b.define("select2/dropdown/search",["jquery","../utils"],function(a,b){function c(){}return c.prototype.render=function(b){var c=b.call(this),d=a(' ');return this.$searchContainer=d,this.$search=d.find("input"),c.prepend(d),c},c.prototype.bind=function(b,c,d){var e=this;b.call(this,c,d),this.$search.on("keydown",function(a){e.trigger("keypress",a),e._keyUpPrevented=a.isDefaultPrevented()}),this.$search.on("input",function(b){a(this).off("keyup")}),this.$search.on("keyup input",function(a){e.handleSearch(a)}),c.on("open",function(){e.$search.attr("tabindex",0),e.$search.focus(),window.setTimeout(function(){e.$search.focus()},0)}),c.on("close",function(){e.$search.attr("tabindex",-1),e.$search.val(""),e.$search.blur()}),c.on("focus",function(){c.isOpen()||e.$search.focus()}),c.on("results:all",function(a){if(null==a.query.term||""===a.query.term){e.showSearch(a)?e.$searchContainer.removeClass("select2-search--hide"):e.$searchContainer.addClass("select2-search--hide")}})},c.prototype.handleSearch=function(a){if(!this._keyUpPrevented){var b=this.$search.val();this.trigger("query",{term:b})}this._keyUpPrevented=!1},c.prototype.showSearch=function(a,b){return!0},c}),b.define("select2/dropdown/hidePlaceholder",[],function(){function a(a,b,c,d){this.placeholder=this.normalizePlaceholder(c.get("placeholder")),a.call(this,b,c,d)}return a.prototype.append=function(a,b){b.results=this.removePlaceholder(b.results),a.call(this,b)},a.prototype.normalizePlaceholder=function(a,b){return"string"==typeof b&&(b={id:"",text:b}),b},a.prototype.removePlaceholder=function(a,b){for(var c=b.slice(0),d=b.length-1;d>=0;d--){var e=b[d];this.placeholder.id===e.id&&c.splice(d,1)}return c},a}),b.define("select2/dropdown/infiniteScroll",["jquery"],function(a){function b(a,b,c,d){this.lastParams={},a.call(this,b,c,d),this.$loadingMore=this.createLoadingMore(),this.loading=!1}return b.prototype.append=function(a,b){this.$loadingMore.remove(),this.loading=!1,a.call(this,b),this.showLoadingMore(b)&&this.$results.append(this.$loadingMore)},b.prototype.bind=function(b,c,d){var e=this;b.call(this,c,d),c.on("query",function(a){e.lastParams=a,e.loading=!0}),c.on("query:append",function(a){e.lastParams=a,e.loading=!0}),this.$results.on("scroll",function(){var b=a.contains(document.documentElement,e.$loadingMore[0]);if(!e.loading&&b){e.$results.offset().top+e.$results.outerHeight(!1)+50>=e.$loadingMore.offset().top+e.$loadingMore.outerHeight(!1)&&e.loadMore()}})},b.prototype.loadMore=function(){this.loading=!0;var b=a.extend({},{page:1},this.lastParams);b.page++,this.trigger("query:append",b)},b.prototype.showLoadingMore=function(a,b){return b.pagination&&b.pagination.more},b.prototype.createLoadingMore=function(){var b=a(' '),c=this.options.get("translations").get("loadingMore");return b.html(c(this.lastParams)),b},b}),b.define("select2/dropdown/attachBody",["jquery","../utils"],function(a,b){function c(b,c,d){this.$dropdownParent=d.get("dropdownParent")||a(document.body),b.call(this,c,d)}return c.prototype.bind=function(a,b,c){var d=this,e=!1;a.call(this,b,c),b.on("open",function(){d._showDropdown(),d._attachPositioningHandler(b),e||(e=!0,b.on("results:all",function(){d._positionDropdown(),d._resizeDropdown()}),b.on("results:append",function(){d._positionDropdown(),d._resizeDropdown()}))}),b.on("close",function(){d._hideDropdown(),d._detachPositioningHandler(b)}),this.$dropdownContainer.on("mousedown",function(a){a.stopPropagation()})},c.prototype.destroy=function(a){a.call(this),this.$dropdownContainer.remove()},c.prototype.position=function(a,b,c){b.attr("class",c.attr("class")),b.removeClass("select2"),b.addClass("select2-container--open"),b.css({position:"absolute",top:-999999}),this.$container=c},c.prototype.render=function(b){var c=a(" "),d=b.call(this);return c.append(d),this.$dropdownContainer=c,c},c.prototype._hideDropdown=function(a){this.$dropdownContainer.detach()},c.prototype._attachPositioningHandler=function(c,d){var e=this,f="scroll.select2."+d.id,g="resize.select2."+d.id,h="orientationchange.select2."+d.id,i=this.$container.parents().filter(b.hasScroll);i.each(function(){b.StoreData(this,"select2-scroll-position",{x:a(this).scrollLeft(),y:a(this).scrollTop()})}),i.on(f,function(c){var d=b.GetData(this,"select2-scroll-position");a(this).scrollTop(d.y)}),a(window).on(f+" "+g+" "+h,function(a){e._positionDropdown(),e._resizeDropdown()})},c.prototype._detachPositioningHandler=function(c,d){var e="scroll.select2."+d.id,f="resize.select2."+d.id,g="orientationchange.select2."+d.id;this.$container.parents().filter(b.hasScroll).off(e),a(window).off(e+" "+f+" "+g)},c.prototype._positionDropdown=function(){var b=a(window),c=this.$dropdown.hasClass("select2-dropdown--above"),d=this.$dropdown.hasClass("select2-dropdown--below"),e=null,f=this.$container.offset();f.bottom=f.top+this.$container.outerHeight(!1);var g={height:this.$container.outerHeight(!1)};g.top=f.top,g.bottom=f.top+g.height;var h={height:this.$dropdown.outerHeight(!1)},i={top:b.scrollTop(),bottom:b.scrollTop()+b.height()},j=i.topf.bottom+h.height,l={left:f.left,top:g.bottom},m=this.$dropdownParent;"static"===m.css("position")&&(m=m.offsetParent());var n=m.offset();l.top-=n.top,l.left-=n.left,c||d||(e="below"),k||!j||c?!j&&k&&c&&(e="below"):e="above",("above"==e||c&&"below"!==e)&&(l.top=g.top-n.top-h.height),null!=e&&(this.$dropdown.removeClass("select2-dropdown--below select2-dropdown--above").addClass("select2-dropdown--"+e),this.$container.removeClass("select2-container--below select2-container--above").addClass("select2-container--"+e)),this.$dropdownContainer.css(l)},c.prototype._resizeDropdown=function(){var a={width:this.$container.outerWidth(!1)+"px"};this.options.get("dropdownAutoWidth")&&(a.minWidth=a.width,a.position="relative",a.width="auto"),this.$dropdown.css(a)},c.prototype._showDropdown=function(a){this.$dropdownContainer.appendTo(this.$dropdownParent),this._positionDropdown(),this._resizeDropdown()},c}),b.define("select2/dropdown/minimumResultsForSearch",[],function(){function a(b){for(var c=0,d=0;d0&&(l.dataAdapter=j.Decorate(l.dataAdapter,r)),l.maximumInputLength>0&&(l.dataAdapter=j.Decorate(l.dataAdapter,s)),l.maximumSelectionLength>0&&(l.dataAdapter=j.Decorate(l.dataAdapter,t)),l.tags&&(l.dataAdapter=j.Decorate(l.dataAdapter,p)),null==l.tokenSeparators&&null==l.tokenizer||(l.dataAdapter=j.Decorate(l.dataAdapter,q)),null!=l.query){var C=b(l.amdBase+"compat/query");l.dataAdapter=j.Decorate(l.dataAdapter,C)}if(null!=l.initSelection){var D=b(l.amdBase+"compat/initSelection");l.dataAdapter=j.Decorate(l.dataAdapter,D)}}if(null==l.resultsAdapter&&(l.resultsAdapter=c,null!=l.ajax&&(l.resultsAdapter=j.Decorate(l.resultsAdapter,x)),null!=l.placeholder&&(l.resultsAdapter=j.Decorate(l.resultsAdapter,w)),l.selectOnClose&&(l.resultsAdapter=j.Decorate(l.resultsAdapter,A))),null==l.dropdownAdapter){if(l.multiple)l.dropdownAdapter=u;else{var E=j.Decorate(u,v);l.dropdownAdapter=E}if(0!==l.minimumResultsForSearch&&(l.dropdownAdapter=j.Decorate(l.dropdownAdapter,z)),l.closeOnSelect&&(l.dropdownAdapter=j.Decorate(l.dropdownAdapter,B)),null!=l.dropdownCssClass||null!=l.dropdownCss||null!=l.adaptDropdownCssClass){var F=b(l.amdBase+"compat/dropdownCss");l.dropdownAdapter=j.Decorate(l.dropdownAdapter,F)}l.dropdownAdapter=j.Decorate(l.dropdownAdapter,y)}if(null==l.selectionAdapter){if(l.multiple?l.selectionAdapter=e:l.selectionAdapter=d,null!=l.placeholder&&(l.selectionAdapter=j.Decorate(l.selectionAdapter,f)),l.allowClear&&(l.selectionAdapter=j.Decorate(l.selectionAdapter,g)),l.multiple&&(l.selectionAdapter=j.Decorate(l.selectionAdapter,h)),null!=l.containerCssClass||null!=l.containerCss||null!=l.adaptContainerCssClass){var G=b(l.amdBase+"compat/containerCss");l.selectionAdapter=j.Decorate(l.selectionAdapter,G)}l.selectionAdapter=j.Decorate(l.selectionAdapter,i)}if("string"==typeof l.language)if(l.language.indexOf("-")>0){var H=l.language.split("-"),I=H[0];l.language=[l.language,I]}else l.language=[l.language];if(a.isArray(l.language)){var J=new k;l.language.push("en");for(var K=l.language,L=0;L0){for(var f=a.extend(!0,{},e),g=e.children.length-1;g>=0;g--){null==c(d,e.children[g])&&f.children.splice(g,1)}return f.children.length>0?f:c(d,f)}var h=b(e.text).toUpperCase(),i=b(d.term).toUpperCase();return h.indexOf(i)>-1?e:null}this.defaults={amdBase:"./",amdLanguageBase:"./i18n/",closeOnSelect:!0,debug:!1,dropdownAutoWidth:!1,escapeMarkup:j.escapeMarkup,language:C,matcher:c,minimumInputLength:0,maximumInputLength:0,maximumSelectionLength:0,minimumResultsForSearch:0,selectOnClose:!1,sorter:function(a){return a},templateResult:function(a){return a.text},templateSelection:function(a){return a.text},theme:"default",width:"resolve"}},D.prototype.set=function(b,c){var d=a.camelCase(b),e={};e[d]=c;var f=j._convertData(e);a.extend(!0,this.defaults,f)},new D}),b.define("select2/options",["require","jquery","./defaults","./utils"],function(a,b,c,d){function e(b,e){if(this.options=b,null!=e&&this.fromElement(e),this.options=c.apply(this.options),e&&e.is("input")){var f=a(this.get("amdBase")+"compat/inputData");this.options.dataAdapter=d.Decorate(this.options.dataAdapter,f)}}return e.prototype.fromElement=function(a){var c=["select2"];null==this.options.multiple&&(this.options.multiple=a.prop("multiple")),null==this.options.disabled&&(this.options.disabled=a.prop("disabled")),null==this.options.language&&(a.prop("lang")?this.options.language=a.prop("lang").toLowerCase():a.closest("[lang]").prop("lang")&&(this.options.language=a.closest("[lang]").prop("lang"))),null==this.options.dir&&(a.prop("dir")?this.options.dir=a.prop("dir"):a.closest("[dir]").prop("dir")?this.options.dir=a.closest("[dir]").prop("dir"):this.options.dir="ltr"),a.prop("disabled",this.options.disabled),a.prop("multiple",this.options.multiple),d.GetData(a[0],"select2Tags")&&(this.options.debug&&window.console&&console.warn&&console.warn('Select2: The `data-select2-tags` attribute has been changed to use the `data-data` and `data-tags="true"` attributes and will be removed in future versions of Select2.'),d.StoreData(a[0],"data",d.GetData(a[0],"select2Tags")),d.StoreData(a[0],"tags",!0)),d.GetData(a[0],"ajaxUrl")&&(this.options.debug&&window.console&&console.warn&&console.warn("Select2: The `data-ajax-url` attribute has been changed to `data-ajax--url` and support for the old attribute will be removed in future versions of Select2."),a.attr("ajax--url",d.GetData(a[0],"ajaxUrl")),d.StoreData(a[0],"ajax-Url",d.GetData(a[0],"ajaxUrl")));var e={};e=b.fn.jquery&&"1."==b.fn.jquery.substr(0,2)&&a[0].dataset?b.extend(!0,{},a[0].dataset,d.GetData(a[0])):d.GetData(a[0]);var f=b.extend(!0,{},e);f=d._convertData(f);for(var g in f)b.inArray(g,c)>-1||(b.isPlainObject(this.options[g])?b.extend(this.options[g],f[g]):this.options[g]=f[g]);return this},e.prototype.get=function(a){return this.options[a]},e.prototype.set=function(a,b){this.options[a]=b},e}),b.define("select2/core",["jquery","./options","./utils","./keys"],function(a,b,c,d){var e=function(a,d){null!=c.GetData(a[0],"select2")&&c.GetData(a[0],"select2").destroy(),this.$element=a,this.id=this._generateId(a),d=d||{},this.options=new b(d,a),e.__super__.constructor.call(this);var f=a.attr("tabindex")||0;c.StoreData(a[0],"old-tabindex",f),a.attr("tabindex","-1");var g=this.options.get("dataAdapter");this.dataAdapter=new g(a,this.options);var h=this.render();this._placeContainer(h);var i=this.options.get("selectionAdapter");this.selection=new i(a,this.options),this.$selection=this.selection.render(),this.selection.position(this.$selection,h);var j=this.options.get("dropdownAdapter");this.dropdown=new j(a,this.options),this.$dropdown=this.dropdown.render(),this.dropdown.position(this.$dropdown,h);var k=this.options.get("resultsAdapter");this.results=new k(a,this.options,this.dataAdapter),this.$results=this.results.render(),this.results.position(this.$results,this.$dropdown);var l=this;this._bindAdapters(),this._registerDomEvents(),this._registerDataEvents(),this._registerSelectionEvents(),this._registerDropdownEvents(),this._registerResultsEvents(),this._registerEvents(),this.dataAdapter.current(function(a){l.trigger("selection:update",{data:a})}),a.addClass("select2-hidden-accessible"),a.attr("aria-hidden","true"),this._syncAttributes(),c.StoreData(a[0],"select2",this),a.data("select2",this)};return c.Extend(e,c.Observable),e.prototype._generateId=function(a){var b="";return b=null!=a.attr("id")?a.attr("id"):null!=a.attr("name")?a.attr("name")+"-"+c.generateChars(2):c.generateChars(4),b=b.replace(/(:|\.|\[|\]|,)/g,""),b="select2-"+b},e.prototype._placeContainer=function(a){a.insertAfter(this.$element);var b=this._resolveWidth(this.$element,this.options.get("width"));null!=b&&a.css("width",b)},e.prototype._resolveWidth=function(a,b){var c=/^width:(([-+]?([0-9]*\.)?[0-9]+)(px|em|ex|%|in|cm|mm|pt|pc))/i;if("resolve"==b){var d=this._resolveWidth(a,"style");return null!=d?d:this._resolveWidth(a,"element")}if("element"==b){var e=a.outerWidth(!1);return e<=0?"auto":e+"px"}if("style"==b){var f=a.attr("style");if("string"!=typeof f)return null;for(var g=f.split(";"),h=0,i=g.length;h=1)return k[1]}return null}return b},e.prototype._bindAdapters=function(){this.dataAdapter.bind(this,this.$container),this.selection.bind(this,this.$container),this.dropdown.bind(this,this.$container),this.results.bind(this,this.$container)},e.prototype._registerDomEvents=function(){var b=this;this.$element.on("change.select2",function(){b.dataAdapter.current(function(a){b.trigger("selection:update",{data:a})})}),this.$element.on("focus.select2",function(a){b.trigger("focus",a)}),this._syncA=c.bind(this._syncAttributes,this),this._syncS=c.bind(this._syncSubtree,this),this.$element[0].attachEvent&&this.$element[0].attachEvent("onpropertychange",this._syncA);var d=window.MutationObserver||window.WebKitMutationObserver||window.MozMutationObserver;null!=d?(this._observer=new d(function(c){a.each(c,b._syncA),a.each(c,b._syncS)}),this._observer.observe(this.$element[0],{attributes:!0,childList:!0,subtree:!1})):this.$element[0].addEventListener&&(this.$element[0].addEventListener("DOMAttrModified",b._syncA,!1),this.$element[0].addEventListener("DOMNodeInserted",b._syncS,!1),this.$element[0].addEventListener("DOMNodeRemoved",b._syncS,!1))},e.prototype._registerDataEvents=function(){var a=this;this.dataAdapter.on("*",function(b,c){a.trigger(b,c)})},e.prototype._registerSelectionEvents=function(){var b=this,c=["toggle","focus"];this.selection.on("toggle",function(){b.toggleDropdown()}),this.selection.on("focus",function(a){b.focus(a)}),this.selection.on("*",function(d,e){-1===a.inArray(d,c)&&b.trigger(d,e)})},e.prototype._registerDropdownEvents=function(){var a=this;this.dropdown.on("*",function(b,c){a.trigger(b,c)})},e.prototype._registerResultsEvents=function(){var a=this;this.results.on("*",function(b,c){a.trigger(b,c)})},e.prototype._registerEvents=function(){var a=this;this.on("open",function(){a.$container.addClass("select2-container--open")}),this.on("close",function(){a.$container.removeClass("select2-container--open")}),this.on("enable",function(){a.$container.removeClass("select2-container--disabled")}),this.on("disable",function(){a.$container.addClass("select2-container--disabled")}),this.on("blur",function(){a.$container.removeClass("select2-container--focus")}),this.on("query",function(b){a.isOpen()||a.trigger("open",{}),this.dataAdapter.query(b,function(c){a.trigger("results:all",{data:c,query:b})})}),this.on("query:append",function(b){this.dataAdapter.query(b,function(c){a.trigger("results:append",{data:c,query:b})})}),this.on("keypress",function(b){var c=b.which;a.isOpen()?c===d.ESC||c===d.TAB||c===d.UP&&b.altKey?(a.close(),b.preventDefault()):c===d.ENTER?(a.trigger("results:select",{}),b.preventDefault()):c===d.SPACE&&b.ctrlKey?(a.trigger("results:toggle",{}),b.preventDefault()):c===d.UP?(a.trigger("results:previous",{}),b.preventDefault()):c===d.DOWN&&(a.trigger("results:next",{}),b.preventDefault()):(c===d.ENTER||c===d.SPACE||c===d.DOWN&&b.altKey)&&(a.open(),b.preventDefault())})},e.prototype._syncAttributes=function(){this.options.set("disabled",this.$element.prop("disabled")),this.options.get("disabled")?(this.isOpen()&&this.close(),this.trigger("disable",{})):this.trigger("enable",{})},e.prototype._syncSubtree=function(a,b){var c=!1,d=this;if(!a||!a.target||"OPTION"===a.target.nodeName||"OPTGROUP"===a.target.nodeName){if(b)if(b.addedNodes&&b.addedNodes.length>0)for(var e=0;e0&&(c=!0);else c=!0;c&&this.dataAdapter.current(function(a){d.trigger("selection:update",{data:a})})}},e.prototype.trigger=function(a,b){var c=e.__super__.trigger,d={open:"opening",close:"closing",select:"selecting",unselect:"unselecting",clear:"clearing"};if(void 0===b&&(b={}),a in d){var f=d[a],g={prevented:!1,name:a,args:b};if(c.call(this,f,g),g.prevented)return void(b.prevented=!0)}c.call(this,a,b)},e.prototype.toggleDropdown=function(){this.options.get("disabled")||(this.isOpen()?this.close():this.open())},e.prototype.open=function(){this.isOpen()||this.trigger("query",{})},e.prototype.close=function(){this.isOpen()&&this.trigger("close",{})},e.prototype.isOpen=function(){return this.$container.hasClass("select2-container--open")},e.prototype.hasFocus=function(){return this.$container.hasClass("select2-container--focus")},e.prototype.focus=function(a){this.hasFocus()||(this.$container.addClass("select2-container--focus"),this.trigger("focus",{}))},e.prototype.enable=function(a){this.options.get("debug")&&window.console&&console.warn&&console.warn('Select2: The `select2("enable")` method has been deprecated and will be removed in later Select2 versions. Use $element.prop("disabled") instead.'),null!=a&&0!==a.length||(a=[!0]);var b=!a[0];this.$element.prop("disabled",b)},e.prototype.data=function(){this.options.get("debug")&&arguments.length>0&&window.console&&console.warn&&console.warn('Select2: Data can no longer be set using `select2("data")`. You should consider setting the value instead using `$element.val()`.');var a=[];return this.dataAdapter.current(function(b){a=b}),a},e.prototype.val=function(b){if(this.options.get("debug")&&window.console&&console.warn&&console.warn('Select2: The `select2("val")` method has been deprecated and will be removed in later Select2 versions. Use $element.val() instead.'),null==b||0===b.length)return this.$element.val();var c=b[0];a.isArray(c)&&(c=a.map(c,function(a){return a.toString()})),this.$element.val(c).trigger("change")},e.prototype.destroy=function(){this.$container.remove(),this.$element[0].detachEvent&&this.$element[0].detachEvent("onpropertychange",this._syncA),null!=this._observer?(this._observer.disconnect(),this._observer=null):this.$element[0].removeEventListener&&(this.$element[0].removeEventListener("DOMAttrModified",this._syncA,!1),this.$element[0].removeEventListener("DOMNodeInserted",this._syncS,!1),this.$element[0].removeEventListener("DOMNodeRemoved",this._syncS,!1)),this._syncA=null,this._syncS=null,this.$element.off(".select2"),this.$element.attr("tabindex",c.GetData(this.$element[0],"old-tabindex")),this.$element.removeClass("select2-hidden-accessible"),this.$element.attr("aria-hidden","false"),c.RemoveData(this.$element[0]),this.$element.removeData("select2"),this.dataAdapter.destroy(),this.selection.destroy(),this.dropdown.destroy(),this.results.destroy(),this.dataAdapter=null,this.selection=null,this.dropdown=null,this.results=null},e.prototype.render=function(){var b=a(' ');return b.attr("dir",this.options.get("dir")),this.$container=b,this.$container.addClass("select2-container--"+this.options.get("theme")),c.StoreData(b[0],"element",this.$element),b},e}),b.define("select2/compat/utils",["jquery"],function(a){function b(b,c,d){var e,f,g=[];e=a.trim(b.attr("class")),e&&(e=""+e,a(e.split(/\s+/)).each(function(){0===this.indexOf("select2-")&&g.push(this)})),e=a.trim(c.attr("class")),e&&(e=""+e,a(e.split(/\s+/)).each(function(){0!==this.indexOf("select2-")&&null!=(f=d(this))&&g.push(f)})),b.attr("class",g.join(" "))}return{syncCssClasses:b}}),b.define("select2/compat/containerCss",["jquery","./utils"],function(a,b){function c(a){return null}function d(){}return d.prototype.render=function(d){var e=d.call(this),f=this.options.get("containerCssClass")||"";a.isFunction(f)&&(f=f(this.$element));var g=this.options.get("adaptContainerCssClass");if(g=g||c,-1!==f.indexOf(":all:")){f=f.replace(":all:","");var h=g;g=function(a){var b=h(a);return null!=b?b+" "+a:a}}var i=this.options.get("containerCss")||{};return a.isFunction(i)&&(i=i(this.$element)),b.syncCssClasses(e,this.$element,g),e.css(i),e.addClass(f),e},d}),b.define("select2/compat/dropdownCss",["jquery","./utils"],function(a,b){function c(a){return null}function d(){}return d.prototype.render=function(d){var e=d.call(this),f=this.options.get("dropdownCssClass")||"";a.isFunction(f)&&(f=f(this.$element));var g=this.options.get("adaptDropdownCssClass");if(g=g||c,-1!==f.indexOf(":all:")){f=f.replace(":all:","");var h=g;g=function(a){var b=h(a);return null!=b?b+" "+a:a}}var i=this.options.get("dropdownCss")||{};return a.isFunction(i)&&(i=i(this.$element)),b.syncCssClasses(e,this.$element,g),e.css(i),e.addClass(f),e},d}),b.define("select2/compat/initSelection",["jquery"],function(a){function b(a,b,c){c.get("debug")&&window.console&&console.warn&&console.warn("Select2: The `initSelection` option has been deprecated in favor of a custom data adapter that overrides the `current` method. This method is now called multiple times instead of a single time when the instance is initialized. Support will be removed for the `initSelection` option in future versions of Select2"),this.initSelection=c.get("initSelection"),this._isInitialized=!1,a.call(this,b,c)}return b.prototype.current=function(b,c){var d=this;if(this._isInitialized)return void b.call(this,c);this.initSelection.call(null,this.$element,function(b){d._isInitialized=!0,a.isArray(b)||(b=[b]),c(b)})},b}),b.define("select2/compat/inputData",["jquery","../utils"],function(a,b){function c(a,b,c){this._currentData=[],this._valueSeparator=c.get("valueSeparator")||",","hidden"===b.prop("type")&&c.get("debug")&&console&&console.warn&&console.warn("Select2: Using a hidden input with Select2 is no longer supported and may stop working in the future. It is recommended to use a `` element instead."),a.call(this,b,c)}return c.prototype.current=function(b,c){function d(b,c){var e=[];return b.selected||-1!==a.inArray(b.id,c)?(b.selected=!0,e.push(b)):b.selected=!1,b.children&&e.push.apply(e,d(b.children,c)),e}for(var e=[],f=0;f=0;f--){var g=d.children[f];b(c.term,g.text,g)||e.children.splice(f,1)}if(e.children.length>0)return e}return b(c.term,d.text,d)?e:null}return c}return b}),b.define("select2/compat/query",[],function(){function a(a,b,c){c.get("debug")&&window.console&&console.warn&&console.warn("Select2: The `query` option has been deprecated in favor of a custom data adapter that overrides the `query` method. Support will be removed for the `query` option in future versions of Select2."),a.call(this,b,c)}return a.prototype.query=function(a,b,c){b.callback=c,this.options.get("query").call(null,b)},a}),b.define("select2/dropdown/attachContainer",[],function(){function a(a,b,c){a.call(this,b,c)}return a.prototype.position=function(a,b,c){c.find(".dropdown-wrapper").append(b),b.addClass("select2-dropdown--below"),c.addClass("select2-container--below")},a}),b.define("select2/dropdown/stopPropagation",[],function(){function a(){}return a.prototype.bind=function(a,b,c){a.call(this,b,c);var d=["blur","change","click","dblclick","focus","focusin","focusout","input","keydown","keyup","keypress","mousedown","mouseenter","mouseleave","mousemove","mouseover","mouseup","search","touchend","touchstart"];this.$dropdown.on(d.join(" "),function(a){a.stopPropagation()})},a}),b.define("select2/selection/stopPropagation",[],function(){function a(){}return a.prototype.bind=function(a,b,c){a.call(this,b,c);var d=["blur","change","click","dblclick","focus","focusin","focusout","input","keydown","keyup","keypress","mousedown","mouseenter","mouseleave","mousemove","mouseover","mouseup","search","touchend","touchstart"];this.$selection.on(d.join(" "),function(a){a.stopPropagation()})},a}),function(c){"function"==typeof b.define&&b.define.amd?b.define("jquery-mousewheel",["jquery"],c):"object"==typeof exports?module.exports=c:c(a)}(function(a){function b(b){var g=b||window.event,h=i.call(arguments,1),j=0,l=0,m=0,n=0,o=0,p=0;if(b=a.event.fix(g),b.type="mousewheel","detail"in g&&(m=-1*g.detail),"wheelDelta"in g&&(m=g.wheelDelta),"wheelDeltaY"in g&&(m=g.wheelDeltaY),"wheelDeltaX"in g&&(l=-1*g.wheelDeltaX),"axis"in g&&g.axis===g.HORIZONTAL_AXIS&&(l=-1*m,m=0),j=0===m?l:m,"deltaY"in g&&(m=-1*g.deltaY,j=m),"deltaX"in g&&(l=g.deltaX,0===m&&(j=-1*l)),0!==m||0!==l){if(1===g.deltaMode){var q=a.data(this,"mousewheel-line-height");j*=q,m*=q,l*=q}else if(2===g.deltaMode){var r=a.data(this,"mousewheel-page-height");j*=r,m*=r,l*=r}if(n=Math.max(Math.abs(m),Math.abs(l)),(!f||n=1?"floor":"ceil"](j/f),l=Math[l>=1?"floor":"ceil"](l/f),m=Math[m>=1?"floor":"ceil"](m/f),k.settings.normalizeOffset&&this.getBoundingClientRect){var s=this.getBoundingClientRect();o=b.clientX-s.left,p=b.clientY-s.top}return b.deltaX=l,b.deltaY=m,b.deltaFactor=f,b.offsetX=o,b.offsetY=p,b.deltaMode=0,h.unshift(b,j,l,m),e&&clearTimeout(e),e=setTimeout(c,200),(a.event.dispatch||a.event.handle).apply(this,h)}}function c(){f=null}function d(a,b){return k.settings.adjustOldDeltas&&"mousewheel"===a.type&&b%120==0}var e,f,g=["wheel","mousewheel","DOMMouseScroll","MozMousePixelScroll"],h="onwheel"in document||document.documentMode>=9?["wheel"]:["mousewheel","DomMouseScroll","MozMousePixelScroll"],i=Array.prototype.slice;if(a.event.fixHooks)for(var j=g.length;j;)a.event.fixHooks[g[--j]]=a.event.mouseHooks;var k=a.event.special.mousewheel={version:"3.1.12",setup:function(){if(this.addEventListener)for(var c=h.length;c;)this.addEventListener(h[--c],b,!1);else this.onmousewheel=b;a.data(this,"mousewheel-line-height",k.getLineHeight(this)),a.data(this,"mousewheel-page-height",k.getPageHeight(this))},teardown:function(){if(this.removeEventListener)for(var c=h.length;c;)this.removeEventListener(h[--c],b,!1);else this.onmousewheel=null;a.removeData(this,"mousewheel-line-height"),a.removeData(this,"mousewheel-page-height")},getLineHeight:function(b){var c=a(b),d=c["offsetParent"in a.fn?"offsetParent":"parent"]();return d.length||(d=a("body")),parseInt(d.css("fontSize"),10)||parseInt(c.css("fontSize"),10)||16},getPageHeight:function(b){return a(b).height()},settings:{adjustOldDeltas:!0,normalizeOffset:!0}};a.fn.extend({mousewheel:function(a){return a?this.bind("mousewheel",a):this.trigger("mousewheel")},unmousewheel:function(a){return this.unbind("mousewheel",a)}})}),b.define("jquery.select2",["jquery","jquery-mousewheel","./select2/core","./select2/defaults","./select2/utils"],function(a,b,c,d,e){if(null==a.fn.select2){var f=["open","close","destroy"];a.fn.select2=function(b){if("object"==typeof(b=b||{}))return this.each(function(){var d=a.extend(!0,{},b);new c(a(this),d)}),this;if("string"==typeof b){var d,g=Array.prototype.slice.call(arguments,1);return this.each(function(){var a=e.GetData(this,"select2");null==a&&window.console&&console.error&&console.error("The select2('"+b+"') method was called on an element that is not using Select2."),d=a[b].apply(a,g)}),a.inArray(b,f)>-1?this:d}throw new Error("Invalid arguments for Select2: "+b)}}return null==a.fn.select2.defaults&&(a.fn.select2.defaults=d),c}),{define:b.define,require:b.require}}(),c=b.require("jquery.select2");return a.fn.select2.amd=b,c});
\ No newline at end of file
diff --git a/AdminPanel/client/src/pages/AiIntegration/ai/vendor/select2-4.0.6-rc.1/dist/js/select2.js b/AdminPanel/client/src/pages/AiIntegration/ai/vendor/select2-4.0.6-rc.1/dist/js/select2.js
new file mode 100644
index 0000000000..73d33af9f4
--- /dev/null
+++ b/AdminPanel/client/src/pages/AiIntegration/ai/vendor/select2-4.0.6-rc.1/dist/js/select2.js
@@ -0,0 +1,5847 @@
+/*!
+ * Select2 4.0.6-rc.1
+ * https://select2.github.io
+ *
+ * Released under the MIT license
+ * https://github.com/select2/select2/blob/master/LICENSE.md
+ */
+;(function (factory) {
+ if (typeof define === 'function' && define.amd) {
+ // AMD. Register as an anonymous module.
+ define(['jquery'], factory);
+ } else if (typeof module === 'object' && module.exports) {
+ // Node/CommonJS
+ module.exports = function (root, jQuery) {
+ if (jQuery === undefined) {
+ // require('jQuery') returns a factory that requires window to
+ // build a jQuery instance, we normalize how we use modules
+ // that require this pattern but the window provided is a noop
+ // if it's defined (how jquery works)
+ if (typeof window !== 'undefined') {
+ jQuery = require('jquery');
+ }
+ else {
+ jQuery = require('jquery')(root);
+ }
+ }
+ factory(jQuery);
+ return jQuery;
+ };
+ } else {
+ // Browser globals
+ factory(jQuery);
+ }
+} (function (jQuery) {
+ // This is needed so we can catch the AMD loader configuration and use it
+ // The inner file should be wrapped (by `banner.start.js`) in a function that
+ // returns the AMD loader references.
+ var S2 =(function () {
+ // Restore the Select2 AMD loader so it can be used
+ // Needed mostly in the language files, where the loader is not inserted
+ if (jQuery && jQuery.fn && jQuery.fn.select2 && jQuery.fn.select2.amd) {
+ var S2 = jQuery.fn.select2.amd;
+ }
+var S2;(function () { if (!S2 || !S2.requirejs) {
+if (!S2) { S2 = {}; } else { require = S2; }
+/**
+ * @license almond 0.3.3 Copyright jQuery Foundation and other contributors.
+ * Released under MIT license, http://github.com/requirejs/almond/LICENSE
+ */
+//Going sloppy to avoid 'use strict' string cost, but strict practices should
+//be followed.
+/*global setTimeout: false */
+
+var requirejs, require, define;
+(function (undef) {
+ var main, req, makeMap, handlers,
+ defined = {},
+ waiting = {},
+ config = {},
+ defining = {},
+ hasOwn = Object.prototype.hasOwnProperty,
+ aps = [].slice,
+ jsSuffixRegExp = /\.js$/;
+
+ function hasProp(obj, prop) {
+ return hasOwn.call(obj, prop);
+ }
+
+ /**
+ * 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.
+ * @returns {String} normalized name
+ */
+ function normalize(name, baseName) {
+ var nameParts, nameSegment, mapValue, foundMap, lastIndex,
+ foundI, foundStarMap, starI, i, j, part, normalizedBaseParts,
+ baseParts = baseName && baseName.split("/"),
+ map = config.map,
+ starMap = (map && map['*']) || {};
+
+ //Adjust any relative paths.
+ if (name) {
+ name = name.split('/');
+ lastIndex = name.length - 1;
+
+ // If wanting node ID compatibility, strip .js from end
+ // of IDs. Have to do this here, and not in nameToUrl
+ // because node allows either .js or non .js to map
+ // to same file.
+ if (config.nodeIdCompat && jsSuffixRegExp.test(name[lastIndex])) {
+ name[lastIndex] = name[lastIndex].replace(jsSuffixRegExp, '');
+ }
+
+ // Starts with a '.' so need the baseName
+ if (name[0].charAt(0) === '.' && baseParts) {
+ //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);
+ }
+
+ //start trimDots
+ for (i = 0; i < name.length; i++) {
+ part = name[i];
+ if (part === '.') {
+ name.splice(i, 1);
+ i -= 1;
+ } else if (part === '..') {
+ // If at the start, or previous value is still ..,
+ // keep them so that when converted to a path it may
+ // still work when converted to a path, even though
+ // as an ID it is less than ideal. In larger point
+ // releases, may be better to just kick out an error.
+ if (i === 0 || (i === 1 && name[2] === '..') || name[i - 1] === '..') {
+ continue;
+ } else if (i > 0) {
+ name.splice(i - 1, 2);
+ i -= 2;
+ }
+ }
+ }
+ //end trimDots
+
+ name = name.join('/');
+ }
+
+ //Apply map config if available.
+ if ((baseParts || starMap) && map) {
+ 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 = map[baseParts.slice(0, j).join('/')];
+
+ //baseName segment has config, find if it has one for
+ //this name.
+ if (mapValue) {
+ mapValue = 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 && starMap[nameSegment]) {
+ foundStarMap = starMap[nameSegment];
+ starI = i;
+ }
+ }
+
+ if (!foundMap && foundStarMap) {
+ foundMap = foundStarMap;
+ foundI = starI;
+ }
+
+ if (foundMap) {
+ nameParts.splice(0, foundI, foundMap);
+ name = nameParts.join('/');
+ }
+ }
+
+ return name;
+ }
+
+ function makeRequire(relName, forceSync) {
+ return function () {
+ //A version of a require function that passes a moduleName
+ //value for items that may need to
+ //look up paths relative to the moduleName
+ var args = aps.call(arguments, 0);
+
+ //If first arg is not require('string'), and there is only
+ //one arg, it is the array form without a callback. Insert
+ //a null so that the following concat is correct.
+ if (typeof args[0] !== 'string' && args.length === 1) {
+ args.push(null);
+ }
+ return req.apply(undef, args.concat([relName, forceSync]));
+ };
+ }
+
+ function makeNormalize(relName) {
+ return function (name) {
+ return normalize(name, relName);
+ };
+ }
+
+ function makeLoad(depName) {
+ return function (value) {
+ defined[depName] = value;
+ };
+ }
+
+ function callDep(name) {
+ if (hasProp(waiting, name)) {
+ var args = waiting[name];
+ delete waiting[name];
+ defining[name] = true;
+ main.apply(undef, args);
+ }
+
+ if (!hasProp(defined, name) && !hasProp(defining, name)) {
+ throw new Error('No ' + name);
+ }
+ return defined[name];
+ }
+
+ //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 parts array for a relName where first part is plugin ID,
+ //second part is resource ID. Assumes relName has already been normalized.
+ function makeRelParts(relName) {
+ return relName ? splitPrefix(relName) : [];
+ }
+
+ /**
+ * Makes a name map, normalizing the name, and using a plugin
+ * for normalization if necessary. Grabs a ref to plugin
+ * too, as an optimization.
+ */
+ makeMap = function (name, relParts) {
+ var plugin,
+ parts = splitPrefix(name),
+ prefix = parts[0],
+ relResourceName = relParts[1];
+
+ name = parts[1];
+
+ if (prefix) {
+ prefix = normalize(prefix, relResourceName);
+ plugin = callDep(prefix);
+ }
+
+ //Normalize according
+ if (prefix) {
+ if (plugin && plugin.normalize) {
+ name = plugin.normalize(name, makeNormalize(relResourceName));
+ } else {
+ name = normalize(name, relResourceName);
+ }
+ } else {
+ name = normalize(name, relResourceName);
+ parts = splitPrefix(name);
+ prefix = parts[0];
+ name = parts[1];
+ if (prefix) {
+ plugin = callDep(prefix);
+ }
+ }
+
+ //Using ridiculous property names for space reasons
+ return {
+ f: prefix ? prefix + '!' + name : name, //fullName
+ n: name,
+ pr: prefix,
+ p: plugin
+ };
+ };
+
+ function makeConfig(name) {
+ return function () {
+ return (config && config.config && config.config[name]) || {};
+ };
+ }
+
+ handlers = {
+ require: function (name) {
+ return makeRequire(name);
+ },
+ exports: function (name) {
+ var e = defined[name];
+ if (typeof e !== 'undefined') {
+ return e;
+ } else {
+ return (defined[name] = {});
+ }
+ },
+ module: function (name) {
+ return {
+ id: name,
+ uri: '',
+ exports: defined[name],
+ config: makeConfig(name)
+ };
+ }
+ };
+
+ main = function (name, deps, callback, relName) {
+ var cjsModule, depName, ret, map, i, relParts,
+ args = [],
+ callbackType = typeof callback,
+ usingExports;
+
+ //Use name if no relName
+ relName = relName || name;
+ relParts = makeRelParts(relName);
+
+ //Call the callback to define the module, if necessary.
+ if (callbackType === 'undefined' || callbackType === 'function') {
+ //Pull out the defined dependencies and pass the ordered
+ //values to the callback.
+ //Default to [require, exports, module] if no deps
+ deps = !deps.length && callback.length ? ['require', 'exports', 'module'] : deps;
+ for (i = 0; i < deps.length; i += 1) {
+ map = makeMap(deps[i], relParts);
+ depName = map.f;
+
+ //Fast path CommonJS standard dependencies.
+ if (depName === "require") {
+ args[i] = handlers.require(name);
+ } else if (depName === "exports") {
+ //CommonJS module spec 1.1
+ args[i] = handlers.exports(name);
+ usingExports = true;
+ } else if (depName === "module") {
+ //CommonJS module spec 1.1
+ cjsModule = args[i] = handlers.module(name);
+ } else if (hasProp(defined, depName) ||
+ hasProp(waiting, depName) ||
+ hasProp(defining, depName)) {
+ args[i] = callDep(depName);
+ } else if (map.p) {
+ map.p.load(map.n, makeRequire(relName, true), makeLoad(depName), {});
+ args[i] = defined[depName];
+ } else {
+ throw new Error(name + ' missing ' + depName);
+ }
+ }
+
+ ret = callback ? callback.apply(defined[name], args) : undefined;
+
+ if (name) {
+ //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.
+ if (cjsModule && cjsModule.exports !== undef &&
+ cjsModule.exports !== defined[name]) {
+ defined[name] = cjsModule.exports;
+ } else if (ret !== undef || !usingExports) {
+ //Use the return value from the function.
+ defined[name] = ret;
+ }
+ }
+ } else if (name) {
+ //May just be an object definition for the module. Only
+ //worry about defining if have a module name.
+ defined[name] = callback;
+ }
+ };
+
+ requirejs = require = req = function (deps, callback, relName, forceSync, alt) {
+ if (typeof deps === "string") {
+ if (handlers[deps]) {
+ //callback in this case is really relName
+ return handlers[deps](callback);
+ }
+ //Just return the module wanted. In this scenario, the
+ //deps arg is the module name, and second arg (if passed)
+ //is just the relName.
+ //Normalize module name, if it contains . or ..
+ return callDep(makeMap(deps, makeRelParts(callback)).f);
+ } else if (!deps.splice) {
+ //deps is a config object, not an array.
+ config = deps;
+ if (config.deps) {
+ req(config.deps, config.callback);
+ }
+ if (!callback) {
+ return;
+ }
+
+ if (callback.splice) {
+ //callback is an array, which means it is a dependency list.
+ //Adjust args if there are dependencies
+ deps = callback;
+ callback = relName;
+ relName = null;
+ } else {
+ deps = undef;
+ }
+ }
+
+ //Support require(['a'])
+ callback = callback || function () {};
+
+ //If relName is a function, it is an errback handler,
+ //so remove it.
+ if (typeof relName === 'function') {
+ relName = forceSync;
+ forceSync = alt;
+ }
+
+ //Simulate async callback;
+ if (forceSync) {
+ main(undef, deps, callback, relName);
+ } else {
+ //Using a non-zero value because of concern for what old browsers
+ //do, and latest browsers "upgrade" to 4 if lower value is used:
+ //http://www.whatwg.org/specs/web-apps/current-work/multipage/timers.html#dom-windowtimers-settimeout:
+ //If want a value immediately, use require('id') instead -- something
+ //that works in almond on the global level, but not guaranteed and
+ //unlikely to work in other AMD implementations.
+ setTimeout(function () {
+ main(undef, deps, callback, relName);
+ }, 4);
+ }
+
+ return req;
+ };
+
+ /**
+ * Just drops the config on the floor, but returns req in case
+ * the config return value is used.
+ */
+ req.config = function (cfg) {
+ return req(cfg);
+ };
+
+ /**
+ * Expose module registry for debugging and tooling
+ */
+ requirejs._defined = defined;
+
+ define = function (name, deps, callback) {
+ if (typeof name !== 'string') {
+ throw new Error('See almond README: incorrect module build, no module name');
+ }
+
+ //This module may not have dependencies
+ if (!deps.splice) {
+ //deps is not an array, so probably means
+ //an object literal or factory function for
+ //the value. Adjust args.
+ callback = deps;
+ deps = [];
+ }
+
+ if (!hasProp(defined, name) && !hasProp(waiting, name)) {
+ waiting[name] = [name, deps, callback];
+ }
+ };
+
+ define.amd = {
+ jQuery: true
+ };
+}());
+
+S2.requirejs = requirejs;S2.require = require;S2.define = define;
+}
+}());
+S2.define("almond", function(){});
+
+/* global jQuery:false, $:false */
+S2.define('jquery',[],function () {
+ var _$ = jQuery || $;
+
+ if (_$ == null && console && console.error) {
+ console.error(
+ 'Select2: An instance of jQuery or a jQuery-compatible library was not ' +
+ 'found. Make sure that you are including jQuery before Select2 on your ' +
+ 'web page.'
+ );
+ }
+
+ return _$;
+});
+
+S2.define('select2/utils',[
+ 'jquery'
+], function ($) {
+ var Utils = {};
+
+ Utils.Extend = function (ChildClass, SuperClass) {
+ var __hasProp = {}.hasOwnProperty;
+
+ function BaseConstructor () {
+ this.constructor = ChildClass;
+ }
+
+ for (var key in SuperClass) {
+ if (__hasProp.call(SuperClass, key)) {
+ ChildClass[key] = SuperClass[key];
+ }
+ }
+
+ BaseConstructor.prototype = SuperClass.prototype;
+ ChildClass.prototype = new BaseConstructor();
+ ChildClass.__super__ = SuperClass.prototype;
+
+ return ChildClass;
+ };
+
+ function getMethods (theClass) {
+ var proto = theClass.prototype;
+
+ var methods = [];
+
+ for (var methodName in proto) {
+ var m = proto[methodName];
+
+ if (typeof m !== 'function') {
+ continue;
+ }
+
+ if (methodName === 'constructor') {
+ continue;
+ }
+
+ methods.push(methodName);
+ }
+
+ return methods;
+ }
+
+ Utils.Decorate = function (SuperClass, DecoratorClass) {
+ var decoratedMethods = getMethods(DecoratorClass);
+ var superMethods = getMethods(SuperClass);
+
+ function DecoratedClass () {
+ var unshift = Array.prototype.unshift;
+
+ var argCount = DecoratorClass.prototype.constructor.length;
+
+ var calledConstructor = SuperClass.prototype.constructor;
+
+ if (argCount > 0) {
+ unshift.call(arguments, SuperClass.prototype.constructor);
+
+ calledConstructor = DecoratorClass.prototype.constructor;
+ }
+
+ calledConstructor.apply(this, arguments);
+ }
+
+ DecoratorClass.displayName = SuperClass.displayName;
+
+ function ctr () {
+ this.constructor = DecoratedClass;
+ }
+
+ DecoratedClass.prototype = new ctr();
+
+ for (var m = 0; m < superMethods.length; m++) {
+ var superMethod = superMethods[m];
+
+ DecoratedClass.prototype[superMethod] =
+ SuperClass.prototype[superMethod];
+ }
+
+ var calledMethod = function (methodName) {
+ // Stub out the original method if it's not decorating an actual method
+ var originalMethod = function () {};
+
+ if (methodName in DecoratedClass.prototype) {
+ originalMethod = DecoratedClass.prototype[methodName];
+ }
+
+ var decoratedMethod = DecoratorClass.prototype[methodName];
+
+ return function () {
+ var unshift = Array.prototype.unshift;
+
+ unshift.call(arguments, originalMethod);
+
+ return decoratedMethod.apply(this, arguments);
+ };
+ };
+
+ for (var d = 0; d < decoratedMethods.length; d++) {
+ var decoratedMethod = decoratedMethods[d];
+
+ DecoratedClass.prototype[decoratedMethod] = calledMethod(decoratedMethod);
+ }
+
+ return DecoratedClass;
+ };
+
+ var Observable = function () {
+ this.listeners = {};
+ };
+
+ Observable.prototype.on = function (event, callback) {
+ this.listeners = this.listeners || {};
+
+ if (event in this.listeners) {
+ this.listeners[event].push(callback);
+ } else {
+ this.listeners[event] = [callback];
+ }
+ };
+
+ Observable.prototype.trigger = function (event) {
+ var slice = Array.prototype.slice;
+ var params = slice.call(arguments, 1);
+
+ this.listeners = this.listeners || {};
+
+ // Params should always come in as an array
+ if (params == null) {
+ params = [];
+ }
+
+ // If there are no arguments to the event, use a temporary object
+ if (params.length === 0) {
+ params.push({});
+ }
+
+ // Set the `_type` of the first object to the event
+ params[0]._type = event;
+
+ if (event in this.listeners) {
+ this.invoke(this.listeners[event], slice.call(arguments, 1));
+ }
+
+ if ('*' in this.listeners) {
+ this.invoke(this.listeners['*'], arguments);
+ }
+ };
+
+ Observable.prototype.invoke = function (listeners, params) {
+ for (var i = 0, len = listeners.length; i < len; i++) {
+ listeners[i].apply(this, params);
+ }
+ };
+
+ Utils.Observable = Observable;
+
+ Utils.generateChars = function (length) {
+ var chars = '';
+
+ for (var i = 0; i < length; i++) {
+ var randomChar = Math.floor(Math.random() * 36);
+ chars += randomChar.toString(36);
+ }
+
+ return chars;
+ };
+
+ Utils.bind = function (func, context) {
+ return function () {
+ func.apply(context, arguments);
+ };
+ };
+
+ Utils._convertData = function (data) {
+ for (var originalKey in data) {
+ var keys = originalKey.split('-');
+
+ var dataLevel = data;
+
+ if (keys.length === 1) {
+ continue;
+ }
+
+ for (var k = 0; k < keys.length; k++) {
+ var key = keys[k];
+
+ // Lowercase the first letter
+ // By default, dash-separated becomes camelCase
+ key = key.substring(0, 1).toLowerCase() + key.substring(1);
+
+ if (!(key in dataLevel)) {
+ dataLevel[key] = {};
+ }
+
+ if (k == keys.length - 1) {
+ dataLevel[key] = data[originalKey];
+ }
+
+ dataLevel = dataLevel[key];
+ }
+
+ delete data[originalKey];
+ }
+
+ return data;
+ };
+
+ Utils.hasScroll = function (index, el) {
+ // Adapted from the function created by @ShadowScripter
+ // and adapted by @BillBarry on the Stack Exchange Code Review website.
+ // The original code can be found at
+ // http://codereview.stackexchange.com/q/13338
+ // and was designed to be used with the Sizzle selector engine.
+
+ var $el = $(el);
+ var overflowX = el.style.overflowX;
+ var overflowY = el.style.overflowY;
+
+ //Check both x and y declarations
+ if (overflowX === overflowY &&
+ (overflowY === 'hidden' || overflowY === 'visible')) {
+ return false;
+ }
+
+ if (overflowX === 'scroll' || overflowY === 'scroll') {
+ return true;
+ }
+
+ return ($el.innerHeight() < el.scrollHeight ||
+ $el.innerWidth() < el.scrollWidth);
+ };
+
+ Utils.escapeMarkup = function (markup) {
+ var replaceMap = {
+ '\\': '\',
+ '&': '&',
+ '<': '<',
+ '>': '>',
+ '"': '"',
+ '\'': ''',
+ '/': '/'
+ };
+
+ // Do not try to escape the markup if it's not a string
+ if (typeof markup !== 'string') {
+ return markup;
+ }
+
+ return String(markup).replace(/[&<>"'\/\\]/g, function (match) {
+ return replaceMap[match];
+ });
+ };
+
+ // Append an array of jQuery nodes to a given element.
+ Utils.appendMany = function ($element, $nodes) {
+ // jQuery 1.7.x does not support $.fn.append() with an array
+ // Fall back to a jQuery object collection using $.fn.add()
+ if ($.fn.jquery.substr(0, 3) === '1.7') {
+ var $jqNodes = $();
+
+ $.map($nodes, function (node) {
+ $jqNodes = $jqNodes.add(node);
+ });
+
+ $nodes = $jqNodes;
+ }
+
+ $element.append($nodes);
+ };
+
+ // Cache objects in Utils.__cache instead of $.data (see #4346)
+ Utils.__cache = {};
+
+ var id = 0;
+ Utils.GetUniqueElementId = function (element) {
+ // Get a unique element Id. If element has no id,
+ // creates a new unique number, stores it in the id
+ // attribute and returns the new id.
+ // If an id already exists, it simply returns it.
+
+ var select2Id = element.getAttribute('data-select2-id');
+ if (select2Id == null) {
+ // If element has id, use it.
+ if (element.id) {
+ select2Id = element.id;
+ element.setAttribute('data-select2-id', select2Id);
+ } else {
+ element.setAttribute('data-select2-id', ++id);
+ select2Id = id.toString();
+ }
+ }
+ return select2Id;
+ };
+
+ Utils.StoreData = function (element, name, value) {
+ // Stores an item in the cache for a specified element.
+ // name is the cache key.
+ var id = Utils.GetUniqueElementId(element);
+ if (!Utils.__cache[id]) {
+ Utils.__cache[id] = {};
+ }
+
+ Utils.__cache[id][name] = value;
+ };
+
+ Utils.GetData = function (element, name) {
+ // Retrieves a value from the cache by its key (name)
+ // name is optional. If no name specified, return
+ // all cache items for the specified element.
+ // and for a specified element.
+ var id = Utils.GetUniqueElementId(element);
+ if (name) {
+ if (Utils.__cache[id]) {
+ return Utils.__cache[id][name] != null ?
+ Utils.__cache[id][name]:
+ $(element).data(name); // Fallback to HTML5 data attribs.
+ }
+ return $(element).data(name); // Fallback to HTML5 data attribs.
+ } else {
+ return Utils.__cache[id];
+ }
+ };
+
+ Utils.RemoveData = function (element) {
+ // Removes all cached items for a specified element.
+ var id = Utils.GetUniqueElementId(element);
+ if (Utils.__cache[id] != null) {
+ delete Utils.__cache[id];
+ }
+ };
+
+ return Utils;
+});
+
+S2.define('select2/results',[
+ 'jquery',
+ './utils'
+], function ($, Utils) {
+ function Results ($element, options, dataAdapter) {
+ this.$element = $element;
+ this.data = dataAdapter;
+ this.options = options;
+
+ Results.__super__.constructor.call(this);
+ }
+
+ Utils.Extend(Results, Utils.Observable);
+
+ Results.prototype.render = function () {
+ var $results = $(
+ ''
+ );
+
+ if (this.options.get('multiple')) {
+ $results.attr('aria-multiselectable', 'true');
+ }
+
+ this.$results = $results;
+
+ return $results;
+ };
+
+ Results.prototype.clear = function () {
+ this.$results.empty();
+ };
+
+ Results.prototype.displayMessage = function (params) {
+ var escapeMarkup = this.options.get('escapeMarkup');
+
+ this.clear();
+ this.hideLoading();
+
+ var $message = $(
+ ' '
+ );
+
+ var message = this.options.get('translations').get(params.message);
+
+ $message.append(
+ escapeMarkup(
+ message(params.args)
+ )
+ );
+
+ $message[0].className += ' select2-results__message';
+
+ this.$results.append($message);
+ };
+
+ Results.prototype.hideMessages = function () {
+ this.$results.find('.select2-results__message').remove();
+ };
+
+ Results.prototype.append = function (data) {
+ this.hideLoading();
+
+ var $options = [];
+
+ if (data.results == null || data.results.length === 0) {
+ if (this.$results.children().length === 0) {
+ this.trigger('results:message', {
+ message: 'noResults'
+ });
+ }
+
+ return;
+ }
+
+ data.results = this.sort(data.results);
+
+ for (var d = 0; d < data.results.length; d++) {
+ var item = data.results[d];
+
+ var $option = this.option(item);
+
+ $options.push($option);
+ }
+
+ this.$results.append($options);
+ };
+
+ Results.prototype.position = function ($results, $dropdown) {
+ var $resultsContainer = $dropdown.find('.select2-results');
+ $resultsContainer.append($results);
+ };
+
+ Results.prototype.sort = function (data) {
+ var sorter = this.options.get('sorter');
+
+ return sorter(data);
+ };
+
+ Results.prototype.highlightFirstItem = function () {
+ var $options = this.$results
+ .find('.select2-results__option[aria-selected]');
+
+ var $selected = $options.filter('[aria-selected=true]');
+
+ // Check if there are any selected options
+ if ($selected.length > 0) {
+ // If there are selected options, highlight the first
+ $selected.first().trigger('mouseenter');
+ } else {
+ // If there are no selected options, highlight the first option
+ // in the dropdown
+ $options.first().trigger('mouseenter');
+ }
+
+ this.ensureHighlightVisible();
+ };
+
+ Results.prototype.setClasses = function () {
+ var self = this;
+
+ this.data.current(function (selected) {
+ var selectedIds = $.map(selected, function (s) {
+ return s.id.toString();
+ });
+
+ var $options = self.$results
+ .find('.select2-results__option[aria-selected]');
+
+ $options.each(function () {
+ var $option = $(this);
+
+ var item = Utils.GetData(this, 'data');
+
+ // id needs to be converted to a string when comparing
+ var id = '' + item.id;
+
+ if ((item.element != null && item.element.selected) ||
+ (item.element == null && $.inArray(id, selectedIds) > -1)) {
+ $option.attr('aria-selected', 'true');
+ } else {
+ $option.attr('aria-selected', 'false');
+ }
+ });
+
+ });
+ };
+
+ Results.prototype.showLoading = function (params) {
+ this.hideLoading();
+
+ var loadingMore = this.options.get('translations').get('searching');
+
+ var loading = {
+ disabled: true,
+ loading: true,
+ text: loadingMore(params)
+ };
+ var $loading = this.option(loading);
+ $loading.className += ' loading-results';
+
+ this.$results.prepend($loading);
+ };
+
+ Results.prototype.hideLoading = function () {
+ this.$results.find('.loading-results').remove();
+ };
+
+ Results.prototype.option = function (data) {
+ var option = document.createElement('li');
+ option.className = 'select2-results__option';
+
+ var attrs = {
+ 'role': 'treeitem',
+ 'aria-selected': 'false'
+ };
+
+ if (data.disabled) {
+ delete attrs['aria-selected'];
+ attrs['aria-disabled'] = 'true';
+ }
+
+ if (data.id == null) {
+ delete attrs['aria-selected'];
+ }
+
+ if (data._resultId != null) {
+ option.id = data._resultId;
+ }
+
+ if (data.title) {
+ option.title = data.title;
+ }
+
+ if (data.children) {
+ attrs.role = 'group';
+ attrs['aria-label'] = data.text;
+ delete attrs['aria-selected'];
+ }
+
+ for (var attr in attrs) {
+ var val = attrs[attr];
+
+ option.setAttribute(attr, val);
+ }
+
+ if (data.children) {
+ var $option = $(option);
+
+ var label = document.createElement('strong');
+ label.className = 'select2-results__group';
+
+ var $label = $(label);
+ this.template(data, label);
+
+ var $children = [];
+
+ for (var c = 0; c < data.children.length; c++) {
+ var child = data.children[c];
+
+ var $child = this.option(child);
+
+ $children.push($child);
+ }
+
+ var $childrenContainer = $('', {
+ 'class': 'select2-results__options select2-results__options--nested'
+ });
+
+ $childrenContainer.append($children);
+
+ $option.append(label);
+ $option.append($childrenContainer);
+ } else {
+ this.template(data, option);
+ }
+
+ Utils.StoreData(option, 'data', data);
+
+ return option;
+ };
+
+ Results.prototype.bind = function (container, $container) {
+ var self = this;
+
+ var id = container.id + '-results';
+
+ this.$results.attr('id', id);
+
+ container.on('results:all', function (params) {
+ self.clear();
+ self.append(params.data);
+
+ if (container.isOpen()) {
+ self.setClasses();
+ self.highlightFirstItem();
+ }
+ });
+
+ container.on('results:append', function (params) {
+ self.append(params.data);
+
+ if (container.isOpen()) {
+ self.setClasses();
+ }
+ });
+
+ container.on('query', function (params) {
+ self.hideMessages();
+ self.showLoading(params);
+ });
+
+ container.on('select', function () {
+ if (!container.isOpen()) {
+ return;
+ }
+
+ self.setClasses();
+ self.highlightFirstItem();
+ });
+
+ container.on('unselect', function () {
+ if (!container.isOpen()) {
+ return;
+ }
+
+ self.setClasses();
+ self.highlightFirstItem();
+ });
+
+ container.on('open', function () {
+ // When the dropdown is open, aria-expended="true"
+ self.$results.attr('aria-expanded', 'true');
+ self.$results.attr('aria-hidden', 'false');
+
+ self.setClasses();
+ self.ensureHighlightVisible();
+ });
+
+ container.on('close', function () {
+ // When the dropdown is closed, aria-expended="false"
+ self.$results.attr('aria-expanded', 'false');
+ self.$results.attr('aria-hidden', 'true');
+ self.$results.removeAttr('aria-activedescendant');
+ });
+
+ container.on('results:toggle', function () {
+ var $highlighted = self.getHighlightedResults();
+
+ if ($highlighted.length === 0) {
+ return;
+ }
+
+ $highlighted.trigger('mouseup');
+ });
+
+ container.on('results:select', function () {
+ var $highlighted = self.getHighlightedResults();
+
+ if ($highlighted.length === 0) {
+ return;
+ }
+
+ var data = Utils.GetData($highlighted[0], 'data');
+
+ if ($highlighted.attr('aria-selected') == 'true') {
+ self.trigger('close', {});
+ } else {
+ self.trigger('select', {
+ data: data
+ });
+ }
+ });
+
+ container.on('results:previous', function () {
+ var $highlighted = self.getHighlightedResults();
+
+ var $options = self.$results.find('[aria-selected]');
+
+ var currentIndex = $options.index($highlighted);
+
+ // If we are already at te top, don't move further
+ // If no options, currentIndex will be -1
+ if (currentIndex <= 0) {
+ return;
+ }
+
+ var nextIndex = currentIndex - 1;
+
+ // If none are highlighted, highlight the first
+ if ($highlighted.length === 0) {
+ nextIndex = 0;
+ }
+
+ var $next = $options.eq(nextIndex);
+
+ $next.trigger('mouseenter');
+
+ var currentOffset = self.$results.offset().top;
+ var nextTop = $next.offset().top;
+ var nextOffset = self.$results.scrollTop() + (nextTop - currentOffset);
+
+ if (nextIndex === 0) {
+ self.$results.scrollTop(0);
+ } else if (nextTop - currentOffset < 0) {
+ self.$results.scrollTop(nextOffset);
+ }
+ });
+
+ container.on('results:next', function () {
+ var $highlighted = self.getHighlightedResults();
+
+ var $options = self.$results.find('[aria-selected]');
+
+ var currentIndex = $options.index($highlighted);
+
+ var nextIndex = currentIndex + 1;
+
+ // If we are at the last option, stay there
+ if (nextIndex >= $options.length) {
+ return;
+ }
+
+ var $next = $options.eq(nextIndex);
+
+ $next.trigger('mouseenter');
+
+ var currentOffset = self.$results.offset().top +
+ self.$results.outerHeight(false);
+ var nextBottom = $next.offset().top + $next.outerHeight(false);
+ var nextOffset = self.$results.scrollTop() + nextBottom - currentOffset;
+
+ if (nextIndex === 0) {
+ self.$results.scrollTop(0);
+ } else if (nextBottom > currentOffset) {
+ self.$results.scrollTop(nextOffset);
+ }
+ });
+
+ container.on('results:focus', function (params) {
+ params.element.addClass('select2-results__option--highlighted');
+ });
+
+ container.on('results:message', function (params) {
+ self.displayMessage(params);
+ });
+
+ if ($.fn.mousewheel) {
+ this.$results.on('mousewheel', function (e) {
+ var top = self.$results.scrollTop();
+
+ var bottom = self.$results.get(0).scrollHeight - top + e.deltaY;
+
+ var isAtTop = e.deltaY > 0 && top - e.deltaY <= 0;
+ var isAtBottom = e.deltaY < 0 && bottom <= self.$results.height();
+
+ if (isAtTop) {
+ self.$results.scrollTop(0);
+
+ e.preventDefault();
+ e.stopPropagation();
+ } else if (isAtBottom) {
+ self.$results.scrollTop(
+ self.$results.get(0).scrollHeight - self.$results.height()
+ );
+
+ e.preventDefault();
+ e.stopPropagation();
+ }
+ });
+ }
+
+ this.$results.on('mouseup', '.select2-results__option[aria-selected]',
+ function (evt) {
+ var $this = $(this);
+
+ var data = Utils.GetData(this, 'data');
+
+ if ($this.attr('aria-selected') === 'true') {
+ if (self.options.get('multiple')) {
+ self.trigger('unselect', {
+ originalEvent: evt,
+ data: data
+ });
+ } else {
+ self.trigger('close', {});
+ }
+
+ return;
+ }
+
+ self.trigger('select', {
+ originalEvent: evt,
+ data: data
+ });
+ });
+
+ this.$results.on('mouseenter', '.select2-results__option[aria-selected]',
+ function (evt) {
+ var data = Utils.GetData(this, 'data');
+
+ self.getHighlightedResults()
+ .removeClass('select2-results__option--highlighted');
+
+ self.trigger('results:focus', {
+ data: data,
+ element: $(this)
+ });
+ });
+ };
+
+ Results.prototype.getHighlightedResults = function () {
+ var $highlighted = this.$results
+ .find('.select2-results__option--highlighted');
+
+ return $highlighted;
+ };
+
+ Results.prototype.destroy = function () {
+ this.$results.remove();
+ };
+
+ Results.prototype.ensureHighlightVisible = function () {
+ var $highlighted = this.getHighlightedResults();
+
+ if ($highlighted.length === 0) {
+ return;
+ }
+
+ var $options = this.$results.find('[aria-selected]');
+
+ var currentIndex = $options.index($highlighted);
+
+ var currentOffset = this.$results.offset().top;
+ var nextTop = $highlighted.offset().top;
+ var nextOffset = this.$results.scrollTop() + (nextTop - currentOffset);
+
+ var offsetDelta = nextTop - currentOffset;
+ nextOffset -= $highlighted.outerHeight(false) * 2;
+
+ if (currentIndex <= 2) {
+ this.$results.scrollTop(0);
+ } else if (offsetDelta > this.$results.outerHeight() || offsetDelta < 0) {
+ this.$results.scrollTop(nextOffset);
+ }
+ };
+
+ Results.prototype.template = function (result, container) {
+ var template = this.options.get('templateResult');
+ var escapeMarkup = this.options.get('escapeMarkup');
+
+ var content = template(result, container);
+
+ if (content == null) {
+ container.style.display = 'none';
+ } else if (typeof content === 'string') {
+ container.innerHTML = escapeMarkup(content);
+ } else {
+ $(container).append(content);
+ }
+ };
+
+ return Results;
+});
+
+S2.define('select2/keys',[
+
+], function () {
+ var KEYS = {
+ BACKSPACE: 8,
+ TAB: 9,
+ ENTER: 13,
+ SHIFT: 16,
+ CTRL: 17,
+ ALT: 18,
+ ESC: 27,
+ SPACE: 32,
+ PAGE_UP: 33,
+ PAGE_DOWN: 34,
+ END: 35,
+ HOME: 36,
+ LEFT: 37,
+ UP: 38,
+ RIGHT: 39,
+ DOWN: 40,
+ DELETE: 46
+ };
+
+ return KEYS;
+});
+
+S2.define('select2/selection/base',[
+ 'jquery',
+ '../utils',
+ '../keys'
+], function ($, Utils, KEYS) {
+ function BaseSelection ($element, options) {
+ this.$element = $element;
+ this.options = options;
+
+ BaseSelection.__super__.constructor.call(this);
+ }
+
+ Utils.Extend(BaseSelection, Utils.Observable);
+
+ BaseSelection.prototype.render = function () {
+ var $selection = $(
+ '' +
+ ' '
+ );
+
+ this._tabindex = 0;
+
+ if (Utils.GetData(this.$element[0], 'old-tabindex') != null) {
+ this._tabindex = Utils.GetData(this.$element[0], 'old-tabindex');
+ } else if (this.$element.attr('tabindex') != null) {
+ this._tabindex = this.$element.attr('tabindex');
+ }
+
+ $selection.attr('title', this.$element.attr('title'));
+ $selection.attr('tabindex', this._tabindex);
+
+ this.$selection = $selection;
+
+ return $selection;
+ };
+
+ BaseSelection.prototype.bind = function (container, $container) {
+ var self = this;
+
+ var id = container.id + '-container';
+ var resultsId = container.id + '-results';
+
+ this.container = container;
+
+ this.$selection.on('focus', function (evt) {
+ self.trigger('focus', evt);
+ });
+
+ this.$selection.on('blur', function (evt) {
+ self._handleBlur(evt);
+ });
+
+ this.$selection.on('keydown', function (evt) {
+ self.trigger('keypress', evt);
+
+ if (evt.which === KEYS.SPACE) {
+ evt.preventDefault();
+ }
+ });
+
+ container.on('results:focus', function (params) {
+ self.$selection.attr('aria-activedescendant', params.data._resultId);
+ });
+
+ container.on('selection:update', function (params) {
+ self.update(params.data);
+ });
+
+ container.on('open', function () {
+ // When the dropdown is open, aria-expanded="true"
+ self.$selection.attr('aria-expanded', 'true');
+ self.$selection.attr('aria-owns', resultsId);
+
+ self._attachCloseHandler(container);
+ });
+
+ container.on('close', function () {
+ // When the dropdown is closed, aria-expanded="false"
+ self.$selection.attr('aria-expanded', 'false');
+ self.$selection.removeAttr('aria-activedescendant');
+ self.$selection.removeAttr('aria-owns');
+
+ self.$selection.focus();
+ window.setTimeout(function () {
+ self.$selection.focus();
+ }, 0);
+
+ self._detachCloseHandler(container);
+ });
+
+ container.on('enable', function () {
+ self.$selection.attr('tabindex', self._tabindex);
+ });
+
+ container.on('disable', function () {
+ self.$selection.attr('tabindex', '-1');
+ });
+ };
+
+ BaseSelection.prototype._handleBlur = function (evt) {
+ var self = this;
+
+ // This needs to be delayed as the active element is the body when the tab
+ // key is pressed, possibly along with others.
+ window.setTimeout(function () {
+ // Don't trigger `blur` if the focus is still in the selection
+ if (
+ (document.activeElement == self.$selection[0]) ||
+ ($.contains(self.$selection[0], document.activeElement))
+ ) {
+ return;
+ }
+
+ self.trigger('blur', evt);
+ }, 1);
+ };
+
+ BaseSelection.prototype._attachCloseHandler = function (container) {
+ var self = this;
+
+ $(document.body).on('mousedown.select2.' + container.id, function (e) {
+ var $target = $(e.target);
+
+ var $select = $target.closest('.select2');
+
+ var $all = $('.select2.select2-container--open');
+
+ $all.each(function () {
+ var $this = $(this);
+
+ if (this == $select[0]) {
+ return;
+ }
+
+ var $element = Utils.GetData(this, 'element');
+
+ $element.select2('close');
+ });
+ });
+ };
+
+ BaseSelection.prototype._detachCloseHandler = function (container) {
+ $(document.body).off('mousedown.select2.' + container.id);
+ };
+
+ BaseSelection.prototype.position = function ($selection, $container) {
+ var $selectionContainer = $container.find('.selection');
+ $selectionContainer.append($selection);
+ };
+
+ BaseSelection.prototype.destroy = function () {
+ this._detachCloseHandler(this.container);
+ };
+
+ BaseSelection.prototype.update = function (data) {
+ throw new Error('The `update` method must be defined in child classes.');
+ };
+
+ return BaseSelection;
+});
+
+S2.define('select2/selection/single',[
+ 'jquery',
+ './base',
+ '../utils',
+ '../keys'
+], function ($, BaseSelection, Utils, KEYS) {
+ function SingleSelection () {
+ SingleSelection.__super__.constructor.apply(this, arguments);
+ }
+
+ Utils.Extend(SingleSelection, BaseSelection);
+
+ SingleSelection.prototype.render = function () {
+ var $selection = SingleSelection.__super__.render.call(this);
+
+ $selection.addClass('select2-selection--single');
+
+ $selection.html(
+ ' ' +
+ '' +
+ ' ' +
+ ' '
+ );
+
+ return $selection;
+ };
+
+ SingleSelection.prototype.bind = function (container, $container) {
+ var self = this;
+
+ SingleSelection.__super__.bind.apply(this, arguments);
+
+ var id = container.id + '-container';
+
+ this.$selection.find('.select2-selection__rendered')
+ .attr('id', id)
+ .attr('role', 'textbox')
+ .attr('aria-readonly', 'true');
+ this.$selection.attr('aria-labelledby', id);
+
+ this.$selection.on('mousedown', function (evt) {
+ // Only respond to left clicks
+ if (evt.which !== 1) {
+ return;
+ }
+
+ self.trigger('toggle', {
+ originalEvent: evt
+ });
+ });
+
+ this.$selection.on('focus', function (evt) {
+ // User focuses on the container
+ });
+
+ this.$selection.on('blur', function (evt) {
+ // User exits the container
+ });
+
+ container.on('focus', function (evt) {
+ if (!container.isOpen()) {
+ self.$selection.focus();
+ }
+ });
+ };
+
+ SingleSelection.prototype.clear = function () {
+ var $rendered = this.$selection.find('.select2-selection__rendered');
+ $rendered.empty();
+ $rendered.removeAttr('title'); // clear tooltip on empty
+ };
+
+ SingleSelection.prototype.display = function (data, container) {
+ var template = this.options.get('templateSelection');
+ var escapeMarkup = this.options.get('escapeMarkup');
+
+ return escapeMarkup(template(data, container));
+ };
+
+ SingleSelection.prototype.selectionContainer = function () {
+ return $(' ');
+ };
+
+ SingleSelection.prototype.update = function (data) {
+ if (data.length === 0) {
+ this.clear();
+ return;
+ }
+
+ var selection = data[0];
+
+ var $rendered = this.$selection.find('.select2-selection__rendered');
+ var formatted = this.display(selection, $rendered);
+
+ $rendered.empty().append(formatted);
+ $rendered.attr('title', selection.title || selection.text);
+ };
+
+ return SingleSelection;
+});
+
+S2.define('select2/selection/multiple',[
+ 'jquery',
+ './base',
+ '../utils'
+], function ($, BaseSelection, Utils) {
+ function MultipleSelection ($element, options) {
+ MultipleSelection.__super__.constructor.apply(this, arguments);
+ }
+
+ Utils.Extend(MultipleSelection, BaseSelection);
+
+ MultipleSelection.prototype.render = function () {
+ var $selection = MultipleSelection.__super__.render.call(this);
+
+ $selection.addClass('select2-selection--multiple');
+
+ $selection.html(
+ ''
+ );
+
+ return $selection;
+ };
+
+ MultipleSelection.prototype.bind = function (container, $container) {
+ var self = this;
+
+ MultipleSelection.__super__.bind.apply(this, arguments);
+
+ this.$selection.on('click', function (evt) {
+ self.trigger('toggle', {
+ originalEvent: evt
+ });
+ });
+
+ this.$selection.on(
+ 'click',
+ '.select2-selection__choice__remove',
+ function (evt) {
+ // Ignore the event if it is disabled
+ if (self.options.get('disabled')) {
+ return;
+ }
+
+ var $remove = $(this);
+ var $selection = $remove.parent();
+
+ var data = Utils.GetData($selection[0], 'data');
+
+ self.trigger('unselect', {
+ originalEvent: evt,
+ data: data
+ });
+ }
+ );
+ };
+
+ MultipleSelection.prototype.clear = function () {
+ var $rendered = this.$selection.find('.select2-selection__rendered');
+ $rendered.empty();
+ $rendered.removeAttr('title');
+ };
+
+ MultipleSelection.prototype.display = function (data, container) {
+ var template = this.options.get('templateSelection');
+ var escapeMarkup = this.options.get('escapeMarkup');
+
+ return escapeMarkup(template(data, container));
+ };
+
+ MultipleSelection.prototype.selectionContainer = function () {
+ var $container = $(
+ '' +
+ '' +
+ '×' +
+ ' ' +
+ ' '
+ );
+
+ return $container;
+ };
+
+ MultipleSelection.prototype.update = function (data) {
+ this.clear();
+
+ if (data.length === 0) {
+ return;
+ }
+
+ var $selections = [];
+
+ for (var d = 0; d < data.length; d++) {
+ var selection = data[d];
+
+ var $selection = this.selectionContainer();
+ var formatted = this.display(selection, $selection);
+
+ $selection.append(formatted);
+ $selection.attr('title', selection.title || selection.text);
+
+ Utils.StoreData($selection[0], 'data', selection);
+
+ $selections.push($selection);
+ }
+
+ var $rendered = this.$selection.find('.select2-selection__rendered');
+
+ Utils.appendMany($rendered, $selections);
+ };
+
+ return MultipleSelection;
+});
+
+S2.define('select2/selection/placeholder',[
+ '../utils'
+], function (Utils) {
+ function Placeholder (decorated, $element, options) {
+ this.placeholder = this.normalizePlaceholder(options.get('placeholder'));
+
+ decorated.call(this, $element, options);
+ }
+
+ Placeholder.prototype.normalizePlaceholder = function (_, placeholder) {
+ if (typeof placeholder === 'string') {
+ placeholder = {
+ id: '',
+ text: placeholder
+ };
+ }
+
+ return placeholder;
+ };
+
+ Placeholder.prototype.createPlaceholder = function (decorated, placeholder) {
+ var $placeholder = this.selectionContainer();
+
+ $placeholder.html(this.display(placeholder));
+ $placeholder.addClass('select2-selection__placeholder')
+ .removeClass('select2-selection__choice');
+
+ return $placeholder;
+ };
+
+ Placeholder.prototype.update = function (decorated, data) {
+ var singlePlaceholder = (
+ data.length == 1 && data[0].id != this.placeholder.id
+ );
+ var multipleSelections = data.length > 1;
+
+ if (multipleSelections || singlePlaceholder) {
+ return decorated.call(this, data);
+ }
+
+ this.clear();
+
+ var $placeholder = this.createPlaceholder(this.placeholder);
+
+ this.$selection.find('.select2-selection__rendered').append($placeholder);
+ };
+
+ return Placeholder;
+});
+
+S2.define('select2/selection/allowClear',[
+ 'jquery',
+ '../keys',
+ '../utils'
+], function ($, KEYS, Utils) {
+ function AllowClear () { }
+
+ AllowClear.prototype.bind = function (decorated, container, $container) {
+ var self = this;
+
+ decorated.call(this, container, $container);
+
+ if (this.placeholder == null) {
+ if (this.options.get('debug') && window.console && console.error) {
+ console.error(
+ 'Select2: The `allowClear` option should be used in combination ' +
+ 'with the `placeholder` option.'
+ );
+ }
+ }
+
+ this.$selection.on('mousedown', '.select2-selection__clear',
+ function (evt) {
+ self._handleClear(evt);
+ });
+
+ container.on('keypress', function (evt) {
+ self._handleKeyboardClear(evt, container);
+ });
+ };
+
+ AllowClear.prototype._handleClear = function (_, evt) {
+ // Ignore the event if it is disabled
+ if (this.options.get('disabled')) {
+ return;
+ }
+
+ var $clear = this.$selection.find('.select2-selection__clear');
+
+ // Ignore the event if nothing has been selected
+ if ($clear.length === 0) {
+ return;
+ }
+
+ evt.stopPropagation();
+
+ var data = Utils.GetData($clear[0], 'data');
+
+ var previousVal = this.$element.val();
+ this.$element.val(this.placeholder.id);
+
+ var unselectData = {
+ data: data
+ };
+ this.trigger('clear', unselectData);
+ if (unselectData.prevented) {
+ this.$element.val(previousVal);
+ return;
+ }
+
+ for (var d = 0; d < data.length; d++) {
+ unselectData = {
+ data: data[d]
+ };
+
+ // Trigger the `unselect` event, so people can prevent it from being
+ // cleared.
+ this.trigger('unselect', unselectData);
+
+ // If the event was prevented, don't clear it out.
+ if (unselectData.prevented) {
+ this.$element.val(previousVal);
+ return;
+ }
+ }
+
+ this.$element.trigger('change');
+
+ this.trigger('toggle', {});
+ };
+
+ AllowClear.prototype._handleKeyboardClear = function (_, evt, container) {
+ if (container.isOpen()) {
+ return;
+ }
+
+ if (evt.which == KEYS.DELETE || evt.which == KEYS.BACKSPACE) {
+ this._handleClear(evt);
+ }
+ };
+
+ AllowClear.prototype.update = function (decorated, data) {
+ decorated.call(this, data);
+
+ if (this.$selection.find('.select2-selection__placeholder').length > 0 ||
+ data.length === 0) {
+ return;
+ }
+
+ var $remove = $(
+ '' +
+ '×' +
+ ' '
+ );
+ Utils.StoreData($remove[0], 'data', data);
+
+ this.$selection.find('.select2-selection__rendered').prepend($remove);
+ };
+
+ return AllowClear;
+});
+
+S2.define('select2/selection/search',[
+ 'jquery',
+ '../utils',
+ '../keys'
+], function ($, Utils, KEYS) {
+ function Search (decorated, $element, options) {
+ decorated.call(this, $element, options);
+ }
+
+ Search.prototype.render = function (decorated) {
+ var $search = $(
+ '' +
+ ' ' +
+ ' '
+ );
+
+ this.$searchContainer = $search;
+ this.$search = $search.find('input');
+
+ var $rendered = decorated.call(this);
+
+ this._transferTabIndex();
+
+ return $rendered;
+ };
+
+ Search.prototype.bind = function (decorated, container, $container) {
+ var self = this;
+
+ decorated.call(this, container, $container);
+
+ container.on('open', function () {
+ self.$search.trigger('focus');
+ });
+
+ container.on('close', function () {
+ self.$search.val('');
+ self.$search.removeAttr('aria-activedescendant');
+ self.$search.trigger('focus');
+ });
+
+ container.on('enable', function () {
+ self.$search.prop('disabled', false);
+
+ self._transferTabIndex();
+ });
+
+ container.on('disable', function () {
+ self.$search.prop('disabled', true);
+ });
+
+ container.on('focus', function (evt) {
+ self.$search.trigger('focus');
+ });
+
+ container.on('results:focus', function (params) {
+ self.$search.attr('aria-activedescendant', params.id);
+ });
+
+ this.$selection.on('focusin', '.select2-search--inline', function (evt) {
+ self.trigger('focus', evt);
+ });
+
+ this.$selection.on('focusout', '.select2-search--inline', function (evt) {
+ self._handleBlur(evt);
+ });
+
+ this.$selection.on('keydown', '.select2-search--inline', function (evt) {
+ evt.stopPropagation();
+
+ self.trigger('keypress', evt);
+
+ self._keyUpPrevented = evt.isDefaultPrevented();
+
+ var key = evt.which;
+
+ if (key === KEYS.BACKSPACE && self.$search.val() === '') {
+ var $previousChoice = self.$searchContainer
+ .prev('.select2-selection__choice');
+
+ if ($previousChoice.length > 0) {
+ var item = Utils.GetData($previousChoice[0], 'data');
+
+ self.searchRemoveChoice(item);
+
+ evt.preventDefault();
+ }
+ }
+ });
+
+ // Try to detect the IE version should the `documentMode` property that
+ // is stored on the document. This is only implemented in IE and is
+ // slightly cleaner than doing a user agent check.
+ // This property is not available in Edge, but Edge also doesn't have
+ // this bug.
+ var msie = document.documentMode;
+ var disableInputEvents = msie && msie <= 11;
+
+ // Workaround for browsers which do not support the `input` event
+ // This will prevent double-triggering of events for browsers which support
+ // both the `keyup` and `input` events.
+ this.$selection.on(
+ 'input.searchcheck',
+ '.select2-search--inline',
+ function (evt) {
+ // IE will trigger the `input` event when a placeholder is used on a
+ // search box. To get around this issue, we are forced to ignore all
+ // `input` events in IE and keep using `keyup`.
+ if (disableInputEvents) {
+ self.$selection.off('input.search input.searchcheck');
+ return;
+ }
+
+ // Unbind the duplicated `keyup` event
+ self.$selection.off('keyup.search');
+ }
+ );
+
+ this.$selection.on(
+ 'keyup.search input.search',
+ '.select2-search--inline',
+ function (evt) {
+ // IE will trigger the `input` event when a placeholder is used on a
+ // search box. To get around this issue, we are forced to ignore all
+ // `input` events in IE and keep using `keyup`.
+ if (disableInputEvents && evt.type === 'input') {
+ self.$selection.off('input.search input.searchcheck');
+ return;
+ }
+
+ var key = evt.which;
+
+ // We can freely ignore events from modifier keys
+ if (key == KEYS.SHIFT || key == KEYS.CTRL || key == KEYS.ALT) {
+ return;
+ }
+
+ // Tabbing will be handled during the `keydown` phase
+ if (key == KEYS.TAB) {
+ return;
+ }
+
+ self.handleSearch(evt);
+ }
+ );
+ };
+
+ /**
+ * This method will transfer the tabindex attribute from the rendered
+ * selection to the search box. This allows for the search box to be used as
+ * the primary focus instead of the selection container.
+ *
+ * @private
+ */
+ Search.prototype._transferTabIndex = function (decorated) {
+ this.$search.attr('tabindex', this.$selection.attr('tabindex'));
+ this.$selection.attr('tabindex', '-1');
+ };
+
+ Search.prototype.createPlaceholder = function (decorated, placeholder) {
+ this.$search.attr('placeholder', placeholder.text);
+ };
+
+ Search.prototype.update = function (decorated, data) {
+ var searchHadFocus = this.$search[0] == document.activeElement;
+
+ this.$search.attr('placeholder', '');
+
+ decorated.call(this, data);
+
+ this.$selection.find('.select2-selection__rendered')
+ .append(this.$searchContainer);
+
+ this.resizeSearch();
+ if (searchHadFocus) {
+ var isTagInput = this.$element.find('[data-select2-tag]').length;
+ if (isTagInput) {
+ // fix IE11 bug where tag input lost focus
+ this.$element.focus();
+ } else {
+ this.$search.focus();
+ }
+ }
+ };
+
+ Search.prototype.handleSearch = function () {
+ this.resizeSearch();
+
+ if (!this._keyUpPrevented) {
+ var input = this.$search.val();
+
+ this.trigger('query', {
+ term: input
+ });
+ }
+
+ this._keyUpPrevented = false;
+ };
+
+ Search.prototype.searchRemoveChoice = function (decorated, item) {
+ this.trigger('unselect', {
+ data: item
+ });
+
+ this.$search.val(item.text);
+ this.handleSearch();
+ };
+
+ Search.prototype.resizeSearch = function () {
+ this.$search.css('width', '25px');
+
+ var width = '';
+
+ if (this.$search.attr('placeholder') !== '') {
+ width = this.$selection.find('.select2-selection__rendered').innerWidth();
+ } else {
+ var minimumWidth = this.$search.val().length + 1;
+
+ width = (minimumWidth * 0.75) + 'em';
+ }
+
+ this.$search.css('width', width);
+ };
+
+ return Search;
+});
+
+S2.define('select2/selection/eventRelay',[
+ 'jquery'
+], function ($) {
+ function EventRelay () { }
+
+ EventRelay.prototype.bind = function (decorated, container, $container) {
+ var self = this;
+ var relayEvents = [
+ 'open', 'opening',
+ 'close', 'closing',
+ 'select', 'selecting',
+ 'unselect', 'unselecting',
+ 'clear', 'clearing'
+ ];
+
+ var preventableEvents = [
+ 'opening', 'closing', 'selecting', 'unselecting', 'clearing'
+ ];
+
+ decorated.call(this, container, $container);
+
+ container.on('*', function (name, params) {
+ // Ignore events that should not be relayed
+ if ($.inArray(name, relayEvents) === -1) {
+ return;
+ }
+
+ // The parameters should always be an object
+ params = params || {};
+
+ // Generate the jQuery event for the Select2 event
+ var evt = $.Event('select2:' + name, {
+ params: params
+ });
+
+ self.$element.trigger(evt);
+
+ // Only handle preventable events if it was one
+ if ($.inArray(name, preventableEvents) === -1) {
+ return;
+ }
+
+ params.prevented = evt.isDefaultPrevented();
+ });
+ };
+
+ return EventRelay;
+});
+
+S2.define('select2/translation',[
+ 'jquery',
+ 'require'
+], function ($, require) {
+ function Translation (dict) {
+ this.dict = dict || {};
+ }
+
+ Translation.prototype.all = function () {
+ return this.dict;
+ };
+
+ Translation.prototype.get = function (key) {
+ return this.dict[key];
+ };
+
+ Translation.prototype.extend = function (translation) {
+ this.dict = $.extend({}, translation.all(), this.dict);
+ };
+
+ // Static functions
+
+ Translation._cache = {};
+
+ Translation.loadPath = function (path) {
+ if (!(path in Translation._cache)) {
+ var translations = require(path);
+
+ Translation._cache[path] = translations;
+ }
+
+ return new Translation(Translation._cache[path]);
+ };
+
+ return Translation;
+});
+
+S2.define('select2/diacritics',[
+
+], function () {
+ var diacritics = {
+ '\u24B6': 'A',
+ '\uFF21': 'A',
+ '\u00C0': 'A',
+ '\u00C1': 'A',
+ '\u00C2': 'A',
+ '\u1EA6': 'A',
+ '\u1EA4': 'A',
+ '\u1EAA': 'A',
+ '\u1EA8': 'A',
+ '\u00C3': 'A',
+ '\u0100': 'A',
+ '\u0102': 'A',
+ '\u1EB0': 'A',
+ '\u1EAE': 'A',
+ '\u1EB4': 'A',
+ '\u1EB2': 'A',
+ '\u0226': 'A',
+ '\u01E0': 'A',
+ '\u00C4': 'A',
+ '\u01DE': 'A',
+ '\u1EA2': 'A',
+ '\u00C5': 'A',
+ '\u01FA': 'A',
+ '\u01CD': 'A',
+ '\u0200': 'A',
+ '\u0202': 'A',
+ '\u1EA0': 'A',
+ '\u1EAC': 'A',
+ '\u1EB6': 'A',
+ '\u1E00': 'A',
+ '\u0104': 'A',
+ '\u023A': 'A',
+ '\u2C6F': 'A',
+ '\uA732': 'AA',
+ '\u00C6': 'AE',
+ '\u01FC': 'AE',
+ '\u01E2': 'AE',
+ '\uA734': 'AO',
+ '\uA736': 'AU',
+ '\uA738': 'AV',
+ '\uA73A': 'AV',
+ '\uA73C': 'AY',
+ '\u24B7': 'B',
+ '\uFF22': 'B',
+ '\u1E02': 'B',
+ '\u1E04': 'B',
+ '\u1E06': 'B',
+ '\u0243': 'B',
+ '\u0182': 'B',
+ '\u0181': 'B',
+ '\u24B8': 'C',
+ '\uFF23': 'C',
+ '\u0106': 'C',
+ '\u0108': 'C',
+ '\u010A': 'C',
+ '\u010C': 'C',
+ '\u00C7': 'C',
+ '\u1E08': 'C',
+ '\u0187': 'C',
+ '\u023B': 'C',
+ '\uA73E': 'C',
+ '\u24B9': 'D',
+ '\uFF24': 'D',
+ '\u1E0A': 'D',
+ '\u010E': 'D',
+ '\u1E0C': 'D',
+ '\u1E10': 'D',
+ '\u1E12': 'D',
+ '\u1E0E': 'D',
+ '\u0110': 'D',
+ '\u018B': 'D',
+ '\u018A': 'D',
+ '\u0189': 'D',
+ '\uA779': 'D',
+ '\u01F1': 'DZ',
+ '\u01C4': 'DZ',
+ '\u01F2': 'Dz',
+ '\u01C5': 'Dz',
+ '\u24BA': 'E',
+ '\uFF25': 'E',
+ '\u00C8': 'E',
+ '\u00C9': 'E',
+ '\u00CA': 'E',
+ '\u1EC0': 'E',
+ '\u1EBE': 'E',
+ '\u1EC4': 'E',
+ '\u1EC2': 'E',
+ '\u1EBC': 'E',
+ '\u0112': 'E',
+ '\u1E14': 'E',
+ '\u1E16': 'E',
+ '\u0114': 'E',
+ '\u0116': 'E',
+ '\u00CB': 'E',
+ '\u1EBA': 'E',
+ '\u011A': 'E',
+ '\u0204': 'E',
+ '\u0206': 'E',
+ '\u1EB8': 'E',
+ '\u1EC6': 'E',
+ '\u0228': 'E',
+ '\u1E1C': 'E',
+ '\u0118': 'E',
+ '\u1E18': 'E',
+ '\u1E1A': 'E',
+ '\u0190': 'E',
+ '\u018E': 'E',
+ '\u24BB': 'F',
+ '\uFF26': 'F',
+ '\u1E1E': 'F',
+ '\u0191': 'F',
+ '\uA77B': 'F',
+ '\u24BC': 'G',
+ '\uFF27': 'G',
+ '\u01F4': 'G',
+ '\u011C': 'G',
+ '\u1E20': 'G',
+ '\u011E': 'G',
+ '\u0120': 'G',
+ '\u01E6': 'G',
+ '\u0122': 'G',
+ '\u01E4': 'G',
+ '\u0193': 'G',
+ '\uA7A0': 'G',
+ '\uA77D': 'G',
+ '\uA77E': 'G',
+ '\u24BD': 'H',
+ '\uFF28': 'H',
+ '\u0124': 'H',
+ '\u1E22': 'H',
+ '\u1E26': 'H',
+ '\u021E': 'H',
+ '\u1E24': 'H',
+ '\u1E28': 'H',
+ '\u1E2A': 'H',
+ '\u0126': 'H',
+ '\u2C67': 'H',
+ '\u2C75': 'H',
+ '\uA78D': 'H',
+ '\u24BE': 'I',
+ '\uFF29': 'I',
+ '\u00CC': 'I',
+ '\u00CD': 'I',
+ '\u00CE': 'I',
+ '\u0128': 'I',
+ '\u012A': 'I',
+ '\u012C': 'I',
+ '\u0130': 'I',
+ '\u00CF': 'I',
+ '\u1E2E': 'I',
+ '\u1EC8': 'I',
+ '\u01CF': 'I',
+ '\u0208': 'I',
+ '\u020A': 'I',
+ '\u1ECA': 'I',
+ '\u012E': 'I',
+ '\u1E2C': 'I',
+ '\u0197': 'I',
+ '\u24BF': 'J',
+ '\uFF2A': 'J',
+ '\u0134': 'J',
+ '\u0248': 'J',
+ '\u24C0': 'K',
+ '\uFF2B': 'K',
+ '\u1E30': 'K',
+ '\u01E8': 'K',
+ '\u1E32': 'K',
+ '\u0136': 'K',
+ '\u1E34': 'K',
+ '\u0198': 'K',
+ '\u2C69': 'K',
+ '\uA740': 'K',
+ '\uA742': 'K',
+ '\uA744': 'K',
+ '\uA7A2': 'K',
+ '\u24C1': 'L',
+ '\uFF2C': 'L',
+ '\u013F': 'L',
+ '\u0139': 'L',
+ '\u013D': 'L',
+ '\u1E36': 'L',
+ '\u1E38': 'L',
+ '\u013B': 'L',
+ '\u1E3C': 'L',
+ '\u1E3A': 'L',
+ '\u0141': 'L',
+ '\u023D': 'L',
+ '\u2C62': 'L',
+ '\u2C60': 'L',
+ '\uA748': 'L',
+ '\uA746': 'L',
+ '\uA780': 'L',
+ '\u01C7': 'LJ',
+ '\u01C8': 'Lj',
+ '\u24C2': 'M',
+ '\uFF2D': 'M',
+ '\u1E3E': 'M',
+ '\u1E40': 'M',
+ '\u1E42': 'M',
+ '\u2C6E': 'M',
+ '\u019C': 'M',
+ '\u24C3': 'N',
+ '\uFF2E': 'N',
+ '\u01F8': 'N',
+ '\u0143': 'N',
+ '\u00D1': 'N',
+ '\u1E44': 'N',
+ '\u0147': 'N',
+ '\u1E46': 'N',
+ '\u0145': 'N',
+ '\u1E4A': 'N',
+ '\u1E48': 'N',
+ '\u0220': 'N',
+ '\u019D': 'N',
+ '\uA790': 'N',
+ '\uA7A4': 'N',
+ '\u01CA': 'NJ',
+ '\u01CB': 'Nj',
+ '\u24C4': 'O',
+ '\uFF2F': 'O',
+ '\u00D2': 'O',
+ '\u00D3': 'O',
+ '\u00D4': 'O',
+ '\u1ED2': 'O',
+ '\u1ED0': 'O',
+ '\u1ED6': 'O',
+ '\u1ED4': 'O',
+ '\u00D5': 'O',
+ '\u1E4C': 'O',
+ '\u022C': 'O',
+ '\u1E4E': 'O',
+ '\u014C': 'O',
+ '\u1E50': 'O',
+ '\u1E52': 'O',
+ '\u014E': 'O',
+ '\u022E': 'O',
+ '\u0230': 'O',
+ '\u00D6': 'O',
+ '\u022A': 'O',
+ '\u1ECE': 'O',
+ '\u0150': 'O',
+ '\u01D1': 'O',
+ '\u020C': 'O',
+ '\u020E': 'O',
+ '\u01A0': 'O',
+ '\u1EDC': 'O',
+ '\u1EDA': 'O',
+ '\u1EE0': 'O',
+ '\u1EDE': 'O',
+ '\u1EE2': 'O',
+ '\u1ECC': 'O',
+ '\u1ED8': 'O',
+ '\u01EA': 'O',
+ '\u01EC': 'O',
+ '\u00D8': 'O',
+ '\u01FE': 'O',
+ '\u0186': 'O',
+ '\u019F': 'O',
+ '\uA74A': 'O',
+ '\uA74C': 'O',
+ '\u01A2': 'OI',
+ '\uA74E': 'OO',
+ '\u0222': 'OU',
+ '\u24C5': 'P',
+ '\uFF30': 'P',
+ '\u1E54': 'P',
+ '\u1E56': 'P',
+ '\u01A4': 'P',
+ '\u2C63': 'P',
+ '\uA750': 'P',
+ '\uA752': 'P',
+ '\uA754': 'P',
+ '\u24C6': 'Q',
+ '\uFF31': 'Q',
+ '\uA756': 'Q',
+ '\uA758': 'Q',
+ '\u024A': 'Q',
+ '\u24C7': 'R',
+ '\uFF32': 'R',
+ '\u0154': 'R',
+ '\u1E58': 'R',
+ '\u0158': 'R',
+ '\u0210': 'R',
+ '\u0212': 'R',
+ '\u1E5A': 'R',
+ '\u1E5C': 'R',
+ '\u0156': 'R',
+ '\u1E5E': 'R',
+ '\u024C': 'R',
+ '\u2C64': 'R',
+ '\uA75A': 'R',
+ '\uA7A6': 'R',
+ '\uA782': 'R',
+ '\u24C8': 'S',
+ '\uFF33': 'S',
+ '\u1E9E': 'S',
+ '\u015A': 'S',
+ '\u1E64': 'S',
+ '\u015C': 'S',
+ '\u1E60': 'S',
+ '\u0160': 'S',
+ '\u1E66': 'S',
+ '\u1E62': 'S',
+ '\u1E68': 'S',
+ '\u0218': 'S',
+ '\u015E': 'S',
+ '\u2C7E': 'S',
+ '\uA7A8': 'S',
+ '\uA784': 'S',
+ '\u24C9': 'T',
+ '\uFF34': 'T',
+ '\u1E6A': 'T',
+ '\u0164': 'T',
+ '\u1E6C': 'T',
+ '\u021A': 'T',
+ '\u0162': 'T',
+ '\u1E70': 'T',
+ '\u1E6E': 'T',
+ '\u0166': 'T',
+ '\u01AC': 'T',
+ '\u01AE': 'T',
+ '\u023E': 'T',
+ '\uA786': 'T',
+ '\uA728': 'TZ',
+ '\u24CA': 'U',
+ '\uFF35': 'U',
+ '\u00D9': 'U',
+ '\u00DA': 'U',
+ '\u00DB': 'U',
+ '\u0168': 'U',
+ '\u1E78': 'U',
+ '\u016A': 'U',
+ '\u1E7A': 'U',
+ '\u016C': 'U',
+ '\u00DC': 'U',
+ '\u01DB': 'U',
+ '\u01D7': 'U',
+ '\u01D5': 'U',
+ '\u01D9': 'U',
+ '\u1EE6': 'U',
+ '\u016E': 'U',
+ '\u0170': 'U',
+ '\u01D3': 'U',
+ '\u0214': 'U',
+ '\u0216': 'U',
+ '\u01AF': 'U',
+ '\u1EEA': 'U',
+ '\u1EE8': 'U',
+ '\u1EEE': 'U',
+ '\u1EEC': 'U',
+ '\u1EF0': 'U',
+ '\u1EE4': 'U',
+ '\u1E72': 'U',
+ '\u0172': 'U',
+ '\u1E76': 'U',
+ '\u1E74': 'U',
+ '\u0244': 'U',
+ '\u24CB': 'V',
+ '\uFF36': 'V',
+ '\u1E7C': 'V',
+ '\u1E7E': 'V',
+ '\u01B2': 'V',
+ '\uA75E': 'V',
+ '\u0245': 'V',
+ '\uA760': 'VY',
+ '\u24CC': 'W',
+ '\uFF37': 'W',
+ '\u1E80': 'W',
+ '\u1E82': 'W',
+ '\u0174': 'W',
+ '\u1E86': 'W',
+ '\u1E84': 'W',
+ '\u1E88': 'W',
+ '\u2C72': 'W',
+ '\u24CD': 'X',
+ '\uFF38': 'X',
+ '\u1E8A': 'X',
+ '\u1E8C': 'X',
+ '\u24CE': 'Y',
+ '\uFF39': 'Y',
+ '\u1EF2': 'Y',
+ '\u00DD': 'Y',
+ '\u0176': 'Y',
+ '\u1EF8': 'Y',
+ '\u0232': 'Y',
+ '\u1E8E': 'Y',
+ '\u0178': 'Y',
+ '\u1EF6': 'Y',
+ '\u1EF4': 'Y',
+ '\u01B3': 'Y',
+ '\u024E': 'Y',
+ '\u1EFE': 'Y',
+ '\u24CF': 'Z',
+ '\uFF3A': 'Z',
+ '\u0179': 'Z',
+ '\u1E90': 'Z',
+ '\u017B': 'Z',
+ '\u017D': 'Z',
+ '\u1E92': 'Z',
+ '\u1E94': 'Z',
+ '\u01B5': 'Z',
+ '\u0224': 'Z',
+ '\u2C7F': 'Z',
+ '\u2C6B': 'Z',
+ '\uA762': 'Z',
+ '\u24D0': 'a',
+ '\uFF41': 'a',
+ '\u1E9A': 'a',
+ '\u00E0': 'a',
+ '\u00E1': 'a',
+ '\u00E2': 'a',
+ '\u1EA7': 'a',
+ '\u1EA5': 'a',
+ '\u1EAB': 'a',
+ '\u1EA9': 'a',
+ '\u00E3': 'a',
+ '\u0101': 'a',
+ '\u0103': 'a',
+ '\u1EB1': 'a',
+ '\u1EAF': 'a',
+ '\u1EB5': 'a',
+ '\u1EB3': 'a',
+ '\u0227': 'a',
+ '\u01E1': 'a',
+ '\u00E4': 'a',
+ '\u01DF': 'a',
+ '\u1EA3': 'a',
+ '\u00E5': 'a',
+ '\u01FB': 'a',
+ '\u01CE': 'a',
+ '\u0201': 'a',
+ '\u0203': 'a',
+ '\u1EA1': 'a',
+ '\u1EAD': 'a',
+ '\u1EB7': 'a',
+ '\u1E01': 'a',
+ '\u0105': 'a',
+ '\u2C65': 'a',
+ '\u0250': 'a',
+ '\uA733': 'aa',
+ '\u00E6': 'ae',
+ '\u01FD': 'ae',
+ '\u01E3': 'ae',
+ '\uA735': 'ao',
+ '\uA737': 'au',
+ '\uA739': 'av',
+ '\uA73B': 'av',
+ '\uA73D': 'ay',
+ '\u24D1': 'b',
+ '\uFF42': 'b',
+ '\u1E03': 'b',
+ '\u1E05': 'b',
+ '\u1E07': 'b',
+ '\u0180': 'b',
+ '\u0183': 'b',
+ '\u0253': 'b',
+ '\u24D2': 'c',
+ '\uFF43': 'c',
+ '\u0107': 'c',
+ '\u0109': 'c',
+ '\u010B': 'c',
+ '\u010D': 'c',
+ '\u00E7': 'c',
+ '\u1E09': 'c',
+ '\u0188': 'c',
+ '\u023C': 'c',
+ '\uA73F': 'c',
+ '\u2184': 'c',
+ '\u24D3': 'd',
+ '\uFF44': 'd',
+ '\u1E0B': 'd',
+ '\u010F': 'd',
+ '\u1E0D': 'd',
+ '\u1E11': 'd',
+ '\u1E13': 'd',
+ '\u1E0F': 'd',
+ '\u0111': 'd',
+ '\u018C': 'd',
+ '\u0256': 'd',
+ '\u0257': 'd',
+ '\uA77A': 'd',
+ '\u01F3': 'dz',
+ '\u01C6': 'dz',
+ '\u24D4': 'e',
+ '\uFF45': 'e',
+ '\u00E8': 'e',
+ '\u00E9': 'e',
+ '\u00EA': 'e',
+ '\u1EC1': 'e',
+ '\u1EBF': 'e',
+ '\u1EC5': 'e',
+ '\u1EC3': 'e',
+ '\u1EBD': 'e',
+ '\u0113': 'e',
+ '\u1E15': 'e',
+ '\u1E17': 'e',
+ '\u0115': 'e',
+ '\u0117': 'e',
+ '\u00EB': 'e',
+ '\u1EBB': 'e',
+ '\u011B': 'e',
+ '\u0205': 'e',
+ '\u0207': 'e',
+ '\u1EB9': 'e',
+ '\u1EC7': 'e',
+ '\u0229': 'e',
+ '\u1E1D': 'e',
+ '\u0119': 'e',
+ '\u1E19': 'e',
+ '\u1E1B': 'e',
+ '\u0247': 'e',
+ '\u025B': 'e',
+ '\u01DD': 'e',
+ '\u24D5': 'f',
+ '\uFF46': 'f',
+ '\u1E1F': 'f',
+ '\u0192': 'f',
+ '\uA77C': 'f',
+ '\u24D6': 'g',
+ '\uFF47': 'g',
+ '\u01F5': 'g',
+ '\u011D': 'g',
+ '\u1E21': 'g',
+ '\u011F': 'g',
+ '\u0121': 'g',
+ '\u01E7': 'g',
+ '\u0123': 'g',
+ '\u01E5': 'g',
+ '\u0260': 'g',
+ '\uA7A1': 'g',
+ '\u1D79': 'g',
+ '\uA77F': 'g',
+ '\u24D7': 'h',
+ '\uFF48': 'h',
+ '\u0125': 'h',
+ '\u1E23': 'h',
+ '\u1E27': 'h',
+ '\u021F': 'h',
+ '\u1E25': 'h',
+ '\u1E29': 'h',
+ '\u1E2B': 'h',
+ '\u1E96': 'h',
+ '\u0127': 'h',
+ '\u2C68': 'h',
+ '\u2C76': 'h',
+ '\u0265': 'h',
+ '\u0195': 'hv',
+ '\u24D8': 'i',
+ '\uFF49': 'i',
+ '\u00EC': 'i',
+ '\u00ED': 'i',
+ '\u00EE': 'i',
+ '\u0129': 'i',
+ '\u012B': 'i',
+ '\u012D': 'i',
+ '\u00EF': 'i',
+ '\u1E2F': 'i',
+ '\u1EC9': 'i',
+ '\u01D0': 'i',
+ '\u0209': 'i',
+ '\u020B': 'i',
+ '\u1ECB': 'i',
+ '\u012F': 'i',
+ '\u1E2D': 'i',
+ '\u0268': 'i',
+ '\u0131': 'i',
+ '\u24D9': 'j',
+ '\uFF4A': 'j',
+ '\u0135': 'j',
+ '\u01F0': 'j',
+ '\u0249': 'j',
+ '\u24DA': 'k',
+ '\uFF4B': 'k',
+ '\u1E31': 'k',
+ '\u01E9': 'k',
+ '\u1E33': 'k',
+ '\u0137': 'k',
+ '\u1E35': 'k',
+ '\u0199': 'k',
+ '\u2C6A': 'k',
+ '\uA741': 'k',
+ '\uA743': 'k',
+ '\uA745': 'k',
+ '\uA7A3': 'k',
+ '\u24DB': 'l',
+ '\uFF4C': 'l',
+ '\u0140': 'l',
+ '\u013A': 'l',
+ '\u013E': 'l',
+ '\u1E37': 'l',
+ '\u1E39': 'l',
+ '\u013C': 'l',
+ '\u1E3D': 'l',
+ '\u1E3B': 'l',
+ '\u017F': 'l',
+ '\u0142': 'l',
+ '\u019A': 'l',
+ '\u026B': 'l',
+ '\u2C61': 'l',
+ '\uA749': 'l',
+ '\uA781': 'l',
+ '\uA747': 'l',
+ '\u01C9': 'lj',
+ '\u24DC': 'm',
+ '\uFF4D': 'm',
+ '\u1E3F': 'm',
+ '\u1E41': 'm',
+ '\u1E43': 'm',
+ '\u0271': 'm',
+ '\u026F': 'm',
+ '\u24DD': 'n',
+ '\uFF4E': 'n',
+ '\u01F9': 'n',
+ '\u0144': 'n',
+ '\u00F1': 'n',
+ '\u1E45': 'n',
+ '\u0148': 'n',
+ '\u1E47': 'n',
+ '\u0146': 'n',
+ '\u1E4B': 'n',
+ '\u1E49': 'n',
+ '\u019E': 'n',
+ '\u0272': 'n',
+ '\u0149': 'n',
+ '\uA791': 'n',
+ '\uA7A5': 'n',
+ '\u01CC': 'nj',
+ '\u24DE': 'o',
+ '\uFF4F': 'o',
+ '\u00F2': 'o',
+ '\u00F3': 'o',
+ '\u00F4': 'o',
+ '\u1ED3': 'o',
+ '\u1ED1': 'o',
+ '\u1ED7': 'o',
+ '\u1ED5': 'o',
+ '\u00F5': 'o',
+ '\u1E4D': 'o',
+ '\u022D': 'o',
+ '\u1E4F': 'o',
+ '\u014D': 'o',
+ '\u1E51': 'o',
+ '\u1E53': 'o',
+ '\u014F': 'o',
+ '\u022F': 'o',
+ '\u0231': 'o',
+ '\u00F6': 'o',
+ '\u022B': 'o',
+ '\u1ECF': 'o',
+ '\u0151': 'o',
+ '\u01D2': 'o',
+ '\u020D': 'o',
+ '\u020F': 'o',
+ '\u01A1': 'o',
+ '\u1EDD': 'o',
+ '\u1EDB': 'o',
+ '\u1EE1': 'o',
+ '\u1EDF': 'o',
+ '\u1EE3': 'o',
+ '\u1ECD': 'o',
+ '\u1ED9': 'o',
+ '\u01EB': 'o',
+ '\u01ED': 'o',
+ '\u00F8': 'o',
+ '\u01FF': 'o',
+ '\u0254': 'o',
+ '\uA74B': 'o',
+ '\uA74D': 'o',
+ '\u0275': 'o',
+ '\u01A3': 'oi',
+ '\u0223': 'ou',
+ '\uA74F': 'oo',
+ '\u24DF': 'p',
+ '\uFF50': 'p',
+ '\u1E55': 'p',
+ '\u1E57': 'p',
+ '\u01A5': 'p',
+ '\u1D7D': 'p',
+ '\uA751': 'p',
+ '\uA753': 'p',
+ '\uA755': 'p',
+ '\u24E0': 'q',
+ '\uFF51': 'q',
+ '\u024B': 'q',
+ '\uA757': 'q',
+ '\uA759': 'q',
+ '\u24E1': 'r',
+ '\uFF52': 'r',
+ '\u0155': 'r',
+ '\u1E59': 'r',
+ '\u0159': 'r',
+ '\u0211': 'r',
+ '\u0213': 'r',
+ '\u1E5B': 'r',
+ '\u1E5D': 'r',
+ '\u0157': 'r',
+ '\u1E5F': 'r',
+ '\u024D': 'r',
+ '\u027D': 'r',
+ '\uA75B': 'r',
+ '\uA7A7': 'r',
+ '\uA783': 'r',
+ '\u24E2': 's',
+ '\uFF53': 's',
+ '\u00DF': 's',
+ '\u015B': 's',
+ '\u1E65': 's',
+ '\u015D': 's',
+ '\u1E61': 's',
+ '\u0161': 's',
+ '\u1E67': 's',
+ '\u1E63': 's',
+ '\u1E69': 's',
+ '\u0219': 's',
+ '\u015F': 's',
+ '\u023F': 's',
+ '\uA7A9': 's',
+ '\uA785': 's',
+ '\u1E9B': 's',
+ '\u24E3': 't',
+ '\uFF54': 't',
+ '\u1E6B': 't',
+ '\u1E97': 't',
+ '\u0165': 't',
+ '\u1E6D': 't',
+ '\u021B': 't',
+ '\u0163': 't',
+ '\u1E71': 't',
+ '\u1E6F': 't',
+ '\u0167': 't',
+ '\u01AD': 't',
+ '\u0288': 't',
+ '\u2C66': 't',
+ '\uA787': 't',
+ '\uA729': 'tz',
+ '\u24E4': 'u',
+ '\uFF55': 'u',
+ '\u00F9': 'u',
+ '\u00FA': 'u',
+ '\u00FB': 'u',
+ '\u0169': 'u',
+ '\u1E79': 'u',
+ '\u016B': 'u',
+ '\u1E7B': 'u',
+ '\u016D': 'u',
+ '\u00FC': 'u',
+ '\u01DC': 'u',
+ '\u01D8': 'u',
+ '\u01D6': 'u',
+ '\u01DA': 'u',
+ '\u1EE7': 'u',
+ '\u016F': 'u',
+ '\u0171': 'u',
+ '\u01D4': 'u',
+ '\u0215': 'u',
+ '\u0217': 'u',
+ '\u01B0': 'u',
+ '\u1EEB': 'u',
+ '\u1EE9': 'u',
+ '\u1EEF': 'u',
+ '\u1EED': 'u',
+ '\u1EF1': 'u',
+ '\u1EE5': 'u',
+ '\u1E73': 'u',
+ '\u0173': 'u',
+ '\u1E77': 'u',
+ '\u1E75': 'u',
+ '\u0289': 'u',
+ '\u24E5': 'v',
+ '\uFF56': 'v',
+ '\u1E7D': 'v',
+ '\u1E7F': 'v',
+ '\u028B': 'v',
+ '\uA75F': 'v',
+ '\u028C': 'v',
+ '\uA761': 'vy',
+ '\u24E6': 'w',
+ '\uFF57': 'w',
+ '\u1E81': 'w',
+ '\u1E83': 'w',
+ '\u0175': 'w',
+ '\u1E87': 'w',
+ '\u1E85': 'w',
+ '\u1E98': 'w',
+ '\u1E89': 'w',
+ '\u2C73': 'w',
+ '\u24E7': 'x',
+ '\uFF58': 'x',
+ '\u1E8B': 'x',
+ '\u1E8D': 'x',
+ '\u24E8': 'y',
+ '\uFF59': 'y',
+ '\u1EF3': 'y',
+ '\u00FD': 'y',
+ '\u0177': 'y',
+ '\u1EF9': 'y',
+ '\u0233': 'y',
+ '\u1E8F': 'y',
+ '\u00FF': 'y',
+ '\u1EF7': 'y',
+ '\u1E99': 'y',
+ '\u1EF5': 'y',
+ '\u01B4': 'y',
+ '\u024F': 'y',
+ '\u1EFF': 'y',
+ '\u24E9': 'z',
+ '\uFF5A': 'z',
+ '\u017A': 'z',
+ '\u1E91': 'z',
+ '\u017C': 'z',
+ '\u017E': 'z',
+ '\u1E93': 'z',
+ '\u1E95': 'z',
+ '\u01B6': 'z',
+ '\u0225': 'z',
+ '\u0240': 'z',
+ '\u2C6C': 'z',
+ '\uA763': 'z',
+ '\u0386': '\u0391',
+ '\u0388': '\u0395',
+ '\u0389': '\u0397',
+ '\u038A': '\u0399',
+ '\u03AA': '\u0399',
+ '\u038C': '\u039F',
+ '\u038E': '\u03A5',
+ '\u03AB': '\u03A5',
+ '\u038F': '\u03A9',
+ '\u03AC': '\u03B1',
+ '\u03AD': '\u03B5',
+ '\u03AE': '\u03B7',
+ '\u03AF': '\u03B9',
+ '\u03CA': '\u03B9',
+ '\u0390': '\u03B9',
+ '\u03CC': '\u03BF',
+ '\u03CD': '\u03C5',
+ '\u03CB': '\u03C5',
+ '\u03B0': '\u03C5',
+ '\u03C9': '\u03C9',
+ '\u03C2': '\u03C3'
+ };
+
+ return diacritics;
+});
+
+S2.define('select2/data/base',[
+ '../utils'
+], function (Utils) {
+ function BaseAdapter ($element, options) {
+ BaseAdapter.__super__.constructor.call(this);
+ }
+
+ Utils.Extend(BaseAdapter, Utils.Observable);
+
+ BaseAdapter.prototype.current = function (callback) {
+ throw new Error('The `current` method must be defined in child classes.');
+ };
+
+ BaseAdapter.prototype.query = function (params, callback) {
+ throw new Error('The `query` method must be defined in child classes.');
+ };
+
+ BaseAdapter.prototype.bind = function (container, $container) {
+ // Can be implemented in subclasses
+ };
+
+ BaseAdapter.prototype.destroy = function () {
+ // Can be implemented in subclasses
+ };
+
+ BaseAdapter.prototype.generateResultId = function (container, data) {
+ var id = container.id + '-result-';
+
+ id += Utils.generateChars(4);
+
+ if (data.id != null) {
+ id += '-' + data.id.toString();
+ } else {
+ id += '-' + Utils.generateChars(4);
+ }
+ return id;
+ };
+
+ return BaseAdapter;
+});
+
+S2.define('select2/data/select',[
+ './base',
+ '../utils',
+ 'jquery'
+], function (BaseAdapter, Utils, $) {
+ function SelectAdapter ($element, options) {
+ this.$element = $element;
+ this.options = options;
+
+ SelectAdapter.__super__.constructor.call(this);
+ }
+
+ Utils.Extend(SelectAdapter, BaseAdapter);
+
+ SelectAdapter.prototype.current = function (callback) {
+ var data = [];
+ var self = this;
+
+ this.$element.find(':selected').each(function () {
+ var $option = $(this);
+
+ var option = self.item($option);
+
+ data.push(option);
+ });
+
+ callback(data);
+ };
+
+ SelectAdapter.prototype.select = function (data) {
+ var self = this;
+
+ data.selected = true;
+
+ // If data.element is a DOM node, use it instead
+ if ($(data.element).is('option')) {
+ data.element.selected = true;
+
+ this.$element.trigger('change');
+
+ return;
+ }
+
+ if (this.$element.prop('multiple')) {
+ this.current(function (currentData) {
+ var val = [];
+
+ data = [data];
+ data.push.apply(data, currentData);
+
+ for (var d = 0; d < data.length; d++) {
+ var id = data[d].id;
+
+ if ($.inArray(id, val) === -1) {
+ val.push(id);
+ }
+ }
+
+ self.$element.val(val);
+ self.$element.trigger('change');
+ });
+ } else {
+ var val = data.id;
+
+ this.$element.val(val);
+ this.$element.trigger('change');
+ }
+ };
+
+ SelectAdapter.prototype.unselect = function (data) {
+ var self = this;
+
+ if (!this.$element.prop('multiple')) {
+ return;
+ }
+
+ data.selected = false;
+
+ if ($(data.element).is('option')) {
+ data.element.selected = false;
+
+ this.$element.trigger('change');
+
+ return;
+ }
+
+ this.current(function (currentData) {
+ var val = [];
+
+ for (var d = 0; d < currentData.length; d++) {
+ var id = currentData[d].id;
+
+ if (id !== data.id && $.inArray(id, val) === -1) {
+ val.push(id);
+ }
+ }
+
+ self.$element.val(val);
+
+ self.$element.trigger('change');
+ });
+ };
+
+ SelectAdapter.prototype.bind = function (container, $container) {
+ var self = this;
+
+ this.container = container;
+
+ container.on('select', function (params) {
+ self.select(params.data);
+ });
+
+ container.on('unselect', function (params) {
+ self.unselect(params.data);
+ });
+ };
+
+ SelectAdapter.prototype.destroy = function () {
+ // Remove anything added to child elements
+ this.$element.find('*').each(function () {
+ // Remove any custom data set by Select2
+ Utils.RemoveData(this);
+ });
+ };
+
+ SelectAdapter.prototype.query = function (params, callback) {
+ var data = [];
+ var self = this;
+
+ var $options = this.$element.children();
+
+ $options.each(function () {
+ var $option = $(this);
+
+ if (!$option.is('option') && !$option.is('optgroup')) {
+ return;
+ }
+
+ var option = self.item($option);
+
+ var matches = self.matches(params, option);
+
+ if (matches !== null) {
+ data.push(matches);
+ }
+ });
+
+ callback({
+ results: data
+ });
+ };
+
+ SelectAdapter.prototype.addOptions = function ($options) {
+ Utils.appendMany(this.$element, $options);
+ };
+
+ SelectAdapter.prototype.option = function (data) {
+ var option;
+
+ if (data.children) {
+ option = document.createElement('optgroup');
+ option.label = data.text;
+ } else {
+ option = document.createElement('option');
+
+ if (option.textContent !== undefined) {
+ option.textContent = data.text;
+ } else {
+ option.innerText = data.text;
+ }
+ }
+
+ if (data.id !== undefined) {
+ option.value = data.id;
+ }
+
+ if (data.disabled) {
+ option.disabled = true;
+ }
+
+ if (data.selected) {
+ option.selected = true;
+ }
+
+ if (data.title) {
+ option.title = data.title;
+ }
+
+ var $option = $(option);
+
+ var normalizedData = this._normalizeItem(data);
+ normalizedData.element = option;
+
+ // Override the option's data with the combined data
+ Utils.StoreData(option, 'data', normalizedData);
+
+ return $option;
+ };
+
+ SelectAdapter.prototype.item = function ($option) {
+ var data = {};
+
+ data = Utils.GetData($option[0], 'data');
+
+ if (data != null) {
+ return data;
+ }
+
+ if ($option.is('option')) {
+ data = {
+ id: $option.val(),
+ text: $option.text(),
+ disabled: $option.prop('disabled'),
+ selected: $option.prop('selected'),
+ title: $option.prop('title')
+ };
+ } else if ($option.is('optgroup')) {
+ data = {
+ text: $option.prop('label'),
+ children: [],
+ title: $option.prop('title')
+ };
+
+ var $children = $option.children('option');
+ var children = [];
+
+ for (var c = 0; c < $children.length; c++) {
+ var $child = $($children[c]);
+
+ var child = this.item($child);
+
+ children.push(child);
+ }
+
+ data.children = children;
+ }
+
+ data = this._normalizeItem(data);
+ data.element = $option[0];
+
+ Utils.StoreData($option[0], 'data', data);
+
+ return data;
+ };
+
+ SelectAdapter.prototype._normalizeItem = function (item) {
+ if (item !== Object(item)) {
+ item = {
+ id: item,
+ text: item
+ };
+ }
+
+ item = $.extend({}, {
+ text: ''
+ }, item);
+
+ var defaults = {
+ selected: false,
+ disabled: false
+ };
+
+ if (item.id != null) {
+ item.id = item.id.toString();
+ }
+
+ if (item.text != null) {
+ item.text = item.text.toString();
+ }
+
+ if (item._resultId == null && item.id && this.container != null) {
+ item._resultId = this.generateResultId(this.container, item);
+ }
+
+ return $.extend({}, defaults, item);
+ };
+
+ SelectAdapter.prototype.matches = function (params, data) {
+ var matcher = this.options.get('matcher');
+
+ return matcher(params, data);
+ };
+
+ return SelectAdapter;
+});
+
+S2.define('select2/data/array',[
+ './select',
+ '../utils',
+ 'jquery'
+], function (SelectAdapter, Utils, $) {
+ function ArrayAdapter ($element, options) {
+ var data = options.get('data') || [];
+
+ ArrayAdapter.__super__.constructor.call(this, $element, options);
+
+ this.addOptions(this.convertToOptions(data));
+ }
+
+ Utils.Extend(ArrayAdapter, SelectAdapter);
+
+ ArrayAdapter.prototype.select = function (data) {
+ var $option = this.$element.find('option').filter(function (i, elm) {
+ return elm.value == data.id.toString();
+ });
+
+ if ($option.length === 0) {
+ $option = this.option(data);
+
+ this.addOptions($option);
+ }
+
+ ArrayAdapter.__super__.select.call(this, data);
+ };
+
+ ArrayAdapter.prototype.convertToOptions = function (data) {
+ var self = this;
+
+ var $existing = this.$element.find('option');
+ var existingIds = $existing.map(function () {
+ return self.item($(this)).id;
+ }).get();
+
+ var $options = [];
+
+ // Filter out all items except for the one passed in the argument
+ function onlyItem (item) {
+ return function () {
+ return $(this).val() == item.id;
+ };
+ }
+
+ for (var d = 0; d < data.length; d++) {
+ var item = this._normalizeItem(data[d]);
+
+ // Skip items which were pre-loaded, only merge the data
+ if ($.inArray(item.id, existingIds) >= 0) {
+ var $existingOption = $existing.filter(onlyItem(item));
+
+ var existingData = this.item($existingOption);
+ var newData = $.extend(true, {}, item, existingData);
+
+ var $newOption = this.option(newData);
+
+ $existingOption.replaceWith($newOption);
+
+ continue;
+ }
+
+ var $option = this.option(item);
+
+ if (item.children) {
+ var $children = this.convertToOptions(item.children);
+
+ Utils.appendMany($option, $children);
+ }
+
+ $options.push($option);
+ }
+
+ return $options;
+ };
+
+ return ArrayAdapter;
+});
+
+S2.define('select2/data/ajax',[
+ './array',
+ '../utils',
+ 'jquery'
+], function (ArrayAdapter, Utils, $) {
+ function AjaxAdapter ($element, options) {
+ this.ajaxOptions = this._applyDefaults(options.get('ajax'));
+
+ if (this.ajaxOptions.processResults != null) {
+ this.processResults = this.ajaxOptions.processResults;
+ }
+
+ AjaxAdapter.__super__.constructor.call(this, $element, options);
+ }
+
+ Utils.Extend(AjaxAdapter, ArrayAdapter);
+
+ AjaxAdapter.prototype._applyDefaults = function (options) {
+ var defaults = {
+ data: function (params) {
+ return $.extend({}, params, {
+ q: params.term
+ });
+ },
+ transport: function (params, success, failure) {
+ var $request = $.ajax(params);
+
+ $request.then(success);
+ $request.fail(failure);
+
+ return $request;
+ }
+ };
+
+ return $.extend({}, defaults, options, true);
+ };
+
+ AjaxAdapter.prototype.processResults = function (results) {
+ return results;
+ };
+
+ AjaxAdapter.prototype.query = function (params, callback) {
+ var matches = [];
+ var self = this;
+
+ if (this._request != null) {
+ // JSONP requests cannot always be aborted
+ if ($.isFunction(this._request.abort)) {
+ this._request.abort();
+ }
+
+ this._request = null;
+ }
+
+ var options = $.extend({
+ type: 'GET'
+ }, this.ajaxOptions);
+
+ if (typeof options.url === 'function') {
+ options.url = options.url.call(this.$element, params);
+ }
+
+ if (typeof options.data === 'function') {
+ options.data = options.data.call(this.$element, params);
+ }
+
+ function request () {
+ var $request = options.transport(options, function (data) {
+ var results = self.processResults(data, params);
+
+ if (self.options.get('debug') && window.console && console.error) {
+ // Check to make sure that the response included a `results` key.
+ if (!results || !results.results || !$.isArray(results.results)) {
+ console.error(
+ 'Select2: The AJAX results did not return an array in the ' +
+ '`results` key of the response.'
+ );
+ }
+ }
+
+ callback(results);
+ }, function () {
+ // Attempt to detect if a request was aborted
+ // Only works if the transport exposes a status property
+ if ('status' in $request &&
+ ($request.status === 0 || $request.status === '0')) {
+ return;
+ }
+
+ self.trigger('results:message', {
+ message: 'errorLoading'
+ });
+ });
+
+ self._request = $request;
+ }
+
+ if (this.ajaxOptions.delay && params.term != null) {
+ if (this._queryTimeout) {
+ window.clearTimeout(this._queryTimeout);
+ }
+
+ this._queryTimeout = window.setTimeout(request, this.ajaxOptions.delay);
+ } else {
+ request();
+ }
+ };
+
+ return AjaxAdapter;
+});
+
+S2.define('select2/data/tags',[
+ 'jquery'
+], function ($) {
+ function Tags (decorated, $element, options) {
+ var tags = options.get('tags');
+
+ var createTag = options.get('createTag');
+
+ if (createTag !== undefined) {
+ this.createTag = createTag;
+ }
+
+ var insertTag = options.get('insertTag');
+
+ if (insertTag !== undefined) {
+ this.insertTag = insertTag;
+ }
+
+ decorated.call(this, $element, options);
+
+ if ($.isArray(tags)) {
+ for (var t = 0; t < tags.length; t++) {
+ var tag = tags[t];
+ var item = this._normalizeItem(tag);
+
+ var $option = this.option(item);
+
+ this.$element.append($option);
+ }
+ }
+ }
+
+ Tags.prototype.query = function (decorated, params, callback) {
+ var self = this;
+
+ this._removeOldTags();
+
+ if (params.term == null || params.page != null) {
+ decorated.call(this, params, callback);
+ return;
+ }
+
+ function wrapper (obj, child) {
+ var data = obj.results;
+
+ for (var i = 0; i < data.length; i++) {
+ var option = data[i];
+
+ var checkChildren = (
+ option.children != null &&
+ !wrapper({
+ results: option.children
+ }, true)
+ );
+
+ var optionText = (option.text || '').toUpperCase();
+ var paramsTerm = (params.term || '').toUpperCase();
+
+ var checkText = optionText === paramsTerm;
+
+ if (checkText || checkChildren) {
+ if (child) {
+ return false;
+ }
+
+ obj.data = data;
+ callback(obj);
+
+ return;
+ }
+ }
+
+ if (child) {
+ return true;
+ }
+
+ var tag = self.createTag(params);
+
+ if (tag != null) {
+ var $option = self.option(tag);
+ $option.attr('data-select2-tag', true);
+
+ self.addOptions([$option]);
+
+ self.insertTag(data, tag);
+ }
+
+ obj.results = data;
+
+ callback(obj);
+ }
+
+ decorated.call(this, params, wrapper);
+ };
+
+ Tags.prototype.createTag = function (decorated, params) {
+ var term = $.trim(params.term);
+
+ if (term === '') {
+ return null;
+ }
+
+ return {
+ id: term,
+ text: term
+ };
+ };
+
+ Tags.prototype.insertTag = function (_, data, tag) {
+ data.unshift(tag);
+ };
+
+ Tags.prototype._removeOldTags = function (_) {
+ var tag = this._lastTag;
+
+ var $options = this.$element.find('option[data-select2-tag]');
+
+ $options.each(function () {
+ if (this.selected) {
+ return;
+ }
+
+ $(this).remove();
+ });
+ };
+
+ return Tags;
+});
+
+S2.define('select2/data/tokenizer',[
+ 'jquery'
+], function ($) {
+ function Tokenizer (decorated, $element, options) {
+ var tokenizer = options.get('tokenizer');
+
+ if (tokenizer !== undefined) {
+ this.tokenizer = tokenizer;
+ }
+
+ decorated.call(this, $element, options);
+ }
+
+ Tokenizer.prototype.bind = function (decorated, container, $container) {
+ decorated.call(this, container, $container);
+
+ this.$search = container.dropdown.$search || container.selection.$search ||
+ $container.find('.select2-search__field');
+ };
+
+ Tokenizer.prototype.query = function (decorated, params, callback) {
+ var self = this;
+
+ function createAndSelect (data) {
+ // Normalize the data object so we can use it for checks
+ var item = self._normalizeItem(data);
+
+ // Check if the data object already exists as a tag
+ // Select it if it doesn't
+ var $existingOptions = self.$element.find('option').filter(function () {
+ return $(this).val() === item.id;
+ });
+
+ // If an existing option wasn't found for it, create the option
+ if (!$existingOptions.length) {
+ var $option = self.option(item);
+ $option.attr('data-select2-tag', true);
+
+ self._removeOldTags();
+ self.addOptions([$option]);
+ }
+
+ // Select the item, now that we know there is an option for it
+ select(item);
+ }
+
+ function select (data) {
+ self.trigger('select', {
+ data: data
+ });
+ }
+
+ params.term = params.term || '';
+
+ var tokenData = this.tokenizer(params, this.options, createAndSelect);
+
+ if (tokenData.term !== params.term) {
+ // Replace the search term if we have the search box
+ if (this.$search.length) {
+ this.$search.val(tokenData.term);
+ this.$search.focus();
+ }
+
+ params.term = tokenData.term;
+ }
+
+ decorated.call(this, params, callback);
+ };
+
+ Tokenizer.prototype.tokenizer = function (_, params, options, callback) {
+ var separators = options.get('tokenSeparators') || [];
+ var term = params.term;
+ var i = 0;
+
+ var createTag = this.createTag || function (params) {
+ return {
+ id: params.term,
+ text: params.term
+ };
+ };
+
+ while (i < term.length) {
+ var termChar = term[i];
+
+ if ($.inArray(termChar, separators) === -1) {
+ i++;
+
+ continue;
+ }
+
+ var part = term.substr(0, i);
+ var partParams = $.extend({}, params, {
+ term: part
+ });
+
+ var data = createTag(partParams);
+
+ if (data == null) {
+ i++;
+ continue;
+ }
+
+ callback(data);
+
+ // Reset the term to not include the tokenized portion
+ term = term.substr(i + 1) || '';
+ i = 0;
+ }
+
+ return {
+ term: term
+ };
+ };
+
+ return Tokenizer;
+});
+
+S2.define('select2/data/minimumInputLength',[
+
+], function () {
+ function MinimumInputLength (decorated, $e, options) {
+ this.minimumInputLength = options.get('minimumInputLength');
+
+ decorated.call(this, $e, options);
+ }
+
+ MinimumInputLength.prototype.query = function (decorated, params, callback) {
+ params.term = params.term || '';
+
+ if (params.term.length < this.minimumInputLength) {
+ this.trigger('results:message', {
+ message: 'inputTooShort',
+ args: {
+ minimum: this.minimumInputLength,
+ input: params.term,
+ params: params
+ }
+ });
+
+ return;
+ }
+
+ decorated.call(this, params, callback);
+ };
+
+ return MinimumInputLength;
+});
+
+S2.define('select2/data/maximumInputLength',[
+
+], function () {
+ function MaximumInputLength (decorated, $e, options) {
+ this.maximumInputLength = options.get('maximumInputLength');
+
+ decorated.call(this, $e, options);
+ }
+
+ MaximumInputLength.prototype.query = function (decorated, params, callback) {
+ params.term = params.term || '';
+
+ if (this.maximumInputLength > 0 &&
+ params.term.length > this.maximumInputLength) {
+ this.trigger('results:message', {
+ message: 'inputTooLong',
+ args: {
+ maximum: this.maximumInputLength,
+ input: params.term,
+ params: params
+ }
+ });
+
+ return;
+ }
+
+ decorated.call(this, params, callback);
+ };
+
+ return MaximumInputLength;
+});
+
+S2.define('select2/data/maximumSelectionLength',[
+
+], function (){
+ function MaximumSelectionLength (decorated, $e, options) {
+ this.maximumSelectionLength = options.get('maximumSelectionLength');
+
+ decorated.call(this, $e, options);
+ }
+
+ MaximumSelectionLength.prototype.query =
+ function (decorated, params, callback) {
+ var self = this;
+
+ this.current(function (currentData) {
+ var count = currentData != null ? currentData.length : 0;
+ if (self.maximumSelectionLength > 0 &&
+ count >= self.maximumSelectionLength) {
+ self.trigger('results:message', {
+ message: 'maximumSelected',
+ args: {
+ maximum: self.maximumSelectionLength
+ }
+ });
+ return;
+ }
+ decorated.call(self, params, callback);
+ });
+ };
+
+ return MaximumSelectionLength;
+});
+
+S2.define('select2/dropdown',[
+ 'jquery',
+ './utils'
+], function ($, Utils) {
+ function Dropdown ($element, options) {
+ this.$element = $element;
+ this.options = options;
+
+ Dropdown.__super__.constructor.call(this);
+ }
+
+ Utils.Extend(Dropdown, Utils.Observable);
+
+ Dropdown.prototype.render = function () {
+ var $dropdown = $(
+ '' +
+ ' ' +
+ ' '
+ );
+
+ $dropdown.attr('dir', this.options.get('dir'));
+
+ this.$dropdown = $dropdown;
+
+ return $dropdown;
+ };
+
+ Dropdown.prototype.bind = function () {
+ // Should be implemented in subclasses
+ };
+
+ Dropdown.prototype.position = function ($dropdown, $container) {
+ // Should be implmented in subclasses
+ };
+
+ Dropdown.prototype.destroy = function () {
+ // Remove the dropdown from the DOM
+ this.$dropdown.remove();
+ };
+
+ return Dropdown;
+});
+
+S2.define('select2/dropdown/search',[
+ 'jquery',
+ '../utils'
+], function ($, Utils) {
+ function Search () { }
+
+ Search.prototype.render = function (decorated) {
+ var $rendered = decorated.call(this);
+
+ var $search = $(
+ '' +
+ ' ' +
+ ' '
+ );
+
+ this.$searchContainer = $search;
+ this.$search = $search.find('input');
+
+ $rendered.prepend($search);
+
+ return $rendered;
+ };
+
+ Search.prototype.bind = function (decorated, container, $container) {
+ var self = this;
+
+ decorated.call(this, container, $container);
+
+ this.$search.on('keydown', function (evt) {
+ self.trigger('keypress', evt);
+
+ self._keyUpPrevented = evt.isDefaultPrevented();
+ });
+
+ // Workaround for browsers which do not support the `input` event
+ // This will prevent double-triggering of events for browsers which support
+ // both the `keyup` and `input` events.
+ this.$search.on('input', function (evt) {
+ // Unbind the duplicated `keyup` event
+ $(this).off('keyup');
+ });
+
+ this.$search.on('keyup input', function (evt) {
+ self.handleSearch(evt);
+ });
+
+ container.on('open', function () {
+ self.$search.attr('tabindex', 0);
+
+ self.$search.focus();
+
+ window.setTimeout(function () {
+ self.$search.focus();
+ }, 0);
+ });
+
+ container.on('close', function () {
+ self.$search.attr('tabindex', -1);
+
+ self.$search.val('');
+ self.$search.blur();
+ });
+
+ container.on('focus', function () {
+ if (!container.isOpen()) {
+ self.$search.focus();
+ }
+ });
+
+ container.on('results:all', function (params) {
+ if (params.query.term == null || params.query.term === '') {
+ var showSearch = self.showSearch(params);
+
+ if (showSearch) {
+ self.$searchContainer.removeClass('select2-search--hide');
+ } else {
+ self.$searchContainer.addClass('select2-search--hide');
+ }
+ }
+ });
+ };
+
+ Search.prototype.handleSearch = function (evt) {
+ if (!this._keyUpPrevented) {
+ var input = this.$search.val();
+
+ this.trigger('query', {
+ term: input
+ });
+ }
+
+ this._keyUpPrevented = false;
+ };
+
+ Search.prototype.showSearch = function (_, params) {
+ return true;
+ };
+
+ return Search;
+});
+
+S2.define('select2/dropdown/hidePlaceholder',[
+
+], function () {
+ function HidePlaceholder (decorated, $element, options, dataAdapter) {
+ this.placeholder = this.normalizePlaceholder(options.get('placeholder'));
+
+ decorated.call(this, $element, options, dataAdapter);
+ }
+
+ HidePlaceholder.prototype.append = function (decorated, data) {
+ data.results = this.removePlaceholder(data.results);
+
+ decorated.call(this, data);
+ };
+
+ HidePlaceholder.prototype.normalizePlaceholder = function (_, placeholder) {
+ if (typeof placeholder === 'string') {
+ placeholder = {
+ id: '',
+ text: placeholder
+ };
+ }
+
+ return placeholder;
+ };
+
+ HidePlaceholder.prototype.removePlaceholder = function (_, data) {
+ var modifiedData = data.slice(0);
+
+ for (var d = data.length - 1; d >= 0; d--) {
+ var item = data[d];
+
+ if (this.placeholder.id === item.id) {
+ modifiedData.splice(d, 1);
+ }
+ }
+
+ return modifiedData;
+ };
+
+ return HidePlaceholder;
+});
+
+S2.define('select2/dropdown/infiniteScroll',[
+ 'jquery'
+], function ($) {
+ function InfiniteScroll (decorated, $element, options, dataAdapter) {
+ this.lastParams = {};
+
+ decorated.call(this, $element, options, dataAdapter);
+
+ this.$loadingMore = this.createLoadingMore();
+ this.loading = false;
+ }
+
+ InfiniteScroll.prototype.append = function (decorated, data) {
+ this.$loadingMore.remove();
+ this.loading = false;
+
+ decorated.call(this, data);
+
+ if (this.showLoadingMore(data)) {
+ this.$results.append(this.$loadingMore);
+ }
+ };
+
+ InfiniteScroll.prototype.bind = function (decorated, container, $container) {
+ var self = this;
+
+ decorated.call(this, container, $container);
+
+ container.on('query', function (params) {
+ self.lastParams = params;
+ self.loading = true;
+ });
+
+ container.on('query:append', function (params) {
+ self.lastParams = params;
+ self.loading = true;
+ });
+
+ this.$results.on('scroll', function () {
+ var isLoadMoreVisible = $.contains(
+ document.documentElement,
+ self.$loadingMore[0]
+ );
+
+ if (self.loading || !isLoadMoreVisible) {
+ return;
+ }
+
+ var currentOffset = self.$results.offset().top +
+ self.$results.outerHeight(false);
+ var loadingMoreOffset = self.$loadingMore.offset().top +
+ self.$loadingMore.outerHeight(false);
+
+ if (currentOffset + 50 >= loadingMoreOffset) {
+ self.loadMore();
+ }
+ });
+ };
+
+ InfiniteScroll.prototype.loadMore = function () {
+ this.loading = true;
+
+ var params = $.extend({}, {page: 1}, this.lastParams);
+
+ params.page++;
+
+ this.trigger('query:append', params);
+ };
+
+ InfiniteScroll.prototype.showLoadingMore = function (_, data) {
+ return data.pagination && data.pagination.more;
+ };
+
+ InfiniteScroll.prototype.createLoadingMore = function () {
+ var $option = $(
+ ' '
+ );
+
+ var message = this.options.get('translations').get('loadingMore');
+
+ $option.html(message(this.lastParams));
+
+ return $option;
+ };
+
+ return InfiniteScroll;
+});
+
+S2.define('select2/dropdown/attachBody',[
+ 'jquery',
+ '../utils'
+], function ($, Utils) {
+ function AttachBody (decorated, $element, options) {
+ this.$dropdownParent = options.get('dropdownParent') || $(document.body);
+
+ decorated.call(this, $element, options);
+ }
+
+ AttachBody.prototype.bind = function (decorated, container, $container) {
+ var self = this;
+
+ var setupResultsEvents = false;
+
+ decorated.call(this, container, $container);
+
+ container.on('open', function () {
+ self._showDropdown();
+ self._attachPositioningHandler(container);
+
+ if (!setupResultsEvents) {
+ setupResultsEvents = true;
+
+ container.on('results:all', function () {
+ self._positionDropdown();
+ self._resizeDropdown();
+ });
+
+ container.on('results:append', function () {
+ self._positionDropdown();
+ self._resizeDropdown();
+ });
+ }
+ });
+
+ container.on('close', function () {
+ self._hideDropdown();
+ self._detachPositioningHandler(container);
+ });
+
+ this.$dropdownContainer.on('mousedown', function (evt) {
+ evt.stopPropagation();
+ });
+ };
+
+ AttachBody.prototype.destroy = function (decorated) {
+ decorated.call(this);
+
+ this.$dropdownContainer.remove();
+ };
+
+ AttachBody.prototype.position = function (decorated, $dropdown, $container) {
+ // Clone all of the container classes
+ $dropdown.attr('class', $container.attr('class'));
+
+ $dropdown.removeClass('select2');
+ $dropdown.addClass('select2-container--open');
+
+ $dropdown.css({
+ position: 'absolute',
+ top: -999999
+ });
+
+ this.$container = $container;
+ };
+
+ AttachBody.prototype.render = function (decorated) {
+ var $container = $(' ');
+
+ var $dropdown = decorated.call(this);
+ $container.append($dropdown);
+
+ this.$dropdownContainer = $container;
+
+ return $container;
+ };
+
+ AttachBody.prototype._hideDropdown = function (decorated) {
+ this.$dropdownContainer.detach();
+ };
+
+ AttachBody.prototype._attachPositioningHandler =
+ function (decorated, container) {
+ var self = this;
+
+ var scrollEvent = 'scroll.select2.' + container.id;
+ var resizeEvent = 'resize.select2.' + container.id;
+ var orientationEvent = 'orientationchange.select2.' + container.id;
+
+ var $watchers = this.$container.parents().filter(Utils.hasScroll);
+ $watchers.each(function () {
+ Utils.StoreData(this, 'select2-scroll-position', {
+ x: $(this).scrollLeft(),
+ y: $(this).scrollTop()
+ });
+ });
+
+ $watchers.on(scrollEvent, function (ev) {
+ var position = Utils.GetData(this, 'select2-scroll-position');
+ $(this).scrollTop(position.y);
+ });
+
+ $(window).on(scrollEvent + ' ' + resizeEvent + ' ' + orientationEvent,
+ function (e) {
+ self._positionDropdown();
+ self._resizeDropdown();
+ });
+ };
+
+ AttachBody.prototype._detachPositioningHandler =
+ function (decorated, container) {
+ var scrollEvent = 'scroll.select2.' + container.id;
+ var resizeEvent = 'resize.select2.' + container.id;
+ var orientationEvent = 'orientationchange.select2.' + container.id;
+
+ var $watchers = this.$container.parents().filter(Utils.hasScroll);
+ $watchers.off(scrollEvent);
+
+ $(window).off(scrollEvent + ' ' + resizeEvent + ' ' + orientationEvent);
+ };
+
+ AttachBody.prototype._positionDropdown = function () {
+ var $window = $(window);
+
+ var isCurrentlyAbove = this.$dropdown.hasClass('select2-dropdown--above');
+ var isCurrentlyBelow = this.$dropdown.hasClass('select2-dropdown--below');
+
+ var newDirection = null;
+
+ var offset = this.$container.offset();
+
+ offset.bottom = offset.top + this.$container.outerHeight(false);
+
+ var container = {
+ height: this.$container.outerHeight(false)
+ };
+
+ container.top = offset.top;
+ container.bottom = offset.top + container.height;
+
+ var dropdown = {
+ height: this.$dropdown.outerHeight(false)
+ };
+
+ var viewport = {
+ top: $window.scrollTop(),
+ bottom: $window.scrollTop() + $window.height()
+ };
+
+ var enoughRoomAbove = viewport.top < (offset.top - dropdown.height);
+ var enoughRoomBelow = viewport.bottom > (offset.bottom + dropdown.height);
+
+ var css = {
+ left: offset.left,
+ top: container.bottom
+ };
+
+ // Determine what the parent element is to use for calciulating the offset
+ var $offsetParent = this.$dropdownParent;
+
+ // For statically positoned elements, we need to get the element
+ // that is determining the offset
+ if ($offsetParent.css('position') === 'static') {
+ $offsetParent = $offsetParent.offsetParent();
+ }
+
+ var parentOffset = $offsetParent.offset();
+
+ css.top -= parentOffset.top;
+ css.left -= parentOffset.left;
+
+ if (!isCurrentlyAbove && !isCurrentlyBelow) {
+ newDirection = 'below';
+ }
+
+ if (!enoughRoomBelow && enoughRoomAbove && !isCurrentlyAbove) {
+ newDirection = 'above';
+ } else if (!enoughRoomAbove && enoughRoomBelow && isCurrentlyAbove) {
+ newDirection = 'below';
+ }
+
+ if (newDirection == 'above' ||
+ (isCurrentlyAbove && newDirection !== 'below')) {
+ css.top = container.top - parentOffset.top - dropdown.height;
+ }
+
+ if (newDirection != null) {
+ this.$dropdown
+ .removeClass('select2-dropdown--below select2-dropdown--above')
+ .addClass('select2-dropdown--' + newDirection);
+ this.$container
+ .removeClass('select2-container--below select2-container--above')
+ .addClass('select2-container--' + newDirection);
+ }
+
+ this.$dropdownContainer.css(css);
+ };
+
+ AttachBody.prototype._resizeDropdown = function () {
+ var css = {
+ width: this.$container.outerWidth(false) + 'px'
+ };
+
+ if (this.options.get('dropdownAutoWidth')) {
+ css.minWidth = css.width;
+ css.position = 'relative';
+ css.width = 'auto';
+ }
+
+ this.$dropdown.css(css);
+ };
+
+ AttachBody.prototype._showDropdown = function (decorated) {
+ this.$dropdownContainer.appendTo(this.$dropdownParent);
+
+ this._positionDropdown();
+ this._resizeDropdown();
+ };
+
+ return AttachBody;
+});
+
+S2.define('select2/dropdown/minimumResultsForSearch',[
+
+], function () {
+ function countResults (data) {
+ var count = 0;
+
+ for (var d = 0; d < data.length; d++) {
+ var item = data[d];
+
+ if (item.children) {
+ count += countResults(item.children);
+ } else {
+ count++;
+ }
+ }
+
+ return count;
+ }
+
+ function MinimumResultsForSearch (decorated, $element, options, dataAdapter) {
+ this.minimumResultsForSearch = options.get('minimumResultsForSearch');
+
+ if (this.minimumResultsForSearch < 0) {
+ this.minimumResultsForSearch = Infinity;
+ }
+
+ decorated.call(this, $element, options, dataAdapter);
+ }
+
+ MinimumResultsForSearch.prototype.showSearch = function (decorated, params) {
+ if (countResults(params.data.results) < this.minimumResultsForSearch) {
+ return false;
+ }
+
+ return decorated.call(this, params);
+ };
+
+ return MinimumResultsForSearch;
+});
+
+S2.define('select2/dropdown/selectOnClose',[
+ '../utils'
+], function (Utils) {
+ function SelectOnClose () { }
+
+ SelectOnClose.prototype.bind = function (decorated, container, $container) {
+ var self = this;
+
+ decorated.call(this, container, $container);
+
+ container.on('close', function (params) {
+ self._handleSelectOnClose(params);
+ });
+ };
+
+ SelectOnClose.prototype._handleSelectOnClose = function (_, params) {
+ if (params && params.originalSelect2Event != null) {
+ var event = params.originalSelect2Event;
+
+ // Don't select an item if the close event was triggered from a select or
+ // unselect event
+ if (event._type === 'select' || event._type === 'unselect') {
+ return;
+ }
+ }
+
+ var $highlightedResults = this.getHighlightedResults();
+
+ // Only select highlighted results
+ if ($highlightedResults.length < 1) {
+ return;
+ }
+
+ var data = Utils.GetData($highlightedResults[0], 'data');
+
+ // Don't re-select already selected resulte
+ if (
+ (data.element != null && data.element.selected) ||
+ (data.element == null && data.selected)
+ ) {
+ return;
+ }
+
+ this.trigger('select', {
+ data: data
+ });
+ };
+
+ return SelectOnClose;
+});
+
+S2.define('select2/dropdown/closeOnSelect',[
+
+], function () {
+ function CloseOnSelect () { }
+
+ CloseOnSelect.prototype.bind = function (decorated, container, $container) {
+ var self = this;
+
+ decorated.call(this, container, $container);
+
+ container.on('select', function (evt) {
+ self._selectTriggered(evt);
+ });
+
+ container.on('unselect', function (evt) {
+ self._selectTriggered(evt);
+ });
+ };
+
+ CloseOnSelect.prototype._selectTriggered = function (_, evt) {
+ var originalEvent = evt.originalEvent;
+
+ // Don't close if the control key is being held
+ if (originalEvent && originalEvent.ctrlKey) {
+ return;
+ }
+
+ this.trigger('close', {
+ originalEvent: originalEvent,
+ originalSelect2Event: evt
+ });
+ };
+
+ return CloseOnSelect;
+});
+
+S2.define('select2/i18n/en',[],function () {
+ // English
+ return {
+ errorLoading: function () {
+ return 'The results could not be loaded.';
+ },
+ inputTooLong: function (args) {
+ var overChars = args.input.length - args.maximum;
+
+ var message = 'Please delete ' + overChars + ' character';
+
+ if (overChars != 1) {
+ message += 's';
+ }
+
+ return message;
+ },
+ inputTooShort: function (args) {
+ var remainingChars = args.minimum - args.input.length;
+
+ var message = 'Please enter ' + remainingChars + ' or more characters';
+
+ return message;
+ },
+ loadingMore: function () {
+ return 'Loading more results…';
+ },
+ maximumSelected: function (args) {
+ var message = 'You can only select ' + args.maximum + ' item';
+
+ if (args.maximum != 1) {
+ message += 's';
+ }
+
+ return message;
+ },
+ noResults: function () {
+ return 'No results found';
+ },
+ searching: function () {
+ return 'Searching…';
+ }
+ };
+});
+
+S2.define('select2/defaults',[
+ 'jquery',
+ 'require',
+
+ './results',
+
+ './selection/single',
+ './selection/multiple',
+ './selection/placeholder',
+ './selection/allowClear',
+ './selection/search',
+ './selection/eventRelay',
+
+ './utils',
+ './translation',
+ './diacritics',
+
+ './data/select',
+ './data/array',
+ './data/ajax',
+ './data/tags',
+ './data/tokenizer',
+ './data/minimumInputLength',
+ './data/maximumInputLength',
+ './data/maximumSelectionLength',
+
+ './dropdown',
+ './dropdown/search',
+ './dropdown/hidePlaceholder',
+ './dropdown/infiniteScroll',
+ './dropdown/attachBody',
+ './dropdown/minimumResultsForSearch',
+ './dropdown/selectOnClose',
+ './dropdown/closeOnSelect',
+
+ './i18n/en'
+], function ($, require,
+
+ ResultsList,
+
+ SingleSelection, MultipleSelection, Placeholder, AllowClear,
+ SelectionSearch, EventRelay,
+
+ Utils, Translation, DIACRITICS,
+
+ SelectData, ArrayData, AjaxData, Tags, Tokenizer,
+ MinimumInputLength, MaximumInputLength, MaximumSelectionLength,
+
+ Dropdown, DropdownSearch, HidePlaceholder, InfiniteScroll,
+ AttachBody, MinimumResultsForSearch, SelectOnClose, CloseOnSelect,
+
+ EnglishTranslation) {
+ function Defaults () {
+ this.reset();
+ }
+
+ Defaults.prototype.apply = function (options) {
+ options = $.extend(true, {}, this.defaults, options);
+
+ if (options.dataAdapter == null) {
+ if (options.ajax != null) {
+ options.dataAdapter = AjaxData;
+ } else if (options.data != null) {
+ options.dataAdapter = ArrayData;
+ } else {
+ options.dataAdapter = SelectData;
+ }
+
+ if (options.minimumInputLength > 0) {
+ options.dataAdapter = Utils.Decorate(
+ options.dataAdapter,
+ MinimumInputLength
+ );
+ }
+
+ if (options.maximumInputLength > 0) {
+ options.dataAdapter = Utils.Decorate(
+ options.dataAdapter,
+ MaximumInputLength
+ );
+ }
+
+ if (options.maximumSelectionLength > 0) {
+ options.dataAdapter = Utils.Decorate(
+ options.dataAdapter,
+ MaximumSelectionLength
+ );
+ }
+
+ if (options.tags) {
+ options.dataAdapter = Utils.Decorate(options.dataAdapter, Tags);
+ }
+
+ if (options.tokenSeparators != null || options.tokenizer != null) {
+ options.dataAdapter = Utils.Decorate(
+ options.dataAdapter,
+ Tokenizer
+ );
+ }
+
+ if (options.query != null) {
+ var Query = require(options.amdBase + 'compat/query');
+
+ options.dataAdapter = Utils.Decorate(
+ options.dataAdapter,
+ Query
+ );
+ }
+
+ if (options.initSelection != null) {
+ var InitSelection = require(options.amdBase + 'compat/initSelection');
+
+ options.dataAdapter = Utils.Decorate(
+ options.dataAdapter,
+ InitSelection
+ );
+ }
+ }
+
+ if (options.resultsAdapter == null) {
+ options.resultsAdapter = ResultsList;
+
+ if (options.ajax != null) {
+ options.resultsAdapter = Utils.Decorate(
+ options.resultsAdapter,
+ InfiniteScroll
+ );
+ }
+
+ if (options.placeholder != null) {
+ options.resultsAdapter = Utils.Decorate(
+ options.resultsAdapter,
+ HidePlaceholder
+ );
+ }
+
+ if (options.selectOnClose) {
+ options.resultsAdapter = Utils.Decorate(
+ options.resultsAdapter,
+ SelectOnClose
+ );
+ }
+ }
+
+ if (options.dropdownAdapter == null) {
+ if (options.multiple) {
+ options.dropdownAdapter = Dropdown;
+ } else {
+ var SearchableDropdown = Utils.Decorate(Dropdown, DropdownSearch);
+
+ options.dropdownAdapter = SearchableDropdown;
+ }
+
+ if (options.minimumResultsForSearch !== 0) {
+ options.dropdownAdapter = Utils.Decorate(
+ options.dropdownAdapter,
+ MinimumResultsForSearch
+ );
+ }
+
+ if (options.closeOnSelect) {
+ options.dropdownAdapter = Utils.Decorate(
+ options.dropdownAdapter,
+ CloseOnSelect
+ );
+ }
+
+ if (
+ options.dropdownCssClass != null ||
+ options.dropdownCss != null ||
+ options.adaptDropdownCssClass != null
+ ) {
+ var DropdownCSS = require(options.amdBase + 'compat/dropdownCss');
+
+ options.dropdownAdapter = Utils.Decorate(
+ options.dropdownAdapter,
+ DropdownCSS
+ );
+ }
+
+ options.dropdownAdapter = Utils.Decorate(
+ options.dropdownAdapter,
+ AttachBody
+ );
+ }
+
+ if (options.selectionAdapter == null) {
+ if (options.multiple) {
+ options.selectionAdapter = MultipleSelection;
+ } else {
+ options.selectionAdapter = SingleSelection;
+ }
+
+ // Add the placeholder mixin if a placeholder was specified
+ if (options.placeholder != null) {
+ options.selectionAdapter = Utils.Decorate(
+ options.selectionAdapter,
+ Placeholder
+ );
+ }
+
+ if (options.allowClear) {
+ options.selectionAdapter = Utils.Decorate(
+ options.selectionAdapter,
+ AllowClear
+ );
+ }
+
+ if (options.multiple) {
+ options.selectionAdapter = Utils.Decorate(
+ options.selectionAdapter,
+ SelectionSearch
+ );
+ }
+
+ if (
+ options.containerCssClass != null ||
+ options.containerCss != null ||
+ options.adaptContainerCssClass != null
+ ) {
+ var ContainerCSS = require(options.amdBase + 'compat/containerCss');
+
+ options.selectionAdapter = Utils.Decorate(
+ options.selectionAdapter,
+ ContainerCSS
+ );
+ }
+
+ options.selectionAdapter = Utils.Decorate(
+ options.selectionAdapter,
+ EventRelay
+ );
+ }
+
+ if (typeof options.language === 'string') {
+ // Check if the language is specified with a region
+ if (options.language.indexOf('-') > 0) {
+ // Extract the region information if it is included
+ var languageParts = options.language.split('-');
+ var baseLanguage = languageParts[0];
+
+ options.language = [options.language, baseLanguage];
+ } else {
+ options.language = [options.language];
+ }
+ }
+
+ if ($.isArray(options.language)) {
+ var languages = new Translation();
+ options.language.push('en');
+
+ var languageNames = options.language;
+
+ for (var l = 0; l < languageNames.length; l++) {
+ var name = languageNames[l];
+ var language = {};
+
+ try {
+ // Try to load it with the original name
+ language = Translation.loadPath(name);
+ } catch (e) {
+ try {
+ // If we couldn't load it, check if it wasn't the full path
+ name = this.defaults.amdLanguageBase + name;
+ language = Translation.loadPath(name);
+ } catch (ex) {
+ // The translation could not be loaded at all. Sometimes this is
+ // because of a configuration problem, other times this can be
+ // because of how Select2 helps load all possible translation files.
+ if (options.debug && window.console && console.warn) {
+ console.warn(
+ 'Select2: The language file for "' + name + '" could not be ' +
+ 'automatically loaded. A fallback will be used instead.'
+ );
+ }
+
+ continue;
+ }
+ }
+
+ languages.extend(language);
+ }
+
+ options.translations = languages;
+ } else {
+ var baseTranslation = Translation.loadPath(
+ this.defaults.amdLanguageBase + 'en'
+ );
+ var customTranslation = new Translation(options.language);
+
+ customTranslation.extend(baseTranslation);
+
+ options.translations = customTranslation;
+ }
+
+ return options;
+ };
+
+ Defaults.prototype.reset = function () {
+ function stripDiacritics (text) {
+ // Used 'uni range + named function' from http://jsperf.com/diacritics/18
+ function match(a) {
+ return DIACRITICS[a] || a;
+ }
+
+ return text.replace(/[^\u0000-\u007E]/g, match);
+ }
+
+ function matcher (params, data) {
+ // Always return the object if there is nothing to compare
+ if ($.trim(params.term) === '') {
+ return data;
+ }
+
+ // Do a recursive check for options with children
+ if (data.children && data.children.length > 0) {
+ // Clone the data object if there are children
+ // This is required as we modify the object to remove any non-matches
+ var match = $.extend(true, {}, data);
+
+ // Check each child of the option
+ for (var c = data.children.length - 1; c >= 0; c--) {
+ var child = data.children[c];
+
+ var matches = matcher(params, child);
+
+ // If there wasn't a match, remove the object in the array
+ if (matches == null) {
+ match.children.splice(c, 1);
+ }
+ }
+
+ // If any children matched, return the new object
+ if (match.children.length > 0) {
+ return match;
+ }
+
+ // If there were no matching children, check just the plain object
+ return matcher(params, match);
+ }
+
+ var original = stripDiacritics(data.text).toUpperCase();
+ var term = stripDiacritics(params.term).toUpperCase();
+
+ // Check if the text contains the term
+ if (original.indexOf(term) > -1) {
+ return data;
+ }
+
+ // If it doesn't contain the term, don't return anything
+ return null;
+ }
+
+ this.defaults = {
+ amdBase: './',
+ amdLanguageBase: './i18n/',
+ closeOnSelect: true,
+ debug: false,
+ dropdownAutoWidth: false,
+ escapeMarkup: Utils.escapeMarkup,
+ language: EnglishTranslation,
+ matcher: matcher,
+ minimumInputLength: 0,
+ maximumInputLength: 0,
+ maximumSelectionLength: 0,
+ minimumResultsForSearch: 0,
+ selectOnClose: false,
+ sorter: function (data) {
+ return data;
+ },
+ templateResult: function (result) {
+ return result.text;
+ },
+ templateSelection: function (selection) {
+ return selection.text;
+ },
+ theme: 'default',
+ width: 'resolve'
+ };
+ };
+
+ Defaults.prototype.set = function (key, value) {
+ var camelKey = $.camelCase(key);
+
+ var data = {};
+ data[camelKey] = value;
+
+ var convertedData = Utils._convertData(data);
+
+ $.extend(true, this.defaults, convertedData);
+ };
+
+ var defaults = new Defaults();
+
+ return defaults;
+});
+
+S2.define('select2/options',[
+ 'require',
+ 'jquery',
+ './defaults',
+ './utils'
+], function (require, $, Defaults, Utils) {
+ function Options (options, $element) {
+ this.options = options;
+
+ if ($element != null) {
+ this.fromElement($element);
+ }
+
+ this.options = Defaults.apply(this.options);
+
+ if ($element && $element.is('input')) {
+ var InputCompat = require(this.get('amdBase') + 'compat/inputData');
+
+ this.options.dataAdapter = Utils.Decorate(
+ this.options.dataAdapter,
+ InputCompat
+ );
+ }
+ }
+
+ Options.prototype.fromElement = function ($e) {
+ var excludedData = ['select2'];
+
+ if (this.options.multiple == null) {
+ this.options.multiple = $e.prop('multiple');
+ }
+
+ if (this.options.disabled == null) {
+ this.options.disabled = $e.prop('disabled');
+ }
+
+ if (this.options.language == null) {
+ if ($e.prop('lang')) {
+ this.options.language = $e.prop('lang').toLowerCase();
+ } else if ($e.closest('[lang]').prop('lang')) {
+ this.options.language = $e.closest('[lang]').prop('lang');
+ }
+ }
+
+ if (this.options.dir == null) {
+ if ($e.prop('dir')) {
+ this.options.dir = $e.prop('dir');
+ } else if ($e.closest('[dir]').prop('dir')) {
+ this.options.dir = $e.closest('[dir]').prop('dir');
+ } else {
+ this.options.dir = 'ltr';
+ }
+ }
+
+ $e.prop('disabled', this.options.disabled);
+ $e.prop('multiple', this.options.multiple);
+
+ if (Utils.GetData($e[0], 'select2Tags')) {
+ if (this.options.debug && window.console && console.warn) {
+ console.warn(
+ 'Select2: The `data-select2-tags` attribute has been changed to ' +
+ 'use the `data-data` and `data-tags="true"` attributes and will be ' +
+ 'removed in future versions of Select2.'
+ );
+ }
+
+ Utils.StoreData($e[0], 'data', Utils.GetData($e[0], 'select2Tags'));
+ Utils.StoreData($e[0], 'tags', true);
+ }
+
+ if (Utils.GetData($e[0], 'ajaxUrl')) {
+ if (this.options.debug && window.console && console.warn) {
+ console.warn(
+ 'Select2: The `data-ajax-url` attribute has been changed to ' +
+ '`data-ajax--url` and support for the old attribute will be removed' +
+ ' in future versions of Select2.'
+ );
+ }
+
+ $e.attr('ajax--url', Utils.GetData($e[0], 'ajaxUrl'));
+ Utils.StoreData($e[0], 'ajax-Url', Utils.GetData($e[0], 'ajaxUrl'));
+
+ }
+
+ var dataset = {};
+
+ // Prefer the element's `dataset` attribute if it exists
+ // jQuery 1.x does not correctly handle data attributes with multiple dashes
+ if ($.fn.jquery && $.fn.jquery.substr(0, 2) == '1.' && $e[0].dataset) {
+ dataset = $.extend(true, {}, $e[0].dataset, Utils.GetData($e[0]));
+ } else {
+ dataset = Utils.GetData($e[0]);
+ }
+
+ var data = $.extend(true, {}, dataset);
+
+ data = Utils._convertData(data);
+
+ for (var key in data) {
+ if ($.inArray(key, excludedData) > -1) {
+ continue;
+ }
+
+ if ($.isPlainObject(this.options[key])) {
+ $.extend(this.options[key], data[key]);
+ } else {
+ this.options[key] = data[key];
+ }
+ }
+
+ return this;
+ };
+
+ Options.prototype.get = function (key) {
+ return this.options[key];
+ };
+
+ Options.prototype.set = function (key, val) {
+ this.options[key] = val;
+ };
+
+ return Options;
+});
+
+S2.define('select2/core',[
+ 'jquery',
+ './options',
+ './utils',
+ './keys'
+], function ($, Options, Utils, KEYS) {
+ var Select2 = function ($element, options) {
+ if (Utils.GetData($element[0], 'select2') != null) {
+ Utils.GetData($element[0], 'select2').destroy();
+ }
+
+ this.$element = $element;
+
+ this.id = this._generateId($element);
+
+ options = options || {};
+
+ this.options = new Options(options, $element);
+
+ Select2.__super__.constructor.call(this);
+
+ // Set up the tabindex
+
+ var tabindex = $element.attr('tabindex') || 0;
+ Utils.StoreData($element[0], 'old-tabindex', tabindex);
+ $element.attr('tabindex', '-1');
+
+ // Set up containers and adapters
+
+ var DataAdapter = this.options.get('dataAdapter');
+ this.dataAdapter = new DataAdapter($element, this.options);
+
+ var $container = this.render();
+
+ this._placeContainer($container);
+
+ var SelectionAdapter = this.options.get('selectionAdapter');
+ this.selection = new SelectionAdapter($element, this.options);
+ this.$selection = this.selection.render();
+
+ this.selection.position(this.$selection, $container);
+
+ var DropdownAdapter = this.options.get('dropdownAdapter');
+ this.dropdown = new DropdownAdapter($element, this.options);
+ this.$dropdown = this.dropdown.render();
+
+ this.dropdown.position(this.$dropdown, $container);
+
+ var ResultsAdapter = this.options.get('resultsAdapter');
+ this.results = new ResultsAdapter($element, this.options, this.dataAdapter);
+ this.$results = this.results.render();
+
+ this.results.position(this.$results, this.$dropdown);
+
+ // Bind events
+
+ var self = this;
+
+ // Bind the container to all of the adapters
+ this._bindAdapters();
+
+ // Register any DOM event handlers
+ this._registerDomEvents();
+
+ // Register any internal event handlers
+ this._registerDataEvents();
+ this._registerSelectionEvents();
+ this._registerDropdownEvents();
+ this._registerResultsEvents();
+ this._registerEvents();
+
+ // Set the initial state
+ this.dataAdapter.current(function (initialData) {
+ self.trigger('selection:update', {
+ data: initialData
+ });
+ });
+
+ // Hide the original select
+ $element.addClass('select2-hidden-accessible');
+ $element.attr('aria-hidden', 'true');
+
+ // Synchronize any monitored attributes
+ this._syncAttributes();
+
+ Utils.StoreData($element[0], 'select2', this);
+
+ // Ensure backwards compatibility with $element.data('select2').
+ $element.data('select2', this);
+ };
+
+ Utils.Extend(Select2, Utils.Observable);
+
+ Select2.prototype._generateId = function ($element) {
+ var id = '';
+
+ if ($element.attr('id') != null) {
+ id = $element.attr('id');
+ } else if ($element.attr('name') != null) {
+ id = $element.attr('name') + '-' + Utils.generateChars(2);
+ } else {
+ id = Utils.generateChars(4);
+ }
+
+ id = id.replace(/(:|\.|\[|\]|,)/g, '');
+ id = 'select2-' + id;
+
+ return id;
+ };
+
+ Select2.prototype._placeContainer = function ($container) {
+ $container.insertAfter(this.$element);
+
+ var width = this._resolveWidth(this.$element, this.options.get('width'));
+
+ if (width != null) {
+ $container.css('width', width);
+ }
+ };
+
+ Select2.prototype._resolveWidth = function ($element, method) {
+ var WIDTH = /^width:(([-+]?([0-9]*\.)?[0-9]+)(px|em|ex|%|in|cm|mm|pt|pc))/i;
+
+ if (method == 'resolve') {
+ var styleWidth = this._resolveWidth($element, 'style');
+
+ if (styleWidth != null) {
+ return styleWidth;
+ }
+
+ return this._resolveWidth($element, 'element');
+ }
+
+ if (method == 'element') {
+ var elementWidth = $element.outerWidth(false);
+
+ if (elementWidth <= 0) {
+ return 'auto';
+ }
+
+ return elementWidth + 'px';
+ }
+
+ if (method == 'style') {
+ var style = $element.attr('style');
+
+ if (typeof(style) !== 'string') {
+ return null;
+ }
+
+ var attrs = style.split(';');
+
+ for (var i = 0, l = attrs.length; i < l; i = i + 1) {
+ var attr = attrs[i].replace(/\s/g, '');
+ var matches = attr.match(WIDTH);
+
+ if (matches !== null && matches.length >= 1) {
+ return matches[1];
+ }
+ }
+
+ return null;
+ }
+
+ return method;
+ };
+
+ Select2.prototype._bindAdapters = function () {
+ this.dataAdapter.bind(this, this.$container);
+ this.selection.bind(this, this.$container);
+
+ this.dropdown.bind(this, this.$container);
+ this.results.bind(this, this.$container);
+ };
+
+ Select2.prototype._registerDomEvents = function () {
+ var self = this;
+
+ this.$element.on('change.select2', function () {
+ self.dataAdapter.current(function (data) {
+ self.trigger('selection:update', {
+ data: data
+ });
+ });
+ });
+
+ this.$element.on('focus.select2', function (evt) {
+ self.trigger('focus', evt);
+ });
+
+ this._syncA = Utils.bind(this._syncAttributes, this);
+ this._syncS = Utils.bind(this._syncSubtree, this);
+
+ if (this.$element[0].attachEvent) {
+ this.$element[0].attachEvent('onpropertychange', this._syncA);
+ }
+
+ var observer = window.MutationObserver ||
+ window.WebKitMutationObserver ||
+ window.MozMutationObserver
+ ;
+
+ if (observer != null) {
+ this._observer = new observer(function (mutations) {
+ $.each(mutations, self._syncA);
+ $.each(mutations, self._syncS);
+ });
+ this._observer.observe(this.$element[0], {
+ attributes: true,
+ childList: true,
+ subtree: false
+ });
+ } else if (this.$element[0].addEventListener) {
+ this.$element[0].addEventListener(
+ 'DOMAttrModified',
+ self._syncA,
+ false
+ );
+ this.$element[0].addEventListener(
+ 'DOMNodeInserted',
+ self._syncS,
+ false
+ );
+ this.$element[0].addEventListener(
+ 'DOMNodeRemoved',
+ self._syncS,
+ false
+ );
+ }
+ };
+
+ Select2.prototype._registerDataEvents = function () {
+ var self = this;
+
+ this.dataAdapter.on('*', function (name, params) {
+ self.trigger(name, params);
+ });
+ };
+
+ Select2.prototype._registerSelectionEvents = function () {
+ var self = this;
+ var nonRelayEvents = ['toggle', 'focus'];
+
+ this.selection.on('toggle', function () {
+ self.toggleDropdown();
+ });
+
+ this.selection.on('focus', function (params) {
+ self.focus(params);
+ });
+
+ this.selection.on('*', function (name, params) {
+ if ($.inArray(name, nonRelayEvents) !== -1) {
+ return;
+ }
+
+ self.trigger(name, params);
+ });
+ };
+
+ Select2.prototype._registerDropdownEvents = function () {
+ var self = this;
+
+ this.dropdown.on('*', function (name, params) {
+ self.trigger(name, params);
+ });
+ };
+
+ Select2.prototype._registerResultsEvents = function () {
+ var self = this;
+
+ this.results.on('*', function (name, params) {
+ self.trigger(name, params);
+ });
+ };
+
+ Select2.prototype._registerEvents = function () {
+ var self = this;
+
+ this.on('open', function () {
+ self.$container.addClass('select2-container--open');
+ });
+
+ this.on('close', function () {
+ self.$container.removeClass('select2-container--open');
+ });
+
+ this.on('enable', function () {
+ self.$container.removeClass('select2-container--disabled');
+ });
+
+ this.on('disable', function () {
+ self.$container.addClass('select2-container--disabled');
+ });
+
+ this.on('blur', function () {
+ self.$container.removeClass('select2-container--focus');
+ });
+
+ this.on('query', function (params) {
+ if (!self.isOpen()) {
+ self.trigger('open', {});
+ }
+
+ this.dataAdapter.query(params, function (data) {
+ self.trigger('results:all', {
+ data: data,
+ query: params
+ });
+ });
+ });
+
+ this.on('query:append', function (params) {
+ this.dataAdapter.query(params, function (data) {
+ self.trigger('results:append', {
+ data: data,
+ query: params
+ });
+ });
+ });
+
+ this.on('keypress', function (evt) {
+ var key = evt.which;
+
+ if (self.isOpen()) {
+ if (key === KEYS.ESC || key === KEYS.TAB ||
+ (key === KEYS.UP && evt.altKey)) {
+ self.close();
+
+ evt.preventDefault();
+ } else if (key === KEYS.ENTER) {
+ self.trigger('results:select', {});
+
+ evt.preventDefault();
+ } else if ((key === KEYS.SPACE && evt.ctrlKey)) {
+ self.trigger('results:toggle', {});
+
+ evt.preventDefault();
+ } else if (key === KEYS.UP) {
+ self.trigger('results:previous', {});
+
+ evt.preventDefault();
+ } else if (key === KEYS.DOWN) {
+ self.trigger('results:next', {});
+
+ evt.preventDefault();
+ }
+ } else {
+ if (key === KEYS.ENTER || key === KEYS.SPACE ||
+ (key === KEYS.DOWN && evt.altKey)) {
+ self.open();
+
+ evt.preventDefault();
+ }
+ }
+ });
+ };
+
+ Select2.prototype._syncAttributes = function () {
+ this.options.set('disabled', this.$element.prop('disabled'));
+
+ if (this.options.get('disabled')) {
+ if (this.isOpen()) {
+ this.close();
+ }
+
+ this.trigger('disable', {});
+ } else {
+ this.trigger('enable', {});
+ }
+ };
+
+ Select2.prototype._syncSubtree = function (evt, mutations) {
+ var changed = false;
+ var self = this;
+
+ // Ignore any mutation events raised for elements that aren't options or
+ // optgroups. This handles the case when the select element is destroyed
+ if (
+ evt && evt.target && (
+ evt.target.nodeName !== 'OPTION' && evt.target.nodeName !== 'OPTGROUP'
+ )
+ ) {
+ return;
+ }
+
+ if (!mutations) {
+ // If mutation events aren't supported, then we can only assume that the
+ // change affected the selections
+ changed = true;
+ } else if (mutations.addedNodes && mutations.addedNodes.length > 0) {
+ for (var n = 0; n < mutations.addedNodes.length; n++) {
+ var node = mutations.addedNodes[n];
+
+ if (node.selected) {
+ changed = true;
+ }
+ }
+ } else if (mutations.removedNodes && mutations.removedNodes.length > 0) {
+ changed = true;
+ }
+
+ // Only re-pull the data if we think there is a change
+ if (changed) {
+ this.dataAdapter.current(function (currentData) {
+ self.trigger('selection:update', {
+ data: currentData
+ });
+ });
+ }
+ };
+
+ /**
+ * Override the trigger method to automatically trigger pre-events when
+ * there are events that can be prevented.
+ */
+ Select2.prototype.trigger = function (name, args) {
+ var actualTrigger = Select2.__super__.trigger;
+ var preTriggerMap = {
+ 'open': 'opening',
+ 'close': 'closing',
+ 'select': 'selecting',
+ 'unselect': 'unselecting',
+ 'clear': 'clearing'
+ };
+
+ if (args === undefined) {
+ args = {};
+ }
+
+ if (name in preTriggerMap) {
+ var preTriggerName = preTriggerMap[name];
+ var preTriggerArgs = {
+ prevented: false,
+ name: name,
+ args: args
+ };
+
+ actualTrigger.call(this, preTriggerName, preTriggerArgs);
+
+ if (preTriggerArgs.prevented) {
+ args.prevented = true;
+
+ return;
+ }
+ }
+
+ actualTrigger.call(this, name, args);
+ };
+
+ Select2.prototype.toggleDropdown = function () {
+ if (this.options.get('disabled')) {
+ return;
+ }
+
+ if (this.isOpen()) {
+ this.close();
+ } else {
+ this.open();
+ }
+ };
+
+ Select2.prototype.open = function () {
+ if (this.isOpen()) {
+ return;
+ }
+
+ this.trigger('query', {});
+ };
+
+ Select2.prototype.close = function () {
+ if (!this.isOpen()) {
+ return;
+ }
+
+ this.trigger('close', {});
+ };
+
+ Select2.prototype.isOpen = function () {
+ return this.$container.hasClass('select2-container--open');
+ };
+
+ Select2.prototype.hasFocus = function () {
+ return this.$container.hasClass('select2-container--focus');
+ };
+
+ Select2.prototype.focus = function (data) {
+ // No need to re-trigger focus events if we are already focused
+ if (this.hasFocus()) {
+ return;
+ }
+
+ this.$container.addClass('select2-container--focus');
+ this.trigger('focus', {});
+ };
+
+ Select2.prototype.enable = function (args) {
+ if (this.options.get('debug') && window.console && console.warn) {
+ console.warn(
+ 'Select2: The `select2("enable")` method has been deprecated and will' +
+ ' be removed in later Select2 versions. Use $element.prop("disabled")' +
+ ' instead.'
+ );
+ }
+
+ if (args == null || args.length === 0) {
+ args = [true];
+ }
+
+ var disabled = !args[0];
+
+ this.$element.prop('disabled', disabled);
+ };
+
+ Select2.prototype.data = function () {
+ if (this.options.get('debug') &&
+ arguments.length > 0 && window.console && console.warn) {
+ console.warn(
+ 'Select2: Data can no longer be set using `select2("data")`. You ' +
+ 'should consider setting the value instead using `$element.val()`.'
+ );
+ }
+
+ var data = [];
+
+ this.dataAdapter.current(function (currentData) {
+ data = currentData;
+ });
+
+ return data;
+ };
+
+ Select2.prototype.val = function (args) {
+ if (this.options.get('debug') && window.console && console.warn) {
+ console.warn(
+ 'Select2: The `select2("val")` method has been deprecated and will be' +
+ ' removed in later Select2 versions. Use $element.val() instead.'
+ );
+ }
+
+ if (args == null || args.length === 0) {
+ return this.$element.val();
+ }
+
+ var newVal = args[0];
+
+ if ($.isArray(newVal)) {
+ newVal = $.map(newVal, function (obj) {
+ return obj.toString();
+ });
+ }
+
+ this.$element.val(newVal).trigger('change');
+ };
+
+ Select2.prototype.destroy = function () {
+ this.$container.remove();
+
+ if (this.$element[0].detachEvent) {
+ this.$element[0].detachEvent('onpropertychange', this._syncA);
+ }
+
+ if (this._observer != null) {
+ this._observer.disconnect();
+ this._observer = null;
+ } else if (this.$element[0].removeEventListener) {
+ this.$element[0]
+ .removeEventListener('DOMAttrModified', this._syncA, false);
+ this.$element[0]
+ .removeEventListener('DOMNodeInserted', this._syncS, false);
+ this.$element[0]
+ .removeEventListener('DOMNodeRemoved', this._syncS, false);
+ }
+
+ this._syncA = null;
+ this._syncS = null;
+
+ this.$element.off('.select2');
+ this.$element.attr('tabindex',
+ Utils.GetData(this.$element[0], 'old-tabindex'));
+
+ this.$element.removeClass('select2-hidden-accessible');
+ this.$element.attr('aria-hidden', 'false');
+ Utils.RemoveData(this.$element[0]);
+ this.$element.removeData('select2');
+
+ this.dataAdapter.destroy();
+ this.selection.destroy();
+ this.dropdown.destroy();
+ this.results.destroy();
+
+ this.dataAdapter = null;
+ this.selection = null;
+ this.dropdown = null;
+ this.results = null;
+ };
+
+ Select2.prototype.render = function () {
+ var $container = $(
+ '' +
+ ' ' +
+ ' ' +
+ ' '
+ );
+
+ $container.attr('dir', this.options.get('dir'));
+
+ this.$container = $container;
+
+ this.$container.addClass('select2-container--' + this.options.get('theme'));
+
+ Utils.StoreData($container[0], 'element', this.$element);
+
+ return $container;
+ };
+
+ return Select2;
+});
+
+S2.define('jquery-mousewheel',[
+ 'jquery'
+], function ($) {
+ // Used to shim jQuery.mousewheel for non-full builds.
+ return $;
+});
+
+S2.define('jquery.select2',[
+ 'jquery',
+ 'jquery-mousewheel',
+
+ './select2/core',
+ './select2/defaults',
+ './select2/utils'
+], function ($, _, Select2, Defaults, Utils) {
+ if ($.fn.select2 == null) {
+ // All methods that should return the element
+ var thisMethods = ['open', 'close', 'destroy'];
+
+ $.fn.select2 = function (options) {
+ options = options || {};
+
+ if (typeof options === 'object') {
+ this.each(function () {
+ var instanceOptions = $.extend(true, {}, options);
+
+ var instance = new Select2($(this), instanceOptions);
+ });
+
+ return this;
+ } else if (typeof options === 'string') {
+ var ret;
+ var args = Array.prototype.slice.call(arguments, 1);
+
+ this.each(function () {
+ var instance = Utils.GetData(this, 'select2');
+
+ if (instance == null && window.console && console.error) {
+ console.error(
+ 'The select2(\'' + options + '\') method was called on an ' +
+ 'element that is not using Select2.'
+ );
+ }
+
+ ret = instance[options].apply(instance, args);
+ });
+
+ // Check if we should be returning `this`
+ if ($.inArray(options, thisMethods) > -1) {
+ return this;
+ }
+
+ return ret;
+ } else {
+ throw new Error('Invalid arguments for Select2: ' + options);
+ }
+ };
+ }
+
+ if ($.fn.select2.defaults == null) {
+ $.fn.select2.defaults = Defaults;
+ }
+
+ return Select2;
+});
+
+ // Return the AMD loader configuration so it can be used outside of this file
+ return {
+ define: S2.define,
+ require: S2.require
+ };
+}());
+
+ // Autoload the jQuery bindings
+ // We know that all of the modules exist above this, so we're safe
+ var select2 = S2.require('jquery.select2');
+
+ // Hold the AMD module references on the jQuery function that was just loaded
+ // This allows Select2 to use the internal loader outside of this file, such
+ // as in the language files.
+ jQuery.fn.select2.amd = S2;
+
+ // Return the Select2 instance for anyone who is importing it.
+ return select2;
+}));
diff --git a/AdminPanel/client/src/pages/AiIntegration/ai/vendor/select2-4.0.6-rc.1/dist/js/select2.min.js b/AdminPanel/client/src/pages/AiIntegration/ai/vendor/select2-4.0.6-rc.1/dist/js/select2.min.js
new file mode 100644
index 0000000000..e505290222
--- /dev/null
+++ b/AdminPanel/client/src/pages/AiIntegration/ai/vendor/select2-4.0.6-rc.1/dist/js/select2.min.js
@@ -0,0 +1 @@
+/*! Select2 4.0.6-rc.1 | https://github.com/select2/select2/blob/master/LICENSE.md */!function(a){"function"==typeof define&&define.amd?define(["jquery"],a):"object"==typeof module&&module.exports?module.exports=function(b,c){return void 0===c&&(c="undefined"!=typeof window?require("jquery"):require("jquery")(b)),a(c),c}:a(jQuery)}(function(a){var b=function(){if(a&&a.fn&&a.fn.select2&&a.fn.select2.amd)var b=a.fn.select2.amd;var b;return function(){if(!b||!b.requirejs){b?c=b:b={};var a,c,d;!function(b){function e(a,b){return v.call(a,b)}function f(a,b){var c,d,e,f,g,h,i,j,k,l,m,n,o=b&&b.split("/"),p=t.map,q=p&&p["*"]||{};if(a){for(a=a.split("/"),g=a.length-1,t.nodeIdCompat&&x.test(a[g])&&(a[g]=a[g].replace(x,"")),"."===a[0].charAt(0)&&o&&(n=o.slice(0,o.length-1),a=n.concat(a)),k=0;k0&&(a.splice(k-1,2),k-=2)}a=a.join("/")}if((o||q)&&p){for(c=a.split("/"),k=c.length;k>0;k-=1){if(d=c.slice(0,k).join("/"),o)for(l=o.length;l>0;l-=1)if((e=p[o.slice(0,l).join("/")])&&(e=e[d])){f=e,h=k;break}if(f)break;!i&&q&&q[d]&&(i=q[d],j=k)}!f&&i&&(f=i,h=j),f&&(c.splice(0,h,f),a=c.join("/"))}return a}function g(a,c){return function(){var d=w.call(arguments,0);return"string"!=typeof d[0]&&1===d.length&&d.push(null),o.apply(b,d.concat([a,c]))}}function h(a){return function(b){return f(b,a)}}function i(a){return function(b){r[a]=b}}function j(a){if(e(s,a)){var c=s[a];delete s[a],u[a]=!0,n.apply(b,c)}if(!e(r,a)&&!e(u,a))throw new Error("No "+a);return r[a]}function k(a){var b,c=a?a.indexOf("!"):-1;return c>-1&&(b=a.substring(0,c),a=a.substring(c+1,a.length)),[b,a]}function l(a){return a?k(a):[]}function m(a){return function(){return t&&t.config&&t.config[a]||{}}}var n,o,p,q,r={},s={},t={},u={},v=Object.prototype.hasOwnProperty,w=[].slice,x=/\.js$/;p=function(a,b){var c,d=k(a),e=d[0],g=b[1];return a=d[1],e&&(e=f(e,g),c=j(e)),e?a=c&&c.normalize?c.normalize(a,h(g)):f(a,g):(a=f(a,g),d=k(a),e=d[0],a=d[1],e&&(c=j(e))),{f:e?e+"!"+a:a,n:a,pr:e,p:c}},q={require:function(a){return g(a)},exports:function(a){var b=r[a];return void 0!==b?b:r[a]={}},module:function(a){return{id:a,uri:"",exports:r[a],config:m(a)}}},n=function(a,c,d,f){var h,k,m,n,o,t,v,w=[],x=typeof d;if(f=f||a,t=l(f),"undefined"===x||"function"===x){for(c=!c.length&&d.length?["require","exports","module"]:c,o=0;o0&&(b.call(arguments,a.prototype.constructor),e=c.prototype.constructor),e.apply(this,arguments)}function e(){this.constructor=d}var f=b(c),g=b(a);c.displayName=a.displayName,d.prototype=new e;for(var h=0;h":">",'"':""","'":"'","/":"/"};return"string"!=typeof a?a:String(a).replace(/[&<>"'\/\\]/g,function(a){return b[a]})},c.appendMany=function(b,c){if("1.7"===a.fn.jquery.substr(0,3)){var d=a();a.map(c,function(a){d=d.add(a)}),c=d}b.append(c)},c.__cache={};var e=0;return c.GetUniqueElementId=function(a){var b=a.getAttribute("data-select2-id");return null==b&&(a.id?(b=a.id,a.setAttribute("data-select2-id",b)):(a.setAttribute("data-select2-id",++e),b=e.toString())),b},c.StoreData=function(a,b,d){var e=c.GetUniqueElementId(a);c.__cache[e]||(c.__cache[e]={}),c.__cache[e][b]=d},c.GetData=function(b,d){var e=c.GetUniqueElementId(b);return d?c.__cache[e]&&null!=c.__cache[e][d]?c.__cache[e][d]:a(b).data(d):c.__cache[e]},c.RemoveData=function(a){var b=c.GetUniqueElementId(a);null!=c.__cache[b]&&delete c.__cache[b]},c}),b.define("select2/results",["jquery","./utils"],function(a,b){function c(a,b,d){this.$element=a,this.data=d,this.options=b,c.__super__.constructor.call(this)}return b.Extend(c,b.Observable),c.prototype.render=function(){var b=a('');return this.options.get("multiple")&&b.attr("aria-multiselectable","true"),this.$results=b,b},c.prototype.clear=function(){this.$results.empty()},c.prototype.displayMessage=function(b){var c=this.options.get("escapeMarkup");this.clear(),this.hideLoading();var d=a(' '),e=this.options.get("translations").get(b.message);d.append(c(e(b.args))),d[0].className+=" select2-results__message",this.$results.append(d)},c.prototype.hideMessages=function(){this.$results.find(".select2-results__message").remove()},c.prototype.append=function(a){this.hideLoading();var b=[];if(null==a.results||0===a.results.length)return void(0===this.$results.children().length&&this.trigger("results:message",{message:"noResults"}));a.results=this.sort(a.results);for(var c=0;c0?b.first().trigger("mouseenter"):a.first().trigger("mouseenter"),this.ensureHighlightVisible()},c.prototype.setClasses=function(){var c=this;this.data.current(function(d){var e=a.map(d,function(a){return a.id.toString()});c.$results.find(".select2-results__option[aria-selected]").each(function(){var c=a(this),d=b.GetData(this,"data"),f=""+d.id;null!=d.element&&d.element.selected||null==d.element&&a.inArray(f,e)>-1?c.attr("aria-selected","true"):c.attr("aria-selected","false")})})},c.prototype.showLoading=function(a){this.hideLoading();var b=this.options.get("translations").get("searching"),c={disabled:!0,loading:!0,text:b(a)},d=this.option(c);d.className+=" loading-results",this.$results.prepend(d)},c.prototype.hideLoading=function(){this.$results.find(".loading-results").remove()},c.prototype.option=function(c){var d=document.createElement("li");d.className="select2-results__option";var e={role:"treeitem","aria-selected":"false"};c.disabled&&(delete e["aria-selected"],e["aria-disabled"]="true"),null==c.id&&delete e["aria-selected"],null!=c._resultId&&(d.id=c._resultId),c.title&&(d.title=c.title),c.children&&(e.role="group",e["aria-label"]=c.text,delete e["aria-selected"]);for(var f in e){var g=e[f];d.setAttribute(f,g)}if(c.children){var h=a(d),i=document.createElement("strong");i.className="select2-results__group";a(i);this.template(c,i);for(var j=[],k=0;k",{class:"select2-results__options select2-results__options--nested"});n.append(j),h.append(i),h.append(n)}else this.template(c,d);return b.StoreData(d,"data",c),d},c.prototype.bind=function(c,d){var e=this,f=c.id+"-results";this.$results.attr("id",f),c.on("results:all",function(a){e.clear(),e.append(a.data),c.isOpen()&&(e.setClasses(),e.highlightFirstItem())}),c.on("results:append",function(a){e.append(a.data),c.isOpen()&&e.setClasses()}),c.on("query",function(a){e.hideMessages(),e.showLoading(a)}),c.on("select",function(){c.isOpen()&&(e.setClasses(),e.highlightFirstItem())}),c.on("unselect",function(){c.isOpen()&&(e.setClasses(),e.highlightFirstItem())}),c.on("open",function(){e.$results.attr("aria-expanded","true"),e.$results.attr("aria-hidden","false"),e.setClasses(),e.ensureHighlightVisible()}),c.on("close",function(){e.$results.attr("aria-expanded","false"),e.$results.attr("aria-hidden","true"),e.$results.removeAttr("aria-activedescendant")}),c.on("results:toggle",function(){var a=e.getHighlightedResults();0!==a.length&&a.trigger("mouseup")}),c.on("results:select",function(){var a=e.getHighlightedResults();if(0!==a.length){var c=b.GetData(a[0],"data");"true"==a.attr("aria-selected")?e.trigger("close",{}):e.trigger("select",{data:c})}}),c.on("results:previous",function(){var a=e.getHighlightedResults(),b=e.$results.find("[aria-selected]"),c=b.index(a);if(!(c<=0)){var d=c-1;0===a.length&&(d=0);var f=b.eq(d);f.trigger("mouseenter");var g=e.$results.offset().top,h=f.offset().top,i=e.$results.scrollTop()+(h-g);0===d?e.$results.scrollTop(0):h-g<0&&e.$results.scrollTop(i)}}),c.on("results:next",function(){var a=e.getHighlightedResults(),b=e.$results.find("[aria-selected]"),c=b.index(a),d=c+1;if(!(d>=b.length)){var f=b.eq(d);f.trigger("mouseenter");var g=e.$results.offset().top+e.$results.outerHeight(!1),h=f.offset().top+f.outerHeight(!1),i=e.$results.scrollTop()+h-g;0===d?e.$results.scrollTop(0):h>g&&e.$results.scrollTop(i)}}),c.on("results:focus",function(a){a.element.addClass("select2-results__option--highlighted")}),c.on("results:message",function(a){e.displayMessage(a)}),a.fn.mousewheel&&this.$results.on("mousewheel",function(a){var b=e.$results.scrollTop(),c=e.$results.get(0).scrollHeight-b+a.deltaY,d=a.deltaY>0&&b-a.deltaY<=0,f=a.deltaY<0&&c<=e.$results.height();d?(e.$results.scrollTop(0),a.preventDefault(),a.stopPropagation()):f&&(e.$results.scrollTop(e.$results.get(0).scrollHeight-e.$results.height()),a.preventDefault(),a.stopPropagation())}),this.$results.on("mouseup",".select2-results__option[aria-selected]",function(c){var d=a(this),f=b.GetData(this,"data");if("true"===d.attr("aria-selected"))return void(e.options.get("multiple")?e.trigger("unselect",{originalEvent:c,data:f}):e.trigger("close",{}));e.trigger("select",{originalEvent:c,data:f})}),this.$results.on("mouseenter",".select2-results__option[aria-selected]",function(c){var d=b.GetData(this,"data");e.getHighlightedResults().removeClass("select2-results__option--highlighted"),e.trigger("results:focus",{data:d,element:a(this)})})},c.prototype.getHighlightedResults=function(){return this.$results.find(".select2-results__option--highlighted")},c.prototype.destroy=function(){this.$results.remove()},c.prototype.ensureHighlightVisible=function(){var a=this.getHighlightedResults();if(0!==a.length){var b=this.$results.find("[aria-selected]"),c=b.index(a),d=this.$results.offset().top,e=a.offset().top,f=this.$results.scrollTop()+(e-d),g=e-d;f-=2*a.outerHeight(!1),c<=2?this.$results.scrollTop(0):(g>this.$results.outerHeight()||g<0)&&this.$results.scrollTop(f)}},c.prototype.template=function(b,c){var d=this.options.get("templateResult"),e=this.options.get("escapeMarkup"),f=d(b,c);null==f?c.style.display="none":"string"==typeof f?c.innerHTML=e(f):a(c).append(f)},c}),b.define("select2/keys",[],function(){return{BACKSPACE:8,TAB:9,ENTER:13,SHIFT:16,CTRL:17,ALT:18,ESC:27,SPACE:32,PAGE_UP:33,PAGE_DOWN:34,END:35,HOME:36,LEFT:37,UP:38,RIGHT:39,DOWN:40,DELETE:46}}),b.define("select2/selection/base",["jquery","../utils","../keys"],function(a,b,c){function d(a,b){this.$element=a,this.options=b,d.__super__.constructor.call(this)}return b.Extend(d,b.Observable),d.prototype.render=function(){var c=a(' ');return this._tabindex=0,null!=b.GetData(this.$element[0],"old-tabindex")?this._tabindex=b.GetData(this.$element[0],"old-tabindex"):null!=this.$element.attr("tabindex")&&(this._tabindex=this.$element.attr("tabindex")),c.attr("title",this.$element.attr("title")),c.attr("tabindex",this._tabindex),this.$selection=c,c},d.prototype.bind=function(a,b){var d=this,e=(a.id,a.id+"-results");this.container=a,this.$selection.on("focus",function(a){d.trigger("focus",a)}),this.$selection.on("blur",function(a){d._handleBlur(a)}),this.$selection.on("keydown",function(a){d.trigger("keypress",a),a.which===c.SPACE&&a.preventDefault()}),a.on("results:focus",function(a){d.$selection.attr("aria-activedescendant",a.data._resultId)}),a.on("selection:update",function(a){d.update(a.data)}),a.on("open",function(){d.$selection.attr("aria-expanded","true"),d.$selection.attr("aria-owns",e),d._attachCloseHandler(a)}),a.on("close",function(){d.$selection.attr("aria-expanded","false"),d.$selection.removeAttr("aria-activedescendant"),d.$selection.removeAttr("aria-owns"),d.$selection.focus(),window.setTimeout(function(){d.$selection.focus()},0),d._detachCloseHandler(a)}),a.on("enable",function(){d.$selection.attr("tabindex",d._tabindex)}),a.on("disable",function(){d.$selection.attr("tabindex","-1")})},d.prototype._handleBlur=function(b){var c=this;window.setTimeout(function(){document.activeElement==c.$selection[0]||a.contains(c.$selection[0],document.activeElement)||c.trigger("blur",b)},1)},d.prototype._attachCloseHandler=function(c){a(document.body).on("mousedown.select2."+c.id,function(c){var d=a(c.target),e=d.closest(".select2");a(".select2.select2-container--open").each(function(){a(this),this!=e[0]&&b.GetData(this,"element").select2("close")})})},d.prototype._detachCloseHandler=function(b){a(document.body).off("mousedown.select2."+b.id)},d.prototype.position=function(a,b){b.find(".selection").append(a)},d.prototype.destroy=function(){this._detachCloseHandler(this.container)},d.prototype.update=function(a){throw new Error("The `update` method must be defined in child classes.")},d}),b.define("select2/selection/single",["jquery","./base","../utils","../keys"],function(a,b,c,d){function e(){e.__super__.constructor.apply(this,arguments)}return c.Extend(e,b),e.prototype.render=function(){var a=e.__super__.render.call(this);return a.addClass("select2-selection--single"),a.html(' '),a},e.prototype.bind=function(a,b){var c=this;e.__super__.bind.apply(this,arguments);var d=a.id+"-container";this.$selection.find(".select2-selection__rendered").attr("id",d).attr("role","textbox").attr("aria-readonly","true"),this.$selection.attr("aria-labelledby",d),this.$selection.on("mousedown",function(a){1===a.which&&c.trigger("toggle",{originalEvent:a})}),this.$selection.on("focus",function(a){}),this.$selection.on("blur",function(a){}),a.on("focus",function(b){a.isOpen()||c.$selection.focus()})},e.prototype.clear=function(){var a=this.$selection.find(".select2-selection__rendered");a.empty(),a.removeAttr("title")},e.prototype.display=function(a,b){var c=this.options.get("templateSelection");return this.options.get("escapeMarkup")(c(a,b))},e.prototype.selectionContainer=function(){return a(" ")},e.prototype.update=function(a){if(0===a.length)return void this.clear();var b=a[0],c=this.$selection.find(".select2-selection__rendered"),d=this.display(b,c);c.empty().append(d),c.attr("title",b.title||b.text)},e}),b.define("select2/selection/multiple",["jquery","./base","../utils"],function(a,b,c){function d(a,b){d.__super__.constructor.apply(this,arguments)}return c.Extend(d,b),d.prototype.render=function(){var a=d.__super__.render.call(this);return a.addClass("select2-selection--multiple"),a.html(''),a},d.prototype.bind=function(b,e){var f=this;d.__super__.bind.apply(this,arguments),this.$selection.on("click",function(a){f.trigger("toggle",{originalEvent:a})}),this.$selection.on("click",".select2-selection__choice__remove",function(b){if(!f.options.get("disabled")){var d=a(this),e=d.parent(),g=c.GetData(e[0],"data");f.trigger("unselect",{originalEvent:b,data:g})}})},d.prototype.clear=function(){var a=this.$selection.find(".select2-selection__rendered");a.empty(),a.removeAttr("title")},d.prototype.display=function(a,b){var c=this.options.get("templateSelection");return this.options.get("escapeMarkup")(c(a,b))},d.prototype.selectionContainer=function(){return a('× ')},d.prototype.update=function(a){if(this.clear(),0!==a.length){for(var b=[],d=0;d1||c)return a.call(this,b);this.clear();var d=this.createPlaceholder(this.placeholder);this.$selection.find(".select2-selection__rendered").append(d)},b}),b.define("select2/selection/allowClear",["jquery","../keys","../utils"],function(a,b,c){function d(){}return d.prototype.bind=function(a,b,c){var d=this;a.call(this,b,c),null==this.placeholder&&this.options.get("debug")&&window.console&&console.error&&console.error("Select2: The `allowClear` option should be used in combination with the `placeholder` option."),this.$selection.on("mousedown",".select2-selection__clear",function(a){d._handleClear(a)}),b.on("keypress",function(a){d._handleKeyboardClear(a,b)})},d.prototype._handleClear=function(a,b){if(!this.options.get("disabled")){var d=this.$selection.find(".select2-selection__clear");if(0!==d.length){b.stopPropagation();var e=c.GetData(d[0],"data"),f=this.$element.val();this.$element.val(this.placeholder.id);var g={data:e};if(this.trigger("clear",g),g.prevented)return void this.$element.val(f);for(var h=0;h0||0===d.length)){var e=a('× ');c.StoreData(e[0],"data",d),this.$selection.find(".select2-selection__rendered").prepend(e)}},d}),b.define("select2/selection/search",["jquery","../utils","../keys"],function(a,b,c){function d(a,b,c){a.call(this,b,c)}return d.prototype.render=function(b){var c=a(' ');this.$searchContainer=c,this.$search=c.find("input");var d=b.call(this);return this._transferTabIndex(),d},d.prototype.bind=function(a,d,e){var f=this;a.call(this,d,e),d.on("open",function(){f.$search.trigger("focus")}),d.on("close",function(){f.$search.val(""),f.$search.removeAttr("aria-activedescendant"),f.$search.trigger("focus")}),d.on("enable",function(){f.$search.prop("disabled",!1),f._transferTabIndex()}),d.on("disable",function(){f.$search.prop("disabled",!0)}),d.on("focus",function(a){f.$search.trigger("focus")}),d.on("results:focus",function(a){f.$search.attr("aria-activedescendant",a.id)}),this.$selection.on("focusin",".select2-search--inline",function(a){f.trigger("focus",a)}),this.$selection.on("focusout",".select2-search--inline",function(a){f._handleBlur(a)}),this.$selection.on("keydown",".select2-search--inline",function(a){if(a.stopPropagation(),f.trigger("keypress",a),f._keyUpPrevented=a.isDefaultPrevented(),a.which===c.BACKSPACE&&""===f.$search.val()){var d=f.$searchContainer.prev(".select2-selection__choice");if(d.length>0){var e=b.GetData(d[0],"data");f.searchRemoveChoice(e),a.preventDefault()}}});var g=document.documentMode,h=g&&g<=11;this.$selection.on("input.searchcheck",".select2-search--inline",function(a){if(h)return void f.$selection.off("input.search input.searchcheck");f.$selection.off("keyup.search")}),this.$selection.on("keyup.search input.search",".select2-search--inline",function(a){if(h&&"input"===a.type)return void f.$selection.off("input.search input.searchcheck");var b=a.which;b!=c.SHIFT&&b!=c.CTRL&&b!=c.ALT&&b!=c.TAB&&f.handleSearch(a)})},d.prototype._transferTabIndex=function(a){this.$search.attr("tabindex",this.$selection.attr("tabindex")),this.$selection.attr("tabindex","-1")},d.prototype.createPlaceholder=function(a,b){this.$search.attr("placeholder",b.text)},d.prototype.update=function(a,b){var c=this.$search[0]==document.activeElement;if(this.$search.attr("placeholder",""),a.call(this,b),this.$selection.find(".select2-selection__rendered").append(this.$searchContainer),this.resizeSearch(),c){this.$element.find("[data-select2-tag]").length?this.$element.focus():this.$search.focus()}},d.prototype.handleSearch=function(){if(this.resizeSearch(),!this._keyUpPrevented){var a=this.$search.val();this.trigger("query",{term:a})}this._keyUpPrevented=!1},d.prototype.searchRemoveChoice=function(a,b){this.trigger("unselect",{data:b}),this.$search.val(b.text),this.handleSearch()},d.prototype.resizeSearch=function(){this.$search.css("width","25px");var a="";if(""!==this.$search.attr("placeholder"))a=this.$selection.find(".select2-selection__rendered").innerWidth();else{a=.75*(this.$search.val().length+1)+"em"}this.$search.css("width",a)},d}),b.define("select2/selection/eventRelay",["jquery"],function(a){function b(){}return b.prototype.bind=function(b,c,d){var e=this,f=["open","opening","close","closing","select","selecting","unselect","unselecting","clear","clearing"],g=["opening","closing","selecting","unselecting","clearing"];b.call(this,c,d),c.on("*",function(b,c){if(-1!==a.inArray(b,f)){c=c||{};var d=a.Event("select2:"+b,{params:c});e.$element.trigger(d),-1!==a.inArray(b,g)&&(c.prevented=d.isDefaultPrevented())}})},b}),b.define("select2/translation",["jquery","require"],function(a,b){function c(a){this.dict=a||{}}return c.prototype.all=function(){return this.dict},c.prototype.get=function(a){return this.dict[a]},c.prototype.extend=function(b){this.dict=a.extend({},b.all(),this.dict)},c._cache={},c.loadPath=function(a){if(!(a in c._cache)){var d=b(a);c._cache[a]=d}return new c(c._cache[a])},c}),b.define("select2/diacritics",[],function(){return{"Ⓐ":"A","A":"A","À":"A","Á":"A","Â":"A","Ầ":"A","Ấ":"A","Ẫ":"A","Ẩ":"A","Ã":"A","Ā":"A","Ă":"A","Ằ":"A","Ắ":"A","Ẵ":"A","Ẳ":"A","Ȧ":"A","Ǡ":"A","Ä":"A","Ǟ":"A","Ả":"A","Å":"A","Ǻ":"A","Ǎ":"A","Ȁ":"A","Ȃ":"A","Ạ":"A","Ậ":"A","Ặ":"A","Ḁ":"A","Ą":"A","Ⱥ":"A","Ɐ":"A","Ꜳ":"AA","Æ":"AE","Ǽ":"AE","Ǣ":"AE","Ꜵ":"AO","Ꜷ":"AU","Ꜹ":"AV","Ꜻ":"AV","Ꜽ":"AY","Ⓑ":"B","B":"B","Ḃ":"B","Ḅ":"B","Ḇ":"B","Ƀ":"B","Ƃ":"B","Ɓ":"B","Ⓒ":"C","C":"C","Ć":"C","Ĉ":"C","Ċ":"C","Č":"C","Ç":"C","Ḉ":"C","Ƈ":"C","Ȼ":"C","Ꜿ":"C","Ⓓ":"D","D":"D","Ḋ":"D","Ď":"D","Ḍ":"D","Ḑ":"D","Ḓ":"D","Ḏ":"D","Đ":"D","Ƌ":"D","Ɗ":"D","Ɖ":"D","Ꝺ":"D","DZ":"DZ","DŽ":"DZ","Dz":"Dz","Dž":"Dz","Ⓔ":"E","E":"E","È":"E","É":"E","Ê":"E","Ề":"E","Ế":"E","Ễ":"E","Ể":"E","Ẽ":"E","Ē":"E","Ḕ":"E","Ḗ":"E","Ĕ":"E","Ė":"E","Ë":"E","Ẻ":"E","Ě":"E","Ȅ":"E","Ȇ":"E","Ẹ":"E","Ệ":"E","Ȩ":"E","Ḝ":"E","Ę":"E","Ḙ":"E","Ḛ":"E","Ɛ":"E","Ǝ":"E","Ⓕ":"F","F":"F","Ḟ":"F","Ƒ":"F","Ꝼ":"F","Ⓖ":"G","G":"G","Ǵ":"G","Ĝ":"G","Ḡ":"G","Ğ":"G","Ġ":"G","Ǧ":"G","Ģ":"G","Ǥ":"G","Ɠ":"G","Ꞡ":"G","Ᵹ":"G","Ꝿ":"G","Ⓗ":"H","H":"H","Ĥ":"H","Ḣ":"H","Ḧ":"H","Ȟ":"H","Ḥ":"H","Ḩ":"H","Ḫ":"H","Ħ":"H","Ⱨ":"H","Ⱶ":"H","Ɥ":"H","Ⓘ":"I","I":"I","Ì":"I","Í":"I","Î":"I","Ĩ":"I","Ī":"I","Ĭ":"I","İ":"I","Ï":"I","Ḯ":"I","Ỉ":"I","Ǐ":"I","Ȉ":"I","Ȋ":"I","Ị":"I","Į":"I","Ḭ":"I","Ɨ":"I","Ⓙ":"J","J":"J","Ĵ":"J","Ɉ":"J","Ⓚ":"K","K":"K","Ḱ":"K","Ǩ":"K","Ḳ":"K","Ķ":"K","Ḵ":"K","Ƙ":"K","Ⱪ":"K","Ꝁ":"K","Ꝃ":"K","Ꝅ":"K","Ꞣ":"K","Ⓛ":"L","L":"L","Ŀ":"L","Ĺ":"L","Ľ":"L","Ḷ":"L","Ḹ":"L","Ļ":"L","Ḽ":"L","Ḻ":"L","Ł":"L","Ƚ":"L","Ɫ":"L","Ⱡ":"L","Ꝉ":"L","Ꝇ":"L","Ꞁ":"L","LJ":"LJ","Lj":"Lj","Ⓜ":"M","M":"M","Ḿ":"M","Ṁ":"M","Ṃ":"M","Ɱ":"M","Ɯ":"M","Ⓝ":"N","N":"N","Ǹ":"N","Ń":"N","Ñ":"N","Ṅ":"N","Ň":"N","Ṇ":"N","Ņ":"N","Ṋ":"N","Ṉ":"N","Ƞ":"N","Ɲ":"N","Ꞑ":"N","Ꞥ":"N","NJ":"NJ","Nj":"Nj","Ⓞ":"O","O":"O","Ò":"O","Ó":"O","Ô":"O","Ồ":"O","Ố":"O","Ỗ":"O","Ổ":"O","Õ":"O","Ṍ":"O","Ȭ":"O","Ṏ":"O","Ō":"O","Ṑ":"O","Ṓ":"O","Ŏ":"O","Ȯ":"O","Ȱ":"O","Ö":"O","Ȫ":"O","Ỏ":"O","Ő":"O","Ǒ":"O","Ȍ":"O","Ȏ":"O","Ơ":"O","Ờ":"O","Ớ":"O","Ỡ":"O","Ở":"O","Ợ":"O","Ọ":"O","Ộ":"O","Ǫ":"O","Ǭ":"O","Ø":"O","Ǿ":"O","Ɔ":"O","Ɵ":"O","Ꝋ":"O","Ꝍ":"O","Ƣ":"OI","Ꝏ":"OO","Ȣ":"OU","Ⓟ":"P","P":"P","Ṕ":"P","Ṗ":"P","Ƥ":"P","Ᵽ":"P","Ꝑ":"P","Ꝓ":"P","Ꝕ":"P","Ⓠ":"Q","Q":"Q","Ꝗ":"Q","Ꝙ":"Q","Ɋ":"Q","Ⓡ":"R","R":"R","Ŕ":"R","Ṙ":"R","Ř":"R","Ȑ":"R","Ȓ":"R","Ṛ":"R","Ṝ":"R","Ŗ":"R","Ṟ":"R","Ɍ":"R","Ɽ":"R","Ꝛ":"R","Ꞧ":"R","Ꞃ":"R","Ⓢ":"S","S":"S","ẞ":"S","Ś":"S","Ṥ":"S","Ŝ":"S","Ṡ":"S","Š":"S","Ṧ":"S","Ṣ":"S","Ṩ":"S","Ș":"S","Ş":"S","Ȿ":"S","Ꞩ":"S","Ꞅ":"S","Ⓣ":"T","T":"T","Ṫ":"T","Ť":"T","Ṭ":"T","Ț":"T","Ţ":"T","Ṱ":"T","Ṯ":"T","Ŧ":"T","Ƭ":"T","Ʈ":"T","Ⱦ":"T","Ꞇ":"T","Ꜩ":"TZ","Ⓤ":"U","U":"U","Ù":"U","Ú":"U","Û":"U","Ũ":"U","Ṹ":"U","Ū":"U","Ṻ":"U","Ŭ":"U","Ü":"U","Ǜ":"U","Ǘ":"U","Ǖ":"U","Ǚ":"U","Ủ":"U","Ů":"U","Ű":"U","Ǔ":"U","Ȕ":"U","Ȗ":"U","Ư":"U","Ừ":"U","Ứ":"U","Ữ":"U","Ử":"U","Ự":"U","Ụ":"U","Ṳ":"U","Ų":"U","Ṷ":"U","Ṵ":"U","Ʉ":"U","Ⓥ":"V","V":"V","Ṽ":"V","Ṿ":"V","Ʋ":"V","Ꝟ":"V","Ʌ":"V","Ꝡ":"VY","Ⓦ":"W","W":"W","Ẁ":"W","Ẃ":"W","Ŵ":"W","Ẇ":"W","Ẅ":"W","Ẉ":"W","Ⱳ":"W","Ⓧ":"X","X":"X","Ẋ":"X","Ẍ":"X","Ⓨ":"Y","Y":"Y","Ỳ":"Y","Ý":"Y","Ŷ":"Y","Ỹ":"Y","Ȳ":"Y","Ẏ":"Y","Ÿ":"Y","Ỷ":"Y","Ỵ":"Y","Ƴ":"Y","Ɏ":"Y","Ỿ":"Y","Ⓩ":"Z","Z":"Z","Ź":"Z","Ẑ":"Z","Ż":"Z","Ž":"Z","Ẓ":"Z","Ẕ":"Z","Ƶ":"Z","Ȥ":"Z","Ɀ":"Z","Ⱬ":"Z","Ꝣ":"Z","ⓐ":"a","a":"a","ẚ":"a","à":"a","á":"a","â":"a","ầ":"a","ấ":"a","ẫ":"a","ẩ":"a","ã":"a","ā":"a","ă":"a","ằ":"a","ắ":"a","ẵ":"a","ẳ":"a","ȧ":"a","ǡ":"a","ä":"a","ǟ":"a","ả":"a","å":"a","ǻ":"a","ǎ":"a","ȁ":"a","ȃ":"a","ạ":"a","ậ":"a","ặ":"a","ḁ":"a","ą":"a","ⱥ":"a","ɐ":"a","ꜳ":"aa","æ":"ae","ǽ":"ae","ǣ":"ae","ꜵ":"ao","ꜷ":"au","ꜹ":"av","ꜻ":"av","ꜽ":"ay","ⓑ":"b","b":"b","ḃ":"b","ḅ":"b","ḇ":"b","ƀ":"b","ƃ":"b","ɓ":"b","ⓒ":"c","c":"c","ć":"c","ĉ":"c","ċ":"c","č":"c","ç":"c","ḉ":"c","ƈ":"c","ȼ":"c","ꜿ":"c","ↄ":"c","ⓓ":"d","d":"d","ḋ":"d","ď":"d","ḍ":"d","ḑ":"d","ḓ":"d","ḏ":"d","đ":"d","ƌ":"d","ɖ":"d","ɗ":"d","ꝺ":"d","dz":"dz","dž":"dz","ⓔ":"e","e":"e","è":"e","é":"e","ê":"e","ề":"e","ế":"e","ễ":"e","ể":"e","ẽ":"e","ē":"e","ḕ":"e","ḗ":"e","ĕ":"e","ė":"e","ë":"e","ẻ":"e","ě":"e","ȅ":"e","ȇ":"e","ẹ":"e","ệ":"e","ȩ":"e","ḝ":"e","ę":"e","ḙ":"e","ḛ":"e","ɇ":"e","ɛ":"e","ǝ":"e","ⓕ":"f","f":"f","ḟ":"f","ƒ":"f","ꝼ":"f","ⓖ":"g","g":"g","ǵ":"g","ĝ":"g","ḡ":"g","ğ":"g","ġ":"g","ǧ":"g","ģ":"g","ǥ":"g","ɠ":"g","ꞡ":"g","ᵹ":"g","ꝿ":"g","ⓗ":"h","h":"h","ĥ":"h","ḣ":"h","ḧ":"h","ȟ":"h","ḥ":"h","ḩ":"h","ḫ":"h","ẖ":"h","ħ":"h","ⱨ":"h","ⱶ":"h","ɥ":"h","ƕ":"hv","ⓘ":"i","i":"i","ì":"i","í":"i","î":"i","ĩ":"i","ī":"i","ĭ":"i","ï":"i","ḯ":"i","ỉ":"i","ǐ":"i","ȉ":"i","ȋ":"i","ị":"i","į":"i","ḭ":"i","ɨ":"i","ı":"i","ⓙ":"j","j":"j","ĵ":"j","ǰ":"j","ɉ":"j","ⓚ":"k","k":"k","ḱ":"k","ǩ":"k","ḳ":"k","ķ":"k","ḵ":"k","ƙ":"k","ⱪ":"k","ꝁ":"k","ꝃ":"k","ꝅ":"k","ꞣ":"k","ⓛ":"l","l":"l","ŀ":"l","ĺ":"l","ľ":"l","ḷ":"l","ḹ":"l","ļ":"l","ḽ":"l","ḻ":"l","ſ":"l","ł":"l","ƚ":"l","ɫ":"l","ⱡ":"l","ꝉ":"l","ꞁ":"l","ꝇ":"l","lj":"lj","ⓜ":"m","m":"m","ḿ":"m","ṁ":"m","ṃ":"m","ɱ":"m","ɯ":"m","ⓝ":"n","n":"n","ǹ":"n","ń":"n","ñ":"n","ṅ":"n","ň":"n","ṇ":"n","ņ":"n","ṋ":"n","ṉ":"n","ƞ":"n","ɲ":"n","ʼn":"n","ꞑ":"n","ꞥ":"n","nj":"nj","ⓞ":"o","o":"o","ò":"o","ó":"o","ô":"o","ồ":"o","ố":"o","ỗ":"o","ổ":"o","õ":"o","ṍ":"o","ȭ":"o","ṏ":"o","ō":"o","ṑ":"o","ṓ":"o","ŏ":"o","ȯ":"o","ȱ":"o","ö":"o","ȫ":"o","ỏ":"o","ő":"o","ǒ":"o","ȍ":"o","ȏ":"o","ơ":"o","ờ":"o","ớ":"o","ỡ":"o","ở":"o","ợ":"o","ọ":"o","ộ":"o","ǫ":"o","ǭ":"o","ø":"o","ǿ":"o","ɔ":"o","ꝋ":"o","ꝍ":"o","ɵ":"o","ƣ":"oi","ȣ":"ou","ꝏ":"oo","ⓟ":"p","p":"p","ṕ":"p","ṗ":"p","ƥ":"p","ᵽ":"p","ꝑ":"p","ꝓ":"p","ꝕ":"p","ⓠ":"q","q":"q","ɋ":"q","ꝗ":"q","ꝙ":"q","ⓡ":"r","r":"r","ŕ":"r","ṙ":"r","ř":"r","ȑ":"r","ȓ":"r","ṛ":"r","ṝ":"r","ŗ":"r","ṟ":"r","ɍ":"r","ɽ":"r","ꝛ":"r","ꞧ":"r","ꞃ":"r","ⓢ":"s","s":"s","ß":"s","ś":"s","ṥ":"s","ŝ":"s","ṡ":"s","š":"s","ṧ":"s","ṣ":"s","ṩ":"s","ș":"s","ş":"s","ȿ":"s","ꞩ":"s","ꞅ":"s","ẛ":"s","ⓣ":"t","t":"t","ṫ":"t","ẗ":"t","ť":"t","ṭ":"t","ț":"t","ţ":"t","ṱ":"t","ṯ":"t","ŧ":"t","ƭ":"t","ʈ":"t","ⱦ":"t","ꞇ":"t","ꜩ":"tz","ⓤ":"u","u":"u","ù":"u","ú":"u","û":"u","ũ":"u","ṹ":"u","ū":"u","ṻ":"u","ŭ":"u","ü":"u","ǜ":"u","ǘ":"u","ǖ":"u","ǚ":"u","ủ":"u","ů":"u","ű":"u","ǔ":"u","ȕ":"u","ȗ":"u","ư":"u","ừ":"u","ứ":"u","ữ":"u","ử":"u","ự":"u","ụ":"u","ṳ":"u","ų":"u","ṷ":"u","ṵ":"u","ʉ":"u","ⓥ":"v","v":"v","ṽ":"v","ṿ":"v","ʋ":"v","ꝟ":"v","ʌ":"v","ꝡ":"vy","ⓦ":"w","w":"w","ẁ":"w","ẃ":"w","ŵ":"w","ẇ":"w","ẅ":"w","ẘ":"w","ẉ":"w","ⱳ":"w","ⓧ":"x","x":"x","ẋ":"x","ẍ":"x","ⓨ":"y","y":"y","ỳ":"y","ý":"y","ŷ":"y","ỹ":"y","ȳ":"y","ẏ":"y","ÿ":"y","ỷ":"y","ẙ":"y","ỵ":"y","ƴ":"y","ɏ":"y","ỿ":"y","ⓩ":"z","z":"z","ź":"z","ẑ":"z","ż":"z","ž":"z","ẓ":"z","ẕ":"z","ƶ":"z","ȥ":"z","ɀ":"z","ⱬ":"z","ꝣ":"z","Ά":"Α","Έ":"Ε","Ή":"Η","Ί":"Ι","Ϊ":"Ι","Ό":"Ο","Ύ":"Υ","Ϋ":"Υ","Ώ":"Ω","ά":"α","έ":"ε","ή":"η","ί":"ι","ϊ":"ι","ΐ":"ι","ό":"ο","ύ":"υ","ϋ":"υ","ΰ":"υ","ω":"ω","ς":"σ"}}),b.define("select2/data/base",["../utils"],function(a){function b(a,c){b.__super__.constructor.call(this)}return a.Extend(b,a.Observable),b.prototype.current=function(a){throw new Error("The `current` method must be defined in child classes.")},b.prototype.query=function(a,b){throw new Error("The `query` method must be defined in child classes.")},b.prototype.bind=function(a,b){},b.prototype.destroy=function(){},b.prototype.generateResultId=function(b,c){var d=b.id+"-result-";return d+=a.generateChars(4),null!=c.id?d+="-"+c.id.toString():d+="-"+a.generateChars(4),d},b}),b.define("select2/data/select",["./base","../utils","jquery"],function(a,b,c){function d(a,b){this.$element=a,this.options=b,d.__super__.constructor.call(this)}return b.Extend(d,a),d.prototype.current=function(a){var b=[],d=this;this.$element.find(":selected").each(function(){var a=c(this),e=d.item(a);b.push(e)}),a(b)},d.prototype.select=function(a){var b=this;if(a.selected=!0,c(a.element).is("option"))return a.element.selected=!0,void this.$element.trigger("change");if(this.$element.prop("multiple"))this.current(function(d){var e=[];a=[a],a.push.apply(a,d);for(var f=0;f=0){var k=f.filter(d(j)),l=this.item(k),m=c.extend(!0,{},j,l),n=this.option(m);k.replaceWith(n)}else{var o=this.option(j);if(j.children){var p=this.convertToOptions(j.children);b.appendMany(o,p)}h.push(o)}}return h},d}),b.define("select2/data/ajax",["./array","../utils","jquery"],function(a,b,c){function d(a,b){this.ajaxOptions=this._applyDefaults(b.get("ajax")),null!=this.ajaxOptions.processResults&&(this.processResults=this.ajaxOptions.processResults),d.__super__.constructor.call(this,a,b)}return b.Extend(d,a),d.prototype._applyDefaults=function(a){var b={data:function(a){return c.extend({},a,{q:a.term})},transport:function(a,b,d){var e=c.ajax(a);return e.then(b),e.fail(d),e}};return c.extend({},b,a,!0)},d.prototype.processResults=function(a){return a},d.prototype.query=function(a,b){function d(){var d=f.transport(f,function(d){var f=e.processResults(d,a);e.options.get("debug")&&window.console&&console.error&&(f&&f.results&&c.isArray(f.results)||console.error("Select2: The AJAX results did not return an array in the `results` key of the response.")),b(f)},function(){"status"in d&&(0===d.status||"0"===d.status)||e.trigger("results:message",{message:"errorLoading"})});e._request=d}var e=this;null!=this._request&&(c.isFunction(this._request.abort)&&this._request.abort(),this._request=null);var f=c.extend({type:"GET"},this.ajaxOptions);"function"==typeof f.url&&(f.url=f.url.call(this.$element,a)),"function"==typeof f.data&&(f.data=f.data.call(this.$element,a)),this.ajaxOptions.delay&&null!=a.term?(this._queryTimeout&&window.clearTimeout(this._queryTimeout),this._queryTimeout=window.setTimeout(d,this.ajaxOptions.delay)):d()},d}),b.define("select2/data/tags",["jquery"],function(a){function b(b,c,d){var e=d.get("tags"),f=d.get("createTag");void 0!==f&&(this.createTag=f);var g=d.get("insertTag");if(void 0!==g&&(this.insertTag=g),b.call(this,c,d),a.isArray(e))for(var h=0;h0&&b.term.length>this.maximumInputLength)return void this.trigger("results:message",{message:"inputTooLong",args:{maximum:this.maximumInputLength,input:b.term,params:b}});a.call(this,b,c)},a}),b.define("select2/data/maximumSelectionLength",[],function(){function a(a,b,c){this.maximumSelectionLength=c.get("maximumSelectionLength"),a.call(this,b,c)}return a.prototype.query=function(a,b,c){var d=this;this.current(function(e){var f=null!=e?e.length:0;if(d.maximumSelectionLength>0&&f>=d.maximumSelectionLength)return void d.trigger("results:message",{message:"maximumSelected",args:{maximum:d.maximumSelectionLength}});a.call(d,b,c)})},a}),b.define("select2/dropdown",["jquery","./utils"],function(a,b){function c(a,b){this.$element=a,this.options=b,c.__super__.constructor.call(this)}return b.Extend(c,b.Observable),c.prototype.render=function(){var b=a(' ');return b.attr("dir",this.options.get("dir")),this.$dropdown=b,b},c.prototype.bind=function(){},c.prototype.position=function(a,b){},c.prototype.destroy=function(){this.$dropdown.remove()},c}),b.define("select2/dropdown/search",["jquery","../utils"],function(a,b){function c(){}return c.prototype.render=function(b){var c=b.call(this),d=a(' ');return this.$searchContainer=d,this.$search=d.find("input"),c.prepend(d),c},c.prototype.bind=function(b,c,d){var e=this;b.call(this,c,d),this.$search.on("keydown",function(a){e.trigger("keypress",a),e._keyUpPrevented=a.isDefaultPrevented()}),this.$search.on("input",function(b){a(this).off("keyup")}),this.$search.on("keyup input",function(a){e.handleSearch(a)}),c.on("open",function(){e.$search.attr("tabindex",0),e.$search.focus(),window.setTimeout(function(){e.$search.focus()},0)}),c.on("close",function(){e.$search.attr("tabindex",-1),e.$search.val(""),e.$search.blur()}),c.on("focus",function(){c.isOpen()||e.$search.focus()}),c.on("results:all",function(a){if(null==a.query.term||""===a.query.term){e.showSearch(a)?e.$searchContainer.removeClass("select2-search--hide"):e.$searchContainer.addClass("select2-search--hide")}})},c.prototype.handleSearch=function(a){if(!this._keyUpPrevented){var b=this.$search.val();this.trigger("query",{term:b})}this._keyUpPrevented=!1},c.prototype.showSearch=function(a,b){return!0},c}),b.define("select2/dropdown/hidePlaceholder",[],function(){function a(a,b,c,d){this.placeholder=this.normalizePlaceholder(c.get("placeholder")),a.call(this,b,c,d)}return a.prototype.append=function(a,b){b.results=this.removePlaceholder(b.results),a.call(this,b)},a.prototype.normalizePlaceholder=function(a,b){return"string"==typeof b&&(b={id:"",text:b}),b},a.prototype.removePlaceholder=function(a,b){for(var c=b.slice(0),d=b.length-1;d>=0;d--){var e=b[d];this.placeholder.id===e.id&&c.splice(d,1)}return c},a}),b.define("select2/dropdown/infiniteScroll",["jquery"],function(a){function b(a,b,c,d){this.lastParams={},a.call(this,b,c,d),this.$loadingMore=this.createLoadingMore(),this.loading=!1}return b.prototype.append=function(a,b){this.$loadingMore.remove(),this.loading=!1,a.call(this,b),this.showLoadingMore(b)&&this.$results.append(this.$loadingMore)},b.prototype.bind=function(b,c,d){var e=this;b.call(this,c,d),c.on("query",function(a){e.lastParams=a,e.loading=!0}),c.on("query:append",function(a){e.lastParams=a,e.loading=!0}),this.$results.on("scroll",function(){var b=a.contains(document.documentElement,e.$loadingMore[0]);if(!e.loading&&b){e.$results.offset().top+e.$results.outerHeight(!1)+50>=e.$loadingMore.offset().top+e.$loadingMore.outerHeight(!1)&&e.loadMore()}})},b.prototype.loadMore=function(){this.loading=!0;var b=a.extend({},{page:1},this.lastParams);b.page++,this.trigger("query:append",b)},b.prototype.showLoadingMore=function(a,b){return b.pagination&&b.pagination.more},b.prototype.createLoadingMore=function(){var b=a(' '),c=this.options.get("translations").get("loadingMore");return b.html(c(this.lastParams)),b},b}),b.define("select2/dropdown/attachBody",["jquery","../utils"],function(a,b){function c(b,c,d){this.$dropdownParent=d.get("dropdownParent")||a(document.body),b.call(this,c,d)}return c.prototype.bind=function(a,b,c){var d=this,e=!1;a.call(this,b,c),b.on("open",function(){d._showDropdown(),d._attachPositioningHandler(b),e||(e=!0,b.on("results:all",function(){d._positionDropdown(),d._resizeDropdown()}),b.on("results:append",function(){d._positionDropdown(),d._resizeDropdown()}))}),b.on("close",function(){d._hideDropdown(),d._detachPositioningHandler(b)}),this.$dropdownContainer.on("mousedown",function(a){a.stopPropagation()})},c.prototype.destroy=function(a){a.call(this),this.$dropdownContainer.remove()},c.prototype.position=function(a,b,c){b.attr("class",c.attr("class")),b.removeClass("select2"),b.addClass("select2-container--open"),b.css({position:"absolute",top:-999999}),this.$container=c},c.prototype.render=function(b){var c=a(" "),d=b.call(this);return c.append(d),this.$dropdownContainer=c,c},c.prototype._hideDropdown=function(a){this.$dropdownContainer.detach()},c.prototype._attachPositioningHandler=function(c,d){var e=this,f="scroll.select2."+d.id,g="resize.select2."+d.id,h="orientationchange.select2."+d.id,i=this.$container.parents().filter(b.hasScroll);i.each(function(){b.StoreData(this,"select2-scroll-position",{x:a(this).scrollLeft(),y:a(this).scrollTop()})}),i.on(f,function(c){var d=b.GetData(this,"select2-scroll-position");a(this).scrollTop(d.y)}),a(window).on(f+" "+g+" "+h,function(a){e._positionDropdown(),e._resizeDropdown()})},c.prototype._detachPositioningHandler=function(c,d){var e="scroll.select2."+d.id,f="resize.select2."+d.id,g="orientationchange.select2."+d.id;this.$container.parents().filter(b.hasScroll).off(e),a(window).off(e+" "+f+" "+g)},c.prototype._positionDropdown=function(){var b=a(window),c=this.$dropdown.hasClass("select2-dropdown--above"),d=this.$dropdown.hasClass("select2-dropdown--below"),e=null,f=this.$container.offset();f.bottom=f.top+this.$container.outerHeight(!1);var g={height:this.$container.outerHeight(!1)};g.top=f.top,g.bottom=f.top+g.height;var h={height:this.$dropdown.outerHeight(!1)},i={top:b.scrollTop(),bottom:b.scrollTop()+b.height()},j=i.topf.bottom+h.height,l={left:f.left,top:g.bottom},m=this.$dropdownParent;"static"===m.css("position")&&(m=m.offsetParent());var n=m.offset();l.top-=n.top,l.left-=n.left,c||d||(e="below"),k||!j||c?!j&&k&&c&&(e="below"):e="above",("above"==e||c&&"below"!==e)&&(l.top=g.top-n.top-h.height),null!=e&&(this.$dropdown.removeClass("select2-dropdown--below select2-dropdown--above").addClass("select2-dropdown--"+e),this.$container.removeClass("select2-container--below select2-container--above").addClass("select2-container--"+e)),this.$dropdownContainer.css(l)},c.prototype._resizeDropdown=function(){var a={width:this.$container.outerWidth(!1)+"px"};this.options.get("dropdownAutoWidth")&&(a.minWidth=a.width,a.position="relative",a.width="auto"),this.$dropdown.css(a)},c.prototype._showDropdown=function(a){this.$dropdownContainer.appendTo(this.$dropdownParent),this._positionDropdown(),this._resizeDropdown()},c}),b.define("select2/dropdown/minimumResultsForSearch",[],function(){function a(b){for(var c=0,d=0;d0&&(l.dataAdapter=j.Decorate(l.dataAdapter,r)),l.maximumInputLength>0&&(l.dataAdapter=j.Decorate(l.dataAdapter,s)),l.maximumSelectionLength>0&&(l.dataAdapter=j.Decorate(l.dataAdapter,t)),l.tags&&(l.dataAdapter=j.Decorate(l.dataAdapter,p)),null==l.tokenSeparators&&null==l.tokenizer||(l.dataAdapter=j.Decorate(l.dataAdapter,q)),null!=l.query){var C=b(l.amdBase+"compat/query");l.dataAdapter=j.Decorate(l.dataAdapter,C)}if(null!=l.initSelection){var D=b(l.amdBase+"compat/initSelection");l.dataAdapter=j.Decorate(l.dataAdapter,D)}}if(null==l.resultsAdapter&&(l.resultsAdapter=c,null!=l.ajax&&(l.resultsAdapter=j.Decorate(l.resultsAdapter,x)),null!=l.placeholder&&(l.resultsAdapter=j.Decorate(l.resultsAdapter,w)),l.selectOnClose&&(l.resultsAdapter=j.Decorate(l.resultsAdapter,A))),null==l.dropdownAdapter){if(l.multiple)l.dropdownAdapter=u;else{var E=j.Decorate(u,v);l.dropdownAdapter=E}if(0!==l.minimumResultsForSearch&&(l.dropdownAdapter=j.Decorate(l.dropdownAdapter,z)),l.closeOnSelect&&(l.dropdownAdapter=j.Decorate(l.dropdownAdapter,B)),null!=l.dropdownCssClass||null!=l.dropdownCss||null!=l.adaptDropdownCssClass){var F=b(l.amdBase+"compat/dropdownCss");l.dropdownAdapter=j.Decorate(l.dropdownAdapter,F)}l.dropdownAdapter=j.Decorate(l.dropdownAdapter,y)}if(null==l.selectionAdapter){if(l.multiple?l.selectionAdapter=e:l.selectionAdapter=d,null!=l.placeholder&&(l.selectionAdapter=j.Decorate(l.selectionAdapter,f)),l.allowClear&&(l.selectionAdapter=j.Decorate(l.selectionAdapter,g)),l.multiple&&(l.selectionAdapter=j.Decorate(l.selectionAdapter,h)),null!=l.containerCssClass||null!=l.containerCss||null!=l.adaptContainerCssClass){var G=b(l.amdBase+"compat/containerCss");l.selectionAdapter=j.Decorate(l.selectionAdapter,G)}l.selectionAdapter=j.Decorate(l.selectionAdapter,i)}if("string"==typeof l.language)if(l.language.indexOf("-")>0){var H=l.language.split("-"),I=H[0];l.language=[l.language,I]}else l.language=[l.language];if(a.isArray(l.language)){var J=new k;l.language.push("en");for(var K=l.language,L=0;L0){for(var f=a.extend(!0,{},e),g=e.children.length-1;g>=0;g--){null==c(d,e.children[g])&&f.children.splice(g,1)}return f.children.length>0?f:c(d,f)}var h=b(e.text).toUpperCase(),i=b(d.term).toUpperCase();return h.indexOf(i)>-1?e:null}this.defaults={amdBase:"./",amdLanguageBase:"./i18n/",closeOnSelect:!0,debug:!1,dropdownAutoWidth:!1,escapeMarkup:j.escapeMarkup,language:C,matcher:c,minimumInputLength:0,maximumInputLength:0,maximumSelectionLength:0,minimumResultsForSearch:0,selectOnClose:!1,sorter:function(a){return a},templateResult:function(a){return a.text},templateSelection:function(a){return a.text},theme:"default",width:"resolve"}},D.prototype.set=function(b,c){var d=a.camelCase(b),e={};e[d]=c;var f=j._convertData(e);a.extend(!0,this.defaults,f)},new D}),b.define("select2/options",["require","jquery","./defaults","./utils"],function(a,b,c,d){function e(b,e){if(this.options=b,null!=e&&this.fromElement(e),this.options=c.apply(this.options),e&&e.is("input")){var f=a(this.get("amdBase")+"compat/inputData");this.options.dataAdapter=d.Decorate(this.options.dataAdapter,f)}}return e.prototype.fromElement=function(a){var c=["select2"];null==this.options.multiple&&(this.options.multiple=a.prop("multiple")),null==this.options.disabled&&(this.options.disabled=a.prop("disabled")),null==this.options.language&&(a.prop("lang")?this.options.language=a.prop("lang").toLowerCase():a.closest("[lang]").prop("lang")&&(this.options.language=a.closest("[lang]").prop("lang"))),null==this.options.dir&&(a.prop("dir")?this.options.dir=a.prop("dir"):a.closest("[dir]").prop("dir")?this.options.dir=a.closest("[dir]").prop("dir"):this.options.dir="ltr"),a.prop("disabled",this.options.disabled),a.prop("multiple",this.options.multiple),d.GetData(a[0],"select2Tags")&&(this.options.debug&&window.console&&console.warn&&console.warn('Select2: The `data-select2-tags` attribute has been changed to use the `data-data` and `data-tags="true"` attributes and will be removed in future versions of Select2.'),d.StoreData(a[0],"data",d.GetData(a[0],"select2Tags")),d.StoreData(a[0],"tags",!0)),d.GetData(a[0],"ajaxUrl")&&(this.options.debug&&window.console&&console.warn&&console.warn("Select2: The `data-ajax-url` attribute has been changed to `data-ajax--url` and support for the old attribute will be removed in future versions of Select2."),a.attr("ajax--url",d.GetData(a[0],"ajaxUrl")),d.StoreData(a[0],"ajax-Url",d.GetData(a[0],"ajaxUrl")));var e={};e=b.fn.jquery&&"1."==b.fn.jquery.substr(0,2)&&a[0].dataset?b.extend(!0,{},a[0].dataset,d.GetData(a[0])):d.GetData(a[0]);var f=b.extend(!0,{},e);f=d._convertData(f);for(var g in f)b.inArray(g,c)>-1||(b.isPlainObject(this.options[g])?b.extend(this.options[g],f[g]):this.options[g]=f[g]);return this},e.prototype.get=function(a){return this.options[a]},e.prototype.set=function(a,b){this.options[a]=b},e}),b.define("select2/core",["jquery","./options","./utils","./keys"],function(a,b,c,d){var e=function(a,d){null!=c.GetData(a[0],"select2")&&c.GetData(a[0],"select2").destroy(),this.$element=a,this.id=this._generateId(a),d=d||{},this.options=new b(d,a),e.__super__.constructor.call(this);var f=a.attr("tabindex")||0;c.StoreData(a[0],"old-tabindex",f),a.attr("tabindex","-1");var g=this.options.get("dataAdapter");this.dataAdapter=new g(a,this.options);var h=this.render();this._placeContainer(h);var i=this.options.get("selectionAdapter");this.selection=new i(a,this.options),this.$selection=this.selection.render(),this.selection.position(this.$selection,h);var j=this.options.get("dropdownAdapter");this.dropdown=new j(a,this.options),this.$dropdown=this.dropdown.render(),this.dropdown.position(this.$dropdown,h);var k=this.options.get("resultsAdapter");this.results=new k(a,this.options,this.dataAdapter),this.$results=this.results.render(),this.results.position(this.$results,this.$dropdown);var l=this;this._bindAdapters(),this._registerDomEvents(),this._registerDataEvents(),this._registerSelectionEvents(),this._registerDropdownEvents(),this._registerResultsEvents(),this._registerEvents(),this.dataAdapter.current(function(a){l.trigger("selection:update",{data:a})}),a.addClass("select2-hidden-accessible"),a.attr("aria-hidden","true"),this._syncAttributes(),c.StoreData(a[0],"select2",this),a.data("select2",this)};return c.Extend(e,c.Observable),e.prototype._generateId=function(a){var b="";return b=null!=a.attr("id")?a.attr("id"):null!=a.attr("name")?a.attr("name")+"-"+c.generateChars(2):c.generateChars(4),b=b.replace(/(:|\.|\[|\]|,)/g,""),b="select2-"+b},e.prototype._placeContainer=function(a){a.insertAfter(this.$element);var b=this._resolveWidth(this.$element,this.options.get("width"));null!=b&&a.css("width",b)},e.prototype._resolveWidth=function(a,b){var c=/^width:(([-+]?([0-9]*\.)?[0-9]+)(px|em|ex|%|in|cm|mm|pt|pc))/i;if("resolve"==b){var d=this._resolveWidth(a,"style");return null!=d?d:this._resolveWidth(a,"element")}if("element"==b){var e=a.outerWidth(!1);return e<=0?"auto":e+"px"}if("style"==b){var f=a.attr("style");if("string"!=typeof f)return null;for(var g=f.split(";"),h=0,i=g.length;h=1)return k[1]}return null}return b},e.prototype._bindAdapters=function(){this.dataAdapter.bind(this,this.$container),this.selection.bind(this,this.$container),this.dropdown.bind(this,this.$container),this.results.bind(this,this.$container)},e.prototype._registerDomEvents=function(){var b=this;this.$element.on("change.select2",function(){b.dataAdapter.current(function(a){b.trigger("selection:update",{data:a})})}),this.$element.on("focus.select2",function(a){b.trigger("focus",a)}),this._syncA=c.bind(this._syncAttributes,this),this._syncS=c.bind(this._syncSubtree,this),this.$element[0].attachEvent&&this.$element[0].attachEvent("onpropertychange",this._syncA);var d=window.MutationObserver||window.WebKitMutationObserver||window.MozMutationObserver;null!=d?(this._observer=new d(function(c){a.each(c,b._syncA),a.each(c,b._syncS)}),this._observer.observe(this.$element[0],{attributes:!0,childList:!0,subtree:!1})):this.$element[0].addEventListener&&(this.$element[0].addEventListener("DOMAttrModified",b._syncA,!1),this.$element[0].addEventListener("DOMNodeInserted",b._syncS,!1),this.$element[0].addEventListener("DOMNodeRemoved",b._syncS,!1))},e.prototype._registerDataEvents=function(){var a=this;this.dataAdapter.on("*",function(b,c){a.trigger(b,c)})},e.prototype._registerSelectionEvents=function(){var b=this,c=["toggle","focus"];this.selection.on("toggle",function(){b.toggleDropdown()}),this.selection.on("focus",function(a){b.focus(a)}),this.selection.on("*",function(d,e){-1===a.inArray(d,c)&&b.trigger(d,e)})},e.prototype._registerDropdownEvents=function(){var a=this;this.dropdown.on("*",function(b,c){a.trigger(b,c)})},e.prototype._registerResultsEvents=function(){var a=this;this.results.on("*",function(b,c){a.trigger(b,c)})},e.prototype._registerEvents=function(){var a=this;this.on("open",function(){a.$container.addClass("select2-container--open")}),this.on("close",function(){a.$container.removeClass("select2-container--open")}),this.on("enable",function(){a.$container.removeClass("select2-container--disabled")}),this.on("disable",function(){a.$container.addClass("select2-container--disabled")}),this.on("blur",function(){a.$container.removeClass("select2-container--focus")}),this.on("query",function(b){a.isOpen()||a.trigger("open",{}),this.dataAdapter.query(b,function(c){a.trigger("results:all",{data:c,query:b})})}),this.on("query:append",function(b){this.dataAdapter.query(b,function(c){a.trigger("results:append",{data:c,query:b})})}),this.on("keypress",function(b){var c=b.which;a.isOpen()?c===d.ESC||c===d.TAB||c===d.UP&&b.altKey?(a.close(),b.preventDefault()):c===d.ENTER?(a.trigger("results:select",{}),b.preventDefault()):c===d.SPACE&&b.ctrlKey?(a.trigger("results:toggle",{}),b.preventDefault()):c===d.UP?(a.trigger("results:previous",{}),b.preventDefault()):c===d.DOWN&&(a.trigger("results:next",{}),b.preventDefault()):(c===d.ENTER||c===d.SPACE||c===d.DOWN&&b.altKey)&&(a.open(),b.preventDefault())})},e.prototype._syncAttributes=function(){this.options.set("disabled",this.$element.prop("disabled")),this.options.get("disabled")?(this.isOpen()&&this.close(),this.trigger("disable",{})):this.trigger("enable",{})},e.prototype._syncSubtree=function(a,b){var c=!1,d=this;if(!a||!a.target||"OPTION"===a.target.nodeName||"OPTGROUP"===a.target.nodeName){if(b)if(b.addedNodes&&b.addedNodes.length>0)for(var e=0;e0&&(c=!0);else c=!0;c&&this.dataAdapter.current(function(a){d.trigger("selection:update",{data:a})})}},e.prototype.trigger=function(a,b){var c=e.__super__.trigger,d={open:"opening",close:"closing",select:"selecting",unselect:"unselecting",clear:"clearing"};if(void 0===b&&(b={}),a in d){var f=d[a],g={prevented:!1,name:a,args:b};if(c.call(this,f,g),g.prevented)return void(b.prevented=!0)}c.call(this,a,b)},e.prototype.toggleDropdown=function(){this.options.get("disabled")||(this.isOpen()?this.close():this.open())},e.prototype.open=function(){this.isOpen()||this.trigger("query",{})},e.prototype.close=function(){this.isOpen()&&this.trigger("close",{})},e.prototype.isOpen=function(){return this.$container.hasClass("select2-container--open")},e.prototype.hasFocus=function(){return this.$container.hasClass("select2-container--focus")},e.prototype.focus=function(a){this.hasFocus()||(this.$container.addClass("select2-container--focus"),this.trigger("focus",{}))},e.prototype.enable=function(a){this.options.get("debug")&&window.console&&console.warn&&console.warn('Select2: The `select2("enable")` method has been deprecated and will be removed in later Select2 versions. Use $element.prop("disabled") instead.'),null!=a&&0!==a.length||(a=[!0]);var b=!a[0];this.$element.prop("disabled",b)},e.prototype.data=function(){this.options.get("debug")&&arguments.length>0&&window.console&&console.warn&&console.warn('Select2: Data can no longer be set using `select2("data")`. You should consider setting the value instead using `$element.val()`.');var a=[];return this.dataAdapter.current(function(b){a=b}),a},e.prototype.val=function(b){if(this.options.get("debug")&&window.console&&console.warn&&console.warn('Select2: The `select2("val")` method has been deprecated and will be removed in later Select2 versions. Use $element.val() instead.'),null==b||0===b.length)return this.$element.val();var c=b[0];a.isArray(c)&&(c=a.map(c,function(a){return a.toString()})),this.$element.val(c).trigger("change")},e.prototype.destroy=function(){this.$container.remove(),this.$element[0].detachEvent&&this.$element[0].detachEvent("onpropertychange",this._syncA),null!=this._observer?(this._observer.disconnect(),this._observer=null):this.$element[0].removeEventListener&&(this.$element[0].removeEventListener("DOMAttrModified",this._syncA,!1),this.$element[0].removeEventListener("DOMNodeInserted",this._syncS,!1),this.$element[0].removeEventListener("DOMNodeRemoved",this._syncS,!1)),this._syncA=null,this._syncS=null,this.$element.off(".select2"),this.$element.attr("tabindex",c.GetData(this.$element[0],"old-tabindex")),this.$element.removeClass("select2-hidden-accessible"),this.$element.attr("aria-hidden","false"),c.RemoveData(this.$element[0]),this.$element.removeData("select2"),this.dataAdapter.destroy(),this.selection.destroy(),this.dropdown.destroy(),this.results.destroy(),this.dataAdapter=null,this.selection=null,this.dropdown=null,this.results=null},e.prototype.render=function(){var b=a(' ');return b.attr("dir",this.options.get("dir")),this.$container=b,this.$container.addClass("select2-container--"+this.options.get("theme")),c.StoreData(b[0],"element",this.$element),b},e}),b.define("jquery-mousewheel",["jquery"],function(a){return a}),b.define("jquery.select2",["jquery","jquery-mousewheel","./select2/core","./select2/defaults","./select2/utils"],function(a,b,c,d,e){if(null==a.fn.select2){var f=["open","close","destroy"];a.fn.select2=function(b){if("object"==typeof(b=b||{}))return this.each(function(){var d=a.extend(!0,{},b);new c(a(this),d)}),this;if("string"==typeof b){var d,g=Array.prototype.slice.call(arguments,1);return this.each(function(){var a=e.GetData(this,"select2");null==a&&window.console&&console.error&&console.error("The select2('"+b+"') method was called on an element that is not using Select2."),d=a[b].apply(a,g)}),a.inArray(b,f)>-1?this:d}throw new Error("Invalid arguments for Select2: "+b)}}return null==a.fn.select2.defaults&&(a.fn.select2.defaults=d),c}),{define:b.define,require:b.require}}(),c=b.require("jquery.select2");return a.fn.select2.amd=b,c});
\ No newline at end of file
diff --git a/AdminPanel/client/src/pages/AiIntegration/ai/vendor/select2-4.0.6-rc.1/docs/README.md b/AdminPanel/client/src/pages/AiIntegration/ai/vendor/select2-4.0.6-rc.1/docs/README.md
new file mode 100644
index 0000000000..06d589d841
--- /dev/null
+++ b/AdminPanel/client/src/pages/AiIntegration/ai/vendor/select2-4.0.6-rc.1/docs/README.md
@@ -0,0 +1 @@
+Effective beginning September 10, 2017, the Select2 documentation repository is now available at [`select2/docs`](https://github.com/select2/docs).
diff --git a/AdminPanel/client/src/pages/AiIntegration/ai/vendor/select2-4.0.6-rc.1/docs/announcements-4.0.html b/AdminPanel/client/src/pages/AiIntegration/ai/vendor/select2-4.0.6-rc.1/docs/announcements-4.0.html
new file mode 100644
index 0000000000..bc85b4c181
--- /dev/null
+++ b/AdminPanel/client/src/pages/AiIntegration/ai/vendor/select2-4.0.6-rc.1/docs/announcements-4.0.html
@@ -0,0 +1,12 @@
+
+
+
+
+ select2
+
+
+
+
+
\ No newline at end of file
diff --git a/AdminPanel/client/src/pages/AiIntegration/ai/vendor/select2-4.0.6-rc.1/docs/community.html b/AdminPanel/client/src/pages/AiIntegration/ai/vendor/select2-4.0.6-rc.1/docs/community.html
new file mode 100644
index 0000000000..ffe8f83fd5
--- /dev/null
+++ b/AdminPanel/client/src/pages/AiIntegration/ai/vendor/select2-4.0.6-rc.1/docs/community.html
@@ -0,0 +1,12 @@
+
+
+
+
+ select2
+
+
+
+
+
\ No newline at end of file
diff --git a/AdminPanel/client/src/pages/AiIntegration/ai/vendor/select2-4.0.6-rc.1/docs/examples.html b/AdminPanel/client/src/pages/AiIntegration/ai/vendor/select2-4.0.6-rc.1/docs/examples.html
new file mode 100644
index 0000000000..a463e84aa9
--- /dev/null
+++ b/AdminPanel/client/src/pages/AiIntegration/ai/vendor/select2-4.0.6-rc.1/docs/examples.html
@@ -0,0 +1,12 @@
+
+
+
+
+ select2
+
+
+
+
+
\ No newline at end of file
diff --git a/AdminPanel/client/src/pages/AiIntegration/ai/vendor/select2-4.0.6-rc.1/docs/index.html b/AdminPanel/client/src/pages/AiIntegration/ai/vendor/select2-4.0.6-rc.1/docs/index.html
new file mode 100644
index 0000000000..ea8214d62c
--- /dev/null
+++ b/AdminPanel/client/src/pages/AiIntegration/ai/vendor/select2-4.0.6-rc.1/docs/index.html
@@ -0,0 +1,12 @@
+
+
+
+
+ select2
+
+
+
+
+
\ No newline at end of file
diff --git a/AdminPanel/client/src/pages/AiIntegration/ai/vendor/select2-4.0.6-rc.1/docs/options-old.html b/AdminPanel/client/src/pages/AiIntegration/ai/vendor/select2-4.0.6-rc.1/docs/options-old.html
new file mode 100644
index 0000000000..4920b76bcc
--- /dev/null
+++ b/AdminPanel/client/src/pages/AiIntegration/ai/vendor/select2-4.0.6-rc.1/docs/options-old.html
@@ -0,0 +1,12 @@
+
+
+
+
+ select2
+
+
+
+
+
\ No newline at end of file
diff --git a/AdminPanel/client/src/pages/AiIntegration/ai/vendor/select2-4.0.6-rc.1/docs/options.html b/AdminPanel/client/src/pages/AiIntegration/ai/vendor/select2-4.0.6-rc.1/docs/options.html
new file mode 100644
index 0000000000..4920b76bcc
--- /dev/null
+++ b/AdminPanel/client/src/pages/AiIntegration/ai/vendor/select2-4.0.6-rc.1/docs/options.html
@@ -0,0 +1,12 @@
+
+
+
+
+ select2
+
+
+
+
+
\ No newline at end of file
diff --git a/AdminPanel/client/src/pages/AiIntegration/css/ai-integration.css b/AdminPanel/client/src/pages/AiIntegration/css/ai-integration.css
new file mode 100644
index 0000000000..0e7b37a9e0
--- /dev/null
+++ b/AdminPanel/client/src/pages/AiIntegration/css/ai-integration.css
@@ -0,0 +1,146 @@
+/* AI Integration Styles */
+.ai-settings-section {
+ margin-top: 15px;
+ margin-bottom: 15px;
+}
+
+.ai-spoiler {
+ cursor: pointer;
+ padding: 12px 15px;
+ background: #f5f5f5;
+ border: 1px solid #efefef;
+ border-radius: 3px;
+ margin-top: 15px;
+ margin-bottom: 15px;
+ font-size: 14px;
+ font-weight: 600;
+ color: #333333;
+ user-select: none;
+ position: relative;
+}
+
+.ai-spoiler:hover {
+ background: #eeeeee;
+}
+
+.ai-spoiler::after {
+ content: '▼';
+ position: absolute;
+ right: 15px;
+ top: 50%;
+ transform: translateY(-50%);
+ transition: transform 0.3s ease;
+ color: #666666;
+}
+
+.ai-spoiler.collapsed::after {
+ transform: translateY(-50%) rotate(-90deg);
+}
+
+.ai-content {
+ display: block;
+ overflow: hidden;
+ transition: max-height 0.3s ease;
+ border: 1px solid #efefef;
+ border-top: none;
+ border-radius: 0 0 3px 3px;
+ background: white;
+}
+
+.ai-content.collapsed {
+ display: none;
+}
+
+.ai-iframe-container {
+ position: relative;
+ background: white;
+ height: 500px;
+}
+
+.ai-iframe {
+ width: 100%;
+ height: 500px;
+ border: none;
+ display: block;
+ position: absolute;
+ top: 0;
+ left: 0;
+}
+
+.ai-iframe.hidden {
+ display: none;
+}
+
+.ai-iframe-overlay {
+ position: absolute;
+ top: 0;
+ left: 0;
+ right: 0;
+ bottom: 0;
+ background: rgba(255, 255, 255, 0.9);
+ display: none;
+ align-items: center;
+ justify-content: center;
+ z-index: 10;
+}
+
+.ai-iframe-overlay.loading {
+ display: flex;
+}
+
+.ai-loading-text {
+ font-size: 14px;
+ color: #666666;
+}
+
+.ai-controls {
+ padding: 10px 15px;
+ background: #f9f9f9;
+ border-top: 1px solid #efefef;
+ text-align: right;
+}
+
+.ai-btn {
+ display: inline-block;
+ padding: 6px 12px;
+ margin-left: 8px;
+ border: 1px solid #cccccc;
+ border-radius: 2px;
+ background: white;
+ color: #333333;
+ font-size: 12px;
+ cursor: pointer;
+ text-decoration: none;
+ transition: all 0.2s ease;
+}
+
+.ai-btn:hover {
+ background: #f5f5f5;
+ border-color: #aaaaaa;
+}
+
+.ai-btn.primary {
+ background: #3d4a6b;
+ color: white;
+ border-color: #3d4a6b;
+}
+
+.ai-btn.primary:hover {
+ background: #2e3b54;
+ border-color: #2e3b54;
+}
+
+.ai-btn:disabled {
+ opacity: 0.6;
+ cursor: not-allowed;
+}
+
+.ai-btn:disabled:hover {
+ background: white;
+ border-color: #cccccc;
+}
+
+.ai-btn.primary:disabled:hover {
+ background: #3d4a6b;
+ border-color: #3d4a6b;
+}
diff --git a/AdminPanel/client/src/pages/AiIntegration/css/plugins.css b/AdminPanel/client/src/pages/AiIntegration/css/plugins.css
new file mode 100644
index 0000000000..23750ffc74
--- /dev/null
+++ b/AdminPanel/client/src/pages/AiIntegration/css/plugins.css
@@ -0,0 +1,667 @@
+body {
+ font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif;
+ font-size: 11px;
+}
+
+/* button */
+
+.btn-text-default {
+ background: #fff;
+ border: 1px solid #cfcfcf;
+ border-radius: 2px;
+ color: #444444;
+ font-size: 11px;
+ font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif;
+ height: 22px;
+ cursor: pointer;
+}
+
+.btn-text-default::-moz-focus-inner {
+ border: 0;
+ padding: 0;
+}
+
+.btn-text-default.submit {
+ font-weight: bold;
+ background-color: #d8dadc;
+ border: 1px solid transparent;
+}
+
+.btn-text-default.submit.primary {
+ color: #fff;
+ background-color: #7d858c;
+}
+
+.btn-text-default:focus {
+ outline: 0;
+ outline-offset: 0;
+}
+
+.btn-text-default:hover {
+ background-color: #d8dadc;
+}
+
+.btn-text-default.submit:hover {
+ background-color: #cbced1;
+}
+
+.btn-text-default.primary:hover {
+ background-color: #666d73 !important;
+ color: #fff;
+}
+
+.btn-text-default:active,
+.btn-text-default.active {
+ background-color: #7d858c !important;
+ color: white;
+ -webkit-box-shadow: none;
+ box-shadow: none;
+ border: 1px solid transparent;
+}
+
+.btn-text-default[disabled]:hover,
+.btn-text-default.disabled:hover,
+.btn-text-default[disabled]:active,
+.btn-text-default[disabled].active,
+.btn-text-default.disabled:active,
+.btn-text-default.disabled.active {
+ background-color: #fff !important;
+ color: #444444;
+ cursor: default;
+}
+
+.btn-text-default[disabled],
+.btn-text-default.disabled {
+ opacity: 0.65;
+}
+
+.btn-edit {
+ width: 13px;
+ height: 13px;
+ cursor: pointer;
+ background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAA0AAAANCAYAAABy6+R8AAAACXBIWXMAAAsTAAALEwEAmpwYAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAGZSURBVHgBfZI/y4FRGMavx7+SRQaTTQab74CVlBKL/FukDGQhEgsDNh/Apiw+gcXm70DJoEikKMUk7vec8/Yi75O7Tj2d+/4913Wuc6Tz+UyQqev1itvtBr1e/6+nkgP2+z0qlYr4DgaDsNls36HtdotisYhoNAqLxYJyuSz230HFO7DZbISC0+lEp9OBRqNBLpdDq9XCeDx+DfIz8TWZTIhZodFoRMvlknw+H8XjcdrtdrRarYgpU6/XE7MC4oMc4OB8Pie/30/ZbJba7TYlk0k6HA4CDIVCxNyQYrFYoNFoIJ1OQ5Ik5PN5WK1WpFIprNdr8H61WhVn5X2VisXg8XhoNpvRYDAgt9tNbICOxyOVSiVyuVzU7/epXq9TIBAQtrkzxeVygclkQrfbhd1uRzgcRq1Ww3A4FKparRbspyJRo9H4G4TD4RD06XQS3pkt8nq9NJ1OiSVGsVjsqfC3nvekVCrxeDxgMBgQiUTEa2g2m8hkMi8FuXtSq9VIJBK43+8iHB7GJ8BL4vY+N3U6HQqFAsxmM+TqB5Je/SVNoN18AAAAAElFTkSuQmCC');
+}
+
+/* div button */
+div.btn-text-default {
+ height: fit-content !important;
+ min-height: 20px;
+}
+
+/* input, textarea */
+
+.form-control {
+ border: 1px solid #cfcfcf;
+ border-radius: 2px;
+ box-sizing: border-box;
+ color: #444444;
+ font-size: 11px;
+ height: 22px;
+ padding: 1px 3px;
+ -webkit-box-shadow: none;
+ box-shadow: none;
+ -webkit-user-select: text;
+ -moz-user-select: text;
+ -ms-user-select: text;
+ user-select: text;
+}
+
+.form-control:focus {
+ border-color: #848484;
+ outline: 0;
+ -webkit-box-shadow: none;
+ box-shadow: none;
+}
+
+.form-control[readonly] {
+ background-color: #fff;
+ cursor: pointer;
+}
+
+.form-control[disabled] {
+ background-color: #fff;
+ cursor: default;
+ -webkit-user-select: none;
+ -moz-user-select: none;
+ -ms-user-select: none;
+ user-select: none;
+ opacity: 0.65;
+}
+
+textarea.form-control {
+ resize: none;
+}
+
+input[type='checkbox'].form-control {
+ height: auto;
+ margin: 0;
+}
+
+@supports (-webkit-appearance: none) or (-moz-appearance: none) {
+ input[type='checkbox'].form-control {
+ -webkit-appearance: none;
+ -moz-appearance: none;
+ width: 14px;
+ height: 14px;
+ background: #fff;
+ border: 1px solid #cfcfcf;
+ border-radius: 2px;
+ padding: 0;
+ position: relative;
+ margin: 0;
+ }
+
+ input[type='checkbox'].form-control:checked:after {
+ content: '';
+ position: absolute;
+ border: solid #444444;
+ border-width: 0 2px 2px 0;
+ transform: rotate(45deg);
+ width: 3px;
+ height: 7px;
+ left: 4px;
+ }
+
+ input[type='checkbox'].form-control:disabled {
+ opacity: 0.5;
+ }
+
+ input[type='radio'].form-control {
+ appearance: none;
+ -webkit-appearance: none;
+ border: 2px solid #fff;
+ border-radius: 100%;
+ box-shadow: 0 0 0 1px #cfcfcf;
+ height: 12px;
+ width: 12px;
+ accent-color: #444;
+ margin: 0 0 1px;
+ background-color: #fff;
+ }
+
+ input[type='radio'].form-control:checked {
+ background-color: #444;
+ }
+
+ input[type='radio'].form-control:disabled {
+ opacity: 0.5;
+ }
+}
+/* label */
+
+label.link {
+ border-bottom: 1px dotted #aaa;
+ cursor: pointer;
+}
+
+label.for-combo {
+ height: 22px;
+ padding-top: 4px;
+}
+
+label.header {
+ font-weight: bold;
+}
+
+/* comments */
+
+.user-comment-item {
+ padding: 5px 0;
+ width: 100%;
+}
+
+.user-comment-item .main-actions {
+ width: 100%;
+ display: flex;
+ padding-bottom: 8px;
+ font-size: 12px;
+}
+
+.user-comment-item .form-control.user-check {
+ margin-right: 5px;
+ flex-grow: 0;
+ flex-shrink: 0;
+}
+
+.user-comment-item .user-name {
+ overflow: hidden;
+ text-overflow: ellipsis;
+ white-space: nowrap;
+ font-weight: bold;
+ max-width: 40%;
+}
+
+.user-comment-item .user-message {
+ overflow: hidden;
+ text-overflow: ellipsis;
+ white-space: nowrap;
+ flex-grow: 1;
+ margin-left: 2px;
+}
+
+.user-comment-item .btn-edit {
+ width: 13px;
+ height: 13px;
+ margin-left: 5px;
+ flex-grow: 0;
+ flex-shrink: 0;
+ cursor: pointer;
+ background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAA0AAAANCAYAAABy6+R8AAAACXBIWXMAAAsTAAALEwEAmpwYAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAGZSURBVHgBfZI/y4FRGMavx7+SRQaTTQab74CVlBKL/FukDGQhEgsDNh/Apiw+gcXm70DJoEikKMUk7vec8/Yi75O7Tj2d+/4913Wuc6Tz+UyQqev1itvtBr1e/6+nkgP2+z0qlYr4DgaDsNls36HtdotisYhoNAqLxYJyuSz230HFO7DZbISC0+lEp9OBRqNBLpdDq9XCeDx+DfIz8TWZTIhZodFoRMvlknw+H8XjcdrtdrRarYgpU6/XE7MC4oMc4OB8Pie/30/ZbJba7TYlk0k6HA4CDIVCxNyQYrFYoNFoIJ1OQ5Ik5PN5WK1WpFIprNdr8H61WhVn5X2VisXg8XhoNpvRYDAgt9tNbICOxyOVSiVyuVzU7/epXq9TIBAQtrkzxeVygclkQrfbhd1uRzgcRq1Ww3A4FKparRbspyJRo9H4G4TD4RD06XQS3pkt8nq9NJ1OiSVGsVjsqfC3nvekVCrxeDxgMBgQiUTEa2g2m8hkMi8FuXtSq9VIJBK43+8iHB7GJ8BL4vY+N3U6HQqFAsxmM+TqB5Je/SVNoN18AAAAAElFTkSuQmCC');
+}
+
+.user-comment-item .reply-actions,
+.user-comment-item .comment-edit {
+ padding-left: 18px;
+ padding-bottom: 10px;
+}
+
+.user-comment-item .reply-view {
+ padding-left: 18px;
+}
+
+.user-comment-item .reply-view .comment-edit {
+ padding-left: 0;
+}
+
+.user-comment-item .msg-edit {
+ width: 100%;
+ height: 45px;
+ margin-bottom: 3px;
+}
+
+.user-comment-item .reply-accept {
+ margin-bottom: 7px;
+}
+
+.user-comment-item .reply-accept label,
+.user-comment-item .reply-accept .user-check {
+ vertical-align: middle;
+}
+
+/* common styles */
+
+.hidden {
+ display: none;
+}
+
+.separator.horizontal {
+ width: 100%;
+ height: 0;
+ border-left: none;
+ border-right: none;
+ border-top: 1px solid #cbcbcb;
+}
+
+.defaultlable {
+ color: #444444;
+ cursor: default;
+ font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif;
+ font-size: 11px;
+ font-weight: normal;
+ -webkit-user-select: none;
+ -moz-user-select: none;
+ -ms-user-select: none;
+ user-select: none;
+}
+
+.defaultcenterlable {
+ color: #444444;
+ cursor: default;
+ text-align: center;
+ font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif;
+ font-size: 11px;
+ font-style: normal;
+ font-weight: normal;
+ -webkit-user-select: none;
+ -moz-user-select: none;
+ -ms-user-select: none;
+ user-select: none;
+ margin: 0px;
+ padding: 0px;
+ width: 100%;
+}
+
+.aboutlable {
+ color: #444444;
+ cursor: default;
+ font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif;
+ font-size: 12px;
+ font-weight: normal;
+ -webkit-user-select: none;
+ -moz-user-select: none;
+ -ms-user-select: none;
+ user-select: none;
+}
+
+a.aboutlink {
+ color: #444444;
+ text-decoration: none;
+}
+
+a.aboutlink:hover {
+ text-decoration: underline;
+}
+a.aboutlink:active {
+ text-decoration: underline;
+}
+
+.noselect {
+ -khtml-user-select: none;
+ user-select: none;
+ -moz-user-select: none;
+ -webkit-user-select: none;
+}
+
+.select2-dropdown,
+.select2-container--default .select2-selection--single {
+ border: 1px solid #cfcfcf !important;
+}
+
+.select2-container--default.select2-container--open .select2-selection--single,
+.select2-container--default.select2-container--focus:not(.select2-container--disabled) .select2-selection--single {
+ border-color: #848484 !important;
+}
+
+.select2-container .select2-selection--single .select2-selection__rendered,
+.select2-results__options {
+ font-size: 11px !important;
+}
+
+.select2-container--default .select2-selection--single .select2-selection__rendered {
+ line-height: 20px !important;
+}
+
+.select2-container--default .select2-results__option[aria-selected='true'] {
+ color: #ffffff;
+}
+
+.select2-container--default .select2-selection--single .select2-selection__arrow b {
+ width: 4px !important;
+ height: 4px !important;
+ margin: -1px 1px !important;
+ border: solid 1px #444 !important;
+ border-bottom: none !important;
+ border-right: none !important;
+ background-image: none;
+ box-sizing: border-box;
+
+ transition: transform 0.2s ease;
+ transform: rotate(-135deg) translate(1px, 1px);
+}
+.select2-container--default .select2-search .select2-selection__arrow b {
+ width: 4px !important;
+ height: 4px !important;
+ margin: -1px 1px !important;
+ border: solid 1px #404040 !important;
+ border-bottom: none !important;
+ border-right: none !important;
+ background-image: none;
+ box-sizing: border-box;
+ transition: transform 0.2s ease;
+ transform: rotate(-135deg) translate(1px, 1px);
+ left: 50%;
+ position: absolute;
+ top: 50%;
+}
+.select2-search--dropdown {
+ padding: 0px !important;
+}
+
+.select2-container--default.select2-container--open .select2-selection__arrow b {
+ transform: rotate(45deg);
+}
+
+.select2-container--default .select2-search--dropdown .select2-search__field {
+ outline: none;
+ border-color: #cfcfcf;
+ border-radius: 2px;
+ font-size: 11px;
+}
+.select2-search.select2-search--dropdown .select2-selection__arrow {
+ height: 20px;
+ position: absolute;
+ top: 1px;
+ right: 1px;
+ width: 20px;
+}
+.select2-container--default .select2-results__option--highlighted[aria-selected] {
+ background-color: #d8dadc !important;
+}
+
+.select2-container--default .select2-results__option--highlighted[aria-selected='true'] {
+ background-color: #7d858c !important;
+}
+.select2-search.select2-search--dropdown .select2-selection__arrow {
+ cursor: pointer !important;
+}
+.select2-container {
+ max-height: 20px !important;
+}
+.select2-container--default.select2-container--disabled {
+ opacity: 0.65 !important;
+}
+/*
+ * Container style
+ */
+.ps {
+ overflow: hidden !important;
+ overflow-anchor: none;
+ -ms-overflow-style: none;
+ touch-action: auto;
+ -ms-touch-action: auto;
+}
+
+/*
+ * Scrollbar rail styles
+ */
+.ps__rail-x {
+ display: none;
+ bottom: 2px; /* there must be 'right' for ps-scrollbar-y-rail */
+ height: 9px;
+ margin: 0 2px 0 2px;
+ /* please don't change 'position' */
+ position: absolute;
+ -webkit-border-radius: 2px;
+ -moz-border-radius: 2px;
+ border-radius: 2px;
+ transition:
+ background-color 0.2s linear,
+ opacity 0.2s linear;
+}
+
+.ps__rail-y {
+ display: none;
+ right: 2px; /* there must be 'right' for ps-scrollbar-y-rail */
+ width: 9px;
+ margin: 2px 0 2px 0;
+ /* please don't change 'position' */
+ position: absolute;
+ -webkit-border-radius: 2px;
+ -moz-border-radius: 2px;
+ border-radius: 2px;
+ transition:
+ background-color 0.2s linear,
+ opacity 0.2s linear;
+}
+
+.ps--active-x > .ps__rail-x,
+.ps--active-y > .ps__rail-y {
+ display: block;
+ background-color: transparent;
+}
+
+.ps .ps__rail-x:hover,
+.ps .ps__rail-y:hover,
+.ps .ps__rail-x:focus,
+.ps .ps__rail-y:focus,
+.ps .ps__rail-x.ps--clicking,
+.ps .ps__rail-y.ps--clicking {
+ background-color: #eeeeee;
+}
+
+/*
+ * Scrollbar thumb styles
+ */
+.ps__thumb-x {
+ position: absolute; /* please don't change 'position' */
+ bottom: 0; /* there must be 'bottom' for ps-scrollbar-x */
+ height: 9px;
+ background-color: rgb(241, 241, 241);
+ -webkit-border-radius: 2px;
+ -moz-border-radius: 2px;
+ border-radius: 2px;
+ visibility: visible;
+ display: block;
+ box-sizing: border-box;
+ background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAA0AAAAOCAYAAAD0f5bSAAAACXBIWXMAAB2HAAAdhwGP5fFlAAAALElEQVQokWNgoBs4f/78f1JpJnIsIkvTsAQfP378TypNxyD/+PEjyRrJsgkAKS81km7nDNQAAAAASUVORK5CYII=);
+ image-rendering: pixelated;
+ background-repeat: no-repeat;
+ background-position: center 0;
+ border: 1px solid #cfcfcf;
+}
+
+.ps__thumb-y {
+ position: absolute; /* please don't change 'position' */
+ right: 0; /* there must be 'right' for ps-scrollbar-y */
+ width: 9px;
+ background-color: rgb(241, 241, 241);
+ -webkit-border-radius: 2px;
+ -moz-border-radius: 2px;
+ border-radius: 2px;
+ visibility: visible;
+ display: block;
+ box-sizing: border-box;
+ background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAA4AAAANCAQAAAAz1Zf0AAAAIUlEQVR42mNgAILz/0GQAQo+/gdBBqLAqE5ydH5k+sgEANHgUH2JtDRHAAAAAElFTkSuQmCC);
+ image-rendering: pixelated;
+ background-repeat: no-repeat;
+ background-position: 0 center;
+ border: 1px solid #cfcfcf;
+}
+
+.ps__rail-x:hover > .ps__thumb-x {
+ background-color: rgb(207, 207, 207);
+}
+.ps__thumb-x:hover {
+ background-position: center -7px;
+}
+.ps__rail-x:focus > .ps__thumb-x,
+.ps__rail-x.ps--clicking .ps__thumb-x {
+ background-color: #adadad;
+ border-color: #adadad;
+ background-position: center -7px;
+}
+
+.ps__rail-y:hover > .ps__thumb-y {
+ background-color: rgb(207, 207, 207);
+}
+.ps__thumb-y:hover {
+ background-position: -7px center;
+}
+.ps__rail-y:focus > .ps__thumb-y,
+.ps__rail-y.ps--clicking .ps__thumb-y {
+ background-color: #adadad;
+ border-color: #adadad;
+ background-position: -7px center;
+}
+
+/* MS supports */
+@supports (-ms-overflow-style: none) {
+ .ps {
+ overflow: auto !important;
+ }
+}
+
+@media screen and (-ms-high-contrast: active), (-ms-high-contrast: none) {
+ .ps {
+ overflow: auto !important;
+ }
+}
+
+/* loader */
+@keyframes rotation {
+ from {
+ transform: rotate(0deg);
+ }
+
+ to {
+ transform: rotate(360deg);
+ }
+}
+.asc-loader-container {
+ position: relative;
+}
+.asc-plugin-loader {
+ position: absolute;
+ left: 50%;
+ top: 50%;
+ margin-top: -10px;
+ z-index: 10000;
+ line-height: 20px;
+ background-image: none;
+ background-color: transparent;
+ color: #444444;
+ transform: translate(-50%, 0);
+}
+.asc-plugin-loader .asc-loader-image {
+ height: 20px;
+ width: 20px;
+ float: left;
+ margin-top: -1px;
+
+ animation-duration: 0.8s;
+ animation-name: rotation;
+ animation-iteration-count: infinite;
+ animation-timing-function: linear;
+}
+.asc-loader-image-light {
+ background-image: url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyOCAyOCI+PGNpcmNsZSBjeD0iMTQiIGN5PSIxNCIgZmlsbD0ibm9uZSIgc3Ryb2tlPSIjZmZmIiBzdHJva2Utd2lkdGg9IjEuNSIgcj0iMTAuMjUiIHN0cm9rZS1kYXNoYXJyYXk9IjE2MCUsIDQwJSIgLz48L3N2Zz4=);
+}
+.asc-loader-image-dark {
+ background-image: url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyMCAyMCI+PGNpcmNsZSBjeD0iMTAiIGN5PSIxMCIgZmlsbD0ibm9uZSIgc3Ryb2tlPSIjNDQ0IiBzdHJva2Utd2lkdGg9IjEuNSIgcj0iNy4yNSIgc3Ryb2tlLWRhc2hhcnJheT0iMTYwJSwgNDAlIiAvPjwvc3ZnPg==);
+}
+
+.asc-plugin-loader .asc-loader-title {
+ font-size: 13px;
+ padding-left: 25px;
+ min-width: 100px;
+}
+
+/* default scroll */
+
+/* * {
+ scrollbar-width: thin;
+} */
+
+*::-webkit-scrollbar {
+ width: 9px;
+ height: 9px;
+}
+
+*::-webkit-scrollbar-thumb {
+ border-radius: 2px;
+ border: 1px solid;
+ image-rendering: pixelated;
+ background-repeat: no-repeat;
+ cursor: default;
+}
+
+*::-webkit-scrollbar-track {
+ cursor: default;
+}
+
+*::-webkit-scrollbar-thumb:vertical {
+ background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAA4AAAANCAQAAAAz1Zf0AAAAIUlEQVR42mNgAILz/0GQAQo+/gdBBqLAqE5ydH5k+sgEANHgUH2JtDRHAAAAAElFTkSuQmCC);
+ background-position: 0px center;
+}
+
+*::-webkit-scrollbar-thumb:horizontal {
+ background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAA0AAAAOCAYAAAD0f5bSAAAACXBIWXMAAB2HAAAdhwGP5fFlAAAALElEQVQokWNgoBs4f/78f1JpJnIsIkvTsAQfP378TypNxyD/+PEjyRrJsgkAKS81km7nDNQAAAAASUVORK5CYII=);
+ background-position: center 0px;
+}
+
+*::-webkit-scrollbar-thumb:vertical:hover {
+ background-position: -7px center;
+}
+*::-webkit-scrollbar-thumb:horizontal:hover {
+ background-position: center -7px;
+}
diff --git a/AdminPanel/client/src/pages/AiIntegration/hooks/useAiPlugin.js b/AdminPanel/client/src/pages/AiIntegration/hooks/useAiPlugin.js
new file mode 100644
index 0000000000..0378732427
--- /dev/null
+++ b/AdminPanel/client/src/pages/AiIntegration/hooks/useAiPlugin.js
@@ -0,0 +1,160 @@
+import {useState, useEffect, useCallback} from 'react';
+import {useSelector, useDispatch} from 'react-redux';
+import {selectConfig, saveConfig} from '../../../store/slices/configSlice';
+import {
+ registerShowWindowCallback,
+ registerCloseWindowCallback,
+ registerSaveCallback,
+ registerLoadInternalProvidersCallback,
+ initAISettings
+} from '../js/plugins-sdk';
+
+/**
+ * Custom hook for managing complete AI plugin functionality
+ * Combines plugin windows, settings initialization, and localStorage synchronization
+ * @param {Object} statisticsData - Statistics data containing server info
+ * @returns {Object} Plugin windows state and handlers
+ */
+const useAiPlugin = statisticsData => {
+ const [pluginWindows, setPluginWindows] = useState([]);
+ const [internalProvidersLoaded, setInternalProvidersLoaded] = useState(false);
+ const dispatch = useDispatch();
+ const config = useSelector(selectConfig);
+
+ /**
+ * Initialize AI settings after iframe loads
+ * @param {string} iframeId - The AI iframe ID
+ */
+ const handleIframeLoad = useCallback(
+ (iframeId = 'ai-iframe') => {
+ // Get version information from statistics data
+ let sdkVersion = 'develop'; // Default for development
+
+ if (statisticsData?.serverInfo) {
+ const {buildVersion} = statisticsData.serverInfo;
+ sdkVersion = buildVersion;
+ }
+
+ initAISettings(iframeId, sdkVersion);
+ },
+ [statisticsData]
+ );
+
+ // Synchronize AI config with localStorage
+ useEffect(() => {
+ // Load AI config from Redux state to localStorage when component mounts/config changes
+ localStorage.removeItem('onlyoffice_ai_actions_key');
+ localStorage.removeItem('onlyoffice_ai_plugin_storage_key');
+ if (config?.aiSettings?.actions) {
+ localStorage.setItem('onlyoffice_ai_actions_key', JSON.stringify(config.aiSettings.actions));
+ }
+ if (config?.aiSettings) {
+ const {actions: _actions, timeout: _timeout, allowedCorsOrigins: _allowedCorsOrigins, proxy: _proxy, ...storage_key} = config.aiSettings;
+ localStorage.setItem('onlyoffice_ai_plugin_storage_key', JSON.stringify(storage_key));
+ }
+ // Cleanup: clear localStorage when component unmounts
+ return () => {
+ localStorage.removeItem('onlyoffice_ai_actions_key');
+ localStorage.removeItem('onlyoffice_ai_plugin_storage_key');
+ };
+ }, [config?.aiSettings]);
+
+ // Manage plugin windows and register all SDK callbacks
+ useEffect(() => {
+ /**
+ * Handle showing a plugin window
+ * @param {string} iframeId - The iframe ID
+ * @param {Object} config - Window configuration
+ */
+ const handleShowWindow = (iframeId, config) => {
+ setPluginWindows(current => {
+ // Avoid duplicate windows with same iframeId
+ const filtered = current.filter(w => w.iframeId !== iframeId);
+ return [...filtered, {iframeId, ...config}];
+ });
+ };
+
+ /**
+ * Handle closing a plugin window
+ * @param {string} id - Window ID to close
+ */
+ const handleCloseWindow = id => {
+ setPluginWindows(current => current.filter(w => w.iframeId !== id));
+ };
+
+ /**
+ * Handle saving AI configuration from localStorage to Redux store
+ */
+ const handleSave = () => {
+ try {
+ // Read AI configuration from localStorage
+ const aiActionsKey = localStorage.getItem('onlyoffice_ai_actions_key');
+ const aiPluginStorageKey = localStorage.getItem('onlyoffice_ai_plugin_storage_key');
+
+ // Prepare updated AI settings
+ const updatedAiSettings = {...config?.aiSettings};
+
+ // Update actions if available
+ if (aiActionsKey) {
+ try {
+ const aiActions = JSON.parse(aiActionsKey);
+ updatedAiSettings.actions = aiActions;
+ } catch (error) {
+ console.error('Error parsing AI actions:', error);
+ }
+ }
+
+ // Update plugin storage settings if available
+ if (aiPluginStorageKey) {
+ try {
+ const pluginStorage = JSON.parse(aiPluginStorageKey);
+ Object.assign(updatedAiSettings, pluginStorage);
+ } catch (error) {
+ console.error('Error parsing AI plugin storage:', error);
+ }
+ }
+
+ if (aiActionsKey || aiPluginStorageKey) {
+ // Create config object with updated AI settings
+ const configToSave = {
+ aiSettings: updatedAiSettings
+ };
+
+ // Save configuration using Redux action
+ dispatch(saveConfig(configToSave));
+ }
+ } catch (error) {
+ console.error('Error saving AI configuration:', error);
+ }
+ };
+
+ const handleLoadInternalProviders = () => {
+ setInternalProvidersLoaded(true);
+ };
+
+ // Register all callbacks with SDK
+ registerShowWindowCallback(handleShowWindow);
+ registerCloseWindowCallback(handleCloseWindow);
+ registerSaveCallback(handleSave);
+ registerLoadInternalProvidersCallback(handleLoadInternalProviders);
+
+ // Cleanup: unregister all callbacks
+ return () => {
+ registerShowWindowCallback(null);
+ registerCloseWindowCallback(null);
+ registerSaveCallback(null);
+ registerLoadInternalProvidersCallback(null);
+ };
+ }, [config, dispatch]);
+
+ const currentWindow = pluginWindows.length > 0 ? pluginWindows[pluginWindows.length - 1] : null;
+
+ return {
+ pluginWindows,
+ currentWindow,
+ handleIframeLoad,
+ internalProvidersLoaded
+ };
+};
+
+export default useAiPlugin;
diff --git a/AdminPanel/client/src/pages/AiIntegration/index.js b/AdminPanel/client/src/pages/AiIntegration/index.js
new file mode 100644
index 0000000000..931bb89c0c
--- /dev/null
+++ b/AdminPanel/client/src/pages/AiIntegration/index.js
@@ -0,0 +1,71 @@
+import {useQuery} from '@tanstack/react-query';
+import {useSelector} from 'react-redux';
+import {selectConfig} from '../../store/slices/configSlice';
+import PageHeader from '../../components/PageHeader/PageHeader';
+import FixedSaveButtonGroup from '../../components/FixedSaveButtonGroup/FixedSaveButtonGroup';
+import {fetchStatistics} from '../../api';
+import useAiPlugin from './hooks/useAiPlugin';
+
+/**
+ * AiIntegration page.
+ * Embeds the AI settings UI and brokers config get/save between the iframe and Redux/API.
+ * @returns {JSX.Element}
+ */
+export default function AiIntegration() {
+ const config = useSelector(selectConfig);
+
+ // Fetch statistics data to get version information
+ // Query depends on config availability since it's a synchronous operation
+ const {data, isLoading, error} = useQuery({
+ queryKey: ['statistics', config?.version], // Include config in query key
+ queryFn: fetchStatistics,
+ enabled: !!config // Only fetch when config is available
+ });
+
+ // Use custom hook for complete AI plugin functionality
+ const {currentWindow, handleIframeLoad, internalProvidersLoaded} = useAiPlugin(data);
+
+ // Constants
+ const AI_IFRAME_SRC = `ai/index.html`;
+ const AI_IFRAME_ID = 'ai-iframe';
+
+ /** @type {import('react').CSSProperties} */
+ const iframeStyle = {
+ width: '100%',
+ height: '100%',
+ minHeight: '700px',
+ border: 0,
+ display: 'none'
+ };
+
+ /** @type {import('react').CSSProperties} */
+ const pluginWindowStyle = {
+ maxWidth: '400px',
+ maxHeight: '500px',
+ width: '100%',
+ height: '100%',
+ border: 0
+ };
+
+ // After hooks and memos: show loading/error states
+ if (error) {
+ return Error: {error.message}
;
+ }
+ if (isLoading || !data) {
+ return Please, wait...
;
+ }
+
+ return (
+
+ );
+}
diff --git a/AdminPanel/client/src/pages/AiIntegration/js/plugins-sdk.js b/AdminPanel/client/src/pages/AiIntegration/js/plugins-sdk.js
new file mode 100644
index 0000000000..2c827888f6
--- /dev/null
+++ b/AdminPanel/client/src/pages/AiIntegration/js/plugins-sdk.js
@@ -0,0 +1,560 @@
+'use strict';
+
+const pluginGuid = 'asc.{9DC93CDB-B576-4F0C-B55E-FCC9C48DD007}';
+let iframeMain = '';
+let sdkVersion = 'develop'; // Dynamic version, defaults to 'develop'
+const mainButtonId = 'settings.html';
+
+// Plugin window management callbacks
+let showPluginWindowCallback = null;
+let closePluginWindowCallback = null;
+let saveCallback = null;
+let loadInternalProvidersCallback = null;
+
+let settingsButton = null;
+
+/**
+ * Sends a message to an iframe
+ * @param {string} iframeId - The iframe element ID
+ * @param {Object} data - The data to send
+ */
+function sendMessageToFrame(iframeId, data) {
+ const frame = document.getElementById(iframeId);
+ if (frame) {
+ frame.contentWindow.postMessage(JSON.stringify(data), '*');
+ }
+}
+
+/**
+ * Handles incoming messages from iframes
+ * @param {MessageEvent} event - The message event
+ */
+function receiveMessage(event) {
+ if (typeof event.data !== 'string') {
+ return;
+ }
+
+ try {
+ const data = JSON.parse(event.data);
+ if (data.type === 'initialize') {
+ initialize(data);
+ } else if (data.type === 'initialize_internal') {
+ initialize_internal(data);
+ } else if (data.type === 'method') {
+ handleMethod(data);
+ } else if (data.type === 'messageToPlugin') {
+ sendMessageToPlugin(data);
+ }
+ } catch (error) {
+ console.error('Failed to parse message data:', error);
+ }
+}
+
+/**
+ * Initializes the plugin with the main iframe
+ * @param {Object} data - Initialization data containing windowID
+ */
+function initialize(data) {
+ const iframeId = data.windowID || iframeMain;
+ const msg = {
+ guid: pluginGuid,
+ type: 'plugin_init',
+ data: /**/ '(function(a,n){var f=[1,1.25,1.5,1.75,2,2.25,2.5,2.75,3,3.5,4,4.5,5];a.AscDesktopEditor&&a.AscDesktopEditor.GetSupportedScaleValues&&(f=a.AscDesktopEditor.GetSupportedScaleValues());var h=function(){if(0===f.length)return!1;var c=navigator.userAgent.toLowerCase(),e=-1e-1E-4);g++)k=Math.abs(f[g]-e),kMath.abs(c.zoom-b)||(b=c.zoom,document.firstElementChild.style.zoom=.001>Math.abs(b-1)?"normal":1/b)}})(window);(function(a,n){function f(b){this.plugin=b;this.ps;this.items=[];this.isCurrentVisible=this.isVisible=!1}function h(){this.id=a.Asc.generateGuid();this.id=this.id.replace(/-/g,"");this._events={};this._register()}f.prototype.createWindow=function(){var b=document.body,c=document.getElementsByTagName("head")[0];b&&c&&(b=document.createElement("style"),b.type="text/css",b.innerHTML=\'.ih_main { margin: 0px; padding: 0px; width: 100%; height: 100%; display: inline-block; overflow: hidden; box-sizing: border-box; user-select: none; position: fixed; border: 1px solid #cfcfcf; } ul { margin: 0px; padding: 0px; width: 100%; height: 100%; list-style-type: none; outline:none; } li { padding: 5px; font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; font-size: 12px; font-weight: 400; color: #373737; } li:hover { background-color: #D8DADC; } .li_selected { background-color: #D8DADC; color: #373737; }.li_selected:hover { background-color: #D8DADC; color: #373737; }\',c.appendChild(b),document.body.style.background="#FFFFFF",document.body.style.width="100%",document.body.style.height="100%",document.body.style.margin="0",document.body.style.padding="0",document.body.innerHTML=\'\',this.ps=new PerfectScrollbar(document.getElementById("ih_area"),{minScrollbarLength:20}),this.updateScrolls(),this.createDefaultEvents())};f.prototype.setItems=function(b){this.items=b;for(var c="",e=b.length,d=0;d\',c+=b[d].text,c+="";document.getElementById("ih_elements_id").innerHTML=c;this.updateScrolls();this.scrollToSelected()};f.prototype.createDefaultEvents=function(){this.plugin.onExternalMouseUp=function(){var c=document.createEvent("MouseEvents");c.initMouseEvent("mouseup",!0,!0,a,1,0,0,0,0,!1,!1,!1,!1,0,null);document.dispatchEvent(c)};var b=this;a.onkeydown=function(c){switch(c.keyCode){case 27:b.isVisible&&(b.isVisible=!1,b.plugin.executeMethod("UnShowInputHelper",[b.plugin.info.guid,!0]));break;case 38:case 40:case 9:case 36:case 35:case 33:case 34:for(var e=document.getElementsByTagName("li"),d=-1,l=0;ld&&(d=0);break;case 40:d++;d>=e.length&&(d=e.length-1);break;case 9:d++;d>=e.length&&(d=0);break;case 36:d=0;break;case 35:d=e.length-1;break;case 33:case 34:l=1;var k=document.getElementById("ih_area").clientHeight/24>>0;1d&&(d=0)):(d+=l,d>=e.length&&(d=d=e.length-1))}d .ps__thumb-y":{"border-color":"canvas-scroll-thumb-hover","background-color":"canvas-scroll-thumb-hover !important"},".ps .ps__rail-x:hover":{"background-color":"background-toolbar"},".ps .ps__rail-x.ps--clicking":{"background-color":"background-toolbar"},".ps__thumb-x":{"background-color":"background-normal","border-color":"Border !important"},".ps__rail-x:hover > .ps__thumb-x":{"border-color":"canvas-scroll-thumb-hover"},a:{color:"text-link !important"},"a:hover":{color:"text-link-hover !important"},"a:active":{color:"text-link-active !important"},"a:visited":{color:"text-link-visited !important"},"*::-webkit-scrollbar-track":{background:"background-normal"},"*::-webkit-scrollbar-track:hover":{background:"background-toolbar-additional"},"*::-webkit-scrollbar-thumb":{"background-color":"background-toolbar","border-color":"border-regular-control"},"*::-webkit-scrollbar-thumb:hover":{"background-color":"canvas-scroll-thumb-hover"},".asc-plugin-loader":{color:"text-normal"}},e=!1,d="";a.plugin_sendMessage=function(k){a.Asc.plugin.ie_channel?a.Asc.plugin.ie_channel.postMessage(k):a.parent.postMessage(k,"*")};a.plugin_onMessage=function(k){if(a.Asc.plugin&&"string"==typeof k.data){var g={};try{g=JSON.parse(k.data)}catch(m){g={}}k=g.type;if(g.guid!=a.Asc.plugin.guid){if(n!==g.guid)return;switch(k){case "onExternalPluginMessage":break;default:return}}"init"===k&&(a.Asc.plugin.info=g);"updateOptions"===k&&g.options&&(a.Asc.plugin.info.options=g.options);if(n!==g.theme&&(!a.Asc.plugin.theme||"onThemeChanged"===k))if(a.Asc.plugin.theme=g.theme,a.Asc.plugin.onThemeChangedBase||(a.Asc.plugin.onThemeChangedBase=function(m){var q="",t;for(t in c){q+=t+" {";var w=c[t],r;for(r in w){var u=w[r],y=u.indexOf(" !important");-1*/
+ };
+ sendMessageToFrame(iframeId, msg);
+}
+/**
+ * Initializes internal plugin settings with mock editor data
+ * @param {Object} data - Initialization data containing windowID
+ */
+function initialize_internal(data) {
+ const iframeId = data.windowID || iframeMain;
+ const msg = {
+ guid: pluginGuid,
+ editorType: 'word',
+ mmToPx: 3.7795275590551185,
+ restrictions: 0,
+ data: '',
+ isViewMode: false,
+ isMobileMode: false,
+ isEmbedMode: false,
+ lang: 'en-EN',
+ documentId: 'documentId',
+ documentTitle: 'documentTitle',
+ documentCallbackUrl: '',
+ userId: 'userId',
+ userName: 'userName',
+ jwt: '',
+ theme: {
+ Name: 'theme-white',
+ Type: 'light',
+ RulersButton: false,
+ NavigationButtons: false,
+ BackgroundColor: '#f3f3f3',
+ PageOutline: '#cccccc',
+ RulerDark: '#d9d9d9',
+ RulerLight: '#ffffff',
+ RulerOutline: '#cbcbcb',
+ RulerMarkersOutlineColor: '#555555',
+ RulerMarkersOutlineColorOld: '#aaaaaa',
+ RulerMarkersFillColor: '#ffffff',
+ RulerMarkersFillColorOld: '#ffffff',
+ RulerTextColor: '#555555',
+ RulerTabsColor: '#000000',
+ RulerTabsColorOld: '#666666',
+ RulerTableColor1: '#ffffff',
+ RulerTableColor2: '#555555',
+ ScrollBackgroundColor: '#f3f3f3',
+ ScrollOutlineColor: '#cbcbcb',
+ ScrollOutlineHoverColor: '#cbcbcb',
+ ScrollOutlineActiveColor: '#adadad',
+ ScrollerColor: '#f7f7f7',
+ ScrollerHoverColor: '#c0c0c0',
+ ScrollerActiveColor: '#adadad',
+ ScrollArrowColor: '#adadad',
+ ScrollArrowHoverColor: '#f7f7f7',
+ ScrollArrowActiveColor: '#f7f7f7',
+ ScrollerTargetColor: '#c0c0c0',
+ ScrollerTargetHoverColor: '#f7f7f7',
+ ScrollerTargetActiveColor: '#f7f7f7',
+ STYLE_THUMBNAIL_WIDTH: 104,
+ STYLE_THUMBNAIL_HEIGHT: 40,
+ isNeedInvertOnActive: false,
+ ContentControlsBack: '#F1F1F1',
+ ContentControlsHover: '#D8DADC',
+ ContentControlsActive: '#7C838A',
+ ContentControlsText: '#444444',
+ ContentControlsTextActive: '#FFFFFF',
+ ContentControlsAnchorActive: '#CFCFCF',
+ FormsContentControlsOutlineHover: 'rgba(0, 0, 0, 0.3)',
+ FormsContentControlsOutlineActive: 'rgba(0, 0, 0, 0.3)',
+ FormsContentControlsOutlineBorderRadiusHover: 0,
+ FormsContentControlsOutlineBorderRadiusActive: 2,
+ FormsContentControlsMarkersBackground: '#FFFFFF',
+ FormsContentControlsMarkersBackgroundHover: '#E1E1E1',
+ FormsContentControlsMarkersBackgroundActive: '#CCCCCC',
+ FormsContentControlsOutlineMoverHover: '#444444',
+ FormsContentControlsOutlineMoverActive: '#444444',
+ BackgroundColorThumbnails: '#FFFFFF',
+ BackgroundColorThumbnailsActive: '#FFFFFF',
+ BackgroundColorThumbnailsHover: '#FFFFFF',
+ ThumbnailsPageOutlineActive: '#4A87E7',
+ ThumbnailsPageOutlineHover: '#92B7F0',
+ ThumbnailsPageNumberText: '#000000',
+ ThumbnailsPageNumberTextActive: '#000000',
+ ThumbnailsPageNumberTextHover: '#000000',
+ ThumbnailsLockColor: '#D34F4F',
+ BackgroundColorNotes: '#f3f3f3',
+ THEMES_THUMBNAIL_WIDTH: 88,
+ THEMES_THUMBNAIL_HEIGHT: 40,
+ THEMES_LAYOUT_THUMBNAIL_HEIGHT: 68,
+ BorderSplitterColor: '#cbcbcb',
+ SupportNotes: true,
+ SplitterWidthMM: 1,
+ ThumbnailScrollWidthNullIfNoScrolling: false,
+ AnimPaneBackground: '#f7f7f7',
+ AnimPaneItemFillSelected: '#cbcbcb',
+ AnimPaneItemFillHovered: '#e0e0e0',
+ AnimPaneButtonFill: '#e0e0e0',
+ AnimPaneButtonFillHovered: '#e0e0e0',
+ AnimPaneButtonFillDisabled: '#e0e0e0',
+ AnimPanePlayButtonFill: '#ffffff',
+ AnimPanePlayButtonOutline: '#c0c0c0',
+ AnimPaneEffectBarFillEntrance: '#77b583',
+ AnimPaneEffectBarOutlineEntrance: '#0e8a26',
+ AnimPaneEffectBarFillEmphasis: '#fbc37c',
+ AnimPaneEffectBarOutlineEmphasis: '#ff8e00',
+ AnimPaneEffectBarFillExit: '#f59a9a',
+ AnimPaneEffectBarOutlineExit: '#f23d3d',
+ AnimPaneEffectBarFillPath: '#a1cee3',
+ AnimPaneEffectBarOutlinePath: '#254662',
+ AnimPaneTimelineRulerOutline: '#cbcbcb',
+ AnimPaneTimelineRulerTick: '#cbcbcb',
+ AnimPaneTimelineScrollerFill: '#cbcbcb',
+ AnimPaneTimelineScrollerOutline: '#444444',
+ AnimPaneTimelineScrollerOpacity: 0,
+ AnimPaneTimelineScrollerOpacityHovered: 0.4,
+ AnimPaneTimelineScrollerOpacityActive: 1,
+ AnimPaneText: '#000000',
+ AnimPaneTextActive: '#000000',
+ AnimPaneTextHover: '#000000',
+ DemBackgroundColor: '#FFFFFF',
+ DemButtonBackgroundColor: '#ffffff',
+ DemButtonBackgroundColorHover: '#EAEAEA',
+ DemButtonBackgroundColorActive: '#E1E1E1',
+ DemButtonBorderColor: '#E1E1E1',
+ DemButtonTextColor: '#000000',
+ DemButtonTextColorActive: '#000000',
+ DemSplitterColor: '#EAEAEA',
+ DemTextColor: '#000000',
+ Background: '#f7f7f7',
+ BackgroundActive: '#cfcfcf',
+ BackgroundHighlighted: '#dfdfdf',
+ Border: '#d8d8d8',
+ BorderActive: '#bbbbbb',
+ BorderHighlighted: '#c9c9c9',
+ Color: '#444444',
+ ColorActive: '#444444',
+ ColorHighlighted: '#444444',
+ ColorFiltering: '#008636',
+ SheetViewCellBackground: '#73bf91',
+ SheetViewCellBackgroundPressed: '#aaffcc',
+ SheetViewCellBackgroundHover: '#97e3b6',
+ SheetViewCellTitleLabel: '#121212',
+ ColorDark: '#ffffff',
+ ColorDarkActive: '#ffffff',
+ ColorDarkHighlighted: '#c1c1c1',
+ ColorDarkFiltering: '#7AFFAF',
+ GroupDataBorder: '#000000',
+ EditorBorder: '#cbcbcb',
+ SelectAllIcon: '#999999',
+ SheetViewSelectAllIcon: '#3D664E',
+ 'toolbar-header-document': '#f3f3f3',
+ 'toolbar-header-spreadsheet': '#f3f3f3',
+ 'toolbar-header-presentation': '#f3f3f3',
+ 'toolbar-header-pdf': '#f3f3f3',
+ 'toolbar-header-visio': '#f3f3f3',
+ 'text-toolbar-header-on-background-document': '#FFFFFF',
+ 'text-toolbar-header-on-background-spreadsheet': '#FFFFFF',
+ 'text-toolbar-header-on-background-presentation': '#FFFFFF',
+ 'text-toolbar-header-on-background-pdf': '#FFFFFF',
+ 'text-toolbar-header-on-background-visio': '#FFFFFF',
+ 'background-normal': '#fff',
+ 'background-toolbar': '#FFFFFF',
+ 'background-toolbar-additional': '#efefef',
+ 'background-primary-dialog-button': '#4A87E7',
+ 'background-notification-popover': '#fcfed7',
+ 'background-notification-badge': '#ffd112',
+ 'background-scrim': 'rgba(0, 0, 0, 0.2)',
+ 'background-loader': 'rgba(24, 24, 24, 0.9)',
+ 'background-accent-button': '#4A87E7',
+ 'background-contrast-popover': '#fff',
+ 'shadow-contrast-popover': 'rgba(0, 0, 0, 0.3)',
+ 'highlight-button-hover': '#EAEAEA',
+ 'highlight-button-pressed': '#E1E1E1',
+ 'highlight-button-pressed-hover': '#bababa',
+ 'highlight-primary-dialog-button-hover': '#2566D5',
+ 'highlight-header-button-hover': '#eaeaea',
+ 'highlight-header-button-pressed': '#e1e1e1',
+ 'highlight-text-select': '#3494fb',
+ 'highlight-accent-button-hover': '#375478',
+ 'highlight-accent-button-pressed': '#293f59',
+ 'highlight-toolbar-tab-underline-document': '#446995',
+ 'highlight-toolbar-tab-underline-spreadsheet': '#3A8056',
+ 'highlight-toolbar-tab-underline-presentation': '#B75B44',
+ 'highlight-toolbar-tab-underline-pdf': '#AA5252',
+ 'highlight-toolbar-tab-underline-visio': '#444796',
+ 'highlight-header-tab-underline-document': '#446995',
+ 'highlight-header-tab-underline-spreadsheet': '#3A8056',
+ 'highlight-header-tab-underline-presentation': '#B75B44',
+ 'highlight-header-tab-underline-pdf': '#AA5252',
+ 'highlight-header-tab-underline-visio': '#444796',
+ 'border-toolbar': '#cbcbcb',
+ 'border-divider': '#EAEAEA',
+ 'border-regular-control': '#E1E1E1',
+ 'border-toolbar-button-hover': '#eaeaea',
+ 'border-preview-hover': '#92B7F0',
+ 'border-preview-select': '#4A87E7',
+ 'border-control-focus': '#4A87E7',
+ 'border-color-shading': 'rgba(0, 0, 0, 0.15)',
+ 'border-error': '#f62211',
+ 'border-contrast-popover': '#fff',
+ 'text-normal': 'rgba(0, 0, 0, 0.8)',
+ 'text-normal-pressed': 'rgba(0, 0, 0, 0.8)',
+ 'text-secondary': 'rgba(0, 0, 0, 0.6)',
+ 'text-tertiary': 'rgba(0, 0, 0, 0.4)',
+ 'text-link': '#445799',
+ 'text-link-hover': '#445799',
+ 'text-link-active': '#445799',
+ 'text-link-visited': '#445799',
+ 'text-inverse': '#fff',
+ 'text-toolbar-header': 'rgba(0, 0, 0, 0.8)',
+ 'text-contrast-background': '#fff',
+ 'text-alt-key-hint': 'rgba(0, 0, 0, 0.8)',
+ 'icon-normal': '#444',
+ 'icon-normal-pressed': '#444',
+ 'icon-inverse': '#444',
+ 'icon-toolbar-header': '#444',
+ 'icon-notification-badge': '#000',
+ 'icon-contrast-popover': '#fff',
+ 'icon-success': '#2e8b57',
+ 'canvas-background': '#f3f3f3',
+ 'canvas-content-background': '#fff',
+ 'canvas-page-border': '#ccc',
+ 'canvas-ruler-background': '#fff',
+ 'canvas-ruler-border': '#cbcbcb',
+ 'canvas-ruler-margins-background': '#d9d9d9',
+ 'canvas-ruler-mark': '#555',
+ 'canvas-ruler-handle-border': '#555',
+ 'canvas-ruler-handle-border-disabled': '#aaa',
+ 'canvas-high-contrast': '#000',
+ 'canvas-high-contrast-disabled': '#666',
+ 'canvas-cell-border': 'rgba(0, 0, 0, 0.1)',
+ 'canvas-cell-title-background': '#f7f7f7',
+ 'canvas-cell-title-background-hover': '#dfdfdf',
+ 'canvas-cell-title-background-selected': '#cfcfcf',
+ 'canvas-cell-title-border': '#d8d8d8',
+ 'canvas-cell-title-border-hover': '#c9c9c9',
+ 'canvas-cell-title-border-selected': '#bbb',
+ 'canvas-cell-title-text': '#444',
+ 'canvas-dark-cell-title': '#666666',
+ 'canvas-dark-cell-title-hover': '#999',
+ 'canvas-dark-cell-title-selected': '#333',
+ 'canvas-dark-cell-title-border': '#3d3d3d',
+ 'canvas-dark-cell-title-border-hover': '#5c5c5c',
+ 'canvas-dark-cell-title-border-selected': '#0f0f0f',
+ 'canvas-dark-content-background': '#3a3a3a',
+ 'canvas-dark-page-border': '#2a2a2a',
+ 'canvas-scroll-thumb': '#f7f7f7',
+ 'canvas-scroll-thumb-hover': '#c0c0c0',
+ 'canvas-scroll-thumb-pressed': '#adadad',
+ 'canvas-scroll-thumb-border': '#cbcbcb',
+ 'canvas-scroll-thumb-border-hover': '#cbcbcb',
+ 'canvas-scroll-thumb-border-pressed': '#adadad',
+ 'canvas-scroll-arrow': '#adadad',
+ 'canvas-scroll-arrow-hover': '#f7f7f7',
+ 'canvas-scroll-arrow-pressed': '#f7f7f7',
+ 'canvas-scroll-thumb-target': '#c0c0c0',
+ 'canvas-scroll-thumb-target-hover': '#f7f7f7',
+ 'canvas-scroll-thumb-target-pressed': '#f7f7f7',
+ 'canvas-sheet-view-cell-background': '#73bf91',
+ 'canvas-sheet-view-cell-background-hover': '#97e3b6',
+ 'canvas-sheet-view-cell-background-pressed': '#aaffcc',
+ 'canvas-sheet-view-cell-title-label': '#121212',
+ 'canvas-freeze-line-1px': '#818182',
+ 'canvas-freeze-line-2px': '#aaaaaa',
+ 'canvas-select-all-icon': '#999',
+ 'canvas-anim-pane-background': '#f7f7f7',
+ 'canvas-anim-pane-item-fill-selected': '#cbcbcb',
+ 'canvas-anim-pane-item-fill-hovered': '#e0e0e0',
+ 'canvas-anim-pane-button-fill': '#e0e0e0',
+ 'canvas-anim-pane-button-fill-hovered': '#e0e0e0',
+ 'canvas-anim-pane-button-fill-disabled': 'rgba(224, 224, 224, 0.4)',
+ 'canvas-anim-pane-play-button-fill': '#fff',
+ 'canvas-anim-pane-play-button-outline': '#c0c0c0',
+ 'canvas-anim-pane-effect-bar-entrance-fill': '#77b583',
+ 'canvas-anim-pane-effect-bar-entrance-outline': '#0e8a26',
+ 'canvas-anim-pane-effect-bar-emphasis-fill': '#fbc37c',
+ 'canvas-anim-pane-effect-bar-emphasis-outline': '#ff8e00',
+ 'canvas-anim-pane-effect-bar-exit-fill': '#f59a9a',
+ 'canvas-anim-pane-effect-bar-exit-outline': '#f23d3d',
+ 'canvas-anim-pane-effect-bar-path-fill': '#a1cee3',
+ 'canvas-anim-pane-effect-bar-path-outline': '#254662',
+ 'canvas-anim-pane-timeline-ruler-outline': '#cbcbcb',
+ 'canvas-anim-pane-timeline-ruler-tick': '#cbcbcb',
+ 'canvas-anim-pane-timeline-scroller-fill': '#cbcbcb',
+ 'canvas-anim-pane-timeline-scroller-outline': '#444',
+ 'canvas-anim-pane-timeline-scroller-opacity': '0',
+ 'canvas-anim-pane-timeline-scroller-opacity-hovered': '0.4',
+ 'canvas-anim-pane-timeline-scroller-opacity-active': '1',
+ 'toolbar-height-controls': '84px',
+ 'sprite-button-icons-uid': 'mod25',
+ type: 'light',
+ name: 'theme-white'
+ },
+ type: 'init',
+ options: {}
+ };
+ sendMessageToFrame(iframeId, msg);
+}
+
+/**
+ * Sends method return data to the main iframe
+ * @param {*} data - The data to return
+ */
+function handleMethodReturn(data) {
+ const dataReturn = {
+ guid: pluginGuid,
+ methodReturnData: data,
+ type: 'onMethodReturn'
+ };
+ sendMessageToFrame(iframeMain, dataReturn);
+}
+
+/**
+ * Handles method calls from the plugin
+ * @param {Object} data - Method call data containing methodName and data
+ */
+function handleMethod(data) {
+ if (data.methodName === 'AddToolbarMenuItem') {
+ handleMethodReturn(undefined);
+ settingsButton = data.data;
+ AddToolbarMenuItem(settingsButton);
+ } else if (data.methodName === 'GetVersion') {
+ handleMethodReturn(sdkVersion);
+ } else if (data.methodName === 'ShowWindow') {
+ ShowWindow(data.data);
+ handleMethodReturn(undefined);
+ } else if (data.methodName === 'SendToWindow') {
+ SendToWindow(data.data);
+ handleMethodReturn(undefined);
+ } else if (data.methodName === 'CloseWindow') {
+ CloseWindow(data.data);
+ handleMethodReturn(undefined);
+ } else if (data.methodName === 'SendEvent') {
+ if (data.data && data.data[0] === 'ai_onLoadInternalProviders' && loadInternalProvidersCallback) {
+ loadInternalProvidersCallback();
+ }
+ handleMethodReturn(undefined);
+ } else {
+ handleMethodReturn(undefined);
+ }
+}
+
+/**
+ * Forwards window events to the plugin
+ * @param {Object} data - Event data with windowID, eventName, and data
+ */
+function sendMessageToPlugin(data) {
+ const pluginData = {
+ guid: pluginGuid,
+ type: 'onWindowEvent',
+ windowID: data.windowID,
+ eventName: data.eventName,
+ eventData: data.data
+ };
+ sendMessageToFrame(iframeMain, pluginData);
+}
+
+/**
+ * Sends an event to a specific window
+ * @param {Array} data - [iframeId, eventName, eventData]
+ */
+function SendToWindow(data) {
+ const iframeId = data[0];
+ const eventName = data[1];
+ const eventData = data[2];
+ const pluginData = {
+ guid: pluginGuid,
+ type: 'onEvent',
+ eventName,
+ eventData
+ };
+ sendMessageToFrame(iframeId, pluginData);
+}
+
+/**
+ * Handles toolbar menu item addition
+ * @param {Array} val - Menu item configuration
+ */
+function AddToolbarMenuItem(val) {
+ const id = val[0].tabs[0].items[0].id;
+ const data = {
+ guid: pluginGuid,
+ type: 'onEvent',
+ eventName: 'onToolbarMenuClick',
+ eventData: id
+ };
+ sendMessageToFrame(iframeMain, data);
+}
+
+/**
+ * Handles button click events
+ * @param {string|number} id - Button ID
+ * @param {string} [windowId] - Optional window ID
+ */
+function onButtonClick(id, windowId) {
+ const pluginData = {
+ guid: pluginGuid,
+ type: 'button',
+ button: '' + id
+ };
+ if (windowId) {
+ pluginData.buttonWindowId = '' + windowId;
+ }
+ sendMessageToFrame(iframeMain, pluginData);
+}
+
+/**
+ * Shows a plugin window with configured buttons
+ * @param {Array} val - [windowId, config] where config contains url, buttons, etc.
+ */
+function ShowWindow(val) {
+ const [iframeId, config] = val;
+ const isMain = config.url.includes(mainButtonId);
+
+ if (isMain) {
+ config.buttons = config.buttons.map((button, index) => ({
+ text: 'Save Changes',
+ onClick: () => {
+ onButtonClick(index, iframeId);
+ if (saveCallback) {
+ saveCallback();
+ }
+ AddToolbarMenuItem(settingsButton);
+ },
+ disabled: false
+ }));
+ } else {
+ config.buttons = config.buttons.map((button, index) => ({
+ text: button.text,
+ onClick: () => {
+ onButtonClick(index, iframeId);
+ },
+ disabled: false
+ }));
+ }
+
+ // Use callback if registered
+ if (showPluginWindowCallback) {
+ showPluginWindowCallback(iframeId, config);
+ }
+}
+
+/**
+ * Closes a plugin window
+ * @param {Array} val - [windowId]
+ */
+function CloseWindow(val) {
+ const id = val[0];
+
+ // Use callback if registered
+ if (closePluginWindowCallback) {
+ closePluginWindowCallback(id);
+ }
+}
+
+/**
+ * Initializes AI settings stub with the main iframe ID and SDK version
+ * @param {string} iframeId - The ID of the main iframe
+ * @param {string} version - The SDK version from statistics data or 'develop' for development
+ */
+function initAISettings(iframeId, version = 'develop') {
+ iframeMain = iframeId;
+ sdkVersion = version;
+ window.addEventListener('message', receiveMessage);
+}
+
+/**
+ * Registers callback for showing plugin windows
+ * @param {function} callback - Function to call when showing a window (iframeId, config) => void
+ */
+function registerShowWindowCallback(callback) {
+ showPluginWindowCallback = callback;
+}
+
+/**
+ * Registers callback for closing plugin windows
+ * @param {function} callback - Function to call when closing a window (id) => void
+ */
+function registerCloseWindowCallback(callback) {
+ closePluginWindowCallback = callback;
+}
+
+/**
+ * Registers callback for save button action
+ * @param {function} callback - Function to call when save button is clicked () => void
+ */
+function registerSaveCallback(callback) {
+ saveCallback = callback;
+}
+
+/**
+ * Registers callback for loading internal providers
+ * @param {function} callback - Function to call when internal providers should be loaded () => void
+ */
+function registerLoadInternalProvidersCallback(callback) {
+ loadInternalProvidersCallback = callback;
+}
+
+export {initAISettings, registerShowWindowCallback, registerCloseWindowCallback, registerSaveCallback, registerLoadInternalProvidersCallback};
diff --git a/AdminPanel/client/src/pages/AiIntegration/js/plugins-ui.js b/AdminPanel/client/src/pages/AiIntegration/js/plugins-ui.js
new file mode 100644
index 0000000000..9490dfbad4
--- /dev/null
+++ b/AdminPanel/client/src/pages/AiIntegration/js/plugins-ui.js
@@ -0,0 +1,54 @@
+/**
+ *
+ * (c) Copyright Ascensio System SIA 2021
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?module.exports=e():"function"==typeof define&&define.amd?define(e):t.PerfectScrollbar=e()}(this,function(){"use strict";function t(t){return getComputedStyle(t)}function e(t,e){for(var i in e){var r=e[i];"number"==typeof r&&(r+="px"),t.style[i]=r}return t}function i(t){var e=document.createElement("div");return e.className=t,e}function r(t,e){if(!v)throw new Error("No element matching method supported");return v.call(t,e)}function l(t){t.remove?t.remove():t.parentNode&&t.parentNode.removeChild(t)}function n(t,e){return Array.prototype.filter.call(t.children,function(t){return r(t,e)})}function o(t,e){var i=t.element.classList,r=m.state.scrolling(e);i.contains(r)?clearTimeout(Y[e]):i.add(r)}function s(t,e){Y[e]=setTimeout(function(){return t.isAlive&&t.element.classList.remove(m.state.scrolling(e))},t.settings.scrollingThreshold)}function a(t,e){o(t,e),s(t,e)}function c(t){if("function"==typeof window.CustomEvent)return new CustomEvent(t);var e=document.createEvent("CustomEvent");return e.initCustomEvent(t,!1,!1,void 0),e}function h(t,e,i,r,l){var n=i[0],o=i[1],s=i[2],h=i[3],u=i[4],d=i[5];void 0===r&&(r=!0),void 0===l&&(l=!1);var f=t.element;t.reach[h]=null,f[s]<1&&(t.reach[h]="start"),f[s]>t[n]-t[o]-1&&(t.reach[h]="end"),e&&(f.dispatchEvent(c("ps-scroll-"+h)),e<0?f.dispatchEvent(c("ps-scroll-"+u)):e>0&&f.dispatchEvent(c("ps-scroll-"+d)),r&&a(t,h)),t.reach[h]&&(e||l)&&f.dispatchEvent(c("ps-"+h+"-reach-"+t.reach[h]))}function u(t){return parseInt(t,10)||0}function d(t){return r(t,"input,[contenteditable]")||r(t,"select,[contenteditable]")||r(t,"textarea,[contenteditable]")||r(t,"button,[contenteditable]")}function f(e){var i=t(e);return u(i.width)+u(i.paddingLeft)+u(i.paddingRight)+u(i.borderLeftWidth)+u(i.borderRightWidth)}function p(t,e){return t.settings.minScrollbarLength&&(e=Math.max(e,t.settings.minScrollbarLength)),t.settings.maxScrollbarLength&&(e=Math.min(e,t.settings.maxScrollbarLength)),e}function b(t,i){var r={width:i.railXWidth},l=Math.floor(t.scrollTop);i.isRtl?r.left=i.negativeScrollAdjustment+t.scrollLeft+i.containerWidth-i.contentWidth:r.left=t.scrollLeft,i.isScrollbarXUsingBottom?r.bottom=i.scrollbarXBottom-l:r.top=i.scrollbarXTop+l,e(i.scrollbarXRail,r);var n={top:l,height:i.railYHeight};i.isScrollbarYUsingRight?i.isRtl?n.right=i.contentWidth-(i.negativeScrollAdjustment+t.scrollLeft)-i.scrollbarYRight-i.scrollbarYOuterWidth:n.right=i.scrollbarYRight-t.scrollLeft:i.isRtl?n.left=i.negativeScrollAdjustment+t.scrollLeft+2*i.containerWidth-i.contentWidth-i.scrollbarYLeft-i.scrollbarYOuterWidth:n.left=i.scrollbarYLeft+t.scrollLeft,e(i.scrollbarYRail,n),e(i.scrollbarX,{left:i.scrollbarXLeft,width:i.scrollbarXWidth-i.railBorderXWidth}),e(i.scrollbarY,{top:i.scrollbarYTop,height:i.scrollbarYHeight-i.railBorderYWidth})}function g(t,e){function i(e){b[d]=g+Y*(e[a]-v),o(t,f),R(t),e.stopPropagation(),e.preventDefault()}function r(){s(t,f),t[p].classList.remove(m.state.clicking),t.event.unbind(t.ownerDocument,"mousemove",i)}var l=e[0],n=e[1],a=e[2],c=e[3],h=e[4],u=e[5],d=e[6],f=e[7],p=e[8],b=t.element,g=null,v=null,Y=null;t.event.bind(t[h],"mousedown",function(e){g=b[d],v=e[a],Y=(t[n]-t[l])/(t[c]-t[u]),t.event.bind(t.ownerDocument,"mousemove",i),t.event.once(t.ownerDocument,"mouseup",r),t[p].classList.add(m.state.clicking),e.stopPropagation()/*,e.preventDefault()*/})}var v="undefined"!=typeof Element&&(Element.prototype.matches||Element.prototype.webkitMatchesSelector||Element.prototype.mozMatchesSelector||Element.prototype.msMatchesSelector),m={main:"ps",element:{thumb:function(t){return"ps__thumb-"+t},rail:function(t){return"ps__rail-"+t},consuming:"ps__child--consume"},state:{focus:"ps--focus",clicking:"ps--clicking",active:function(t){return"ps--active-"+t},scrolling:function(t){return"ps--scrolling-"+t}}},Y={x:null,y:null},X=function(t){this.element=t,this.handlers={}},w={isEmpty:{configurable:!0}};X.prototype.bind=function(t,e){void 0===this.handlers[t]&&(this.handlers[t]=[]),this.handlers[t].push(e),this.element.addEventListener(t,e,!1)},X.prototype.unbind=function(t,e){var i=this;this.handlers[t]=this.handlers[t].filter(function(r){return!(!e||r===e)||(i.element.removeEventListener(t,r,!1),!1)})},X.prototype.unbindAll=function(){var t=this;for(var e in t.handlers)t.unbind(e)},w.isEmpty.get=function(){var t=this;return Object.keys(this.handlers).every(function(e){return 0===t.handlers[e].length})},Object.defineProperties(X.prototype,w);var y=function(){this.eventElements=[]};y.prototype.eventElement=function(t){var e=this.eventElements.filter(function(e){return e.element===t})[0];return e||(e=new X(t),this.eventElements.push(e)),e},y.prototype.bind=function(t,e,i){this.eventElement(t).bind(e,i)},y.prototype.unbind=function(t,e,i){var r=this.eventElement(t);r.unbind(e,i),r.isEmpty&&this.eventElements.splice(this.eventElements.indexOf(r),1)},y.prototype.unbindAll=function(){this.eventElements.forEach(function(t){return t.unbindAll()}),this.eventElements=[]},y.prototype.once=function(t,e,i){var r=this.eventElement(t),l=function(t){r.unbind(e,l),i(t)};r.bind(e,l)};var W=function(t,e,i,r,l){void 0===r&&(r=!0),void 0===l&&(l=!1);var n;if("top"===e)n=["contentHeight","containerHeight","scrollTop","y","up","down"];else{if("left"!==e)throw new Error("A proper axis should be provided");n=["contentWidth","containerWidth","scrollLeft","x","left","right"]}h(t,i,n,r,l)},L={isWebKit:"undefined"!=typeof document&&"WebkitAppearance"in document.documentElement.style,supportsTouch:"undefined"!=typeof window&&("ontouchstart"in window||window.DocumentTouch&&document instanceof window.DocumentTouch),supportsIePointer:"undefined"!=typeof navigator&&navigator.msMaxTouchPoints,isChrome:"undefined"!=typeof navigator&&/Chrome/i.test(navigator&&navigator.userAgent)},R=function(t){var e=t.element,i=Math.floor(e.scrollTop);t.containerWidth=e.clientWidth,t.containerHeight=e.clientHeight,t.contentWidth=e.scrollWidth,t.contentHeight=e.scrollHeight,e.contains(t.scrollbarXRail)||(n(e,m.element.rail("x")).forEach(function(t){return l(t)}),e.appendChild(t.scrollbarXRail)),e.contains(t.scrollbarYRail)||(n(e,m.element.rail("y")).forEach(function(t){return l(t)}),e.appendChild(t.scrollbarYRail)),!t.settings.suppressScrollX&&t.containerWidth+t.settings.scrollXMarginOffset=t.railXWidth-t.scrollbarXWidth&&(t.scrollbarXLeft=t.railXWidth-t.scrollbarXWidth),t.scrollbarYTop>=t.railYHeight-t.scrollbarYHeight&&(t.scrollbarYTop=t.railYHeight-t.scrollbarYHeight),b(e,t),t.scrollbarXActive?e.classList.add(m.state.active("x")):(e.classList.remove(m.state.active("x")),t.scrollbarXWidth=0,t.scrollbarXLeft=0,e.scrollLeft=0),t.scrollbarYActive?e.classList.add(m.state.active("y")):(e.classList.remove(m.state.active("y")),t.scrollbarYHeight=0,t.scrollbarYTop=0,e.scrollTop=0)},T={"click-rail":function(t){t.event.bind(t.scrollbarY,"mousedown",function(t){return t.stopPropagation()}),t.event.bind(t.scrollbarYRail,"mousedown",function(e){var i=e.pageY-window.pageYOffset-t.scrollbarYRail.getBoundingClientRect().top>t.scrollbarYTop?1:-1;t.element.scrollTop+=i*t.containerHeight,R(t),e.stopPropagation()}),t.event.bind(t.scrollbarX,"mousedown",function(t){return t.stopPropagation()}),t.event.bind(t.scrollbarXRail,"mousedown",function(e){var i=e.pageX-window.pageXOffset-t.scrollbarXRail.getBoundingClientRect().left>t.scrollbarXLeft?1:-1;t.element.scrollLeft+=i*t.containerWidth,R(t),e.stopPropagation()})},"drag-thumb":function(t){g(t,["containerWidth","contentWidth","pageX","railXWidth","scrollbarX","scrollbarXWidth","scrollLeft","x","scrollbarXRail"]),g(t,["containerHeight","contentHeight","pageY","railYHeight","scrollbarY","scrollbarYHeight","scrollTop","y","scrollbarYRail"])},keyboard:function(t){function e(e,r){var l=Math.floor(i.scrollTop);if(0===e){if(!t.scrollbarYActive)return!1;if(0===l&&r>0||l>=t.contentHeight-t.containerHeight&&r<0)return!t.settings.wheelPropagation}var n=i.scrollLeft;if(0===r){if(!t.scrollbarXActive)return!1;if(0===n&&e<0||n>=t.contentWidth-t.containerWidth&&e>0)return!t.settings.wheelPropagation}return!0}var i=t.element,l=function(){return r(i,":hover")},n=function(){return r(t.scrollbarX,":focus")||r(t.scrollbarY,":focus")};t.event.bind(t.ownerDocument,"keydown",function(r){if(!(r.isDefaultPrevented&&r.isDefaultPrevented()||r.defaultPrevented)&&(l()||n())){var o=document.activeElement?document.activeElement:t.ownerDocument.activeElement;if(o){if("IFRAME"===o.tagName)o=o.contentDocument.activeElement;else for(;o.shadowRoot;)o=o.shadowRoot.activeElement;if(d(o))return}var s=0,a=0;switch(r.which){case 37:s=r.metaKey?-t.contentWidth:r.altKey?-t.containerWidth:-30;break;case 38:a=r.metaKey?t.contentHeight:r.altKey?t.containerHeight:30;break;case 39:s=r.metaKey?t.contentWidth:r.altKey?t.containerWidth:30;break;case 40:a=r.metaKey?-t.contentHeight:r.altKey?-t.containerHeight:-30;break;case 32:a=r.shiftKey?t.containerHeight:-t.containerHeight;break;case 33:a=t.containerHeight;break;case 34:a=-t.containerHeight;break;case 36:a=t.contentHeight;break;case 35:a=-t.contentHeight;break;default:return}t.settings.suppressScrollX&&0!==s||t.settings.suppressScrollY&&0!==a||(i.scrollTop-=a,i.scrollLeft+=s,R(t),e(s,a)&&r.preventDefault())}})},wheel:function(e){function i(t,i){var r=Math.floor(o.scrollTop),l=0===o.scrollTop,n=r+o.offsetHeight===o.scrollHeight,s=0===o.scrollLeft,a=o.scrollLeft+o.offsetWidth===o.scrollWidth;return!(Math.abs(i)>Math.abs(t)?l||n:s||a)||!e.settings.wheelPropagation}function r(t){var e=t.deltaX,i=-1*t.deltaY;return void 0!==e&&void 0!==i||(e=-1*t.wheelDeltaX/6,i=t.wheelDeltaY/6),t.deltaMode&&1===t.deltaMode&&(e*=10,i*=10),e!==e&&i!==i&&(e=0,i=t.wheelDelta),t.shiftKey?[-i,-e]:[e,i]}function l(e,i,r){if(!L.isWebKit&&o.querySelector("select:focus"))return!0;if(!o.contains(e))return!1;for(var l=e;l&&l!==o;){if(l.classList.contains(m.element.consuming))return!0;var n=t(l);if([n.overflow,n.overflowX,n.overflowY].join("").match(/(scroll|auto)/)){var s=l.scrollHeight-l.clientHeight;if(s>0&&!(0===l.scrollTop&&r>0||l.scrollTop===s&&r<0))return!0;var a=l.scrollWidth-l.clientWidth;if(a>0&&!(0===l.scrollLeft&&i<0||l.scrollLeft===a&&i>0))return!0}l=l.parentNode}return!1}function n(t){var n=r(t),s=n[0],a=n[1];if(!l(t.target,s,a)){var c=!1;e.settings.useBothWheelAxes?e.scrollbarYActive&&!e.scrollbarXActive?(a?o.scrollTop-=a*e.settings.wheelSpeed:o.scrollTop+=s*e.settings.wheelSpeed,c=!0):e.scrollbarXActive&&!e.scrollbarYActive&&(s?o.scrollLeft+=s*e.settings.wheelSpeed:o.scrollLeft-=a*e.settings.wheelSpeed,c=!0):(o.scrollTop-=a*e.settings.wheelSpeed,o.scrollLeft+=s*e.settings.wheelSpeed),R(e),(c=c||i(s,a))&&!t.ctrlKey&&(t.stopPropagation(),t.preventDefault())}}var o=e.element;void 0!==window.onwheel?e.event.bind(o,"wheel",n):void 0!==window.onmousewheel&&e.event.bind(o,"mousewheel",n)},touch:function(e){function i(t,i){var r=Math.floor(h.scrollTop),l=h.scrollLeft,n=Math.abs(t),o=Math.abs(i);if(o>n){if(i<0&&r===e.contentHeight-e.containerHeight||i>0&&0===r)return 0===window.scrollY&&i>0&&L.isChrome}else if(n>o&&(t<0&&l===e.contentWidth-e.containerWidth||t>0&&0===l))return!0;return!0}function r(t,i){h.scrollTop-=i,h.scrollLeft-=t,R(e)}function l(t){return t.targetTouches?t.targetTouches[0]:t}function n(t){return!(t.pointerType&&"pen"===t.pointerType&&0===t.buttons||(!t.targetTouches||1!==t.targetTouches.length)&&(!t.pointerType||"mouse"===t.pointerType||t.pointerType===t.MSPOINTER_TYPE_MOUSE))}function o(t){if(n(t)){var e=l(t);u.pageX=e.pageX,u.pageY=e.pageY,d=(new Date).getTime(),null!==p&&clearInterval(p)}}function s(e,i,r){if(!h.contains(e))return!1;for(var l=e;l&&l!==h;){if(l.classList.contains(m.element.consuming))return!0;var n=t(l);if([n.overflow,n.overflowX,n.overflowY].join("").match(/(scroll|auto)/)){var o=l.scrollHeight-l.clientHeight;if(o>0&&!(0===l.scrollTop&&r>0||l.scrollTop===o&&r<0))return!0;var s=l.scrollLeft-l.clientWidth;if(s>0&&!(0===l.scrollLeft&&i<0||l.scrollLeft===s&&i>0))return!0}l=l.parentNode}return!1}function a(t){if(n(t)){var e=l(t),o={pageX:e.pageX,pageY:e.pageY},a=o.pageX-u.pageX,c=o.pageY-u.pageY;if(s(t.target,a,c))return;r(a,c),u=o;var h=(new Date).getTime(),p=h-d;p>0&&(f.x=a/p,f.y=c/p,d=h),i(a,c)&&t.preventDefault()}}function c(){e.settings.swipeEasing&&(clearInterval(p),p=setInterval(function(){e.isInitialized?clearInterval(p):f.x||f.y?Math.abs(f.x)<.01&&Math.abs(f.y)<.01?clearInterval(p):(r(30*f.x,30*f.y),f.x*=.8,f.y*=.8):clearInterval(p)},10))}if(L.supportsTouch||L.supportsIePointer){var h=e.element,u={},d=0,f={},p=null;L.supportsTouch?(e.event.bind(h,"touchstart",o),e.event.bind(h,"touchmove",a),e.event.bind(h,"touchend",c)):L.supportsIePointer&&(window.PointerEvent?(e.event.bind(h,"pointerdown",o),e.event.bind(h,"pointermove",a),e.event.bind(h,"pointerup",c)):window.MSPointerEvent&&(e.event.bind(h,"MSPointerDown",o),e.event.bind(h,"MSPointerMove",a),e.event.bind(h,"MSPointerUp",c)))}}},H=function(r,l){var n=this;if(void 0===l&&(l={}),"string"==typeof r&&(r=document.querySelector(r)),!r||!r.nodeName)throw new Error("no element is specified to initialize PerfectScrollbar");this.element=r,r.classList.add(m.main),this.settings={handlers:["click-rail","drag-thumb","keyboard","wheel","touch"],maxScrollbarLength:null,minScrollbarLength:null,scrollingThreshold:1e3,scrollXMarginOffset:0,scrollYMarginOffset:0,suppressScrollX:!1,suppressScrollY:!1,swipeEasing:!0,useBothWheelAxes:!1,wheelPropagation:!0,wheelSpeed:0.35};for(var o in l)n.settings[o]=l[o];this.containerWidth=null,this.containerHeight=null,this.contentWidth=null,this.contentHeight=null;var s=function(){return r.classList.add(m.state.focus)},a=function(){return r.classList.remove(m.state.focus)};this.isRtl="rtl"===t(r).direction,this.isNegativeScroll=function(){var t=r.scrollLeft,e=null;return r.scrollLeft=-1,e=r.scrollLeft<0,r.scrollLeft=t,e}(),this.negativeScrollAdjustment=this.isNegativeScroll?r.scrollWidth-r.clientWidth:0,this.event=new y,this.ownerDocument=r.ownerDocument||document,this.scrollbarXRail=i(m.element.rail("x")),r.appendChild(this.scrollbarXRail),this.scrollbarX=i(m.element.thumb("x")),this.scrollbarXRail.appendChild(this.scrollbarX),this.scrollbarX.setAttribute("tabindex",0),this.event.bind(this.scrollbarX,"focus",s),this.event.bind(this.scrollbarX,"blur",a),this.scrollbarXActive=null,this.scrollbarXWidth=null,this.scrollbarXLeft=null;var c=t(this.scrollbarXRail);this.scrollbarXBottom=parseInt(c.bottom,10),isNaN(this.scrollbarXBottom)?(this.isScrollbarXUsingBottom=!1,this.scrollbarXTop=u(c.top)):this.isScrollbarXUsingBottom=!0,this.railBorderXWidth=u(c.borderLeftWidth)+u(c.borderRightWidth),e(this.scrollbarXRail,{display:"block"}),this.railXMarginWidth=u(c.marginLeft)+u(c.marginRight),e(this.scrollbarXRail,{display:""}),this.railXWidth=null,this.railXRatio=null,this.scrollbarYRail=i(m.element.rail("y")),r.appendChild(this.scrollbarYRail),this.scrollbarY=i(m.element.thumb("y")),this.scrollbarYRail.appendChild(this.scrollbarY),this.scrollbarY.setAttribute("tabindex",0),this.event.bind(this.scrollbarY,"focus",s),this.event.bind(this.scrollbarY,"blur",a),this.scrollbarYActive=null,this.scrollbarYHeight=null,this.scrollbarYTop=null;var h=t(this.scrollbarYRail);this.scrollbarYRight=parseInt(h.right,10),isNaN(this.scrollbarYRight)?(this.isScrollbarYUsingRight=!1,this.scrollbarYLeft=u(h.left)):this.isScrollbarYUsingRight=!0,this.scrollbarYOuterWidth=this.isRtl?f(this.scrollbarY):null,this.railBorderYWidth=u(h.borderTopWidth)+u(h.borderBottomWidth),e(this.scrollbarYRail,{display:"block"}),this.railYMarginHeight=u(h.marginTop)+u(h.marginBottom),e(this.scrollbarYRail,{display:""}),this.railYHeight=null,this.railYRatio=null,this.reach={x:r.scrollLeft<=0?"start":r.scrollLeft>=this.contentWidth-this.containerWidth?"end":null,y:r.scrollTop<=0?"start":r.scrollTop>=this.contentHeight-this.containerHeight?"end":null},this.isAlive=!0,this.settings.handlers.forEach(function(t){return T[t](n)}),this.lastScrollTop=Math.floor(r.scrollTop),this.lastScrollLeft=r.scrollLeft,this.event.bind(this.element,"scroll",function(t){return n.onScroll(t)}),R(this)};return H.prototype.update=function(){this.isAlive&&(this.negativeScrollAdjustment=this.isNegativeScroll?this.element.scrollWidth-this.element.clientWidth:0,e(this.scrollbarXRail,{display:"block"}),e(this.scrollbarYRail,{display:"block"}),this.railXMarginWidth=u(t(this.scrollbarXRail).marginLeft)+u(t(this.scrollbarXRail).marginRight),this.railYMarginHeight=u(t(this.scrollbarYRail).marginTop)+u(t(this.scrollbarYRail).marginBottom),e(this.scrollbarXRail,{display:"none"}),e(this.scrollbarYRail,{display:"none"}),R(this),W(this,"top",0,!1,!0),W(this,"left",0,!1,!0),e(this.scrollbarXRail,{display:""}),e(this.scrollbarYRail,{display:""}))},H.prototype.onScroll=function(t){this.isAlive&&(R(this),W(this,"top",this.element.scrollTop-this.lastScrollTop),W(this,"left",this.element.scrollLeft-this.lastScrollLeft),this.lastScrollTop=Math.floor(this.element.scrollTop),this.lastScrollLeft=this.element.scrollLeft)},H.prototype.destroy=function(){this.isAlive&&(this.event.unbindAll(),l(this.scrollbarX),l(this.scrollbarY),l(this.scrollbarXRail),l(this.scrollbarYRail),this.removePsClasses(),this.element=null,this.scrollbarX=null,this.scrollbarY=null,this.scrollbarXRail=null,this.scrollbarYRail=null,this.isAlive=!1)},H.prototype.removePsClasses=function(){this.element.className=this.element.className.split(" ").filter(function(t){return!t.match(/^ps([-_].+|)$/)}).join(" ")},H});
+var Ps = null;
+/**
+ *
+ * var loader = showLoader(document.getElementById("parent-id"))
+ * loader.remove()
+ *
+ * parent must have position: relative
+ */
+showLoader = function (parent, text) {
+ var themeType = window.Asc && window.Asc.plugin && window.Asc.plugin.theme && window.Asc.plugin.theme.type;
+ var loader = document.createElement('div');
+ loader.className = 'asc-plugin-loader';
+ loader.innerHTML = '
' + (text || "Loading") + '
';
+ parent.append ? parent.append(loader) : parent.appendChild(loader);
+ return loader;
+};
+// check css load
+if (document.currentScript && document.currentScript.src) {
+ if (document.currentScript.getAttribute("loadCss") === "true") {
+ var scriptDirectory = document.currentScript.src;
+ var lastSlash = scriptDirectory.lastIndexOf("/");
+ if (0 < lastSlash) scriptDirectory = scriptDirectory.substr(0, lastSlash);
+
+ var link = document.createElement("link");
+ link.rel = "stylesheet";
+ link.type = "text/css";
+ link.href = scriptDirectory + "/plugins.css";
+ document.getElementsByTagName('HEAD')[0].appendChild(link);
+ }
+}
+// escape and unescape func
+!function(e){function n(n){function t(e){return n[e]}var e="(?:"+Object.keys(n).join("|")+")",u=RegExp(e),c=RegExp(e,"g");return function(e){return e=null==e?"":""+e,u.test(e)?e.replace(c,t):e}}escape=n({"&":"&","<":"<",">":">",'"':""","'":"'","`":"`"}),unescape=n({"&":"&","<":"<",">":">",""":'"',"'":"'","`":"`"}),e.escape=escape,e.unescape=unescape}(window);
+
+// select2 fix search field
+var select2_amd,select2_defaults;"undefined"!=typeof jQuery&&null!=$.fn.select2&&(select2_amd=$.fn.select2.amd,select2_defaults=$.fn.select2.defaults,$.fn.select2.amd.define("SearchableSingleSelection",["select2/utils","select2/selection/single","select2/selection/eventRelay","select2/dropdown/search"],function(e,t,n,l){var s=e.Decorate(t,l);(s=e.Decorate(s,n)).prototype.render=function(){var e=l.prototype.render.call(this,t.prototype.render);return this.$searchContainer.hide(),this.$element.siblings(".select2").find(".selection").prepend(this.$searchContainer),e};var c=s.prototype.bind;return s.prototype.bind=function(e){var t=this;c.apply(this,arguments),e.on("open",function(){t.$selection.hide(),t.$searchContainer.show()}),e.on("close",function(){t.$searchContainer.hide(),t.$selection.show()})},s}),$.fn.select2.amd.define("UnsearchableDropdown",["select2/utils","select2/dropdown","select2/dropdown/attachBody","select2/dropdown/closeOnSelect"],function(e,t,n,l){n=e.Decorate(t,n);return n=e.Decorate(n,l)}),select2_amd.define("jquery.select2_",["jquery","jquery-mousewheel","./select2/core","./select2/defaults","./select2/utils"],function(s,e,c,t,o){var r;return null!=s.fn.select2&&(r=["open","close","destroy"],s.fn.select2=function(l){if((l=l||{}).selectionAdapter=!1!==l.selectionAdapter?select2_amd.require("SearchableSingleSelection"):void 0,l.dropdownAdapter=!1!==l.dropdownAdapter?select2_amd.require("UnsearchableDropdown"):void 0,"object"==typeof l)return this.each(function(){var e=s.extend(!0,{},l),t=new c(s(this),e),n=s(this).next().find(".select2-search.select2-search--dropdown"),e=s(this).next().find("span.selection").find(".select2-selection__arrow").clone();s(e).click(function(){t.close()}),e.appendTo(n)}),this;if("string"!=typeof l)throw new Error("Invalid arguments for Select2: "+l);var t,n=Array.prototype.slice.call(arguments,1);return this.each(function(){var e=o.GetData(this,"select2");null==e&&window.console&&console.error&&console.error("The select2('"+l+"') method was called on an element that is not using Select2."),t=e[l].apply(e,n)}),-1g&&(g=d.length),d.substring(c,g)):t}function m(){var c=p("windowID");c&&(a.Asc.plugin.windowID=c,
+a.Asc.plugin.guid||(a.Asc.plugin.guid=decodeURIComponent(p("guid"))));return t!==c?!0:!1}function q(c){if(a.Asc&&a.Asc.plugin)if(a.plugin_onMessage)a.Asc.supportOrigins[c.origin]&&a.plugin_onMessage(c);else if(a.Asc.plugin._initInternal&&"string"==typeof c.data){var d={};try{d=JSON.parse(c.data)}catch(g){d={}}"plugin_init"==d.type&&(a.Asc.supportOrigins[c.origin]=!0,a.Asc.plugin.ie_channel_check(c),eval(d.data))}}a.Asc=a.Asc||{};a.Asc.plugin={};a.Asc.plugin.ie_channel=null;a.Asc.plugin.ie_channel_check=
+function(c){var d=navigator.userAgent.toLowerCase();(-1 {
+ setPasswordError('');
+ setPasswordSuccess(false);
+
+ // Validation
+ if (!currentPassword) {
+ setPasswordError('Current password is required');
+ throw new Error('Validation failed');
+ }
+
+ if (!newPassword) {
+ setPasswordError('New password is required');
+ throw new Error('Validation failed');
+ }
+
+ if (newPassword.length > 128) {
+ setPasswordError('Password must not exceed 128 characters');
+ throw new Error('Validation failed');
+ }
+
+ if (newPassword !== confirmPassword) {
+ setPasswordError('New passwords do not match');
+ throw new Error('Validation failed');
+ }
+
+ try {
+ await changePassword({currentPassword, newPassword});
+ setPasswordSuccess(true);
+ setCurrentPassword('');
+ setNewPassword('');
+ setConfirmPassword('');
+ } catch (error) {
+ setPasswordError(error.message || 'Failed to change password');
+ throw error;
+ }
+ };
+
+ return (
+
+
Change Password
+
Update your admin panel password
+
+
+
+ );
+}
+
+export default ChangePassword;
diff --git a/AdminPanel/client/src/pages/ChangePassword/ChangePassword.module.scss b/AdminPanel/client/src/pages/ChangePassword/ChangePassword.module.scss
new file mode 100644
index 0000000000..ab9551c5f1
--- /dev/null
+++ b/AdminPanel/client/src/pages/ChangePassword/ChangePassword.module.scss
@@ -0,0 +1,119 @@
+.content {
+ margin-top: 20px;
+}
+
+.section {
+ background: white;
+ padding: 32px;
+ border-radius: 8px;
+ border: 1px solid #e0e0e0;
+}
+
+.sectionHeader {
+ margin-bottom: 24px;
+}
+
+.sectionTitle {
+ font-size: 18px;
+ font-weight: 600;
+ color: #333;
+ margin: 0 0 8px 0;
+}
+
+.sectionDescription {
+ font-size: 14px;
+ color: #666;
+ margin: 0;
+}
+
+.form {
+ display: flex;
+ flex-direction: column;
+ gap: 20px;
+ max-width: 500px;
+}
+
+.successMessage {
+ background: #d4edda;
+ border: 1px solid #c3e6cb;
+ border-radius: 4px;
+ color: #155724;
+ padding: 12px 16px;
+ margin-bottom: 20px;
+ font-size: 14px;
+}
+
+.errorMessage {
+ background: #f8d7da;
+ border: 1px solid #f5c6cb;
+ border-radius: 4px;
+ color: #721c24;
+ padding: 12px 16px;
+ margin-bottom: 20px;
+ font-size: 14px;
+}
+
+.accountInfo {
+ margin-bottom: 32px;
+}
+
+.infoRow {
+ display: flex;
+ padding: 12px 0;
+ border-bottom: 1px solid #eee;
+}
+
+.infoRow:last-child {
+ border-bottom: none;
+}
+
+.infoLabel {
+ font-weight: 600;
+ color: #333;
+ min-width: 120px;
+}
+
+.infoValue {
+ color: #666;
+}
+
+.dangerZone {
+ border: 1px solid #dc3545;
+ border-radius: 4px;
+ padding: 20px;
+ background: #fff5f5;
+}
+
+.dangerTitle {
+ font-size: 16px;
+ font-weight: 600;
+ color: #dc3545;
+ margin: 0 0 8px 0;
+}
+
+.dangerDescription {
+ font-size: 14px;
+ color: #666;
+ margin: 0 0 16px 0;
+ line-height: 1.5;
+}
+
+.logoutButton {
+ background: #dc3545;
+ color: white;
+ border: none;
+ border-radius: 4px;
+ padding: 10px 20px;
+ font-size: 14px;
+ font-weight: 600;
+ cursor: pointer;
+ transition: background 0.2s;
+}
+
+.logoutButton:hover {
+ background: #c82333;
+}
+
+.logoutButton:active {
+ background: #bd2130;
+}
diff --git a/AdminPanel/client/src/pages/Example/Example.js b/AdminPanel/client/src/pages/Example/Example.js
new file mode 100644
index 0000000000..3ea8b636ae
--- /dev/null
+++ b/AdminPanel/client/src/pages/Example/Example.js
@@ -0,0 +1,115 @@
+import {useState, useEffect, useRef, useCallback} from 'react';
+import {generateDocServerToken} from '../../api';
+
+/**
+ * Preview page component with ONLYOFFICE Document Editor
+ * @param {Object} props - Component props
+ * @returns {JSX.Element} Preview component
+ */
+function Preview(props) {
+ const {user} = props;
+
+ const [editorConfig, setEditorConfig] = useState(null);
+ const editorRef = useRef(null);
+
+ /**
+ * Initialize the ONLYOFFICE editor
+ */
+ const initEditor = useCallback(async () => {
+ const userName = user?.email?.split('@')[0] || 'admin';
+
+ const document = {
+ fileType: 'docx',
+ key: '0' + Math.random(),
+ title: 'Example Document',
+ url: `${window.location.origin}/${window.location.pathname.split('/')[1].includes('example') ? '' : window.location.pathname.split('/')[1] + '/'}assets/sample.docx`,
+ permissions: {
+ edit: true,
+ review: true,
+ comment: true,
+ copy: true,
+ print: true,
+ chat: true,
+ fillForms: true
+ }
+ };
+
+ const editorConfig = {
+ user: {
+ id: userName,
+ name: userName
+ },
+ lang: navigator.language || navigator.userLanguage || 'en',
+ mode: 'edit'
+ };
+
+ try {
+ const config = {
+ document,
+ documentType: 'word',
+ editorConfig,
+ height: '100%',
+ width: '100%'
+ };
+ const {token} = await generateDocServerToken(config);
+ config.token = token;
+
+ if (
+ /Android|webOS|iPhone|iPad|iPod|BlackBerry|BB|PlayBook|IEMobile|Windows Phone|Kindle|Silk|Opera Mini|Macintosh/i.test(navigator.userAgent) &&
+ navigator.maxTouchPoints &&
+ navigator.maxTouchPoints > 1
+ ) {
+ config.type = 'mobile';
+ }
+
+ setEditorConfig(config);
+ } catch (error) {
+ console.error('Failed to load editor:', error);
+ }
+ }, [user]);
+
+ useEffect(() => {
+ // Load ONLYOFFICE API script
+ const script = document.createElement('script');
+ const url = process.env.REACT_APP_DOCSERVICE_URL
+ ? `${process.env.REACT_APP_DOCSERVICE_URL}/web-apps/apps/api/documents/api.js`
+ : '../web-apps/apps/api/documents/api.js';
+ script.src = url;
+ script.async = true;
+ script.onload = () => {
+ initEditor();
+ };
+ document.head.appendChild(script);
+
+ return () => {
+ // Cleanup
+ if (window.docEditor) {
+ try {
+ window.docEditor.destroyEditor();
+ } catch (e) {
+ console.warn('Editor cleanup error:', e);
+ }
+ }
+ window.DocsAPI = undefined;
+ document.head.removeChild(script);
+ };
+ }, [initEditor]);
+
+ useEffect(() => {
+ if (editorConfig && window.DocsAPI && editorRef.current) {
+ try {
+ window.docEditor = new window.DocsAPI.DocEditor('onlyoffice-editor', editorConfig);
+ } catch (error) {
+ console.error('Error initializing editor:', error);
+ }
+ }
+ }, [editorConfig]);
+
+ return (
+
+ );
+}
+
+export default Preview;
diff --git a/AdminPanel/client/src/pages/Expiration/Expiration.js b/AdminPanel/client/src/pages/Expiration/Expiration.js
new file mode 100644
index 0000000000..ec54e9be34
--- /dev/null
+++ b/AdminPanel/client/src/pages/Expiration/Expiration.js
@@ -0,0 +1,234 @@
+import {useState, useRef} from 'react';
+import {useSelector, useDispatch} from 'react-redux';
+import {saveConfig, selectConfig} from '../../store/slices/configSlice';
+import {getNestedValue} from '../../utils/getNestedValue';
+import {mergeNestedObjects} from '../../utils/mergeNestedObjects';
+import {useFieldValidation} from '../../hooks/useFieldValidation';
+import PageHeader from '../../components/PageHeader/PageHeader';
+import PageDescription from '../../components/PageDescription/PageDescription';
+import Tabs from '../../components/Tabs/Tabs';
+import Input from '../../components/Input/Input';
+import FixedSaveButton from '../../components/FixedSaveButton/FixedSaveButton';
+import styles from './Expiration.module.scss';
+
+const expirationTabs = [
+ {key: 'garbage-collection', label: 'Garbage Collection'},
+ {key: 'session-management', label: 'Session Management'}
+];
+
+function Expiration() {
+ const dispatch = useDispatch();
+ const config = useSelector(selectConfig);
+ const {validateField, getFieldError, hasValidationErrors, clearFieldError} = useFieldValidation();
+
+ const [activeTab, setActiveTab] = useState('garbage-collection');
+
+ // Local state for form fields
+ const [localSettings, setLocalSettings] = useState({
+ filesCron: '',
+ documentsCron: '',
+ files: '',
+ filesremovedatonce: '',
+ sessionidle: '',
+ sessionabsolute: ''
+ });
+ const [hasChanges, setHasChanges] = useState(false);
+ const hasInitialized = useRef(false);
+
+ // Configuration paths
+ const CONFIG_PATHS = {
+ filesCron: 'services.CoAuthoring.expire.filesCron',
+ documentsCron: 'services.CoAuthoring.expire.documentsCron',
+ files: 'services.CoAuthoring.expire.files',
+ filesremovedatonce: 'services.CoAuthoring.expire.filesremovedatonce',
+ sessionidle: 'services.CoAuthoring.expire.sessionidle',
+ sessionabsolute: 'services.CoAuthoring.expire.sessionabsolute'
+ };
+
+ // Reset state and errors to global config
+ const resetToGlobalConfig = () => {
+ if (config) {
+ const settings = {};
+ Object.keys(CONFIG_PATHS).forEach(key => {
+ const value = getNestedValue(config, CONFIG_PATHS[key], '');
+ settings[key] = value;
+ });
+ setLocalSettings(settings);
+ setHasChanges(false);
+ // Clear validation errors for all fields
+ Object.values(CONFIG_PATHS).forEach(path => {
+ clearFieldError(path);
+ });
+ }
+ };
+
+ // Handle tab change and reset state
+ const handleTabChange = newTab => {
+ setActiveTab(newTab);
+ resetToGlobalConfig();
+ };
+
+ // Initialize settings from config when component loads (only once)
+ if (config && !hasInitialized.current) {
+ resetToGlobalConfig();
+ hasInitialized.current = true;
+ }
+
+ // Handle field changes
+ const handleFieldChange = (field, value) => {
+ setLocalSettings(prev => ({
+ ...prev,
+ [field]: value
+ }));
+
+ // Validate fields with schema validation
+ if (value !== '' && CONFIG_PATHS[field]) {
+ let validationValue = value;
+
+ // Convert numeric fields to integers for validation
+ if (field === 'files' || field === 'filesremovedatonce') {
+ validationValue = parseInt(value);
+ if (!isNaN(validationValue)) {
+ validateField(CONFIG_PATHS[field], validationValue);
+ }
+ } else if (typeof value === 'string') {
+ validateField(CONFIG_PATHS[field], value);
+ }
+ }
+
+ // Check if there are changes
+ const hasFieldChanges = Object.keys(CONFIG_PATHS).some(key => {
+ const currentValue = key === field ? value : localSettings[key];
+ const originalFieldValue = getNestedValue(config, CONFIG_PATHS[key], '');
+ return currentValue.toString() !== originalFieldValue.toString();
+ });
+
+ setHasChanges(hasFieldChanges);
+ };
+
+ // Handle save
+ const handleSave = async () => {
+ if (!hasChanges) return;
+
+ // Create config update object
+ const configUpdate = {};
+ Object.keys(CONFIG_PATHS).forEach(key => {
+ const path = CONFIG_PATHS[key];
+ let value = localSettings[key];
+
+ // Convert numeric fields to integers
+ if (key === 'files' || key === 'filesremovedatonce') {
+ value = value ? parseInt(value) : 0;
+ }
+
+ configUpdate[path] = value;
+ });
+
+ const mergedConfig = mergeNestedObjects([configUpdate]);
+ await dispatch(saveConfig(mergedConfig)).unwrap();
+ setHasChanges(false);
+ };
+
+ // Render tab content
+ const renderTabContent = () => {
+ switch (activeTab) {
+ case 'garbage-collection':
+ return (
+
+ );
+ case 'session-management':
+ return (
+
+ );
+ default:
+ return null;
+ }
+ };
+
+ return (
+
+
Expiration Settings
+
Configure file cleanup schedules, session timeouts, and garbage collection settings
+
+
+ {renderTabContent()}
+
+
+
+ Save Changes
+
+
+ );
+}
+
+export default Expiration;
diff --git a/AdminPanel/client/src/pages/Expiration/Expiration.module.scss b/AdminPanel/client/src/pages/Expiration/Expiration.module.scss
new file mode 100644
index 0000000000..1c8d804218
--- /dev/null
+++ b/AdminPanel/client/src/pages/Expiration/Expiration.module.scss
@@ -0,0 +1,49 @@
+.loading {
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ height: 200px;
+ font-size: 16px;
+ color: #666;
+}
+
+.settingsSection {
+ margin-bottom: 32px;
+ padding: 24px;
+ background: #fff;
+ border-radius: 8px;
+ border: 1px solid #e0e0e0;
+}
+
+.sectionTitle {
+ font-size: 18px;
+ font-weight: 600;
+ color: #333;
+ margin-bottom: 20px;
+ padding-bottom: 8px;
+ border-bottom: 2px solid #f0f0f0;
+}
+
+.formRow {
+ margin-bottom: 24px;
+
+ &:last-child {
+ margin-bottom: 0;
+ }
+}
+
+.tabPanel {
+ padding: 32px;
+ background: #fff;
+ border-radius: 8px;
+ border: 1px solid #e0e0e0;
+}
+
+.actions {
+ display: flex;
+ justify-content: flex-start;
+}
+
+.pageWithFixedSave {
+ padding-bottom: 40px;
+}
diff --git a/AdminPanel/client/src/pages/FileLimits/FileLimits.js b/AdminPanel/client/src/pages/FileLimits/FileLimits.js
new file mode 100644
index 0000000000..7c4fb525d4
--- /dev/null
+++ b/AdminPanel/client/src/pages/FileLimits/FileLimits.js
@@ -0,0 +1,240 @@
+import {useState, useEffect} from 'react';
+import {useSelector, useDispatch} from 'react-redux';
+import {saveConfig, selectConfig} from '../../store/slices/configSlice';
+import {getNestedValue} from '../../utils/getNestedValue';
+import {mergeNestedObjects} from '../../utils/mergeNestedObjects';
+import {useFieldValidation} from '../../hooks/useFieldValidation';
+import PageHeader from '../../components/PageHeader/PageHeader';
+import PageDescription from '../../components/PageDescription/PageDescription';
+import Input from '../../components/Input/Input';
+import FixedSaveButton from '../../components/FixedSaveButton/FixedSaveButton';
+import styles from './FileLimits.module.scss';
+
+function FileLimits() {
+ const dispatch = useDispatch();
+ const config = useSelector(selectConfig);
+ const {validateField, getFieldError, hasValidationErrors} = useFieldValidation();
+
+ // Local state for form fields
+ const [localSettings, setLocalSettings] = useState({
+ maxDownloadBytes: '',
+ docxUncompressed: '',
+ xlsxUncompressed: '',
+ pptxUncompressed: '',
+ vsdxUncompressed: ''
+ });
+ const [hasChanges, setHasChanges] = useState(false);
+
+ // Configuration paths
+ const CONFIG_PATHS = {
+ maxDownloadBytes: 'FileConverter.converter.maxDownloadBytes',
+ docxUncompressed: 'FileConverter.converter.inputLimits.0.zip.uncompressed',
+ xlsxUncompressed: 'FileConverter.converter.inputLimits.1.zip.uncompressed',
+ pptxUncompressed: 'FileConverter.converter.inputLimits.2.zip.uncompressed',
+ vsdxUncompressed: 'FileConverter.converter.inputLimits.3.zip.uncompressed'
+ };
+
+ // Load config data when component mounts
+ useEffect(() => {
+ if (config) {
+ const settings = {};
+
+ // Get max download bytes
+ settings.maxDownloadBytes = getNestedValue(config, 'FileConverter.converter.maxDownloadBytes', '');
+
+ // Get input limits - need to handle array structure
+ const inputLimits = getNestedValue(config, 'FileConverter.converter.inputLimits', []);
+
+ // Find limits by document type
+ const docxLimit = inputLimits.find(limit => limit.type && limit.type.includes('docx'));
+ const xlsxLimit = inputLimits.find(limit => limit.type && limit.type.includes('xlsx'));
+ const pptxLimit = inputLimits.find(limit => limit.type && limit.type.includes('pptx'));
+ const vsdxLimit = inputLimits.find(limit => limit.type && limit.type.includes('vsdx'));
+
+ settings.docxUncompressed = docxLimit?.zip?.uncompressed || '';
+ settings.xlsxUncompressed = xlsxLimit?.zip?.uncompressed || '';
+ settings.pptxUncompressed = pptxLimit?.zip?.uncompressed || '';
+ settings.vsdxUncompressed = vsdxLimit?.zip?.uncompressed || '';
+
+ setLocalSettings(settings);
+ setHasChanges(false);
+ }
+ }, [dispatch, config]);
+
+ // Handle field changes
+ const handleFieldChange = (field, value) => {
+ setLocalSettings(prev => ({
+ ...prev,
+ [field]: value
+ }));
+
+ // Validate the field if it's maxDownloadBytes (has schema validation)
+ if (field === 'maxDownloadBytes' && value !== '') {
+ const numericValue = parseInt(value);
+ if (!isNaN(numericValue)) {
+ validateField(CONFIG_PATHS.maxDownloadBytes, numericValue);
+ }
+ }
+
+ // Check if there are changes
+ const hasFieldChanges = Object.keys(localSettings).some(key => {
+ const currentValue = key === field ? value : localSettings[key];
+ let originalValue;
+
+ if (key === 'maxDownloadBytes') {
+ originalValue = getNestedValue(config, 'FileConverter.converter.maxDownloadBytes', '');
+ } else {
+ // Handle input limits array structure for comparison
+ const inputLimits = getNestedValue(config, 'FileConverter.converter.inputLimits', []);
+ if (key === 'docxUncompressed') {
+ const docxLimit = inputLimits.find(limit => limit.type && limit.type.includes('docx'));
+ originalValue = docxLimit?.zip?.uncompressed || '';
+ } else if (key === 'xlsxUncompressed') {
+ const xlsxLimit = inputLimits.find(limit => limit.type && limit.type.includes('xlsx'));
+ originalValue = xlsxLimit?.zip?.uncompressed || '';
+ } else if (key === 'pptxUncompressed') {
+ const pptxLimit = inputLimits.find(limit => limit.type && limit.type.includes('pptx'));
+ originalValue = pptxLimit?.zip?.uncompressed || '';
+ } else if (key === 'vsdxUncompressed') {
+ const vsdxLimit = inputLimits.find(limit => limit.type && limit.type.includes('vsdx'));
+ originalValue = vsdxLimit?.zip?.uncompressed || '';
+ }
+ }
+
+ return currentValue.toString() !== originalValue.toString();
+ });
+
+ setHasChanges(hasFieldChanges);
+ };
+
+ // Handle save
+ const handleSave = async () => {
+ if (!hasChanges) return;
+
+ // Create config update object
+ const configUpdate = {};
+
+ // Set max download bytes
+ configUpdate['FileConverter.converter.maxDownloadBytes'] = parseInt(localSettings.maxDownloadBytes);
+
+ // Update input limits - we need to preserve the existing structure
+ const currentInputLimits = getNestedValue(config, 'FileConverter.converter.inputLimits', []);
+ const updatedInputLimits = currentInputLimits.map(limit => {
+ if (limit.type && limit.type.includes('docx')) {
+ return {
+ ...limit,
+ zip: {
+ ...limit.zip,
+ uncompressed: localSettings.docxUncompressed
+ }
+ };
+ } else if (limit.type && limit.type.includes('xlsx')) {
+ return {
+ ...limit,
+ zip: {
+ ...limit.zip,
+ uncompressed: localSettings.xlsxUncompressed
+ }
+ };
+ } else if (limit.type && limit.type.includes('pptx')) {
+ return {
+ ...limit,
+ zip: {
+ ...limit.zip,
+ uncompressed: localSettings.pptxUncompressed
+ }
+ };
+ } else if (limit.type && limit.type.includes('vsdx')) {
+ return {
+ ...limit,
+ zip: {
+ ...limit.zip,
+ uncompressed: localSettings.vsdxUncompressed
+ }
+ };
+ }
+ return limit;
+ });
+
+ configUpdate['FileConverter.converter.inputLimits'] = updatedInputLimits;
+
+ const mergedConfig = mergeNestedObjects([configUpdate]);
+ await dispatch(saveConfig(mergedConfig)).unwrap();
+ setHasChanges(false);
+ };
+
+ return (
+
+
File Size Limits
+
Configure maximum file sizes and download limits for document processing
+
+
+
Download Limits
+
+
+ handleFieldChange('maxDownloadBytes', value)}
+ placeholder='104857600'
+ description='Maximum number of bytes that can be downloaded (e.g., 104857600 = 100MB)'
+ min='0'
+ error={getFieldError(CONFIG_PATHS.maxDownloadBytes)}
+ />
+
+
+
+
+
Input File Size Limits
+
Configure uncompressed size limits for different document types when processing ZIP archives
+
+
+ handleFieldChange('docxUncompressed', value)}
+ placeholder='50MB'
+ description='Maximum uncompressed size for Word document archives'
+ />
+
+
+
+ handleFieldChange('xlsxUncompressed', value)}
+ placeholder='300MB'
+ description='Maximum uncompressed size for Excel document archives'
+ />
+
+
+
+ handleFieldChange('pptxUncompressed', value)}
+ placeholder='50MB'
+ description='Maximum uncompressed size for PowerPoint document archives'
+ />
+
+
+
+ handleFieldChange('vsdxUncompressed', value)}
+ placeholder='50MB'
+ description='Maximum uncompressed size for Visio document archives'
+ />
+
+
+
+
+ Save Changes
+
+
+ );
+}
+
+export default FileLimits;
diff --git a/AdminPanel/client/src/pages/FileLimits/FileLimits.module.scss b/AdminPanel/client/src/pages/FileLimits/FileLimits.module.scss
new file mode 100644
index 0000000000..69380bd53c
--- /dev/null
+++ b/AdminPanel/client/src/pages/FileLimits/FileLimits.module.scss
@@ -0,0 +1,49 @@
+.loading {
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ height: 200px;
+ font-size: 16px;
+ color: #666;
+}
+
+.settingsSection {
+ margin-bottom: 32px;
+ padding: 32px;
+ background: #fff;
+ border-radius: 8px;
+ border: 1px solid #e0e0e0;
+}
+
+.sectionTitle {
+ font-size: 18px;
+ font-weight: 600;
+ color: #333;
+ margin-bottom: 20px;
+ padding-bottom: 8px;
+ border-bottom: 2px solid #f0f0f0;
+}
+
+.sectionDescription {
+ font-size: 14px;
+ color: #666;
+ margin-bottom: 20px;
+ line-height: 1.5;
+}
+
+.formRow {
+ margin-bottom: 24px;
+
+ &:last-child {
+ margin-bottom: 0;
+ }
+}
+
+.actions {
+ display: flex;
+ justify-content: flex-start;
+}
+
+.pageWithFixedSave {
+ padding-bottom: 40px;
+}
diff --git a/AdminPanel/client/src/pages/Forgotten/Forgotten.js b/AdminPanel/client/src/pages/Forgotten/Forgotten.js
new file mode 100644
index 0000000000..84b7ca405d
--- /dev/null
+++ b/AdminPanel/client/src/pages/Forgotten/Forgotten.js
@@ -0,0 +1,110 @@
+import {useState, useEffect} from 'react';
+import {getForgottenList, getForgotten} from '../../api';
+import DownloadIcon from '../../assets/Download.svg';
+import styles from './Forgotten.module.scss';
+
+const Forgotten = () => {
+ const [forgottenFiles, setForgottenFiles] = useState([]);
+ const [error, setError] = useState(null);
+ const [downloadingFiles, setDownloadingFiles] = useState(new Set());
+
+ const loadForgottenFiles = async () => {
+ try {
+ setError(null);
+ const files = await getForgottenList();
+ setForgottenFiles(files);
+ } catch (err) {
+ console.error('Error loading forgotten files:', err);
+ setError(`Failed to load forgotten files: ${err.message}`);
+ }
+ };
+
+ useEffect(() => {
+ loadForgottenFiles();
+ }, []);
+
+ const handleDownload = async file => {
+ try {
+ console.log('Downloading file:', file.name);
+
+ setDownloadingFiles(prev => new Set(prev).add(file.key));
+
+ const result = await getForgotten(file.key);
+
+ if (result.url) {
+ const link = document.createElement('a');
+ link.href = result.url;
+ document.body.appendChild(link);
+ link.click();
+ document.body.removeChild(link);
+ } else if (result.error) {
+ console.error('Backend error for file:', file.name, 'Error code:', result.error);
+ setError(`Failed to download ${file.name}: Backend error ${result.error}`);
+ } else {
+ console.error('No download URL received for file:', file.name);
+ setError(`Failed to get download URL for ${file.name}`);
+ }
+ } catch (err) {
+ console.error('Error downloading file:', err);
+ setError(`Failed to download ${file.name}: ${err.message}`);
+ } finally {
+ setDownloadingFiles(prev => {
+ const newSet = new Set(prev);
+ newSet.delete(file.key);
+ return newSet;
+ });
+ }
+ };
+
+ if (error) {
+ return (
+
+
+
Forgotten Files
+
+ Failed to load forgotten files
+
+ );
+ }
+
+ return (
+
+
+
Forgotten Files
+
+
+
+ {forgottenFiles.length === 0 ? (
+
+
No forgotten files found.
+
+ ) : (
+
+ {forgottenFiles.map((file, index) => (
+
+
+ {file.name}
+
+
handleDownload(file)}
+ disabled={downloadingFiles.has(file.key)}
+ title='Download file'
+ >
+
+
+
+ ))}
+
+ )}
+
+
+ );
+};
+
+export default Forgotten;
diff --git a/AdminPanel/client/src/pages/Forgotten/Forgotten.module.scss b/AdminPanel/client/src/pages/Forgotten/Forgotten.module.scss
new file mode 100644
index 0000000000..69649d3283
--- /dev/null
+++ b/AdminPanel/client/src/pages/Forgotten/Forgotten.module.scss
@@ -0,0 +1,168 @@
+.forgottenPage {
+ margin: 0 auto;
+
+ .pageHeader {
+ margin-bottom: 32px;
+
+ h1 {
+ margin: 0;
+ color: #333;
+ font-size: 28px;
+ font-weight: 600;
+ }
+ }
+
+ .loading {
+ text-align: center;
+ padding: 60px 20px;
+
+ .spinner {
+ width: 40px;
+ height: 40px;
+ border: 4px solid #f3f3f3;
+ border-top: 4px solid #007bff;
+ border-radius: 50%;
+ animation: spin 1s linear infinite;
+ margin: 0 auto 20px;
+ }
+
+ p {
+ color: #666;
+ font-size: 16px;
+ }
+ }
+
+ .error {
+ text-align: center;
+ padding: 60px 20px;
+ background: #f8f9fa;
+ border-radius: 8px;
+ border: 1px solid #e9ecef;
+
+ p {
+ color: #dc3545;
+ font-size: 16px;
+ margin-bottom: 20px;
+ }
+
+ .retryBtn {
+ background: #dc3545;
+ color: white;
+ border: none;
+ padding: 10px 20px;
+ border-radius: 4px;
+ cursor: pointer;
+ font-size: 14px;
+ transition: background-color 0.2s;
+
+ &:hover {
+ background: #c82333;
+ }
+ }
+ }
+
+ .emptyState {
+ text-align: center;
+ padding: 60px 20px;
+ background: #f8f9fa;
+ border-radius: 8px;
+ border: 1px solid #e9ecef;
+
+ p {
+ color: #666;
+ font-size: 16px;
+ margin: 0;
+ }
+ }
+
+ .filesList {
+ .fileRow {
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+ padding: 2px 0;
+ border-bottom: 1px solid rgb(226, 226, 226);
+
+ &:last-child {
+ border-bottom: none;
+ }
+
+ .fileName {
+ font-size: 12px;
+ font-weight: 400;
+ color: #333;
+ overflow: hidden;
+ text-overflow: ellipsis;
+ white-space: nowrap;
+ flex: 1;
+ margin-right: 16px;
+ }
+
+ .downloadBtn {
+ background: none;
+ border: none;
+ cursor: pointer;
+ padding: 0;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+
+ &:hover {
+ opacity: 0.7;
+ }
+
+ &:disabled {
+ cursor: not-allowed;
+ }
+
+ .downloadIcon {
+ width: 24px;
+ height: 24px;
+ }
+ }
+ }
+ }
+}
+
+@keyframes spin {
+ 0% {
+ transform: rotate(0deg);
+ }
+ 100% {
+ transform: rotate(360deg);
+ }
+}
+
+// Responsive design
+@media (max-width: 768px) {
+ .forgottenPage {
+ // padding: 15px;
+
+ .pageHeader {
+ flex-direction: column;
+ gap: 15px;
+ align-items: flex-start;
+
+ h1 {
+ font-size: 24px;
+ }
+ }
+
+ .filesList {
+ .fileRow {
+ flex-direction: column;
+ align-items: flex-start;
+ gap: 12px;
+
+ .fileName {
+ margin-right: 0;
+ margin-bottom: 8px;
+ }
+
+ .downloadBtn {
+ align-self: flex-end;
+ }
+ }
+ }
+ }
+}
diff --git a/AdminPanel/client/src/pages/HealthCheck/HealthCheck.js b/AdminPanel/client/src/pages/HealthCheck/HealthCheck.js
new file mode 100644
index 0000000000..755886be5a
--- /dev/null
+++ b/AdminPanel/client/src/pages/HealthCheck/HealthCheck.js
@@ -0,0 +1,70 @@
+import {useState, useEffect} from 'react';
+import {checkHealth} from '../../api';
+import PageHeader from '../../components/PageHeader/PageHeader';
+import PageDescription from '../../components/PageDescription/PageDescription';
+import FixedSaveButton from '../../components/FixedSaveButton/FixedSaveButton';
+import styles from './HealthCheck.module.scss';
+
+function HealthCheck() {
+ const [healthStatus, setHealthStatus] = useState(null);
+ const [loading, setLoading] = useState(true);
+ const [error, setError] = useState(null);
+
+ const fetchHealthStatus = async () => {
+ try {
+ setLoading(true);
+ setError(null);
+ const status = await checkHealth();
+ setHealthStatus(status);
+ } catch (err) {
+ setError(err.message);
+ setHealthStatus(null);
+ } finally {
+ setLoading(false);
+ }
+ };
+
+ useEffect(() => {
+ fetchHealthStatus();
+ }, []);
+
+ const getStatusColor = () => {
+ if (loading) return '#666';
+ if (error) return '#dc3545';
+ return '#28a745';
+ };
+
+ return (
+
+
Health Check
+
Monitor the status of DocService backend
+
+
+
+
+
+ {error && (
+
+
{error}
+
+ )}
+
+ {healthStatus && (
+
+
Service is healthy
+
+ )}
+
+
+
+
+ {loading ? 'Checking...' : 'Refresh'}
+
+
+ );
+}
+
+export default HealthCheck;
diff --git a/AdminPanel/client/src/pages/HealthCheck/HealthCheck.module.scss b/AdminPanel/client/src/pages/HealthCheck/HealthCheck.module.scss
new file mode 100644
index 0000000000..551b3bf677
--- /dev/null
+++ b/AdminPanel/client/src/pages/HealthCheck/HealthCheck.module.scss
@@ -0,0 +1,97 @@
+.healthCheck {
+ padding: 0;
+}
+
+.pageWithFixedSave {
+ padding-bottom: 40px;
+}
+
+.statusCard {
+ background: white;
+ border: 1px solid #e2e2e2;
+ border-radius: 8px;
+ padding: 32px;
+ margin-bottom: 32px;
+}
+
+.statusHeader {
+ display: flex;
+ align-items: center;
+ margin-bottom: 24px;
+ gap: 12px;
+}
+
+.statusIndicator {
+ width: 12px;
+ height: 12px;
+ border-radius: 50%;
+ flex-shrink: 0;
+}
+
+.statusTitle {
+ font-size: 18px;
+ font-weight: 600;
+ color: #333;
+ margin: 0;
+ flex-grow: 1;
+}
+
+.loading {
+ display: flex;
+ align-items: center;
+ gap: 12px;
+ color: #666;
+}
+
+.spinner {
+ width: 20px;
+ height: 20px;
+ border: 2px solid #f3f3f3;
+ border-top: 2px solid #007bff;
+ border-radius: 50%;
+ animation: spin 1s linear infinite;
+}
+
+@keyframes spin {
+ 0% {
+ transform: rotate(0deg);
+ }
+ 100% {
+ transform: rotate(360deg);
+ }
+}
+
+.error {
+ color: #dc3545;
+
+ h4 {
+ margin: 0;
+ font-size: 16px;
+ }
+}
+
+.success {
+ color: #28a745;
+
+ h4 {
+ margin: 0;
+ font-size: 16px;
+ }
+}
+
+.statusDetails {
+ background: #f8f9fa;
+ border: 1px solid #e9ecef;
+ border-radius: 4px;
+ padding: 16px;
+ overflow-x: auto;
+
+ pre {
+ margin: 0;
+ font-family: 'Courier New', monospace;
+ font-size: 12px;
+ color: #333;
+ white-space: pre-wrap;
+ word-break: break-all;
+ }
+}
diff --git a/AdminPanel/client/src/pages/LoggerConfig/LoggerConfig.js b/AdminPanel/client/src/pages/LoggerConfig/LoggerConfig.js
new file mode 100644
index 0000000000..164a7ea6c6
--- /dev/null
+++ b/AdminPanel/client/src/pages/LoggerConfig/LoggerConfig.js
@@ -0,0 +1,130 @@
+import {useState, useRef} from 'react';
+import {useSelector, useDispatch} from 'react-redux';
+import {saveConfig, selectConfig} from '../../store/slices/configSlice';
+import {getNestedValue} from '../../utils/getNestedValue';
+import {mergeNestedObjects} from '../../utils/mergeNestedObjects';
+import {useFieldValidation} from '../../hooks/useFieldValidation';
+import PageHeader from '../../components/PageHeader/PageHeader';
+import PageDescription from '../../components/PageDescription/PageDescription';
+import Select from '../../components/Select/Select';
+import FixedSaveButton from '../../components/FixedSaveButton/FixedSaveButton';
+import styles from './LoggerConfig.module.scss';
+
+const LOG_LEVELS = [
+ {value: 'ALL', label: 'ALL - All log messages'},
+ {value: 'TRACE', label: 'TRACE - Trace level messages'},
+ {value: 'DEBUG', label: 'DEBUG - Debug level messages'},
+ {value: 'INFO', label: 'INFO - Information level messages'},
+ {value: 'WARN', label: 'WARN - Warning level messages'},
+ {value: 'ERROR', label: 'ERROR - Error level messages'},
+ {value: 'FATAL', label: 'FATAL - Fatal level messages'},
+ {value: 'OFF', label: 'OFF - No log messages'}
+];
+
+function LoggerConfig() {
+ const dispatch = useDispatch();
+ const config = useSelector(selectConfig);
+ const {validateField, getFieldError, hasValidationErrors, clearFieldError} = useFieldValidation();
+
+ // Local state for form fields
+ const [localSettings, setLocalSettings] = useState({
+ logLevel: 'INFO'
+ });
+ const [hasChanges, setHasChanges] = useState(false);
+ const hasInitialized = useRef(false);
+
+ // Configuration paths
+ const CONFIG_PATHS = {
+ logLevel: 'log.options.categories.default.level'
+ };
+
+ // Reset state and errors to global config
+ const resetToGlobalConfig = () => {
+ if (config) {
+ const settings = {
+ logLevel: getNestedValue(config, CONFIG_PATHS.logLevel, 'INFO')
+ };
+ setLocalSettings(settings);
+ setHasChanges(false);
+ // Clear validation errors for all fields
+ Object.values(CONFIG_PATHS).forEach(path => {
+ clearFieldError(path);
+ });
+ }
+ };
+
+ // Initialize settings from config when component loads (only once)
+ if (config && !hasInitialized.current) {
+ resetToGlobalConfig();
+ hasInitialized.current = true;
+ }
+
+ // Handle field changes
+ const handleFieldChange = (field, value) => {
+ setLocalSettings(prev => ({
+ ...prev,
+ [field]: value
+ }));
+
+ // Validate fields with schema validation
+ if (CONFIG_PATHS[field]) {
+ validateField(CONFIG_PATHS[field], value);
+ }
+
+ // Check if there are changes
+ const hasFieldChanges = Object.keys(CONFIG_PATHS).some(key => {
+ const currentValue = key === field ? value : localSettings[key];
+ const originalFieldValue = getNestedValue(config, CONFIG_PATHS[key], 'INFO');
+
+ return currentValue.toString() !== originalFieldValue.toString();
+ });
+
+ setHasChanges(hasFieldChanges);
+ };
+
+ // Handle save
+ const handleSave = async () => {
+ if (!hasChanges) return;
+
+ // Create config update object
+ const configUpdate = {};
+ Object.keys(CONFIG_PATHS).forEach(key => {
+ const path = CONFIG_PATHS[key];
+ const value = localSettings[key];
+ configUpdate[path] = value;
+ });
+
+ const mergedConfig = mergeNestedObjects([configUpdate]);
+ await dispatch(saveConfig(mergedConfig)).unwrap();
+ setHasChanges(false);
+ };
+
+ return (
+
+
Logger Configuration
+
Configure the logging level for the application
+
+
+
+
+
Log Level:
+
handleFieldChange('logLevel', value)}
+ options={LOG_LEVELS}
+ placeholder='Select log level'
+ />
+ Select the minimum log level to capture. Messages below this level will be filtered out.
+ {getFieldError(CONFIG_PATHS.logLevel) && {getFieldError(CONFIG_PATHS.logLevel)}
}
+
+
+
+
+
+ Save Changes
+
+
+ );
+}
+
+export default LoggerConfig;
diff --git a/AdminPanel/client/src/pages/LoggerConfig/LoggerConfig.module.scss b/AdminPanel/client/src/pages/LoggerConfig/LoggerConfig.module.scss
new file mode 100644
index 0000000000..9cfd0503c8
--- /dev/null
+++ b/AdminPanel/client/src/pages/LoggerConfig/LoggerConfig.module.scss
@@ -0,0 +1,46 @@
+.loggerConfig {
+ margin: 0 auto;
+}
+
+.configSection {
+ background: white;
+ border-radius: 8px;
+ padding: 32px;
+ border: 1px solid #e0e0e0;
+ margin-bottom: 24px;
+}
+
+.formRow {
+ margin-bottom: 24px;
+
+ &:last-child {
+ margin-bottom: 0;
+ }
+}
+
+.fieldGroup {
+ display: flex;
+ flex-direction: column;
+ gap: 8px;
+ max-width: 500px;
+}
+
+.label {
+ font-weight: 600;
+ color: #333;
+ font-size: 14px;
+ margin-bottom: 4px;
+}
+
+.description {
+ color: #666;
+ font-size: 13px;
+ line-height: 1.4;
+ margin-top: 4px;
+}
+
+.error {
+ color: #dc3545;
+ font-size: 12px;
+ margin-top: 4px;
+}
diff --git a/AdminPanel/client/src/pages/Login/LoginPage.js b/AdminPanel/client/src/pages/Login/LoginPage.js
new file mode 100644
index 0000000000..6a49417d0f
--- /dev/null
+++ b/AdminPanel/client/src/pages/Login/LoginPage.js
@@ -0,0 +1,64 @@
+import {useState, useRef} from 'react';
+import {useDispatch} from 'react-redux';
+import {fetchUser} from '../../store/slices/userSlice';
+import {login} from '../../api';
+import Input from '../../components/LoginInput';
+import Button from '../../components/LoginButton';
+import styles from './styles.module.css';
+
+export default function Login() {
+ const [password, setPassword] = useState('');
+ const [error, setError] = useState('');
+ const dispatch = useDispatch();
+ const buttonRef = useRef();
+
+ const handleSubmit = async () => {
+ setError('');
+
+ try {
+ await login(password);
+ // Wait for cookie to be set and verify authentication works
+ await dispatch(fetchUser()).unwrap();
+ // AuthWrapper will automatically redirect based on isAuthenticated
+ } catch (error) {
+ setError(error.message || 'Invalid password. Please try again.');
+ throw error;
+ }
+ };
+
+ const handleKeyDown = e => {
+ if (e.key === 'Enter') {
+ if (buttonRef.current) {
+ buttonRef.current.click();
+ }
+ }
+ };
+
+ return (
+
+
+
ONLYOFFICE Admin Panel
+
Enter your password to access the admin panel
+
The session is valid for 60 minutes.
+
+
+
+
+ );
+}
diff --git a/AdminPanel/client/src/pages/Login/styles.module.css b/AdminPanel/client/src/pages/Login/styles.module.css
new file mode 100644
index 0000000000..d6c74a0936
--- /dev/null
+++ b/AdminPanel/client/src/pages/Login/styles.module.css
@@ -0,0 +1,65 @@
+.loginContainer {
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ min-height: calc(100vh - 60px); /* Account for header height */
+ background: white;
+ padding: 20px;
+ width: 100%;
+}
+
+.loginCard {
+ background: white;
+ width: 100%;
+ max-width: 500px;
+ text-align: center;
+}
+
+.title {
+ color: #333;
+ font-size: 32px;
+ font-weight: bold;
+ margin: 0 0 16px 0;
+ font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
+}
+
+.subtitle {
+ color: #333;
+ font-size: 16px;
+ font-weight: bold;
+ margin: 0 0 16px 0;
+ font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
+}
+
+.description {
+ color: #333;
+ font-size: 14px;
+ margin: 0 0 32px 0;
+ line-height: 1.5;
+ font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
+}
+
+.form {
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ gap: 20px;
+}
+
+.inputGroup {
+ width: 100%;
+ max-width: 300px;
+}
+
+.errorMessage {
+ background: #fee;
+ border: 1px solid #fcc;
+ border-radius: 4px;
+ color: #c33;
+ padding: 12px 16px;
+ margin: 0 0 20px 0;
+ font-size: 14px;
+ text-align: center;
+ max-width: 400px;
+ width: 100%;
+}
diff --git a/AdminPanel/client/src/pages/NotitifcationConfig/NotificationConfig.js b/AdminPanel/client/src/pages/NotitifcationConfig/NotificationConfig.js
new file mode 100644
index 0000000000..f0769953ae
--- /dev/null
+++ b/AdminPanel/client/src/pages/NotitifcationConfig/NotificationConfig.js
@@ -0,0 +1,357 @@
+import {useState, useRef} from 'react';
+import {useSelector, useDispatch} from 'react-redux';
+import {saveConfig, selectConfig} from '../../store/slices/configSlice';
+import {getNestedValue} from '../../utils/getNestedValue';
+import {mergeNestedObjects} from '../../utils/mergeNestedObjects';
+import {useFieldValidation} from '../../hooks/useFieldValidation';
+import PageHeader from '../../components/PageHeader/PageHeader';
+import PageDescription from '../../components/PageDescription/PageDescription';
+import Tabs from '../../components/Tabs/Tabs';
+import Input from '../../components/Input/Input';
+import Checkbox from '../../components/Checkbox/Checkbox';
+import FixedSaveButton from '../../components/FixedSaveButton/FixedSaveButton';
+import styles from './NotificationConfig.module.scss';
+
+const emailConfigTabs = [
+ {key: 'notifications', label: 'Notification Rules'},
+ {key: 'smtp-server', label: 'SMTP Server'},
+ {key: 'defaults', label: 'Default Emails'}
+];
+
+function EmailConfig() {
+ const dispatch = useDispatch();
+ const config = useSelector(selectConfig);
+ const {validateField, getFieldError, hasValidationErrors, clearFieldError} = useFieldValidation();
+
+ const [activeTab, setActiveTab] = useState('notifications');
+
+ // Local state for form fields
+ const [localSettings, setLocalSettings] = useState({
+ smtpHost: '',
+ smtpPort: '',
+ smtpUsername: '',
+ smtpPassword: '',
+ defaultFromEmail: '',
+ defaultToEmail: '',
+ licenseExpirationWarningEnable: false,
+ licenseExpirationWarningRepeatInterval: '',
+ licenseExpirationErrorEnable: false,
+ licenseExpirationErrorRepeatInterval: '',
+ licenseLimitEditEnable: false,
+ licenseLimitEditRepeatInterval: '',
+ licenseLimitLiveViewerEnable: false,
+ licenseLimitLiveViewerRepeatInterval: ''
+ });
+ const [hasChanges, setHasChanges] = useState(false);
+ const hasInitialized = useRef(false);
+
+ // Configuration paths
+ const CONFIG_PATHS = {
+ smtpHost: 'email.smtpServerConfiguration.host',
+ smtpPort: 'email.smtpServerConfiguration.port',
+ smtpUsername: 'email.smtpServerConfiguration.auth.user',
+ smtpPassword: 'email.smtpServerConfiguration.auth.pass',
+ defaultFromEmail: 'email.contactDefaults.from',
+ defaultToEmail: 'email.contactDefaults.to',
+ licenseExpirationWarningEnable: 'notification.rules.licenseExpirationWarning.enable',
+ licenseExpirationWarningRepeatInterval: 'notification.rules.licenseExpirationWarning.policies.repeatInterval',
+ licenseExpirationErrorEnable: 'notification.rules.licenseExpirationError.enable',
+ licenseExpirationErrorRepeatInterval: 'notification.rules.licenseExpirationError.policies.repeatInterval',
+ licenseLimitEditEnable: 'notification.rules.licenseLimitEdit.enable',
+ licenseLimitEditRepeatInterval: 'notification.rules.licenseLimitEdit.policies.repeatInterval',
+ licenseLimitLiveViewerEnable: 'notification.rules.licenseLimitLiveViewer.enable',
+ licenseLimitLiveViewerRepeatInterval: 'notification.rules.licenseLimitLiveViewer.policies.repeatInterval'
+ };
+
+ // Reset state and errors to global config
+ const resetToGlobalConfig = () => {
+ if (config) {
+ const settings = {};
+ Object.keys(CONFIG_PATHS).forEach(key => {
+ const value = getNestedValue(config, CONFIG_PATHS[key], '');
+ settings[key] = value;
+ });
+ setLocalSettings(settings);
+ setHasChanges(false);
+ // Clear validation errors for all fields
+ Object.values(CONFIG_PATHS).forEach(path => {
+ clearFieldError(path);
+ });
+ }
+ };
+
+ // Initialize settings from config when component loads (only once)
+ if (config && !hasInitialized.current) {
+ resetToGlobalConfig();
+ hasInitialized.current = true;
+ }
+
+ // Handle tab change and reset state
+ const handleTabChange = newTab => {
+ setActiveTab(newTab);
+ resetToGlobalConfig();
+ };
+
+ // Handle field changes
+ const handleFieldChange = (field, value) => {
+ setLocalSettings(prev => ({
+ ...prev,
+ [field]: value
+ }));
+
+ // Validate fields with schema validation
+ if (CONFIG_PATHS[field]) {
+ let validationValue = value;
+
+ // Convert port to integer for validation
+ if (field === 'smtpPort' && value !== '') {
+ validationValue = parseInt(value);
+ if (!isNaN(validationValue)) {
+ validateField(CONFIG_PATHS[field], validationValue);
+ }
+ } else if (typeof value === 'string') {
+ validateField(CONFIG_PATHS[field], value);
+ } else if (typeof value === 'boolean') {
+ validateField(CONFIG_PATHS[field], value);
+ }
+ }
+
+ // Check if there are changes
+ const hasFieldChanges = Object.keys(CONFIG_PATHS).some(key => {
+ const currentValue = key === field ? value : localSettings[key];
+ const originalFieldValue = getNestedValue(config, CONFIG_PATHS[key], '');
+
+ // Handle different data types properly
+ if (typeof originalFieldValue === 'boolean') {
+ return currentValue !== originalFieldValue;
+ }
+ return currentValue.toString() !== originalFieldValue.toString();
+ });
+
+ setHasChanges(hasFieldChanges);
+ };
+
+ // Handle save
+ const handleSave = async () => {
+ if (!hasChanges) return;
+
+ // Create config update object
+ const configUpdate = {};
+ Object.keys(CONFIG_PATHS).forEach(key => {
+ const path = CONFIG_PATHS[key];
+ let value = localSettings[key];
+
+ // Convert port to integer
+ if (key === 'smtpPort') {
+ value = value ? parseInt(value) : 587;
+ }
+
+ configUpdate[path] = value;
+ });
+
+ const mergedConfig = mergeNestedObjects([configUpdate]);
+ await dispatch(saveConfig(mergedConfig)).unwrap();
+ setHasChanges(false);
+ };
+
+ // Render tab content
+ const renderTabContent = () => {
+ switch (activeTab) {
+ case 'smtp-server':
+ return (
+
+ );
+ case 'defaults':
+ return (
+
+ );
+ case 'notifications':
+ return (
+ <>
+
+
License Expiration Warning
+
Configure email notifications when the license is about to expire
+
+ handleFieldChange('licenseExpirationWarningEnable', value)}
+ error={getFieldError(CONFIG_PATHS.licenseExpirationWarningEnable)}
+ />
+
+
+ handleFieldChange('licenseExpirationWarningRepeatInterval', value)}
+ placeholder='1d'
+ description='How often to repeat the warning (e.g., 1d, 1h, 30m)'
+ error={getFieldError(CONFIG_PATHS.licenseExpirationWarningRepeatInterval)}
+ />
+
+
+
+
+
License Expiration Error
+
Configure email notifications when the license has expired
+
+ handleFieldChange('licenseExpirationErrorEnable', value)}
+ error={getFieldError(CONFIG_PATHS.licenseExpirationErrorEnable)}
+ />
+
+
+ handleFieldChange('licenseExpirationErrorRepeatInterval', value)}
+ placeholder='1d'
+ description='How often to repeat the error notification (e.g., 1d, 1h, 30m)'
+ error={getFieldError(CONFIG_PATHS.licenseExpirationErrorRepeatInterval)}
+ />
+
+
+
+
+
License Limit Edit
+
Configure email notifications when the edit limit is reached
+
+ handleFieldChange('licenseLimitEditEnable', value)}
+ error={getFieldError(CONFIG_PATHS.licenseLimitEditEnable)}
+ />
+
+
+ handleFieldChange('licenseLimitEditRepeatInterval', value)}
+ placeholder='1h'
+ description='How often to repeat the limit warning (e.g., 1d, 1h, 30m)'
+ error={getFieldError(CONFIG_PATHS.licenseLimitEditRepeatInterval)}
+ />
+
+
+
+
+
License Limit Live Viewer
+
Configure email notifications when the live viewer limit is reached
+
+ handleFieldChange('licenseLimitLiveViewerEnable', value)}
+ error={getFieldError(CONFIG_PATHS.licenseLimitLiveViewerEnable)}
+ />
+
+
+ handleFieldChange('licenseLimitLiveViewerRepeatInterval', value)}
+ placeholder='1h'
+ description='How often to repeat the limit warning (e.g., 1d, 1h, 30m)'
+ error={getFieldError(CONFIG_PATHS.licenseLimitLiveViewerRepeatInterval)}
+ />
+
+
+ >
+ );
+ default:
+ return null;
+ }
+ };
+
+ return (
+
+
Notifications
+
Configure SMTP server settings, security options, default email addresses, and notification rules
+
+
+ {renderTabContent()}
+
+
+
+ Save Changes
+
+
+ );
+}
+
+export default EmailConfig;
diff --git a/AdminPanel/client/src/pages/NotitifcationConfig/NotificationConfig.module.scss b/AdminPanel/client/src/pages/NotitifcationConfig/NotificationConfig.module.scss
new file mode 100644
index 0000000000..f45b7ecdc0
--- /dev/null
+++ b/AdminPanel/client/src/pages/NotitifcationConfig/NotificationConfig.module.scss
@@ -0,0 +1,54 @@
+.loading {
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ height: 200px;
+ font-size: 16px;
+ color: #666;
+}
+
+.settingsSection {
+ background: white;
+ border: 1px solid #e2e2e2;
+ border-radius: 8px;
+ padding: 32px;
+ margin-bottom: 32px;
+}
+
+.sectionTitle {
+ font-size: 18px;
+ font-weight: 600;
+ color: #333;
+ margin-bottom: 8px;
+}
+
+.sectionDescription {
+ font-size: 14px;
+ color: #666666;
+ margin-bottom: 24px;
+ line-height: 1.5;
+}
+
+.formRow {
+ margin-bottom: 24px;
+
+ &:last-child {
+ margin-bottom: 0;
+ }
+}
+
+.tabPanel {
+ padding: 32px;
+ background: #fff;
+ border-radius: 8px;
+ border: 1px solid #e0e0e0;
+}
+
+.actions {
+ display: flex;
+ justify-content: flex-start;
+}
+
+.pageWithFixedSave {
+ padding-bottom: 40px;
+}
diff --git a/AdminPanel/client/src/pages/RequestFiltering/RequestFiltering.js b/AdminPanel/client/src/pages/RequestFiltering/RequestFiltering.js
new file mode 100644
index 0000000000..f905098778
--- /dev/null
+++ b/AdminPanel/client/src/pages/RequestFiltering/RequestFiltering.js
@@ -0,0 +1,124 @@
+import {useState, useRef} from 'react';
+import {useDispatch, useSelector} from 'react-redux';
+import {saveConfig, selectConfig} from '../../store/slices/configSlice';
+import {getNestedValue} from '../../utils/getNestedValue';
+import {mergeNestedObjects} from '../../utils/mergeNestedObjects';
+import {useFieldValidation} from '../../hooks/useFieldValidation';
+import Checkbox from '../../components/Checkbox/Checkbox';
+import FixedSaveButton from '../../components/FixedSaveButton/FixedSaveButton';
+import PageHeader from '../../components/PageHeader/PageHeader';
+import PageDescription from '../../components/PageDescription/PageDescription';
+import styles from './RequestFiltering.module.scss';
+
+function RequestFiltering() {
+ const dispatch = useDispatch();
+ const config = useSelector(selectConfig);
+ const {validateField, getFieldError, hasValidationErrors} = useFieldValidation();
+
+ const [localSettings, setLocalSettings] = useState({
+ allowPrivateIPAddress: false,
+ allowMetaIPAddress: false
+ });
+ const [hasChanges, setHasChanges] = useState(false);
+
+ // Configuration paths
+ const CONFIG_PATHS = {
+ allowPrivateIPAddress: 'services.CoAuthoring.request-filtering-agent.allowPrivateIPAddress',
+ allowMetaIPAddress: 'services.CoAuthoring.request-filtering-agent.allowMetaIPAddress'
+ };
+
+ const hasInitialized = useRef(false);
+ const resetToGlobalConfig = () => {
+ if (config) {
+ const newSettings = {};
+ Object.keys(CONFIG_PATHS).forEach(key => {
+ const path = CONFIG_PATHS[key];
+ newSettings[key] = getNestedValue(config, path, false);
+ });
+ setLocalSettings(newSettings);
+ }
+ };
+ // Load initial values from config
+ if (config && !hasInitialized.current) {
+ resetToGlobalConfig();
+ hasInitialized.current = true;
+ }
+
+ // Handle field changes
+ const handleFieldChange = (field, value) => {
+ setLocalSettings(prev => ({
+ ...prev,
+ [field]: value
+ }));
+
+ // Validate boolean fields
+ if (CONFIG_PATHS[field]) {
+ validateField(CONFIG_PATHS[field], value);
+ }
+
+ // Check if there are changes
+ const hasFieldChanges = Object.keys(CONFIG_PATHS).some(key => {
+ const currentValue = key === field ? value : localSettings[key];
+ const originalFieldValue = getNestedValue(config, CONFIG_PATHS[key], false);
+ return currentValue !== originalFieldValue;
+ });
+
+ setHasChanges(hasFieldChanges);
+ };
+
+ // Handle save
+ const handleSave = async () => {
+ if (!hasChanges) return;
+
+ // Create config update object
+ const configUpdate = {};
+ Object.keys(CONFIG_PATHS).forEach(key => {
+ const path = CONFIG_PATHS[key];
+ configUpdate[path] = localSettings[key];
+ });
+
+ const mergedConfig = mergeNestedObjects([configUpdate]);
+ await dispatch(saveConfig(mergedConfig)).unwrap();
+ setHasChanges(false);
+ };
+
+ return (
+
+
Request Filtering
+
+ Configure request filtering settings to control which IP addresses are allowed to make requests to the server.
+
+
+
+
IP Address Filtering
+
Control access based on IP address types to enhance security.
+
+
+ handleFieldChange('allowPrivateIPAddress', value)}
+ description='Allow requests from private IP address ranges (10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16). Disable this to block requests from internal networks.'
+ error={getFieldError(CONFIG_PATHS.allowPrivateIPAddress)}
+ />
+
+
+
+ handleFieldChange('allowMetaIPAddress', value)}
+ description='Allow requests from meta IP addresses (127.0.0.1, ::1, 0.0.0.0, etc.). Disable this to block localhost and other special-use addresses.'
+ error={getFieldError(CONFIG_PATHS.allowMetaIPAddress)}
+ />
+
+
+
+
+ Save Changes
+
+
+ );
+}
+
+export default RequestFiltering;
diff --git a/AdminPanel/client/src/pages/RequestFiltering/RequestFiltering.module.scss b/AdminPanel/client/src/pages/RequestFiltering/RequestFiltering.module.scss
new file mode 100644
index 0000000000..9ac325b940
--- /dev/null
+++ b/AdminPanel/client/src/pages/RequestFiltering/RequestFiltering.module.scss
@@ -0,0 +1,73 @@
+.loading {
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ height: 200px;
+ font-size: 16px;
+ color: #666;
+}
+
+.header {
+ margin-bottom: 32px;
+}
+
+.title {
+ font-family: 'Open Sans', sans-serif;
+ font-weight: 700;
+ font-size: 32px;
+ line-height: 44px;
+ color: #333333;
+ margin: 0 0 8px 0;
+}
+
+.description {
+ font-family: 'Open Sans', sans-serif;
+ font-weight: 400;
+ font-size: 16px;
+ line-height: 150%;
+ color: #666666;
+ margin: 0;
+}
+
+.section {
+ background: #fff;
+ border-radius: 8px;
+ border: 1px solid #e0e0e0;
+ padding: 32px;
+ margin-bottom: 32px;
+}
+
+.sectionTitle {
+ font-family: 'Open Sans', sans-serif;
+ font-weight: 600;
+ font-size: 20px;
+ line-height: 150%;
+ color: #333333;
+ margin: 0 0 3px 0;
+}
+
+.sectionDescription {
+ font-family: 'Open Sans', sans-serif;
+ font-weight: 400;
+ font-size: 14px;
+ line-height: 150%;
+ color: #666666;
+ margin: 0 0 24px 0;
+}
+
+.formRow {
+ margin-bottom: 24px;
+
+ &:last-child {
+ margin-bottom: 0;
+ }
+}
+
+.actions {
+ display: flex;
+ justify-content: flex-start;
+}
+
+.pageWithFixedSave {
+ padding-bottom: 40px;
+}
diff --git a/AdminPanel/client/src/pages/SecuritySettings/SecuritySettings.js b/AdminPanel/client/src/pages/SecuritySettings/SecuritySettings.js
new file mode 100644
index 0000000000..0dcb893e50
--- /dev/null
+++ b/AdminPanel/client/src/pages/SecuritySettings/SecuritySettings.js
@@ -0,0 +1,120 @@
+import {useState, useRef} from 'react';
+import {useSelector, useDispatch} from 'react-redux';
+import {saveConfig, selectConfig} from '../../store/slices/configSlice';
+import {getNestedValue} from '../../utils/getNestedValue';
+import {mergeNestedObjects} from '../../utils/mergeNestedObjects';
+import {useFieldValidation} from '../../hooks/useFieldValidation';
+import PageHeader from '../../components/PageHeader/PageHeader';
+import PageDescription from '../../components/PageDescription/PageDescription';
+import Tabs from '../../components/Tabs/Tabs';
+import AccessRules from '../../components/AccessRules/AccessRules';
+import FixedSaveButton from '../../components/FixedSaveButton/FixedSaveButton';
+import styles from './SecuritySettings.module.scss';
+
+const securityTabs = [{key: 'ip-filtering', label: 'IP Filtering'}];
+
+function SecuritySettings() {
+ const dispatch = useDispatch();
+ const config = useSelector(selectConfig);
+ const {validateField, getFieldError, hasValidationErrors, clearFieldError} = useFieldValidation();
+
+ const [activeTab, setActiveTab] = useState('ip-filtering');
+ const [localRules, setLocalRules] = useState([]);
+ const [hasChanges, setHasChanges] = useState(false);
+
+ // Reset state and errors to global config
+ const resetToGlobalConfig = () => {
+ if (config) {
+ const ipFilterRules = getNestedValue(config, 'services.CoAuthoring.ipfilter.rules', []);
+ const uiRules = ipFilterRules.map(rule => ({
+ type: rule.allowed ? 'Allow' : 'Deny',
+ value: rule.address
+ }));
+ setLocalRules(uiRules);
+ setHasChanges(false);
+ // Clear validation errors
+ clearFieldError('services.CoAuthoring.ipfilter.rules');
+ }
+ };
+
+ // Handle tab change and reset state
+ const handleTabChange = newTab => {
+ setActiveTab(newTab);
+ resetToGlobalConfig();
+ };
+
+ const hasInitialized = useRef(false);
+
+ if (config && !hasInitialized.current) {
+ resetToGlobalConfig();
+ hasInitialized.current = true;
+ }
+
+ // Handle rules changes
+ const handleRulesChange = newRules => {
+ setLocalRules(newRules);
+ setHasChanges(true);
+
+ // Validate the rules array structure
+ if (newRules.length > 0) {
+ const backendRules = newRules.map(rule => ({
+ address: rule.value,
+ allowed: rule.type === 'Allow'
+ }));
+ validateField('services.CoAuthoring.ipfilter.rules', backendRules);
+ }
+ };
+
+ const handleSave = async () => {
+ if (!hasChanges) return;
+
+ // Convert UI rules back to backend format
+ const backendRules = localRules.map(rule => ({
+ address: rule.value,
+ allowed: rule.type === 'Allow'
+ }));
+
+ // Create config update object
+ const configUpdate = mergeNestedObjects([
+ {
+ 'services.CoAuthoring.ipfilter.rules': backendRules
+ }
+ ]);
+
+ await dispatch(saveConfig(configUpdate)).unwrap();
+ setHasChanges(false);
+ };
+
+ const renderTabContent = () => {
+ switch (activeTab) {
+ case 'ip-filtering':
+ return (
+
+
+ {getFieldError('services.CoAuthoring.ipfilter.rules') && (
+
{getFieldError('services.CoAuthoring.ipfilter.rules')}
+ )}
+
+ );
+ default:
+ return null;
+ }
+ };
+
+ return (
+
+
Security Settings
+
Configure IP filtering, authentication, and security policies
+
+
+ {renderTabContent()}
+
+
+
+ Save Changes
+
+
+ );
+}
+
+export default SecuritySettings;
diff --git a/AdminPanel/client/src/pages/SecuritySettings/SecuritySettings.module.scss b/AdminPanel/client/src/pages/SecuritySettings/SecuritySettings.module.scss
new file mode 100644
index 0000000000..a1dffe0915
--- /dev/null
+++ b/AdminPanel/client/src/pages/SecuritySettings/SecuritySettings.module.scss
@@ -0,0 +1,57 @@
+.securitySettings {
+ padding: 0;
+}
+
+.pageWithFixedSave {
+ padding-bottom: 40px;
+}
+
+.loading {
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ height: 200px;
+ font-family: 'Open Sans', sans-serif;
+ color: #666666;
+}
+
+.tabPanel {
+ background: white;
+ border: 1px solid #e2e2e2;
+ border-radius: 8px;
+ padding: 24px;
+ margin-bottom: 24px;
+
+ h3 {
+ font-family: 'Open Sans', sans-serif;
+ font-weight: 700;
+ font-size: 18px;
+ line-height: 150%;
+ color: #333333;
+ margin: 0 0 16px 0;
+ }
+
+ p {
+ font-family: 'Open Sans', sans-serif;
+ font-size: 14px;
+ line-height: 150%;
+ color: #666666;
+ margin: 0;
+ }
+}
+
+.actions {
+ display: flex;
+ justify-content: flex-start;
+}
+
+.error {
+ font-family: 'Open Sans', sans-serif;
+ font-size: 12px;
+ color: #dc3545;
+ margin-top: 8px;
+ padding: 8px 12px;
+ background: #fff5f5;
+ border: 1px solid #fecaca;
+ border-radius: 4px;
+}
diff --git a/AdminPanel/client/src/pages/Settings/Settings.js b/AdminPanel/client/src/pages/Settings/Settings.js
new file mode 100644
index 0000000000..ed0c1d9ea7
--- /dev/null
+++ b/AdminPanel/client/src/pages/Settings/Settings.js
@@ -0,0 +1,37 @@
+import {resetConfiguration} from '../../api';
+import SaveButton from '../../components/SaveButton/SaveButton';
+import './Settings.scss';
+
+const Settings = () => {
+ const handleResetConfig = async () => {
+ if (!window.confirm('Are you sure you want to reset the configuration? This action cannot be undone.')) {
+ throw new Error('Operation cancelled');
+ }
+
+ await resetConfiguration();
+ };
+
+ return (
+
+
+
Settings
+
+
+
+
+
+
+
Reset Configuration
+
This will reset all configuration settings to their default values. This action cannot be undone.
+
+
+ Reset
+
+
+
+
+
+ );
+};
+
+export default Settings;
diff --git a/AdminPanel/client/src/pages/Settings/Settings.scss b/AdminPanel/client/src/pages/Settings/Settings.scss
new file mode 100644
index 0000000000..3257373ecd
--- /dev/null
+++ b/AdminPanel/client/src/pages/Settings/Settings.scss
@@ -0,0 +1,148 @@
+.settings-page {
+ margin: 0 auto;
+
+ .page-header {
+ margin-bottom: 32px;
+
+ h1 {
+ margin: 0;
+ color: #333;
+ font-size: 28px;
+ font-weight: 600;
+ }
+ }
+
+ .settings-content {
+ .settings-section {
+ background: white;
+ border-radius: 8px;
+ border: 1px solid #e0e0e0;
+ margin-bottom: 20px;
+ overflow: hidden;
+
+ h2 {
+ margin: 0;
+ padding: 20px;
+ background: #f8f9fa;
+ border-bottom: 1px solid #e0e0e0;
+ color: #333;
+ font-size: 20px;
+ font-weight: 600;
+ }
+
+ .settings-item {
+ padding: 20px;
+ display: flex;
+ justify-content: space-between;
+ align-items: flex-start;
+ gap: 20px;
+
+ .settings-info {
+ flex: 1;
+
+ h3 {
+ margin: 0 0 10px 0;
+ color: #333;
+ font-size: 16px;
+ font-weight: 600;
+ }
+
+ p {
+ margin: 0;
+ color: #666;
+ font-size: 14px;
+ line-height: 1.5;
+ }
+ }
+
+ .settings-actions {
+ flex-shrink: 0;
+
+ .reset-btn {
+ background: #dc3545;
+ color: white;
+ border: none;
+ padding: 10px 20px;
+ border-radius: 4px;
+ cursor: pointer;
+ font-size: 14px;
+ font-weight: 500;
+ transition: all 0.2s;
+ min-width: 150px;
+
+ &:hover:not(:disabled) {
+ background: #c82333;
+ transform: translateY(-1px);
+ }
+
+ &:disabled {
+ background: #6c757d;
+ cursor: not-allowed;
+ transform: none;
+ }
+
+ &:active:not(:disabled) {
+ transform: translateY(0);
+ }
+ }
+ }
+ }
+ }
+
+ .error-message {
+ background: #f8d7da;
+ border: 1px solid #f5c6cb;
+ border-radius: 4px;
+ padding: 15px;
+ margin-bottom: 20px;
+
+ p {
+ margin: 0;
+ color: #721c24;
+ font-size: 14px;
+ }
+ }
+
+ .success-message {
+ background: #d4edda;
+ border: 1px solid #c3e6cb;
+ border-radius: 4px;
+ padding: 15px;
+ margin-bottom: 20px;
+
+ p {
+ margin: 0;
+ color: #155724;
+ font-size: 14px;
+ }
+ }
+ }
+}
+
+// Responsive design
+@media (max-width: 768px) {
+ .settings-page {
+ padding: 15px;
+
+ .page-header h1 {
+ font-size: 24px;
+ }
+
+ .settings-content {
+ .settings-section {
+ .settings-item {
+ flex-direction: column;
+ gap: 15px;
+
+ .settings-actions {
+ width: 100%;
+
+ .reset-btn {
+ width: 100%;
+ }
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/AdminPanel/client/src/pages/Setup/SetupPage.js b/AdminPanel/client/src/pages/Setup/SetupPage.js
new file mode 100644
index 0000000000..8997eff419
--- /dev/null
+++ b/AdminPanel/client/src/pages/Setup/SetupPage.js
@@ -0,0 +1,120 @@
+import {useState, useRef} from 'react';
+import {useDispatch} from 'react-redux';
+import {setupAdminPassword} from '../../api';
+import {fetchUser} from '../../store/slices/userSlice';
+import Input from '../../components/LoginInput';
+import Button from '../../components/LoginButton';
+import styles from './styles.module.css';
+
+export default function Setup() {
+ const [bootstrapToken, setBootstrapToken] = useState('');
+ const [password, setPassword] = useState('');
+ const [confirmPassword, setConfirmPassword] = useState('');
+ const [errors, setErrors] = useState({});
+ const dispatch = useDispatch();
+ const buttonRef = useRef();
+
+ const handleSubmit = async () => {
+ setErrors({});
+
+ // Validate all fields
+ const newErrors = {};
+
+ if (!bootstrapToken.trim()) {
+ newErrors.bootstrapToken = 'Bootstrap token is required';
+ }
+
+ if (!password) {
+ newErrors.password = 'Password is required';
+ } else if (password.length > 128) {
+ newErrors.password = 'Password must not exceed 128 characters';
+ }
+
+ if (!confirmPassword) {
+ newErrors.confirmPassword = 'Please confirm your password';
+ } else if (password !== confirmPassword) {
+ newErrors.confirmPassword = 'Passwords do not match';
+ }
+
+ // If there are validation errors, show them
+ if (Object.keys(newErrors).length > 0) {
+ setErrors(newErrors);
+ throw new Error('Validation failed');
+ }
+
+ try {
+ await setupAdminPassword({bootstrapToken, password});
+ // Wait for cookie to be set and verify authentication works
+ await dispatch(fetchUser()).unwrap();
+ // AuthWrapper will automatically redirect based on isAuthenticated
+ } catch (error) {
+ // Server error
+ setErrors({
+ general: error.message || 'Setup failed. Invalid token or server error.'
+ });
+ throw error;
+ }
+ };
+
+ const handleKeyDown = e => {
+ if (e.key === 'Enter') {
+ if (buttonRef.current) {
+ buttonRef.current.click();
+ }
+ }
+ };
+
+ return (
+
+
+
ONLYOFFICE Admin Panel
+
Initial Setup
+
Enter the bootstrap token from server logs and create your admin password.
+
+ {errors.general &&
{errors.general}
}
+
+
+
+
+ );
+}
diff --git a/AdminPanel/client/src/pages/Setup/styles.module.css b/AdminPanel/client/src/pages/Setup/styles.module.css
new file mode 100644
index 0000000000..0faf996e93
--- /dev/null
+++ b/AdminPanel/client/src/pages/Setup/styles.module.css
@@ -0,0 +1,68 @@
+.loginContainer {
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ min-height: calc(100vh - 60px);
+ background: white;
+ padding: 20px;
+ width: 100%;
+}
+
+.loginCard {
+ background: white;
+ width: 100%;
+ max-width: 500px;
+ text-align: center;
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+}
+
+.title {
+ color: #333;
+ font-size: 32px;
+ font-weight: bold;
+ margin: 0 0 16px 0;
+ font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
+}
+
+.subtitle {
+ color: #333;
+ font-size: 16px;
+ font-weight: bold;
+ margin: 0 0 16px 0;
+ font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
+}
+
+.description {
+ color: #333;
+ font-size: 14px;
+ margin: 0 0 32px 0;
+ line-height: 1.5;
+ font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
+}
+
+.form {
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ gap: 20px;
+}
+
+.inputGroup {
+ width: 100%;
+ max-width: 300px;
+}
+
+.errorMessage {
+ background: #fee;
+ border: 1px solid #fcc;
+ border-radius: 4px;
+ color: #c33;
+ padding: 12px 16px;
+ margin: 0 0 20px 0;
+ font-size: 14px;
+ text-align: center;
+ max-width: 400px;
+ width: 100%;
+}
diff --git a/AdminPanel/client/src/pages/Statistics/InfoTable/index.js b/AdminPanel/client/src/pages/Statistics/InfoTable/index.js
new file mode 100644
index 0000000000..9137b602e1
--- /dev/null
+++ b/AdminPanel/client/src/pages/Statistics/InfoTable/index.js
@@ -0,0 +1,64 @@
+import styles from './styles.module.css';
+
+/**
+ * Renders a two-section info table for Editor and Live Viewer values.
+ * Values can optionally include a status class in v[1] like 'critical' or 'normal'.
+ * Sections can be toggled via the `mode` prop: 'all' | 'edit' | 'view'.
+ *
+ * @param {{
+ * caption?: string,
+ * editor: Array<[number|string, ("critical"|"normal")?]>,
+ * viewer: Array<[number|string, ("critical"|"normal")?]>,
+ * desc: string[],
+ * mode?: 'all' | 'edit' | 'view'
+ * }} props
+ */
+export default function InfoTable({caption, editor, viewer, desc, mode = 'all'}) {
+ return (
+
+ {caption &&
{caption}
}
+
+ {mode !== 'view' && (
+ <>
+
EDITORS
+
+
+ {[0, 1, 2, 3].map(i => (
+
+ {editor[i] && editor[i][0] !== undefined ? editor[i][0] : ''}
+
+ ))}
+
+
+ {[0, 1, 2, 3].map(i => (
+
+ {desc[i] || ''}
+
+ ))}
+
+ >
+ )}
+
+ {mode !== 'edit' && (
+ <>
+
LIVE VIEWER
+
+
+ {[0, 1, 2, 3].map(i => (
+
+ {viewer[i] && viewer[i][0] !== undefined ? viewer[i][0] : ''}
+
+ ))}
+
+
+ {[0, 1, 2, 3].map(i => (
+
+ {desc[i] || ''}
+
+ ))}
+
+ >
+ )}
+
+ );
+}
diff --git a/AdminPanel/client/src/pages/Statistics/InfoTable/styles.module.css b/AdminPanel/client/src/pages/Statistics/InfoTable/styles.module.css
new file mode 100644
index 0000000000..d187698daf
--- /dev/null
+++ b/AdminPanel/client/src/pages/Statistics/InfoTable/styles.module.css
@@ -0,0 +1,56 @@
+.container {
+ margin-bottom: 25px;
+}
+.sectionHeader {
+ background: #efefef;
+ font-size: 16px;
+ font-weight: 400;
+ padding: 6px 8px;
+ margin-bottom: 8px;
+ border-radius: 1px;
+}
+.row {
+ display: flex;
+ justify-content: start;
+}
+.valueCell {
+ font-size: 26px;
+ line-height: 28px;
+ padding: 8px 0;
+ width: 25%;
+ padding-left: 10px;
+}
+.labelCell {
+ font-size: 12px;
+ color: #555;
+ padding-bottom: 8px;
+ width: 25%;
+ padding-left: 10px;
+}
+.editorsLabel,
+.viewerLabel {
+ font-weight: 600;
+ font-size: 12px;
+ padding: 8px 0 0 10px;
+}
+
+.viewerLabel {
+ margin-top: 15px;
+}
+
+.divider {
+ border-bottom: 1px solid #dadada;
+ margin: 2px 10px;
+}
+
+.remainingValue {
+ color: rgb(1, 125, 28);
+}
+
+/* match branding coloring */
+.critical {
+ color: #ff0000;
+}
+.normal {
+ color: #017d1c;
+}
diff --git a/AdminPanel/client/src/pages/Statistics/ModeSwitcher.js b/AdminPanel/client/src/pages/Statistics/ModeSwitcher.js
new file mode 100644
index 0000000000..de78f3df52
--- /dev/null
+++ b/AdminPanel/client/src/pages/Statistics/ModeSwitcher.js
@@ -0,0 +1,28 @@
+import styles from './styles.module.css';
+
+/**
+ * Mode switcher component for statistics view.
+ * Persists selected mode to localStorage via parent.
+ *
+ * @param {{
+ * mode: 'all'|'edit'|'view',
+ * setMode: (mode: 'all'|'edit'|'view') => void
+ * }} props
+ */
+export default function ModeSwitcher({mode, setMode}) {
+ return (
+
+ setMode('all')}>
+ All
+
+ |
+ setMode('edit')}>
+ Editors
+
+ |
+ setMode('view')}>
+ Live Viewer
+
+
+ );
+}
diff --git a/AdminPanel/client/src/pages/Statistics/MonthlyStatistics.js b/AdminPanel/client/src/pages/Statistics/MonthlyStatistics.js
new file mode 100644
index 0000000000..d77fab017f
--- /dev/null
+++ b/AdminPanel/client/src/pages/Statistics/MonthlyStatistics.js
@@ -0,0 +1,86 @@
+import {memo, useMemo} from 'react';
+import InfoTable from './InfoTable/index';
+
+const MILLISECONDS_PER_DAY = 86400000;
+
+/**
+ * Count internal/external users.
+ * @param {Record} users
+ * @returns {{internal: number, external: number}}
+ */
+function countUsers(users = {}) {
+ let internal = 0;
+ let external = 0;
+ for (const uid in users) {
+ if (Object.prototype.hasOwnProperty.call(users, uid)) {
+ users[uid]?.anonym ? external++ : internal++;
+ }
+ }
+ return {internal, external};
+}
+
+/**
+ * MonthlyStatistics - renders usage statistics by month.
+ * Mirrors logic from branding/info/index.html fillStatistic().
+ *
+ * @param {{ byMonth?: Array, mode: 'all'|'edit'|'view' }} props
+ */
+function MonthlyStatistics({byMonth, mode}) {
+ const periods = useMemo(() => {
+ if (!Array.isArray(byMonth) || byMonth.length < 1) return [];
+
+ // Build periods in chronological order, then reverse for display.
+ const mapped = byMonth
+ .map((item, index) => {
+ const date = item?.date ? new Date(item.date) : null;
+ if (!date) return null;
+
+ const editCounts = countUsers(item?.users);
+ const viewCounts = countUsers(item?.usersView);
+
+ const nextDate = index + 1 < byMonth.length ? new Date(byMonth[index + 1].date) : null;
+
+ return {
+ startDate: date,
+ endDate: nextDate ? new Date(nextDate.getTime() - MILLISECONDS_PER_DAY) : null,
+ internalEdit: editCounts.internal,
+ externalEdit: editCounts.external,
+ internalView: viewCounts.internal,
+ externalView: viewCounts.external
+ };
+ })
+ .filter(Boolean)
+ .reverse();
+
+ return mapped;
+ }, [byMonth]);
+
+ if (periods.length < 1) return null;
+
+ return (
+ <>
+ Usage statistics for the reporting period
+ {periods.map((p, idx) => {
+ const caption = p.endDate
+ ? `${p.startDate.toLocaleDateString()} - ${p.endDate.toLocaleDateString()}`
+ : `From ${p.startDate.toLocaleDateString()}`;
+
+ const editor = [
+ [p.internalEdit, ''],
+ [p.externalEdit, ''],
+ [p.internalEdit + p.externalEdit, '']
+ ];
+ const viewer = [
+ [p.internalView, ''],
+ [p.externalView, ''],
+ [p.internalView + p.externalView, '']
+ ];
+ const desc = ['Internal', 'External', 'Active', ''];
+
+ return ;
+ })}
+ >
+ );
+}
+
+export default memo(MonthlyStatistics);
diff --git a/AdminPanel/client/src/pages/Statistics/Statistics.module.scss b/AdminPanel/client/src/pages/Statistics/Statistics.module.scss
new file mode 100644
index 0000000000..49e6994d6e
--- /dev/null
+++ b/AdminPanel/client/src/pages/Statistics/Statistics.module.scss
@@ -0,0 +1,20 @@
+.topRow {
+ display: flex;
+ margin-bottom: 24px;
+ gap: 24px;
+}
+
+.modeBar {
+ margin: 8px 0 16px;
+ font-size: 14px;
+}
+.modeLink {
+ cursor: pointer;
+ padding: 0 6px;
+}
+.modeSeparator {
+ color: #777;
+}
+.current {
+ font-weight: 700;
+}
diff --git a/AdminPanel/client/src/pages/Statistics/TopBlock/index.js b/AdminPanel/client/src/pages/Statistics/TopBlock/index.js
new file mode 100644
index 0000000000..ffe584c9ba
--- /dev/null
+++ b/AdminPanel/client/src/pages/Statistics/TopBlock/index.js
@@ -0,0 +1,10 @@
+import styles from './styles.module.css';
+
+export default function TopBlock({title, children}) {
+ return (
+
+ );
+}
diff --git a/AdminPanel/client/src/pages/Statistics/TopBlock/styles.module.css b/AdminPanel/client/src/pages/Statistics/TopBlock/styles.module.css
new file mode 100644
index 0000000000..4b4537223a
--- /dev/null
+++ b/AdminPanel/client/src/pages/Statistics/TopBlock/styles.module.css
@@ -0,0 +1,18 @@
+.block {
+ flex: 1;
+ min-width: 180px;
+}
+.title {
+ font-weight: 400;
+ font-size: 18px;
+ border-bottom: 1px solid #ddd;
+ padding: 0 0 5px 10px;
+}
+.content {
+ font-size: 12px;
+ display: flex;
+ flex-direction: column;
+ gap: 16px;
+ margin-top: 16px;
+ padding-left: 10px;
+}
diff --git a/AdminPanel/client/src/pages/Statistics/index.js b/AdminPanel/client/src/pages/Statistics/index.js
new file mode 100644
index 0000000000..bb4c53ffae
--- /dev/null
+++ b/AdminPanel/client/src/pages/Statistics/index.js
@@ -0,0 +1,261 @@
+import {useEffect, useMemo, useState} from 'react';
+import {useQuery} from '@tanstack/react-query';
+import TopBlock from './TopBlock/index';
+import InfoTable from './InfoTable/index';
+import ModeSwitcher from './ModeSwitcher';
+import MonthlyStatistics from './MonthlyStatistics';
+import styles from './styles.module.css';
+import {fetchStatistics, fetchConfiguration} from '../../api';
+
+// Constants
+const CRITICAL_COLOR = '#ff0000';
+const CRITICAL_THRESHOLD = 0.1;
+const TIME_PERIODS = ['hour', 'day', 'week', 'month'];
+const TIME_PERIOD_LABELS = ['Last Hour', '24 Hours', 'Week', 'Month'];
+const SECONDS_PER_DAY = 86400;
+
+/**
+ * Calculate critical status for remaining values
+ * @param {number} remaining - Remaining count
+ * @param {number} limit - Total limit
+ * @returns {string} 'normal' | 'critical'
+ */
+const getCriticalStatus = (remaining, limit) => (remaining > limit * CRITICAL_THRESHOLD ? 'normal' : 'critical');
+
+// ModeSwitcher moved to ./ModeSwitcher (kept behavior, simplified markup/styles)
+
+/**
+ * Statistics component - renders Document Server statistics
+ * Mirrors branding/info/index.html rendering logic with mode toggling
+ */
+export default function Statistics() {
+ const {data, isLoading, error} = useQuery({
+ queryKey: ['statistics'],
+ queryFn: fetchStatistics
+ });
+
+ // Fetch configuration to display DB info
+ const {data: configData} = useQuery({
+ queryKey: ['configuration'],
+ queryFn: fetchConfiguration
+ });
+
+ const [mode, setMode] = useState(() => {
+ try {
+ const saved = window.localStorage?.getItem('server-info-display-mode');
+ return saved || 'all';
+ } catch {
+ return 'all';
+ }
+ });
+
+ useEffect(() => {
+ try {
+ window.localStorage?.setItem('server-info-display-mode', mode);
+ } catch {
+ /* ignore */
+ }
+ }, [mode]);
+
+ // Safe defaults to maintain hook order consistency (memoized to avoid dependency changes)
+ const licenseInfo = useMemo(() => data?.licenseInfo ?? {}, [data?.licenseInfo]);
+ const quota = useMemo(() => data?.quota ?? {}, [data?.quota]);
+ const connectionsStat = useMemo(() => data?.connectionsStat ?? {}, [data?.connectionsStat]);
+ const serverInfo = useMemo(() => data?.serverInfo ?? {}, [data?.serverInfo]);
+
+ // Derived values used across multiple components
+ const isUsersModel = licenseInfo.usersCount > 0;
+ const limitEdit = isUsersModel ? licenseInfo.usersCount : licenseInfo.connections;
+ const limitView = isUsersModel ? licenseInfo.usersViewCount : licenseInfo.connectionsView;
+
+ // Build block
+ const buildDate = licenseInfo.buildDate ? new Date(licenseInfo.buildDate).toLocaleDateString() : '';
+ const isOpenSource = licenseInfo.packageType === 0;
+ const packageTypeLabel = isOpenSource ? 'Open source' : licenseInfo.packageType === 1 ? 'Enterprise Edition' : 'Developer Edition';
+ const buildBlock = (
+
+ Type: {packageTypeLabel}
+
+ Version: {serverInfo.buildVersion}.{serverInfo.buildNumber}
+
+ Release date: {buildDate}
+
+ );
+
+ // License block (mirrors fillInfo license validity rendering)
+ const licenseBlock = (() => {
+ if (licenseInfo.endDate === null) {
+ return (
+
+ No license
+
+ );
+ }
+ const isLimited = licenseInfo.mode & 1 || licenseInfo.mode & 4;
+ const licEnd = new Date(licenseInfo.endDate);
+ const srvDate = new Date(serverInfo.date);
+ const licType = licenseInfo.type;
+ const isInvalid = licType === 2 || licType === 1 || licType === 6 || licType === 11;
+ const isUpdateUnavailable = !isLimited && srvDate > licEnd;
+ const licValidText = isLimited ? 'Valid: ' : 'Updates available: ';
+ const licValidColor = isInvalid || isUpdateUnavailable ? CRITICAL_COLOR : undefined;
+
+ const startDateStr = licenseInfo.startDate ? new Date(licenseInfo.startDate).toLocaleDateString() : '';
+ const isStartCritical = licType === 16 || (licenseInfo.startDate ? new Date(licenseInfo.startDate) > srvDate : false);
+ const trialText = licenseInfo.mode & 1 ? 'Trial' : '';
+
+ return (
+
+ {startDateStr && Start date: {startDateStr}
}
+
+ {licValidText}
+ {licEnd.toLocaleDateString()}
+
+ {trialText && {trialText}
}
+
+ );
+ })();
+
+ // Limits block
+ const limitTitle = isUsersModel ? 'Users limit' : 'Connections limit';
+ const limitsBlock = (
+
+ Editors: {limitEdit}
+ Live Viewer: {limitView}
+
+ );
+
+ /**
+ * Render database info block
+ * @param {object|null} sql - services.CoAuthoring.sql config
+ * @returns {JSX.Element|null}
+ */
+ const renderDatabaseBlock = sql => {
+ if (!sql) return null;
+ return (
+
+ Type: {sql.type}
+ Host: {sql.dbHost}
+ Port: {sql.dbPort}
+ Name: {sql.dbName}
+
+ );
+ };
+
+ // Current activity/usage table
+ const currentTable = useMemo(() => {
+ if (isUsersModel) {
+ // Users model
+ const days = parseInt(licenseInfo.usersExpire / SECONDS_PER_DAY, 10) || 1;
+ const qEditUnique = quota?.edit?.usersCount?.unique || 0;
+ const qEditAnon = quota?.edit?.usersCount?.anonymous || 0;
+ const qViewUnique = quota?.view?.usersCount?.unique || 0;
+ const qViewAnon = quota?.view?.usersCount?.anonymous || 0;
+
+ const remainingEdit = limitEdit - qEditUnique;
+ const remainingView = limitView - qViewUnique;
+
+ const editor = [
+ [qEditUnique, ''],
+ [qEditUnique - qEditAnon, ''],
+ [qEditAnon, ''],
+ [remainingEdit, getCriticalStatus(remainingEdit, limitEdit)]
+ ];
+ const viewer = [
+ [qViewUnique, ''],
+ [qViewUnique - qViewAnon, ''],
+ [qViewAnon, ''],
+ [remainingView, getCriticalStatus(remainingView, limitView)]
+ ];
+ const desc = ['Active', 'Internal', 'External', 'Remaining'];
+ return (
+ 1 ? 'days' : 'day'}`}
+ editor={editor}
+ viewer={viewer}
+ desc={desc}
+ />
+ );
+ }
+
+ // Connections model
+ const activeEdit = quota?.edit?.connectionsCount || 0;
+ const activeView = quota?.view?.connectionsCount || 0;
+ const remainingEdit = limitEdit - activeEdit;
+ const remainingView = limitView - activeView;
+ const editor = [
+ [activeEdit, ''],
+ [remainingEdit, getCriticalStatus(remainingEdit, limitEdit)]
+ ];
+ const viewer = [
+ [activeView, ''],
+ [remainingView, getCriticalStatus(remainingView, limitView)]
+ ];
+ const desc = ['Active', 'Remaining'];
+ return ;
+ }, [isUsersModel, licenseInfo, quota, limitEdit, limitView, mode]);
+
+ // Peaks and Averages (only for connections model)
+ const peaksAverage = useMemo(() => {
+ if (isUsersModel) return null;
+
+ const editorPeaks = [];
+ const viewerPeaks = [];
+ const editorAvr = [];
+ const viewerAvr = [];
+
+ TIME_PERIODS.forEach((k, index) => {
+ const item = connectionsStat?.[k];
+ if (item?.edit) {
+ let value = item.edit.max || 0;
+ editorPeaks[index] = [value, value >= limitEdit ? 'critical' : ''];
+ value = item.edit.avr || 0;
+ editorAvr[index] = [value, value >= limitEdit ? 'critical' : ''];
+ }
+ if (item?.liveview) {
+ let value = item.liveview.max || 0;
+ viewerPeaks[index] = [value, value >= limitView ? 'critical' : ''];
+ value = item.liveview.avr || 0;
+ viewerAvr[index] = [value, value >= limitView ? 'critical' : ''];
+ }
+ });
+ return (
+ <>
+
+
+ >
+ );
+ }, [isUsersModel, connectionsStat, limitEdit, limitView, mode]);
+ // MonthlyStatistics moved to ./MonthlyStatistics for clarity and to keep this file concise
+
+ // After hooks and memos: show loading/error states
+ if (error) {
+ return Error: {error.message}
;
+ }
+ if (isLoading || !data) {
+ return Please, wait...
;
+ }
+
+ return (
+
+
+ {buildBlock}
+ {licenseBlock}
+ {limitsBlock}
+
+
+ {renderDatabaseBlock(configData?.services?.CoAuthoring?.sql)}
+
+ {!isOpenSource && (
+ <>
+
+
+ {currentTable}
+ {peaksAverage}
+ {isUsersModel &&
}
+ >
+ )}
+
+ );
+}
diff --git a/AdminPanel/client/src/pages/Statistics/styles.module.css b/AdminPanel/client/src/pages/Statistics/styles.module.css
new file mode 100644
index 0000000000..49e6994d6e
--- /dev/null
+++ b/AdminPanel/client/src/pages/Statistics/styles.module.css
@@ -0,0 +1,20 @@
+.topRow {
+ display: flex;
+ margin-bottom: 24px;
+ gap: 24px;
+}
+
+.modeBar {
+ margin: 8px 0 16px;
+ font-size: 14px;
+}
+.modeLink {
+ cursor: pointer;
+ padding: 0 6px;
+}
+.modeSeparator {
+ color: #777;
+}
+.current {
+ font-weight: 700;
+}
diff --git a/AdminPanel/client/src/pages/WOPISettings/WOPISettings.js b/AdminPanel/client/src/pages/WOPISettings/WOPISettings.js
new file mode 100644
index 0000000000..cc4b7ac4d4
--- /dev/null
+++ b/AdminPanel/client/src/pages/WOPISettings/WOPISettings.js
@@ -0,0 +1,185 @@
+import {useState, useRef} from 'react';
+import {useSelector, useDispatch} from 'react-redux';
+import {saveConfig, selectConfig, rotateWopiKeysAction} from '../../store/slices/configSlice';
+import {getNestedValue} from '../../utils/getNestedValue';
+import {mergeNestedObjects} from '../../utils/mergeNestedObjects';
+import {useFieldValidation} from '../../hooks/useFieldValidation';
+import {maskKey} from '../../utils/maskKey';
+import PageHeader from '../../components/PageHeader/PageHeader';
+import PageDescription from '../../components/PageDescription/PageDescription';
+import ToggleSwitch from '../../components/ToggleSwitch/ToggleSwitch';
+import Input from '../../components/Input/Input';
+import Checkbox from '../../components/Checkbox/Checkbox';
+import FixedSaveButton from '../../components/FixedSaveButton/FixedSaveButton';
+import Note from '../../components/Note/Note';
+import styles from './WOPISettings.module.scss';
+
+function WOPISettings() {
+ const dispatch = useDispatch();
+ const config = useSelector(selectConfig);
+ const {validateField, hasValidationErrors} = useFieldValidation();
+
+ // Local state for WOPI settings
+ const [localWopiEnabled, setLocalWopiEnabled] = useState(false);
+ const [localRotateKeys, setLocalRotateKeys] = useState(false);
+ const [localRefreshLockInterval, setLocalRefreshLockInterval] = useState('');
+ const [hasChanges, setHasChanges] = useState(false);
+ const hasInitialized = useRef(false);
+
+ // Get the actual config values
+ const configWopiEnabled = getNestedValue(config, 'wopi.enable', false);
+ const wopiPublicKey = getNestedValue(config, 'wopi.publicKey', '');
+ const configRefreshLockInterval = getNestedValue(config, 'wopi.refreshLockInterval', '10m');
+
+ const resetToGlobalConfig = () => {
+ if (config) {
+ setLocalWopiEnabled(configWopiEnabled);
+ setLocalRotateKeys(false);
+ setLocalRefreshLockInterval(configRefreshLockInterval);
+ setHasChanges(false);
+ validateField('wopi.enable', configWopiEnabled);
+ validateField('wopi.refreshLockInterval', configRefreshLockInterval);
+ }
+ };
+
+ // Initialize settings from config when component loads (only once)
+ if (config && !hasInitialized.current) {
+ resetToGlobalConfig();
+ hasInitialized.current = true;
+ }
+
+ const handleWopiEnabledChange = enabled => {
+ setLocalWopiEnabled(enabled);
+ // If WOPI is disabled, uncheck rotate keys
+ if (!enabled) {
+ setLocalRotateKeys(false);
+ }
+ setHasChanges(enabled !== configWopiEnabled || localRotateKeys || localRefreshLockInterval !== configRefreshLockInterval);
+
+ // Validate the boolean field
+ validateField('wopi.enable', enabled);
+ };
+
+ const handleRotateKeysChange = checked => {
+ setLocalRotateKeys(checked);
+ setHasChanges(localWopiEnabled !== configWopiEnabled || checked || localRefreshLockInterval !== configRefreshLockInterval);
+ };
+
+ const handleRefreshLockIntervalChange = value => {
+ setLocalRefreshLockInterval(value);
+ setHasChanges(localWopiEnabled !== configWopiEnabled || localRotateKeys || value !== configRefreshLockInterval);
+ validateField('wopi.refreshLockInterval', value);
+ };
+
+ const handleSave = async () => {
+ if (!hasChanges) return;
+
+ try {
+ const enableChanged = localWopiEnabled !== configWopiEnabled;
+ const rotateRequested = localRotateKeys;
+ const refreshLockIntervalChanged = localRefreshLockInterval !== configRefreshLockInterval;
+
+ // Build config update object
+ const configUpdates = {};
+ if (enableChanged) {
+ configUpdates['wopi.enable'] = localWopiEnabled;
+ }
+ if (refreshLockIntervalChanged) {
+ configUpdates['wopi.refreshLockInterval'] = localRefreshLockInterval;
+ }
+
+ // If only rotate requested, just rotate keys
+ if (!enableChanged && !refreshLockIntervalChanged && rotateRequested) {
+ await dispatch(rotateWopiKeysAction()).unwrap();
+ }
+ // If config changes (enable or refreshLockInterval) but no rotate
+ else if ((enableChanged || refreshLockIntervalChanged) && !rotateRequested) {
+ const updatedConfig = mergeNestedObjects([configUpdates]);
+ await dispatch(saveConfig(updatedConfig)).unwrap();
+ }
+ // If both config changes and rotate requested, make two requests
+ else if ((enableChanged || refreshLockIntervalChanged) && rotateRequested) {
+ // First update the config settings
+ const updatedConfig = mergeNestedObjects([configUpdates]);
+ await dispatch(saveConfig(updatedConfig)).unwrap();
+ // Then rotate keys
+ await dispatch(rotateWopiKeysAction()).unwrap();
+ }
+
+ setHasChanges(false);
+ setLocalRotateKeys(false);
+ } catch (error) {
+ console.error('Failed to save WOPI settings:', error);
+ // Revert local state on error
+ setLocalWopiEnabled(configWopiEnabled);
+ setLocalRotateKeys(false);
+ setLocalRefreshLockInterval(configRefreshLockInterval);
+ setHasChanges(false);
+ }
+ };
+
+ return (
+
+
WOPI Settings
+
Configure WOPI (Web Application Open Platform Interface) support for document editing
+
+
+
+
+
+ {localWopiEnabled && (
+ <>
+
+
Lock Settings
+
Configure document lock refresh interval for WOPI sessions.
+
+
+
+
+
+
+
Key Management
+
+ Rotate WOPI encryption keys. Current keys will be moved to "Old" and new keys will be generated.
+
+
+ Do not rotate keys more than once per 24 hours; storage may not refresh in time and authentication can fail.
+
+
+
+
+
+
+
+
+ >
+ )}
+
+
+ Save Changes
+
+
+ );
+}
+
+export default WOPISettings;
diff --git a/AdminPanel/client/src/pages/WOPISettings/WOPISettings.module.scss b/AdminPanel/client/src/pages/WOPISettings/WOPISettings.module.scss
new file mode 100644
index 0000000000..8a5634d27f
--- /dev/null
+++ b/AdminPanel/client/src/pages/WOPISettings/WOPISettings.module.scss
@@ -0,0 +1,69 @@
+.wopiSettings {
+ padding: 0;
+}
+
+.pageWithFixedSave {
+ padding-bottom: 40px;
+}
+
+.loading {
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ height: 200px;
+ font-family: 'Open Sans', sans-serif;
+ color: #666666;
+}
+
+.settingsSection {
+ background: white;
+ border: 1px solid #e2e2e2;
+ border-radius: 8px;
+ padding: 32px;
+ margin-bottom: 32px;
+}
+
+.sectionTitle {
+ font-size: 18px;
+ font-weight: 600;
+ color: #333333;
+ margin-bottom: 8px;
+}
+
+.sectionDescription {
+ font-size: 14px;
+ color: #666666;
+ margin-bottom: 24px;
+ line-height: 1.5;
+}
+
+.noteWrapper {
+ margin-bottom: 20px;
+}
+
+.formRow {
+ margin-bottom: 16px;
+ display: flex;
+ align-items: flex-end;
+ gap: 16px;
+ flex-wrap: wrap;
+}
+
+// Ensure SaveButton aligns properly in form row
+:global(.saveButton) {
+ margin-top: 0;
+}
+
+// Override Input component styles for disabled key display
+:global(.input[disabled]) {
+ background-color: #f8f9fa !important;
+ color: #666666 !important;
+ cursor: not-allowed !important;
+ opacity: 0.8;
+}
+
+.actions {
+ display: flex;
+ justify-content: flex-start;
+ // padding-top: 16px;
+}
diff --git a/AdminPanel/client/src/store/index.js b/AdminPanel/client/src/store/index.js
new file mode 100644
index 0000000000..002855cf3e
--- /dev/null
+++ b/AdminPanel/client/src/store/index.js
@@ -0,0 +1,10 @@
+import {configureStore} from '@reduxjs/toolkit';
+import userReducer from './slices/userSlice';
+import configReducer from './slices/configSlice';
+
+export const store = configureStore({
+ reducer: {
+ user: userReducer,
+ config: configReducer
+ }
+});
diff --git a/AdminPanel/client/src/store/slices/configSlice.js b/AdminPanel/client/src/store/slices/configSlice.js
new file mode 100644
index 0000000000..ed193fc21a
--- /dev/null
+++ b/AdminPanel/client/src/store/slices/configSlice.js
@@ -0,0 +1,141 @@
+import {createSlice, createAsyncThunk} from '@reduxjs/toolkit';
+import {fetchConfiguration, fetchConfigurationSchema, updateConfiguration, rotateWopiKeys} from '../../api';
+
+export const fetchConfig = createAsyncThunk('config/fetchConfig', async (_, {rejectWithValue}) => {
+ try {
+ const config = await fetchConfiguration();
+ return {config};
+ } catch (error) {
+ return rejectWithValue(error.message);
+ }
+});
+
+export const fetchSchema = createAsyncThunk('config/fetchSchema', async (_, {rejectWithValue}) => {
+ try {
+ const schema = await fetchConfigurationSchema();
+ return {schema};
+ } catch (error) {
+ return rejectWithValue(error.message);
+ }
+});
+
+export const saveConfig = createAsyncThunk('config/saveConfig', async (configData, {rejectWithValue}) => {
+ try {
+ const newConfig = await updateConfiguration(configData);
+ return newConfig;
+ } catch (error) {
+ return rejectWithValue(error.message);
+ }
+});
+
+export const rotateWopiKeysAction = createAsyncThunk('config/rotateWopiKeys', async (_, {rejectWithValue}) => {
+ try {
+ const newConfig = await rotateWopiKeys();
+ return newConfig;
+ } catch (error) {
+ return rejectWithValue(error.message);
+ }
+});
+
+const initialState = {
+ config: null,
+ schema: null,
+ loading: false,
+ schemaLoading: false,
+ saving: false,
+ error: null,
+ schemaError: null
+};
+
+const configSlice = createSlice({
+ name: 'config',
+ initialState,
+ reducers: {
+ updateLocalConfig: (state, action) => {
+ // Merge updates into local config without saving
+ if (state.config) {
+ state.config = {...state.config, ...action.payload};
+ }
+ },
+ clearConfig: state => {
+ state.config = null;
+ state.loading = false;
+ state.error = null;
+ },
+ clearError: state => {
+ state.error = null;
+ }
+ },
+ extraReducers: builder => {
+ builder
+ // Fetch config cases
+ .addCase(fetchConfig.pending, state => {
+ state.loading = true;
+ state.error = null;
+ })
+ .addCase(fetchConfig.fulfilled, (state, action) => {
+ state.loading = false;
+ state.config = action.payload.config;
+ state.error = null;
+ })
+ .addCase(fetchConfig.rejected, (state, action) => {
+ state.loading = false;
+ state.error = action.payload;
+ })
+ // Fetch schema cases
+ .addCase(fetchSchema.pending, state => {
+ state.schemaLoading = true;
+ state.schemaError = null;
+ })
+ .addCase(fetchSchema.fulfilled, (state, action) => {
+ state.schemaLoading = false;
+ state.schema = action.payload.schema;
+ state.schemaError = null;
+ })
+ .addCase(fetchSchema.rejected, (state, action) => {
+ state.schemaLoading = false;
+ state.schemaError = action.payload;
+ })
+ // Save config cases
+ .addCase(saveConfig.pending, state => {
+ state.saving = true;
+ state.error = null;
+ })
+ .addCase(saveConfig.fulfilled, (state, action) => {
+ state.saving = false;
+ // Update the global config with the complete new config from server
+ state.config = action.payload;
+ state.error = null;
+ })
+ .addCase(saveConfig.rejected, (state, action) => {
+ state.saving = false;
+ state.error = action.payload;
+ })
+ .addCase(rotateWopiKeysAction.pending, state => {
+ state.saving = true;
+ state.error = null;
+ })
+ .addCase(rotateWopiKeysAction.fulfilled, (state, action) => {
+ state.saving = false;
+ state.config = action.payload;
+ state.error = null;
+ })
+ .addCase(rotateWopiKeysAction.rejected, (state, action) => {
+ state.saving = false;
+ state.error = action.payload;
+ });
+ }
+});
+
+export const {updateLocalConfig, clearConfig, clearError} = configSlice.actions;
+
+// Selectors
+export const selectConfig = state => state.config.config;
+export const selectSchema = state => state.config.schema;
+export const selectConfigLoading = state => state.config.loading;
+export const selectSchemaLoading = state => state.config.schemaLoading;
+export const selectConfigSaving = state => state.config.saving;
+export const selectConfigError = state => state.config.error;
+export const selectSchemaError = state => state.config.schemaError;
+
+export default configSlice.reducer;
diff --git a/AdminPanel/client/src/store/slices/userSlice.js b/AdminPanel/client/src/store/slices/userSlice.js
new file mode 100644
index 0000000000..794eb73677
--- /dev/null
+++ b/AdminPanel/client/src/store/slices/userSlice.js
@@ -0,0 +1,66 @@
+import {createSlice, createAsyncThunk} from '@reduxjs/toolkit';
+import {fetchCurrentUser} from '../../api';
+
+export const fetchUser = createAsyncThunk('user/fetchUser', async (_, {rejectWithValue}) => {
+ try {
+ return await fetchCurrentUser();
+ } catch (error) {
+ return rejectWithValue(error.message);
+ }
+});
+
+const initialState = {
+ user: null,
+ loading: false,
+ error: null,
+ isAuthenticated: false
+};
+
+const userSlice = createSlice({
+ name: 'user',
+ initialState,
+ reducers: {
+ // Clear user data (logout)
+ clearUser: state => {
+ state.user = null;
+ state.isAuthenticated = false;
+ state.error = null;
+ },
+ // Clear error
+ clearError: state => {
+ state.error = null;
+ }
+ },
+ extraReducers: builder => {
+ builder
+ // Fetch user cases
+ .addCase(fetchUser.pending, state => {
+ state.loading = true;
+ state.error = null;
+ })
+ .addCase(fetchUser.fulfilled, (state, action) => {
+ state.loading = false;
+ state.user = {
+ tenant: action.payload.tenant,
+ isAdmin: action.payload.isAdmin
+ };
+ state.isAuthenticated = true;
+ state.error = null;
+ })
+ .addCase(fetchUser.rejected, (state, action) => {
+ state.loading = false;
+ state.error = action.payload;
+ state.isAuthenticated = false;
+ });
+ }
+});
+
+export const {clearUser, clearError} = userSlice.actions;
+
+// Selectors
+export const selectUser = state => state.user.user;
+export const selectUserLoading = state => state.user.loading;
+export const selectUserError = state => state.user.error;
+export const selectIsAuthenticated = state => state.user.isAuthenticated;
+
+export default userSlice.reducer;
diff --git a/AdminPanel/client/src/utils/getNestedValue.js b/AdminPanel/client/src/utils/getNestedValue.js
new file mode 100644
index 0000000000..00e25947c8
--- /dev/null
+++ b/AdminPanel/client/src/utils/getNestedValue.js
@@ -0,0 +1,16 @@
+export function getNestedValue(obj, path, defaultValue = '') {
+ if (!obj || !path) return defaultValue;
+
+ const keys = path.split('.');
+ let current = obj;
+
+ for (const key of keys) {
+ if (current && typeof current === 'object' && key in current) {
+ current = current[key];
+ } else {
+ return defaultValue;
+ }
+ }
+
+ return current !== undefined ? current : defaultValue;
+}
diff --git a/AdminPanel/client/src/utils/maskKey.js b/AdminPanel/client/src/utils/maskKey.js
new file mode 100644
index 0000000000..5be9841e54
--- /dev/null
+++ b/AdminPanel/client/src/utils/maskKey.js
@@ -0,0 +1,20 @@
+/**
+ * Masks a key string to show only first 5 and last 10 characters
+ * Format: ABCDE...FGHIJKLMNO
+ * @param {string} key - The key string to mask
+ * @returns {string} - The masked key string
+ */
+export const maskKey = key => {
+ if (!key || typeof key !== 'string') {
+ return '';
+ }
+
+ if (key.length <= 15) {
+ return key;
+ }
+
+ const firstPart = key.substring(0, 5);
+ const lastPart = key.substring(key.length - 10);
+
+ return `${firstPart}...${lastPart}`;
+};
diff --git a/AdminPanel/client/src/utils/mergeNestedObjects.js b/AdminPanel/client/src/utils/mergeNestedObjects.js
new file mode 100644
index 0000000000..d2a34694c1
--- /dev/null
+++ b/AdminPanel/client/src/utils/mergeNestedObjects.js
@@ -0,0 +1,27 @@
+export function mergeNestedObjects(objects) {
+ const result = {};
+
+ for (const obj of objects) {
+ for (const key in obj) {
+ if (Object.hasOwn(obj, key)) {
+ const keys = key.split('.');
+ let current = result;
+
+ for (let i = 0; i < keys.length; i++) {
+ const part = keys[i];
+
+ if (i === keys.length - 1) {
+ current[part] = obj[key];
+ } else {
+ if (!current[part]) {
+ current[part] = {};
+ }
+ current = current[part];
+ }
+ }
+ }
+ }
+ }
+
+ return result;
+}
diff --git a/AdminPanel/client/webpack.config.js b/AdminPanel/client/webpack.config.js
new file mode 100644
index 0000000000..a33ffd44ad
--- /dev/null
+++ b/AdminPanel/client/webpack.config.js
@@ -0,0 +1,161 @@
+const path = require('path');
+const HtmlWebpackPlugin = require('html-webpack-plugin');
+const CopyPlugin = require('copy-webpack-plugin');
+const webpack = require('webpack');
+const dotenv = require('dotenv');
+
+module.exports = (env, argv) => {
+ const mode = argv && argv.mode ? argv.mode : 'development';
+
+ // Load environment variables from .env files
+ // Priority: .env.local > .env.development/.env.production > .env
+ const envFiles = ['.env.local', mode === 'production' ? '.env.production' : '.env.development', '.env'];
+
+ envFiles.forEach(file => {
+ dotenv.config({path: file});
+ });
+
+ return {
+ entry: './src/index.js',
+ output: {
+ filename: 'main.[contenthash].js',
+ path: path.resolve(__dirname, 'build'),
+ // Use relative URLs so assets load under any prefix (e.g., /admin)
+ publicPath: '',
+ // Clean the output directory before emit to avoid stale files (e.g., js/js duplicates)
+ clean: true
+ },
+
+ devServer: {
+ static: {
+ directory: path.join(__dirname, 'build'),
+ publicPath: ''
+ },
+ port: 3000,
+ open: true,
+ historyApiFallback: true,
+ proxy: {
+ '/healthcheck-api': {
+ target: process.env.REACT_APP_DOCSERVICE_URL,
+ changeOrigin: true,
+ pathRewrite: {
+ '^/healthcheck-api': '/healthcheck'
+ }
+ }
+ }
+ },
+
+ plugins: [
+ new HtmlWebpackPlugin({
+ template: path.join(__dirname, 'public', 'index.html')
+ }),
+ new CopyPlugin({
+ patterns: [
+ {
+ context: path.resolve(__dirname, 'public'),
+ from: 'images/*.*',
+ to: 'images/[name][ext]'
+ },
+ {
+ context: path.resolve(__dirname, 'src/assets'),
+ from: '*.svg',
+ to: 'static/[name][ext]'
+ },
+ {
+ context: path.resolve(__dirname, 'src', 'pages', 'AiIntegration', 'css'),
+ from: '**/*',
+ to: 'css'
+ },
+ {
+ context: path.resolve(__dirname, 'src', 'pages', 'AiIntegration', 'js'),
+ from: '**/*',
+ to: 'js'
+ },
+ {
+ context: path.resolve(__dirname, 'src', 'pages', 'AiIntegration', 'ai'),
+ from: '**/*',
+ to: 'ai'
+ },
+ {
+ context: path.resolve(__dirname, '../../../document-templates/sample'),
+ from: 'sample.docx',
+ to: 'assets/sample.docx',
+ noErrorOnMissing: true
+ }
+ ]
+ }),
+ new webpack.DefinePlugin({
+ 'process.env.REACT_APP_BACKEND_URL': JSON.stringify(process.env.REACT_APP_BACKEND_URL),
+ 'process.env.REACT_APP_DOCSERVICE_URL': JSON.stringify(process.env.REACT_APP_DOCSERVICE_URL)
+ })
+ ],
+
+ module: {
+ rules: [
+ {
+ test: /\.(js)$/,
+ exclude: /node_modules/,
+ use: {
+ loader: 'babel-loader',
+ options: {
+ presets: [['@babel/preset-react', {runtime: 'automatic'}], '@babel/preset-env']
+ }
+ }
+ },
+ {
+ test: /\.module\.(css|scss)$/i,
+ use: [
+ 'style-loader',
+ {
+ loader: 'css-loader',
+ options: {
+ modules: {
+ localIdentName: '[local]-[hash:base64:5]'
+ }
+ }
+ },
+ {
+ loader: 'sass-loader',
+ options: {
+ api: 'modern'
+ }
+ }
+ ]
+ },
+ {
+ test: /\.(css|scss)$/i,
+ exclude: /\.module\.(css|scss)$/i,
+ use: [
+ 'style-loader',
+ 'css-loader',
+ {
+ loader: 'sass-loader',
+ options: {
+ api: 'modern'
+ }
+ }
+ ]
+ },
+ {
+ test: /\.(png|svg|jpg|jpeg|gif)$/i,
+ type: 'asset/resource',
+ generator: {
+ filename: 'static/[hash][ext]'
+ }
+ }
+ ]
+ },
+
+ resolve: {
+ extensions: ['', '.js'],
+ alias: {
+ '@components': path.resolve(__dirname, 'src/components'),
+ '@screen': path.resolve(__dirname, 'src/screen'),
+ '@services': path.resolve(__dirname, 'src/services'),
+ '@store': path.resolve(__dirname, 'src/store'),
+ '@utility': path.resolve(__dirname, 'src/utility'),
+ '@assets': path.resolve(__dirname, 'src/assets')
+ }
+ }
+ };
+};
diff --git a/AdminPanel/server/.gitignore b/AdminPanel/server/.gitignore
new file mode 100644
index 0000000000..607842428f
--- /dev/null
+++ b/AdminPanel/server/.gitignore
@@ -0,0 +1,4 @@
+runtime/config.json
+node_modules/
+
+
diff --git a/AdminPanel/server/package-lock.json b/AdminPanel/server/package-lock.json
new file mode 100644
index 0000000000..954fe8e9af
--- /dev/null
+++ b/AdminPanel/server/package-lock.json
@@ -0,0 +1,755 @@
+{
+ "name": "onlyoffice-adminpanel-server",
+ "version": "1.0.0",
+ "lockfileVersion": 1,
+ "requires": true,
+ "dependencies": {
+ "@hapi/hoek": {
+ "version": "9.3.0",
+ "resolved": "https://registry.npmjs.org/@hapi/hoek/-/hoek-9.3.0.tgz",
+ "integrity": "sha512-/c6rf4UJlmHlC9b5BaNvzAcFv7HZ2QHaV0D4/HNlBdvFnvQq8RI4kYdhyPCl7Xj+oWvTWQ8ujhqS53LIgAe6KQ=="
+ },
+ "@hapi/topo": {
+ "version": "5.1.0",
+ "resolved": "https://registry.npmjs.org/@hapi/topo/-/topo-5.1.0.tgz",
+ "integrity": "sha512-foQZKJig7Ob0BMAYBfcJk8d77QtOe7Wo4ox7ff1lQYoNNAb6jwcY1ncdoy2e9wQZzvNy7ODZCYJkK8kzmcAnAg==",
+ "requires": {
+ "@hapi/hoek": "^9.0.0"
+ }
+ },
+ "@sideway/address": {
+ "version": "4.1.5",
+ "resolved": "https://registry.npmjs.org/@sideway/address/-/address-4.1.5.tgz",
+ "integrity": "sha512-IqO/DUQHUkPeixNQ8n0JA6102hT9CmaljNTPmQ1u8MEhBo/R4Q8eKLN/vGZxuebwOroDB4cbpjheD4+/sKFK4Q==",
+ "requires": {
+ "@hapi/hoek": "^9.0.0"
+ }
+ },
+ "@sideway/formula": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/@sideway/formula/-/formula-3.0.1.tgz",
+ "integrity": "sha512-/poHZJJVjx3L+zVD6g9KgHfYnb443oi7wLu/XKojDviHy6HOEOA6z1Trk5aR1dGcmPenJEgb2sK2I80LeS3MIg=="
+ },
+ "@sideway/pinpoint": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/@sideway/pinpoint/-/pinpoint-2.0.0.tgz",
+ "integrity": "sha512-RNiOoTPkptFtSVzQevY/yWtZwf/RxyVnPy/OcA9HBM3MlGDnBEYL5B41H0MTn0Uec8Hi+2qUtTfG2WWZBmMejQ=="
+ },
+ "accepts": {
+ "version": "1.3.8",
+ "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz",
+ "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==",
+ "requires": {
+ "mime-types": "~2.1.34",
+ "negotiator": "0.6.3"
+ }
+ },
+ "ajv": {
+ "version": "8.17.1",
+ "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz",
+ "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==",
+ "requires": {
+ "fast-deep-equal": "^3.1.3",
+ "fast-uri": "^3.0.1",
+ "json-schema-traverse": "^1.0.0",
+ "require-from-string": "^2.0.2"
+ }
+ },
+ "ajv-formats": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-2.1.1.tgz",
+ "integrity": "sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA==",
+ "requires": {
+ "ajv": "^8.0.0"
+ }
+ },
+ "apicache": {
+ "version": "1.6.3",
+ "resolved": "https://registry.npmjs.org/apicache/-/apicache-1.6.3.tgz",
+ "integrity": "sha512-jS3VfUFpQ9BesFQZcdd1vVYg3ZsO2kGPmTJHqycIYPAQs54r74CRiyj8DuzJpwzLwIfCBYzh4dy9Jt8xYbo27w=="
+ },
+ "array-flatten": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz",
+ "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg=="
+ },
+ "body-parser": {
+ "version": "1.20.3",
+ "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.3.tgz",
+ "integrity": "sha512-7rAxByjUMqQ3/bHJy7D6OGXvx/MMc4IqBn/X0fcM1QUcAItpZrBEYhWGem+tzXH90c+G01ypMcYJBO9Y30203g==",
+ "requires": {
+ "bytes": "3.1.2",
+ "content-type": "~1.0.5",
+ "debug": "2.6.9",
+ "depd": "2.0.0",
+ "destroy": "1.2.0",
+ "http-errors": "2.0.0",
+ "iconv-lite": "0.4.24",
+ "on-finished": "2.4.1",
+ "qs": "6.13.0",
+ "raw-body": "2.5.2",
+ "type-is": "~1.6.18",
+ "unpipe": "1.0.0"
+ }
+ },
+ "buffer-equal-constant-time": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz",
+ "integrity": "sha512-zRpUiDwd/xk6ADqPMATG8vc9VPrkck7T07OIx0gnjmJAnHnTVXNQG3vfvWNuiZIkwu9KrKdA1iJKfsfTVxE6NA=="
+ },
+ "bytes": {
+ "version": "3.1.2",
+ "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz",
+ "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg=="
+ },
+ "call-bind-apply-helpers": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz",
+ "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==",
+ "requires": {
+ "es-errors": "^1.3.0",
+ "function-bind": "^1.1.2"
+ }
+ },
+ "call-bound": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/call-bound/-/call-bound-1.0.4.tgz",
+ "integrity": "sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==",
+ "requires": {
+ "call-bind-apply-helpers": "^1.0.2",
+ "get-intrinsic": "^1.3.0"
+ }
+ },
+ "config": {
+ "version": "3.3.12",
+ "resolved": "https://registry.npmjs.org/config/-/config-3.3.12.tgz",
+ "integrity": "sha512-Vmx389R/QVM3foxqBzXO8t2tUikYZP64Q6vQxGrsMpREeJc/aWRnPRERXWsYzOHAumx/AOoILWe6nU3ZJL+6Sw==",
+ "requires": {
+ "json5": "^2.2.3"
+ }
+ },
+ "content-disposition": {
+ "version": "0.5.4",
+ "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz",
+ "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==",
+ "requires": {
+ "safe-buffer": "5.2.1"
+ }
+ },
+ "content-type": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz",
+ "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA=="
+ },
+ "cookie": {
+ "version": "0.7.2",
+ "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.7.2.tgz",
+ "integrity": "sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w=="
+ },
+ "cookie-parser": {
+ "version": "1.4.7",
+ "resolved": "https://registry.npmjs.org/cookie-parser/-/cookie-parser-1.4.7.tgz",
+ "integrity": "sha512-nGUvgXnotP3BsjiLX2ypbQnWoGUPIIfHQNZkkC668ntrzGWEZVW70HDEB1qnNGMicPje6EttlIgzo51YSwNQGw==",
+ "requires": {
+ "cookie": "0.7.2",
+ "cookie-signature": "1.0.6"
+ }
+ },
+ "cookie-signature": {
+ "version": "1.0.6",
+ "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz",
+ "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ=="
+ },
+ "cors": {
+ "version": "2.8.5",
+ "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz",
+ "integrity": "sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==",
+ "requires": {
+ "object-assign": "^4",
+ "vary": "^1"
+ }
+ },
+ "debug": {
+ "version": "2.6.9",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
+ "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
+ "requires": {
+ "ms": "2.0.0"
+ },
+ "dependencies": {
+ "ms": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
+ "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A=="
+ }
+ }
+ },
+ "depd": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz",
+ "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw=="
+ },
+ "destroy": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz",
+ "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg=="
+ },
+ "dunder-proto": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz",
+ "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==",
+ "requires": {
+ "call-bind-apply-helpers": "^1.0.1",
+ "es-errors": "^1.3.0",
+ "gopd": "^1.2.0"
+ }
+ },
+ "ecdsa-sig-formatter": {
+ "version": "1.0.11",
+ "resolved": "https://registry.npmjs.org/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz",
+ "integrity": "sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==",
+ "requires": {
+ "safe-buffer": "^5.0.1"
+ }
+ },
+ "ee-first": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz",
+ "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow=="
+ },
+ "encodeurl": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-2.0.0.tgz",
+ "integrity": "sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg=="
+ },
+ "es-define-property": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz",
+ "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g=="
+ },
+ "es-errors": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz",
+ "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw=="
+ },
+ "es-object-atoms": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz",
+ "integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==",
+ "requires": {
+ "es-errors": "^1.3.0"
+ }
+ },
+ "escape-html": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz",
+ "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow=="
+ },
+ "etag": {
+ "version": "1.8.1",
+ "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz",
+ "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg=="
+ },
+ "express": {
+ "version": "4.21.2",
+ "resolved": "https://registry.npmjs.org/express/-/express-4.21.2.tgz",
+ "integrity": "sha512-28HqgMZAmih1Czt9ny7qr6ek2qddF4FclbMzwhCREB6OFfH+rXAnuNCwo1/wFvrtbgsQDb4kSbX9de9lFbrXnA==",
+ "requires": {
+ "accepts": "~1.3.8",
+ "array-flatten": "1.1.1",
+ "body-parser": "1.20.3",
+ "content-disposition": "0.5.4",
+ "content-type": "~1.0.4",
+ "cookie": "0.7.1",
+ "cookie-signature": "1.0.6",
+ "debug": "2.6.9",
+ "depd": "2.0.0",
+ "encodeurl": "~2.0.0",
+ "escape-html": "~1.0.3",
+ "etag": "~1.8.1",
+ "finalhandler": "1.3.1",
+ "fresh": "0.5.2",
+ "http-errors": "2.0.0",
+ "merge-descriptors": "1.0.3",
+ "methods": "~1.1.2",
+ "on-finished": "2.4.1",
+ "parseurl": "~1.3.3",
+ "path-to-regexp": "0.1.12",
+ "proxy-addr": "~2.0.7",
+ "qs": "6.13.0",
+ "range-parser": "~1.2.1",
+ "safe-buffer": "5.2.1",
+ "send": "0.19.0",
+ "serve-static": "1.16.2",
+ "setprototypeof": "1.2.0",
+ "statuses": "2.0.1",
+ "type-is": "~1.6.18",
+ "utils-merge": "1.0.1",
+ "vary": "~1.1.2"
+ },
+ "dependencies": {
+ "cookie": {
+ "version": "0.7.1",
+ "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.7.1.tgz",
+ "integrity": "sha512-6DnInpx7SJ2AK3+CTUE/ZM0vWTUboZCegxhC2xiIydHR9jNuTAASBrfEpHhiGOZw/nX51bHt6YQl8jsGo4y/0w=="
+ }
+ }
+ },
+ "fast-deep-equal": {
+ "version": "3.1.3",
+ "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz",
+ "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q=="
+ },
+ "fast-uri": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.1.0.tgz",
+ "integrity": "sha512-iPeeDKJSWf4IEOasVVrknXpaBV0IApz/gp7S2bb7Z4Lljbl2MGJRqInZiUrQwV16cpzw/D3S5j5Julj/gT52AA=="
+ },
+ "finalhandler": {
+ "version": "1.3.1",
+ "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.3.1.tgz",
+ "integrity": "sha512-6BN9trH7bp3qvnrRyzsBz+g3lZxTNZTbVO2EV1CS0WIcDbawYVdYvGflME/9QP0h0pYlCDBCTjYa9nZzMDpyxQ==",
+ "requires": {
+ "debug": "2.6.9",
+ "encodeurl": "~2.0.0",
+ "escape-html": "~1.0.3",
+ "on-finished": "2.4.1",
+ "parseurl": "~1.3.3",
+ "statuses": "2.0.1",
+ "unpipe": "~1.0.0"
+ }
+ },
+ "forwarded": {
+ "version": "0.2.0",
+ "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz",
+ "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow=="
+ },
+ "fresh": {
+ "version": "0.5.2",
+ "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz",
+ "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q=="
+ },
+ "function-bind": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz",
+ "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA=="
+ },
+ "get-intrinsic": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz",
+ "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==",
+ "requires": {
+ "call-bind-apply-helpers": "^1.0.2",
+ "es-define-property": "^1.0.1",
+ "es-errors": "^1.3.0",
+ "es-object-atoms": "^1.1.1",
+ "function-bind": "^1.1.2",
+ "get-proto": "^1.0.1",
+ "gopd": "^1.2.0",
+ "has-symbols": "^1.1.0",
+ "hasown": "^2.0.2",
+ "math-intrinsics": "^1.1.0"
+ }
+ },
+ "get-proto": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz",
+ "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==",
+ "requires": {
+ "dunder-proto": "^1.0.1",
+ "es-object-atoms": "^1.0.0"
+ }
+ },
+ "gopd": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz",
+ "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg=="
+ },
+ "has-symbols": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz",
+ "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ=="
+ },
+ "hasown": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz",
+ "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==",
+ "requires": {
+ "function-bind": "^1.1.2"
+ }
+ },
+ "http-errors": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz",
+ "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==",
+ "requires": {
+ "depd": "2.0.0",
+ "inherits": "2.0.4",
+ "setprototypeof": "1.2.0",
+ "statuses": "2.0.1",
+ "toidentifier": "1.0.1"
+ }
+ },
+ "iconv-lite": {
+ "version": "0.4.24",
+ "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz",
+ "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==",
+ "requires": {
+ "safer-buffer": ">= 2.1.2 < 3"
+ }
+ },
+ "inherits": {
+ "version": "2.0.4",
+ "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
+ "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ=="
+ },
+ "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=="
+ },
+ "joi": {
+ "version": "17.13.3",
+ "resolved": "https://registry.npmjs.org/joi/-/joi-17.13.3.tgz",
+ "integrity": "sha512-otDA4ldcIx+ZXsKHWmp0YizCweVRZG96J10b0FevjfuncLO1oX59THoAmHkNubYJ+9gWsYsp5k8v4ib6oDv1fA==",
+ "requires": {
+ "@hapi/hoek": "^9.3.0",
+ "@hapi/topo": "^5.1.0",
+ "@sideway/address": "^4.1.5",
+ "@sideway/formula": "^3.0.1",
+ "@sideway/pinpoint": "^2.0.0"
+ }
+ },
+ "json-schema-traverse": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz",
+ "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug=="
+ },
+ "json5": {
+ "version": "2.2.3",
+ "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz",
+ "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg=="
+ },
+ "jsonwebtoken": {
+ "version": "9.0.2",
+ "resolved": "https://registry.npmjs.org/jsonwebtoken/-/jsonwebtoken-9.0.2.tgz",
+ "integrity": "sha512-PRp66vJ865SSqOlgqS8hujT5U4AOgMfhrwYIuIhfKaoSCZcirrmASQr8CX7cUg+RMih+hgznrjp99o+W4pJLHQ==",
+ "requires": {
+ "jws": "^3.2.2",
+ "lodash.includes": "^4.3.0",
+ "lodash.isboolean": "^3.0.3",
+ "lodash.isinteger": "^4.0.4",
+ "lodash.isnumber": "^3.0.3",
+ "lodash.isplainobject": "^4.0.6",
+ "lodash.isstring": "^4.0.1",
+ "lodash.once": "^4.0.0",
+ "ms": "^2.1.1",
+ "semver": "^7.5.4"
+ }
+ },
+ "jwa": {
+ "version": "1.4.2",
+ "resolved": "https://registry.npmjs.org/jwa/-/jwa-1.4.2.tgz",
+ "integrity": "sha512-eeH5JO+21J78qMvTIDdBXidBd6nG2kZjg5Ohz/1fpa28Z4CcsWUzJ1ZZyFq/3z3N17aZy+ZuBoHljASbL1WfOw==",
+ "requires": {
+ "buffer-equal-constant-time": "^1.0.1",
+ "ecdsa-sig-formatter": "1.0.11",
+ "safe-buffer": "^5.0.1"
+ }
+ },
+ "jws": {
+ "version": "3.2.2",
+ "resolved": "https://registry.npmjs.org/jws/-/jws-3.2.2.tgz",
+ "integrity": "sha512-YHlZCB6lMTllWDtSPHz/ZXTsi8S00usEV6v1tjq8tOUZzw7DpSDWVXjXDre6ed1w/pd495ODpHZYSdkRTsa0HA==",
+ "requires": {
+ "jwa": "^1.4.1",
+ "safe-buffer": "^5.0.1"
+ }
+ },
+ "lodash.includes": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/lodash.includes/-/lodash.includes-4.3.0.tgz",
+ "integrity": "sha512-W3Bx6mdkRTGtlJISOvVD/lbqjTlPPUDTMnlXZFnVwi9NKJ6tiAk6LVdlhZMm17VZisqhKcgzpO5Wz91PCt5b0w=="
+ },
+ "lodash.isboolean": {
+ "version": "3.0.3",
+ "resolved": "https://registry.npmjs.org/lodash.isboolean/-/lodash.isboolean-3.0.3.tgz",
+ "integrity": "sha512-Bz5mupy2SVbPHURB98VAcw+aHh4vRV5IPNhILUCsOzRmsTmSQ17jIuqopAentWoehktxGd9e/hbIXq980/1QJg=="
+ },
+ "lodash.isinteger": {
+ "version": "4.0.4",
+ "resolved": "https://registry.npmjs.org/lodash.isinteger/-/lodash.isinteger-4.0.4.tgz",
+ "integrity": "sha512-DBwtEWN2caHQ9/imiNeEA5ys1JoRtRfY3d7V9wkqtbycnAmTvRRmbHKDV4a0EYc678/dia0jrte4tjYwVBaZUA=="
+ },
+ "lodash.isnumber": {
+ "version": "3.0.3",
+ "resolved": "https://registry.npmjs.org/lodash.isnumber/-/lodash.isnumber-3.0.3.tgz",
+ "integrity": "sha512-QYqzpfwO3/CWf3XP+Z+tkQsfaLL/EnUlXWVkIk5FUPc4sBdTehEqZONuyRt2P67PXAk+NXmTBcc97zw9t1FQrw=="
+ },
+ "lodash.isplainobject": {
+ "version": "4.0.6",
+ "resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz",
+ "integrity": "sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA=="
+ },
+ "lodash.isstring": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/lodash.isstring/-/lodash.isstring-4.0.1.tgz",
+ "integrity": "sha512-0wJxfxH1wgO3GrbuP+dTTk7op+6L41QCXbGINEmD+ny/G/eCqGzxyCsh7159S+mgDDcoarnBw6PC1PS5+wUGgw=="
+ },
+ "lodash.once": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/lodash.once/-/lodash.once-4.1.1.tgz",
+ "integrity": "sha512-Sb487aTOCr9drQVL8pIxOzVhafOjZN9UU54hiN8PU3uAiSV7lx1yYNpbNmex2PK6dSJoNTSJUUswT651yww3Mg=="
+ },
+ "math-intrinsics": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz",
+ "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g=="
+ },
+ "media-typer": {
+ "version": "0.3.0",
+ "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz",
+ "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ=="
+ },
+ "merge-descriptors": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.3.tgz",
+ "integrity": "sha512-gaNvAS7TZ897/rVaZ0nMtAyxNyi/pdbjbAwUpFQpN70GqnVfOiXpeUUMKRBmzXaSQ8DdTX4/0ms62r2K+hE6mQ=="
+ },
+ "methods": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz",
+ "integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w=="
+ },
+ "mime": {
+ "version": "1.6.0",
+ "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz",
+ "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg=="
+ },
+ "mime-db": {
+ "version": "1.52.0",
+ "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz",
+ "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg=="
+ },
+ "mime-types": {
+ "version": "2.1.35",
+ "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz",
+ "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==",
+ "requires": {
+ "mime-db": "1.52.0"
+ }
+ },
+ "ms": {
+ "version": "2.1.3",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
+ "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA=="
+ },
+ "negotiator": {
+ "version": "0.6.3",
+ "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz",
+ "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg=="
+ },
+ "object-assign": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
+ "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg=="
+ },
+ "object-inspect": {
+ "version": "1.13.4",
+ "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.4.tgz",
+ "integrity": "sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew=="
+ },
+ "on-finished": {
+ "version": "2.4.1",
+ "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz",
+ "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==",
+ "requires": {
+ "ee-first": "1.1.1"
+ }
+ },
+ "parseurl": {
+ "version": "1.3.3",
+ "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz",
+ "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ=="
+ },
+ "path-to-regexp": {
+ "version": "0.1.12",
+ "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.12.tgz",
+ "integrity": "sha512-RA1GjUVMnvYFxuqovrEqZoxxW5NUZqbwKtYz/Tt7nXerk0LbLblQmrsgdeOxV5SFHf0UDggjS/bSeOZwt1pmEQ=="
+ },
+ "proxy-addr": {
+ "version": "2.0.7",
+ "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz",
+ "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==",
+ "requires": {
+ "forwarded": "0.2.0",
+ "ipaddr.js": "1.9.1"
+ }
+ },
+ "qs": {
+ "version": "6.13.0",
+ "resolved": "https://registry.npmjs.org/qs/-/qs-6.13.0.tgz",
+ "integrity": "sha512-+38qI9SOr8tfZ4QmJNplMUxqjbe7LKvvZgWdExBOmd+egZTtjLB67Gu0HRX3u/XOq7UU2Nx6nsjvS16Z9uwfpg==",
+ "requires": {
+ "side-channel": "^1.0.6"
+ }
+ },
+ "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=="
+ },
+ "raw-body": {
+ "version": "2.5.2",
+ "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.2.tgz",
+ "integrity": "sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA==",
+ "requires": {
+ "bytes": "3.1.2",
+ "http-errors": "2.0.0",
+ "iconv-lite": "0.4.24",
+ "unpipe": "1.0.0"
+ }
+ },
+ "require-from-string": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz",
+ "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw=="
+ },
+ "safe-buffer": {
+ "version": "5.2.1",
+ "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz",
+ "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ=="
+ },
+ "safer-buffer": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
+ "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg=="
+ },
+ "semver": {
+ "version": "7.7.2",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.2.tgz",
+ "integrity": "sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA=="
+ },
+ "send": {
+ "version": "0.19.0",
+ "resolved": "https://registry.npmjs.org/send/-/send-0.19.0.tgz",
+ "integrity": "sha512-dW41u5VfLXu8SJh5bwRmyYUbAoSB3c9uQh6L8h/KtsFREPWpbX1lrljJo186Jc4nmci/sGUZ9a0a0J2zgfq2hw==",
+ "requires": {
+ "debug": "2.6.9",
+ "depd": "2.0.0",
+ "destroy": "1.2.0",
+ "encodeurl": "~1.0.2",
+ "escape-html": "~1.0.3",
+ "etag": "~1.8.1",
+ "fresh": "0.5.2",
+ "http-errors": "2.0.0",
+ "mime": "1.6.0",
+ "ms": "2.1.3",
+ "on-finished": "2.4.1",
+ "range-parser": "~1.2.1",
+ "statuses": "2.0.1"
+ },
+ "dependencies": {
+ "encodeurl": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz",
+ "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w=="
+ }
+ }
+ },
+ "serve-static": {
+ "version": "1.16.2",
+ "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.16.2.tgz",
+ "integrity": "sha512-VqpjJZKadQB/PEbEwvFdO43Ax5dFBZ2UECszz8bQ7pi7wt//PWe1P6MN7eCnjsatYtBT6EuiClbjSWP2WrIoTw==",
+ "requires": {
+ "encodeurl": "~2.0.0",
+ "escape-html": "~1.0.3",
+ "parseurl": "~1.3.3",
+ "send": "0.19.0"
+ }
+ },
+ "setprototypeof": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz",
+ "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw=="
+ },
+ "side-channel": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.1.0.tgz",
+ "integrity": "sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==",
+ "requires": {
+ "es-errors": "^1.3.0",
+ "object-inspect": "^1.13.3",
+ "side-channel-list": "^1.0.0",
+ "side-channel-map": "^1.0.1",
+ "side-channel-weakmap": "^1.0.2"
+ }
+ },
+ "side-channel-list": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/side-channel-list/-/side-channel-list-1.0.0.tgz",
+ "integrity": "sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==",
+ "requires": {
+ "es-errors": "^1.3.0",
+ "object-inspect": "^1.13.3"
+ }
+ },
+ "side-channel-map": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/side-channel-map/-/side-channel-map-1.0.1.tgz",
+ "integrity": "sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==",
+ "requires": {
+ "call-bound": "^1.0.2",
+ "es-errors": "^1.3.0",
+ "get-intrinsic": "^1.2.5",
+ "object-inspect": "^1.13.3"
+ }
+ },
+ "side-channel-weakmap": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/side-channel-weakmap/-/side-channel-weakmap-1.0.2.tgz",
+ "integrity": "sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==",
+ "requires": {
+ "call-bound": "^1.0.2",
+ "es-errors": "^1.3.0",
+ "get-intrinsic": "^1.2.5",
+ "object-inspect": "^1.13.3",
+ "side-channel-map": "^1.0.1"
+ }
+ },
+ "statuses": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz",
+ "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ=="
+ },
+ "toidentifier": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz",
+ "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA=="
+ },
+ "type-is": {
+ "version": "1.6.18",
+ "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz",
+ "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==",
+ "requires": {
+ "media-typer": "0.3.0",
+ "mime-types": "~2.1.24"
+ }
+ },
+ "unpipe": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz",
+ "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ=="
+ },
+ "utils-merge": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz",
+ "integrity": "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA=="
+ },
+ "vary": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz",
+ "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg=="
+ }
+ }
+}
diff --git a/AdminPanel/server/package.json b/AdminPanel/server/package.json
new file mode 100644
index 0000000000..8aef1a5b4b
--- /dev/null
+++ b/AdminPanel/server/package.json
@@ -0,0 +1,32 @@
+{
+ "name": "adminpanel",
+ "version": "1.0.0",
+ "homepage": "https://www.onlyoffice.com",
+ "private": true,
+ "bin": {
+ "adminpanel": "sources/server.js"
+ },
+ "main": "sources/server.js",
+ "type": "commonjs",
+ "scripts": {
+ "start": "cd .. && npm --prefix client run build && set \"NODE_CONFIG_DIR=../Common/config\" && set \"NODE_ENV=development-windows\" && node server/sources/server.js"
+ },
+ "dependencies": {
+ "apicache": "^1.6.3",
+ "config": "^3.3.11",
+ "cookie-parser": "^1.4.6",
+ "cors": "^2.8.5",
+ "express": "^4.19.2",
+ "ajv": "^8.17.1",
+ "ajv-formats": "^2.1.1",
+ "joi": "^17.13.3",
+ "jsonwebtoken": "^9.0.2",
+ "ms": "^2.1.3"
+ },
+ "pkg": {
+ "scripts": [
+ "../../DocService/sources/editorDataMemory.js",
+ "../../DocService/sources/editorDataRedis.js"
+ ]
+ }
+}
diff --git a/AdminPanel/server/sources/bootstrap.js b/AdminPanel/server/sources/bootstrap.js
new file mode 100644
index 0000000000..573841ec0e
--- /dev/null
+++ b/AdminPanel/server/sources/bootstrap.js
@@ -0,0 +1,218 @@
+/*
+ * (c) Copyright Ascensio System SIA 2010-2024
+ *
+ * This program is a free software product. You can redistribute it and/or
+ * modify it under the terms of the GNU Affero General Public License (AGPL)
+ * version 3 as published by the Free Software Foundation. In accordance with
+ * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect
+ * that Ascensio System SIA expressly excludes the warranty of non-infringement
+ * of any third-party rights.
+ *
+ * This program is distributed WITHOUT ANY WARRANTY; without even the implied
+ * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For
+ * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html
+ *
+ * You can contact Ascensio System SIA at 20A-6 Ernesta Birznieka-Upish
+ * street, Riga, Latvia, EU, LV-1050.
+ *
+ * The interactive user interfaces in modified source and object code versions
+ * of the Program must display Appropriate Legal Notices, as required under
+ * Section 5 of the GNU AGPL version 3.
+ *
+ * Pursuant to Section 7(b) of the License you must retain the original Product
+ * logo when distributing the program. Pursuant to Section 7(e) we decline to
+ * grant you any rights under trademark law for use of our trademarks.
+ *
+ * All the Product's GUI elements, including illustrations and icon sets, as
+ * well as technical writing content are licensed under the terms of the
+ * Creative Commons Attribution-ShareAlike 4.0 International. See the License
+ * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode
+ *
+ */
+
+'use strict';
+
+const crypto = require('crypto');
+const runtimeConfigManager = require('../../../Common/sources/runtimeConfigManager');
+const passwordManager = require('./passwordManager');
+
+const BOOTSTRAP_TOKEN_TTL = 1 * 60 * 60 * 1000; // 1 hour
+const BOOTSTRAP_CODE_LENGTH = 12; // 12 chars = ~62 bits entropy (4.7 quintillion combinations)
+
+/**
+ * Bootstrap secret for HMAC-based code generation and verification
+ * REQUIRED for cluster: All pods must use the same ADMINPANEL_BOOTSTRAP_SECRET env variable
+ * This enables stateless verification across multiple nodes
+ */
+const BOOTSTRAP_SECRET = process.env.ADMINPANEL_BOOTSTRAP_SECRET || crypto.randomBytes(32).toString('hex');
+
+if (!process.env.ADMINPANEL_BOOTSTRAP_SECRET) {
+ console.info('ADMINPANEL_BOOTSTRAP_SECRET not set. Bootstrap codes will not work in cluster mode!');
+}
+
+/**
+ * In-memory cache for current bootstrap code (for display only)
+ * Actual verification is stateless and works across all cluster nodes
+ */
+let cachedBootstrapCode = null;
+
+/**
+ * Generate deterministic bootstrap code from timestamp and secret
+ * All cluster nodes with same secret will generate/verify same code for same time window
+ *
+ * @param {number} timestamp - Timestamp to generate code for
+ * @returns {string} 12-character code like "AB12CD34EF56"
+ */
+function generateShortCode(timestamp) {
+ // Round timestamp to TTL window (1 hour) for deterministic generation
+ const timeWindow = Math.floor(timestamp / BOOTSTRAP_TOKEN_TTL);
+
+ // Generate HMAC-based code using secret and time window
+ const hmac = crypto.createHmac('sha256', BOOTSTRAP_SECRET).update(`bootstrap:${timeWindow}`).digest('hex');
+
+ // Convert to readable alphanumeric code
+ const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';
+ let code = '';
+ for (let i = 0; i < BOOTSTRAP_CODE_LENGTH; i++) {
+ const byte = parseInt(hmac.substring(i * 2, i * 2 + 2), 16);
+ code += chars[byte % chars.length];
+ }
+ return code;
+}
+
+/**
+ * Generate bootstrap token for initial setup
+ * Code is deterministic based on time window and secret (cluster-safe)
+ * All pods with same secret will generate same code for current time window
+ *
+ * @param {import('../../../Common/sources/operationContext').Context} ctx - Operation context
+ * @returns {Promise<{code: string, expiresAt: Date}>}
+ */
+async function generateBootstrapToken(ctx) {
+ const now = Date.now();
+ const code = generateShortCode(now);
+ const expiresAt = new Date(Math.ceil(now / BOOTSTRAP_TOKEN_TTL) * BOOTSTRAP_TOKEN_TTL);
+
+ // Cache for display (same code will be generated by all nodes)
+ cachedBootstrapCode = {
+ code,
+ expiresAt,
+ generatedAt: now
+ };
+
+ ctx.logger.info('Bootstrap code generated (valid until %s)', expiresAt.toISOString());
+
+ return {code, expiresAt};
+}
+
+/**
+ * Verify bootstrap code from user input
+ * Stateless verification - works across all cluster nodes with same secret
+ * Verifies that code matches HMAC signature for current or previous time window
+ *
+ * @param {import('../../../Common/sources/operationContext').Context} ctx - Operation context
+ * @param {string} providedCode - Code provided by user (e.g. "AB12CD34EF56")
+ * @returns {Promise} True if code is valid and not expired
+ */
+async function verifyBootstrapToken(ctx, providedCode) {
+ if (!providedCode) {
+ ctx.logger.warn('Bootstrap code verification failed: empty code');
+ return false;
+ }
+
+ // Normalize code (remove spaces, dashes, uppercase)
+ const normalizedCode = providedCode.toUpperCase().replace(/[\s-]/g, '');
+
+ // Validate format
+ if (normalizedCode.length !== BOOTSTRAP_CODE_LENGTH || !/^[A-Z0-9]+$/.test(normalizedCode)) {
+ ctx.logger.warn('Bootstrap code verification failed: invalid format');
+ return false;
+ }
+
+ // Check if setup already completed
+ // Invalid or old format is treated as no password set
+ const config = await runtimeConfigManager.getConfig(ctx);
+ const passwordHash = config?.adminPanel?.passwordHash;
+
+ if (passwordManager.isValidPasswordHash(passwordHash)) {
+ ctx.logger.warn('Bootstrap code rejected: setup already completed');
+ return false;
+ }
+
+ if (passwordHash && !passwordManager.isValidPasswordHash(passwordHash)) {
+ ctx.logger.info('Invalid password hash format detected - allowing bootstrap for re-setup');
+ }
+
+ // Stateless verification: check if code matches current or previous time window
+ // This allows codes from any pod in cluster, as long as they have same secret
+ const now = Date.now();
+
+ // Check current time window
+ const currentCode = generateShortCode(now);
+ if (currentCode === normalizedCode) {
+ ctx.logger.info('Bootstrap code verified successfully (current window)');
+ cachedBootstrapCode = null; // Clear cache
+ return true;
+ }
+
+ // Check previous time window (in case code was generated at window boundary)
+ const previousCode = generateShortCode(now - BOOTSTRAP_TOKEN_TTL);
+ if (previousCode === normalizedCode) {
+ ctx.logger.info('Bootstrap code verified successfully (previous window)');
+ cachedBootstrapCode = null; // Clear cache
+ return true;
+ }
+
+ ctx.logger.warn('Bootstrap code verification failed: invalid or expired code');
+ return false;
+}
+
+/**
+ * Check if bootstrap code exists and is valid in cache
+ * Note: Code is always valid if setup not completed (cluster-wide)
+ * @returns {boolean} True if cached bootstrap code exists and not expired
+ */
+function hasValidBootstrapToken() {
+ if (!cachedBootstrapCode) {
+ return false;
+ }
+
+ // Check expiration
+ if (cachedBootstrapCode.expiresAt < new Date()) {
+ cachedBootstrapCode = null; // Clear expired cache
+ return false;
+ }
+
+ return true;
+}
+
+/**
+ * Invalidate bootstrap code cache (for reset scenarios)
+ * Note: Code itself remains valid across cluster until time window expires
+ * @param {import('../../../Common/sources/operationContext').Context} ctx - Operation context
+ */
+async function invalidateBootstrapToken(ctx) {
+ cachedBootstrapCode = null;
+ ctx.logger.info('Bootstrap code cache cleared');
+}
+
+/**
+ * Get current bootstrap code for display
+ * Generates fresh code based on current time window (cluster-safe)
+ * @returns {string|null} Current code or null
+ */
+function getCurrentBootstrapCode() {
+ if (hasValidBootstrapToken()) {
+ return cachedBootstrapCode.code;
+ }
+ return null;
+}
+
+module.exports = {
+ generateBootstrapToken,
+ verifyBootstrapToken,
+ hasValidBootstrapToken,
+ invalidateBootstrapToken,
+ getCurrentBootstrapCode,
+ BOOTSTRAP_TOKEN_TTL
+};
diff --git a/AdminPanel/server/sources/jwtSecret.js b/AdminPanel/server/sources/jwtSecret.js
new file mode 100644
index 0000000000..aa3e4db642
--- /dev/null
+++ b/AdminPanel/server/sources/jwtSecret.js
@@ -0,0 +1,9 @@
+'use strict';
+
+const crypto = require('crypto');
+const config = require('config');
+
+//todo Need common secret in case of cluster deployment
+const adminPanelJwtSecret = config.has('adminPanel.secret') ? config.get('adminPanel.secret') : crypto.randomBytes(64).toString('hex');
+
+module.exports = adminPanelJwtSecret;
diff --git a/AdminPanel/server/sources/middleware/auth.js b/AdminPanel/server/sources/middleware/auth.js
new file mode 100644
index 0000000000..4104511b2d
--- /dev/null
+++ b/AdminPanel/server/sources/middleware/auth.js
@@ -0,0 +1,34 @@
+'use strict';
+
+const jwt = require('jsonwebtoken');
+const operationContext = require('../../../../Common/sources/operationContext');
+const adminPanelJwtSecret = require('../jwtSecret');
+
+/**
+ * JWT Authentication Middleware
+ * Validates JWT token from cookies and initializes operation context
+ * @param {Object} req - Express request object
+ * @param {Object} res - Express response object
+ * @param {Function} next - Express next function
+ */
+const validateJWT = async (req, res, next) => {
+ const ctx = new operationContext.Context();
+ try {
+ const token = req.cookies.accessToken;
+ if (!token) {
+ return res.status(401).json({error: 'Unauthorized - No token provided'});
+ }
+ const decoded = jwt.verify(token, adminPanelJwtSecret);
+ ctx.init(decoded.tenant);
+ await ctx.initTenantCache();
+ req.user = decoded;
+ req.ctx = ctx;
+ return next();
+ } catch {
+ return res.status(401).json({error: 'Unauthorized'});
+ }
+};
+
+module.exports = {
+ validateJWT
+};
diff --git a/AdminPanel/server/sources/passwordManager.js b/AdminPanel/server/sources/passwordManager.js
new file mode 100644
index 0000000000..6ed8b46f52
--- /dev/null
+++ b/AdminPanel/server/sources/passwordManager.js
@@ -0,0 +1,226 @@
+/*
+ * (c) Copyright Ascensio System SIA 2010-2024
+ *
+ * This program is a free software product. You can redistribute it and/or
+ * modify it under the terms of the GNU Affero General Public License (AGPL)
+ * version 3 as published by the Free Software Foundation. In accordance with
+ * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect
+ * that Ascensio System SIA expressly excludes the warranty of non-infringement
+ * of any third-party rights.
+ *
+ * This program is distributed WITHOUT ANY WARRANTY; without even the implied
+ * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For
+ * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html
+ *
+ * You can contact Ascensio System SIA at 20A-6 Ernesta Birznieka-Upish
+ * street, Riga, Latvia, EU, LV-1050.
+ *
+ * The interactive user interfaces in modified source and object code versions
+ * of the Program must display Appropriate Legal Notices, as required under
+ * Section 5 of the GNU AGPL version 3.
+ *
+ * Pursuant to Section 7(b) of the License you must retain the original Product
+ * logo when distributing the program. Pursuant to Section 7(e) we decline to
+ * grant you any rights under trademark law for use of our trademarks.
+ *
+ * All the Product's GUI elements, including illustrations and icon sets, as
+ * well as technical writing content are licensed under the terms of the
+ * Creative Commons Attribution-ShareAlike 4.0 International. See the License
+ * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode
+ *
+ */
+
+'use strict';
+
+const crypto = require('crypto');
+const util = require('util');
+const runtimeConfigManager = require('../../../Common/sources/runtimeConfigManager');
+
+const pbkdf2 = util.promisify(crypto.pbkdf2);
+const PASSWORD_MIN_LENGTH = 1; // Any non-empty password allowed
+const PASSWORD_MAX_LENGTH = 128; // Prevent DoS attacks
+const PBKDF2_ITERATIONS = 600000; // OWASP 2023 recommendation for SHA-256
+const PBKDF2_KEYLEN = 32; // 32 bytes = 256 bits
+const PBKDF2_DIGEST = 'sha256'; // SHA-256 algorithm
+
+/**
+ * Hash a password using PBKDF2-SHA256 in MCF format (OWASP recommended)
+ * Format: $pbkdf2-sha256$iterations$salt$hash (all base64)
+ *
+ * OpenSSL equivalent (requires OpenSSL 3.0+):
+ * I=600000; S=$(openssl rand -base64 16 | tr -d '\n'); H=$(openssl kdf -binary -keylen 32 -kdfopt digest:SHA256 -kdfopt pass:UTF8:"password" -kdfopt salt:base64:"$S" -kdfopt iter:$I PBKDF2 | base64 | tr -d '\n'); echo "$pbkdf2-sha256$$I$$S$$H"
+ *
+ * @param {string} password - Plain text password to hash
+ * @returns {Promise} Hashed password in MCF format
+ */
+async function hashPassword(password) {
+ if (!password || password.length < PASSWORD_MIN_LENGTH) {
+ throw new Error(`Password must be at least ${PASSWORD_MIN_LENGTH} characters long`);
+ }
+
+ if (password.length > PASSWORD_MAX_LENGTH) {
+ throw new Error(`Password must not exceed ${PASSWORD_MAX_LENGTH} characters`);
+ }
+
+ // Generate random salt (16 bytes = 128 bits, OWASP minimum)
+ const saltBuffer = crypto.randomBytes(16);
+ const saltBase64 = saltBuffer.toString('base64').replace(/\+/g, '.').replace(/=/g, '');
+
+ // Derive key using PBKDF2-SHA256 with 600,000 iterations
+ const derivedKey = await pbkdf2(password, saltBuffer, PBKDF2_ITERATIONS, PBKDF2_KEYLEN, PBKDF2_DIGEST);
+ const hashBase64 = derivedKey.toString('base64').replace(/\+/g, '.').replace(/=/g, '');
+
+ // Return MCF format: $pbkdf2-sha256$iterations$salt$hash
+ return `$pbkdf2-sha256$${PBKDF2_ITERATIONS}$${saltBase64}$${hashBase64}`;
+}
+
+/**
+ * Verify a password against a hash
+ * @param {string} password - Plain text password to verify
+ * @param {string} hash - Hashed password in MCF format
+ * @returns {Promise} True if password matches hash
+ */
+async function verifyPassword(password, hash) {
+ if (!password || !hash) {
+ return false;
+ }
+
+ try {
+ // Parse MCF format: $pbkdf2-sha256$iterations$salt$hash
+ if (!hash.startsWith('$pbkdf2-sha256$')) {
+ return false;
+ }
+
+ const parts = hash.split('$');
+ if (parts.length !== 5) {
+ return false;
+ }
+
+ const [, , iterationsStr, saltBase64, expectedHashBase64] = parts;
+ const iterations = parseInt(iterationsStr, 10);
+
+ if (!iterations || !saltBase64 || !expectedHashBase64) {
+ return false;
+ }
+
+ // Decode base64 salt (restore + from .)
+ const saltBuffer = Buffer.from(saltBase64.replace(/\./g, '+'), 'base64');
+
+ // Derive key from password with same parameters
+ const derivedKey = await pbkdf2(password, saltBuffer, iterations, PBKDF2_KEYLEN, PBKDF2_DIGEST);
+
+ // Decode expected hash from base64 (restore + from .)
+ const expectedHashBuffer = Buffer.from(expectedHashBase64.replace(/\./g, '+'), 'base64');
+
+ // Compare using timing-safe comparison (compare raw buffers, not base64 strings)
+ return crypto.timingSafeEqual(derivedKey, expectedHashBuffer);
+ } catch {
+ return false;
+ }
+}
+
+/**
+ * Check if password hash is valid (proper MCF format)
+ * @param {string} hash - Password hash to validate
+ * @returns {boolean} True if hash is in valid MCF format
+ */
+function isValidPasswordHash(hash) {
+ if (!hash || typeof hash !== 'string') {
+ return false;
+ }
+
+ // Must start with correct MCF prefix
+ if (!hash.startsWith('$pbkdf2-sha256$')) {
+ return false;
+ }
+
+ // Must have correct structure: $pbkdf2-sha256$iterations$salt$hash
+ const parts = hash.split('$');
+ if (parts.length !== 5) {
+ return false;
+ }
+
+ const [, , iterationsStr, saltBase64, hashBase64] = parts;
+
+ // Validate iterations is a number
+ const iterations = parseInt(iterationsStr, 10);
+ if (!iterations || iterations < 1000) {
+ return false;
+ }
+
+ // Validate salt and hash are present and reasonable length
+ if (!saltBase64 || saltBase64.length < 10 || !hashBase64 || hashBase64.length < 10) {
+ return false;
+ }
+
+ return true;
+}
+
+/**
+ * Check if AdminPanel setup is required (no password configured or invalid format)
+ * Invalid or old format is treated as no password set
+ * @param {import('./operationContext').Context} ctx - Operation context
+ * @returns {Promise} True if setup is required
+ */
+async function isSetupRequired(ctx) {
+ const config = await runtimeConfigManager.getConfig(ctx);
+ const passwordHash = config?.adminPanel?.passwordHash;
+
+ // No password hash or invalid format - setup required
+ if (!isValidPasswordHash(passwordHash)) {
+ if (passwordHash) {
+ ctx.logger.warn('Invalid password hash format detected - setup required');
+ }
+ return true;
+ }
+
+ return false;
+}
+
+/**
+ * Save admin password hash to runtime config
+ * @param {import('./operationContext').Context} ctx - Operation context
+ * @param {string} password - Plain text password to hash and save
+ * @returns {Promise}
+ */
+async function saveAdminPassword(ctx, password) {
+ const hash = await hashPassword(password);
+ await runtimeConfigManager.saveConfig(ctx, {
+ adminPanel: {
+ passwordHash: hash
+ }
+ });
+}
+
+/**
+ * Verify admin password against stored hash
+ * Invalid or old format is treated as no password set - returns false
+ * @param {import('./operationContext').Context} ctx - Operation context
+ * @param {string} password - Plain text password to verify
+ * @returns {Promise} True if password matches stored hash
+ */
+async function verifyAdminPassword(ctx, password) {
+ const config = await runtimeConfigManager.getConfig(ctx);
+ const hash = config?.adminPanel?.passwordHash;
+
+ // No hash or invalid format - treat as no password set
+ if (!isValidPasswordHash(hash)) {
+ if (hash) {
+ ctx.logger.warn('Invalid password hash format detected - authentication rejected, re-setup required');
+ }
+ return false;
+ }
+
+ return verifyPassword(password, hash);
+}
+
+module.exports = {
+ hashPassword,
+ verifyPassword,
+ isValidPasswordHash,
+ isSetupRequired,
+ saveAdminPassword,
+ verifyAdminPassword,
+ PASSWORD_MIN_LENGTH,
+ PASSWORD_MAX_LENGTH
+};
diff --git a/AdminPanel/server/sources/routes/adminpanel/router.js b/AdminPanel/server/sources/routes/adminpanel/router.js
new file mode 100644
index 0000000000..1e3954fea6
--- /dev/null
+++ b/AdminPanel/server/sources/routes/adminpanel/router.js
@@ -0,0 +1,261 @@
+'use strict';
+const express = require('express');
+const jwt = require('jsonwebtoken');
+const cookieParser = require('cookie-parser');
+const operationContext = require('../../../../../Common/sources/operationContext');
+const passwordManager = require('../../passwordManager');
+const bootstrap = require('../../bootstrap');
+const adminPanelJwtSecret = require('../../jwtSecret');
+const tenantManager = require('../../../../../Common/sources/tenantManager');
+const commonDefines = require('../../../../../Common/sources/commondefines');
+
+const router = express.Router();
+
+router.use(express.json());
+router.use(cookieParser());
+
+/**
+ * Create session cookie with standard options
+ * @param {import('express').Response} res - Express response
+ * @param {import('express').Request} req - Express request
+ * @param {string} token - JWT token
+ */
+function setAuthCookie(res, req, token) {
+ res.cookie('accessToken', token, {
+ httpOnly: true,
+ secure: req.secure,
+ sameSite: 'strict',
+ maxAge: 60 * 60 * 1000,
+ path: '/'
+ });
+}
+
+/**
+ * Middleware to verify JWT token
+ * @param {import('express').Request} req - Express request
+ * @param {import('express').Response} res - Express response
+ * @param {import('express').NextFunction} next - Next middleware
+ */
+function requireAuth(req, res, next) {
+ try {
+ const token = req.cookies?.accessToken;
+ if (!token) {
+ return res.status(401).json({error: 'Unauthorized'});
+ }
+ const decoded = jwt.verify(token, adminPanelJwtSecret);
+ req.user = decoded;
+ next();
+ } catch {
+ res.status(401).json({error: 'Unauthorized'});
+ }
+}
+
+/**
+ * Check if AdminPanel setup is required
+ */
+router.get('/setup/required', async (req, res) => {
+ const ctx = new operationContext.Context();
+ try {
+ ctx.initFromRequest(req);
+ const setupRequired = await passwordManager.isSetupRequired(ctx);
+
+ // If setup required but no valid code, generate new one (lazy generation)
+ if (setupRequired) {
+ const hasCode = bootstrap.hasValidBootstrapToken();
+ if (!hasCode) {
+ const {code, expiresAt} = await bootstrap.generateBootstrapToken(ctx);
+ ctx.logger.warn('Bootstrap code generated on demand | Code: ' + code + ' | Expires: ' + expiresAt.toISOString());
+ }
+ }
+
+ res.json({setupRequired});
+ } catch (error) {
+ ctx.logger.error('Setup check error: %s', error.stack);
+ res.status(500).json({error: 'Internal server error'});
+ }
+});
+
+/**
+ * Complete initial setup with password
+ * Requires valid bootstrap token
+ */
+router.post('/setup', async (req, res) => {
+ const ctx = new operationContext.Context();
+ try {
+ ctx.initFromRequest(req);
+
+ const setupRequired = await passwordManager.isSetupRequired(ctx);
+ if (!setupRequired) {
+ return res.status(400).json({error: 'Setup already completed'});
+ }
+
+ const {bootstrapToken, password} = req.body;
+
+ // Verify bootstrap token
+ if (!bootstrapToken) {
+ return res.status(400).json({error: 'Bootstrap token is required'});
+ }
+
+ const tokenValid = await bootstrap.verifyBootstrapToken(ctx, bootstrapToken);
+ if (!tokenValid) {
+ ctx.logger.warn('Invalid or expired bootstrap token attempt');
+ return res.status(401).json({error: 'Invalid or expired bootstrap token'});
+ }
+
+ if (!password) {
+ return res.status(400).json({error: 'Password is required'});
+ }
+
+ if (password.length < passwordManager.PASSWORD_MIN_LENGTH) {
+ return res.status(400).json({error: `Password must be at least ${passwordManager.PASSWORD_MIN_LENGTH} characters long`});
+ }
+
+ if (password.length > passwordManager.PASSWORD_MAX_LENGTH) {
+ return res.status(400).json({error: `Password must not exceed ${passwordManager.PASSWORD_MAX_LENGTH} characters`});
+ }
+
+ await passwordManager.saveAdminPassword(ctx, password);
+
+ // Invalidate bootstrap token after successful setup
+ await bootstrap.invalidateBootstrapToken(ctx);
+
+ const token = jwt.sign({tenant: 'localhost', isAdmin: true}, adminPanelJwtSecret, {expiresIn: '1h'});
+ setAuthCookie(res, req, token);
+
+ ctx.logger.info('AdminPanel setup completed successfully');
+ res.json({message: 'Setup completed successfully'});
+ } catch (error) {
+ ctx.logger.error('Setup error: %s', error.stack);
+ res.status(500).json({error: error.message || 'Internal server error'});
+ }
+});
+
+/**
+ * Change admin password
+ */
+router.post('/change-password', requireAuth, async (req, res) => {
+ const ctx = new operationContext.Context();
+ try {
+ ctx.initFromRequest(req);
+
+ const {currentPassword, newPassword} = req.body;
+ if (!currentPassword || !newPassword) {
+ return res.status(400).json({error: 'Current password and new password are required'});
+ }
+
+ if (newPassword.length < passwordManager.PASSWORD_MIN_LENGTH) {
+ return res.status(400).json({error: `Password must be at least ${passwordManager.PASSWORD_MIN_LENGTH} characters long`});
+ }
+
+ if (newPassword.length > passwordManager.PASSWORD_MAX_LENGTH) {
+ return res.status(400).json({error: `Password must not exceed ${passwordManager.PASSWORD_MAX_LENGTH} characters`});
+ }
+
+ if (currentPassword === newPassword) {
+ return res.status(400).json({error: 'New password must be different from current password'});
+ }
+
+ const isValid = await passwordManager.verifyAdminPassword(ctx, currentPassword);
+ if (!isValid) {
+ return res.status(401).json({error: 'Current password is incorrect'});
+ }
+
+ await passwordManager.saveAdminPassword(ctx, newPassword);
+
+ ctx.logger.info('AdminPanel password changed successfully');
+ res.json({message: 'Password changed successfully'});
+ } catch (error) {
+ ctx.logger.error('Change password error: %s', error.stack);
+ res.status(500).json({error: 'Internal server error'});
+ }
+});
+
+router.get('/me', (req, res) => {
+ try {
+ const token = req.cookies?.accessToken;
+ if (!token) {
+ return res.json({authorized: false});
+ }
+ const decoded = jwt.verify(token, adminPanelJwtSecret);
+ return res.json({authorized: true, ...decoded});
+ } catch {
+ return res.json({authorized: false});
+ }
+});
+
+router.post('/login', async (req, res) => {
+ const ctx = new operationContext.Context();
+ try {
+ ctx.initFromRequest(req);
+
+ const setupRequired = await passwordManager.isSetupRequired(ctx);
+ if (setupRequired) {
+ return res.status(403).json({error: 'Setup required', setupRequired: true});
+ }
+
+ const {password} = req.body;
+ if (!password) {
+ return res.status(400).json({error: 'Password is required'});
+ }
+
+ const isValid = await passwordManager.verifyAdminPassword(ctx, password);
+ if (!isValid) {
+ ctx.logger.warn('Failed login attempt for AdminPanel');
+ return res.status(401).json({error: 'Invalid password'});
+ }
+
+ const token = jwt.sign({tenant: 'localhost', isAdmin: true}, adminPanelJwtSecret, {expiresIn: '1h'});
+ setAuthCookie(res, req, token);
+
+ ctx.logger.info('AdminPanel login successful');
+ res.json({tenant: 'localhost', isAdmin: true});
+ } catch (error) {
+ ctx.logger.error('Login error: %s', error.stack);
+ res.status(500).json({error: 'Internal server error'});
+ }
+});
+
+router.post('/logout', async (req, res) => {
+ try {
+ res.clearCookie('accessToken', {
+ httpOnly: true,
+ sameSite: 'strict',
+ path: '/'
+ });
+ res.json({message: 'Logged out successfully'});
+ } catch {
+ res.status(500).json({error: 'Internal server error'});
+ }
+});
+
+/**
+ * Generate JWT token for Document Server requests
+ */
+router.post('/generate-docserver-token', requireAuth, async (req, res) => {
+ const ctx = new operationContext.Context();
+ try {
+ ctx.initFromRequest(req);
+
+ const body = req.body;
+
+ const secret = await tenantManager.getTenantSecret(ctx, commonDefines.c_oAscSecretType.Inbox);
+
+ if (!secret) {
+ return res.status(500).json({error: 'JWT secret not configured'});
+ }
+
+ const tenTokenInboxAlgorithm = ctx.getCfg('services.CoAuthoring.token.inbox.algorithm', 'HS256');
+ const tenTokenInboxExpires = ctx.getCfg('services.CoAuthoring.token.inbox.expires', '5m');
+
+ const options = {algorithm: tenTokenInboxAlgorithm, expiresIn: tenTokenInboxExpires};
+ const token = jwt.sign(body, secret, options);
+
+ ctx.logger.info('Generated Document Server JWT token');
+ res.json({token});
+ } catch (error) {
+ ctx.logger.error('JWT token generation error: %s', error.stack);
+ res.status(500).json({error: 'Internal server error'});
+ }
+});
+
+module.exports = router;
diff --git a/AdminPanel/server/sources/routes/config/config.schema.utils.js b/AdminPanel/server/sources/routes/config/config.schema.utils.js
new file mode 100644
index 0000000000..3029a91cf5
--- /dev/null
+++ b/AdminPanel/server/sources/routes/config/config.schema.utils.js
@@ -0,0 +1,166 @@
+/*
+ * ONLYOFFICE Document Server
+ * Copyright (c) Ascensio System SIA. All rights reserved.
+ *
+ * This program is a free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, version 3 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
+ *
+ * ONLYOFFICE is a trademark of Ascensio System SIA. Other brand and product
+ * names mentioned herein may be trademarks of their respective owners.
+ */
+
+'use strict';
+
+// Constants
+const X_SCOPE_KEYWORD = 'x-scope';
+const SCHEMA_COMBINATORS = ['anyOf', 'oneOf', 'allOf'];
+const SCHEMA_DEFINITIONS = ['definitions', '$defs'];
+
+/**
+ * Checks if a node should be included in the target scope.
+ * @param {any} node
+ * @param {string} scope
+ * @returns {boolean}
+ */
+function isNodeAllowedInScope(node, scope) {
+ if (!node || typeof node !== 'object') return true;
+ if (!Object.prototype.hasOwnProperty.call(node, X_SCOPE_KEYWORD)) return true;
+
+ const marker = node[X_SCOPE_KEYWORD];
+ return Array.isArray(marker) ? marker.includes(scope) : marker === scope;
+}
+
+/**
+ * Processes object properties by pruning each property.
+ * @param {Object} properties
+ * @param {Function} pruneFn
+ * @returns {Object}
+ */
+function processObjectProperties(properties, pruneFn) {
+ const newProps = {};
+ for (const [key, value] of Object.entries(properties)) {
+ const pruned = pruneFn(value);
+ if (pruned) newProps[key] = pruned;
+ }
+ return newProps;
+}
+
+/**
+ * Processes schema combinators (anyOf, oneOf, allOf).
+ * @param {Object} result
+ * @param {Function} pruneFn
+ */
+function processCombinators(result, pruneFn) {
+ for (const key of SCHEMA_COMBINATORS) {
+ if (Array.isArray(result[key])) {
+ const mapped = result[key].map(pruneFn).filter(Boolean);
+ if (mapped.length === 0) delete result[key];
+ else result[key] = mapped;
+ }
+ }
+}
+
+/**
+ * Processes schema definitions (definitions, $defs).
+ * @param {Object} result
+ * @param {Function} pruneFn
+ */
+function processDefinitions(result, pruneFn) {
+ for (const defKey of SCHEMA_DEFINITIONS) {
+ if (result[defKey] && typeof result[defKey] === 'object') {
+ result[defKey] = processObjectProperties(result[defKey], pruneFn);
+ }
+ }
+}
+
+/**
+ * Processes conditional schemas (if/then/else).
+ * @param {Object} result
+ * @param {Function} pruneFn
+ */
+function processConditionals(result, pruneFn) {
+ if (!result.if) return;
+
+ const pIf = pruneFn(result.if);
+ if (pIf === null) delete result.if;
+ else result.if = pIf;
+
+ if (result.then) {
+ const pThen = pruneFn(result.then);
+ if (pThen === null) delete result.then;
+ else result.then = pThen;
+ }
+
+ if (result.else) {
+ const pElse = pruneFn(result.else);
+ if (pElse === null) delete result.else;
+ else result.else = pElse;
+ }
+}
+
+/**
+ * Build a per-scope schema by pruning nodes marked with x-scope.
+ * @param {object} schema - Superset JSON schema object
+ * @param {'admin'|'tenant'} scope - Target scope
+ * @returns {object} Derived schema for scope
+ */
+function deriveSchemaForScope(schema, scope) {
+ const prune = node => {
+ if (!node || typeof node !== 'object') return node;
+ if (!isNodeAllowedInScope(node, scope)) return null;
+
+ const result = Array.isArray(node) ? node.map(prune).filter(Boolean) : {...node};
+ if (result[X_SCOPE_KEYWORD] !== undefined) delete result[X_SCOPE_KEYWORD];
+
+ // Handle object properties
+ if (result.type === 'object') {
+ if (result.properties && typeof result.properties === 'object') {
+ result.properties = processObjectProperties(result.properties, prune);
+ }
+ if (result.patternProperties && typeof result.patternProperties === 'object') {
+ result.patternProperties = processObjectProperties(result.patternProperties, prune);
+ }
+ if (Array.isArray(result.required)) {
+ result.required = result.required.filter(k => result.properties && Object.prototype.hasOwnProperty.call(result.properties, k));
+ if (result.required.length === 0) delete result.required;
+ }
+ if (typeof result.additionalProperties === 'object') {
+ const prunedAP = prune(result.additionalProperties);
+ result.additionalProperties = prunedAP === null ? false : prunedAP;
+ }
+ }
+
+ // Handle array items
+ if (result.items) {
+ const prunedItems = prune(result.items);
+ if (prunedItems === null) delete result.items;
+ else result.items = prunedItems;
+ }
+
+ processCombinators(result, prune);
+ processConditionals(result, prune);
+ processDefinitions(result, prune);
+
+ return result;
+ };
+
+ const derived = prune(schema);
+ if (derived && typeof derived === 'object') {
+ derived.$id = derived.$id ? `${derived.$id}:${scope}` : `urn:onlyoffice:config:derived:${scope}`;
+ }
+ return derived;
+}
+
+module.exports = {
+ deriveSchemaForScope,
+ X_SCOPE_KEYWORD
+};
diff --git a/AdminPanel/server/sources/routes/config/config.service.js b/AdminPanel/server/sources/routes/config/config.service.js
new file mode 100644
index 0000000000..a5fbd3c95c
--- /dev/null
+++ b/AdminPanel/server/sources/routes/config/config.service.js
@@ -0,0 +1,126 @@
+/*
+ * (c) Copyright Ascensio System SIA 2010-2024
+ *
+ * This program is a free software product. You can redistribute it and/or
+ * modify it under the terms of the GNU Affero General Public License (AGPL)
+ * version 3 as published by the Free Software Foundation. In accordance with
+ * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect
+ * that Ascensio System SIA expressly excludes the warranty of non-infringement
+ * of any third-party rights.
+ *
+ * This program is distributed WITHOUT ANY WARRANTY; without even the implied
+ * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For
+ * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html
+ *
+ * You can contact Ascensio System SIA at 20A-6 Ernesta Birznieka-Upish
+ * street, Riga, Latvia, EU, LV-1050.
+ *
+ * The interactive user interfaces in modified source and object code versions
+ * of the Program must display Appropriate Legal Notices, as required under
+ * Section 5 of the GNU AGPL version 3.
+ *
+ * Pursuant to Section 7(b) of the License you must retain the original Product
+ * logo when distributing the program. Pursuant to Section 7(e) we decline to
+ * grant you any rights under trademark law for use of our trademarks.
+ *
+ * All the Product's GUI elements, including illustrations and icon sets, as
+ * well as technical writing content are licensed under the terms of the
+ * Creative Commons Attribution-ShareAlike 4.0 International. See the License
+ * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode
+ *
+ */
+
+'use strict';
+const Ajv = require('ajv');
+const addFormats = require('ajv-formats');
+const logger = require('../../../../../Common/sources/logger');
+const tenantManager = require('../../../../../Common/sources/tenantManager');
+const supersetSchema = require('../../../../../Common/config/schemas/config.schema.json');
+const {deriveSchemaForScope, X_SCOPE_KEYWORD} = require('./config.schema.utils');
+
+// Constants
+const CRON6_REGEX = /^\s*\S+(?:\s+\S+){5}\s*$/;
+const AJV_CONFIG = {allErrors: true, strict: false};
+const AJV_FILTER_CONFIG = {allErrors: true, strict: false, removeAdditional: true};
+
+/**
+ * Registers custom keyword and formats on an AJV instance.
+ * @param {Ajv.default} instance
+ */
+function registerAjvExtras(instance) {
+ instance.addKeyword({keyword: X_SCOPE_KEYWORD, schemaType: ['string', 'array'], errors: false});
+ instance.addFormat('cron6', CRON6_REGEX);
+}
+
+/**
+ * Creates and configures an AJV instance.
+ * @param {Object} config - AJV configuration
+ * @returns {Ajv.default}
+ */
+function createAjvInstance(config) {
+ const instance = new Ajv(config);
+ addFormats(instance);
+ registerAjvExtras(instance);
+ return instance;
+}
+
+const ajvValidator = createAjvInstance(AJV_CONFIG);
+const ajvFilter = createAjvInstance(AJV_FILTER_CONFIG);
+
+// Derive and compile per-scope schemas
+const adminSchema = deriveSchemaForScope(supersetSchema, 'admin');
+const tenantSchema = deriveSchemaForScope(supersetSchema, 'tenant');
+const validateAdmin = ajvValidator.compile(adminSchema);
+const validateTenant = ajvValidator.compile(tenantSchema);
+const filterAdmin = ajvFilter.compile(adminSchema);
+const filterTenant = ajvFilter.compile(tenantSchema);
+
+function isAdminScope(ctx) {
+ return tenantManager.isDefaultTenant(ctx);
+}
+
+/**
+ * Validates updateData against the derived per-scope schema selected by ctx.
+ * @param {operationContext} ctx
+ * @param {Object} updateData
+ * @returns {{ value?: Object, errors?: any, errorsText?: string }}
+ */
+function validateScoped(ctx, updateData) {
+ const validator = isAdminScope(ctx) ? validateAdmin : validateTenant;
+ const valid = validator(updateData);
+
+ return valid
+ ? {value: updateData, errors: null, errorsText: null}
+ : {value: null, errors: validator.errors, errorsText: ajvValidator.errorsText(validator.errors)};
+}
+
+/**
+ * Filters configuration to include only fields defined in the appropriate schema
+ * @param {operationContext} ctx - Operation context
+ * @returns {Object} Filtered configuration object
+ */
+function getScopedConfig(ctx) {
+ const cfg = ctx.getFullCfg();
+ const configCopy = JSON.parse(JSON.stringify(cfg));
+
+ // Add log config. getLoggerConfig return merged config
+ if (!configCopy.log) {
+ configCopy.log = {};
+ }
+ configCopy.log.options = logger.getLoggerConfig();
+
+ const filter = isAdminScope(ctx) ? filterAdmin : filterTenant;
+ filter(configCopy);
+ return configCopy;
+}
+
+/**
+ * Returns the derived per-scope schema for ctx (admin or tenant).
+ * @param {operationContext} ctx
+ * @returns {object}
+ */
+function getScopedSchema(ctx) {
+ return isAdminScope(ctx) ? adminSchema : tenantSchema;
+}
+
+module.exports = {validateScoped, getScopedConfig, getScopedSchema};
diff --git a/AdminPanel/server/sources/routes/config/router.js b/AdminPanel/server/sources/routes/config/router.js
new file mode 100644
index 0000000000..22a3b9e772
--- /dev/null
+++ b/AdminPanel/server/sources/routes/config/router.js
@@ -0,0 +1,113 @@
+'use strict';
+const config = require('config');
+const express = require('express');
+const bodyParser = require('body-parser');
+const tenantManager = require('../../../../../Common/sources/tenantManager');
+const runtimeConfigManager = require('../../../../../Common/sources/runtimeConfigManager');
+const {getScopedConfig, validateScoped, getScopedSchema} = require('./config.service');
+const {validateJWT} = require('../../middleware/auth');
+const cookieParser = require('cookie-parser');
+const utils = require('../../../../../Common/sources/utils');
+
+const router = express.Router();
+router.use(cookieParser());
+
+const rawFileParser = bodyParser.raw({
+ inflate: true,
+ limit: config.get('services.CoAuthoring.server.limits_tempfile_upload'),
+ type() {
+ return true;
+ }
+});
+
+router.get('/', validateJWT, async (req, res) => {
+ const ctx = req.ctx;
+ try {
+ ctx.logger.info('config get start');
+ const filteredConfig = getScopedConfig(ctx);
+ res.setHeader('Content-Type', 'application/json');
+ res.json(filteredConfig);
+ } catch (error) {
+ ctx.logger.error('Config get error: %s', error.stack);
+ res.status(500).json({error: 'Internal server error'});
+ } finally {
+ ctx.logger.info('config get end');
+ }
+});
+
+router.get('/schema', validateJWT, async (req, res) => {
+ const ctx = req.ctx;
+ try {
+ ctx.logger.info('config schema start');
+ const schema = getScopedSchema(ctx);
+ res.json(schema);
+ } catch (error) {
+ ctx.logger.error('Config schema error: %s', error.stack);
+ res.status(500).json({error: 'Internal server error'});
+ } finally {
+ ctx.logger.info('config schema end');
+ }
+});
+
+router.patch('/', validateJWT, rawFileParser, async (req, res) => {
+ const ctx = req.ctx;
+ try {
+ ctx.logger.info('config patch start');
+ const updateData = JSON.parse(req.body);
+ const validationResult = validateScoped(ctx, updateData);
+ if (validationResult.errors) {
+ ctx.logger.error('Config save error: %j', validationResult.errors);
+ return res.status(400).json({
+ errors: validationResult.errors,
+ errorsText: validationResult.errorsText
+ });
+ }
+ if (tenantManager.isMultitenantMode(ctx) && !tenantManager.isDefaultTenant(ctx)) {
+ await tenantManager.setTenantConfig(ctx, validationResult.value);
+ } else {
+ await runtimeConfigManager.saveConfig(ctx, validationResult.value);
+ }
+ const filteredConfig = getScopedConfig(ctx);
+ const newConfig = await runtimeConfigManager.getConfig(ctx);
+
+ res.status(200).json(utils.deepMergeObjects(filteredConfig, newConfig));
+ } catch (error) {
+ ctx.logger.error('Configuration save error: %s', error.stack);
+ res.status(500).json({error: 'Internal server error', details: error.message});
+ } finally {
+ ctx.logger.info('config patch end');
+ }
+});
+
+router.post('/reset', validateJWT, async (req, res) => {
+ const ctx = req.ctx;
+ try {
+ ctx.logger.info('config reset start');
+
+ const currentConfig = await runtimeConfigManager.getConfig(ctx);
+ const passwordHash = currentConfig?.adminPanel?.passwordHash;
+
+ const resetConfig = {};
+ if (passwordHash) {
+ resetConfig.adminPanel = {
+ passwordHash
+ };
+ }
+
+ if (tenantManager.isMultitenantMode(ctx) && !tenantManager.isDefaultTenant(ctx)) {
+ await tenantManager.replaceTenantConfig(ctx, resetConfig);
+ } else {
+ await runtimeConfigManager.replaceConfig(ctx, resetConfig);
+ }
+
+ ctx.logger.info('Configuration reset successfully');
+ res.status(200).json({message: 'Configuration reset successfully'});
+ } catch (error) {
+ ctx.logger.error('Configuration reset error: %s', error.stack);
+ res.status(500).json({error: 'Internal server error', details: error.message});
+ } finally {
+ ctx.logger.info('config reset end');
+ }
+});
+
+module.exports = router;
diff --git a/AdminPanel/server/sources/routes/wopi/router.js b/AdminPanel/server/sources/routes/wopi/router.js
new file mode 100644
index 0000000000..2ee16dfc50
--- /dev/null
+++ b/AdminPanel/server/sources/routes/wopi/router.js
@@ -0,0 +1,213 @@
+/*
+ * (c) Copyright Ascensio System SIA 2010-2024
+ *
+ * This program is a free software product. You can redistribute it and/or
+ * modify it under the terms of the GNU Affero General Public License (AGPL)
+ * version 3 as published by the Free Software Foundation. In accordance with
+ * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect
+ * that Ascensio System SIA expressly excludes the warranty of non-infringement
+ * of any third-party rights.
+ *
+ * This program is distributed WITHOUT ANY WARRANTY; without even the implied
+ * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For
+ * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html
+ *
+ * You can contact Ascensio System SIA at 20A-6 Ernesta Birznieka-Upish
+ * street, Riga, Latvia, EU, LV-1050.
+ *
+ * The interactive user interfaces in modified source and object code versions
+ * of the Program must display Appropriate Legal Notices, as required under
+ * Section 5 of the GNU AGPL version 3.
+ *
+ * Pursuant to Section 7(b) of the License you must retain the original Product
+ * logo when distributing the program. Pursuant to Section 7(e) we decline to
+ * grant you any rights under trademark law for use of our trademarks.
+ *
+ * All the Product's GUI elements, including illustrations and icon sets, as
+ * well as technical writing content are licensed under the terms of the
+ * Creative Commons Attribution-ShareAlike 4.0 International. See the License
+ * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode
+ *
+ */
+
+'use strict';
+
+const config = require('config');
+const express = require('express');
+const crypto = require('crypto');
+const utils = require('../../../../../Common/sources/utils');
+const runtimeConfigManager = require('../../../../../Common/sources/runtimeConfigManager');
+const tenantManager = require('../../../../../Common/sources/tenantManager');
+const {validateJWT} = require('../../middleware/auth');
+const {getConfig} = require('../../../../../Common/sources/runtimeConfigManager');
+const cookieParser = require('cookie-parser');
+
+const cfgWopiPublicKey = config.get('wopi.publicKey');
+const cfgWopiModulus = config.get('wopi.modulus');
+const cfgWopiPrivateKey = config.get('wopi.privateKey');
+const cfgWopiExponent = config.get('wopi.exponent');
+
+const router = express.Router();
+router.use(cookieParser());
+
+/**
+ * Decode a base64url string into a Buffer (RFC 7515)
+ * @param {string} b64url base64url-encoded string (no padding)
+ * @returns {Buffer} decoded bytes
+ */
+function base64UrlToBuffer(b64url) {
+ const b64 = b64url
+ .replace(/-/g, '+')
+ .replace(/_/g, '/')
+ .padEnd(Math.ceil(b64url.length / 4) * 4, '=');
+ return Buffer.from(b64, 'base64');
+}
+
+/**
+ * Convert a big-endian Buffer into a safe JavaScript Number.
+ * Note: Only for small integers (like RSA public exponent). For large values use BigInt.
+ * @param {Buffer} buf big-endian buffer (<= 6 bytes recommended)
+ * @returns {number} numeric value
+ */
+function bufferBEToNumber(buf) {
+ let n = 0;
+ for (const byte of buf.values()) {
+ n = (n << 8) | byte;
+ }
+ return n >>> 0;
+}
+
+/**
+ * Build a Microsoft PUBLICKEYBLOB from modulus and exponent.
+ * Layout:
+ * BLOBHEADER (8 bytes):
+ * bType=0x06 (PUBLICKEYBLOB), bVersion=0x02, reserved=0x0000, aiKeyAlg=0x0000A400 (CALG_RSA_KEYX)
+ * RSAPUBKEY (12 bytes):
+ * magic='RSA1' (0x31415352 LE), bitlen=modBits (LE), pubexp (LE)
+ * modulus bytes (little-endian)
+ * @param {Buffer} modulusBE Modulus big-endian, length = keySizeBytes
+ * @param {number} exponent Public exponent (decimal)
+ * @returns {Buffer} PUBLICKEYBLOB bytes
+ */
+function makeMsPublicKeyBlob(modulusBE, exponent) {
+ const keySizeBytes = modulusBE.length;
+ const header = Buffer.alloc(8);
+ // BLOBHEADER
+ header.writeUInt8(0x06, 0); // PUBLICKEYBLOB
+ header.writeUInt8(0x02, 1); // version
+ header.writeUInt16LE(0, 2); // reserved
+ header.writeUInt32LE(0x0000a400, 4); // CALG_RSA_KEYX
+
+ const rsapub = Buffer.alloc(12);
+ // 'RSA1' magic LE
+ rsapub.writeUInt32LE(0x31415352, 0);
+ rsapub.writeUInt32LE(keySizeBytes * 8, 4); // bit length
+ rsapub.writeUInt32LE(exponent >>> 0, 8); // exponent (fits in 32-bit)
+
+ // modulus little-endian
+ const modulusLE = Buffer.from(modulusBE);
+ modulusLE.reverse();
+
+ return Buffer.concat([header, rsapub, modulusLE]);
+}
+
+/**
+ * Generates WOPI private/public key pair and extracts modulus/exponent using Microsoft PUBLICKEYBLOB format.
+ * Uses JWK export for robust modulus/exponent retrieval across Node versions.
+ * @returns {Object} WOPI configuration object
+ */
+function generateWopiKeys() {
+ // Generate RSA private key (2048 bits)
+ const {privateKey, publicKey} = crypto.generateKeyPairSync('rsa', {
+ modulusLength: 2048,
+ publicKeyEncoding: {
+ type: 'spki',
+ format: 'pem'
+ },
+ privateKeyEncoding: {
+ type: 'pkcs8',
+ format: 'pem'
+ }
+ });
+
+ // Extract modulus (n) and exponent (e) via JWK for compatibility
+ const publicKeyObj = crypto.createPublicKey(publicKey);
+ /** @type {{kty:string,n:string,e:string}} */
+ const jwk = publicKeyObj.export({format: 'jwk'});
+ const modulusBE = base64UrlToBuffer(jwk.n); // big-endian bytes
+ const exponent = bufferBEToNumber(base64UrlToBuffer(jwk.e));
+
+ // Create MS PUBLICKEYBLOB format (matches bash script behavior)
+ const publicKeyBlob = makeMsPublicKeyBlob(modulusBE, exponent);
+
+ // Convert modulus to base64 (same as bash script: xxd -r -p | openssl base64 -A)
+ const modulus = modulusBE.toString('base64');
+
+ // Convert keys to base64 for storage
+ const publicKeyBase64 = publicKeyBlob.toString('base64');
+
+ return {
+ publicKey: publicKeyBase64,
+ modulus,
+ exponent,
+ privateKey
+ };
+}
+
+/**
+ * Rotates WOPI keys - moves current keys to Old and generates new ones.
+ */
+router.post('/rotate-keys', validateJWT, express.json(), async (req, res) => {
+ const ctx = req.ctx;
+ try {
+ ctx.initTenantCache();
+ ctx.logger.info('WOPI key rotation start');
+
+ const currentConfig = await getConfig(ctx);
+
+ const newWopiConfig = generateWopiKeys();
+
+ const publicKey = ctx.getCfg('wopi.publicKey', cfgWopiPublicKey);
+ const modulus = ctx.getCfg('wopi.modulus', cfgWopiModulus);
+ const privateKey = ctx.getCfg('wopi.privateKey', cfgWopiPrivateKey);
+ const exponent = ctx.getCfg('wopi.exponent', cfgWopiExponent);
+
+ const hasEmptyKeys = !(publicKey && modulus && privateKey && exponent);
+
+ const configUpdate = {
+ wopi: {
+ publicKeyOld: hasEmptyKeys ? newWopiConfig.publicKey : publicKey,
+ modulusOld: hasEmptyKeys ? newWopiConfig.modulus : modulus,
+ exponentOld: hasEmptyKeys ? newWopiConfig.exponent : exponent,
+ privateKeyOld: hasEmptyKeys ? newWopiConfig.privateKey : privateKey,
+ publicKey: newWopiConfig.publicKey,
+ modulus: newWopiConfig.modulus,
+ exponent: newWopiConfig.exponent,
+ privateKey: newWopiConfig.privateKey
+ }
+ };
+
+ const newConfig = utils.deepMergeObjects(currentConfig, configUpdate);
+
+ if (tenantManager.isMultitenantMode(ctx) && !tenantManager.isDefaultTenant(ctx)) {
+ await tenantManager.setTenantConfig(ctx, newConfig);
+ } else {
+ await runtimeConfigManager.saveConfig(ctx, newConfig);
+ }
+
+ res.status(200).json(newConfig);
+ } catch (error) {
+ ctx.logger.error('WOPI key rotation error: %s', error.stack);
+ res.status(500).json({
+ success: false,
+ error: 'Failed to rotate WOPI keys',
+ details: error.message
+ });
+ } finally {
+ ctx.logger.info('WOPI key rotation end');
+ }
+});
+
+// Export router and helper for reuse in tests or other modules
+module.exports = router;
+module.exports.generateWopiKeys = generateWopiKeys;
diff --git a/AdminPanel/server/sources/server.js b/AdminPanel/server/sources/server.js
new file mode 100644
index 0000000000..214da33d8a
--- /dev/null
+++ b/AdminPanel/server/sources/server.js
@@ -0,0 +1,169 @@
+/*
+ * (c) Copyright Ascensio System SIA 2010-2024
+ *
+ * This program is a free software product. You can redistribute it and/or
+ * modify it under the terms of the GNU Affero General Public License (AGPL)
+ * version 3 as published by the Free Software Foundation. In accordance with
+ * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect
+ * that Ascensio System SIA expressly excludes the warranty of non-infringement
+ * of any third-party rights.
+ *
+ * This program is distributed WITHOUT ANY WARRANTY; without even the implied
+ * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For
+ * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html
+ *
+ * You can contact Ascensio System SIA at 20A-6 Ernesta Birznieka-Upish
+ * street, Riga, Latvia, EU, LV-1050.
+ *
+ * The interactive user interfaces in modified source and object code versions
+ * of the Program must display Appropriate Legal Notices, as required under
+ * Section 5 of the GNU AGPL version 3.
+ *
+ * Pursuant to Section 7(b) of the License you must retain the original Product
+ * logo when distributing the program. Pursuant to Section 7(e) we decline to
+ * grant you any rights under trademark law for use of our trademarks.
+ *
+ * All the Product's GUI elements, including illustrations and icon sets, as
+ * well as technical writing content are licensed under the terms of the
+ * Creative Commons Attribution-ShareAlike 4.0 International. See the License
+ * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode
+ *
+ */
+
+'use strict';
+
+const moduleReloader = require('../../../Common/sources/moduleReloader');
+const config = moduleReloader.requireConfigWithRuntime();
+const operationContext = require('../../../Common/sources/operationContext');
+const tenantManager = require('../../../Common/sources/tenantManager');
+const license = require('../../../Common/sources/license');
+const utils = require('../../../Common/sources/utils');
+const runtimeConfigManager = require('../../../Common/sources/runtimeConfigManager');
+
+const express = require('express');
+const http = require('http');
+const cors = require('cors');
+const path = require('path');
+const fs = require('fs');
+const infoRouter = require('../../../DocService/sources/routes/info');
+
+const configRouter = require('./routes/config/router');
+const adminpanelRouter = require('./routes/adminpanel/router');
+const wopiRouter = require('./routes/wopi/router');
+const passwordManager = require('./passwordManager');
+const bootstrap = require('./bootstrap');
+
+const port = config.get('adminPanel.port');
+const cfgLicenseFile = config.get('license.license_file');
+
+const app = express();
+app.disable('x-powered-by');
+
+// Trust first proxy for X-Forwarded-* headers (nginx, load balancer)
+app.set('trust proxy', 1);
+
+const server = http.createServer(app);
+
+let licenseInfo, licenseOriginal;
+
+const readLicense = async function () {
+ [licenseInfo, licenseOriginal] = await license.readLicense(cfgLicenseFile);
+};
+
+const updateLicense = async () => {
+ try {
+ await readLicense();
+ tenantManager.setDefLicense(licenseInfo, licenseOriginal);
+ operationContext.global.logger.info('End updateLicense');
+ } catch (err) {
+ operationContext.global.logger.error('updateLicense error: %s', err.stack);
+ }
+};
+
+updateLicense();
+fs.watchFile(cfgLicenseFile, updateLicense);
+setInterval(updateLicense, 86400000);
+
+// Generate and display bootstrap token if setup is required
+(async () => {
+ try {
+ const ctx = operationContext.global;
+ const setupRequired = await passwordManager.isSetupRequired(ctx);
+
+ if (setupRequired) {
+ // Check if token already exists and valid
+ const hasToken = bootstrap.hasValidBootstrapToken();
+
+ if (!hasToken) {
+ // Generate new bootstrap code
+ const {code, expiresAt} = await bootstrap.generateBootstrapToken(ctx);
+
+ // Log code as single line for log aggregation systems
+ ctx.logger.warn(
+ 'AdminPanel SETUP REQUIRED | Bootstrap code: ' + code + ' | Expires: ' + expiresAt.toISOString() + ' | Open: http://host/admin'
+ );
+ } else {
+ ctx.logger.warn('AdminPanel SETUP REQUIRED | Bootstrap code already exists in memory');
+ }
+ }
+ } catch (e) {
+ operationContext.global.logger.error('Bootstrap token generation error: %s', e.stack);
+ }
+})();
+
+const corsWithCredentials = cors({
+ origin: true,
+ credentials: true,
+ methods: ['GET', 'POST', 'PUT', 'DELETE', 'PATCH', 'OPTIONS'],
+ allowedHeaders: ['Content-Type', 'Authorization']
+});
+
+operationContext.global.logger.warn('AdminPanel server starting...');
+
+function disableCache(req, res, next) {
+ res.set({
+ 'Cache-Control': 'no-cache, no-store, must-revalidate',
+ Pragma: 'no-cache',
+ Expires: '0'
+ });
+ next();
+}
+
+app.use('/api/v1/admin/config', corsWithCredentials, utils.checkClientIp, disableCache, configRouter);
+app.use('/api/v1/admin/wopi', corsWithCredentials, utils.checkClientIp, disableCache, wopiRouter);
+app.use('/api/v1/admin', corsWithCredentials, utils.checkClientIp, disableCache, adminpanelRouter);
+app.get('/api/v1/admin/stat', corsWithCredentials, utils.checkClientIp, disableCache, async (req, res) => {
+ await infoRouter.licenseInfo(req, res);
+});
+// Serve AdminPanel client build as static assets
+const clientBuildPath = path.resolve('client/build');
+app.use('/', express.static(clientBuildPath));
+
+function serveSpaIndex(req, res, next) {
+ if (req.path.startsWith('/api')) return next();
+
+ // Disable caching for SPA index.html to ensure updates work
+ disableCache(req, res, () => {});
+
+ res.sendFile(path.join(clientBuildPath, 'index.html'));
+}
+// Client SPA routes fallback
+app.get('*', serveSpaIndex);
+
+app.use((err, req, res, _next) => {
+ const ctx = new operationContext.Context();
+ ctx.initFromRequest(req);
+ ctx.logger.error('default error handler:%s', err.stack);
+ res.sendStatus(500);
+});
+
+server.listen(port, () => {
+ operationContext.global.logger.warn('AdminPanel server listening on port %d', port);
+});
+
+//Initialize watch here to avoid circular import with operationContext
+runtimeConfigManager.initRuntimeConfigWatcher(operationContext.global).catch(err => {
+ operationContext.global.logger.warn('initRuntimeConfigWatcher error: %s', err.stack);
+});
+//after all required modules in all files
+moduleReloader.finalizeConfigWithRuntime();
diff --git a/CHANGELOG.md b/CHANGELOG.md
new file mode 100644
index 0000000000..58f54c7d21
--- /dev/null
+++ b/CHANGELOG.md
@@ -0,0 +1,15 @@
+# Change log
+
+## develop
+
+### Back-end
+
+-
+
+## 5.1.1
+
+### Back-end
+
+- Add reconnection.attempts, reconnection.delay options to config - applicable for editor-server connection
+- Add sockjs config section for testing purposes
+- Fix inconsistent database status after files assemble in case of rapid open/close connection
diff --git a/CoAuthoring/coauthoring.teamlab.com.txt b/CoAuthoring/coauthoring.teamlab.com.txt
deleted file mode 100644
index 880bd1fb0e..0000000000
--- a/CoAuthoring/coauthoring.teamlab.com.txt
+++ /dev/null
@@ -1,47 +0,0 @@
-coauthoring.teamlab.com
-50.19.108.255
-
---------------------------------------------------------------
-login: ******************
-password: ******************
-
-SSH через PyTTY - http://www.chiark.greenend.org.uk/~sgtatham/putty/download.html
-вместо FTP - SFTP через Filezilla - http://filezilla.ru/get/
-
---------------------------------------------------------------
-/home/www/nodejs-coauthoring - здесь размещено приложение
-Приложение запущенно через supervisord - он запускает при старте и перезапускает при падении - http://supervisord.org
-supervisord запущен от root и сама nodejs тоже работает от root
-supervisor.conf - (симлинка) на конфиг приложения в супервизоре
-
-чтоб перезапустить приложение необходимо выплнить в консоли
->sudo supervisorctl restart nodejs-coauthoring
-
-чтоб посмотреть статусы приложений
->sudo supervisorctl status
-
-Создать pem файл(на винде)
->openssl pkcs12 -in "C:\Users\Alexey.Golubev\Documents\teamlab.com-2014.pfx" -out "C:\Users\Alexey.Golubev\Documents\teamlab.com-2014.pem" -nodes
-В полученом файле хранится и приватный ключ и сертификат, далее необходимо в ручную разделить его на две части.
-
-Удалить апач
->sudo /etc/init.d/apache2 stop
->sudo apt-get purge apache2*
-
-Как развернуть сервер
-
-Устанавливаем апдейт для apt-get
->apt-get update
-
-Устанавливаем необходимые тулзы
->apt-get install g++
->apt-get install mongodb
->apt-get install nodejs npm
->apt-get install supervisor
-
-Устанавливаем расширения для node.js
->npm install express@2.5.8
->npm install underscore
->npm install sockjs
->npm install mongodb
-
diff --git a/CoAuthoring/documentation/helpMongo.txt b/CoAuthoring/documentation/helpMongo.txt
deleted file mode 100644
index 09c14edd87..0000000000
--- a/CoAuthoring/documentation/helpMongo.txt
+++ /dev/null
@@ -1,51 +0,0 @@
-show dbs -
-show collections -
-db.createCollection("name_collection") -
-db."name_collection".remove() -
-db."name_collection".find() -
-db."name_collection".drop() -
-db."name_collection".insert({_element_}) -
-db."name_collection".ensureIndex(_index_) -
-db."name_collection".update() -
-
-
-:
-http://habrahabr.ru/post/74273/
-http://habrahabr.ru/post/103699/
-http://ru.wiki.mongodb.org/display/DOCS/Manual
-
- mongodb AWS Market Place.
-
-- .
- : https://aws.amazon.com/marketplace/pp/B0087GMEQ2/ref=srh_res_product_title?ie=UTF8&sr=0-3&qid=1362476550209
-MongoDB with EBS RAID
-Sold by: 10gen
-
- MongoDB Security Group :
-TCP 22
-TCP 27017
- VPC, security group .
-
- SSH :
-$ sudo chkconfig mongod on
-$ sudo /etc/init.d/mongod start
- http://docs.mongodb.org/ecosystem/tutorial/install-mongodb-on-amazon-ec2/#starting-mongodb
-
-
-mongo coAuthoring
-> db.createCollection("messages")
-> db.messages.ensureIndex({"docid":1})
-> db.createCollection("changes")
-> db.changes.ensureIndex({"docid":1})
-> exit
-
- - c VPC. , . .
-
- SSH Amazon'e
- (Key Pair).
- ( ) /home/root/cert/key_pair.pem ( SFTP)
- :
-chmod 600 /home/root/cert/key_pair.pem ( SFTP)
- SSH:
-ssh internal_ip -i /home/root/cert/key_pair.pem -l ec2-user
-
diff --git a/CoAuthoring/install/ConfigMongoDB.bat b/CoAuthoring/install/ConfigMongoDB.bat
deleted file mode 100644
index c1e1f14368..0000000000
--- a/CoAuthoring/install/ConfigMongoDB.bat
+++ /dev/null
@@ -1,20 +0,0 @@
-ECHO OFF
-SET DB_CONFIG_FILE=config_db.tmp
-SET DB_NAME=coAuthoring
-
-ECHO.
-ECHO ----------------------------------------
-ECHO Configure %DB_NAME% database
-ECHO ----------------------------------------
-
-ECHO db.createCollection("messages") > %DB_CONFIG_FILE%
-ECHO db.messages.ensureIndex({"docid":1}) >> %DB_CONFIG_FILE%
-ECHO db.createCollection("changes") >> %DB_CONFIG_FILE%
-ECHO db.changes.ensureIndex({"docid":1}) >> %DB_CONFIG_FILE%
-ECHO exit >> %DB_CONFIG_FILE%
-
-call %~dp0..\mongodb\bin\mongo.exe %DB_NAME% < %DB_CONFIG_FILE% || exit /b 1
-
-DEL /Q %DB_CONFIG_FILE%
-
-exit /b 0
\ No newline at end of file
diff --git a/CoAuthoring/install/InstallNodeJSModules.bat b/CoAuthoring/install/InstallNodeJSModules.bat
deleted file mode 100644
index a030bd5ad9..0000000000
--- a/CoAuthoring/install/InstallNodeJSModules.bat
+++ /dev/null
@@ -1,23 +0,0 @@
-ECHO OFF
-
-SET RUN_FOLDER=%CD%
-
-CD /D %~dp0..\ || exit /b 1
-
-ECHO.
-ECHO ----------------------------------------
-ECHO Install node.js modules
-ECHO ----------------------------------------
-
-call npm install express --production || exit /b 1
-call npm install underscore --production || exit /b 1
-call npm install sockjs --production|| exit /b 1
-call npm install mongodb@1.1.4 --production || exit /b 1
-call npm install mysql || exit /b 1
-
-cd /D ..\Common || exit /b 1
-call npm install log4js@0.6.2 --production || exit /b 1
-
-CD /D %RUN_FOLDER% || exit /b 1
-
-exit /b 0
diff --git a/CoAuthoring/install/StartMongoDb.bat b/CoAuthoring/install/StartMongoDb.bat
deleted file mode 100644
index 702d6dbd1c..0000000000
--- a/CoAuthoring/install/StartMongoDb.bat
+++ /dev/null
@@ -1,5 +0,0 @@
-SET DB_FILE_PATH=..\data\db
-IF NOT EXIST %DB_FILE_PATH% MKDIR %DB_FILE_PATH%
-
-call ..\mongodb\bin\mongod.exe --journal --dbpath "%DB_FILE_PATH%"
-pause
\ No newline at end of file
diff --git a/CoAuthoring/install/StartServer.bat b/CoAuthoring/install/StartServer.bat
deleted file mode 100644
index d9d0038b17..0000000000
--- a/CoAuthoring/install/StartServer.bat
+++ /dev/null
@@ -1,2 +0,0 @@
-call node --debug ../sources/server.js
-pause
\ No newline at end of file
diff --git a/CoAuthoring/node_modules/express/.npmignore b/CoAuthoring/node_modules/express/.npmignore
deleted file mode 100644
index 52fcd60330..0000000000
--- a/CoAuthoring/node_modules/express/.npmignore
+++ /dev/null
@@ -1,11 +0,0 @@
-.git*
-benchmarks/
-coverage/
-docs/
-examples/
-support/
-test/
-testing.js
-.DS_Store
-.travis.yml
-Contributing.md
diff --git a/CoAuthoring/node_modules/express/History.md b/CoAuthoring/node_modules/express/History.md
deleted file mode 100644
index 17ba278ac9..0000000000
--- a/CoAuthoring/node_modules/express/History.md
+++ /dev/null
@@ -1,2356 +0,0 @@
-4.9.8 / 2014-10-17
-==================
-
- * Fix `res.redirect` body when redirect status specified
- * deps: accepts@~1.1.2
- - Fix error when media type has invalid parameter
- - deps: negotiator@0.4.9
-
-4.9.7 / 2014-10-10
-==================
-
- * Fix using same param name in array of paths
-
-4.9.6 / 2014-10-08
-==================
-
- * deps: accepts@~1.1.1
- - deps: mime-types@~2.0.2
- - deps: negotiator@0.4.8
- * deps: serve-static@~1.6.4
- - Fix redirect loop when index file serving disabled
- * deps: type-is@~1.5.2
- - deps: mime-types@~2.0.2
-
-4.9.5 / 2014-09-24
-==================
-
- * deps: etag@~1.4.0
- * deps: proxy-addr@~1.0.3
- - Use `forwarded` npm module
- * deps: send@0.9.3
- - deps: etag@~1.4.0
- * deps: serve-static@~1.6.3
- - deps: send@0.9.3
-
-4.9.4 / 2014-09-19
-==================
-
- * deps: qs@2.2.4
- - Fix issue with object keys starting with numbers truncated
-
-4.9.3 / 2014-09-18
-==================
-
- * deps: proxy-addr@~1.0.2
- - Fix a global leak when multiple subnets are trusted
- - deps: ipaddr.js@0.1.3
-
-4.9.2 / 2014-09-17
-==================
-
- * Fix regression for empty string `path` in `app.use`
- * Fix `router.use` to accept array of middleware without path
- * Improve error message for bad `app.use` arguments
-
-4.9.1 / 2014-09-16
-==================
-
- * Fix `app.use` to accept array of middleware without path
- * deps: depd@0.4.5
- * deps: etag@~1.3.1
- * deps: send@0.9.2
- - deps: depd@0.4.5
- - deps: etag@~1.3.1
- - deps: range-parser@~1.0.2
- * deps: serve-static@~1.6.2
- - deps: send@0.9.2
-
-4.9.0 / 2014-09-08
-==================
-
- * Add `res.sendStatus`
- * Invoke callback for sendfile when client aborts
- - Applies to `res.sendFile`, `res.sendfile`, and `res.download`
- - `err` will be populated with request aborted error
- * Support IP address host in `req.subdomains`
- * Use `etag` to generate `ETag` headers
- * deps: accepts@~1.1.0
- - update `mime-types`
- * deps: cookie-signature@1.0.5
- * deps: debug@~2.0.0
- * deps: finalhandler@0.2.0
- - Set `X-Content-Type-Options: nosniff` header
- - deps: debug@~2.0.0
- * deps: fresh@0.2.4
- * deps: media-typer@0.3.0
- - Throw error when parameter format invalid on parse
- * deps: qs@2.2.3
- - Fix issue where first empty value in array is discarded
- * deps: range-parser@~1.0.2
- * deps: send@0.9.1
- - Add `lastModified` option
- - Use `etag` to generate `ETag` header
- - deps: debug@~2.0.0
- - deps: fresh@0.2.4
- * deps: serve-static@~1.6.1
- - Add `lastModified` option
- - deps: send@0.9.1
- * deps: type-is@~1.5.1
- - fix `hasbody` to be true for `content-length: 0`
- - deps: media-typer@0.3.0
- - deps: mime-types@~2.0.1
- * deps: vary@~1.0.0
- - Accept valid `Vary` header string as `field`
-
-4.8.8 / 2014-09-04
-==================
-
- * deps: send@0.8.5
- - Fix a path traversal issue when using `root`
- - Fix malicious path detection for empty string path
- * deps: serve-static@~1.5.4
- - deps: send@0.8.5
-
-4.8.7 / 2014-08-29
-==================
-
- * deps: qs@2.2.2
- - Remove unnecessary cloning
-
-4.8.6 / 2014-08-27
-==================
-
- * deps: qs@2.2.0
- - Array parsing fix
- - Performance improvements
-
-4.8.5 / 2014-08-18
-==================
-
- * deps: send@0.8.3
- - deps: destroy@1.0.3
- - deps: on-finished@2.1.0
- * deps: serve-static@~1.5.3
- - deps: send@0.8.3
-
-4.8.4 / 2014-08-14
-==================
-
- * deps: qs@1.2.2
- * deps: send@0.8.2
- - Work around `fd` leak in Node.js 0.10 for `fs.ReadStream`
- * deps: serve-static@~1.5.2
- - deps: send@0.8.2
-
-4.8.3 / 2014-08-10
-==================
-
- * deps: parseurl@~1.3.0
- * deps: qs@1.2.1
- * deps: serve-static@~1.5.1
- - Fix parsing of weird `req.originalUrl` values
- - deps: parseurl@~1.3.0
- - deps: utils-merge@1.0.0
-
-4.8.2 / 2014-08-07
-==================
-
- * deps: qs@1.2.0
- - Fix parsing array of objects
-
-4.8.1 / 2014-08-06
-==================
-
- * fix incorrect deprecation warnings on `res.download`
- * deps: qs@1.1.0
- - Accept urlencoded square brackets
- - Accept empty values in implicit array notation
-
-4.8.0 / 2014-08-05
-==================
-
- * add `res.sendFile`
- - accepts a file system path instead of a URL
- - requires an absolute path or `root` option specified
- * deprecate `res.sendfile` -- use `res.sendFile` instead
- * support mounted app as any argument to `app.use()`
- * deps: qs@1.0.2
- - Complete rewrite
- - Limits array length to 20
- - Limits object depth to 5
- - Limits parameters to 1,000
- * deps: send@0.8.1
- - Add `extensions` option
- * deps: serve-static@~1.5.0
- - Add `extensions` option
- - deps: send@0.8.1
-
-4.7.4 / 2014-08-04
-==================
-
- * fix `res.sendfile` regression for serving directory index files
- * deps: send@0.7.4
- - Fix incorrect 403 on Windows and Node.js 0.11
- - Fix serving index files without root dir
- * deps: serve-static@~1.4.4
- - deps: send@0.7.4
-
-4.7.3 / 2014-08-04
-==================
-
- * deps: send@0.7.3
- - Fix incorrect 403 on Windows and Node.js 0.11
- * deps: serve-static@~1.4.3
- - Fix incorrect 403 on Windows and Node.js 0.11
- - deps: send@0.7.3
-
-4.7.2 / 2014-07-27
-==================
-
- * deps: depd@0.4.4
- - Work-around v8 generating empty stack traces
- * deps: send@0.7.2
- - deps: depd@0.4.4
- * deps: serve-static@~1.4.2
-
-4.7.1 / 2014-07-26
-==================
-
- * deps: depd@0.4.3
- - Fix exception when global `Error.stackTraceLimit` is too low
- * deps: send@0.7.1
- - deps: depd@0.4.3
- * deps: serve-static@~1.4.1
-
-4.7.0 / 2014-07-25
-==================
-
- * fix `req.protocol` for proxy-direct connections
- * configurable query parser with `app.set('query parser', parser)`
- - `app.set('query parser', 'extended')` parse with "qs" module
- - `app.set('query parser', 'simple')` parse with "querystring" core module
- - `app.set('query parser', false)` disable query string parsing
- - `app.set('query parser', true)` enable simple parsing
- * deprecate `res.json(status, obj)` -- use `res.status(status).json(obj)` instead
- * deprecate `res.jsonp(status, obj)` -- use `res.status(status).jsonp(obj)` instead
- * deprecate `res.send(status, body)` -- use `res.status(status).send(body)` instead
- * deps: debug@1.0.4
- * deps: depd@0.4.2
- - Add `TRACE_DEPRECATION` environment variable
- - Remove non-standard grey color from color output
- - Support `--no-deprecation` argument
- - Support `--trace-deprecation` argument
- * deps: finalhandler@0.1.0
- - Respond after request fully read
- - deps: debug@1.0.4
- * deps: parseurl@~1.2.0
- - Cache URLs based on original value
- - Remove no-longer-needed URL mis-parse work-around
- - Simplify the "fast-path" `RegExp`
- * deps: send@0.7.0
- - Add `dotfiles` option
- - Cap `maxAge` value to 1 year
- - deps: debug@1.0.4
- - deps: depd@0.4.2
- * deps: serve-static@~1.4.0
- - deps: parseurl@~1.2.0
- - deps: send@0.7.0
- * perf: prevent multiple `Buffer` creation in `res.send`
-
-4.6.1 / 2014-07-12
-==================
-
- * fix `subapp.mountpath` regression for `app.use(subapp)`
-
-4.6.0 / 2014-07-11
-==================
-
- * accept multiple callbacks to `app.use()`
- * add explicit "Rosetta Flash JSONP abuse" protection
- - previous versions are not vulnerable; this is just explicit protection
- * catch errors in multiple `req.param(name, fn)` handlers
- * deprecate `res.redirect(url, status)` -- use `res.redirect(status, url)` instead
- * fix `res.send(status, num)` to send `num` as json (not error)
- * remove unnecessary escaping when `res.jsonp` returns JSON response
- * support non-string `path` in `app.use(path, fn)`
- - supports array of paths
- - supports `RegExp`
- * router: fix optimization on router exit
- * router: refactor location of `try` blocks
- * router: speed up standard `app.use(fn)`
- * deps: debug@1.0.3
- - Add support for multiple wildcards in namespaces
- * deps: finalhandler@0.0.3
- - deps: debug@1.0.3
- * deps: methods@1.1.0
- - add `CONNECT`
- * deps: parseurl@~1.1.3
- - faster parsing of href-only URLs
- * deps: path-to-regexp@0.1.3
- * deps: send@0.6.0
- - deps: debug@1.0.3
- * deps: serve-static@~1.3.2
- - deps: parseurl@~1.1.3
- - deps: send@0.6.0
- * perf: fix arguments reassign deopt in some `res` methods
-
-4.5.1 / 2014-07-06
-==================
-
- * fix routing regression when altering `req.method`
-
-4.5.0 / 2014-07-04
-==================
-
- * add deprecation message to non-plural `req.accepts*`
- * add deprecation message to `res.send(body, status)`
- * add deprecation message to `res.vary()`
- * add `headers` option to `res.sendfile`
- - use to set headers on successful file transfer
- * add `mergeParams` option to `Router`
- - merges `req.params` from parent routes
- * add `req.hostname` -- correct name for what `req.host` returns
- * deprecate things with `depd` module
- * deprecate `req.host` -- use `req.hostname` instead
- * fix behavior when handling request without routes
- * fix handling when `route.all` is only route
- * invoke `router.param()` only when route matches
- * restore `req.params` after invoking router
- * use `finalhandler` for final response handling
- * use `media-typer` to alter content-type charset
- * deps: accepts@~1.0.7
- * deps: send@0.5.0
- - Accept string for `maxage` (converted by `ms`)
- - Include link in default redirect response
- * deps: serve-static@~1.3.0
- - Accept string for `maxAge` (converted by `ms`)
- - Add `setHeaders` option
- - Include HTML link in redirect response
- - deps: send@0.5.0
- * deps: type-is@~1.3.2
-
-4.4.5 / 2014-06-26
-==================
-
- * deps: cookie-signature@1.0.4
- - fix for timing attacks
-
-4.4.4 / 2014-06-20
-==================
-
- * fix `res.attachment` Unicode filenames in Safari
- * fix "trim prefix" debug message in `express:router`
- * deps: accepts@~1.0.5
- * deps: buffer-crc32@0.2.3
-
-4.4.3 / 2014-06-11
-==================
-
- * fix persistence of modified `req.params[name]` from `app.param()`
- * deps: accepts@1.0.3
- - deps: negotiator@0.4.6
- * deps: debug@1.0.2
- * deps: send@0.4.3
- - Do not throw un-catchable error on file open race condition
- - Use `escape-html` for HTML escaping
- - deps: debug@1.0.2
- - deps: finished@1.2.2
- - deps: fresh@0.2.2
- * deps: serve-static@1.2.3
- - Do not throw un-catchable error on file open race condition
- - deps: send@0.4.3
-
-4.4.2 / 2014-06-09
-==================
-
- * fix catching errors from top-level handlers
- * use `vary` module for `res.vary`
- * deps: debug@1.0.1
- * deps: proxy-addr@1.0.1
- * deps: send@0.4.2
- - fix "event emitter leak" warnings
- - deps: debug@1.0.1
- - deps: finished@1.2.1
- * deps: serve-static@1.2.2
- - fix "event emitter leak" warnings
- - deps: send@0.4.2
- * deps: type-is@1.2.1
-
-4.4.1 / 2014-06-02
-==================
-
- * deps: methods@1.0.1
- * deps: send@0.4.1
- - Send `max-age` in `Cache-Control` in correct format
- * deps: serve-static@1.2.1
- - use `escape-html` for escaping
- - deps: send@0.4.1
-
-4.4.0 / 2014-05-30
-==================
-
- * custom etag control with `app.set('etag', val)`
- - `app.set('etag', function(body, encoding){ return '"etag"' })` custom etag generation
- - `app.set('etag', 'weak')` weak tag
- - `app.set('etag', 'strong')` strong etag
- - `app.set('etag', false)` turn off
- - `app.set('etag', true)` standard etag
- * mark `res.send` ETag as weak and reduce collisions
- * update accepts to 1.0.2
- - Fix interpretation when header not in request
- * update send to 0.4.0
- - Calculate ETag with md5 for reduced collisions
- - Ignore stream errors after request ends
- - deps: debug@0.8.1
- * update serve-static to 1.2.0
- - Calculate ETag with md5 for reduced collisions
- - Ignore stream errors after request ends
- - deps: send@0.4.0
-
-4.3.2 / 2014-05-28
-==================
-
- * fix handling of errors from `router.param()` callbacks
-
-4.3.1 / 2014-05-23
-==================
-
- * revert "fix behavior of multiple `app.VERB` for the same path"
- - this caused a regression in the order of route execution
-
-4.3.0 / 2014-05-21
-==================
-
- * add `req.baseUrl` to access the path stripped from `req.url` in routes
- * fix behavior of multiple `app.VERB` for the same path
- * fix issue routing requests among sub routers
- * invoke `router.param()` only when necessary instead of every match
- * proper proxy trust with `app.set('trust proxy', trust)`
- - `app.set('trust proxy', 1)` trust first hop
- - `app.set('trust proxy', 'loopback')` trust loopback addresses
- - `app.set('trust proxy', '10.0.0.1')` trust single IP
- - `app.set('trust proxy', '10.0.0.1/16')` trust subnet
- - `app.set('trust proxy', '10.0.0.1, 10.0.0.2')` trust list
- - `app.set('trust proxy', false)` turn off
- - `app.set('trust proxy', true)` trust everything
- * set proper `charset` in `Content-Type` for `res.send`
- * update type-is to 1.2.0
- - support suffix matching
-
-4.2.0 / 2014-05-11
-==================
-
- * deprecate `app.del()` -- use `app.delete()` instead
- * deprecate `res.json(obj, status)` -- use `res.json(status, obj)` instead
- - the edge-case `res.json(status, num)` requires `res.status(status).json(num)`
- * deprecate `res.jsonp(obj, status)` -- use `res.jsonp(status, obj)` instead
- - the edge-case `res.jsonp(status, num)` requires `res.status(status).jsonp(num)`
- * fix `req.next` when inside router instance
- * include `ETag` header in `HEAD` requests
- * keep previous `Content-Type` for `res.jsonp`
- * support PURGE method
- - add `app.purge`
- - add `router.purge`
- - include PURGE in `app.all`
- * update debug to 0.8.0
- - add `enable()` method
- - change from stderr to stdout
- * update methods to 1.0.0
- - add PURGE
-
-4.1.2 / 2014-05-08
-==================
-
- * fix `req.host` for IPv6 literals
- * fix `res.jsonp` error if callback param is object
-
-4.1.1 / 2014-04-27
-==================
-
- * fix package.json to reflect supported node version
-
-4.1.0 / 2014-04-24
-==================
-
- * pass options from `res.sendfile` to `send`
- * preserve casing of headers in `res.header` and `res.set`
- * support unicode file names in `res.attachment` and `res.download`
- * update accepts to 1.0.1
- - deps: negotiator@0.4.0
- * update cookie to 0.1.2
- - Fix for maxAge == 0
- - made compat with expires field
- * update send to 0.3.0
- - Accept API options in options object
- - Coerce option types
- - Control whether to generate etags
- - Default directory access to 403 when index disabled
- - Fix sending files with dots without root set
- - Include file path in etag
- - Make "Can't set headers after they are sent." catchable
- - Send full entity-body for multi range requests
- - Set etags to "weak"
- - Support "If-Range" header
- - Support multiple index paths
- - deps: mime@1.2.11
- * update serve-static to 1.1.0
- - Accept options directly to `send` module
- - Resolve relative paths at middleware setup
- - Use parseurl to parse the URL from request
- - deps: send@0.3.0
- * update type-is to 1.1.0
- - add non-array values support
- - add `multipart` as a shorthand
-
-4.0.0 / 2014-04-09
-==================
-
- * remove:
- - node 0.8 support
- - connect and connect's patches except for charset handling
- - express(1) - moved to [express-generator](https://github.com/expressjs/generator)
- - `express.createServer()` - it has been deprecated for a long time. Use `express()`
- - `app.configure` - use logic in your own app code
- - `app.router` - is removed
- - `req.auth` - use `basic-auth` instead
- - `req.accepted*` - use `req.accepts*()` instead
- - `res.location` - relative URL resolution is removed
- - `res.charset` - include the charset in the content type when using `res.set()`
- - all bundled middleware except `static`
- * change:
- - `app.route` -> `app.mountpath` when mounting an express app in another express app
- - `json spaces` no longer enabled by default in development
- - `req.accepts*` -> `req.accepts*s` - i.e. `req.acceptsEncoding` -> `req.acceptsEncodings`
- - `req.params` is now an object instead of an array
- - `res.locals` is no longer a function. It is a plain js object. Treat it as such.
- - `res.headerSent` -> `res.headersSent` to match node.js ServerResponse object
- * refactor:
- - `req.accepts*` with [accepts](https://github.com/expressjs/accepts)
- - `req.is` with [type-is](https://github.com/expressjs/type-is)
- - [path-to-regexp](https://github.com/component/path-to-regexp)
- * add:
- - `app.router()` - returns the app Router instance
- - `app.route()` - Proxy to the app's `Router#route()` method to create a new route
- - Router & Route - public API
-
-3.17.8 / 2014-10-15
-===================
-
- * deps: connect@2.26.6
- - deps: compression@~1.1.2
- - deps: csurf@~1.6.2
- - deps: errorhandler@~1.2.2
-
-3.17.7 / 2014-10-08
-===================
-
- * deps: connect@2.26.5
- - Fix accepting non-object arguments to `logger`
- - deps: serve-static@~1.6.4
-
-3.17.6 / 2014-10-02
-===================
-
- * deps: connect@2.26.4
- - deps: morgan@~1.3.2
- - deps: type-is@~1.5.2
-
-3.17.5 / 2014-09-24
-===================
-
- * deps: connect@2.26.3
- - deps: body-parser@~1.8.4
- - deps: serve-favicon@~2.1.5
- - deps: serve-static@~1.6.3
- * deps: proxy-addr@~1.0.3
- - Use `forwarded` npm module
- * deps: send@0.9.3
- - deps: etag@~1.4.0
-
-3.17.4 / 2014-09-19
-===================
-
- * deps: connect@2.26.2
- - deps: body-parser@~1.8.3
- - deps: qs@2.2.4
-
-3.17.3 / 2014-09-18
-===================
-
- * deps: proxy-addr@~1.0.2
- - Fix a global leak when multiple subnets are trusted
- - deps: ipaddr.js@0.1.3
-
-3.17.2 / 2014-09-15
-===================
-
- * Use `crc` instead of `buffer-crc32` for speed
- * deps: connect@2.26.1
- - deps: body-parser@~1.8.2
- - deps: depd@0.4.5
- - deps: express-session@~1.8.2
- - deps: morgan@~1.3.1
- - deps: serve-favicon@~2.1.3
- - deps: serve-static@~1.6.2
- * deps: depd@0.4.5
- * deps: send@0.9.2
- - deps: depd@0.4.5
- - deps: etag@~1.3.1
- - deps: range-parser@~1.0.2
-
-3.17.1 / 2014-09-08
-===================
-
- * Fix error in `req.subdomains` on empty host
-
-3.17.0 / 2014-09-08
-===================
-
- * Support `X-Forwarded-Host` in `req.subdomains`
- * Support IP address host in `req.subdomains`
- * deps: connect@2.26.0
- - deps: body-parser@~1.8.1
- - deps: compression@~1.1.0
- - deps: connect-timeout@~1.3.0
- - deps: cookie-parser@~1.3.3
- - deps: cookie-signature@1.0.5
- - deps: csurf@~1.6.1
- - deps: debug@~2.0.0
- - deps: errorhandler@~1.2.0
- - deps: express-session@~1.8.1
- - deps: finalhandler@0.2.0
- - deps: fresh@0.2.4
- - deps: media-typer@0.3.0
- - deps: method-override@~2.2.0
- - deps: morgan@~1.3.0
- - deps: qs@2.2.3
- - deps: serve-favicon@~2.1.3
- - deps: serve-index@~1.2.1
- - deps: serve-static@~1.6.1
- - deps: type-is@~1.5.1
- - deps: vhost@~3.0.0
- * deps: cookie-signature@1.0.5
- * deps: debug@~2.0.0
- * deps: fresh@0.2.4
- * deps: media-typer@0.3.0
- - Throw error when parameter format invalid on parse
- * deps: range-parser@~1.0.2
- * deps: send@0.9.1
- - Add `lastModified` option
- - Use `etag` to generate `ETag` header
- - deps: debug@~2.0.0
- - deps: fresh@0.2.4
- * deps: vary@~1.0.0
- - Accept valid `Vary` header string as `field`
-
-3.16.10 / 2014-09-04
-====================
-
- * deps: connect@2.25.10
- - deps: serve-static@~1.5.4
- * deps: send@0.8.5
- - Fix a path traversal issue when using `root`
- - Fix malicious path detection for empty string path
-
-3.16.9 / 2014-08-29
-===================
-
- * deps: connect@2.25.9
- - deps: body-parser@~1.6.7
- - deps: qs@2.2.2
-
-3.16.8 / 2014-08-27
-===================
-
- * deps: connect@2.25.8
- - deps: body-parser@~1.6.6
- - deps: csurf@~1.4.1
- - deps: qs@2.2.0
-
-3.16.7 / 2014-08-18
-===================
-
- * deps: connect@2.25.7
- - deps: body-parser@~1.6.5
- - deps: express-session@~1.7.6
- - deps: morgan@~1.2.3
- - deps: serve-static@~1.5.3
- * deps: send@0.8.3
- - deps: destroy@1.0.3
- - deps: on-finished@2.1.0
-
-3.16.6 / 2014-08-14
-===================
-
- * deps: connect@2.25.6
- - deps: body-parser@~1.6.4
- - deps: qs@1.2.2
- - deps: serve-static@~1.5.2
- * deps: send@0.8.2
- - Work around `fd` leak in Node.js 0.10 for `fs.ReadStream`
-
-3.16.5 / 2014-08-11
-===================
-
- * deps: connect@2.25.5
- - Fix backwards compatibility in `logger`
-
-3.16.4 / 2014-08-10
-===================
-
- * Fix original URL parsing in `res.location`
- * deps: connect@2.25.4
- - Fix `query` middleware breaking with argument
- - deps: body-parser@~1.6.3
- - deps: compression@~1.0.11
- - deps: connect-timeout@~1.2.2
- - deps: express-session@~1.7.5
- - deps: method-override@~2.1.3
- - deps: on-headers@~1.0.0
- - deps: parseurl@~1.3.0
- - deps: qs@1.2.1
- - deps: response-time@~2.0.1
- - deps: serve-index@~1.1.6
- - deps: serve-static@~1.5.1
- * deps: parseurl@~1.3.0
-
-3.16.3 / 2014-08-07
-===================
-
- * deps: connect@2.25.3
- - deps: multiparty@3.3.2
-
-3.16.2 / 2014-08-07
-===================
-
- * deps: connect@2.25.2
- - deps: body-parser@~1.6.2
- - deps: qs@1.2.0
-
-3.16.1 / 2014-08-06
-===================
-
- * deps: connect@2.25.1
- - deps: body-parser@~1.6.1
- - deps: qs@1.1.0
-
-3.16.0 / 2014-08-05
-===================
-
- * deps: connect@2.25.0
- - deps: body-parser@~1.6.0
- - deps: compression@~1.0.10
- - deps: csurf@~1.4.0
- - deps: express-session@~1.7.4
- - deps: qs@1.0.2
- - deps: serve-static@~1.5.0
- * deps: send@0.8.1
- - Add `extensions` option
-
-3.15.3 / 2014-08-04
-===================
-
- * fix `res.sendfile` regression for serving directory index files
- * deps: connect@2.24.3
- - deps: serve-index@~1.1.5
- - deps: serve-static@~1.4.4
- * deps: send@0.7.4
- - Fix incorrect 403 on Windows and Node.js 0.11
- - Fix serving index files without root dir
-
-3.15.2 / 2014-07-27
-===================
-
- * deps: connect@2.24.2
- - deps: body-parser@~1.5.2
- - deps: depd@0.4.4
- - deps: express-session@~1.7.2
- - deps: morgan@~1.2.2
- - deps: serve-static@~1.4.2
- * deps: depd@0.4.4
- - Work-around v8 generating empty stack traces
- * deps: send@0.7.2
- - deps: depd@0.4.4
-
-3.15.1 / 2014-07-26
-===================
-
- * deps: connect@2.24.1
- - deps: body-parser@~1.5.1
- - deps: depd@0.4.3
- - deps: express-session@~1.7.1
- - deps: morgan@~1.2.1
- - deps: serve-index@~1.1.4
- - deps: serve-static@~1.4.1
- * deps: depd@0.4.3
- - Fix exception when global `Error.stackTraceLimit` is too low
- * deps: send@0.7.1
- - deps: depd@0.4.3
-
-3.15.0 / 2014-07-22
-===================
-
- * Fix `req.protocol` for proxy-direct connections
- * Pass options from `res.sendfile` to `send`
- * deps: connect@2.24.0
- - deps: body-parser@~1.5.0
- - deps: compression@~1.0.9
- - deps: connect-timeout@~1.2.1
- - deps: debug@1.0.4
- - deps: depd@0.4.2
- - deps: express-session@~1.7.0
- - deps: finalhandler@0.1.0
- - deps: method-override@~2.1.2
- - deps: morgan@~1.2.0
- - deps: multiparty@3.3.1
- - deps: parseurl@~1.2.0
- - deps: serve-static@~1.4.0
- * deps: debug@1.0.4
- * deps: depd@0.4.2
- - Add `TRACE_DEPRECATION` environment variable
- - Remove non-standard grey color from color output
- - Support `--no-deprecation` argument
- - Support `--trace-deprecation` argument
- * deps: parseurl@~1.2.0
- - Cache URLs based on original value
- - Remove no-longer-needed URL mis-parse work-around
- - Simplify the "fast-path" `RegExp`
- * deps: send@0.7.0
- - Add `dotfiles` option
- - Cap `maxAge` value to 1 year
- - deps: debug@1.0.4
- - deps: depd@0.4.2
-
-3.14.0 / 2014-07-11
-===================
-
- * add explicit "Rosetta Flash JSONP abuse" protection
- - previous versions are not vulnerable; this is just explicit protection
- * deprecate `res.redirect(url, status)` -- use `res.redirect(status, url)` instead
- * fix `res.send(status, num)` to send `num` as json (not error)
- * remove unnecessary escaping when `res.jsonp` returns JSON response
- * deps: basic-auth@1.0.0
- - support empty password
- - support empty username
- * deps: connect@2.23.0
- - deps: debug@1.0.3
- - deps: express-session@~1.6.4
- - deps: method-override@~2.1.0
- - deps: parseurl@~1.1.3
- - deps: serve-static@~1.3.1
- * deps: debug@1.0.3
- - Add support for multiple wildcards in namespaces
- * deps: methods@1.1.0
- - add `CONNECT`
- * deps: parseurl@~1.1.3
- - faster parsing of href-only URLs
-
-3.13.0 / 2014-07-03
-===================
-
- * add deprecation message to `app.configure`
- * add deprecation message to `req.auth`
- * use `basic-auth` to parse `Authorization` header
- * deps: connect@2.22.0
- - deps: csurf@~1.3.0
- - deps: express-session@~1.6.1
- - deps: multiparty@3.3.0
- - deps: serve-static@~1.3.0
- * deps: send@0.5.0
- - Accept string for `maxage` (converted by `ms`)
- - Include link in default redirect response
-
-3.12.1 / 2014-06-26
-===================
-
- * deps: connect@2.21.1
- - deps: cookie-parser@1.3.2
- - deps: cookie-signature@1.0.4
- - deps: express-session@~1.5.2
- - deps: type-is@~1.3.2
- * deps: cookie-signature@1.0.4
- - fix for timing attacks
-
-3.12.0 / 2014-06-21
-===================
-
- * use `media-typer` to alter content-type charset
- * deps: connect@2.21.0
- - deprecate `connect(middleware)` -- use `app.use(middleware)` instead
- - deprecate `connect.createServer()` -- use `connect()` instead
- - fix `res.setHeader()` patch to work with with get -> append -> set pattern
- - deps: compression@~1.0.8
- - deps: errorhandler@~1.1.1
- - deps: express-session@~1.5.0
- - deps: serve-index@~1.1.3
-
-3.11.0 / 2014-06-19
-===================
-
- * deprecate things with `depd` module
- * deps: buffer-crc32@0.2.3
- * deps: connect@2.20.2
- - deprecate `verify` option to `json` -- use `body-parser` npm module instead
- - deprecate `verify` option to `urlencoded` -- use `body-parser` npm module instead
- - deprecate things with `depd` module
- - use `finalhandler` for final response handling
- - use `media-typer` to parse `content-type` for charset
- - deps: body-parser@1.4.3
- - deps: connect-timeout@1.1.1
- - deps: cookie-parser@1.3.1
- - deps: csurf@1.2.2
- - deps: errorhandler@1.1.0
- - deps: express-session@1.4.0
- - deps: multiparty@3.2.9
- - deps: serve-index@1.1.2
- - deps: type-is@1.3.1
- - deps: vhost@2.0.0
-
-3.10.5 / 2014-06-11
-===================
-
- * deps: connect@2.19.6
- - deps: body-parser@1.3.1
- - deps: compression@1.0.7
- - deps: debug@1.0.2
- - deps: serve-index@1.1.1
- - deps: serve-static@1.2.3
- * deps: debug@1.0.2
- * deps: send@0.4.3
- - Do not throw un-catchable error on file open race condition
- - Use `escape-html` for HTML escaping
- - deps: debug@1.0.2
- - deps: finished@1.2.2
- - deps: fresh@0.2.2
-
-3.10.4 / 2014-06-09
-===================
-
- * deps: connect@2.19.5
- - fix "event emitter leak" warnings
- - deps: csurf@1.2.1
- - deps: debug@1.0.1
- - deps: serve-static@1.2.2
- - deps: type-is@1.2.1
- * deps: debug@1.0.1
- * deps: send@0.4.2
- - fix "event emitter leak" warnings
- - deps: finished@1.2.1
- - deps: debug@1.0.1
-
-3.10.3 / 2014-06-05
-===================
-
- * use `vary` module for `res.vary`
- * deps: connect@2.19.4
- - deps: errorhandler@1.0.2
- - deps: method-override@2.0.2
- - deps: serve-favicon@2.0.1
- * deps: debug@1.0.0
-
-3.10.2 / 2014-06-03
-===================
-
- * deps: connect@2.19.3
- - deps: compression@1.0.6
-
-3.10.1 / 2014-06-03
-===================
-
- * deps: connect@2.19.2
- - deps: compression@1.0.4
- * deps: proxy-addr@1.0.1
-
-3.10.0 / 2014-06-02
-===================
-
- * deps: connect@2.19.1
- - deprecate `methodOverride()` -- use `method-override` npm module instead
- - deps: body-parser@1.3.0
- - deps: method-override@2.0.1
- - deps: multiparty@3.2.8
- - deps: response-time@2.0.0
- - deps: serve-static@1.2.1
- * deps: methods@1.0.1
- * deps: send@0.4.1
- - Send `max-age` in `Cache-Control` in correct format
-
-3.9.0 / 2014-05-30
-==================
-
- * custom etag control with `app.set('etag', val)`
- - `app.set('etag', function(body, encoding){ return '"etag"' })` custom etag generation
- - `app.set('etag', 'weak')` weak tag
- - `app.set('etag', 'strong')` strong etag
- - `app.set('etag', false)` turn off
- - `app.set('etag', true)` standard etag
- * Include ETag in HEAD requests
- * mark `res.send` ETag as weak and reduce collisions
- * update connect to 2.18.0
- - deps: compression@1.0.3
- - deps: serve-index@1.1.0
- - deps: serve-static@1.2.0
- * update send to 0.4.0
- - Calculate ETag with md5 for reduced collisions
- - Ignore stream errors after request ends
- - deps: debug@0.8.1
-
-3.8.1 / 2014-05-27
-==================
-
- * update connect to 2.17.3
- - deps: body-parser@1.2.2
- - deps: express-session@1.2.1
- - deps: method-override@1.0.2
-
-3.8.0 / 2014-05-21
-==================
-
- * keep previous `Content-Type` for `res.jsonp`
- * set proper `charset` in `Content-Type` for `res.send`
- * update connect to 2.17.1
- - fix `res.charset` appending charset when `content-type` has one
- - deps: express-session@1.2.0
- - deps: morgan@1.1.1
- - deps: serve-index@1.0.3
-
-3.7.0 / 2014-05-18
-==================
-
- * proper proxy trust with `app.set('trust proxy', trust)`
- - `app.set('trust proxy', 1)` trust first hop
- - `app.set('trust proxy', 'loopback')` trust loopback addresses
- - `app.set('trust proxy', '10.0.0.1')` trust single IP
- - `app.set('trust proxy', '10.0.0.1/16')` trust subnet
- - `app.set('trust proxy', '10.0.0.1, 10.0.0.2')` trust list
- - `app.set('trust proxy', false)` turn off
- - `app.set('trust proxy', true)` trust everything
- * update connect to 2.16.2
- - deprecate `res.headerSent` -- use `res.headersSent`
- - deprecate `res.on("header")` -- use on-headers module instead
- - fix edge-case in `res.appendHeader` that would append in wrong order
- - json: use body-parser
- - urlencoded: use body-parser
- - dep: bytes@1.0.0
- - dep: cookie-parser@1.1.0
- - dep: csurf@1.2.0
- - dep: express-session@1.1.0
- - dep: method-override@1.0.1
-
-3.6.0 / 2014-05-09
-==================
-
- * deprecate `app.del()` -- use `app.delete()` instead
- * deprecate `res.json(obj, status)` -- use `res.json(status, obj)` instead
- - the edge-case `res.json(status, num)` requires `res.status(status).json(num)`
- * deprecate `res.jsonp(obj, status)` -- use `res.jsonp(status, obj)` instead
- - the edge-case `res.jsonp(status, num)` requires `res.status(status).jsonp(num)`
- * support PURGE method
- - add `app.purge`
- - add `router.purge`
- - include PURGE in `app.all`
- * update connect to 2.15.0
- * Add `res.appendHeader`
- * Call error stack even when response has been sent
- * Patch `res.headerSent` to return Boolean
- * Patch `res.headersSent` for node.js 0.8
- * Prevent default 404 handler after response sent
- * dep: compression@1.0.2
- * dep: connect-timeout@1.1.0
- * dep: debug@^0.8.0
- * dep: errorhandler@1.0.1
- * dep: express-session@1.0.4
- * dep: morgan@1.0.1
- * dep: serve-favicon@2.0.0
- * dep: serve-index@1.0.2
- * update debug to 0.8.0
- * add `enable()` method
- * change from stderr to stdout
- * update methods to 1.0.0
- - add PURGE
- * update mkdirp to 0.5.0
-
-3.5.3 / 2014-05-08
-==================
-
- * fix `req.host` for IPv6 literals
- * fix `res.jsonp` error if callback param is object
-
-3.5.2 / 2014-04-24
-==================
-
- * update connect to 2.14.5
- * update cookie to 0.1.2
- * update mkdirp to 0.4.0
- * update send to 0.3.0
-
-3.5.1 / 2014-03-25
-==================
-
- * pin less-middleware in generated app
-
-3.5.0 / 2014-03-06
-==================
-
- * bump deps
-
-3.4.8 / 2014-01-13
-==================
-
- * prevent incorrect automatic OPTIONS responses #1868 @dpatti
- * update binary and examples for jade 1.0 #1876 @yossi, #1877 @reqshark, #1892 @matheusazzi
- * throw 400 in case of malformed paths @rlidwka
-
-3.4.7 / 2013-12-10
-==================
-
- * update connect
-
-3.4.6 / 2013-12-01
-==================
-
- * update connect (raw-body)
-
-3.4.5 / 2013-11-27
-==================
-
- * update connect
- * res.location: remove leading ./ #1802 @kapouer
- * res.redirect: fix `res.redirect('toString') #1829 @michaelficarra
- * res.send: always send ETag when content-length > 0
- * router: add Router.all() method
-
-3.4.4 / 2013-10-29
-==================
-
- * update connect
- * update supertest
- * update methods
- * express(1): replace bodyParser() with urlencoded() and json() #1795 @chirag04
-
-3.4.3 / 2013-10-23
-==================
-
- * update connect
-
-3.4.2 / 2013-10-18
-==================
-
- * update connect
- * downgrade commander
-
-3.4.1 / 2013-10-15
-==================
-
- * update connect
- * update commander
- * jsonp: check if callback is a function
- * router: wrap encodeURIComponent in a try/catch #1735 (@lxe)
- * res.format: now includes chraset @1747 (@sorribas)
- * res.links: allow multiple calls @1746 (@sorribas)
-
-3.4.0 / 2013-09-07
-==================
-
- * add res.vary(). Closes #1682
- * update connect
-
-3.3.8 / 2013-09-02
-==================
-
- * update connect
-
-3.3.7 / 2013-08-28
-==================
-
- * update connect
-
-3.3.6 / 2013-08-27
-==================
-
- * Revert "remove charset from json responses. Closes #1631" (causes issues in some clients)
- * add: req.accepts take an argument list
-
-3.3.4 / 2013-07-08
-==================
-
- * update send and connect
-
-3.3.3 / 2013-07-04
-==================
-
- * update connect
-
-3.3.2 / 2013-07-03
-==================
-
- * update connect
- * update send
- * remove .version export
-
-3.3.1 / 2013-06-27
-==================
-
- * update connect
-
-3.3.0 / 2013-06-26
-==================
-
- * update connect
- * add support for multiple X-Forwarded-Proto values. Closes #1646
- * change: remove charset from json responses. Closes #1631
- * change: return actual booleans from req.accept* functions
- * fix jsonp callback array throw
-
-3.2.6 / 2013-06-02
-==================
-
- * update connect
-
-3.2.5 / 2013-05-21
-==================
-
- * update connect
- * update node-cookie
- * add: throw a meaningful error when there is no default engine
- * change generation of ETags with res.send() to GET requests only. Closes #1619
-
-3.2.4 / 2013-05-09
-==================
-
- * fix `req.subdomains` when no Host is present
- * fix `req.host` when no Host is present, return undefined
-
-3.2.3 / 2013-05-07
-==================
-
- * update connect / qs
-
-3.2.2 / 2013-05-03
-==================
-
- * update qs
-
-3.2.1 / 2013-04-29
-==================
-
- * add app.VERB() paths array deprecation warning
- * update connect
- * update qs and remove all ~ semver crap
- * fix: accept number as value of Signed Cookie
-
-3.2.0 / 2013-04-15
-==================
-
- * add "view" constructor setting to override view behaviour
- * add req.acceptsEncoding(name)
- * add req.acceptedEncodings
- * revert cookie signature change causing session race conditions
- * fix sorting of Accept values of the same quality
-
-3.1.2 / 2013-04-12
-==================
-
- * add support for custom Accept parameters
- * update cookie-signature
-
-3.1.1 / 2013-04-01
-==================
-
- * add X-Forwarded-Host support to `req.host`
- * fix relative redirects
- * update mkdirp
- * update buffer-crc32
- * remove legacy app.configure() method from app template.
-
-3.1.0 / 2013-01-25
-==================
-
- * add support for leading "." in "view engine" setting
- * add array support to `res.set()`
- * add node 0.8.x to travis.yml
- * add "subdomain offset" setting for tweaking `req.subdomains`
- * add `res.location(url)` implementing `res.redirect()`-like setting of Location
- * use app.get() for x-powered-by setting for inheritance
- * fix colons in passwords for `req.auth`
-
-3.0.6 / 2013-01-04
-==================
-
- * add http verb methods to Router
- * update connect
- * fix mangling of the `res.cookie()` options object
- * fix jsonp whitespace escape. Closes #1132
-
-3.0.5 / 2012-12-19
-==================
-
- * add throwing when a non-function is passed to a route
- * fix: explicitly remove Transfer-Encoding header from 204 and 304 responses
- * revert "add 'etag' option"
-
-3.0.4 / 2012-12-05
-==================
-
- * add 'etag' option to disable `res.send()` Etags
- * add escaping of urls in text/plain in `res.redirect()`
- for old browsers interpreting as html
- * change crc32 module for a more liberal license
- * update connect
-
-3.0.3 / 2012-11-13
-==================
-
- * update connect
- * update cookie module
- * fix cookie max-age
-
-3.0.2 / 2012-11-08
-==================
-
- * add OPTIONS to cors example. Closes #1398
- * fix route chaining regression. Closes #1397
-
-3.0.1 / 2012-11-01
-==================
-
- * update connect
-
-3.0.0 / 2012-10-23
-==================
-
- * add `make clean`
- * add "Basic" check to req.auth
- * add `req.auth` test coverage
- * add cb && cb(payload) to `res.jsonp()`. Closes #1374
- * add backwards compat for `res.redirect()` status. Closes #1336
- * add support for `res.json()` to retain previously defined Content-Types. Closes #1349
- * update connect
- * change `res.redirect()` to utilize a pathname-relative Location again. Closes #1382
- * remove non-primitive string support for `res.send()`
- * fix view-locals example. Closes #1370
- * fix route-separation example
-
-3.0.0rc5 / 2012-09-18
-==================
-
- * update connect
- * add redis search example
- * add static-files example
- * add "x-powered-by" setting (`app.disable('x-powered-by')`)
- * add "application/octet-stream" redirect Accept test case. Closes #1317
-
-3.0.0rc4 / 2012-08-30
-==================
-
- * add `res.jsonp()`. Closes #1307
- * add "verbose errors" option to error-pages example
- * add another route example to express(1) so people are not so confused
- * add redis online user activity tracking example
- * update connect dep
- * fix etag quoting. Closes #1310
- * fix error-pages 404 status
- * fix jsonp callback char restrictions
- * remove old OPTIONS default response
-
-3.0.0rc3 / 2012-08-13
-==================
-
- * update connect dep
- * fix signed cookies to work with `connect.cookieParser()` ("s:" prefix was missing) [tnydwrds]
- * fix `res.render()` clobbering of "locals"
-
-3.0.0rc2 / 2012-08-03
-==================
-
- * add CORS example
- * update connect dep
- * deprecate `.createServer()` & remove old stale examples
- * fix: escape `res.redirect()` link
- * fix vhost example
-
-3.0.0rc1 / 2012-07-24
-==================
-
- * add more examples to view-locals
- * add scheme-relative redirects (`res.redirect("//foo.com")`) support
- * update cookie dep
- * update connect dep
- * update send dep
- * fix `express(1)` -h flag, use -H for hogan. Closes #1245
- * fix `res.sendfile()` socket error handling regression
-
-3.0.0beta7 / 2012-07-16
-==================
-
- * update connect dep for `send()` root normalization regression
-
-3.0.0beta6 / 2012-07-13
-==================
-
- * add `err.view` property for view errors. Closes #1226
- * add "jsonp callback name" setting
- * add support for "/foo/:bar*" non-greedy matches
- * change `res.sendfile()` to use `send()` module
- * change `res.send` to use "response-send" module
- * remove `app.locals.use` and `res.locals.use`, use regular middleware
-
-3.0.0beta5 / 2012-07-03
-==================
-
- * add "make check" support
- * add route-map example
- * add `res.json(obj, status)` support back for BC
- * add "methods" dep, remove internal methods module
- * update connect dep
- * update auth example to utilize cores pbkdf2
- * updated tests to use "supertest"
-
-3.0.0beta4 / 2012-06-25
-==================
-
- * Added `req.auth`
- * Added `req.range(size)`
- * Added `res.links(obj)`
- * Added `res.send(body, status)` support back for backwards compat
- * Added `.default()` support to `res.format()`
- * Added 2xx / 304 check to `req.fresh`
- * Revert "Added + support to the router"
- * Fixed `res.send()` freshness check, respect res.statusCode
-
-3.0.0beta3 / 2012-06-15
-==================
-
- * Added hogan `--hjs` to express(1) [nullfirm]
- * Added another example to content-negotiation
- * Added `fresh` dep
- * Changed: `res.send()` always checks freshness
- * Fixed: expose connects mime module. Cloases #1165
-
-3.0.0beta2 / 2012-06-06
-==================
-
- * Added `+` support to the router
- * Added `req.host`
- * Changed `req.param()` to check route first
- * Update connect dep
-
-3.0.0beta1 / 2012-06-01
-==================
-
- * Added `res.format()` callback to override default 406 behaviour
- * Fixed `res.redirect()` 406. Closes #1154
-
-3.0.0alpha5 / 2012-05-30
-==================
-
- * Added `req.ip`
- * Added `{ signed: true }` option to `res.cookie()`
- * Removed `res.signedCookie()`
- * Changed: dont reverse `req.ips`
- * Fixed "trust proxy" setting check for `req.ips`
-
-3.0.0alpha4 / 2012-05-09
-==================
-
- * Added: allow `[]` in jsonp callback. Closes #1128
- * Added `PORT` env var support in generated template. Closes #1118 [benatkin]
- * Updated: connect 2.2.2
-
-3.0.0alpha3 / 2012-05-04
-==================
-
- * Added public `app.routes`. Closes #887
- * Added _view-locals_ example
- * Added _mvc_ example
- * Added `res.locals.use()`. Closes #1120
- * Added conditional-GET support to `res.send()`
- * Added: coerce `res.set()` values to strings
- * Changed: moved `static()` in generated apps below router
- * Changed: `res.send()` only set ETag when not previously set
- * Changed connect 2.2.1 dep
- * Changed: `make test` now runs unit / acceptance tests
- * Fixed req/res proto inheritance
-
-3.0.0alpha2 / 2012-04-26
-==================
-
- * Added `make benchmark` back
- * Added `res.send()` support for `String` objects
- * Added client-side data exposing example
- * Added `res.header()` and `req.header()` aliases for BC
- * Added `express.createServer()` for BC
- * Perf: memoize parsed urls
- * Perf: connect 2.2.0 dep
- * Changed: make `expressInit()` middleware self-aware
- * Fixed: use app.get() for all core settings
- * Fixed redis session example
- * Fixed session example. Closes #1105
- * Fixed generated express dep. Closes #1078
-
-3.0.0alpha1 / 2012-04-15
-==================
-
- * Added `app.locals.use(callback)`
- * Added `app.locals` object
- * Added `app.locals(obj)`
- * Added `res.locals` object
- * Added `res.locals(obj)`
- * Added `res.format()` for content-negotiation
- * Added `app.engine()`
- * Added `res.cookie()` JSON cookie support
- * Added "trust proxy" setting
- * Added `req.subdomains`
- * Added `req.protocol`
- * Added `req.secure`
- * Added `req.path`
- * Added `req.ips`
- * Added `req.fresh`
- * Added `req.stale`
- * Added comma-delmited / array support for `req.accepts()`
- * Added debug instrumentation
- * Added `res.set(obj)`
- * Added `res.set(field, value)`
- * Added `res.get(field)`
- * Added `app.get(setting)`. Closes #842
- * Added `req.acceptsLanguage()`
- * Added `req.acceptsCharset()`
- * Added `req.accepted`
- * Added `req.acceptedLanguages`
- * Added `req.acceptedCharsets`
- * Added "json replacer" setting
- * Added "json spaces" setting
- * Added X-Forwarded-Proto support to `res.redirect()`. Closes #92
- * Added `--less` support to express(1)
- * Added `express.response` prototype
- * Added `express.request` prototype
- * Added `express.application` prototype
- * Added `app.path()`
- * Added `app.render()`
- * Added `res.type()` to replace `res.contentType()`
- * Changed: `res.redirect()` to add relative support
- * Changed: enable "jsonp callback" by default
- * Changed: renamed "case sensitive routes" to "case sensitive routing"
- * Rewrite of all tests with mocha
- * Removed "root" setting
- * Removed `res.redirect('home')` support
- * Removed `req.notify()`
- * Removed `app.register()`
- * Removed `app.redirect()`
- * Removed `app.is()`
- * Removed `app.helpers()`
- * Removed `app.dynamicHelpers()`
- * Fixed `res.sendfile()` with non-GET. Closes #723
- * Fixed express(1) public dir for windows. Closes #866
-
-2.5.9/ 2012-04-02
-==================
-
- * Added support for PURGE request method [pbuyle]
- * Fixed `express(1)` generated app `app.address()` before `listening` [mmalecki]
-
-2.5.8 / 2012-02-08
-==================
-
- * Update mkdirp dep. Closes #991
-
-2.5.7 / 2012-02-06
-==================
-
- * Fixed `app.all` duplicate DELETE requests [mscdex]
-
-2.5.6 / 2012-01-13
-==================
-
- * Updated hamljs dev dep. Closes #953
-
-2.5.5 / 2012-01-08
-==================
-
- * Fixed: set `filename` on cached templates [matthewleon]
-
-2.5.4 / 2012-01-02
-==================
-
- * Fixed `express(1)` eol on 0.4.x. Closes #947
-
-2.5.3 / 2011-12-30
-==================
-
- * Fixed `req.is()` when a charset is present
-
-2.5.2 / 2011-12-10
-==================
-
- * Fixed: express(1) LF -> CRLF for windows
-
-2.5.1 / 2011-11-17
-==================
-
- * Changed: updated connect to 1.8.x
- * Removed sass.js support from express(1)
-
-2.5.0 / 2011-10-24
-==================
-
- * Added ./routes dir for generated app by default
- * Added npm install reminder to express(1) app gen
- * Added 0.5.x support
- * Removed `make test-cov` since it wont work with node 0.5.x
- * Fixed express(1) public dir for windows. Closes #866
-
-2.4.7 / 2011-10-05
-==================
-
- * Added mkdirp to express(1). Closes #795
- * Added simple _json-config_ example
- * Added shorthand for the parsed request's pathname via `req.path`
- * Changed connect dep to 1.7.x to fix npm issue...
- * Fixed `res.redirect()` __HEAD__ support. [reported by xerox]
- * Fixed `req.flash()`, only escape args
- * Fixed absolute path checking on windows. Closes #829 [reported by andrewpmckenzie]
-
-2.4.6 / 2011-08-22
-==================
-
- * Fixed multiple param callback regression. Closes #824 [reported by TroyGoode]
-
-2.4.5 / 2011-08-19
-==================
-
- * Added support for routes to handle errors. Closes #809
- * Added `app.routes.all()`. Closes #803
- * Added "basepath" setting to work in conjunction with reverse proxies etc.
- * Refactored `Route` to use a single array of callbacks
- * Added support for multiple callbacks for `app.param()`. Closes #801
-Closes #805
- * Changed: removed .call(self) for route callbacks
- * Dependency: `qs >= 0.3.1`
- * Fixed `res.redirect()` on windows due to `join()` usage. Closes #808
-
-2.4.4 / 2011-08-05
-==================
-
- * Fixed `res.header()` intention of a set, even when `undefined`
- * Fixed `*`, value no longer required
- * Fixed `res.send(204)` support. Closes #771
-
-2.4.3 / 2011-07-14
-==================
-
- * Added docs for `status` option special-case. Closes #739
- * Fixed `options.filename`, exposing the view path to template engines
-
-2.4.2. / 2011-07-06
-==================
-
- * Revert "removed jsonp stripping" for XSS
-
-2.4.1 / 2011-07-06
-==================
-
- * Added `res.json()` JSONP support. Closes #737
- * Added _extending-templates_ example. Closes #730
- * Added "strict routing" setting for trailing slashes
- * Added support for multiple envs in `app.configure()` calls. Closes #735
- * Changed: `res.send()` using `res.json()`
- * Changed: when cookie `path === null` don't default it
- * Changed; default cookie path to "home" setting. Closes #731
- * Removed _pids/logs_ creation from express(1)
-
-2.4.0 / 2011-06-28
-==================
-
- * Added chainable `res.status(code)`
- * Added `res.json()`, an explicit version of `res.send(obj)`
- * Added simple web-service example
-
-2.3.12 / 2011-06-22
-==================
-
- * \#express is now on freenode! come join!
- * Added `req.get(field, param)`
- * Added links to Japanese documentation, thanks @hideyukisaito!
- * Added; the `express(1)` generated app outputs the env
- * Added `content-negotiation` example
- * Dependency: connect >= 1.5.1 < 2.0.0
- * Fixed view layout bug. Closes #720
- * Fixed; ignore body on 304. Closes #701
-
-2.3.11 / 2011-06-04
-==================
-
- * Added `npm test`
- * Removed generation of dummy test file from `express(1)`
- * Fixed; `express(1)` adds express as a dep
- * Fixed; prune on `prepublish`
-
-2.3.10 / 2011-05-27
-==================
-
- * Added `req.route`, exposing the current route
- * Added _package.json_ generation support to `express(1)`
- * Fixed call to `app.param()` function for optional params. Closes #682
-
-2.3.9 / 2011-05-25
-==================
-
- * Fixed bug-ish with `../' in `res.partial()` calls
-
-2.3.8 / 2011-05-24
-==================
-
- * Fixed `app.options()`
-
-2.3.7 / 2011-05-23
-==================
-
- * Added route `Collection`, ex: `app.get('/user/:id').remove();`
- * Added support for `app.param(fn)` to define param logic
- * Removed `app.param()` support for callback with return value
- * Removed module.parent check from express(1) generated app. Closes #670
- * Refactored router. Closes #639
-
-2.3.6 / 2011-05-20
-==================
-
- * Changed; using devDependencies instead of git submodules
- * Fixed redis session example
- * Fixed markdown example
- * Fixed view caching, should not be enabled in development
-
-2.3.5 / 2011-05-20
-==================
-
- * Added export `.view` as alias for `.View`
-
-2.3.4 / 2011-05-08
-==================
-
- * Added `./examples/say`
- * Fixed `res.sendfile()` bug preventing the transfer of files with spaces
-
-2.3.3 / 2011-05-03
-==================
-
- * Added "case sensitive routes" option.
- * Changed; split methods supported per rfc [slaskis]
- * Fixed route-specific middleware when using the same callback function several times
-
-2.3.2 / 2011-04-27
-==================
-
- * Fixed view hints
-
-2.3.1 / 2011-04-26
-==================
-
- * Added `app.match()` as `app.match.all()`
- * Added `app.lookup()` as `app.lookup.all()`
- * Added `app.remove()` for `app.remove.all()`
- * Added `app.remove.VERB()`
- * Fixed template caching collision issue. Closes #644
- * Moved router over from connect and started refactor
-
-2.3.0 / 2011-04-25
-==================
-
- * Added options support to `res.clearCookie()`
- * Added `res.helpers()` as alias of `res.locals()`
- * Added; json defaults to UTF-8 with `res.send()`. Closes #632. [Daniel * Dependency `connect >= 1.4.0`
- * Changed; auto set Content-Type in res.attachement [Aaron Heckmann]
- * Renamed "cache views" to "view cache". Closes #628
- * Fixed caching of views when using several apps. Closes #637
- * Fixed gotcha invoking `app.param()` callbacks once per route middleware.
-Closes #638
- * Fixed partial lookup precedence. Closes #631
-Shaw]
-
-2.2.2 / 2011-04-12
-==================
-
- * Added second callback support for `res.download()` connection errors
- * Fixed `filename` option passing to template engine
-
-2.2.1 / 2011-04-04
-==================
-
- * Added `layout(path)` helper to change the layout within a view. Closes #610
- * Fixed `partial()` collection object support.
- Previously only anything with `.length` would work.
- When `.length` is present one must still be aware of holes,
- however now `{ collection: {foo: 'bar'}}` is valid, exposes
- `keyInCollection` and `keysInCollection`.
-
- * Performance improved with better view caching
- * Removed `request` and `response` locals
- * Changed; errorHandler page title is now `Express` instead of `Connect`
-
-2.2.0 / 2011-03-30
-==================
-
- * Added `app.lookup.VERB()`, ex `app.lookup.put('/user/:id')`. Closes #606
- * Added `app.match.VERB()`, ex `app.match.put('/user/12')`. Closes #606
- * Added `app.VERB(path)` as alias of `app.lookup.VERB()`.
- * Dependency `connect >= 1.2.0`
-
-2.1.1 / 2011-03-29
-==================
-
- * Added; expose `err.view` object when failing to locate a view
- * Fixed `res.partial()` call `next(err)` when no callback is given [reported by aheckmann]
- * Fixed; `res.send(undefined)` responds with 204 [aheckmann]
-
-2.1.0 / 2011-03-24
-==================
-
- * Added `/_?` partial lookup support. Closes #447
- * Added `request`, `response`, and `app` local variables
- * Added `settings` local variable, containing the app's settings
- * Added `req.flash()` exception if `req.session` is not available
- * Added `res.send(bool)` support (json response)
- * Fixed stylus example for latest version
- * Fixed; wrap try/catch around `res.render()`
-
-2.0.0 / 2011-03-17
-==================
-
- * Fixed up index view path alternative.
- * Changed; `res.locals()` without object returns the locals
-
-2.0.0rc3 / 2011-03-17
-==================
-
- * Added `res.locals(obj)` to compliment `res.local(key, val)`
- * Added `res.partial()` callback support
- * Fixed recursive error reporting issue in `res.render()`
-
-2.0.0rc2 / 2011-03-17
-==================
-
- * Changed; `partial()` "locals" are now optional
- * Fixed `SlowBuffer` support. Closes #584 [reported by tyrda01]
- * Fixed .filename view engine option [reported by drudge]
- * Fixed blog example
- * Fixed `{req,res}.app` reference when mounting [Ben Weaver]
-
-2.0.0rc / 2011-03-14
-==================
-
- * Fixed; expose `HTTPSServer` constructor
- * Fixed express(1) default test charset. Closes #579 [reported by secoif]
- * Fixed; default charset to utf-8 instead of utf8 for lame IE [reported by NickP]
-
-2.0.0beta3 / 2011-03-09
-==================
-
- * Added support for `res.contentType()` literal
- The original `res.contentType('.json')`,
- `res.contentType('application/json')`, and `res.contentType('json')`
- will work now.
- * Added `res.render()` status option support back
- * Added charset option for `res.render()`
- * Added `.charset` support (via connect 1.0.4)
- * Added view resolution hints when in development and a lookup fails
- * Added layout lookup support relative to the page view.
- For example while rendering `./views/user/index.jade` if you create
- `./views/user/layout.jade` it will be used in favour of the root layout.
- * Fixed `res.redirect()`. RFC states absolute url [reported by unlink]
- * Fixed; default `res.send()` string charset to utf8
- * Removed `Partial` constructor (not currently used)
-
-2.0.0beta2 / 2011-03-07
-==================
-
- * Added res.render() `.locals` support back to aid in migration process
- * Fixed flash example
-
-2.0.0beta / 2011-03-03
-==================
-
- * Added HTTPS support
- * Added `res.cookie()` maxAge support
- * Added `req.header()` _Referrer_ / _Referer_ special-case, either works
- * Added mount support for `res.redirect()`, now respects the mount-point
- * Added `union()` util, taking place of `merge(clone())` combo
- * Added stylus support to express(1) generated app
- * Added secret to session middleware used in examples and generated app
- * Added `res.local(name, val)` for progressive view locals
- * Added default param support to `req.param(name, default)`
- * Added `app.disabled()` and `app.enabled()`
- * Added `app.register()` support for omitting leading ".", either works
- * Added `res.partial()`, using the same interface as `partial()` within a view. Closes #539
- * Added `app.param()` to map route params to async/sync logic
- * Added; aliased `app.helpers()` as `app.locals()`. Closes #481
- * Added extname with no leading "." support to `res.contentType()`
- * Added `cache views` setting, defaulting to enabled in "production" env
- * Added index file partial resolution, eg: partial('user') may try _views/user/index.jade_.
- * Added `req.accepts()` support for extensions
- * Changed; `res.download()` and `res.sendfile()` now utilize Connect's
- static file server `connect.static.send()`.
- * Changed; replaced `connect.utils.mime()` with npm _mime_ module
- * Changed; allow `req.query` to be pre-defined (via middleware or other parent
- * Changed view partial resolution, now relative to parent view
- * Changed view engine signature. no longer `engine.render(str, options, callback)`, now `engine.compile(str, options) -> Function`, the returned function accepts `fn(locals)`.
- * Fixed `req.param()` bug returning Array.prototype methods. Closes #552
- * Fixed; using `Stream#pipe()` instead of `sys.pump()` in `res.sendfile()`
- * Fixed; using _qs_ module instead of _querystring_
- * Fixed; strip unsafe chars from jsonp callbacks
- * Removed "stream threshold" setting
-
-1.0.8 / 2011-03-01
-==================
-
- * Allow `req.query` to be pre-defined (via middleware or other parent app)
- * "connect": ">= 0.5.0 < 1.0.0". Closes #547
- * Removed the long deprecated __EXPRESS_ENV__ support
-
-1.0.7 / 2011-02-07
-==================
-
- * Fixed `render()` setting inheritance.
- Mounted apps would not inherit "view engine"
-
-1.0.6 / 2011-02-07
-==================
-
- * Fixed `view engine` setting bug when period is in dirname
-
-1.0.5 / 2011-02-05
-==================
-
- * Added secret to generated app `session()` call
-
-1.0.4 / 2011-02-05
-==================
-
- * Added `qs` dependency to _package.json_
- * Fixed namespaced `require()`s for latest connect support
-
-1.0.3 / 2011-01-13
-==================
-
- * Remove unsafe characters from JSONP callback names [Ryan Grove]
-
-1.0.2 / 2011-01-10
-==================
-
- * Removed nested require, using `connect.router`
-
-1.0.1 / 2010-12-29
-==================
-
- * Fixed for middleware stacked via `createServer()`
- previously the `foo` middleware passed to `createServer(foo)`
- would not have access to Express methods such as `res.send()`
- or props like `req.query` etc.
-
-1.0.0 / 2010-11-16
-==================
-
- * Added; deduce partial object names from the last segment.
- For example by default `partial('forum/post', postObject)` will
- give you the _post_ object, providing a meaningful default.
- * Added http status code string representation to `res.redirect()` body
- * Added; `res.redirect()` supporting _text/plain_ and _text/html_ via __Accept__.
- * Added `req.is()` to aid in content negotiation
- * Added partial local inheritance [suggested by masylum]. Closes #102
- providing access to parent template locals.
- * Added _-s, --session[s]_ flag to express(1) to add session related middleware
- * Added _--template_ flag to express(1) to specify the
- template engine to use.
- * Added _--css_ flag to express(1) to specify the
- stylesheet engine to use (or just plain css by default).
- * Added `app.all()` support [thanks aheckmann]
- * Added partial direct object support.
- You may now `partial('user', user)` providing the "user" local,
- vs previously `partial('user', { object: user })`.
- * Added _route-separation_ example since many people question ways
- to do this with CommonJS modules. Also view the _blog_ example for
- an alternative.
- * Performance; caching view path derived partial object names
- * Fixed partial local inheritance precedence. [reported by Nick Poulden] Closes #454
- * Fixed jsonp support; _text/javascript_ as per mailinglist discussion
-
-1.0.0rc4 / 2010-10-14
-==================
-
- * Added _NODE_ENV_ support, _EXPRESS_ENV_ is deprecated and will be removed in 1.0.0
- * Added route-middleware support (very helpful, see the [docs](http://expressjs.com/guide.html#Route-Middleware))
- * Added _jsonp callback_ setting to enable/disable jsonp autowrapping [Dav Glass]
- * Added callback query check on response.send to autowrap JSON objects for simple webservice implementations [Dav Glass]
- * Added `partial()` support for array-like collections. Closes #434
- * Added support for swappable querystring parsers
- * Added session usage docs. Closes #443
- * Added dynamic helper caching. Closes #439 [suggested by maritz]
- * Added authentication example
- * Added basic Range support to `res.sendfile()` (and `res.download()` etc)
- * Changed; `express(1)` generated app using 2 spaces instead of 4
- * Default env to "development" again [aheckmann]
- * Removed _context_ option is no more, use "scope"
- * Fixed; exposing _./support_ libs to examples so they can run without installs
- * Fixed mvc example
-
-1.0.0rc3 / 2010-09-20
-==================
-
- * Added confirmation for `express(1)` app generation. Closes #391
- * Added extending of flash formatters via `app.flashFormatters`
- * Added flash formatter support. Closes #411
- * Added streaming support to `res.sendfile()` using `sys.pump()` when >= "stream threshold"
- * Added _stream threshold_ setting for `res.sendfile()`
- * Added `res.send()` __HEAD__ support
- * Added `res.clearCookie()`
- * Added `res.cookie()`
- * Added `res.render()` headers option
- * Added `res.redirect()` response bodies
- * Added `res.render()` status option support. Closes #425 [thanks aheckmann]
- * Fixed `res.sendfile()` responding with 403 on malicious path
- * Fixed `res.download()` bug; when an error occurs remove _Content-Disposition_
- * Fixed; mounted apps settings now inherit from parent app [aheckmann]
- * Fixed; stripping Content-Length / Content-Type when 204
- * Fixed `res.send()` 204. Closes #419
- * Fixed multiple _Set-Cookie_ headers via `res.header()`. Closes #402
- * Fixed bug messing with error handlers when `listenFD()` is called instead of `listen()`. [thanks guillermo]
-
-
-1.0.0rc2 / 2010-08-17
-==================
-
- * Added `app.register()` for template engine mapping. Closes #390
- * Added `res.render()` callback support as second argument (no options)
- * Added callback support to `res.download()`
- * Added callback support for `res.sendfile()`
- * Added support for middleware access via `express.middlewareName()` vs `connect.middlewareName()`
- * Added "partials" setting to docs
- * Added default expresso tests to `express(1)` generated app. Closes #384
- * Fixed `res.sendfile()` error handling, defer via `next()`
- * Fixed `res.render()` callback when a layout is used [thanks guillermo]
- * Fixed; `make install` creating ~/.node_libraries when not present
- * Fixed issue preventing error handlers from being defined anywhere. Closes #387
-
-1.0.0rc / 2010-07-28
-==================
-
- * Added mounted hook. Closes #369
- * Added connect dependency to _package.json_
-
- * Removed "reload views" setting and support code
- development env never caches, production always caches.
-
- * Removed _param_ in route callbacks, signature is now
- simply (req, res, next), previously (req, res, params, next).
- Use _req.params_ for path captures, _req.query_ for GET params.
-
- * Fixed "home" setting
- * Fixed middleware/router precedence issue. Closes #366
- * Fixed; _configure()_ callbacks called immediately. Closes #368
-
-1.0.0beta2 / 2010-07-23
-==================
-
- * Added more examples
- * Added; exporting `Server` constructor
- * Added `Server#helpers()` for view locals
- * Added `Server#dynamicHelpers()` for dynamic view locals. Closes #349
- * Added support for absolute view paths
- * Added; _home_ setting defaults to `Server#route` for mounted apps. Closes #363
- * Added Guillermo Rauch to the contributor list
- * Added support for "as" for non-collection partials. Closes #341
- * Fixed _install.sh_, ensuring _~/.node_libraries_ exists. Closes #362 [thanks jf]
- * Fixed `res.render()` exceptions, now passed to `next()` when no callback is given [thanks guillermo]
- * Fixed instanceof `Array` checks, now `Array.isArray()`
- * Fixed express(1) expansion of public dirs. Closes #348
- * Fixed middleware precedence. Closes #345
- * Fixed view watcher, now async [thanks aheckmann]
-
-1.0.0beta / 2010-07-15
-==================
-
- * Re-write
- - much faster
- - much lighter
- - Check [ExpressJS.com](http://expressjs.com) for migration guide and updated docs
-
-0.14.0 / 2010-06-15
-==================
-
- * Utilize relative requires
- * Added Static bufferSize option [aheckmann]
- * Fixed caching of view and partial subdirectories [aheckmann]
- * Fixed mime.type() comments now that ".ext" is not supported
- * Updated haml submodule
- * Updated class submodule
- * Removed bin/express
-
-0.13.0 / 2010-06-01
-==================
-
- * Added node v0.1.97 compatibility
- * Added support for deleting cookies via Request#cookie('key', null)
- * Updated haml submodule
- * Fixed not-found page, now using using charset utf-8
- * Fixed show-exceptions page, now using using charset utf-8
- * Fixed view support due to fs.readFile Buffers
- * Changed; mime.type() no longer accepts ".type" due to node extname() changes
-
-0.12.0 / 2010-05-22
-==================
-
- * Added node v0.1.96 compatibility
- * Added view `helpers` export which act as additional local variables
- * Updated haml submodule
- * Changed ETag; removed inode, modified time only
- * Fixed LF to CRLF for setting multiple cookies
- * Fixed cookie complation; values are now urlencoded
- * Fixed cookies parsing; accepts quoted values and url escaped cookies
-
-0.11.0 / 2010-05-06
-==================
-
- * Added support for layouts using different engines
- - this.render('page.html.haml', { layout: 'super-cool-layout.html.ejs' })
- - this.render('page.html.haml', { layout: 'foo' }) // assumes 'foo.html.haml'
- - this.render('page.html.haml', { layout: false }) // no layout
- * Updated ext submodule
- * Updated haml submodule
- * Fixed EJS partial support by passing along the context. Issue #307
-
-0.10.1 / 2010-05-03
-==================
-
- * Fixed binary uploads.
-
-0.10.0 / 2010-04-30
-==================
-
- * Added charset support via Request#charset (automatically assigned to 'UTF-8' when respond()'s
- encoding is set to 'utf8' or 'utf-8'.
- * Added "encoding" option to Request#render(). Closes #299
- * Added "dump exceptions" setting, which is enabled by default.
- * Added simple ejs template engine support
- * Added error response support for text/plain, application/json. Closes #297
- * Added callback function param to Request#error()
- * Added Request#sendHead()
- * Added Request#stream()
- * Added support for Request#respond(304, null) for empty response bodies
- * Added ETag support to Request#sendfile()
- * Added options to Request#sendfile(), passed to fs.createReadStream()
- * Added filename arg to Request#download()
- * Performance enhanced due to pre-reversing plugins so that plugins.reverse() is not called on each request
- * Performance enhanced by preventing several calls to toLowerCase() in Router#match()
- * Changed; Request#sendfile() now streams
- * Changed; Renamed Request#halt() to Request#respond(). Closes #289
- * Changed; Using sys.inspect() instead of JSON.encode() for error output
- * Changed; run() returns the http.Server instance. Closes #298
- * Changed; Defaulting Server#host to null (INADDR_ANY)
- * Changed; Logger "common" format scale of 0.4f
- * Removed Logger "request" format
- * Fixed; Catching ENOENT in view caching, preventing error when "views/partials" is not found
- * Fixed several issues with http client
- * Fixed Logger Content-Length output
- * Fixed bug preventing Opera from retaining the generated session id. Closes #292
-
-0.9.0 / 2010-04-14
-==================
-
- * Added DSL level error() route support
- * Added DSL level notFound() route support
- * Added Request#error()
- * Added Request#notFound()
- * Added Request#render() callback function. Closes #258
- * Added "max upload size" setting
- * Added "magic" variables to collection partials (\_\_index\_\_, \_\_length\_\_, \_\_isFirst\_\_, \_\_isLast\_\_). Closes #254
- * Added [haml.js](http://github.com/visionmedia/haml.js) submodule; removed haml-js
- * Added callback function support to Request#halt() as 3rd/4th arg
- * Added preprocessing of route param wildcards using param(). Closes #251
- * Added view partial support (with collections etc)
- * Fixed bug preventing falsey params (such as ?page=0). Closes #286
- * Fixed setting of multiple cookies. Closes #199
- * Changed; view naming convention is now NAME.TYPE.ENGINE (for example page.html.haml)
- * Changed; session cookie is now httpOnly
- * Changed; Request is no longer global
- * Changed; Event is no longer global
- * Changed; "sys" module is no longer global
- * Changed; moved Request#download to Static plugin where it belongs
- * Changed; Request instance created before body parsing. Closes #262
- * Changed; Pre-caching views in memory when "cache view contents" is enabled. Closes #253
- * Changed; Pre-caching view partials in memory when "cache view partials" is enabled
- * Updated support to node --version 0.1.90
- * Updated dependencies
- * Removed set("session cookie") in favour of use(Session, { cookie: { ... }})
- * Removed utils.mixin(); use Object#mergeDeep()
-
-0.8.0 / 2010-03-19
-==================
-
- * Added coffeescript example app. Closes #242
- * Changed; cache api now async friendly. Closes #240
- * Removed deprecated 'express/static' support. Use 'express/plugins/static'
-
-0.7.6 / 2010-03-19
-==================
-
- * Added Request#isXHR. Closes #229
- * Added `make install` (for the executable)
- * Added `express` executable for setting up simple app templates
- * Added "GET /public/*" to Static plugin, defaulting to /public
- * Added Static plugin
- * Fixed; Request#render() only calls cache.get() once
- * Fixed; Namespacing View caches with "view:"
- * Fixed; Namespacing Static caches with "static:"
- * Fixed; Both example apps now use the Static plugin
- * Fixed set("views"). Closes #239
- * Fixed missing space for combined log format
- * Deprecated Request#sendfile() and 'express/static'
- * Removed Server#running
-
-0.7.5 / 2010-03-16
-==================
-
- * Added Request#flash() support without args, now returns all flashes
- * Updated ext submodule
-
-0.7.4 / 2010-03-16
-==================
-
- * Fixed session reaper
- * Changed; class.js replacing js-oo Class implementation (quite a bit faster, no browser cruft)
-
-0.7.3 / 2010-03-16
-==================
-
- * Added package.json
- * Fixed requiring of haml / sass due to kiwi removal
-
-0.7.2 / 2010-03-16
-==================
-
- * Fixed GIT submodules (HAH!)
-
-0.7.1 / 2010-03-16
-==================
-
- * Changed; Express now using submodules again until a PM is adopted
- * Changed; chat example using millisecond conversions from ext
-
-0.7.0 / 2010-03-15
-==================
-
- * Added Request#pass() support (finds the next matching route, or the given path)
- * Added Logger plugin (default "common" format replaces CommonLogger)
- * Removed Profiler plugin
- * Removed CommonLogger plugin
-
-0.6.0 / 2010-03-11
-==================
-
- * Added seed.yml for kiwi package management support
- * Added HTTP client query string support when method is GET. Closes #205
-
- * Added support for arbitrary view engines.
- For example "foo.engine.html" will now require('engine'),
- the exports from this module are cached after the first require().
-
- * Added async plugin support
-
- * Removed usage of RESTful route funcs as http client
- get() etc, use http.get() and friends
-
- * Removed custom exceptions
-
-0.5.0 / 2010-03-10
-==================
-
- * Added ext dependency (library of js extensions)
- * Removed extname() / basename() utils. Use path module
- * Removed toArray() util. Use arguments.values
- * Removed escapeRegexp() util. Use RegExp.escape()
- * Removed process.mixin() dependency. Use utils.mixin()
- * Removed Collection
- * Removed ElementCollection
- * Shameless self promotion of ebook "Advanced JavaScript" (http://dev-mag.com) ;)
-
-0.4.0 / 2010-02-11
-==================
-
- * Added flash() example to sample upload app
- * Added high level restful http client module (express/http)
- * Changed; RESTful route functions double as HTTP clients. Closes #69
- * Changed; throwing error when routes are added at runtime
- * Changed; defaulting render() context to the current Request. Closes #197
- * Updated haml submodule
-
-0.3.0 / 2010-02-11
-==================
-
- * Updated haml / sass submodules. Closes #200
- * Added flash message support. Closes #64
- * Added accepts() now allows multiple args. fixes #117
- * Added support for plugins to halt. Closes #189
- * Added alternate layout support. Closes #119
- * Removed Route#run(). Closes #188
- * Fixed broken specs due to use(Cookie) missing
-
-0.2.1 / 2010-02-05
-==================
-
- * Added "plot" format option for Profiler (for gnuplot processing)
- * Added request number to Profiler plugin
- * Fixed binary encoding for multi-part file uploads, was previously defaulting to UTF8
- * Fixed issue with routes not firing when not files are present. Closes #184
- * Fixed process.Promise -> events.Promise
-
-0.2.0 / 2010-02-03
-==================
-
- * Added parseParam() support for name[] etc. (allows for file inputs with "multiple" attr) Closes #180
- * Added Both Cache and Session option "reapInterval" may be "reapEvery". Closes #174
- * Added expiration support to cache api with reaper. Closes #133
- * Added cache Store.Memory#reap()
- * Added Cache; cache api now uses first class Cache instances
- * Added abstract session Store. Closes #172
- * Changed; cache Memory.Store#get() utilizing Collection
- * Renamed MemoryStore -> Store.Memory
- * Fixed use() of the same plugin several time will always use latest options. Closes #176
-
-0.1.0 / 2010-02-03
-==================
-
- * Changed; Hooks (before / after) pass request as arg as well as evaluated in their context
- * Updated node support to 0.1.27 Closes #169
- * Updated dirname(__filename) -> __dirname
- * Updated libxmljs support to v0.2.0
- * Added session support with memory store / reaping
- * Added quick uid() helper
- * Added multi-part upload support
- * Added Sass.js support / submodule
- * Added production env caching view contents and static files
- * Added static file caching. Closes #136
- * Added cache plugin with memory stores
- * Added support to StaticFile so that it works with non-textual files.
- * Removed dirname() helper
- * Removed several globals (now their modules must be required)
-
-0.0.2 / 2010-01-10
-==================
-
- * Added view benchmarks; currently haml vs ejs
- * Added Request#attachment() specs. Closes #116
- * Added use of node's parseQuery() util. Closes #123
- * Added `make init` for submodules
- * Updated Haml
- * Updated sample chat app to show messages on load
- * Updated libxmljs parseString -> parseHtmlString
- * Fixed `make init` to work with older versions of git
- * Fixed specs can now run independent specs for those who cant build deps. Closes #127
- * Fixed issues introduced by the node url module changes. Closes 126.
- * Fixed two assertions failing due to Collection#keys() returning strings
- * Fixed faulty Collection#toArray() spec due to keys() returning strings
- * Fixed `make test` now builds libxmljs.node before testing
-
-0.0.1 / 2010-01-03
-==================
-
- * Initial release
diff --git a/CoAuthoring/node_modules/express/LICENSE b/CoAuthoring/node_modules/express/LICENSE
deleted file mode 100644
index 0f3c767892..0000000000
--- a/CoAuthoring/node_modules/express/LICENSE
+++ /dev/null
@@ -1,22 +0,0 @@
-(The MIT License)
-
-Copyright (c) 2009-2014 TJ Holowaychuk
-
-Permission is hereby granted, free of charge, to any person obtaining
-a copy of this software and associated documentation files (the
-'Software'), to deal in the Software without restriction, including
-without limitation the rights to use, copy, modify, merge, publish,
-distribute, sublicense, and/or sell copies of the Software, and to
-permit persons to whom the Software is furnished to do so, subject to
-the following conditions:
-
-The above copyright notice and this permission notice shall be
-included in all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
-EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
-IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
-CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
-TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
-SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
diff --git a/CoAuthoring/node_modules/express/Readme.md b/CoAuthoring/node_modules/express/Readme.md
deleted file mode 100644
index 426bb723f2..0000000000
--- a/CoAuthoring/node_modules/express/Readme.md
+++ /dev/null
@@ -1,128 +0,0 @@
-[](http://expressjs.com/)
-
- Fast, unopinionated, minimalist web framework for [node](http://nodejs.org).
-
- [](https://www.npmjs.org/package/express)
- [](https://travis-ci.org/strongloop/express)
- [](https://coveralls.io/r/strongloop/express)
- [](https://www.gittip.com/dougwilson/)
-
-```js
-var express = require('express')
-var app = express()
-
-app.get('/', function (req, res) {
- res.send('Hello World')
-})
-
-app.listen(3000)
-```
-
- **PROTIP** Be sure to read [Migrating from 3.x to 4.x](https://github.com/strongloop/express/wiki/Migrating-from-3.x-to-4.x) as well as [New features in 4.x](https://github.com/strongloop/express/wiki/New-features-in-4.x).
-
-### Installation
-
-```bash
-$ npm install express
-```
-
-## Quick Start
-
- The quickest way to get started with express is to utilize the executable [`express(1)`](https://github.com/expressjs/generator) to generate an application as shown below:
-
- Install the executable. The executable's major version will match Express's:
-
-```bash
-$ npm install -g express-generator@4
-```
-
- Create the app:
-
-```bash
-$ express /tmp/foo && cd /tmp/foo
-```
-
- Install dependencies:
-
-```bash
-$ npm install
-```
-
- Start the server:
-
-```bash
-$ npm start
-```
-
-## Features
-
- * Robust routing
- * HTTP helpers (redirection, caching, etc)
- * View system supporting 14+ template engines
- * Content negotiation
- * Focus on high performance
- * Executable for generating applications quickly
- * High test coverage
-
-## Philosophy
-
- The Express philosophy is to provide small, robust tooling for HTTP servers, making
- it a great solution for single page applications, web sites, hybrids, or public
- HTTP APIs.
-
- Express does not force you to use any specific ORM or template engine. With support for over
- 14 template engines via [Consolidate.js](https://github.com/visionmedia/consolidate.js),
- you can quickly craft your perfect framework.
-
-## More Information
-
- * [Website and Documentation](http://expressjs.com/) - [[website repo](https://github.com/strongloop/expressjs.com)]
- * [Github Organization](https://github.com/expressjs) for Official Middleware & Modules
- * [#express](https://webchat.freenode.net/?channels=express) on freenode IRC
- * Visit the [Wiki](https://github.com/strongloop/express/wiki)
- * [Google Group](https://groups.google.com/group/express-js) for discussion
- * [Русскоязычная документация](http://jsman.ru/express/)
- * [한국어 문서](http://expressjs.kr) - [[website repo](https://github.com/Hanul/expressjs.kr)]
- * Run express examples [online](https://runnable.com/express)
-
-## Viewing Examples
-
- Clone the Express repo, then install the dev dependencies to install all the example / test suite dependencies:
-
-```bash
-$ git clone git://github.com/strongloop/express.git --depth 1
-$ cd express
-$ npm install
-```
-
- Then run whichever example you want:
-
- $ node examples/content-negotiation
-
- You can also view live examples here:
-
-
-
-## Running Tests
-
- To run the test suite, first invoke the following command within the repo, installing the development dependencies:
-
-```bash
-$ npm install
-```
-
- Then run the tests:
-
-```bash
-$ npm test
-```
-
-### Contributors
-
- * Author: [TJ Holowaychuk](https://github.com/visionmedia)
- * Lead Maintainer: [Douglas Christopher Wilson](https://github.com/dougwilson)
- * [All Contributors](https://github.com/strongloop/express/graphs/contributors)
-
-### License
-
- [MIT](LICENSE)
diff --git a/CoAuthoring/node_modules/express/index.js b/CoAuthoring/node_modules/express/index.js
deleted file mode 100644
index 3da3378379..0000000000
--- a/CoAuthoring/node_modules/express/index.js
+++ /dev/null
@@ -1,2 +0,0 @@
-
-module.exports = require('./lib/express');
diff --git a/CoAuthoring/node_modules/express/lib/application.js b/CoAuthoring/node_modules/express/lib/application.js
deleted file mode 100644
index 2c7cc2de26..0000000000
--- a/CoAuthoring/node_modules/express/lib/application.js
+++ /dev/null
@@ -1,568 +0,0 @@
-/**
- * Module dependencies.
- */
-
-var finalhandler = require('finalhandler');
-var flatten = require('./utils').flatten;
-var mixin = require('utils-merge');
-var Router = require('./router');
-var methods = require('methods');
-var middleware = require('./middleware/init');
-var query = require('./middleware/query');
-var debug = require('debug')('express:application');
-var View = require('./view');
-var http = require('http');
-var compileETag = require('./utils').compileETag;
-var compileQueryParser = require('./utils').compileQueryParser;
-var compileTrust = require('./utils').compileTrust;
-var deprecate = require('depd')('express');
-var resolve = require('path').resolve;
-var slice = Array.prototype.slice;
-
-/**
- * Application prototype.
- */
-
-var app = exports = module.exports = {};
-
-/**
- * Initialize the server.
- *
- * - setup default configuration
- * - setup default middleware
- * - setup route reflection methods
- *
- * @api private
- */
-
-app.init = function(){
- this.cache = {};
- this.settings = {};
- this.engines = {};
- this.defaultConfiguration();
-};
-
-/**
- * Initialize application configuration.
- *
- * @api private
- */
-
-app.defaultConfiguration = function(){
- // default settings
- this.enable('x-powered-by');
- this.set('etag', 'weak');
- var env = process.env.NODE_ENV || 'development';
- this.set('env', env);
- this.set('query parser', 'extended');
- this.set('subdomain offset', 2);
- this.set('trust proxy', false);
-
- debug('booting in %s mode', env);
-
- // inherit protos
- this.on('mount', function(parent){
- this.request.__proto__ = parent.request;
- this.response.__proto__ = parent.response;
- this.engines.__proto__ = parent.engines;
- this.settings.__proto__ = parent.settings;
- });
-
- // setup locals
- this.locals = Object.create(null);
-
- // top-most app is mounted at /
- this.mountpath = '/';
-
- // default locals
- this.locals.settings = this.settings;
-
- // default configuration
- this.set('view', View);
- this.set('views', resolve('views'));
- this.set('jsonp callback name', 'callback');
-
- if (env === 'production') {
- this.enable('view cache');
- }
-
- Object.defineProperty(this, 'router', {
- get: function() {
- throw new Error('\'app.router\' is deprecated!\nPlease see the 3.x to 4.x migration guide for details on how to update your app.');
- }
- });
-};
-
-/**
- * lazily adds the base router if it has not yet been added.
- *
- * We cannot add the base router in the defaultConfiguration because
- * it reads app settings which might be set after that has run.
- *
- * @api private
- */
-app.lazyrouter = function() {
- if (!this._router) {
- this._router = new Router({
- caseSensitive: this.enabled('case sensitive routing'),
- strict: this.enabled('strict routing')
- });
-
- this._router.use(query(this.get('query parser fn')));
- this._router.use(middleware.init(this));
- }
-};
-
-/**
- * Dispatch a req, res pair into the application. Starts pipeline processing.
- *
- * If no _done_ callback is provided, then default error handlers will respond
- * in the event of an error bubbling through the stack.
- *
- * @api private
- */
-
-app.handle = function(req, res, done) {
- var router = this._router;
-
- // final handler
- done = done || finalhandler(req, res, {
- env: this.get('env'),
- onerror: logerror.bind(this)
- });
-
- // no routes
- if (!router) {
- debug('no routes defined on app');
- done();
- return;
- }
-
- router.handle(req, res, done);
-};
-
-/**
- * Proxy `Router#use()` to add middleware to the app router.
- * See Router#use() documentation for details.
- *
- * If the _fn_ parameter is an express app, then it will be
- * mounted at the _route_ specified.
- *
- * @api public
- */
-
-app.use = function use(fn) {
- var offset = 0;
- var path = '/';
- var self = this;
-
- // default path to '/'
- // disambiguate app.use([fn])
- if (typeof fn !== 'function') {
- var arg = fn;
-
- while (Array.isArray(arg) && arg.length !== 0) {
- arg = arg[0];
- }
-
- // first arg is the path
- if (typeof arg !== 'function') {
- offset = 1;
- path = fn;
- }
- }
-
- var fns = flatten(slice.call(arguments, offset));
-
- if (fns.length === 0) {
- throw new TypeError('app.use() requires middleware functions');
- }
-
- // setup router
- this.lazyrouter();
- var router = this._router;
-
- fns.forEach(function (fn) {
- // non-express app
- if (!fn || !fn.handle || !fn.set) {
- return router.use(path, fn);
- }
-
- debug('.use app under %s', path);
- fn.mountpath = path;
- fn.parent = self;
-
- // restore .app property on req and res
- router.use(path, function mounted_app(req, res, next) {
- var orig = req.app;
- fn.handle(req, res, function (err) {
- req.__proto__ = orig.request;
- res.__proto__ = orig.response;
- next(err);
- });
- });
-
- // mounted an app
- fn.emit('mount', self);
- });
-
- return this;
-};
-
-/**
- * Proxy to the app `Router#route()`
- * Returns a new `Route` instance for the _path_.
- *
- * Routes are isolated middleware stacks for specific paths.
- * See the Route api docs for details.
- *
- * @api public
- */
-
-app.route = function(path){
- this.lazyrouter();
- return this._router.route(path);
-};
-
-/**
- * Register the given template engine callback `fn`
- * as `ext`.
- *
- * By default will `require()` the engine based on the
- * file extension. For example if you try to render
- * a "foo.jade" file Express will invoke the following internally:
- *
- * app.engine('jade', require('jade').__express);
- *
- * For engines that do not provide `.__express` out of the box,
- * or if you wish to "map" a different extension to the template engine
- * you may use this method. For example mapping the EJS template engine to
- * ".html" files:
- *
- * app.engine('html', require('ejs').renderFile);
- *
- * In this case EJS provides a `.renderFile()` method with
- * the same signature that Express expects: `(path, options, callback)`,
- * though note that it aliases this method as `ejs.__express` internally
- * so if you're using ".ejs" extensions you dont need to do anything.
- *
- * Some template engines do not follow this convention, the
- * [Consolidate.js](https://github.com/visionmedia/consolidate.js)
- * library was created to map all of node's popular template
- * engines to follow this convention, thus allowing them to
- * work seamlessly within Express.
- *
- * @param {String} ext
- * @param {Function} fn
- * @return {app} for chaining
- * @api public
- */
-
-app.engine = function(ext, fn){
- if ('function' != typeof fn) throw new Error('callback function required');
- if ('.' != ext[0]) ext = '.' + ext;
- this.engines[ext] = fn;
- return this;
-};
-
-/**
- * Proxy to `Router#param()` with one added api feature. The _name_ parameter
- * can be an array of names.
- *
- * See the Router#param() docs for more details.
- *
- * @param {String|Array} name
- * @param {Function} fn
- * @return {app} for chaining
- * @api public
- */
-
-app.param = function(name, fn){
- var self = this;
- self.lazyrouter();
-
- if (Array.isArray(name)) {
- name.forEach(function(key) {
- self.param(key, fn);
- });
- return this;
- }
-
- self._router.param(name, fn);
- return this;
-};
-
-/**
- * Assign `setting` to `val`, or return `setting`'s value.
- *
- * app.set('foo', 'bar');
- * app.get('foo');
- * // => "bar"
- *
- * Mounted servers inherit their parent server's settings.
- *
- * @param {String} setting
- * @param {*} [val]
- * @return {Server} for chaining
- * @api public
- */
-
-app.set = function(setting, val){
- if (arguments.length === 1) {
- // app.get(setting)
- return this.settings[setting];
- }
-
- // set value
- this.settings[setting] = val;
-
- // trigger matched settings
- switch (setting) {
- case 'etag':
- debug('compile etag %s', val);
- this.set('etag fn', compileETag(val));
- break;
- case 'query parser':
- debug('compile query parser %s', val);
- this.set('query parser fn', compileQueryParser(val));
- break;
- case 'trust proxy':
- debug('compile trust proxy %s', val);
- this.set('trust proxy fn', compileTrust(val));
- break;
- }
-
- return this;
-};
-
-/**
- * Return the app's absolute pathname
- * based on the parent(s) that have
- * mounted it.
- *
- * For example if the application was
- * mounted as "/admin", which itself
- * was mounted as "/blog" then the
- * return value would be "/blog/admin".
- *
- * @return {String}
- * @api private
- */
-
-app.path = function(){
- return this.parent
- ? this.parent.path() + this.mountpath
- : '';
-};
-
-/**
- * Check if `setting` is enabled (truthy).
- *
- * app.enabled('foo')
- * // => false
- *
- * app.enable('foo')
- * app.enabled('foo')
- * // => true
- *
- * @param {String} setting
- * @return {Boolean}
- * @api public
- */
-
-app.enabled = function(setting){
- return !!this.set(setting);
-};
-
-/**
- * Check if `setting` is disabled.
- *
- * app.disabled('foo')
- * // => true
- *
- * app.enable('foo')
- * app.disabled('foo')
- * // => false
- *
- * @param {String} setting
- * @return {Boolean}
- * @api public
- */
-
-app.disabled = function(setting){
- return !this.set(setting);
-};
-
-/**
- * Enable `setting`.
- *
- * @param {String} setting
- * @return {app} for chaining
- * @api public
- */
-
-app.enable = function(setting){
- return this.set(setting, true);
-};
-
-/**
- * Disable `setting`.
- *
- * @param {String} setting
- * @return {app} for chaining
- * @api public
- */
-
-app.disable = function(setting){
- return this.set(setting, false);
-};
-
-/**
- * Delegate `.VERB(...)` calls to `router.VERB(...)`.
- */
-
-methods.forEach(function(method){
- app[method] = function(path){
- if ('get' == method && 1 == arguments.length) return this.set(path);
-
- this.lazyrouter();
-
- var route = this._router.route(path);
- route[method].apply(route, slice.call(arguments, 1));
- return this;
- };
-});
-
-/**
- * Special-cased "all" method, applying the given route `path`,
- * middleware, and callback to _every_ HTTP method.
- *
- * @param {String} path
- * @param {Function} ...
- * @return {app} for chaining
- * @api public
- */
-
-app.all = function(path){
- this.lazyrouter();
-
- var route = this._router.route(path);
- var args = slice.call(arguments, 1);
- methods.forEach(function(method){
- route[method].apply(route, args);
- });
-
- return this;
-};
-
-// del -> delete alias
-
-app.del = deprecate.function(app.delete, 'app.del: Use app.delete instead');
-
-/**
- * Render the given view `name` name with `options`
- * and a callback accepting an error and the
- * rendered template string.
- *
- * Example:
- *
- * app.render('email', { name: 'Tobi' }, function(err, html){
- * // ...
- * })
- *
- * @param {String} name
- * @param {String|Function} options or fn
- * @param {Function} fn
- * @api public
- */
-
-app.render = function(name, options, fn){
- var opts = {};
- var cache = this.cache;
- var engines = this.engines;
- var view;
-
- // support callback function as second arg
- if ('function' == typeof options) {
- fn = options, options = {};
- }
-
- // merge app.locals
- mixin(opts, this.locals);
-
- // merge options._locals
- if (options._locals) mixin(opts, options._locals);
-
- // merge options
- mixin(opts, options);
-
- // set .cache unless explicitly provided
- opts.cache = null == opts.cache
- ? this.enabled('view cache')
- : opts.cache;
-
- // primed cache
- if (opts.cache) view = cache[name];
-
- // view
- if (!view) {
- view = new (this.get('view'))(name, {
- defaultEngine: this.get('view engine'),
- root: this.get('views'),
- engines: engines
- });
-
- if (!view.path) {
- var err = new Error('Failed to lookup view "' + name + '" in views directory "' + view.root + '"');
- err.view = view;
- return fn(err);
- }
-
- // prime the cache
- if (opts.cache) cache[name] = view;
- }
-
- // render
- try {
- view.render(opts, fn);
- } catch (err) {
- fn(err);
- }
-};
-
-/**
- * Listen for connections.
- *
- * A node `http.Server` is returned, with this
- * application (which is a `Function`) as its
- * callback. If you wish to create both an HTTP
- * and HTTPS server you may do so with the "http"
- * and "https" modules as shown here:
- *
- * var http = require('http')
- * , https = require('https')
- * , express = require('express')
- * , app = express();
- *
- * http.createServer(app).listen(80);
- * https.createServer({ ... }, app).listen(443);
- *
- * @return {http.Server}
- * @api public
- */
-
-app.listen = function(){
- var server = http.createServer(this);
- return server.listen.apply(server, arguments);
-};
-
-/**
-* Log error using console.error.
-*
-* @param {Error} err
-* @api public
-*/
-
-function logerror(err){
- if (this.get('env') !== 'test') console.error(err.stack || err.toString());
-}
diff --git a/CoAuthoring/node_modules/express/lib/express.js b/CoAuthoring/node_modules/express/lib/express.js
deleted file mode 100644
index 7be6832fb6..0000000000
--- a/CoAuthoring/node_modules/express/lib/express.js
+++ /dev/null
@@ -1,93 +0,0 @@
-/**
- * Module dependencies.
- */
-
-var EventEmitter = require('events').EventEmitter;
-var mixin = require('utils-merge');
-var proto = require('./application');
-var Route = require('./router/route');
-var Router = require('./router');
-var req = require('./request');
-var res = require('./response');
-
-/**
- * Expose `createApplication()`.
- */
-
-exports = module.exports = createApplication;
-
-/**
- * Create an express application.
- *
- * @return {Function}
- * @api public
- */
-
-function createApplication() {
- var app = function(req, res, next) {
- app.handle(req, res, next);
- };
-
- mixin(app, proto);
- mixin(app, EventEmitter.prototype);
-
- app.request = { __proto__: req, app: app };
- app.response = { __proto__: res, app: app };
- app.init();
- return app;
-}
-
-/**
- * Expose the prototypes.
- */
-
-exports.application = proto;
-exports.request = req;
-exports.response = res;
-
-/**
- * Expose constructors.
- */
-
-exports.Route = Route;
-exports.Router = Router;
-
-/**
- * Expose middleware
- */
-
-exports.query = require('./middleware/query');
-exports.static = require('serve-static');
-
-/**
- * Replace removed middleware with an appropriate error message.
- */
-
-[
- 'json',
- 'urlencoded',
- 'bodyParser',
- 'compress',
- 'cookieSession',
- 'session',
- 'logger',
- 'cookieParser',
- 'favicon',
- 'responseTime',
- 'errorHandler',
- 'timeout',
- 'methodOverride',
- 'vhost',
- 'csrf',
- 'directory',
- 'limit',
- 'multipart',
- 'staticCache',
-].forEach(function (name) {
- Object.defineProperty(exports, name, {
- get: function () {
- throw new Error('Most middleware (like ' + name + ') is no longer bundled with Express and must be installed separately. Please see https://github.com/senchalabs/connect#middleware.');
- },
- configurable: true
- });
-});
diff --git a/CoAuthoring/node_modules/express/lib/middleware/init.js b/CoAuthoring/node_modules/express/lib/middleware/init.js
deleted file mode 100644
index c09cf0c69c..0000000000
--- a/CoAuthoring/node_modules/express/lib/middleware/init.js
+++ /dev/null
@@ -1,26 +0,0 @@
-/**
- * Initialization middleware, exposing the
- * request and response to eachother, as well
- * as defaulting the X-Powered-By header field.
- *
- * @param {Function} app
- * @return {Function}
- * @api private
- */
-
-exports.init = function(app){
- return function expressInit(req, res, next){
- if (app.enabled('x-powered-by')) res.setHeader('X-Powered-By', 'Express');
- req.res = res;
- res.req = req;
- req.next = next;
-
- req.__proto__ = app.request;
- res.__proto__ = app.response;
-
- res.locals = res.locals || Object.create(null);
-
- next();
- };
-};
-
diff --git a/CoAuthoring/node_modules/express/lib/middleware/query.js b/CoAuthoring/node_modules/express/lib/middleware/query.js
deleted file mode 100644
index 092bbd9985..0000000000
--- a/CoAuthoring/node_modules/express/lib/middleware/query.js
+++ /dev/null
@@ -1,30 +0,0 @@
-/**
- * Module dependencies.
- */
-
-var parseUrl = require('parseurl');
-var qs = require('qs');
-
-/**
- * @param {Object} options
- * @return {Function}
- * @api public
- */
-
-module.exports = function query(options) {
- var queryparse = qs.parse;
-
- if (typeof options === 'function') {
- queryparse = options;
- options = undefined;
- }
-
- return function query(req, res, next){
- if (!req.query) {
- var val = parseUrl(req).query;
- req.query = queryparse(val, options);
- }
-
- next();
- };
-};
diff --git a/CoAuthoring/node_modules/express/lib/request.js b/CoAuthoring/node_modules/express/lib/request.js
deleted file mode 100644
index 483ee1c149..0000000000
--- a/CoAuthoring/node_modules/express/lib/request.js
+++ /dev/null
@@ -1,460 +0,0 @@
-/**
- * Module dependencies.
- */
-
-var accepts = require('accepts');
-var deprecate = require('depd')('express');
-var isIP = require('net').isIP;
-var typeis = require('type-is');
-var http = require('http');
-var fresh = require('fresh');
-var parseRange = require('range-parser');
-var parse = require('parseurl');
-var proxyaddr = require('proxy-addr');
-
-/**
- * Request prototype.
- */
-
-var req = exports = module.exports = {
- __proto__: http.IncomingMessage.prototype
-};
-
-/**
- * Return request header.
- *
- * The `Referrer` header field is special-cased,
- * both `Referrer` and `Referer` are interchangeable.
- *
- * Examples:
- *
- * req.get('Content-Type');
- * // => "text/plain"
- *
- * req.get('content-type');
- * // => "text/plain"
- *
- * req.get('Something');
- * // => undefined
- *
- * Aliased as `req.header()`.
- *
- * @param {String} name
- * @return {String}
- * @api public
- */
-
-req.get =
-req.header = function(name){
- switch (name = name.toLowerCase()) {
- case 'referer':
- case 'referrer':
- return this.headers.referrer
- || this.headers.referer;
- default:
- return this.headers[name];
- }
-};
-
-/**
- * To do: update docs.
- *
- * Check if the given `type(s)` is acceptable, returning
- * the best match when true, otherwise `undefined`, in which
- * case you should respond with 406 "Not Acceptable".
- *
- * The `type` value may be a single mime type string
- * such as "application/json", the extension name
- * such as "json", a comma-delimted list such as "json, html, text/plain",
- * an argument list such as `"json", "html", "text/plain"`,
- * or an array `["json", "html", "text/plain"]`. When a list
- * or array is given the _best_ match, if any is returned.
- *
- * Examples:
- *
- * // Accept: text/html
- * req.accepts('html');
- * // => "html"
- *
- * // Accept: text/*, application/json
- * req.accepts('html');
- * // => "html"
- * req.accepts('text/html');
- * // => "text/html"
- * req.accepts('json, text');
- * // => "json"
- * req.accepts('application/json');
- * // => "application/json"
- *
- * // Accept: text/*, application/json
- * req.accepts('image/png');
- * req.accepts('png');
- * // => undefined
- *
- * // Accept: text/*;q=.5, application/json
- * req.accepts(['html', 'json']);
- * req.accepts('html', 'json');
- * req.accepts('html, json');
- * // => "json"
- *
- * @param {String|Array} type(s)
- * @return {String}
- * @api public
- */
-
-req.accepts = function(){
- var accept = accepts(this);
- return accept.types.apply(accept, arguments);
-};
-
-/**
- * Check if the given `encoding`s are accepted.
- *
- * @param {String} ...encoding
- * @return {Boolean}
- * @api public
- */
-
-req.acceptsEncodings = function(){
- var accept = accepts(this);
- return accept.encodings.apply(accept, arguments);
-};
-
-req.acceptsEncoding = deprecate.function(req.acceptsEncodings,
- 'req.acceptsEncoding: Use acceptsEncodings instead');
-
-/**
- * Check if the given `charset`s are acceptable,
- * otherwise you should respond with 406 "Not Acceptable".
- *
- * @param {String} ...charset
- * @return {Boolean}
- * @api public
- */
-
-req.acceptsCharsets = function(){
- var accept = accepts(this);
- return accept.charsets.apply(accept, arguments);
-};
-
-req.acceptsCharset = deprecate.function(req.acceptsCharsets,
- 'req.acceptsCharset: Use acceptsCharsets instead');
-
-/**
- * Check if the given `lang`s are acceptable,
- * otherwise you should respond with 406 "Not Acceptable".
- *
- * @param {String} ...lang
- * @return {Boolean}
- * @api public
- */
-
-req.acceptsLanguages = function(){
- var accept = accepts(this);
- return accept.languages.apply(accept, arguments);
-};
-
-req.acceptsLanguage = deprecate.function(req.acceptsLanguages,
- 'req.acceptsLanguage: Use acceptsLanguages instead');
-
-/**
- * Parse Range header field,
- * capping to the given `size`.
- *
- * Unspecified ranges such as "0-" require
- * knowledge of your resource length. In
- * the case of a byte range this is of course
- * the total number of bytes. If the Range
- * header field is not given `null` is returned,
- * `-1` when unsatisfiable, `-2` when syntactically invalid.
- *
- * NOTE: remember that ranges are inclusive, so
- * for example "Range: users=0-3" should respond
- * with 4 users when available, not 3.
- *
- * @param {Number} size
- * @return {Array}
- * @api public
- */
-
-req.range = function(size){
- var range = this.get('Range');
- if (!range) return;
- return parseRange(size, range);
-};
-
-/**
- * Return the value of param `name` when present or `defaultValue`.
- *
- * - Checks route placeholders, ex: _/user/:id_
- * - Checks body params, ex: id=12, {"id":12}
- * - Checks query string params, ex: ?id=12
- *
- * To utilize request bodies, `req.body`
- * should be an object. This can be done by using
- * the `bodyParser()` middleware.
- *
- * @param {String} name
- * @param {Mixed} [defaultValue]
- * @return {String}
- * @api public
- */
-
-req.param = function(name, defaultValue){
- var params = this.params || {};
- var body = this.body || {};
- var query = this.query || {};
- if (null != params[name] && params.hasOwnProperty(name)) return params[name];
- if (null != body[name]) return body[name];
- if (null != query[name]) return query[name];
- return defaultValue;
-};
-
-/**
- * Check if the incoming request contains the "Content-Type"
- * header field, and it contains the give mime `type`.
- *
- * Examples:
- *
- * // With Content-Type: text/html; charset=utf-8
- * req.is('html');
- * req.is('text/html');
- * req.is('text/*');
- * // => true
- *
- * // When Content-Type is application/json
- * req.is('json');
- * req.is('application/json');
- * req.is('application/*');
- * // => true
- *
- * req.is('html');
- * // => false
- *
- * @param {String} type
- * @return {Boolean}
- * @api public
- */
-
-req.is = function(types){
- if (!Array.isArray(types)) types = [].slice.call(arguments);
- return typeis(this, types);
-};
-
-/**
- * Return the protocol string "http" or "https"
- * when requested with TLS. When the "trust proxy"
- * setting trusts the socket address, the
- * "X-Forwarded-Proto" header field will be trusted
- * and used if present.
- *
- * If you're running behind a reverse proxy that
- * supplies https for you this may be enabled.
- *
- * @return {String}
- * @api public
- */
-
-defineGetter(req, 'protocol', function protocol(){
- var proto = this.connection.encrypted
- ? 'https'
- : 'http';
- var trust = this.app.get('trust proxy fn');
-
- if (!trust(this.connection.remoteAddress)) {
- return proto;
- }
-
- // Note: X-Forwarded-Proto is normally only ever a
- // single value, but this is to be safe.
- proto = this.get('X-Forwarded-Proto') || proto;
- return proto.split(/\s*,\s*/)[0];
-});
-
-/**
- * Short-hand for:
- *
- * req.protocol == 'https'
- *
- * @return {Boolean}
- * @api public
- */
-
-defineGetter(req, 'secure', function secure(){
- return 'https' == this.protocol;
-});
-
-/**
- * Return the remote address from the trusted proxy.
- *
- * The is the remote address on the socket unless
- * "trust proxy" is set.
- *
- * @return {String}
- * @api public
- */
-
-defineGetter(req, 'ip', function ip(){
- var trust = this.app.get('trust proxy fn');
- return proxyaddr(this, trust);
-});
-
-/**
- * When "trust proxy" is set, trusted proxy addresses + client.
- *
- * For example if the value were "client, proxy1, proxy2"
- * you would receive the array `["client", "proxy1", "proxy2"]`
- * where "proxy2" is the furthest down-stream and "proxy1" and
- * "proxy2" were trusted.
- *
- * @return {Array}
- * @api public
- */
-
-defineGetter(req, 'ips', function ips() {
- var trust = this.app.get('trust proxy fn');
- var addrs = proxyaddr.all(this, trust);
- return addrs.slice(1).reverse();
-});
-
-/**
- * Return subdomains as an array.
- *
- * Subdomains are the dot-separated parts of the host before the main domain of
- * the app. By default, the domain of the app is assumed to be the last two
- * parts of the host. This can be changed by setting "subdomain offset".
- *
- * For example, if the domain is "tobi.ferrets.example.com":
- * If "subdomain offset" is not set, req.subdomains is `["ferrets", "tobi"]`.
- * If "subdomain offset" is 3, req.subdomains is `["tobi"]`.
- *
- * @return {Array}
- * @api public
- */
-
-defineGetter(req, 'subdomains', function subdomains() {
- var hostname = this.hostname;
-
- if (!hostname) return [];
-
- var offset = this.app.get('subdomain offset');
- var subdomains = !isIP(hostname)
- ? hostname.split('.').reverse()
- : [hostname];
-
- return subdomains.slice(offset);
-});
-
-/**
- * Short-hand for `url.parse(req.url).pathname`.
- *
- * @return {String}
- * @api public
- */
-
-defineGetter(req, 'path', function path() {
- return parse(this).pathname;
-});
-
-/**
- * Parse the "Host" header field to a hostname.
- *
- * When the "trust proxy" setting trusts the socket
- * address, the "X-Forwarded-Host" header field will
- * be trusted.
- *
- * @return {String}
- * @api public
- */
-
-defineGetter(req, 'hostname', function hostname(){
- var trust = this.app.get('trust proxy fn');
- var host = this.get('X-Forwarded-Host');
-
- if (!host || !trust(this.connection.remoteAddress)) {
- host = this.get('Host');
- }
-
- if (!host) return;
-
- // IPv6 literal support
- var offset = host[0] === '['
- ? host.indexOf(']') + 1
- : 0;
- var index = host.indexOf(':', offset);
-
- return ~index
- ? host.substring(0, index)
- : host;
-});
-
-// TODO: change req.host to return host in next major
-
-defineGetter(req, 'host', deprecate.function(function host(){
- return this.hostname;
-}, 'req.host: Use req.hostname instead'));
-
-/**
- * Check if the request is fresh, aka
- * Last-Modified and/or the ETag
- * still match.
- *
- * @return {Boolean}
- * @api public
- */
-
-defineGetter(req, 'fresh', function(){
- var method = this.method;
- var s = this.res.statusCode;
-
- // GET or HEAD for weak freshness validation only
- if ('GET' != method && 'HEAD' != method) return false;
-
- // 2xx or 304 as per rfc2616 14.26
- if ((s >= 200 && s < 300) || 304 == s) {
- return fresh(this.headers, this.res._headers);
- }
-
- return false;
-});
-
-/**
- * Check if the request is stale, aka
- * "Last-Modified" and / or the "ETag" for the
- * resource has changed.
- *
- * @return {Boolean}
- * @api public
- */
-
-defineGetter(req, 'stale', function stale(){
- return !this.fresh;
-});
-
-/**
- * Check if the request was an _XMLHttpRequest_.
- *
- * @return {Boolean}
- * @api public
- */
-
-defineGetter(req, 'xhr', function xhr(){
- var val = this.get('X-Requested-With') || '';
- return 'xmlhttprequest' == val.toLowerCase();
-});
-
-/**
- * Helper function for creating a getter on an object.
- *
- * @param {Object} obj
- * @param {String} name
- * @param {Function} getter
- * @api private
- */
-function defineGetter(obj, name, getter) {
- Object.defineProperty(obj, name, {
- configurable: true,
- enumerable: true,
- get: getter
- });
-};
diff --git a/CoAuthoring/node_modules/express/lib/response.js b/CoAuthoring/node_modules/express/lib/response.js
deleted file mode 100644
index c26f68ac8a..0000000000
--- a/CoAuthoring/node_modules/express/lib/response.js
+++ /dev/null
@@ -1,967 +0,0 @@
-/**
- * Module dependencies.
- */
-
-var deprecate = require('depd')('express');
-var escapeHtml = require('escape-html');
-var http = require('http');
-var isAbsolute = require('./utils').isAbsolute;
-var onFinished = require('on-finished');
-var path = require('path');
-var mixin = require('utils-merge');
-var sign = require('cookie-signature').sign;
-var normalizeType = require('./utils').normalizeType;
-var normalizeTypes = require('./utils').normalizeTypes;
-var setCharset = require('./utils').setCharset;
-var contentDisposition = require('./utils').contentDisposition;
-var statusCodes = http.STATUS_CODES;
-var cookie = require('cookie');
-var send = require('send');
-var extname = path.extname;
-var mime = send.mime;
-var resolve = path.resolve;
-var vary = require('vary');
-
-/**
- * Response prototype.
- */
-
-var res = module.exports = {
- __proto__: http.ServerResponse.prototype
-};
-
-/**
- * Set status `code`.
- *
- * @param {Number} code
- * @return {ServerResponse}
- * @api public
- */
-
-res.status = function(code){
- this.statusCode = code;
- return this;
-};
-
-/**
- * Set Link header field with the given `links`.
- *
- * Examples:
- *
- * res.links({
- * next: 'http://api.example.com/users?page=2',
- * last: 'http://api.example.com/users?page=5'
- * });
- *
- * @param {Object} links
- * @return {ServerResponse}
- * @api public
- */
-
-res.links = function(links){
- var link = this.get('Link') || '';
- if (link) link += ', ';
- return this.set('Link', link + Object.keys(links).map(function(rel){
- return '<' + links[rel] + '>; rel="' + rel + '"';
- }).join(', '));
-};
-
-/**
- * Send a response.
- *
- * Examples:
- *
- * res.send(new Buffer('wahoo'));
- * res.send({ some: 'json' });
- * res.send('some html
');
- *
- * @param {string|number|boolean|object|Buffer} body
- * @api public
- */
-
-res.send = function send(body) {
- var chunk = body;
- var encoding;
- var len;
- var req = this.req;
- var type;
-
- // settings
- var app = this.app;
-
- // allow status / body
- if (arguments.length === 2) {
- // res.send(body, status) backwards compat
- if (typeof arguments[0] !== 'number' && typeof arguments[1] === 'number') {
- deprecate('res.send(body, status): Use res.status(status).send(body) instead');
- this.statusCode = arguments[1];
- } else {
- deprecate('res.send(status, body): Use res.status(status).send(body) instead');
- this.statusCode = arguments[0];
- chunk = arguments[1];
- }
- }
-
- // disambiguate res.send(status) and res.send(status, num)
- if (typeof chunk === 'number' && arguments.length === 1) {
- // res.send(status) will set status message as text string
- if (!this.get('Content-Type')) {
- this.type('txt');
- }
-
- deprecate('res.send(status): Use res.status(status).end() instead');
- this.statusCode = chunk;
- chunk = http.STATUS_CODES[chunk];
- }
-
- switch (typeof chunk) {
- // string defaulting to html
- case 'string':
- if (!this.get('Content-Type')) {
- this.type('html');
- }
- break;
- case 'boolean':
- case 'number':
- case 'object':
- if (chunk === null) {
- chunk = '';
- } else if (Buffer.isBuffer(chunk)) {
- if (!this.get('Content-Type')) {
- this.type('bin');
- }
- } else {
- return this.json(chunk);
- }
- break;
- }
-
- // write strings in utf-8
- if (typeof chunk === 'string') {
- encoding = 'utf8';
- type = this.get('Content-Type');
-
- // reflect this in content-type
- if (typeof type === 'string') {
- this.set('Content-Type', setCharset(type, 'utf-8'));
- }
- }
-
- // populate Content-Length
- if (chunk !== undefined) {
- if (!Buffer.isBuffer(chunk)) {
- // convert chunk to Buffer; saves later double conversions
- chunk = new Buffer(chunk, encoding);
- encoding = undefined;
- }
-
- len = chunk.length;
- this.set('Content-Length', len);
- }
-
- // method check
- var isHead = req.method === 'HEAD';
-
- // ETag support
- if (len !== undefined && (isHead || req.method === 'GET')) {
- var etag = app.get('etag fn');
- if (etag && !this.get('ETag')) {
- etag = etag(chunk, encoding);
- etag && this.set('ETag', etag);
- }
- }
-
- // freshness
- if (req.fresh) this.statusCode = 304;
-
- // strip irrelevant headers
- if (204 == this.statusCode || 304 == this.statusCode) {
- this.removeHeader('Content-Type');
- this.removeHeader('Content-Length');
- this.removeHeader('Transfer-Encoding');
- chunk = '';
- }
-
- // skip body for HEAD
- if (isHead) {
- this.end();
- }
-
- // respond
- this.end(chunk, encoding);
-
- return this;
-};
-
-/**
- * Send JSON response.
- *
- * Examples:
- *
- * res.json(null);
- * res.json({ user: 'tj' });
- *
- * @param {string|number|boolean|object} obj
- * @api public
- */
-
-res.json = function json(obj) {
- var val = obj;
-
- // allow status / body
- if (arguments.length === 2) {
- // res.json(body, status) backwards compat
- if (typeof arguments[1] === 'number') {
- deprecate('res.json(obj, status): Use res.status(status).json(obj) instead');
- this.statusCode = arguments[1];
- } else {
- deprecate('res.json(status, obj): Use res.status(status).json(obj) instead');
- this.statusCode = arguments[0];
- val = arguments[1];
- }
- }
-
- // settings
- var app = this.app;
- var replacer = app.get('json replacer');
- var spaces = app.get('json spaces');
- var body = JSON.stringify(val, replacer, spaces);
-
- // content-type
- if (!this.get('Content-Type')) {
- this.set('Content-Type', 'application/json');
- }
-
- return this.send(body);
-};
-
-/**
- * Send JSON response with JSONP callback support.
- *
- * Examples:
- *
- * res.jsonp(null);
- * res.jsonp({ user: 'tj' });
- *
- * @param {string|number|boolean|object} obj
- * @api public
- */
-
-res.jsonp = function jsonp(obj) {
- var val = obj;
-
- // allow status / body
- if (arguments.length === 2) {
- // res.json(body, status) backwards compat
- if (typeof arguments[1] === 'number') {
- deprecate('res.jsonp(obj, status): Use res.status(status).json(obj) instead');
- this.statusCode = arguments[1];
- } else {
- deprecate('res.jsonp(status, obj): Use res.status(status).jsonp(obj) instead');
- this.statusCode = arguments[0];
- val = arguments[1];
- }
- }
-
- // settings
- var app = this.app;
- var replacer = app.get('json replacer');
- var spaces = app.get('json spaces');
- var body = JSON.stringify(val, replacer, spaces);
- var callback = this.req.query[app.get('jsonp callback name')];
-
- // content-type
- if (!this.get('Content-Type')) {
- this.set('X-Content-Type-Options', 'nosniff');
- this.set('Content-Type', 'application/json');
- }
-
- // fixup callback
- if (Array.isArray(callback)) {
- callback = callback[0];
- }
-
- // jsonp
- if (typeof callback === 'string' && callback.length !== 0) {
- this.charset = 'utf-8';
- this.set('X-Content-Type-Options', 'nosniff');
- this.set('Content-Type', 'text/javascript');
-
- // restrict callback charset
- callback = callback.replace(/[^\[\]\w$.]/g, '');
-
- // replace chars not allowed in JavaScript that are in JSON
- body = body
- .replace(/\u2028/g, '\\u2028')
- .replace(/\u2029/g, '\\u2029');
-
- // the /**/ is a specific security mitigation for "Rosetta Flash JSONP abuse"
- // the typeof check is just to reduce client error noise
- body = '/**/ typeof ' + callback + ' === \'function\' && ' + callback + '(' + body + ');';
- }
-
- return this.send(body);
-};
-
-/**
- * Send given HTTP status code.
- *
- * Sets the response status to `statusCode` and the body of the
- * response to the standard description from node's http.STATUS_CODES
- * or the statusCode number if no description.
- *
- * Examples:
- *
- * res.sendStatus(200);
- *
- * @param {number} statusCode
- * @api public
- */
-
-res.sendStatus = function sendStatus(statusCode) {
- var body = http.STATUS_CODES[statusCode] || String(statusCode);
-
- this.statusCode = statusCode;
- this.type('txt');
-
- return this.send(body);
-};
-
-/**
- * Transfer the file at the given `path`.
- *
- * Automatically sets the _Content-Type_ response header field.
- * The callback `fn(err)` is invoked when the transfer is complete
- * or when an error occurs. Be sure to check `res.sentHeader`
- * if you wish to attempt responding, as the header and some data
- * may have already been transferred.
- *
- * Options:
- *
- * - `maxAge` defaulting to 0 (can be string converted by `ms`)
- * - `root` root directory for relative filenames
- * - `headers` object of headers to serve with file
- * - `dotfiles` serve dotfiles, defaulting to false; can be `"allow"` to send them
- *
- * Other options are passed along to `send`.
- *
- * Examples:
- *
- * The following example illustrates how `res.sendFile()` may
- * be used as an alternative for the `static()` middleware for
- * dynamic situations. The code backing `res.sendFile()` is actually
- * the same code, so HTTP cache support etc is identical.
- *
- * app.get('/user/:uid/photos/:file', function(req, res){
- * var uid = req.params.uid
- * , file = req.params.file;
- *
- * req.user.mayViewFilesFrom(uid, function(yes){
- * if (yes) {
- * res.sendFile('/uploads/' + uid + '/' + file);
- * } else {
- * res.send(403, 'Sorry! you cant see that.');
- * }
- * });
- * });
- *
- * @api public
- */
-
-res.sendFile = function sendFile(path, options, fn) {
- var req = this.req;
- var res = this;
- var next = req.next;
-
- if (!path) {
- throw new TypeError('path argument is required to res.sendFile');
- }
-
- // support function as second arg
- if (typeof options === 'function') {
- fn = options;
- options = {};
- }
-
- options = options || {};
-
- if (!options.root && !isAbsolute(path)) {
- throw new TypeError('path must be absolute or specify root to res.sendFile');
- }
-
- // create file stream
- var pathname = encodeURI(path);
- var file = send(req, pathname, options);
-
- // transfer
- sendfile(res, file, options, function (err) {
- if (fn) return fn(err);
- if (err && err.code === 'EISDIR') return next();
-
- // next() all but aborted errors
- if (err && err.code !== 'ECONNABORT') {
- next(err);
- }
- });
-};
-
-/**
- * Transfer the file at the given `path`.
- *
- * Automatically sets the _Content-Type_ response header field.
- * The callback `fn(err)` is invoked when the transfer is complete
- * or when an error occurs. Be sure to check `res.sentHeader`
- * if you wish to attempt responding, as the header and some data
- * may have already been transferred.
- *
- * Options:
- *
- * - `maxAge` defaulting to 0 (can be string converted by `ms`)
- * - `root` root directory for relative filenames
- * - `headers` object of headers to serve with file
- * - `dotfiles` serve dotfiles, defaulting to false; can be `"allow"` to send them
- *
- * Other options are passed along to `send`.
- *
- * Examples:
- *
- * The following example illustrates how `res.sendfile()` may
- * be used as an alternative for the `static()` middleware for
- * dynamic situations. The code backing `res.sendfile()` is actually
- * the same code, so HTTP cache support etc is identical.
- *
- * app.get('/user/:uid/photos/:file', function(req, res){
- * var uid = req.params.uid
- * , file = req.params.file;
- *
- * req.user.mayViewFilesFrom(uid, function(yes){
- * if (yes) {
- * res.sendfile('/uploads/' + uid + '/' + file);
- * } else {
- * res.send(403, 'Sorry! you cant see that.');
- * }
- * });
- * });
- *
- * @api public
- */
-
-res.sendfile = function(path, options, fn){
- var req = this.req;
- var res = this;
- var next = req.next;
-
- // support function as second arg
- if (typeof options === 'function') {
- fn = options;
- options = {};
- }
-
- options = options || {};
-
- // create file stream
- var file = send(req, path, options);
-
- // transfer
- sendfile(res, file, options, function (err) {
- if (fn) return fn(err);
- if (err && err.code === 'EISDIR') return next();
-
- // next() all but aborted errors
- if (err && err.code !== 'ECONNABORT') {
- next(err);
- }
- });
-};
-
-res.sendfile = deprecate.function(res.sendfile,
- 'res.sendfile: Use res.sendFile instead');
-
-/**
- * Transfer the file at the given `path` as an attachment.
- *
- * Optionally providing an alternate attachment `filename`,
- * and optional callback `fn(err)`. The callback is invoked
- * when the data transfer is complete, or when an error has
- * ocurred. Be sure to check `res.headersSent` if you plan to respond.
- *
- * This method uses `res.sendfile()`.
- *
- * @api public
- */
-
-res.download = function download(path, filename, fn) {
- // support function as second arg
- if (typeof filename === 'function') {
- fn = filename;
- filename = null;
- }
-
- filename = filename || path;
-
- // set Content-Disposition when file is sent
- var headers = {
- 'Content-Disposition': contentDisposition(filename)
- };
-
- // Resolve the full path for sendFile
- var fullPath = resolve(path);
-
- return this.sendFile(fullPath, { headers: headers }, fn);
-};
-
-/**
- * Set _Content-Type_ response header with `type` through `mime.lookup()`
- * when it does not contain "/", or set the Content-Type to `type` otherwise.
- *
- * Examples:
- *
- * res.type('.html');
- * res.type('html');
- * res.type('json');
- * res.type('application/json');
- * res.type('png');
- *
- * @param {String} type
- * @return {ServerResponse} for chaining
- * @api public
- */
-
-res.contentType =
-res.type = function(type){
- return this.set('Content-Type', ~type.indexOf('/')
- ? type
- : mime.lookup(type));
-};
-
-/**
- * Respond to the Acceptable formats using an `obj`
- * of mime-type callbacks.
- *
- * This method uses `req.accepted`, an array of
- * acceptable types ordered by their quality values.
- * When "Accept" is not present the _first_ callback
- * is invoked, otherwise the first match is used. When
- * no match is performed the server responds with
- * 406 "Not Acceptable".
- *
- * Content-Type is set for you, however if you choose
- * you may alter this within the callback using `res.type()`
- * or `res.set('Content-Type', ...)`.
- *
- * res.format({
- * 'text/plain': function(){
- * res.send('hey');
- * },
- *
- * 'text/html': function(){
- * res.send('hey
');
- * },
- *
- * 'appliation/json': function(){
- * res.send({ message: 'hey' });
- * }
- * });
- *
- * In addition to canonicalized MIME types you may
- * also use extnames mapped to these types:
- *
- * res.format({
- * text: function(){
- * res.send('hey');
- * },
- *
- * html: function(){
- * res.send('hey
');
- * },
- *
- * json: function(){
- * res.send({ message: 'hey' });
- * }
- * });
- *
- * By default Express passes an `Error`
- * with a `.status` of 406 to `next(err)`
- * if a match is not made. If you provide
- * a `.default` callback it will be invoked
- * instead.
- *
- * @param {Object} obj
- * @return {ServerResponse} for chaining
- * @api public
- */
-
-res.format = function(obj){
- var req = this.req;
- var next = req.next;
-
- var fn = obj.default;
- if (fn) delete obj.default;
- var keys = Object.keys(obj);
-
- var key = req.accepts(keys);
-
- this.vary("Accept");
-
- if (key) {
- this.set('Content-Type', normalizeType(key).value);
- obj[key](req, this, next);
- } else if (fn) {
- fn();
- } else {
- var err = new Error('Not Acceptable');
- err.status = 406;
- err.types = normalizeTypes(keys).map(function(o){ return o.value });
- next(err);
- }
-
- return this;
-};
-
-/**
- * Set _Content-Disposition_ header to _attachment_ with optional `filename`.
- *
- * @param {String} filename
- * @return {ServerResponse}
- * @api public
- */
-
-res.attachment = function(filename){
- if (filename) this.type(extname(filename));
- this.set('Content-Disposition', contentDisposition(filename));
- return this;
-};
-
-/**
- * Set header `field` to `val`, or pass
- * an object of header fields.
- *
- * Examples:
- *
- * res.set('Foo', ['bar', 'baz']);
- * res.set('Accept', 'application/json');
- * res.set({ Accept: 'text/plain', 'X-API-Key': 'tobi' });
- *
- * Aliased as `res.header()`.
- *
- * @param {String|Object|Array} field
- * @param {String} val
- * @return {ServerResponse} for chaining
- * @api public
- */
-
-res.set =
-res.header = function header(field, val) {
- if (arguments.length === 2) {
- if (Array.isArray(val)) val = val.map(String);
- else val = String(val);
- if ('content-type' == field.toLowerCase() && !/;\s*charset\s*=/.test(val)) {
- var charset = mime.charsets.lookup(val.split(';')[0]);
- if (charset) val += '; charset=' + charset.toLowerCase();
- }
- this.setHeader(field, val);
- } else {
- for (var key in field) {
- this.set(key, field[key]);
- }
- }
- return this;
-};
-
-/**
- * Get value for header `field`.
- *
- * @param {String} field
- * @return {String}
- * @api public
- */
-
-res.get = function(field){
- return this.getHeader(field);
-};
-
-/**
- * Clear cookie `name`.
- *
- * @param {String} name
- * @param {Object} options
- * @return {ServerResponse} for chaining
- * @api public
- */
-
-res.clearCookie = function(name, options){
- var opts = { expires: new Date(1), path: '/' };
- return this.cookie(name, '', options
- ? mixin(opts, options)
- : opts);
-};
-
-/**
- * Set cookie `name` to `val`, with the given `options`.
- *
- * Options:
- *
- * - `maxAge` max-age in milliseconds, converted to `expires`
- * - `signed` sign the cookie
- * - `path` defaults to "/"
- *
- * Examples:
- *
- * // "Remember Me" for 15 minutes
- * res.cookie('rememberme', '1', { expires: new Date(Date.now() + 900000), httpOnly: true });
- *
- * // save as above
- * res.cookie('rememberme', '1', { maxAge: 900000, httpOnly: true })
- *
- * @param {String} name
- * @param {String|Object} val
- * @param {Options} options
- * @return {ServerResponse} for chaining
- * @api public
- */
-
-res.cookie = function(name, val, options){
- options = mixin({}, options);
- var secret = this.req.secret;
- var signed = options.signed;
- if (signed && !secret) throw new Error('cookieParser("secret") required for signed cookies');
- if ('number' == typeof val) val = val.toString();
- if ('object' == typeof val) val = 'j:' + JSON.stringify(val);
- if (signed) val = 's:' + sign(val, secret);
- if ('maxAge' in options) {
- options.expires = new Date(Date.now() + options.maxAge);
- options.maxAge /= 1000;
- }
- if (null == options.path) options.path = '/';
- var headerVal = cookie.serialize(name, String(val), options);
-
- // supports multiple 'res.cookie' calls by getting previous value
- var prev = this.get('Set-Cookie');
- if (prev) {
- if (Array.isArray(prev)) {
- headerVal = prev.concat(headerVal);
- } else {
- headerVal = [prev, headerVal];
- }
- }
- this.set('Set-Cookie', headerVal);
- return this;
-};
-
-
-/**
- * Set the location header to `url`.
- *
- * The given `url` can also be "back", which redirects
- * to the _Referrer_ or _Referer_ headers or "/".
- *
- * Examples:
- *
- * res.location('/foo/bar').;
- * res.location('http://example.com');
- * res.location('../login');
- *
- * @param {String} url
- * @return {ServerResponse} for chaining
- * @api public
- */
-
-res.location = function(url){
- var req = this.req;
-
- // "back" is an alias for the referrer
- if ('back' == url) url = req.get('Referrer') || '/';
-
- // Respond
- this.set('Location', url);
- return this;
-};
-
-/**
- * Redirect to the given `url` with optional response `status`
- * defaulting to 302.
- *
- * The resulting `url` is determined by `res.location()`, so
- * it will play nicely with mounted apps, relative paths,
- * `"back"` etc.
- *
- * Examples:
- *
- * res.redirect('/foo/bar');
- * res.redirect('http://example.com');
- * res.redirect(301, 'http://example.com');
- * res.redirect('../login'); // /blog/post/1 -> /blog/login
- *
- * @api public
- */
-
-res.redirect = function redirect(url) {
- var address = url;
- var body;
- var status = 302;
-
- // allow status / url
- if (arguments.length === 2) {
- if (typeof arguments[0] === 'number') {
- status = arguments[0];
- address = arguments[1];
- } else {
- deprecate('res.redirect(url, status): Use res.redirect(status, url) instead');
- status = arguments[1];
- }
- }
-
- // Set location header
- this.location(address);
- address = this.get('Location');
-
- // Support text/{plain,html} by default
- this.format({
- text: function(){
- body = statusCodes[status] + '. Redirecting to ' + encodeURI(address);
- },
-
- html: function(){
- var u = escapeHtml(address);
- body = '' + statusCodes[status] + '. Redirecting to ' + u + '
';
- },
-
- default: function(){
- body = '';
- }
- });
-
- // Respond
- this.statusCode = status;
- this.set('Content-Length', Buffer.byteLength(body));
-
- if (this.req.method === 'HEAD') {
- this.end();
- }
-
- this.end(body);
-};
-
-/**
- * Add `field` to Vary. If already present in the Vary set, then
- * this call is simply ignored.
- *
- * @param {Array|String} field
- * @return {ServerResponse} for chaining
- * @api public
- */
-
-res.vary = function(field){
- // checks for back-compat
- if (!field || (Array.isArray(field) && !field.length)) {
- deprecate('res.vary(): Provide a field name');
- return this;
- }
-
- vary(this, field);
-
- return this;
-};
-
-/**
- * Render `view` with the given `options` and optional callback `fn`.
- * When a callback function is given a response will _not_ be made
- * automatically, otherwise a response of _200_ and _text/html_ is given.
- *
- * Options:
- *
- * - `cache` boolean hinting to the engine it should cache
- * - `filename` filename of the view being rendered
- *
- * @api public
- */
-
-res.render = function(view, options, fn){
- options = options || {};
- var self = this;
- var req = this.req;
- var app = req.app;
-
- // support callback function as second arg
- if ('function' == typeof options) {
- fn = options, options = {};
- }
-
- // merge res.locals
- options._locals = self.locals;
-
- // default callback to respond
- fn = fn || function(err, str){
- if (err) return req.next(err);
- self.send(str);
- };
-
- // render
- app.render(view, options, fn);
-};
-
-// pipe the send file stream
-function sendfile(res, file, options, callback) {
- var done = false;
-
- // directory
- function ondirectory() {
- if (done) return;
- done = true;
-
- var err = new Error('EISDIR, read');
- err.code = 'EISDIR';
- callback(err);
- }
-
- // errors
- function onerror(err) {
- if (done) return;
- done = true;
- callback(err);
- }
-
- // ended
- function onend() {
- if (done) return;
- done = true;
- callback();
- }
-
- // finished
- function onfinish(err) {
- if (err) return onerror(err);
- if (done) return;
-
- setImmediate(function () {
- if (done) return;
- done = true;
-
- // response finished before end of file
- var err = new Error('Request aborted');
- err.code = 'ECONNABORT';
- callback(err);
- });
- }
-
- file.on('end', onend);
- file.on('error', onerror);
- file.on('directory', ondirectory);
- onFinished(res, onfinish);
-
- if (options.headers) {
- // set headers on successful transfer
- file.on('headers', function headers(res) {
- var obj = options.headers;
- var keys = Object.keys(obj);
-
- for (var i = 0; i < keys.length; i++) {
- var k = keys[i];
- res.setHeader(k, obj[k]);
- }
- });
- }
-
- // pipe
- file.pipe(res);
-}
diff --git a/CoAuthoring/node_modules/express/lib/router/index.js b/CoAuthoring/node_modules/express/lib/router/index.js
deleted file mode 100644
index 64fcd1e3ac..0000000000
--- a/CoAuthoring/node_modules/express/lib/router/index.js
+++ /dev/null
@@ -1,576 +0,0 @@
-
-/**
- * Module dependencies.
- */
-
-var Route = require('./route');
-var Layer = require('./layer');
-var methods = require('methods');
-var mixin = require('utils-merge');
-var debug = require('debug')('express:router');
-var parseUrl = require('parseurl');
-var utils = require('../utils');
-
-/**
- * Module variables.
- */
-
-var objectRegExp = /^\[object (\S+)\]$/;
-var slice = Array.prototype.slice;
-var toString = Object.prototype.toString;
-
-/**
- * Initialize a new `Router` with the given `options`.
- *
- * @param {Object} options
- * @return {Router} which is an callable function
- * @api public
- */
-
-var proto = module.exports = function(options) {
- options = options || {};
-
- function router(req, res, next) {
- router.handle(req, res, next);
- }
-
- // mixin Router class functions
- router.__proto__ = proto;
-
- router.params = {};
- router._params = [];
- router.caseSensitive = options.caseSensitive;
- router.mergeParams = options.mergeParams;
- router.strict = options.strict;
- router.stack = [];
-
- return router;
-};
-
-/**
- * Map the given param placeholder `name`(s) to the given callback.
- *
- * Parameter mapping is used to provide pre-conditions to routes
- * which use normalized placeholders. For example a _:user_id_ parameter
- * could automatically load a user's information from the database without
- * any additional code,
- *
- * The callback uses the same signature as middleware, the only difference
- * being that the value of the placeholder is passed, in this case the _id_
- * of the user. Once the `next()` function is invoked, just like middleware
- * it will continue on to execute the route, or subsequent parameter functions.
- *
- * Just like in middleware, you must either respond to the request or call next
- * to avoid stalling the request.
- *
- * app.param('user_id', function(req, res, next, id){
- * User.find(id, function(err, user){
- * if (err) {
- * return next(err);
- * } else if (!user) {
- * return next(new Error('failed to load user'));
- * }
- * req.user = user;
- * next();
- * });
- * });
- *
- * @param {String} name
- * @param {Function} fn
- * @return {app} for chaining
- * @api public
- */
-
-proto.param = function(name, fn){
- // param logic
- if ('function' == typeof name) {
- this._params.push(name);
- return;
- }
-
- // apply param functions
- var params = this._params;
- var len = params.length;
- var ret;
-
- if (name[0] === ':') {
- name = name.substr(1);
- }
-
- for (var i = 0; i < len; ++i) {
- if (ret = params[i](name, fn)) {
- fn = ret;
- }
- }
-
- // ensure we end up with a
- // middleware function
- if ('function' != typeof fn) {
- throw new Error('invalid param() call for ' + name + ', got ' + fn);
- }
-
- (this.params[name] = this.params[name] || []).push(fn);
- return this;
-};
-
-/**
- * Dispatch a req, res into the router.
- *
- * @api private
- */
-
-proto.handle = function(req, res, done) {
- var self = this;
-
- debug('dispatching %s %s', req.method, req.url);
-
- var search = 1 + req.url.indexOf('?');
- var pathlength = search ? search - 1 : req.url.length;
- var fqdn = 1 + req.url.substr(0, pathlength).indexOf('://');
- var protohost = fqdn ? req.url.substr(0, req.url.indexOf('/', 2 + fqdn)) : '';
- var idx = 0;
- var removed = '';
- var slashAdded = false;
- var paramcalled = {};
-
- // store options for OPTIONS request
- // only used if OPTIONS request
- var options = [];
-
- // middleware and routes
- var stack = self.stack;
-
- // manage inter-router variables
- var parentParams = req.params;
- var parentUrl = req.baseUrl || '';
- done = restore(done, req, 'baseUrl', 'next', 'params');
-
- // setup next layer
- req.next = next;
-
- // for options requests, respond with a default if nothing else responds
- if (req.method === 'OPTIONS') {
- done = wrap(done, function(old, err) {
- if (err || options.length === 0) return old(err);
-
- var body = options.join(',');
- return res.set('Allow', body).send(body);
- });
- }
-
- // setup basic req values
- req.baseUrl = parentUrl;
- req.originalUrl = req.originalUrl || req.url;
-
- next();
-
- function next(err) {
- var layerError = err === 'route'
- ? null
- : err;
-
- var layer = stack[idx++];
-
- if (slashAdded) {
- req.url = req.url.substr(1);
- slashAdded = false;
- }
-
- if (removed.length !== 0) {
- req.baseUrl = parentUrl;
- req.url = protohost + removed + req.url.substr(protohost.length);
- removed = '';
- }
-
- if (!layer) {
- return done(layerError);
- }
-
- self.match_layer(layer, req, res, function (err, path) {
- if (err || path === undefined) {
- return next(layerError || err);
- }
-
- // route object and not middleware
- var route = layer.route;
-
- // if final route, then we support options
- if (route) {
- // we don't run any routes with error first
- if (layerError) {
- return next(layerError);
- }
-
- var method = req.method;
- var has_method = route._handles_method(method);
-
- // build up automatic options response
- if (!has_method && method === 'OPTIONS') {
- options.push.apply(options, route._options());
- }
-
- // don't even bother
- if (!has_method && method !== 'HEAD') {
- return next();
- }
-
- // we can now dispatch to the route
- req.route = route;
- }
-
- // Capture one-time layer values
- req.params = self.mergeParams
- ? mergeParams(layer.params, parentParams)
- : layer.params;
- var layerPath = layer.path;
-
- // this should be done for the layer
- self.process_params(layer, paramcalled, req, res, function (err) {
- if (err) {
- return next(layerError || err);
- }
-
- if (route) {
- return layer.handle_request(req, res, next);
- }
-
- trim_prefix(layer, layerError, layerPath, path);
- });
- });
- }
-
- function trim_prefix(layer, layerError, layerPath, path) {
- var c = path[layerPath.length];
- if (c && '/' !== c && '.' !== c) return next(layerError);
-
- // Trim off the part of the url that matches the route
- // middleware (.use stuff) needs to have the path stripped
- if (layerPath.length !== 0) {
- debug('trim prefix (%s) from url %s', layerPath, req.url);
- removed = layerPath;
- req.url = protohost + req.url.substr(protohost.length + removed.length);
-
- // Ensure leading slash
- if (!fqdn && req.url[0] !== '/') {
- req.url = '/' + req.url;
- slashAdded = true;
- }
-
- // Setup base URL (no trailing slash)
- req.baseUrl = parentUrl + (removed[removed.length - 1] === '/'
- ? removed.substring(0, removed.length - 1)
- : removed);
- }
-
- debug('%s %s : %s', layer.name, layerPath, req.originalUrl);
-
- if (layerError) {
- layer.handle_error(layerError, req, res, next);
- } else {
- layer.handle_request(req, res, next);
- }
- }
-};
-
-/**
- * Match request to a layer.
- *
- * @api private
- */
-
-proto.match_layer = function match_layer(layer, req, res, done) {
- var error = null;
- var path;
-
- try {
- path = parseUrl(req).pathname;
-
- if (!layer.match(path)) {
- path = undefined;
- }
- } catch (err) {
- error = err;
- }
-
- done(error, path);
-};
-
-/**
- * Process any parameters for the layer.
- *
- * @api private
- */
-
-proto.process_params = function(layer, called, req, res, done) {
- var params = this.params;
-
- // captured parameters from the layer, keys and values
- var keys = layer.keys;
-
- // fast track
- if (!keys || keys.length === 0) {
- return done();
- }
-
- var i = 0;
- var name;
- var paramIndex = 0;
- var key;
- var paramVal;
- var paramCallbacks;
- var paramCalled;
-
- // process params in order
- // param callbacks can be async
- function param(err) {
- if (err) {
- return done(err);
- }
-
- if (i >= keys.length ) {
- return done();
- }
-
- paramIndex = 0;
- key = keys[i++];
-
- if (!key) {
- return done();
- }
-
- name = key.name;
- paramVal = req.params[name];
- paramCallbacks = params[name];
- paramCalled = called[name];
-
- if (paramVal === undefined || !paramCallbacks) {
- return param();
- }
-
- // param previously called with same value or error occurred
- if (paramCalled && (paramCalled.error || paramCalled.match === paramVal)) {
- // restore value
- req.params[name] = paramCalled.value;
-
- // next param
- return param(paramCalled.error);
- }
-
- called[name] = paramCalled = {
- error: null,
- match: paramVal,
- value: paramVal
- };
-
- paramCallback();
- }
-
- // single param callbacks
- function paramCallback(err) {
- var fn = paramCallbacks[paramIndex++];
-
- // store updated value
- paramCalled.value = req.params[key.name];
-
- if (err) {
- // store error
- paramCalled.error = err;
- param(err);
- return;
- }
-
- if (!fn) return param();
-
- try {
- fn(req, res, paramCallback, paramVal, key.name);
- } catch (e) {
- paramCallback(e);
- }
- }
-
- param();
-};
-
-/**
- * Use the given middleware function, with optional path, defaulting to "/".
- *
- * Use (like `.all`) will run for any http METHOD, but it will not add
- * handlers for those methods so OPTIONS requests will not consider `.use`
- * functions even if they could respond.
- *
- * The other difference is that _route_ path is stripped and not visible
- * to the handler function. The main effect of this feature is that mounted
- * handlers can operate without any code changes regardless of the "prefix"
- * pathname.
- *
- * @api public
- */
-
-proto.use = function use(fn) {
- var offset = 0;
- var path = '/';
- var self = this;
-
- // default path to '/'
- // disambiguate router.use([fn])
- if (typeof fn !== 'function') {
- var arg = fn;
-
- while (Array.isArray(arg) && arg.length !== 0) {
- arg = arg[0];
- }
-
- // first arg is the path
- if (typeof arg !== 'function') {
- offset = 1;
- path = fn;
- }
- }
-
- var callbacks = utils.flatten(slice.call(arguments, offset));
-
- if (callbacks.length === 0) {
- throw new TypeError('Router.use() requires middleware functions');
- }
-
- callbacks.forEach(function (fn) {
- if (typeof fn !== 'function') {
- throw new TypeError('Router.use() requires middleware function but got a ' + gettype(fn));
- }
-
- // add the middleware
- debug('use %s %s', path, fn.name || '');
-
- var layer = new Layer(path, {
- sensitive: self.caseSensitive,
- strict: false,
- end: false
- }, fn);
-
- layer.route = undefined;
-
- self.stack.push(layer);
- });
-
- return this;
-};
-
-/**
- * Create a new Route for the given path.
- *
- * Each route contains a separate middleware stack and VERB handlers.
- *
- * See the Route api documentation for details on adding handlers
- * and middleware to routes.
- *
- * @param {String} path
- * @return {Route}
- * @api public
- */
-
-proto.route = function(path){
- var route = new Route(path);
-
- var layer = new Layer(path, {
- sensitive: this.caseSensitive,
- strict: this.strict,
- end: true
- }, route.dispatch.bind(route));
-
- layer.route = route;
-
- this.stack.push(layer);
- return route;
-};
-
-// create Router#VERB functions
-methods.concat('all').forEach(function(method){
- proto[method] = function(path){
- var route = this.route(path)
- route[method].apply(route, slice.call(arguments, 1));
- return this;
- };
-});
-
-// get type for error message
-function gettype(obj) {
- var type = typeof obj;
-
- if (type !== 'object') {
- return type;
- }
-
- // inspect [[Class]] for objects
- return toString.call(obj)
- .replace(objectRegExp, '$1');
-}
-
-// merge params with parent params
-function mergeParams(params, parent) {
- if (typeof parent !== 'object' || !parent) {
- return params;
- }
-
- // make copy of parent for base
- var obj = mixin({}, parent);
-
- // simple non-numeric merging
- if (!(0 in params) || !(0 in parent)) {
- return mixin(obj, params);
- }
-
- var i = 0;
- var o = 0;
-
- // determine numeric gaps
- while (i === o || o in parent) {
- if (i in params) i++;
- if (o in parent) o++;
- }
-
- // offset numeric indices in params before merge
- for (i--; i >= 0; i--) {
- params[i + o] = params[i];
-
- // create holes for the merge when necessary
- if (i < o) {
- delete params[i];
- }
- }
-
- return mixin(parent, params);
-}
-
-// restore obj props after function
-function restore(fn, obj) {
- var props = new Array(arguments.length - 2);
- var vals = new Array(arguments.length - 2);
-
- for (var i = 0; i < props.length; i++) {
- props[i] = arguments[i + 2];
- vals[i] = obj[props[i]];
- }
-
- return function(err){
- // restore vals
- for (var i = 0; i < props.length; i++) {
- obj[props[i]] = vals[i];
- }
-
- return fn.apply(this, arguments);
- };
-}
-
-// wrap a function
-function wrap(old, fn) {
- return function proxy() {
- var args = new Array(arguments.length + 1);
-
- args[0] = old;
- for (var i = 0, len = arguments.length; i < len; i++) {
- args[i + 1] = arguments[i];
- }
-
- fn.apply(this, args);
- };
-}
diff --git a/CoAuthoring/node_modules/express/lib/router/layer.js b/CoAuthoring/node_modules/express/lib/router/layer.js
deleted file mode 100644
index 3f15002383..0000000000
--- a/CoAuthoring/node_modules/express/lib/router/layer.js
+++ /dev/null
@@ -1,159 +0,0 @@
-/**
- * Module dependencies.
- */
-
-var pathRegexp = require('path-to-regexp');
-var debug = require('debug')('express:router:layer');
-
-/**
- * Module variables.
- */
-
-var hasOwnProperty = Object.prototype.hasOwnProperty;
-
-/**
- * Expose `Layer`.
- */
-
-module.exports = Layer;
-
-function Layer(path, options, fn) {
- if (!(this instanceof Layer)) {
- return new Layer(path, options, fn);
- }
-
- debug('new %s', path);
- options = options || {};
-
- this.handle = fn;
- this.name = fn.name || '';
- this.params = undefined;
- this.path = undefined;
- this.regexp = pathRegexp(path, this.keys = [], options);
-
- if (path === '/' && options.end === false) {
- this.regexp.fast_slash = true;
- }
-}
-
-/**
- * Handle the error for the layer.
- *
- * @param {Error} error
- * @param {Request} req
- * @param {Response} res
- * @param {function} next
- * @api private
- */
-
-Layer.prototype.handle_error = function handle_error(error, req, res, next) {
- var fn = this.handle;
-
- if (fn.length !== 4) {
- // not a standard error handler
- return next(error);
- }
-
- try {
- fn(error, req, res, next);
- } catch (err) {
- next(err);
- }
-};
-
-/**
- * Handle the request for the layer.
- *
- * @param {Request} req
- * @param {Response} res
- * @param {function} next
- * @api private
- */
-
-Layer.prototype.handle_request = function handle(req, res, next) {
- var fn = this.handle;
-
- if (fn.length > 3) {
- // not a standard request handler
- return next();
- }
-
- try {
- fn(req, res, next);
- } catch (err) {
- next(err);
- }
-};
-
-/**
- * Check if this route matches `path`, if so
- * populate `.params`.
- *
- * @param {String} path
- * @return {Boolean}
- * @api private
- */
-
-Layer.prototype.match = function match(path) {
- if (this.regexp.fast_slash) {
- // fast path non-ending match for / (everything matches)
- this.params = {};
- this.path = '';
- return true;
- }
-
- var m = this.regexp.exec(path);
-
- if (!m) {
- this.params = undefined;
- this.path = undefined;
- return false;
- }
-
- // store values
- this.params = {};
- this.path = m[0];
-
- var keys = this.keys;
- var params = this.params;
- var prop;
- var n = 0;
- var key;
- var val;
-
- for (var i = 1, len = m.length; i < len; ++i) {
- key = keys[i - 1];
- prop = key
- ? key.name
- : n++;
- val = decode_param(m[i]);
-
- if (val !== undefined || !(hasOwnProperty.call(params, prop))) {
- params[prop] = val;
- }
- }
-
- return true;
-};
-
-/**
- * Decode param value.
- *
- * @param {string} val
- * @return {string}
- * @api private
- */
-
-function decode_param(val){
- if (typeof val !== 'string') {
- return val;
- }
-
- try {
- return decodeURIComponent(val);
- } catch (e) {
- var err = new TypeError("Failed to decode param '" + val + "'");
- err.status = 400;
- throw err;
- }
-}
diff --git a/CoAuthoring/node_modules/express/lib/router/match.js b/CoAuthoring/node_modules/express/lib/router/match.js
deleted file mode 100644
index 9afebfc8b3..0000000000
--- a/CoAuthoring/node_modules/express/lib/router/match.js
+++ /dev/null
@@ -1,56 +0,0 @@
-
-/**
- * Expose `Layer`.
- */
-
-module.exports = Match;
-
-function Match(layer, path, params) {
- this.layer = layer;
- this.params = {};
- this.path = path || '';
-
- if (!params) {
- return this;
- }
-
- var keys = layer.keys;
- var n = 0;
- var prop;
- var key;
- var val;
-
- for (var i = 0; i < params.length; i++) {
- key = keys[i];
- val = decode_param(params[i]);
- prop = key
- ? key.name
- : n++;
-
- this.params[prop] = val;
- }
-
- return this;
-};
-
-/**
- * Decode param value.
- *
- * @param {string} val
- * @return {string}
- * @api private
- */
-
-function decode_param(val){
- if (typeof val !== 'string') {
- return val;
- }
-
- try {
- return decodeURIComponent(val);
- } catch (e) {
- var err = new TypeError("Failed to decode param '" + val + "'");
- err.status = 400;
- throw err;
- }
-}
diff --git a/CoAuthoring/node_modules/express/lib/router/route.js b/CoAuthoring/node_modules/express/lib/router/route.js
deleted file mode 100644
index 6b39211921..0000000000
--- a/CoAuthoring/node_modules/express/lib/router/route.js
+++ /dev/null
@@ -1,175 +0,0 @@
-/**
- * Module dependencies.
- */
-
-var debug = require('debug')('express:router:route');
-var Layer = require('./layer');
-var methods = require('methods');
-var utils = require('../utils');
-
-/**
- * Expose `Route`.
- */
-
-module.exports = Route;
-
-/**
- * Initialize `Route` with the given `path`,
- *
- * @param {String} path
- * @api private
- */
-
-function Route(path) {
- debug('new %s', path);
- this.path = path;
- this.stack = [];
-
- // route handlers for various http methods
- this.methods = {};
-}
-
-/**
- * @api private
- */
-
-Route.prototype._handles_method = function _handles_method(method) {
- if (this.methods._all) {
- return true;
- }
-
- method = method.toLowerCase();
-
- if (method === 'head' && !this.methods['head']) {
- method = 'get';
- }
-
- return Boolean(this.methods[method]);
-};
-
-/**
- * @return {Array} supported HTTP methods
- * @api private
- */
-
-Route.prototype._options = function(){
- return Object.keys(this.methods).map(function(method) {
- return method.toUpperCase();
- });
-};
-
-/**
- * dispatch req, res into this route
- *
- * @api private
- */
-
-Route.prototype.dispatch = function(req, res, done){
- var idx = 0;
- var stack = this.stack;
- if (stack.length === 0) {
- return done();
- }
-
- var method = req.method.toLowerCase();
- if (method === 'head' && !this.methods['head']) {
- method = 'get';
- }
-
- req.route = this;
-
- next();
-
- function next(err) {
- if (err && err === 'route') {
- return done();
- }
-
- var layer = stack[idx++];
- if (!layer) {
- return done(err);
- }
-
- if (layer.method && layer.method !== method) {
- return next(err);
- }
-
- if (err) {
- layer.handle_error(err, req, res, next);
- } else {
- layer.handle_request(req, res, next);
- }
- }
-};
-
-/**
- * Add a handler for all HTTP verbs to this route.
- *
- * Behaves just like middleware and can respond or call `next`
- * to continue processing.
- *
- * You can use multiple `.all` call to add multiple handlers.
- *
- * function check_something(req, res, next){
- * next();
- * };
- *
- * function validate_user(req, res, next){
- * next();
- * };
- *
- * route
- * .all(validate_user)
- * .all(check_something)
- * .get(function(req, res, next){
- * res.send('hello world');
- * });
- *
- * @param {function} handler
- * @return {Route} for chaining
- * @api public
- */
-
-Route.prototype.all = function(){
- var self = this;
- var callbacks = utils.flatten([].slice.call(arguments));
- callbacks.forEach(function(fn) {
- if (typeof fn !== 'function') {
- var type = {}.toString.call(fn);
- var msg = 'Route.all() requires callback functions but got a ' + type;
- throw new Error(msg);
- }
-
- var layer = Layer('/', {}, fn);
- layer.method = undefined;
-
- self.methods._all = true;
- self.stack.push(layer);
- });
-
- return self;
-};
-
-methods.forEach(function(method){
- Route.prototype[method] = function(){
- var self = this;
- var callbacks = utils.flatten([].slice.call(arguments));
-
- callbacks.forEach(function(fn) {
- if (typeof fn !== 'function') {
- var type = {}.toString.call(fn);
- var msg = 'Route.' + method + '() requires callback functions but got a ' + type;
- throw new Error(msg);
- }
-
- debug('%s %s', method, self.path);
-
- var layer = Layer('/', {}, fn);
- layer.method = method;
-
- self.methods[method] = true;
- self.stack.push(layer);
- });
- return self;
- };
-});
diff --git a/CoAuthoring/node_modules/express/lib/utils.js b/CoAuthoring/node_modules/express/lib/utils.js
deleted file mode 100644
index 8dd29664cb..0000000000
--- a/CoAuthoring/node_modules/express/lib/utils.js
+++ /dev/null
@@ -1,291 +0,0 @@
-/**
- * Module dependencies.
- */
-
-var mime = require('send').mime;
-var basename = require('path').basename;
-var etag = require('etag');
-var proxyaddr = require('proxy-addr');
-var qs = require('qs');
-var querystring = require('querystring');
-var typer = require('media-typer');
-
-/**
- * Return strong ETag for `body`.
- *
- * @param {String|Buffer} body
- * @param {String} [encoding]
- * @return {String}
- * @api private
- */
-
-exports.etag = function (body, encoding) {
- var buf = !Buffer.isBuffer(body)
- ? new Buffer(body, encoding)
- : body
-
- return etag(buf, {weak: false})
-};
-
-/**
- * Return weak ETag for `body`.
- *
- * @param {String|Buffer} body
- * @param {String} [encoding]
- * @return {String}
- * @api private
- */
-
-exports.wetag = function wetag(body, encoding){
- var buf = !Buffer.isBuffer(body)
- ? new Buffer(body, encoding)
- : body
-
- return etag(buf, {weak: true})
-};
-
-/**
- * Check if `path` looks absolute.
- *
- * @param {String} path
- * @return {Boolean}
- * @api private
- */
-
-exports.isAbsolute = function(path){
- if ('/' == path[0]) return true;
- if (':' == path[1] && '\\' == path[2]) return true;
- if ('\\\\' == path.substring(0, 2)) return true; // Microsoft Azure absolute path
-};
-
-/**
- * Flatten the given `arr`.
- *
- * @param {Array} arr
- * @return {Array}
- * @api private
- */
-
-exports.flatten = function(arr, ret){
- ret = ret || [];
- var len = arr.length;
- for (var i = 0; i < len; ++i) {
- if (Array.isArray(arr[i])) {
- exports.flatten(arr[i], ret);
- } else {
- ret.push(arr[i]);
- }
- }
- return ret;
-};
-
-/**
- * Normalize the given `type`, for example "html" becomes "text/html".
- *
- * @param {String} type
- * @return {Object}
- * @api private
- */
-
-exports.normalizeType = function(type){
- return ~type.indexOf('/')
- ? acceptParams(type)
- : { value: mime.lookup(type), params: {} };
-};
-
-/**
- * Normalize `types`, for example "html" becomes "text/html".
- *
- * @param {Array} types
- * @return {Array}
- * @api private
- */
-
-exports.normalizeTypes = function(types){
- var ret = [];
-
- for (var i = 0; i < types.length; ++i) {
- ret.push(exports.normalizeType(types[i]));
- }
-
- return ret;
-};
-
-/**
- * Generate Content-Disposition header appropriate for the filename.
- * non-ascii filenames are urlencoded and a filename* parameter is added
- *
- * @param {String} filename
- * @return {String}
- * @api private
- */
-
-exports.contentDisposition = function(filename){
- var ret = 'attachment';
- if (filename) {
- filename = basename(filename);
- // if filename contains non-ascii characters, add a utf-8 version ala RFC 5987
- ret = /[^\040-\176]/.test(filename)
- ? 'attachment; filename="' + encodeURI(filename) + '"; filename*=UTF-8\'\'' + encodeURI(filename)
- : 'attachment; filename="' + filename + '"';
- }
-
- return ret;
-};
-
-/**
- * Parse accept params `str` returning an
- * object with `.value`, `.quality` and `.params`.
- * also includes `.originalIndex` for stable sorting
- *
- * @param {String} str
- * @return {Object}
- * @api private
- */
-
-function acceptParams(str, index) {
- var parts = str.split(/ *; */);
- var ret = { value: parts[0], quality: 1, params: {}, originalIndex: index };
-
- for (var i = 1; i < parts.length; ++i) {
- var pms = parts[i].split(/ *= */);
- if ('q' == pms[0]) {
- ret.quality = parseFloat(pms[1]);
- } else {
- ret.params[pms[0]] = pms[1];
- }
- }
-
- return ret;
-}
-
-/**
- * Compile "etag" value to function.
- *
- * @param {Boolean|String|Function} val
- * @return {Function}
- * @api private
- */
-
-exports.compileETag = function(val) {
- var fn;
-
- if (typeof val === 'function') {
- return val;
- }
-
- switch (val) {
- case true:
- fn = exports.wetag;
- break;
- case false:
- break;
- case 'strong':
- fn = exports.etag;
- break;
- case 'weak':
- fn = exports.wetag;
- break;
- default:
- throw new TypeError('unknown value for etag function: ' + val);
- }
-
- return fn;
-}
-
-/**
- * Compile "query parser" value to function.
- *
- * @param {String|Function} val
- * @return {Function}
- * @api private
- */
-
-exports.compileQueryParser = function compileQueryParser(val) {
- var fn;
-
- if (typeof val === 'function') {
- return val;
- }
-
- switch (val) {
- case true:
- fn = querystring.parse;
- break;
- case false:
- fn = newObject;
- break;
- case 'extended':
- fn = qs.parse;
- break;
- case 'simple':
- fn = querystring.parse;
- break;
- default:
- throw new TypeError('unknown value for query parser function: ' + val);
- }
-
- return fn;
-}
-
-/**
- * Compile "proxy trust" value to function.
- *
- * @param {Boolean|String|Number|Array|Function} val
- * @return {Function}
- * @api private
- */
-
-exports.compileTrust = function(val) {
- if (typeof val === 'function') return val;
-
- if (val === true) {
- // Support plain true/false
- return function(){ return true };
- }
-
- if (typeof val === 'number') {
- // Support trusting hop count
- return function(a, i){ return i < val };
- }
-
- if (typeof val === 'string') {
- // Support comma-separated values
- val = val.split(/ *, */);
- }
-
- return proxyaddr.compile(val || []);
-}
-
-/**
- * Set the charset in a given Content-Type string.
- *
- * @param {String} type
- * @param {String} charset
- * @return {String}
- * @api private
- */
-
-exports.setCharset = function(type, charset){
- if (!type || !charset) return type;
-
- // parse type
- var parsed = typer.parse(type);
-
- // set charset
- parsed.parameters.charset = charset;
-
- // format type
- return typer.format(parsed);
-};
-
-/**
- * Return new empty objet.
- *
- * @return {Object}
- * @api private
- */
-
-function newObject() {
- return {};
-}
diff --git a/CoAuthoring/node_modules/express/lib/view.js b/CoAuthoring/node_modules/express/lib/view.js
deleted file mode 100644
index 989e8bb251..0000000000
--- a/CoAuthoring/node_modules/express/lib/view.js
+++ /dev/null
@@ -1,77 +0,0 @@
-/**
- * Module dependencies.
- */
-
-var path = require('path');
-var fs = require('fs');
-var utils = require('./utils');
-var dirname = path.dirname;
-var basename = path.basename;
-var extname = path.extname;
-var exists = fs.existsSync || path.existsSync;
-var join = path.join;
-
-/**
- * Expose `View`.
- */
-
-module.exports = View;
-
-/**
- * Initialize a new `View` with the given `name`.
- *
- * Options:
- *
- * - `defaultEngine` the default template engine name
- * - `engines` template engine require() cache
- * - `root` root path for view lookup
- *
- * @param {String} name
- * @param {Object} options
- * @api private
- */
-
-function View(name, options) {
- options = options || {};
- this.name = name;
- this.root = options.root;
- var engines = options.engines;
- this.defaultEngine = options.defaultEngine;
- var ext = this.ext = extname(name);
- if (!ext && !this.defaultEngine) throw new Error('No default engine was specified and no extension was provided.');
- if (!ext) name += (ext = this.ext = ('.' != this.defaultEngine[0] ? '.' : '') + this.defaultEngine);
- this.engine = engines[ext] || (engines[ext] = require(ext.slice(1)).__express);
- this.path = this.lookup(name);
-}
-
-/**
- * Lookup view by the given `path`
- *
- * @param {String} path
- * @return {String}
- * @api private
- */
-
-View.prototype.lookup = function(path){
- var ext = this.ext;
-
- // .
- if (!utils.isAbsolute(path)) path = join(this.root, path);
- if (exists(path)) return path;
-
- // /index.
- path = join(dirname(path), basename(path, ext), 'index' + ext);
- if (exists(path)) return path;
-};
-
-/**
- * Render with the given `options` and callback `fn(err, str)`.
- *
- * @param {Object} options
- * @param {Function} fn
- * @api private
- */
-
-View.prototype.render = function(options, fn){
- this.engine(this.path, options, fn);
-};
diff --git a/CoAuthoring/node_modules/express/node_modules/accepts/HISTORY.md b/CoAuthoring/node_modules/express/node_modules/accepts/HISTORY.md
deleted file mode 100644
index efc07cb924..0000000000
--- a/CoAuthoring/node_modules/express/node_modules/accepts/HISTORY.md
+++ /dev/null
@@ -1,62 +0,0 @@
-1.1.2 / 2014-10-14
-==================
-
- * deps: negotiator@0.4.9
- - Fix error when media type has invalid parameter
-
-1.1.1 / 2014-09-28
-==================
-
- * deps: mime-types@~2.0.2
- - deps: mime-db@~1.1.0
- * deps: negotiator@0.4.8
- - Fix all negotiations to be case-insensitive
- - Stable sort preferences of same quality according to client order
-
-1.1.0 / 2014-09-02
-==================
-
- * update `mime-types`
-
-1.0.7 / 2014-07-04
-==================
-
- * Fix wrong type returned from `type` when match after unknown extension
-
-1.0.6 / 2014-06-24
-==================
-
- * deps: negotiator@0.4.7
-
-1.0.5 / 2014-06-20
-==================
-
- * fix crash when unknown extension given
-
-1.0.4 / 2014-06-19
-==================
-
- * use `mime-types`
-
-1.0.3 / 2014-06-11
-==================
-
- * deps: negotiator@0.4.6
- - Order by specificity when quality is the same
-
-1.0.2 / 2014-05-29
-==================
-
- * Fix interpretation when header not in request
- * deps: pin negotiator@0.4.5
-
-1.0.1 / 2014-01-18
-==================
-
- * Identity encoding isn't always acceptable
- * deps: negotiator@~0.4.0
-
-1.0.0 / 2013-12-27
-==================
-
- * Genesis
diff --git a/CoAuthoring/node_modules/express/node_modules/accepts/LICENSE b/CoAuthoring/node_modules/express/node_modules/accepts/LICENSE
deleted file mode 100644
index f23dca8de1..0000000000
--- a/CoAuthoring/node_modules/express/node_modules/accepts/LICENSE
+++ /dev/null
@@ -1,22 +0,0 @@
-(The MIT License)
-
-Copyright (c) 2014 Jonathan Ong
-
-Permission is hereby granted, free of charge, to any person obtaining
-a copy of this software and associated documentation files (the
-'Software'), to deal in the Software without restriction, including
-without limitation the rights to use, copy, modify, merge, publish,
-distribute, sublicense, and/or sell copies of the Software, and to
-permit persons to whom the Software is furnished to do so, subject to
-the following conditions:
-
-The above copyright notice and this permission notice shall be
-included in all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
-EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
-IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
-CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
-TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
-SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
diff --git a/CoAuthoring/node_modules/express/node_modules/accepts/README.md b/CoAuthoring/node_modules/express/node_modules/accepts/README.md
deleted file mode 100644
index 1223ee10be..0000000000
--- a/CoAuthoring/node_modules/express/node_modules/accepts/README.md
+++ /dev/null
@@ -1,94 +0,0 @@
-# accepts
-
-[![NPM Version][npm-image]][npm-url]
-[![NPM Downloads][downloads-image]][downloads-url]
-[![Node.js Version][node-version-image]][node-version-url]
-[![Build Status][travis-image]][travis-url]
-[![Test Coverage][coveralls-image]][coveralls-url]
-
-Higher level content negotation based on [negotiator](https://github.com/federomero/negotiator). Extracted from [koa](https://github.com/koajs/koa) for general use.
-
-In addition to negotatior, it allows:
-
-- Allows types as an array or arguments list, ie `(['text/html', 'application/json'])` as well as `('text/html', 'application/json')`.
-- Allows type shorthands such as `json`.
-- Returns `false` when no types match
-- Treats non-existent headers as `*`
-
-## API
-
-### var accept = new Accepts(req)
-
-```js
-var accepts = require('accepts')
-
-http.createServer(function (req, res) {
- var accept = accepts(req)
-})
-```
-
-### accept\[property\]\(\)
-
-Returns all the explicitly accepted content property as an array in descending priority.
-
-- `accept.types()`
-- `accept.encodings()`
-- `accept.charsets()`
-- `accept.languages()`
-
-They are also aliased in singular form such as `accept.type()`. `accept.languages()` is also aliased as `accept.langs()`, etc.
-
-Note: you should almost never do this in a real app as it defeats the purpose of content negotiation.
-
-Example:
-
-```js
-// in Google Chrome
-var encodings = accept.encodings() // -> ['sdch', 'gzip', 'deflate']
-```
-
-Since you probably don't support `sdch`, you should just supply the encodings you support:
-
-```js
-var encoding = accept.encodings('gzip', 'deflate') // -> 'gzip', probably
-```
-
-### accept\[property\]\(values, ...\)
-
-You can either have `values` be an array or have an argument list of values.
-
-If the client does not accept any `values`, `false` will be returned.
-If the client accepts any `values`, the preferred `value` will be return.
-
-For `accept.types()`, shorthand mime types are allowed.
-
-Example:
-
-```js
-// req.headers.accept = 'application/json'
-
-accept.types('json') // -> 'json'
-accept.types('html', 'json') // -> 'json'
-accept.types('html') // -> false
-
-// req.headers.accept = ''
-// which is equivalent to `*`
-
-accept.types() // -> [], no explicit types
-accept.types('text/html', 'text/json') // -> 'text/html', since it was first
-```
-
-## License
-
-[MIT](LICENSE)
-
-[npm-image]: https://img.shields.io/npm/v/accepts.svg?style=flat
-[npm-url]: https://npmjs.org/package/accepts
-[node-version-image]: https://img.shields.io/badge/node.js-%3E%3D_0.8-brightgreen.svg?style=flat
-[node-version-url]: http://nodejs.org/download/
-[travis-image]: https://img.shields.io/travis/jshttp/accepts.svg?style=flat
-[travis-url]: https://travis-ci.org/jshttp/accepts
-[coveralls-image]: https://img.shields.io/coveralls/jshttp/accepts.svg?style=flat
-[coveralls-url]: https://coveralls.io/r/jshttp/accepts
-[downloads-image]: https://img.shields.io/npm/dm/accepts.svg?style=flat
-[downloads-url]: https://npmjs.org/package/accepts
diff --git a/CoAuthoring/node_modules/express/node_modules/accepts/index.js b/CoAuthoring/node_modules/express/node_modules/accepts/index.js
deleted file mode 100644
index 805e33ab83..0000000000
--- a/CoAuthoring/node_modules/express/node_modules/accepts/index.js
+++ /dev/null
@@ -1,160 +0,0 @@
-var Negotiator = require('negotiator')
-var mime = require('mime-types')
-
-var slice = [].slice
-
-module.exports = Accepts
-
-function Accepts(req) {
- if (!(this instanceof Accepts))
- return new Accepts(req)
-
- this.headers = req.headers
- this.negotiator = Negotiator(req)
-}
-
-/**
- * Check if the given `type(s)` is acceptable, returning
- * the best match when true, otherwise `undefined`, in which
- * case you should respond with 406 "Not Acceptable".
- *
- * The `type` value may be a single mime type string
- * such as "application/json", the extension name
- * such as "json" or an array `["json", "html", "text/plain"]`. When a list
- * or array is given the _best_ match, if any is returned.
- *
- * Examples:
- *
- * // Accept: text/html
- * this.types('html');
- * // => "html"
- *
- * // Accept: text/*, application/json
- * this.types('html');
- * // => "html"
- * this.types('text/html');
- * // => "text/html"
- * this.types('json', 'text');
- * // => "json"
- * this.types('application/json');
- * // => "application/json"
- *
- * // Accept: text/*, application/json
- * this.types('image/png');
- * this.types('png');
- * // => undefined
- *
- * // Accept: text/*;q=.5, application/json
- * this.types(['html', 'json']);
- * this.types('html', 'json');
- * // => "json"
- *
- * @param {String|Array} type(s)...
- * @return {String|Array|Boolean}
- * @api public
- */
-
-Accepts.prototype.type =
-Accepts.prototype.types = function (types) {
- if (!Array.isArray(types)) types = slice.call(arguments);
- var n = this.negotiator;
- if (!types.length) return n.mediaTypes();
- if (!this.headers.accept) return types[0];
- var mimes = types.map(extToMime);
- var accepts = n.mediaTypes(mimes.filter(validMime));
- var first = accepts[0];
- if (!first) return false;
- return types[mimes.indexOf(first)];
-}
-
-/**
- * Return accepted encodings or best fit based on `encodings`.
- *
- * Given `Accept-Encoding: gzip, deflate`
- * an array sorted by quality is returned:
- *
- * ['gzip', 'deflate']
- *
- * @param {String|Array} encoding(s)...
- * @return {String|Array}
- * @api public
- */
-
-Accepts.prototype.encoding =
-Accepts.prototype.encodings = function (encodings) {
- if (!Array.isArray(encodings)) encodings = slice.call(arguments);
- var n = this.negotiator;
- if (!encodings.length) return n.encodings();
- return n.encodings(encodings)[0] || false;
-}
-
-/**
- * Return accepted charsets or best fit based on `charsets`.
- *
- * Given `Accept-Charset: utf-8, iso-8859-1;q=0.2, utf-7;q=0.5`
- * an array sorted by quality is returned:
- *
- * ['utf-8', 'utf-7', 'iso-8859-1']
- *
- * @param {String|Array} charset(s)...
- * @return {String|Array}
- * @api public
- */
-
-Accepts.prototype.charset =
-Accepts.prototype.charsets = function (charsets) {
- if (!Array.isArray(charsets)) charsets = [].slice.call(arguments);
- var n = this.negotiator;
- if (!charsets.length) return n.charsets();
- if (!this.headers['accept-charset']) return charsets[0];
- return n.charsets(charsets)[0] || false;
-}
-
-/**
- * Return accepted languages or best fit based on `langs`.
- *
- * Given `Accept-Language: en;q=0.8, es, pt`
- * an array sorted by quality is returned:
- *
- * ['es', 'pt', 'en']
- *
- * @param {String|Array} lang(s)...
- * @return {Array|String}
- * @api public
- */
-
-Accepts.prototype.lang =
-Accepts.prototype.langs =
-Accepts.prototype.language =
-Accepts.prototype.languages = function (langs) {
- if (!Array.isArray(langs)) langs = slice.call(arguments);
- var n = this.negotiator;
- if (!langs.length) return n.languages();
- if (!this.headers['accept-language']) return langs[0];
- return n.languages(langs)[0] || false;
-}
-
-/**
- * Convert extnames to mime.
- *
- * @param {String} type
- * @return {String}
- * @api private
- */
-
-function extToMime(type) {
- if (~type.indexOf('/')) return type;
- return mime.lookup(type);
-}
-
-/**
- * Check if mime is valid.
- *
- * @param {String} type
- * @return {String}
- * @api private
- */
-
-function validMime(type) {
- return typeof type === 'string';
-}
diff --git a/CoAuthoring/node_modules/express/node_modules/accepts/node_modules/mime-types/HISTORY.md b/CoAuthoring/node_modules/express/node_modules/accepts/node_modules/mime-types/HISTORY.md
deleted file mode 100644
index 6071381665..0000000000
--- a/CoAuthoring/node_modules/express/node_modules/accepts/node_modules/mime-types/HISTORY.md
+++ /dev/null
@@ -1,39 +0,0 @@
-2.0.2 / 2014-09-28
-==================
-
- * deps: mime-db@~1.1.0
- - Add new mime types
- - Add additional compressible
- - Update charsets
-
-2.0.1 / 2014-09-07
-==================
-
- * Support Node.js 0.6
-
-2.0.0 / 2014-09-02
-==================
-
- * Use `mime-db`
- * Remove `.define()`
-
-1.0.2 / 2014-08-04
-==================
-
- * Set charset=utf-8 for `text/javascript`
-
-1.0.1 / 2014-06-24
-==================
-
- * Add `text/jsx` type
-
-1.0.0 / 2014-05-12
-==================
-
- * Return `false` for unknown types
- * Set charset=utf-8 for `application/json`
-
-0.1.0 / 2014-05-02
-==================
-
- * Initial release
diff --git a/CoAuthoring/node_modules/express/node_modules/accepts/node_modules/mime-types/LICENSE b/CoAuthoring/node_modules/express/node_modules/accepts/node_modules/mime-types/LICENSE
deleted file mode 100644
index a7ae8ee9b8..0000000000
--- a/CoAuthoring/node_modules/express/node_modules/accepts/node_modules/mime-types/LICENSE
+++ /dev/null
@@ -1,22 +0,0 @@
-
-The MIT License (MIT)
-
-Copyright (c) 2014 Jonathan Ong me@jongleberry.com
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in
-all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-THE SOFTWARE.
diff --git a/CoAuthoring/node_modules/express/node_modules/accepts/node_modules/mime-types/README.md b/CoAuthoring/node_modules/express/node_modules/accepts/node_modules/mime-types/README.md
deleted file mode 100644
index 99d658b8b3..0000000000
--- a/CoAuthoring/node_modules/express/node_modules/accepts/node_modules/mime-types/README.md
+++ /dev/null
@@ -1,99 +0,0 @@
-# mime-types
-
-[![NPM Version][npm-image]][npm-url]
-[![NPM Downloads][downloads-image]][downloads-url]
-[![Node.js Version][node-version-image]][node-version-url]
-[![Build Status][travis-image]][travis-url]
-[![Test Coverage][coveralls-image]][coveralls-url]
-
-The ultimate javascript content-type utility.
-
-Similar to [node-mime](https://github.com/broofa/node-mime), except:
-
-- __No fallbacks.__ Instead of naively returning the first available type, `mime-types` simply returns `false`,
- so do `var type = mime.lookup('unrecognized') || 'application/octet-stream'`.
-- No `new Mime()` business, so you could do `var lookup = require('mime-types').lookup`.
-- Additional mime types are added such as jade and stylus via [mime-db](https://github.com/jshttp/mime-db)
-- No `.define()` functionality
-
-Otherwise, the API is compatible.
-
-## Install
-
-```sh
-$ npm install mime-types
-```
-
-## Adding Types
-
-All mime types are based on [mime-db](https://github.com/jshttp/mime-db),
-so open a PR there if you'd like to add mime types.
-
-## API
-
-```js
-var mime = require('mime-types')
-```
-
-All functions return `false` if input is invalid or not found.
-
-### mime.lookup(path)
-
-Lookup the content-type associated with a file.
-
-```js
-mime.lookup('json') // 'application/json'
-mime.lookup('.md') // 'text/x-markdown'
-mime.lookup('file.html') // 'text/html'
-mime.lookup('folder/file.js') // 'application/javascript'
-
-mime.lookup('cats') // false
-```
-
-### mime.contentType(type)
-
-Create a full content-type header given a content-type or extension.
-
-```js
-mime.contentType('markdown') // 'text/x-markdown; charset=utf-8'
-mime.contentType('file.json') // 'application/json; charset=utf-8'
-```
-
-### mime.extension(type)
-
-Get the default extension for a content-type.
-
-```js
-mime.extension('application/octet-stream') // 'bin'
-```
-
-### mime.charset(type)
-
-Lookup the implied default charset of a content-type.
-
-```js
-mime.charset('text/x-markdown') // 'UTF-8'
-```
-
-### var type = mime.types[extension]
-
-A map of content-types by extension.
-
-### [extensions...] = mime.extensions[type]
-
-A map of extensions by content-type.
-
-## License
-
-[MIT](LICENSE)
-
-[npm-image]: https://img.shields.io/npm/v/mime-types.svg?style=flat
-[npm-url]: https://npmjs.org/package/mime-types
-[node-version-image]: https://img.shields.io/badge/node.js-%3E%3D_0.6-brightgreen.svg?style=flat
-[node-version-url]: http://nodejs.org/download/
-[travis-image]: https://img.shields.io/travis/jshttp/mime-types.svg?style=flat
-[travis-url]: https://travis-ci.org/jshttp/mime-types
-[coveralls-image]: https://img.shields.io/coveralls/jshttp/mime-types.svg?style=flat
-[coveralls-url]: https://coveralls.io/r/jshttp/mime-types
-[downloads-image]: https://img.shields.io/npm/dm/mime-types.svg?style=flat
-[downloads-url]: https://npmjs.org/package/mime-types
diff --git a/CoAuthoring/node_modules/express/node_modules/accepts/node_modules/mime-types/index.js b/CoAuthoring/node_modules/express/node_modules/accepts/node_modules/mime-types/index.js
deleted file mode 100644
index b46a202f53..0000000000
--- a/CoAuthoring/node_modules/express/node_modules/accepts/node_modules/mime-types/index.js
+++ /dev/null
@@ -1,63 +0,0 @@
-
-var db = require('mime-db')
-
-// types[extension] = type
-exports.types = Object.create(null)
-// extensions[type] = [extensions]
-exports.extensions = Object.create(null)
-
-Object.keys(db).forEach(function (name) {
- var mime = db[name]
- var exts = mime.extensions
- if (!exts || !exts.length) return
- exports.extensions[name] = exts
- exts.forEach(function (ext) {
- exports.types[ext] = name
- })
-})
-
-exports.lookup = function (string) {
- if (!string || typeof string !== "string") return false
- // remove any leading paths, though we should just use path.basename
- string = string.replace(/.*[\.\/\\]/, '').toLowerCase()
- if (!string) return false
- return exports.types[string] || false
-}
-
-exports.extension = function (type) {
- if (!type || typeof type !== "string") return false
- // to do: use media-typer
- type = type.match(/^\s*([^;\s]*)(?:;|\s|$)/)
- if (!type) return false
- var exts = exports.extensions[type[1].toLowerCase()]
- if (!exts || !exts.length) return false
- return exts[0]
-}
-
-// type has to be an exact mime type
-exports.charset = function (type) {
- var mime = db[type]
- if (mime && mime.charset) return mime.charset
-
- // default text/* to utf-8
- if (/^text\//.test(type)) return 'UTF-8'
-
- return false
-}
-
-// backwards compatibility
-exports.charsets = {
- lookup: exports.charset
-}
-
-// to do: maybe use set-type module or something
-exports.contentType = function (type) {
- if (!type || typeof type !== "string") return false
- if (!~type.indexOf('/')) type = exports.lookup(type)
- if (!type) return false
- if (!~type.indexOf('charset')) {
- var charset = exports.charset(type)
- if (charset) type += '; charset=' + charset.toLowerCase()
- }
- return type
-}
diff --git a/CoAuthoring/node_modules/express/node_modules/accepts/node_modules/mime-types/node_modules/mime-db/LICENSE b/CoAuthoring/node_modules/express/node_modules/accepts/node_modules/mime-types/node_modules/mime-db/LICENSE
deleted file mode 100644
index a7ae8ee9b8..0000000000
--- a/CoAuthoring/node_modules/express/node_modules/accepts/node_modules/mime-types/node_modules/mime-db/LICENSE
+++ /dev/null
@@ -1,22 +0,0 @@
-
-The MIT License (MIT)
-
-Copyright (c) 2014 Jonathan Ong me@jongleberry.com
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in
-all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-THE SOFTWARE.
diff --git a/CoAuthoring/node_modules/express/node_modules/accepts/node_modules/mime-types/node_modules/mime-db/README.md b/CoAuthoring/node_modules/express/node_modules/accepts/node_modules/mime-types/node_modules/mime-db/README.md
deleted file mode 100644
index 3b6364ebb8..0000000000
--- a/CoAuthoring/node_modules/express/node_modules/accepts/node_modules/mime-types/node_modules/mime-db/README.md
+++ /dev/null
@@ -1,72 +0,0 @@
-# mime-db
-
-[![NPM Version][npm-version-image]][npm-url]
-[![NPM Downloads][npm-downloads-image]][npm-url]
-[![Node.js Version][node-image]][node-url]
-[![Build Status][travis-image]][travis-url]
-[![Coverage Status][coveralls-image]][coveralls-url]
-
-This is a database of all mime types.
-It consistents of a single, public JSON file and does not include any logic,
-allowing it to remain as unopinionated as possible with an API.
-It aggregates data from the following sources:
-
-- http://www.iana.org/assignments/media-types/media-types.xhtml
-- http://svn.apache.org/repos/asf/httpd/httpd/trunk/docs/conf/mime.types
-
-## Usage
-
-```bash
-npm i mime-db
-```
-
-```js
-var db = require('mime-db');
-
-// grab data on .js files
-var data = db['application/javascript'];
-```
-
-If you're crazy enough to use this in the browser,
-you can just grab the JSON file:
-
-```
-https://cdn.rawgit.com/jshttp/mime-db/master/db.json
-```
-
-## Data Structure
-
-The JSON file is a map lookup for lowercased mime types.
-Each mime type has the following properties:
-
-- `.source` - where the mime type is defined.
- If not set, it's probably a custom media type.
- - `apache` - [Apache common media types](http://svn.apache.org/repos/asf/httpd/httpd/trunk/docs/conf/mime.types)
- - `iana` - [IANA-defined media types](http://www.iana.org/assignments/media-types/media-types.xhtml)
-- `.extensions[]` - known extensions associated with this mime type.
-- `.compressible` - whether a file of this type is can be gzipped.
-- `.charset` - the default charset associated with this type, if any.
-
-If unknown, every property could be `undefined`.
-
-## Repository Structure
-
-- `scripts` - these are scripts to run to build the database
-- `src/` - this is a folder of files created from remote sources like Apache and IANA
-- `lib/` - this is a folder of our own custom sources and db, which will be merged into `db.json`
-- `db.json` - the final built JSON file for end-user usage
-
-## Contributing
-
-To edit the database, only make PRs against files in the `lib/` folder.
-To update the build, run `npm run update`.
-
-[npm-version-image]: https://img.shields.io/npm/v/mime-db.svg?style=flat
-[npm-downloads-image]: https://img.shields.io/npm/dm/mime-db.svg?style=flat
-[npm-url]: https://npmjs.org/package/mime-db
-[travis-image]: https://img.shields.io/travis/jshttp/mime-db.svg?style=flat
-[travis-url]: https://travis-ci.org/jshttp/mime-db
-[coveralls-image]: https://img.shields.io/coveralls/jshttp/mime-db.svg?style=flat
-[coveralls-url]: https://coveralls.io/r/jshttp/mime-db?branch=master
-[node-image]: https://img.shields.io/node/v/mime-db.svg?style=flat
-[node-url]: http://nodejs.org/download/
diff --git a/CoAuthoring/node_modules/express/node_modules/accepts/node_modules/mime-types/node_modules/mime-db/db.json b/CoAuthoring/node_modules/express/node_modules/accepts/node_modules/mime-types/node_modules/mime-db/db.json
deleted file mode 100644
index 6887056691..0000000000
--- a/CoAuthoring/node_modules/express/node_modules/accepts/node_modules/mime-types/node_modules/mime-db/db.json
+++ /dev/null
@@ -1,6327 +0,0 @@
-{
- "application/1d-interleaved-parityfec": {
- "source": "iana"
- },
- "application/3gpdash-qoe-report+xml": {
- "source": "iana"
- },
- "application/3gpp-ims+xml": {
- "source": "iana"
- },
- "application/activemessage": {
- "source": "iana"
- },
- "application/alto-costmap+json": {
- "source": "iana",
- "compressible": true
- },
- "application/alto-costmapfilter+json": {
- "source": "iana",
- "compressible": true
- },
- "application/alto-directory+json": {
- "source": "iana",
- "compressible": true
- },
- "application/alto-endpointcost+json": {
- "source": "iana",
- "compressible": true
- },
- "application/alto-endpointcostparams+json": {
- "source": "iana",
- "compressible": true
- },
- "application/alto-endpointprop+json": {
- "source": "iana",
- "compressible": true
- },
- "application/alto-endpointpropparams+json": {
- "source": "iana",
- "compressible": true
- },
- "application/alto-error+json": {
- "source": "iana",
- "compressible": true
- },
- "application/alto-networkmap+json": {
- "source": "iana",
- "compressible": true
- },
- "application/alto-networkmapfilter+json": {
- "source": "iana",
- "compressible": true
- },
- "application/andrew-inset": {
- "source": "iana",
- "extensions": ["ez"]
- },
- "application/applefile": {
- "source": "iana"
- },
- "application/applixware": {
- "source": "apache",
- "extensions": ["aw"]
- },
- "application/atf": {
- "source": "iana"
- },
- "application/atom+xml": {
- "source": "iana",
- "compressible": true,
- "extensions": ["atom"]
- },
- "application/atomcat+xml": {
- "source": "iana",
- "extensions": ["atomcat"]
- },
- "application/atomdeleted+xml": {
- "source": "iana"
- },
- "application/atomicmail": {
- "source": "iana"
- },
- "application/atomsvc+xml": {
- "source": "iana",
- "extensions": ["atomsvc"]
- },
- "application/auth-policy+xml": {
- "source": "iana"
- },
- "application/bacnet-xdd+zip": {
- "source": "iana"
- },
- "application/batch-smtp": {
- "source": "iana"
- },
- "application/beep+xml": {
- "source": "iana"
- },
- "application/calendar+json": {
- "source": "iana",
- "compressible": true
- },
- "application/calendar+xml": {
- "source": "iana"
- },
- "application/call-completion": {
- "source": "iana"
- },
- "application/cals-1840": {
- "source": "iana"
- },
- "application/cbor": {
- "source": "iana"
- },
- "application/ccmp+xml": {
- "source": "iana"
- },
- "application/ccxml+xml": {
- "source": "iana",
- "extensions": ["ccxml"]
- },
- "application/cdmi-capability": {
- "source": "iana",
- "extensions": ["cdmia"]
- },
- "application/cdmi-container": {
- "source": "iana",
- "extensions": ["cdmic"]
- },
- "application/cdmi-domain": {
- "source": "iana",
- "extensions": ["cdmid"]
- },
- "application/cdmi-object": {
- "source": "iana",
- "extensions": ["cdmio"]
- },
- "application/cdmi-queue": {
- "source": "iana",
- "extensions": ["cdmiq"]
- },
- "application/cea-2018+xml": {
- "source": "iana"
- },
- "application/cellml+xml": {
- "source": "iana"
- },
- "application/cfw": {
- "source": "iana"
- },
- "application/cms": {
- "source": "iana"
- },
- "application/cnrp+xml": {
- "source": "iana"
- },
- "application/coap-group+json": {
- "source": "iana",
- "compressible": true
- },
- "application/commonground": {
- "source": "iana"
- },
- "application/conference-info+xml": {
- "source": "iana"
- },
- "application/cpl+xml": {
- "source": "iana"
- },
- "application/csrattrs": {
- "source": "iana"
- },
- "application/csta+xml": {
- "source": "iana"
- },
- "application/cstadata+xml": {
- "source": "iana"
- },
- "application/cu-seeme": {
- "source": "apache",
- "extensions": ["cu"]
- },
- "application/cybercash": {
- "source": "iana"
- },
- "application/dart": {
- "compressible": true
- },
- "application/dash+xml": {
- "source": "iana",
- "extensions": ["mdp"]
- },
- "application/dashdelta": {
- "source": "iana"
- },
- "application/davmount+xml": {
- "source": "iana",
- "extensions": ["davmount"]
- },
- "application/dca-rft": {
- "source": "iana"
- },
- "application/dcd": {
- "source": "iana"
- },
- "application/dec-dx": {
- "source": "iana"
- },
- "application/dialog-info+xml": {
- "source": "iana"
- },
- "application/dicom": {
- "source": "iana"
- },
- "application/dns": {
- "source": "iana"
- },
- "application/docbook+xml": {
- "source": "apache",
- "extensions": ["dbk"]
- },
- "application/dskpp+xml": {
- "source": "iana"
- },
- "application/dssc+der": {
- "source": "iana",
- "extensions": ["dssc"]
- },
- "application/dssc+xml": {
- "source": "iana",
- "extensions": ["xdssc"]
- },
- "application/dvcs": {
- "source": "iana"
- },
- "application/ecmascript": {
- "source": "iana",
- "compressible": true,
- "extensions": ["ecma"]
- },
- "application/edi-consent": {
- "source": "iana"
- },
- "application/edi-x12": {
- "source": "iana",
- "compressible": false
- },
- "application/edifact": {
- "source": "iana",
- "compressible": false
- },
- "application/emma+xml": {
- "source": "iana",
- "extensions": ["emma"]
- },
- "application/emotionml+xml": {
- "source": "iana"
- },
- "application/encaprtp": {
- "source": "iana"
- },
- "application/epp+xml": {
- "source": "iana"
- },
- "application/epub+zip": {
- "source": "apache",
- "extensions": ["epub"]
- },
- "application/eshop": {
- "source": "iana"
- },
- "application/example": {
- "source": "iana"
- },
- "application/exi": {
- "source": "iana",
- "extensions": ["exi"]
- },
- "application/fastinfoset": {
- "source": "iana"
- },
- "application/fastsoap": {
- "source": "iana"
- },
- "application/fdt+xml": {
- "source": "iana"
- },
- "application/fits": {
- "source": "iana"
- },
- "application/font-sfnt": {
- "source": "iana"
- },
- "application/font-tdpfr": {
- "source": "iana",
- "extensions": ["pfr"]
- },
- "application/font-woff": {
- "source": "iana",
- "compressible": false,
- "extensions": ["woff"]
- },
- "application/font-woff2": {
- "compressible": false,
- "extensions": ["woff2"]
- },
- "application/framework-attributes+xml": {
- "source": "iana"
- },
- "application/gml+xml": {
- "source": "apache",
- "extensions": ["gml"]
- },
- "application/gpx+xml": {
- "source": "apache",
- "extensions": ["gpx"]
- },
- "application/gxf": {
- "source": "apache",
- "extensions": ["gxf"]
- },
- "application/gzip": {
- "source": "iana",
- "compressible": false
- },
- "application/h224": {
- "source": "iana"
- },
- "application/held+xml": {
- "source": "iana"
- },
- "application/http": {
- "source": "iana"
- },
- "application/hyperstudio": {
- "source": "iana",
- "extensions": ["stk"]
- },
- "application/ibe-key-request+xml": {
- "source": "iana"
- },
- "application/ibe-pkg-reply+xml": {
- "source": "iana"
- },
- "application/ibe-pp-data": {
- "source": "iana"
- },
- "application/iges": {
- "source": "iana"
- },
- "application/im-iscomposing+xml": {
- "source": "iana"
- },
- "application/index": {
- "source": "iana"
- },
- "application/index.cmd": {
- "source": "iana"
- },
- "application/index.obj": {
- "source": "iana"
- },
- "application/index.response": {
- "source": "iana"
- },
- "application/index.vnd": {
- "source": "iana"
- },
- "application/inkml+xml": {
- "source": "iana",
- "extensions": ["ink","inkml"]
- },
- "application/iotp": {
- "source": "iana"
- },
- "application/ipfix": {
- "source": "iana",
- "extensions": ["ipfix"]
- },
- "application/ipp": {
- "source": "iana"
- },
- "application/isup": {
- "source": "iana"
- },
- "application/its+xml": {
- "source": "iana"
- },
- "application/java-archive": {
- "source": "apache",
- "compressible": false,
- "extensions": ["jar"]
- },
- "application/java-serialized-object": {
- "source": "apache",
- "compressible": false,
- "extensions": ["ser"]
- },
- "application/java-vm": {
- "source": "apache",
- "compressible": false,
- "extensions": ["class"]
- },
- "application/javascript": {
- "source": "iana",
- "charset": "UTF-8",
- "compressible": true,
- "extensions": ["js"]
- },
- "application/jrd+json": {
- "source": "iana",
- "compressible": true
- },
- "application/json": {
- "source": "iana",
- "charset": "UTF-8",
- "compressible": true,
- "extensions": ["json","map"]
- },
- "application/json-patch+json": {
- "source": "iana",
- "compressible": true
- },
- "application/jsonml+json": {
- "source": "apache",
- "compressible": true,
- "extensions": ["jsonml"]
- },
- "application/kpml-request+xml": {
- "source": "iana"
- },
- "application/kpml-response+xml": {
- "source": "iana"
- },
- "application/ld+json": {
- "source": "iana",
- "compressible": true
- },
- "application/link-format": {
- "source": "iana"
- },
- "application/load-control+xml": {
- "source": "iana"
- },
- "application/lost+xml": {
- "source": "iana",
- "extensions": ["lostxml"]
- },
- "application/lostsync+xml": {
- "source": "iana"
- },
- "application/mac-binhex40": {
- "source": "iana",
- "extensions": ["hqx"]
- },
- "application/mac-compactpro": {
- "source": "apache",
- "extensions": ["cpt"]
- },
- "application/macwriteii": {
- "source": "iana"
- },
- "application/mads+xml": {
- "source": "iana",
- "extensions": ["mads"]
- },
- "application/marc": {
- "source": "iana",
- "extensions": ["mrc"]
- },
- "application/marcxml+xml": {
- "source": "iana",
- "extensions": ["mrcx"]
- },
- "application/mathematica": {
- "source": "iana",
- "extensions": ["ma","nb","mb"]
- },
- "application/mathml+xml": {
- "source": "iana",
- "extensions": ["mathml"]
- },
- "application/mathml-content+xml": {
- "source": "iana"
- },
- "application/mathml-presentation+xml": {
- "source": "iana"
- },
- "application/mbms-associated-procedure-description+xml": {
- "source": "iana"
- },
- "application/mbms-deregister+xml": {
- "source": "iana"
- },
- "application/mbms-envelope+xml": {
- "source": "iana"
- },
- "application/mbms-msk+xml": {
- "source": "iana"
- },
- "application/mbms-msk-response+xml": {
- "source": "iana"
- },
- "application/mbms-protection-description+xml": {
- "source": "iana"
- },
- "application/mbms-reception-report+xml": {
- "source": "iana"
- },
- "application/mbms-register+xml": {
- "source": "iana"
- },
- "application/mbms-register-response+xml": {
- "source": "iana"
- },
- "application/mbms-schedule+xml": {
- "source": "iana"
- },
- "application/mbms-user-service-description+xml": {
- "source": "iana"
- },
- "application/mbox": {
- "source": "apache",
- "extensions": ["mbox"]
- },
- "application/mbox+xml": {
- "source": "iana"
- },
- "application/media-policy-dataset+xml": {
- "source": "iana"
- },
- "application/media_control+xml": {
- "source": "iana"
- },
- "application/mediaservercontrol+xml": {
- "source": "iana",
- "extensions": ["mscml"]
- },
- "application/merge-patch+json": {
- "source": "iana",
- "compressible": true
- },
- "application/metalink+xml": {
- "source": "apache",
- "extensions": ["metalink"]
- },
- "application/metalink4+xml": {
- "source": "iana",
- "extensions": ["meta4"]
- },
- "application/mets+xml": {
- "source": "iana",
- "extensions": ["mets"]
- },
- "application/mikey": {
- "source": "iana"
- },
- "application/mods+xml": {
- "source": "iana",
- "extensions": ["mods"]
- },
- "application/moss-keys": {
- "source": "iana"
- },
- "application/moss-signature": {
- "source": "iana"
- },
- "application/mosskey-data": {
- "source": "iana"
- },
- "application/mosskey-request": {
- "source": "iana"
- },
- "application/mp21": {
- "source": "iana",
- "extensions": ["m21","mp21"]
- },
- "application/mp4": {
- "source": "iana",
- "extensions": ["mp4s","m4p"]
- },
- "application/mpeg4-generic": {
- "source": "iana"
- },
- "application/mpeg4-iod": {
- "source": "iana"
- },
- "application/mpeg4-iod-xmt": {
- "source": "iana"
- },
- "application/mrb-consumer+xml": {
- "source": "iana"
- },
- "application/mrb-publish+xml": {
- "source": "iana"
- },
- "application/msc-ivr+xml": {
- "source": "iana"
- },
- "application/msc-mixer+xml": {
- "source": "iana"
- },
- "application/msword": {
- "source": "iana",
- "compressible": false,
- "extensions": ["doc","dot"]
- },
- "application/mxf": {
- "source": "iana",
- "extensions": ["mxf"]
- },
- "application/nasdata": {
- "source": "iana"
- },
- "application/news-checkgroups": {
- "source": "iana"
- },
- "application/news-groupinfo": {
- "source": "iana"
- },
- "application/news-transmission": {
- "source": "iana"
- },
- "application/nlsml+xml": {
- "source": "iana"
- },
- "application/nss": {
- "source": "iana"
- },
- "application/ocsp-request": {
- "source": "iana"
- },
- "application/ocsp-response": {
- "source": "apache"
- },
- "application/octet-stream": {
- "source": "iana",
- "compressible": false,
- "extensions": ["bin","dms","lrf","mar","so","dist","distz","pkg","bpk","dump","elc","deploy","buffer"]
- },
- "application/oda": {
- "source": "iana",
- "extensions": ["oda"]
- },
- "application/odx": {
- "source": "iana"
- },
- "application/oebps-package+xml": {
- "source": "iana",
- "extensions": ["opf"]
- },
- "application/ogg": {
- "source": "iana",
- "compressible": false,
- "extensions": ["ogx"]
- },
- "application/omdoc+xml": {
- "source": "apache",
- "extensions": ["omdoc"]
- },
- "application/onenote": {
- "source": "apache",
- "extensions": ["onetoc","onetoc2","onetmp","onepkg"]
- },
- "application/oscp-response": {
- "source": "iana"
- },
- "application/oxps": {
- "source": "iana",
- "extensions": ["oxps"]
- },
- "application/p2p-overlay+xml": {
- "source": "iana"
- },
- "application/parityfec": {
- "source": "iana"
- },
- "application/patch-ops-error+xml": {
- "source": "iana",
- "extensions": ["xer"]
- },
- "application/pdf": {
- "source": "iana",
- "compressible": false,
- "extensions": ["pdf"]
- },
- "application/pdx": {
- "source": "iana"
- },
- "application/pgp-encrypted": {
- "source": "iana",
- "compressible": false,
- "extensions": ["pgp"]
- },
- "application/pgp-keys": {
- "source": "iana"
- },
- "application/pgp-signature": {
- "source": "iana",
- "extensions": ["asc","sig"]
- },
- "application/pics-rules": {
- "source": "apache",
- "extensions": ["prf"]
- },
- "application/pidf+xml": {
- "source": "iana"
- },
- "application/pidf-diff+xml": {
- "source": "iana"
- },
- "application/pkcs10": {
- "source": "iana",
- "extensions": ["p10"]
- },
- "application/pkcs7-mime": {
- "source": "iana",
- "extensions": ["p7m","p7c"]
- },
- "application/pkcs7-signature": {
- "source": "iana",
- "extensions": ["p7s"]
- },
- "application/pkcs8": {
- "source": "iana",
- "extensions": ["p8"]
- },
- "application/pkix-attr-cert": {
- "source": "iana",
- "extensions": ["ac"]
- },
- "application/pkix-cert": {
- "source": "iana",
- "extensions": ["cer"]
- },
- "application/pkix-crl": {
- "source": "iana",
- "extensions": ["crl"]
- },
- "application/pkix-pkipath": {
- "source": "iana",
- "extensions": ["pkipath"]
- },
- "application/pkixcmp": {
- "source": "iana",
- "extensions": ["pki"]
- },
- "application/pls+xml": {
- "source": "iana",
- "extensions": ["pls"]
- },
- "application/poc-settings+xml": {
- "source": "iana"
- },
- "application/postscript": {
- "source": "iana",
- "compressible": true,
- "extensions": ["ai","eps","ps"]
- },
- "application/provenance+xml": {
- "source": "iana"
- },
- "application/prs.alvestrand.titrax-sheet": {
- "source": "iana"
- },
- "application/prs.cww": {
- "source": "iana",
- "extensions": ["cww"]
- },
- "application/prs.hpub+zip": {
- "source": "iana"
- },
- "application/prs.nprend": {
- "source": "iana"
- },
- "application/prs.plucker": {
- "source": "iana"
- },
- "application/prs.rdf-xml-crypt": {
- "source": "iana"
- },
- "application/prs.xsf+xml": {
- "source": "iana"
- },
- "application/pskc+xml": {
- "source": "iana",
- "extensions": ["pskcxml"]
- },
- "application/qsig": {
- "source": "iana"
- },
- "application/raptorfec": {
- "source": "iana"
- },
- "application/rdf+xml": {
- "source": "iana",
- "compressible": true,
- "extensions": ["rdf"]
- },
- "application/reginfo+xml": {
- "source": "iana",
- "extensions": ["rif"]
- },
- "application/relax-ng-compact-syntax": {
- "source": "iana",
- "extensions": ["rnc"]
- },
- "application/remote-printing": {
- "source": "iana"
- },
- "application/reputon+json": {
- "source": "iana",
- "compressible": true
- },
- "application/resource-lists+xml": {
- "source": "iana",
- "extensions": ["rl"]
- },
- "application/resource-lists-diff+xml": {
- "source": "iana",
- "extensions": ["rld"]
- },
- "application/riscos": {
- "source": "iana"
- },
- "application/rlmi+xml": {
- "source": "iana"
- },
- "application/rls-services+xml": {
- "source": "iana",
- "extensions": ["rs"]
- },
- "application/rpki-ghostbusters": {
- "source": "iana",
- "extensions": ["gbr"]
- },
- "application/rpki-manifest": {
- "source": "iana",
- "extensions": ["mft"]
- },
- "application/rpki-roa": {
- "source": "iana",
- "extensions": ["roa"]
- },
- "application/rpki-updown": {
- "source": "iana"
- },
- "application/rsd+xml": {
- "source": "apache",
- "extensions": ["rsd"]
- },
- "application/rss+xml": {
- "source": "apache",
- "compressible": true,
- "extensions": ["rss"]
- },
- "application/rtf": {
- "source": "iana",
- "compressible": true,
- "extensions": ["rtf"]
- },
- "application/rtploopback": {
- "source": "iana"
- },
- "application/rtx": {
- "source": "iana"
- },
- "application/samlassertion+xml": {
- "source": "iana"
- },
- "application/samlmetadata+xml": {
- "source": "iana"
- },
- "application/sbml+xml": {
- "source": "iana",
- "extensions": ["sbml"]
- },
- "application/scaip+xml": {
- "source": "iana"
- },
- "application/scvp-cv-request": {
- "source": "iana",
- "extensions": ["scq"]
- },
- "application/scvp-cv-response": {
- "source": "iana",
- "extensions": ["scs"]
- },
- "application/scvp-vp-request": {
- "source": "iana",
- "extensions": ["spq"]
- },
- "application/scvp-vp-response": {
- "source": "iana",
- "extensions": ["spp"]
- },
- "application/sdp": {
- "source": "iana",
- "extensions": ["sdp"]
- },
- "application/sep+xml": {
- "source": "iana"
- },
- "application/sep-exi": {
- "source": "iana"
- },
- "application/session-info": {
- "source": "iana"
- },
- "application/set-payment": {
- "source": "iana"
- },
- "application/set-payment-initiation": {
- "source": "iana",
- "extensions": ["setpay"]
- },
- "application/set-registration": {
- "source": "iana"
- },
- "application/set-registration-initiation": {
- "source": "iana",
- "extensions": ["setreg"]
- },
- "application/sgml": {
- "source": "iana"
- },
- "application/sgml-open-catalog": {
- "source": "iana"
- },
- "application/shf+xml": {
- "source": "iana",
- "extensions": ["shf"]
- },
- "application/sieve": {
- "source": "iana"
- },
- "application/simple-filter+xml": {
- "source": "iana"
- },
- "application/simple-message-summary": {
- "source": "iana"
- },
- "application/simplesymbolcontainer": {
- "source": "iana"
- },
- "application/slate": {
- "source": "iana"
- },
- "application/smil": {
- "source": "iana"
- },
- "application/smil+xml": {
- "source": "iana",
- "extensions": ["smi","smil"]
- },
- "application/smpte336m": {
- "source": "iana"
- },
- "application/soap+fastinfoset": {
- "source": "iana"
- },
- "application/soap+xml": {
- "source": "iana",
- "compressible": true
- },
- "application/sparql-query": {
- "source": "iana",
- "extensions": ["rq"]
- },
- "application/sparql-results+xml": {
- "source": "iana",
- "extensions": ["srx"]
- },
- "application/spirits-event+xml": {
- "source": "iana"
- },
- "application/sql": {
- "source": "iana"
- },
- "application/srgs": {
- "source": "iana",
- "extensions": ["gram"]
- },
- "application/srgs+xml": {
- "source": "iana",
- "extensions": ["grxml"]
- },
- "application/sru+xml": {
- "source": "iana",
- "extensions": ["sru"]
- },
- "application/ssdl+xml": {
- "source": "apache",
- "extensions": ["ssdl"]
- },
- "application/ssml+xml": {
- "source": "iana",
- "extensions": ["ssml"]
- },
- "application/tamp-apex-update": {
- "source": "iana"
- },
- "application/tamp-apex-update-confirm": {
- "source": "iana"
- },
- "application/tamp-community-update": {
- "source": "iana"
- },
- "application/tamp-community-update-confirm": {
- "source": "iana"
- },
- "application/tamp-error": {
- "source": "iana"
- },
- "application/tamp-sequence-adjust": {
- "source": "iana"
- },
- "application/tamp-sequence-adjust-confirm": {
- "source": "iana"
- },
- "application/tamp-status-query": {
- "source": "iana"
- },
- "application/tamp-status-response": {
- "source": "iana"
- },
- "application/tamp-update": {
- "source": "iana"
- },
- "application/tamp-update-confirm": {
- "source": "iana"
- },
- "application/tar": {
- "compressible": true
- },
- "application/tei+xml": {
- "source": "iana",
- "extensions": ["tei","teicorpus"]
- },
- "application/thraud+xml": {
- "source": "iana",
- "extensions": ["tfi"]
- },
- "application/timestamp-query": {
- "source": "iana"
- },
- "application/timestamp-reply": {
- "source": "iana"
- },
- "application/timestamped-data": {
- "source": "iana",
- "extensions": ["tsd"]
- },
- "application/ttml+xml": {
- "source": "iana"
- },
- "application/tve-trigger": {
- "source": "iana"
- },
- "application/ulpfec": {
- "source": "iana"
- },
- "application/urc-grpsheet+xml": {
- "source": "iana"
- },
- "application/urc-ressheet+xml": {
- "source": "iana"
- },
- "application/urc-targetdesc+xml": {
- "source": "iana"
- },
- "application/urc-uisocketdesc+xml": {
- "source": "iana"
- },
- "application/vcard+json": {
- "source": "iana",
- "compressible": true
- },
- "application/vcard+xml": {
- "source": "iana"
- },
- "application/vemmi": {
- "source": "iana"
- },
- "application/vividence.scriptfile": {
- "source": "apache"
- },
- "application/vnd-acucobol": {
- "source": "iana"
- },
- "application/vnd-curl": {
- "source": "iana"
- },
- "application/vnd-dart": {
- "source": "iana"
- },
- "application/vnd-dxr": {
- "source": "iana"
- },
- "application/vnd-fdf": {
- "source": "iana"
- },
- "application/vnd-mif": {
- "source": "iana"
- },
- "application/vnd-sema": {
- "source": "iana"
- },
- "application/vnd-wap-wmlc": {
- "source": "iana"
- },
- "application/vnd.3gpp.bsf+xml": {
- "source": "iana"
- },
- "application/vnd.3gpp.pic-bw-large": {
- "source": "iana",
- "extensions": ["plb"]
- },
- "application/vnd.3gpp.pic-bw-small": {
- "source": "iana",
- "extensions": ["psb"]
- },
- "application/vnd.3gpp.pic-bw-var": {
- "source": "iana",
- "extensions": ["pvb"]
- },
- "application/vnd.3gpp.sms": {
- "source": "iana"
- },
- "application/vnd.3gpp2.bcmcsinfo+xml": {
- "source": "iana"
- },
- "application/vnd.3gpp2.sms": {
- "source": "iana"
- },
- "application/vnd.3gpp2.tcap": {
- "source": "iana",
- "extensions": ["tcap"]
- },
- "application/vnd.3m.post-it-notes": {
- "source": "iana",
- "extensions": ["pwn"]
- },
- "application/vnd.accpac.simply.aso": {
- "source": "iana",
- "extensions": ["aso"]
- },
- "application/vnd.accpac.simply.imp": {
- "source": "iana",
- "extensions": ["imp"]
- },
- "application/vnd.acucobol": {
- "source": "apache",
- "extensions": ["acu"]
- },
- "application/vnd.acucorp": {
- "source": "iana",
- "extensions": ["atc","acutc"]
- },
- "application/vnd.adobe.air-application-installer-package+zip": {
- "source": "apache",
- "extensions": ["air"]
- },
- "application/vnd.adobe.flash-movie": {
- "source": "iana"
- },
- "application/vnd.adobe.formscentral.fcdt": {
- "source": "iana",
- "extensions": ["fcdt"]
- },
- "application/vnd.adobe.fxp": {
- "source": "iana",
- "extensions": ["fxp","fxpl"]
- },
- "application/vnd.adobe.partial-upload": {
- "source": "iana"
- },
- "application/vnd.adobe.xdp+xml": {
- "source": "iana",
- "extensions": ["xdp"]
- },
- "application/vnd.adobe.xfdf": {
- "source": "iana",
- "extensions": ["xfdf"]
- },
- "application/vnd.aether.imp": {
- "source": "iana"
- },
- "application/vnd.ah-barcode": {
- "source": "iana"
- },
- "application/vnd.ahead.space": {
- "source": "iana",
- "extensions": ["ahead"]
- },
- "application/vnd.airzip.filesecure.azf": {
- "source": "iana",
- "extensions": ["azf"]
- },
- "application/vnd.airzip.filesecure.azs": {
- "source": "iana",
- "extensions": ["azs"]
- },
- "application/vnd.amazon.ebook": {
- "source": "apache",
- "extensions": ["azw"]
- },
- "application/vnd.americandynamics.acc": {
- "source": "iana",
- "extensions": ["acc"]
- },
- "application/vnd.amiga.ami": {
- "source": "iana",
- "extensions": ["ami"]
- },
- "application/vnd.amundsen.maze+xml": {
- "source": "iana"
- },
- "application/vnd.android.package-archive": {
- "source": "apache",
- "compressible": false,
- "extensions": ["apk"]
- },
- "application/vnd.anser-web-certificate-issue-initiation": {
- "source": "iana",
- "extensions": ["cii"]
- },
- "application/vnd.anser-web-funds-transfer-initiation": {
- "source": "apache",
- "extensions": ["fti"]
- },
- "application/vnd.antix.game-component": {
- "source": "iana",
- "extensions": ["atx"]
- },
- "application/vnd.apache.thrift.binary": {
- "source": "iana"
- },
- "application/vnd.api+json": {
- "source": "iana",
- "compressible": true
- },
- "application/vnd.apple.installer+xml": {
- "source": "iana",
- "extensions": ["mpkg"]
- },
- "application/vnd.apple.mpegurl": {
- "source": "iana",
- "extensions": ["m3u8"]
- },
- "application/vnd.arastra.swi": {
- "source": "iana"
- },
- "application/vnd.aristanetworks.swi": {
- "source": "iana",
- "extensions": ["swi"]
- },
- "application/vnd.artsquare": {
- "source": "iana"
- },
- "application/vnd.astraea-software.iota": {
- "source": "iana",
- "extensions": ["iota"]
- },
- "application/vnd.audiograph": {
- "source": "iana",
- "extensions": ["aep"]
- },
- "application/vnd.autopackage": {
- "source": "iana"
- },
- "application/vnd.avistar+xml": {
- "source": "iana"
- },
- "application/vnd.balsamiq.bmml+xml": {
- "source": "iana"
- },
- "application/vnd.bekitzur-stech+json": {
- "source": "iana",
- "compressible": true
- },
- "application/vnd.blueice.multipass": {
- "source": "iana",
- "extensions": ["mpm"]
- },
- "application/vnd.bluetooth.ep.oob": {
- "source": "iana"
- },
- "application/vnd.bluetooth.le.oob": {
- "source": "iana"
- },
- "application/vnd.bmi": {
- "source": "iana",
- "extensions": ["bmi"]
- },
- "application/vnd.businessobjects": {
- "source": "iana",
- "extensions": ["rep"]
- },
- "application/vnd.cab-jscript": {
- "source": "iana"
- },
- "application/vnd.canon-cpdl": {
- "source": "iana"
- },
- "application/vnd.canon-lips": {
- "source": "iana"
- },
- "application/vnd.cendio.thinlinc.clientconf": {
- "source": "iana"
- },
- "application/vnd.century-systems.tcp_stream": {
- "source": "iana"
- },
- "application/vnd.chemdraw+xml": {
- "source": "iana",
- "extensions": ["cdxml"]
- },
- "application/vnd.chipnuts.karaoke-mmd": {
- "source": "iana",
- "extensions": ["mmd"]
- },
- "application/vnd.cinderella": {
- "source": "iana",
- "extensions": ["cdy"]
- },
- "application/vnd.cirpack.isdn-ext": {
- "source": "iana"
- },
- "application/vnd.claymore": {
- "source": "iana",
- "extensions": ["cla"]
- },
- "application/vnd.cloanto.rp9": {
- "source": "iana",
- "extensions": ["rp9"]
- },
- "application/vnd.clonk.c4group": {
- "source": "iana",
- "extensions": ["c4g","c4d","c4f","c4p","c4u"]
- },
- "application/vnd.cluetrust.cartomobile-config": {
- "source": "iana",
- "extensions": ["c11amc"]
- },
- "application/vnd.cluetrust.cartomobile-config-pkg": {
- "source": "iana",
- "extensions": ["c11amz"]
- },
- "application/vnd.collection+json": {
- "source": "iana",
- "compressible": true
- },
- "application/vnd.collection.doc+json": {
- "source": "iana",
- "compressible": true
- },
- "application/vnd.collection.next+json": {
- "source": "iana",
- "compressible": true
- },
- "application/vnd.commerce-battelle": {
- "source": "iana"
- },
- "application/vnd.commonspace": {
- "source": "iana",
- "extensions": ["csp"]
- },
- "application/vnd.contact.cmsg": {
- "source": "iana",
- "extensions": ["cdbcmsg"]
- },
- "application/vnd.cosmocaller": {
- "source": "iana",
- "extensions": ["cmc"]
- },
- "application/vnd.crick.clicker": {
- "source": "iana",
- "extensions": ["clkx"]
- },
- "application/vnd.crick.clicker.keyboard": {
- "source": "iana",
- "extensions": ["clkk"]
- },
- "application/vnd.crick.clicker.palette": {
- "source": "iana",
- "extensions": ["clkp"]
- },
- "application/vnd.crick.clicker.template": {
- "source": "iana",
- "extensions": ["clkt"]
- },
- "application/vnd.crick.clicker.wordbank": {
- "source": "iana",
- "extensions": ["clkw"]
- },
- "application/vnd.criticaltools.wbs+xml": {
- "source": "iana",
- "extensions": ["wbs"]
- },
- "application/vnd.ctc-posml": {
- "source": "iana",
- "extensions": ["pml"]
- },
- "application/vnd.ctct.ws+xml": {
- "source": "iana"
- },
- "application/vnd.cups-pdf": {
- "source": "iana"
- },
- "application/vnd.cups-postscript": {
- "source": "iana"
- },
- "application/vnd.cups-ppd": {
- "source": "iana",
- "extensions": ["ppd"]
- },
- "application/vnd.cups-raster": {
- "source": "iana"
- },
- "application/vnd.cups-raw": {
- "source": "iana"
- },
- "application/vnd.curl": {
- "source": "apache"
- },
- "application/vnd.curl.car": {
- "source": "apache",
- "extensions": ["car"]
- },
- "application/vnd.curl.pcurl": {
- "source": "apache",
- "extensions": ["pcurl"]
- },
- "application/vnd.cyan.dean.root+xml": {
- "source": "iana"
- },
- "application/vnd.cybank": {
- "source": "iana"
- },
- "application/vnd.dart": {
- "source": "apache",
- "compressible": true,
- "extensions": ["dart"]
- },
- "application/vnd.data-vision.rdz": {
- "source": "iana",
- "extensions": ["rdz"]
- },
- "application/vnd.debian.binary-package": {
- "source": "iana"
- },
- "application/vnd.dece-zip": {
- "source": "iana"
- },
- "application/vnd.dece.data": {
- "source": "iana",
- "extensions": ["uvf","uvvf","uvd","uvvd"]
- },
- "application/vnd.dece.ttml+xml": {
- "source": "iana",
- "extensions": ["uvt","uvvt"]
- },
- "application/vnd.dece.unspecified": {
- "source": "iana",
- "extensions": ["uvx","uvvx"]
- },
- "application/vnd.dece.zip": {
- "source": "apache",
- "extensions": ["uvz","uvvz"]
- },
- "application/vnd.denovo.fcselayout-link": {
- "source": "iana",
- "extensions": ["fe_launch"]
- },
- "application/vnd.desmume-movie": {
- "source": "iana"
- },
- "application/vnd.dir-bi.plate-dl-nosuffix": {
- "source": "iana"
- },
- "application/vnd.dm.delegation+xml": {
- "source": "iana"
- },
- "application/vnd.dna": {
- "source": "iana",
- "extensions": ["dna"]
- },
- "application/vnd.document+json": {
- "source": "iana",
- "compressible": true
- },
- "application/vnd.dolby.mlp": {
- "source": "apache",
- "extensions": ["mlp"]
- },
- "application/vnd.dolby.mobile.1": {
- "source": "iana"
- },
- "application/vnd.dolby.mobile.2": {
- "source": "iana"
- },
- "application/vnd.doremir.scorecloud-binary-document": {
- "source": "iana"
- },
- "application/vnd.dpgraph": {
- "source": "iana",
- "extensions": ["dpg"]
- },
- "application/vnd.dreamfactory": {
- "source": "iana",
- "extensions": ["dfac"]
- },
- "application/vnd.ds-keypoint": {
- "source": "apache",
- "extensions": ["kpxx"]
- },
- "application/vnd.dtg.local": {
- "source": "iana"
- },
- "application/vnd.dtg.local.flash": {
- "source": "iana"
- },
- "application/vnd.dtg.local.html": {
- "source": "iana"
- },
- "application/vnd.dvb.ait": {
- "source": "iana",
- "extensions": ["ait"]
- },
- "application/vnd.dvb.dvbj": {
- "source": "iana"
- },
- "application/vnd.dvb.esgcontainer": {
- "source": "iana"
- },
- "application/vnd.dvb.ipdcdftnotifaccess": {
- "source": "iana"
- },
- "application/vnd.dvb.ipdcesgaccess": {
- "source": "iana"
- },
- "application/vnd.dvb.ipdcesgaccess2": {
- "source": "iana"
- },
- "application/vnd.dvb.ipdcesgpdd": {
- "source": "iana"
- },
- "application/vnd.dvb.ipdcroaming": {
- "source": "iana"
- },
- "application/vnd.dvb.iptv.alfec-base": {
- "source": "iana"
- },
- "application/vnd.dvb.iptv.alfec-enhancement": {
- "source": "iana"
- },
- "application/vnd.dvb.notif-aggregate-root+xml": {
- "source": "iana"
- },
- "application/vnd.dvb.notif-container+xml": {
- "source": "iana"
- },
- "application/vnd.dvb.notif-generic+xml": {
- "source": "iana"
- },
- "application/vnd.dvb.notif-ia-msglist+xml": {
- "source": "iana"
- },
- "application/vnd.dvb.notif-ia-registration-request+xml": {
- "source": "iana"
- },
- "application/vnd.dvb.notif-ia-registration-response+xml": {
- "source": "iana"
- },
- "application/vnd.dvb.notif-init+xml": {
- "source": "iana"
- },
- "application/vnd.dvb.pfr": {
- "source": "iana"
- },
- "application/vnd.dvb.service": {
- "source": "apache",
- "extensions": ["svc"]
- },
- "application/vnd.dvb_service": {
- "source": "iana"
- },
- "application/vnd.dxr": {
- "source": "apache"
- },
- "application/vnd.dynageo": {
- "source": "iana",
- "extensions": ["geo"]
- },
- "application/vnd.dzr": {
- "source": "iana"
- },
- "application/vnd.easykaraoke.cdgdownload": {
- "source": "iana"
- },
- "application/vnd.ecdis-update": {
- "source": "iana"
- },
- "application/vnd.ecowin.chart": {
- "source": "iana",
- "extensions": ["mag"]
- },
- "application/vnd.ecowin.filerequest": {
- "source": "iana"
- },
- "application/vnd.ecowin.fileupdate": {
- "source": "iana"
- },
- "application/vnd.ecowin.series": {
- "source": "iana"
- },
- "application/vnd.ecowin.seriesrequest": {
- "source": "iana"
- },
- "application/vnd.ecowin.seriesupdate": {
- "source": "iana"
- },
- "application/vnd.emclient.accessrequest+xml": {
- "source": "iana"
- },
- "application/vnd.enliven": {
- "source": "iana",
- "extensions": ["nml"]
- },
- "application/vnd.eprints.data+xml": {
- "source": "iana"
- },
- "application/vnd.epson.esf": {
- "source": "iana",
- "extensions": ["esf"]
- },
- "application/vnd.epson.msf": {
- "source": "iana",
- "extensions": ["msf"]
- },
- "application/vnd.epson.quickanime": {
- "source": "iana",
- "extensions": ["qam"]
- },
- "application/vnd.epson.salt": {
- "source": "iana",
- "extensions": ["slt"]
- },
- "application/vnd.epson.ssf": {
- "source": "iana",
- "extensions": ["ssf"]
- },
- "application/vnd.ericsson.quickcall": {
- "source": "iana"
- },
- "application/vnd.eszigno3+xml": {
- "source": "iana",
- "extensions": ["es3","et3"]
- },
- "application/vnd.etsi.aoc+xml": {
- "source": "iana"
- },
- "application/vnd.etsi.asic-e+zip": {
- "source": "iana"
- },
- "application/vnd.etsi.asic-s+zip": {
- "source": "iana"
- },
- "application/vnd.etsi.cug+xml": {
- "source": "iana"
- },
- "application/vnd.etsi.iptvcommand+xml": {
- "source": "iana"
- },
- "application/vnd.etsi.iptvdiscovery+xml": {
- "source": "iana"
- },
- "application/vnd.etsi.iptvprofile+xml": {
- "source": "iana"
- },
- "application/vnd.etsi.iptvsad-bc+xml": {
- "source": "iana"
- },
- "application/vnd.etsi.iptvsad-cod+xml": {
- "source": "iana"
- },
- "application/vnd.etsi.iptvsad-npvr+xml": {
- "source": "iana"
- },
- "application/vnd.etsi.iptvservice+xml": {
- "source": "iana"
- },
- "application/vnd.etsi.iptvsync+xml": {
- "source": "iana"
- },
- "application/vnd.etsi.iptvueprofile+xml": {
- "source": "iana"
- },
- "application/vnd.etsi.mcid+xml": {
- "source": "iana"
- },
- "application/vnd.etsi.mheg5": {
- "source": "iana"
- },
- "application/vnd.etsi.overload-control-policy-dataset+xml": {
- "source": "iana"
- },
- "application/vnd.etsi.pstn+xml": {
- "source": "iana"
- },
- "application/vnd.etsi.sci+xml": {
- "source": "iana"
- },
- "application/vnd.etsi.simservs+xml": {
- "source": "iana"
- },
- "application/vnd.etsi.timestamp-token": {
- "source": "iana"
- },
- "application/vnd.etsi.tsl+xml": {
- "source": "iana"
- },
- "application/vnd.etsi.tsl.der": {
- "source": "iana"
- },
- "application/vnd.eudora.data": {
- "source": "iana"
- },
- "application/vnd.ezpix-album": {
- "source": "iana",
- "extensions": ["ez2"]
- },
- "application/vnd.ezpix-package": {
- "source": "iana",
- "extensions": ["ez3"]
- },
- "application/vnd.f-secure.mobile": {
- "source": "iana"
- },
- "application/vnd.fdf": {
- "source": "apache",
- "extensions": ["fdf"]
- },
- "application/vnd.fdsn.mseed": {
- "source": "iana",
- "extensions": ["mseed"]
- },
- "application/vnd.fdsn.seed": {
- "source": "iana",
- "extensions": ["seed","dataless"]
- },
- "application/vnd.ffsns": {
- "source": "iana"
- },
- "application/vnd.fints": {
- "source": "iana"
- },
- "application/vnd.flographit": {
- "source": "iana",
- "extensions": ["gph"]
- },
- "application/vnd.fluxtime.clip": {
- "source": "iana",
- "extensions": ["ftc"]
- },
- "application/vnd.font-fontforge-sfd": {
- "source": "iana"
- },
- "application/vnd.framemaker": {
- "source": "iana",
- "extensions": ["fm","frame","maker","book"]
- },
- "application/vnd.frogans.fnc": {
- "source": "iana",
- "extensions": ["fnc"]
- },
- "application/vnd.frogans.ltf": {
- "source": "iana",
- "extensions": ["ltf"]
- },
- "application/vnd.fsc.weblaunch": {
- "source": "iana",
- "extensions": ["fsc"]
- },
- "application/vnd.fujitsu.oasys": {
- "source": "iana",
- "extensions": ["oas"]
- },
- "application/vnd.fujitsu.oasys2": {
- "source": "iana",
- "extensions": ["oa2"]
- },
- "application/vnd.fujitsu.oasys3": {
- "source": "iana",
- "extensions": ["oa3"]
- },
- "application/vnd.fujitsu.oasysgp": {
- "source": "iana",
- "extensions": ["fg5"]
- },
- "application/vnd.fujitsu.oasysprs": {
- "source": "iana",
- "extensions": ["bh2"]
- },
- "application/vnd.fujixerox.art-ex": {
- "source": "iana"
- },
- "application/vnd.fujixerox.art4": {
- "source": "iana"
- },
- "application/vnd.fujixerox.ddd": {
- "source": "iana",
- "extensions": ["ddd"]
- },
- "application/vnd.fujixerox.docuworks": {
- "source": "iana",
- "extensions": ["xdw"]
- },
- "application/vnd.fujixerox.docuworks.binder": {
- "source": "iana",
- "extensions": ["xbd"]
- },
- "application/vnd.fujixerox.docuworks.container": {
- "source": "iana"
- },
- "application/vnd.fujixerox.hbpl": {
- "source": "iana"
- },
- "application/vnd.fut-misnet": {
- "source": "iana"
- },
- "application/vnd.fuzzysheet": {
- "source": "iana",
- "extensions": ["fzs"]
- },
- "application/vnd.genomatix.tuxedo": {
- "source": "iana",
- "extensions": ["txd"]
- },
- "application/vnd.geo+json": {
- "source": "iana",
- "compressible": true
- },
- "application/vnd.geocube+xml": {
- "source": "iana"
- },
- "application/vnd.geogebra.file": {
- "source": "iana",
- "extensions": ["ggb"]
- },
- "application/vnd.geogebra.tool": {
- "source": "iana",
- "extensions": ["ggt"]
- },
- "application/vnd.geometry-explorer": {
- "source": "iana",
- "extensions": ["gex","gre"]
- },
- "application/vnd.geonext": {
- "source": "iana",
- "extensions": ["gxt"]
- },
- "application/vnd.geoplan": {
- "source": "iana",
- "extensions": ["g2w"]
- },
- "application/vnd.geospace": {
- "source": "iana",
- "extensions": ["g3w"]
- },
- "application/vnd.globalplatform.card-content-mgt": {
- "source": "iana"
- },
- "application/vnd.globalplatform.card-content-mgt-response": {
- "source": "iana"
- },
- "application/vnd.gmx": {
- "source": "iana",
- "extensions": ["gmx"]
- },
- "application/vnd.google-earth.kml+xml": {
- "source": "iana",
- "compressible": true,
- "extensions": ["kml"]
- },
- "application/vnd.google-earth.kmz": {
- "source": "iana",
- "compressible": false,
- "extensions": ["kmz"]
- },
- "application/vnd.grafeq": {
- "source": "iana",
- "extensions": ["gqf","gqs"]
- },
- "application/vnd.gridmp": {
- "source": "iana"
- },
- "application/vnd.groove-account": {
- "source": "iana",
- "extensions": ["gac"]
- },
- "application/vnd.groove-help": {
- "source": "iana",
- "extensions": ["ghf"]
- },
- "application/vnd.groove-identity-message": {
- "source": "iana",
- "extensions": ["gim"]
- },
- "application/vnd.groove-injector": {
- "source": "iana",
- "extensions": ["grv"]
- },
- "application/vnd.groove-tool-message": {
- "source": "iana",
- "extensions": ["gtm"]
- },
- "application/vnd.groove-tool-template": {
- "source": "iana",
- "extensions": ["tpl"]
- },
- "application/vnd.groove-vcard": {
- "source": "iana",
- "extensions": ["vcg"]
- },
- "application/vnd.hal+json": {
- "source": "iana",
- "compressible": true
- },
- "application/vnd.hal+xml": {
- "source": "iana",
- "extensions": ["hal"]
- },
- "application/vnd.handheld-entertainment+xml": {
- "source": "iana",
- "extensions": ["zmm"]
- },
- "application/vnd.hbci": {
- "source": "iana",
- "extensions": ["hbci"]
- },
- "application/vnd.hcl-bireports": {
- "source": "iana"
- },
- "application/vnd.heroku+json": {
- "source": "iana",
- "compressible": true
- },
- "application/vnd.hhe.lesson-player": {
- "source": "iana",
- "extensions": ["les"]
- },
- "application/vnd.hp-hpgl": {
- "source": "iana",
- "extensions": ["hpgl"]
- },
- "application/vnd.hp-hpid": {
- "source": "iana",
- "extensions": ["hpid"]
- },
- "application/vnd.hp-hps": {
- "source": "iana",
- "extensions": ["hps"]
- },
- "application/vnd.hp-jlyt": {
- "source": "iana",
- "extensions": ["jlt"]
- },
- "application/vnd.hp-pcl": {
- "source": "iana",
- "extensions": ["pcl"]
- },
- "application/vnd.hp-pclxl": {
- "source": "iana",
- "extensions": ["pclxl"]
- },
- "application/vnd.httphone": {
- "source": "iana"
- },
- "application/vnd.hydrostatix.sof-data": {
- "source": "iana"
- },
- "application/vnd.hzn-3d-crossword": {
- "source": "iana"
- },
- "application/vnd.ibm.afplinedata": {
- "source": "iana"
- },
- "application/vnd.ibm.electronic-media": {
- "source": "iana"
- },
- "application/vnd.ibm.minipay": {
- "source": "iana",
- "extensions": ["mpy"]
- },
- "application/vnd.ibm.modcap": {
- "source": "iana",
- "extensions": ["afp","listafp","list3820"]
- },
- "application/vnd.ibm.rights-management": {
- "source": "iana",
- "extensions": ["irm"]
- },
- "application/vnd.ibm.secure-container": {
- "source": "iana",
- "extensions": ["sc"]
- },
- "application/vnd.iccprofile": {
- "source": "iana",
- "extensions": ["icc","icm"]
- },
- "application/vnd.ieee.1905": {
- "source": "iana"
- },
- "application/vnd.igloader": {
- "source": "iana",
- "extensions": ["igl"]
- },
- "application/vnd.immervision-ivp": {
- "source": "iana",
- "extensions": ["ivp"]
- },
- "application/vnd.immervision-ivu": {
- "source": "iana",
- "extensions": ["ivu"]
- },
- "application/vnd.ims.lis.v2.result+json": {
- "source": "iana",
- "compressible": true
- },
- "application/vnd.ims.lti.v2.toolconsumerprofile+json": {
- "source": "iana",
- "compressible": true
- },
- "application/vnd.ims.lti.v2.toolproxy+json": {
- "source": "iana",
- "compressible": true
- },
- "application/vnd.ims.lti.v2.toolproxy.id+json": {
- "source": "iana",
- "compressible": true
- },
- "application/vnd.ims.lti.v2.toolsettings+json": {
- "source": "iana",
- "compressible": true
- },
- "application/vnd.ims.lti.v2.toolsettings.simple+json": {
- "source": "iana",
- "compressible": true
- },
- "application/vnd.informedcontrol.rms+xml": {
- "source": "iana"
- },
- "application/vnd.informix-visionary": {
- "source": "iana"
- },
- "application/vnd.infotech.project": {
- "source": "iana"
- },
- "application/vnd.infotech.project+xml": {
- "source": "iana"
- },
- "application/vnd.innopath.wamp.notification": {
- "source": "iana"
- },
- "application/vnd.insors.igm": {
- "source": "iana",
- "extensions": ["igm"]
- },
- "application/vnd.intercon.formnet": {
- "source": "iana",
- "extensions": ["xpw","xpx"]
- },
- "application/vnd.intergeo": {
- "source": "iana",
- "extensions": ["i2g"]
- },
- "application/vnd.intertrust.digibox": {
- "source": "iana"
- },
- "application/vnd.intertrust.nncp": {
- "source": "iana"
- },
- "application/vnd.intu.qbo": {
- "source": "iana",
- "extensions": ["qbo"]
- },
- "application/vnd.intu.qfx": {
- "source": "iana",
- "extensions": ["qfx"]
- },
- "application/vnd.iptc.g2.catalogitem+xml": {
- "source": "iana"
- },
- "application/vnd.iptc.g2.conceptitem+xml": {
- "source": "iana"
- },
- "application/vnd.iptc.g2.knowledgeitem+xml": {
- "source": "iana"
- },
- "application/vnd.iptc.g2.newsitem+xml": {
- "source": "iana"
- },
- "application/vnd.iptc.g2.newsmessage+xml": {
- "source": "iana"
- },
- "application/vnd.iptc.g2.packageitem+xml": {
- "source": "iana"
- },
- "application/vnd.iptc.g2.planningitem+xml": {
- "source": "iana"
- },
- "application/vnd.ipunplugged.rcprofile": {
- "source": "iana",
- "extensions": ["rcprofile"]
- },
- "application/vnd.irepository.package+xml": {
- "source": "iana",
- "extensions": ["irp"]
- },
- "application/vnd.is-xpr": {
- "source": "iana",
- "extensions": ["xpr"]
- },
- "application/vnd.isac.fcs": {
- "source": "iana",
- "extensions": ["fcs"]
- },
- "application/vnd.jam": {
- "source": "iana",
- "extensions": ["jam"]
- },
- "application/vnd.japannet-directory-service": {
- "source": "iana"
- },
- "application/vnd.japannet-jpnstore-wakeup": {
- "source": "iana"
- },
- "application/vnd.japannet-payment-wakeup": {
- "source": "iana"
- },
- "application/vnd.japannet-registration": {
- "source": "iana"
- },
- "application/vnd.japannet-registration-wakeup": {
- "source": "iana"
- },
- "application/vnd.japannet-setstore-wakeup": {
- "source": "iana"
- },
- "application/vnd.japannet-verification": {
- "source": "iana"
- },
- "application/vnd.japannet-verification-wakeup": {
- "source": "iana"
- },
- "application/vnd.jcp.javame.midlet-rms": {
- "source": "iana",
- "extensions": ["rms"]
- },
- "application/vnd.jisp": {
- "source": "iana",
- "extensions": ["jisp"]
- },
- "application/vnd.joost.joda-archive": {
- "source": "iana",
- "extensions": ["joda"]
- },
- "application/vnd.jsk.isdn-ngn": {
- "source": "iana"
- },
- "application/vnd.kahootz": {
- "source": "iana",
- "extensions": ["ktz","ktr"]
- },
- "application/vnd.kde.karbon": {
- "source": "iana",
- "extensions": ["karbon"]
- },
- "application/vnd.kde.kchart": {
- "source": "iana",
- "extensions": ["chrt"]
- },
- "application/vnd.kde.kformula": {
- "source": "iana",
- "extensions": ["kfo"]
- },
- "application/vnd.kde.kivio": {
- "source": "iana",
- "extensions": ["flw"]
- },
- "application/vnd.kde.kontour": {
- "source": "iana",
- "extensions": ["kon"]
- },
- "application/vnd.kde.kpresenter": {
- "source": "iana",
- "extensions": ["kpr","kpt"]
- },
- "application/vnd.kde.kspread": {
- "source": "iana",
- "extensions": ["ksp"]
- },
- "application/vnd.kde.kword": {
- "source": "iana",
- "extensions": ["kwd","kwt"]
- },
- "application/vnd.kenameaapp": {
- "source": "iana",
- "extensions": ["htke"]
- },
- "application/vnd.kidspiration": {
- "source": "iana",
- "extensions": ["kia"]
- },
- "application/vnd.kinar": {
- "source": "iana",
- "extensions": ["kne","knp"]
- },
- "application/vnd.koan": {
- "source": "iana",
- "extensions": ["skp","skd","skt","skm"]
- },
- "application/vnd.kodak-descriptor": {
- "source": "iana",
- "extensions": ["sse"]
- },
- "application/vnd.las.las+xml": {
- "source": "iana",
- "extensions": ["lasxml"]
- },
- "application/vnd.liberty-request+xml": {
- "source": "iana"
- },
- "application/vnd.llamagraphics.life-balance.desktop": {
- "source": "iana",
- "extensions": ["lbd"]
- },
- "application/vnd.llamagraphics.life-balance.exchange+xml": {
- "source": "iana",
- "extensions": ["lbe"]
- },
- "application/vnd.lotus-1-2-3": {
- "source": "iana",
- "extensions": ["123"]
- },
- "application/vnd.lotus-approach": {
- "source": "iana",
- "extensions": ["apr"]
- },
- "application/vnd.lotus-freelance": {
- "source": "iana",
- "extensions": ["pre"]
- },
- "application/vnd.lotus-notes": {
- "source": "iana",
- "extensions": ["nsf"]
- },
- "application/vnd.lotus-organizer": {
- "source": "iana",
- "extensions": ["org"]
- },
- "application/vnd.lotus-screencam": {
- "source": "iana",
- "extensions": ["scm"]
- },
- "application/vnd.lotus-wordpro": {
- "source": "iana",
- "extensions": ["lwp"]
- },
- "application/vnd.macports.portpkg": {
- "source": "iana",
- "extensions": ["portpkg"]
- },
- "application/vnd.marlin.drm.actiontoken+xml": {
- "source": "iana"
- },
- "application/vnd.marlin.drm.conftoken+xml": {
- "source": "iana"
- },
- "application/vnd.marlin.drm.license+xml": {
- "source": "iana"
- },
- "application/vnd.marlin.drm.mdcf": {
- "source": "iana"
- },
- "application/vnd.mason+json": {
- "source": "iana",
- "compressible": true
- },
- "application/vnd.maxmind.maxmind-db": {
- "source": "iana"
- },
- "application/vnd.mcd": {
- "source": "iana",
- "extensions": ["mcd"]
- },
- "application/vnd.medcalcdata": {
- "source": "iana",
- "extensions": ["mc1"]
- },
- "application/vnd.mediastation.cdkey": {
- "source": "iana",
- "extensions": ["cdkey"]
- },
- "application/vnd.meridian-slingshot": {
- "source": "iana"
- },
- "application/vnd.mfer": {
- "source": "iana",
- "extensions": ["mwf"]
- },
- "application/vnd.mfmp": {
- "source": "iana",
- "extensions": ["mfm"]
- },
- "application/vnd.micrografx-igx": {
- "source": "iana"
- },
- "application/vnd.micrografx.flo": {
- "source": "iana",
- "extensions": ["flo"]
- },
- "application/vnd.micrografx.igx": {
- "source": "apache",
- "extensions": ["igx"]
- },
- "application/vnd.miele+json": {
- "source": "iana",
- "compressible": true
- },
- "application/vnd.mif": {
- "source": "apache",
- "extensions": ["mif"]
- },
- "application/vnd.minisoft-hp3000-save": {
- "source": "iana"
- },
- "application/vnd.mitsubishi.misty-guard.trustweb": {
- "source": "iana"
- },
- "application/vnd.mobius.daf": {
- "source": "iana",
- "extensions": ["daf"]
- },
- "application/vnd.mobius.dis": {
- "source": "iana",
- "extensions": ["dis"]
- },
- "application/vnd.mobius.mbk": {
- "source": "iana",
- "extensions": ["mbk"]
- },
- "application/vnd.mobius.mqy": {
- "source": "iana",
- "extensions": ["mqy"]
- },
- "application/vnd.mobius.msl": {
- "source": "iana",
- "extensions": ["msl"]
- },
- "application/vnd.mobius.plc": {
- "source": "iana",
- "extensions": ["plc"]
- },
- "application/vnd.mobius.txf": {
- "source": "iana",
- "extensions": ["txf"]
- },
- "application/vnd.mophun.application": {
- "source": "iana",
- "extensions": ["mpn"]
- },
- "application/vnd.mophun.certificate": {
- "source": "iana",
- "extensions": ["mpc"]
- },
- "application/vnd.motorola.flexsuite": {
- "source": "iana"
- },
- "application/vnd.motorola.flexsuite.adsi": {
- "source": "iana"
- },
- "application/vnd.motorola.flexsuite.fis": {
- "source": "iana"
- },
- "application/vnd.motorola.flexsuite.gotap": {
- "source": "iana"
- },
- "application/vnd.motorola.flexsuite.kmr": {
- "source": "iana"
- },
- "application/vnd.motorola.flexsuite.ttc": {
- "source": "iana"
- },
- "application/vnd.motorola.flexsuite.wem": {
- "source": "iana"
- },
- "application/vnd.motorola.iprm": {
- "source": "iana"
- },
- "application/vnd.mozilla.xul+xml": {
- "source": "iana",
- "compressible": true,
- "extensions": ["xul"]
- },
- "application/vnd.ms-3mfdocument": {
- "source": "iana"
- },
- "application/vnd.ms-artgalry": {
- "source": "iana",
- "extensions": ["cil"]
- },
- "application/vnd.ms-asf": {
- "source": "iana"
- },
- "application/vnd.ms-cab-compressed": {
- "source": "iana",
- "extensions": ["cab"]
- },
- "application/vnd.ms-color.iccprofile": {
- "source": "apache"
- },
- "application/vnd.ms-excel": {
- "source": "iana",
- "compressible": false,
- "extensions": ["xls","xlm","xla","xlc","xlt","xlw"]
- },
- "application/vnd.ms-excel.addin.macroenabled.12": {
- "source": "iana",
- "extensions": ["xlam"]
- },
- "application/vnd.ms-excel.sheet.binary.macroenabled.12": {
- "source": "iana",
- "extensions": ["xlsb"]
- },
- "application/vnd.ms-excel.sheet.macroenabled.12": {
- "source": "iana",
- "extensions": ["xlsm"]
- },
- "application/vnd.ms-excel.template.macroenabled.12": {
- "source": "iana",
- "extensions": ["xltm"]
- },
- "application/vnd.ms-fontobject": {
- "source": "iana",
- "compressible": true,
- "extensions": ["eot"]
- },
- "application/vnd.ms-htmlhelp": {
- "source": "iana",
- "extensions": ["chm"]
- },
- "application/vnd.ms-ims": {
- "source": "iana",
- "extensions": ["ims"]
- },
- "application/vnd.ms-lrm": {
- "source": "iana",
- "extensions": ["lrm"]
- },
- "application/vnd.ms-office.activex+xml": {
- "source": "iana"
- },
- "application/vnd.ms-officetheme": {
- "source": "iana",
- "extensions": ["thmx"]
- },
- "application/vnd.ms-opentype": {
- "source": "apache",
- "compressible": true
- },
- "application/vnd.ms-package.obfuscated-opentype": {
- "source": "apache"
- },
- "application/vnd.ms-pki.seccat": {
- "source": "apache",
- "extensions": ["cat"]
- },
- "application/vnd.ms-pki.stl": {
- "source": "apache",
- "extensions": ["stl"]
- },
- "application/vnd.ms-playready.initiator+xml": {
- "source": "iana"
- },
- "application/vnd.ms-powerpoint": {
- "source": "iana",
- "compressible": false,
- "extensions": ["ppt","pps","pot"]
- },
- "application/vnd.ms-powerpoint.addin.macroenabled.12": {
- "source": "iana",
- "extensions": ["ppam"]
- },
- "application/vnd.ms-powerpoint.presentation.macroenabled.12": {
- "source": "iana",
- "extensions": ["pptm"]
- },
- "application/vnd.ms-powerpoint.slide.macroenabled.12": {
- "source": "iana",
- "extensions": ["sldm"]
- },
- "application/vnd.ms-powerpoint.slideshow.macroenabled.12": {
- "source": "iana",
- "extensions": ["ppsm"]
- },
- "application/vnd.ms-powerpoint.template.macroenabled.12": {
- "source": "iana",
- "extensions": ["potm"]
- },
- "application/vnd.ms-printing.printticket+xml": {
- "source": "apache"
- },
- "application/vnd.ms-project": {
- "source": "iana",
- "extensions": ["mpp","mpt"]
- },
- "application/vnd.ms-tnef": {
- "source": "iana"
- },
- "application/vnd.ms-windows.printerpairing": {
- "source": "iana"
- },
- "application/vnd.ms-wmdrm.lic-chlg-req": {
- "source": "iana"
- },
- "application/vnd.ms-wmdrm.lic-resp": {
- "source": "iana"
- },
- "application/vnd.ms-wmdrm.meter-chlg-req": {
- "source": "iana"
- },
- "application/vnd.ms-wmdrm.meter-resp": {
- "source": "iana"
- },
- "application/vnd.ms-word.document.macroenabled.12": {
- "source": "iana",
- "extensions": ["docm"]
- },
- "application/vnd.ms-word.template.macroenabled.12": {
- "source": "iana",
- "extensions": ["dotm"]
- },
- "application/vnd.ms-works": {
- "source": "iana",
- "extensions": ["wps","wks","wcm","wdb"]
- },
- "application/vnd.ms-wpl": {
- "source": "iana",
- "extensions": ["wpl"]
- },
- "application/vnd.ms-xpsdocument": {
- "source": "iana",
- "compressible": false,
- "extensions": ["xps"]
- },
- "application/vnd.mseq": {
- "source": "iana",
- "extensions": ["mseq"]
- },
- "application/vnd.msign": {
- "source": "iana"
- },
- "application/vnd.multiad.creator": {
- "source": "iana"
- },
- "application/vnd.multiad.creator.cif": {
- "source": "iana"
- },
- "application/vnd.music-niff": {
- "source": "iana"
- },
- "application/vnd.musician": {
- "source": "iana",
- "extensions": ["mus"]
- },
- "application/vnd.muvee.style": {
- "source": "iana",
- "extensions": ["msty"]
- },
- "application/vnd.mynfc": {
- "source": "iana",
- "extensions": ["taglet"]
- },
- "application/vnd.ncd.control": {
- "source": "iana"
- },
- "application/vnd.ncd.reference": {
- "source": "iana"
- },
- "application/vnd.nervana": {
- "source": "iana"
- },
- "application/vnd.netfpx": {
- "source": "iana"
- },
- "application/vnd.neurolanguage.nlu": {
- "source": "iana",
- "extensions": ["nlu"]
- },
- "application/vnd.nintendo.nitro.rom": {
- "source": "iana"
- },
- "application/vnd.nintendo.snes.rom": {
- "source": "iana"
- },
- "application/vnd.nitf": {
- "source": "iana",
- "extensions": ["ntf","nitf"]
- },
- "application/vnd.noblenet-directory": {
- "source": "iana",
- "extensions": ["nnd"]
- },
- "application/vnd.noblenet-sealer": {
- "source": "iana",
- "extensions": ["nns"]
- },
- "application/vnd.noblenet-web": {
- "source": "iana",
- "extensions": ["nnw"]
- },
- "application/vnd.nokia.catalogs": {
- "source": "iana"
- },
- "application/vnd.nokia.conml+wbxml": {
- "source": "iana"
- },
- "application/vnd.nokia.conml+xml": {
- "source": "iana"
- },
- "application/vnd.nokia.iptv.config+xml": {
- "source": "iana"
- },
- "application/vnd.nokia.isds-radio-presets": {
- "source": "iana"
- },
- "application/vnd.nokia.landmark+wbxml": {
- "source": "iana"
- },
- "application/vnd.nokia.landmark+xml": {
- "source": "iana"
- },
- "application/vnd.nokia.landmarkcollection+xml": {
- "source": "iana"
- },
- "application/vnd.nokia.n-gage.ac+xml": {
- "source": "iana"
- },
- "application/vnd.nokia.n-gage.data": {
- "source": "iana",
- "extensions": ["ngdat"]
- },
- "application/vnd.nokia.n-gage.symbian.install": {
- "source": "iana"
- },
- "application/vnd.nokia.ncd": {
- "source": "iana"
- },
- "application/vnd.nokia.pcd+wbxml": {
- "source": "iana"
- },
- "application/vnd.nokia.pcd+xml": {
- "source": "iana"
- },
- "application/vnd.nokia.radio-preset": {
- "source": "iana",
- "extensions": ["rpst"]
- },
- "application/vnd.nokia.radio-presets": {
- "source": "iana",
- "extensions": ["rpss"]
- },
- "application/vnd.novadigm.edm": {
- "source": "iana",
- "extensions": ["edm"]
- },
- "application/vnd.novadigm.edx": {
- "source": "iana",
- "extensions": ["edx"]
- },
- "application/vnd.novadigm.ext": {
- "source": "iana",
- "extensions": ["ext"]
- },
- "application/vnd.ntt-local.content-share": {
- "source": "iana"
- },
- "application/vnd.ntt-local.file-transfer": {
- "source": "iana"
- },
- "application/vnd.ntt-local.ogw_remote-access": {
- "source": "iana"
- },
- "application/vnd.ntt-local.sip-ta_remote": {
- "source": "iana"
- },
- "application/vnd.ntt-local.sip-ta_tcp_stream": {
- "source": "iana"
- },
- "application/vnd.oasis.opendocument.chart": {
- "source": "iana",
- "extensions": ["odc"]
- },
- "application/vnd.oasis.opendocument.chart-template": {
- "source": "iana",
- "extensions": ["otc"]
- },
- "application/vnd.oasis.opendocument.database": {
- "source": "iana",
- "extensions": ["odb"]
- },
- "application/vnd.oasis.opendocument.formula": {
- "source": "iana",
- "extensions": ["odf"]
- },
- "application/vnd.oasis.opendocument.formula-template": {
- "source": "iana",
- "extensions": ["odft"]
- },
- "application/vnd.oasis.opendocument.graphics": {
- "source": "iana",
- "compressible": false,
- "extensions": ["odg"]
- },
- "application/vnd.oasis.opendocument.graphics-template": {
- "source": "iana",
- "extensions": ["otg"]
- },
- "application/vnd.oasis.opendocument.image": {
- "source": "iana",
- "extensions": ["odi"]
- },
- "application/vnd.oasis.opendocument.image-template": {
- "source": "iana",
- "extensions": ["oti"]
- },
- "application/vnd.oasis.opendocument.presentation": {
- "source": "iana",
- "compressible": false,
- "extensions": ["odp"]
- },
- "application/vnd.oasis.opendocument.presentation-template": {
- "source": "iana",
- "extensions": ["otp"]
- },
- "application/vnd.oasis.opendocument.spreadsheet": {
- "source": "iana",
- "compressible": false,
- "extensions": ["ods"]
- },
- "application/vnd.oasis.opendocument.spreadsheet-template": {
- "source": "iana",
- "extensions": ["ots"]
- },
- "application/vnd.oasis.opendocument.text": {
- "source": "iana",
- "compressible": false,
- "extensions": ["odt"]
- },
- "application/vnd.oasis.opendocument.text-master": {
- "source": "iana",
- "extensions": ["odm"]
- },
- "application/vnd.oasis.opendocument.text-template": {
- "source": "iana",
- "extensions": ["ott"]
- },
- "application/vnd.oasis.opendocument.text-web": {
- "source": "iana",
- "extensions": ["oth"]
- },
- "application/vnd.obn": {
- "source": "iana"
- },
- "application/vnd.oftn.l10n+json": {
- "source": "iana",
- "compressible": true
- },
- "application/vnd.oipf.contentaccessdownload+xml": {
- "source": "iana"
- },
- "application/vnd.oipf.contentaccessstreaming+xml": {
- "source": "iana"
- },
- "application/vnd.oipf.cspg-hexbinary": {
- "source": "iana"
- },
- "application/vnd.oipf.dae.svg+xml": {
- "source": "iana"
- },
- "application/vnd.oipf.dae.xhtml+xml": {
- "source": "iana"
- },
- "application/vnd.oipf.mippvcontrolmessage+xml": {
- "source": "iana"
- },
- "application/vnd.oipf.pae.gem": {
- "source": "iana"
- },
- "application/vnd.oipf.spdiscovery+xml": {
- "source": "iana"
- },
- "application/vnd.oipf.spdlist+xml": {
- "source": "iana"
- },
- "application/vnd.oipf.ueprofile+xml": {
- "source": "iana"
- },
- "application/vnd.oipf.userprofile+xml": {
- "source": "iana"
- },
- "application/vnd.olpc-sugar": {
- "source": "iana",
- "extensions": ["xo"]
- },
- "application/vnd.oma-scws-config": {
- "source": "iana"
- },
- "application/vnd.oma-scws-http-request": {
- "source": "iana"
- },
- "application/vnd.oma-scws-http-response": {
- "source": "iana"
- },
- "application/vnd.oma.bcast.associated-procedure-parameter+xml": {
- "source": "iana"
- },
- "application/vnd.oma.bcast.drm-trigger+xml": {
- "source": "iana"
- },
- "application/vnd.oma.bcast.imd+xml": {
- "source": "iana"
- },
- "application/vnd.oma.bcast.ltkm": {
- "source": "iana"
- },
- "application/vnd.oma.bcast.notification+xml": {
- "source": "iana"
- },
- "application/vnd.oma.bcast.provisioningtrigger": {
- "source": "iana"
- },
- "application/vnd.oma.bcast.sgboot": {
- "source": "iana"
- },
- "application/vnd.oma.bcast.sgdd+xml": {
- "source": "iana"
- },
- "application/vnd.oma.bcast.sgdu": {
- "source": "iana"
- },
- "application/vnd.oma.bcast.simple-symbol-container": {
- "source": "iana"
- },
- "application/vnd.oma.bcast.smartcard-trigger+xml": {
- "source": "iana"
- },
- "application/vnd.oma.bcast.sprov+xml": {
- "source": "iana"
- },
- "application/vnd.oma.bcast.stkm": {
- "source": "iana"
- },
- "application/vnd.oma.cab-address-book+xml": {
- "source": "iana"
- },
- "application/vnd.oma.cab-feature-handler+xml": {
- "source": "iana"
- },
- "application/vnd.oma.cab-pcc+xml": {
- "source": "iana"
- },
- "application/vnd.oma.cab-subs-invite+xml": {
- "source": "iana"
- },
- "application/vnd.oma.cab-user-prefs+xml": {
- "source": "iana"
- },
- "application/vnd.oma.dcd": {
- "source": "iana"
- },
- "application/vnd.oma.dcdc": {
- "source": "iana"
- },
- "application/vnd.oma.dd2+xml": {
- "source": "iana",
- "extensions": ["dd2"]
- },
- "application/vnd.oma.drm.risd+xml": {
- "source": "iana"
- },
- "application/vnd.oma.group-usage-list+xml": {
- "source": "iana"
- },
- "application/vnd.oma.pal+xml": {
- "source": "iana"
- },
- "application/vnd.oma.poc.detailed-progress-report+xml": {
- "source": "iana"
- },
- "application/vnd.oma.poc.final-report+xml": {
- "source": "iana"
- },
- "application/vnd.oma.poc.groups+xml": {
- "source": "iana"
- },
- "application/vnd.oma.poc.invocation-descriptor+xml": {
- "source": "iana"
- },
- "application/vnd.oma.poc.optimized-progress-report+xml": {
- "source": "iana"
- },
- "application/vnd.oma.push": {
- "source": "iana"
- },
- "application/vnd.oma.scidm.messages+xml": {
- "source": "iana"
- },
- "application/vnd.oma.xcap-directory+xml": {
- "source": "iana"
- },
- "application/vnd.omads-email+xml": {
- "source": "iana"
- },
- "application/vnd.omads-file+xml": {
- "source": "iana"
- },
- "application/vnd.omads-folder+xml": {
- "source": "iana"
- },
- "application/vnd.omaloc-supl-init": {
- "source": "iana"
- },
- "application/vnd.openeye.oeb": {
- "source": "iana"
- },
- "application/vnd.openofficeorg.extension": {
- "source": "apache",
- "extensions": ["oxt"]
- },
- "application/vnd.openxmlformats-officedocument.custom-properties+xml": {
- "source": "iana"
- },
- "application/vnd.openxmlformats-officedocument.customxmlproperties+xml": {
- "source": "iana"
- },
- "application/vnd.openxmlformats-officedocument.drawing+xml": {
- "source": "iana"
- },
- "application/vnd.openxmlformats-officedocument.drawingml.chart+xml": {
- "source": "iana"
- },
- "application/vnd.openxmlformats-officedocument.drawingml.chartshapes+xml": {
- "source": "iana"
- },
- "application/vnd.openxmlformats-officedocument.drawingml.diagramcolors+xml": {
- "source": "iana"
- },
- "application/vnd.openxmlformats-officedocument.drawingml.diagramdata+xml": {
- "source": "iana"
- },
- "application/vnd.openxmlformats-officedocument.drawingml.diagramlayout+xml": {
- "source": "iana"
- },
- "application/vnd.openxmlformats-officedocument.drawingml.diagramstyle+xml": {
- "source": "iana"
- },
- "application/vnd.openxmlformats-officedocument.extended-properties+xml": {
- "source": "iana"
- },
- "application/vnd.openxmlformats-officedocument.presentationml-template": {
- "source": "iana"
- },
- "application/vnd.openxmlformats-officedocument.presentationml.commentauthors+xml": {
- "source": "iana"
- },
- "application/vnd.openxmlformats-officedocument.presentationml.comments+xml": {
- "source": "iana"
- },
- "application/vnd.openxmlformats-officedocument.presentationml.handoutmaster+xml": {
- "source": "iana"
- },
- "application/vnd.openxmlformats-officedocument.presentationml.notesmaster+xml": {
- "source": "iana"
- },
- "application/vnd.openxmlformats-officedocument.presentationml.notesslide+xml": {
- "source": "iana"
- },
- "application/vnd.openxmlformats-officedocument.presentationml.presentation": {
- "source": "iana",
- "compressible": false,
- "extensions": ["pptx"]
- },
- "application/vnd.openxmlformats-officedocument.presentationml.presentation.main+xml": {
- "source": "iana"
- },
- "application/vnd.openxmlformats-officedocument.presentationml.presprops+xml": {
- "source": "iana"
- },
- "application/vnd.openxmlformats-officedocument.presentationml.slide": {
- "source": "iana",
- "extensions": ["sldx"]
- },
- "application/vnd.openxmlformats-officedocument.presentationml.slide+xml": {
- "source": "iana"
- },
- "application/vnd.openxmlformats-officedocument.presentationml.slidelayout+xml": {
- "source": "iana"
- },
- "application/vnd.openxmlformats-officedocument.presentationml.slidemaster+xml": {
- "source": "iana"
- },
- "application/vnd.openxmlformats-officedocument.presentationml.slideshow": {
- "source": "iana",
- "extensions": ["ppsx"]
- },
- "application/vnd.openxmlformats-officedocument.presentationml.slideshow.main+xml": {
- "source": "iana"
- },
- "application/vnd.openxmlformats-officedocument.presentationml.slideupdateinfo+xml": {
- "source": "iana"
- },
- "application/vnd.openxmlformats-officedocument.presentationml.tablestyles+xml": {
- "source": "iana"
- },
- "application/vnd.openxmlformats-officedocument.presentationml.tags+xml": {
- "source": "iana"
- },
- "application/vnd.openxmlformats-officedocument.presentationml.template": {
- "source": "apache",
- "extensions": ["potx"]
- },
- "application/vnd.openxmlformats-officedocument.presentationml.template.main+xml": {
- "source": "iana"
- },
- "application/vnd.openxmlformats-officedocument.presentationml.viewprops+xml": {
- "source": "iana"
- },
- "application/vnd.openxmlformats-officedocument.spreadsheetml-template": {
- "source": "iana"
- },
- "application/vnd.openxmlformats-officedocument.spreadsheetml.calcchain+xml": {
- "source": "iana"
- },
- "application/vnd.openxmlformats-officedocument.spreadsheetml.chartsheet+xml": {
- "source": "iana"
- },
- "application/vnd.openxmlformats-officedocument.spreadsheetml.comments+xml": {
- "source": "iana"
- },
- "application/vnd.openxmlformats-officedocument.spreadsheetml.connections+xml": {
- "source": "iana"
- },
- "application/vnd.openxmlformats-officedocument.spreadsheetml.dialogsheet+xml": {
- "source": "iana"
- },
- "application/vnd.openxmlformats-officedocument.spreadsheetml.externallink+xml": {
- "source": "iana"
- },
- "application/vnd.openxmlformats-officedocument.spreadsheetml.pivotcachedefinition+xml": {
- "source": "iana"
- },
- "application/vnd.openxmlformats-officedocument.spreadsheetml.pivotcacherecords+xml": {
- "source": "iana"
- },
- "application/vnd.openxmlformats-officedocument.spreadsheetml.pivottable+xml": {
- "source": "iana"
- },
- "application/vnd.openxmlformats-officedocument.spreadsheetml.querytable+xml": {
- "source": "iana"
- },
- "application/vnd.openxmlformats-officedocument.spreadsheetml.revisionheaders+xml": {
- "source": "iana"
- },
- "application/vnd.openxmlformats-officedocument.spreadsheetml.revisionlog+xml": {
- "source": "iana"
- },
- "application/vnd.openxmlformats-officedocument.spreadsheetml.sharedstrings+xml": {
- "source": "iana"
- },
- "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet": {
- "source": "iana",
- "compressible": false,
- "extensions": ["xlsx"]
- },
- "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet.main+xml": {
- "source": "iana"
- },
- "application/vnd.openxmlformats-officedocument.spreadsheetml.sheetmetadata+xml": {
- "source": "iana"
- },
- "application/vnd.openxmlformats-officedocument.spreadsheetml.styles+xml": {
- "source": "iana"
- },
- "application/vnd.openxmlformats-officedocument.spreadsheetml.table+xml": {
- "source": "iana"
- },
- "application/vnd.openxmlformats-officedocument.spreadsheetml.tablesinglecells+xml": {
- "source": "iana"
- },
- "application/vnd.openxmlformats-officedocument.spreadsheetml.template": {
- "source": "apache",
- "extensions": ["xltx"]
- },
- "application/vnd.openxmlformats-officedocument.spreadsheetml.template.main+xml": {
- "source": "iana"
- },
- "application/vnd.openxmlformats-officedocument.spreadsheetml.usernames+xml": {
- "source": "iana"
- },
- "application/vnd.openxmlformats-officedocument.spreadsheetml.volatiledependencies+xml": {
- "source": "iana"
- },
- "application/vnd.openxmlformats-officedocument.spreadsheetml.worksheet+xml": {
- "source": "iana"
- },
- "application/vnd.openxmlformats-officedocument.theme+xml": {
- "source": "iana"
- },
- "application/vnd.openxmlformats-officedocument.themeoverride+xml": {
- "source": "iana"
- },
- "application/vnd.openxmlformats-officedocument.vmldrawing": {
- "source": "iana"
- },
- "application/vnd.openxmlformats-officedocument.wordprocessingml-template": {
- "source": "iana"
- },
- "application/vnd.openxmlformats-officedocument.wordprocessingml.comments+xml": {
- "source": "iana"
- },
- "application/vnd.openxmlformats-officedocument.wordprocessingml.document": {
- "source": "iana",
- "compressible": false,
- "extensions": ["docx"]
- },
- "application/vnd.openxmlformats-officedocument.wordprocessingml.document.glossary+xml": {
- "source": "iana"
- },
- "application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml": {
- "source": "iana"
- },
- "application/vnd.openxmlformats-officedocument.wordprocessingml.endnotes+xml": {
- "source": "iana"
- },
- "application/vnd.openxmlformats-officedocument.wordprocessingml.fonttable+xml": {
- "source": "iana"
- },
- "application/vnd.openxmlformats-officedocument.wordprocessingml.footer+xml": {
- "source": "iana"
- },
- "application/vnd.openxmlformats-officedocument.wordprocessingml.footnotes+xml": {
- "source": "iana"
- },
- "application/vnd.openxmlformats-officedocument.wordprocessingml.numbering+xml": {
- "source": "iana"
- },
- "application/vnd.openxmlformats-officedocument.wordprocessingml.settings+xml": {
- "source": "iana"
- },
- "application/vnd.openxmlformats-officedocument.wordprocessingml.styles+xml": {
- "source": "iana"
- },
- "application/vnd.openxmlformats-officedocument.wordprocessingml.template": {
- "source": "apache",
- "extensions": ["dotx"]
- },
- "application/vnd.openxmlformats-officedocument.wordprocessingml.template.main+xml": {
- "source": "iana"
- },
- "application/vnd.openxmlformats-officedocument.wordprocessingml.websettings+xml": {
- "source": "iana"
- },
- "application/vnd.openxmlformats-package.core-properties+xml": {
- "source": "iana"
- },
- "application/vnd.openxmlformats-package.digital-signature-xmlsignature+xml": {
- "source": "iana"
- },
- "application/vnd.openxmlformats-package.relationships+xml": {
- "source": "iana"
- },
- "application/vnd.orange.indata": {
- "source": "iana"
- },
- "application/vnd.osa.netdeploy": {
- "source": "iana"
- },
- "application/vnd.osgeo.mapguide.package": {
- "source": "iana",
- "extensions": ["mgp"]
- },
- "application/vnd.osgi.bundle": {
- "source": "iana"
- },
- "application/vnd.osgi.dp": {
- "source": "iana",
- "extensions": ["dp"]
- },
- "application/vnd.osgi.subsystem": {
- "source": "iana",
- "extensions": ["esa"]
- },
- "application/vnd.otps.ct-kip+xml": {
- "source": "iana"
- },
- "application/vnd.palm": {
- "source": "iana",
- "extensions": ["pdb","pqa","oprc"]
- },
- "application/vnd.panoply": {
- "source": "iana"
- },
- "application/vnd.paos+xml": {
- "source": "iana"
- },
- "application/vnd.paos.xml": {
- "source": "apache"
- },
- "application/vnd.pawaafile": {
- "source": "iana",
- "extensions": ["paw"]
- },
- "application/vnd.pcos": {
- "source": "iana"
- },
- "application/vnd.pg.format": {
- "source": "iana",
- "extensions": ["str"]
- },
- "application/vnd.pg.osasli": {
- "source": "iana",
- "extensions": ["ei6"]
- },
- "application/vnd.piaccess.application-licence": {
- "source": "iana"
- },
- "application/vnd.picsel": {
- "source": "iana",
- "extensions": ["efif"]
- },
- "application/vnd.pmi.widget": {
- "source": "iana",
- "extensions": ["wg"]
- },
- "application/vnd.poc.group-advertisement+xml": {
- "source": "iana"
- },
- "application/vnd.pocketlearn": {
- "source": "iana",
- "extensions": ["plf"]
- },
- "application/vnd.powerbuilder6": {
- "source": "iana",
- "extensions": ["pbd"]
- },
- "application/vnd.powerbuilder6-s": {
- "source": "iana"
- },
- "application/vnd.powerbuilder7": {
- "source": "iana"
- },
- "application/vnd.powerbuilder7-s": {
- "source": "iana"
- },
- "application/vnd.powerbuilder75": {
- "source": "iana"
- },
- "application/vnd.powerbuilder75-s": {
- "source": "iana"
- },
- "application/vnd.preminet": {
- "source": "iana"
- },
- "application/vnd.previewsystems.box": {
- "source": "iana",
- "extensions": ["box"]
- },
- "application/vnd.proteus.magazine": {
- "source": "iana",
- "extensions": ["mgz"]
- },
- "application/vnd.publishare-delta-tree": {
- "source": "iana",
- "extensions": ["qps"]
- },
- "application/vnd.pvi.ptid1": {
- "source": "iana",
- "extensions": ["ptid"]
- },
- "application/vnd.pwg-multiplexed": {
- "source": "apache"
- },
- "application/vnd.pwg-xhtml-print+xml": {
- "source": "iana"
- },
- "application/vnd.qualcomm.brew-app-res": {
- "source": "iana"
- },
- "application/vnd.quark.quarkxpress": {
- "source": "iana",
- "extensions": ["qxd","qxt","qwd","qwt","qxl","qxb"]
- },
- "application/vnd.quobject-quoxdocument": {
- "source": "iana"
- },
- "application/vnd.radisys.moml+xml": {
- "source": "iana"
- },
- "application/vnd.radisys.msml+xml": {
- "source": "iana"
- },
- "application/vnd.radisys.msml-audit+xml": {
- "source": "iana"
- },
- "application/vnd.radisys.msml-audit-conf+xml": {
- "source": "iana"
- },
- "application/vnd.radisys.msml-audit-conn+xml": {
- "source": "iana"
- },
- "application/vnd.radisys.msml-audit-dialog+xml": {
- "source": "iana"
- },
- "application/vnd.radisys.msml-audit-stream+xml": {
- "source": "iana"
- },
- "application/vnd.radisys.msml-conf+xml": {
- "source": "iana"
- },
- "application/vnd.radisys.msml-dialog+xml": {
- "source": "iana"
- },
- "application/vnd.radisys.msml-dialog-base+xml": {
- "source": "iana"
- },
- "application/vnd.radisys.msml-dialog-fax-detect+xml": {
- "source": "iana"
- },
- "application/vnd.radisys.msml-dialog-fax-sendrecv+xml": {
- "source": "iana"
- },
- "application/vnd.radisys.msml-dialog-group+xml": {
- "source": "iana"
- },
- "application/vnd.radisys.msml-dialog-speech+xml": {
- "source": "iana"
- },
- "application/vnd.radisys.msml-dialog-transform+xml": {
- "source": "iana"
- },
- "application/vnd.rainstor.data": {
- "source": "iana"
- },
- "application/vnd.rapid": {
- "source": "iana"
- },
- "application/vnd.realvnc.bed": {
- "source": "iana",
- "extensions": ["bed"]
- },
- "application/vnd.recordare.musicxml": {
- "source": "iana",
- "extensions": ["mxl"]
- },
- "application/vnd.recordare.musicxml+xml": {
- "source": "iana",
- "extensions": ["musicxml"]
- },
- "application/vnd.renlearn.rlprint": {
- "source": "iana"
- },
- "application/vnd.rig.cryptonote": {
- "source": "iana",
- "extensions": ["cryptonote"]
- },
- "application/vnd.rim.cod": {
- "source": "apache",
- "extensions": ["cod"]
- },
- "application/vnd.rn-realmedia": {
- "source": "apache",
- "extensions": ["rm"]
- },
- "application/vnd.rn-realmedia-vbr": {
- "source": "apache",
- "extensions": ["rmvb"]
- },
- "application/vnd.route66.link66+xml": {
- "source": "iana",
- "extensions": ["link66"]
- },
- "application/vnd.rs-274x": {
- "source": "iana"
- },
- "application/vnd.ruckus.download": {
- "source": "iana"
- },
- "application/vnd.s3sms": {
- "source": "iana"
- },
- "application/vnd.sailingtracker.track": {
- "source": "iana",
- "extensions": ["st"]
- },
- "application/vnd.sbm.cid": {
- "source": "iana"
- },
- "application/vnd.sbm.mid2": {
- "source": "iana"
- },
- "application/vnd.scribus": {
- "source": "iana"
- },
- "application/vnd.sealed-doc": {
- "source": "iana"
- },
- "application/vnd.sealed-eml": {
- "source": "iana"
- },
- "application/vnd.sealed-mht": {
- "source": "iana"
- },
- "application/vnd.sealed-ppt": {
- "source": "iana"
- },
- "application/vnd.sealed-tiff": {
- "source": "iana"
- },
- "application/vnd.sealed-xls": {
- "source": "iana"
- },
- "application/vnd.sealed.3df": {
- "source": "iana"
- },
- "application/vnd.sealed.csf": {
- "source": "iana"
- },
- "application/vnd.sealed.doc": {
- "source": "apache"
- },
- "application/vnd.sealed.eml": {
- "source": "apache"
- },
- "application/vnd.sealed.mht": {
- "source": "apache"
- },
- "application/vnd.sealed.net": {
- "source": "iana"
- },
- "application/vnd.sealed.ppt": {
- "source": "apache"
- },
- "application/vnd.sealed.tiff": {
- "source": "apache"
- },
- "application/vnd.sealed.xls": {
- "source": "apache"
- },
- "application/vnd.sealedmedia.softseal-html": {
- "source": "iana"
- },
- "application/vnd.sealedmedia.softseal-pdf": {
- "source": "iana"
- },
- "application/vnd.sealedmedia.softseal.html": {
- "source": "apache"
- },
- "application/vnd.sealedmedia.softseal.pdf": {
- "source": "apache"
- },
- "application/vnd.seemail": {
- "source": "iana",
- "extensions": ["see"]
- },
- "application/vnd.sema": {
- "source": "apache",
- "extensions": ["sema"]
- },
- "application/vnd.semd": {
- "source": "iana",
- "extensions": ["semd"]
- },
- "application/vnd.semf": {
- "source": "iana",
- "extensions": ["semf"]
- },
- "application/vnd.shana.informed.formdata": {
- "source": "iana",
- "extensions": ["ifm"]
- },
- "application/vnd.shana.informed.formtemplate": {
- "source": "iana",
- "extensions": ["itp"]
- },
- "application/vnd.shana.informed.interchange": {
- "source": "iana",
- "extensions": ["iif"]
- },
- "application/vnd.shana.informed.package": {
- "source": "iana",
- "extensions": ["ipk"]
- },
- "application/vnd.simtech-mindmapper": {
- "source": "iana",
- "extensions": ["twd","twds"]
- },
- "application/vnd.siren+json": {
- "source": "iana",
- "compressible": true
- },
- "application/vnd.smaf": {
- "source": "iana",
- "extensions": ["mmf"]
- },
- "application/vnd.smart.notebook": {
- "source": "iana"
- },
- "application/vnd.smart.teacher": {
- "source": "iana",
- "extensions": ["teacher"]
- },
- "application/vnd.software602.filler.form+xml": {
- "source": "iana"
- },
- "application/vnd.software602.filler.form-xml-zip": {
- "source": "iana"
- },
- "application/vnd.solent.sdkm+xml": {
- "source": "iana",
- "extensions": ["sdkm","sdkd"]
- },
- "application/vnd.spotfire.dxp": {
- "source": "iana",
- "extensions": ["dxp"]
- },
- "application/vnd.spotfire.sfs": {
- "source": "iana",
- "extensions": ["sfs"]
- },
- "application/vnd.sss-cod": {
- "source": "iana"
- },
- "application/vnd.sss-dtf": {
- "source": "iana"
- },
- "application/vnd.sss-ntf": {
- "source": "iana"
- },
- "application/vnd.stardivision.calc": {
- "source": "apache",
- "extensions": ["sdc"]
- },
- "application/vnd.stardivision.draw": {
- "source": "apache",
- "extensions": ["sda"]
- },
- "application/vnd.stardivision.impress": {
- "source": "apache",
- "extensions": ["sdd"]
- },
- "application/vnd.stardivision.math": {
- "source": "apache",
- "extensions": ["smf"]
- },
- "application/vnd.stardivision.writer": {
- "source": "apache",
- "extensions": ["sdw","vor"]
- },
- "application/vnd.stardivision.writer-global": {
- "source": "apache",
- "extensions": ["sgl"]
- },
- "application/vnd.stepmania.package": {
- "source": "iana",
- "extensions": ["smzip"]
- },
- "application/vnd.stepmania.stepchart": {
- "source": "iana",
- "extensions": ["sm"]
- },
- "application/vnd.street-stream": {
- "source": "iana"
- },
- "application/vnd.sun.wadl+xml": {
- "source": "iana"
- },
- "application/vnd.sun.xml.calc": {
- "source": "apache",
- "extensions": ["sxc"]
- },
- "application/vnd.sun.xml.calc.template": {
- "source": "apache",
- "extensions": ["stc"]
- },
- "application/vnd.sun.xml.draw": {
- "source": "apache",
- "extensions": ["sxd"]
- },
- "application/vnd.sun.xml.draw.template": {
- "source": "apache",
- "extensions": ["std"]
- },
- "application/vnd.sun.xml.impress": {
- "source": "apache",
- "extensions": ["sxi"]
- },
- "application/vnd.sun.xml.impress.template": {
- "source": "apache",
- "extensions": ["sti"]
- },
- "application/vnd.sun.xml.math": {
- "source": "apache",
- "extensions": ["sxm"]
- },
- "application/vnd.sun.xml.writer": {
- "source": "apache",
- "extensions": ["sxw"]
- },
- "application/vnd.sun.xml.writer.global": {
- "source": "apache",
- "extensions": ["sxg"]
- },
- "application/vnd.sun.xml.writer.template": {
- "source": "apache",
- "extensions": ["stw"]
- },
- "application/vnd.sus-calendar": {
- "source": "iana",
- "extensions": ["sus","susp"]
- },
- "application/vnd.svd": {
- "source": "iana",
- "extensions": ["svd"]
- },
- "application/vnd.swiftview-ics": {
- "source": "iana"
- },
- "application/vnd.symbian.install": {
- "source": "apache",
- "extensions": ["sis","sisx"]
- },
- "application/vnd.syncml+xml": {
- "source": "iana",
- "extensions": ["xsm"]
- },
- "application/vnd.syncml.dm+wbxml": {
- "source": "iana",
- "extensions": ["bdm"]
- },
- "application/vnd.syncml.dm+xml": {
- "source": "iana",
- "extensions": ["xdm"]
- },
- "application/vnd.syncml.dm.notification": {
- "source": "iana"
- },
- "application/vnd.syncml.dmddf+wbxml": {
- "source": "iana"
- },
- "application/vnd.syncml.dmddf+xml": {
- "source": "iana"
- },
- "application/vnd.syncml.dmtnds+wbxml": {
- "source": "iana"
- },
- "application/vnd.syncml.dmtnds+xml": {
- "source": "iana"
- },
- "application/vnd.syncml.ds.notification": {
- "source": "iana"
- },
- "application/vnd.tao.intent-module-archive": {
- "source": "iana",
- "extensions": ["tao"]
- },
- "application/vnd.tcpdump.pcap": {
- "source": "iana",
- "extensions": ["pcap","cap","dmp"]
- },
- "application/vnd.tmobile-livetv": {
- "source": "iana",
- "extensions": ["tmo"]
- },
- "application/vnd.trid.tpt": {
- "source": "iana",
- "extensions": ["tpt"]
- },
- "application/vnd.triscape.mxs": {
- "source": "iana",
- "extensions": ["mxs"]
- },
- "application/vnd.trueapp": {
- "source": "iana",
- "extensions": ["tra"]
- },
- "application/vnd.truedoc": {
- "source": "iana"
- },
- "application/vnd.ubisoft.webplayer": {
- "source": "iana"
- },
- "application/vnd.ufdl": {
- "source": "iana",
- "extensions": ["ufd","ufdl"]
- },
- "application/vnd.uiq.theme": {
- "source": "iana",
- "extensions": ["utz"]
- },
- "application/vnd.umajin": {
- "source": "iana",
- "extensions": ["umj"]
- },
- "application/vnd.unity": {
- "source": "iana",
- "extensions": ["unityweb"]
- },
- "application/vnd.uoml+xml": {
- "source": "iana",
- "extensions": ["uoml"]
- },
- "application/vnd.uplanet.alert": {
- "source": "iana"
- },
- "application/vnd.uplanet.alert-wbxml": {
- "source": "iana"
- },
- "application/vnd.uplanet.bearer-choice": {
- "source": "iana"
- },
- "application/vnd.uplanet.bearer-choice-wbxml": {
- "source": "iana"
- },
- "application/vnd.uplanet.cacheop": {
- "source": "iana"
- },
- "application/vnd.uplanet.cacheop-wbxml": {
- "source": "iana"
- },
- "application/vnd.uplanet.channel": {
- "source": "iana"
- },
- "application/vnd.uplanet.channel-wbxml": {
- "source": "iana"
- },
- "application/vnd.uplanet.list": {
- "source": "iana"
- },
- "application/vnd.uplanet.list-wbxml": {
- "source": "iana"
- },
- "application/vnd.uplanet.listcmd": {
- "source": "iana"
- },
- "application/vnd.uplanet.listcmd-wbxml": {
- "source": "iana"
- },
- "application/vnd.uplanet.signal": {
- "source": "iana"
- },
- "application/vnd.valve.source.material": {
- "source": "iana"
- },
- "application/vnd.vcx": {
- "source": "iana",
- "extensions": ["vcx"]
- },
- "application/vnd.vd-study": {
- "source": "iana"
- },
- "application/vnd.vectorworks": {
- "source": "iana"
- },
- "application/vnd.verimatrix.vcas": {
- "source": "iana"
- },
- "application/vnd.vidsoft.vidconference": {
- "source": "iana"
- },
- "application/vnd.visio": {
- "source": "iana",
- "extensions": ["vsd","vst","vss","vsw"]
- },
- "application/vnd.visionary": {
- "source": "iana",
- "extensions": ["vis"]
- },
- "application/vnd.vividence.scriptfile": {
- "source": "iana"
- },
- "application/vnd.vsf": {
- "source": "iana",
- "extensions": ["vsf"]
- },
- "application/vnd.wap-slc": {
- "source": "iana"
- },
- "application/vnd.wap-wbxml": {
- "source": "iana"
- },
- "application/vnd.wap.sic": {
- "source": "iana"
- },
- "application/vnd.wap.slc": {
- "source": "apache"
- },
- "application/vnd.wap.wbxml": {
- "source": "apache",
- "extensions": ["wbxml"]
- },
- "application/vnd.wap.wmlc": {
- "source": "apache",
- "extensions": ["wmlc"]
- },
- "application/vnd.wap.wmlscriptc": {
- "source": "iana",
- "extensions": ["wmlsc"]
- },
- "application/vnd.webturbo": {
- "source": "iana",
- "extensions": ["wtb"]
- },
- "application/vnd.wfa.p2p": {
- "source": "iana"
- },
- "application/vnd.wfa.wsc": {
- "source": "iana"
- },
- "application/vnd.windows.devicepairing": {
- "source": "iana"
- },
- "application/vnd.wmc": {
- "source": "iana"
- },
- "application/vnd.wmf.bootstrap": {
- "source": "iana"
- },
- "application/vnd.wolfram.mathematica": {
- "source": "iana"
- },
- "application/vnd.wolfram.mathematica.package": {
- "source": "iana"
- },
- "application/vnd.wolfram.player": {
- "source": "iana",
- "extensions": ["nbp"]
- },
- "application/vnd.wordperfect": {
- "source": "iana",
- "extensions": ["wpd"]
- },
- "application/vnd.wqd": {
- "source": "iana",
- "extensions": ["wqd"]
- },
- "application/vnd.wrq-hp3000-labelled": {
- "source": "iana"
- },
- "application/vnd.wt.stf": {
- "source": "iana",
- "extensions": ["stf"]
- },
- "application/vnd.wv.csp+wbxml": {
- "source": "iana"
- },
- "application/vnd.wv.csp+xml": {
- "source": "iana"
- },
- "application/vnd.wv.ssp+xml": {
- "source": "iana"
- },
- "application/vnd.xacml+json": {
- "source": "iana",
- "compressible": true
- },
- "application/vnd.xara": {
- "source": "iana",
- "extensions": ["xar"]
- },
- "application/vnd.xfdl": {
- "source": "iana",
- "extensions": ["xfdl"]
- },
- "application/vnd.xfdl.webform": {
- "source": "iana"
- },
- "application/vnd.xmi+xml": {
- "source": "iana"
- },
- "application/vnd.xmpie.cpkg": {
- "source": "iana"
- },
- "application/vnd.xmpie.dpkg": {
- "source": "iana"
- },
- "application/vnd.xmpie.plan": {
- "source": "iana"
- },
- "application/vnd.xmpie.ppkg": {
- "source": "iana"
- },
- "application/vnd.xmpie.xlim": {
- "source": "iana"
- },
- "application/vnd.yamaha.hv-dic": {
- "source": "iana",
- "extensions": ["hvd"]
- },
- "application/vnd.yamaha.hv-script": {
- "source": "iana",
- "extensions": ["hvs"]
- },
- "application/vnd.yamaha.hv-voice": {
- "source": "iana",
- "extensions": ["hvp"]
- },
- "application/vnd.yamaha.openscoreformat": {
- "source": "iana",
- "extensions": ["osf"]
- },
- "application/vnd.yamaha.openscoreformat.osfpvg+xml": {
- "source": "iana",
- "extensions": ["osfpvg"]
- },
- "application/vnd.yamaha.remote-setup": {
- "source": "iana"
- },
- "application/vnd.yamaha.smaf-audio": {
- "source": "iana",
- "extensions": ["saf"]
- },
- "application/vnd.yamaha.smaf-phrase": {
- "source": "iana",
- "extensions": ["spf"]
- },
- "application/vnd.yamaha.through-ngn": {
- "source": "iana"
- },
- "application/vnd.yamaha.tunnel-udpencap": {
- "source": "iana"
- },
- "application/vnd.yaoweme": {
- "source": "iana"
- },
- "application/vnd.yellowriver-custom-menu": {
- "source": "iana",
- "extensions": ["cmp"]
- },
- "application/vnd.zul": {
- "source": "iana",
- "extensions": ["zir","zirz"]
- },
- "application/vnd.zzazz.deck+xml": {
- "source": "iana",
- "extensions": ["zaz"]
- },
- "application/voicexml+xml": {
- "source": "iana",
- "extensions": ["vxml"]
- },
- "application/vq-rtcpxr": {
- "source": "iana"
- },
- "application/vwg-multiplexed": {
- "source": "iana"
- },
- "application/watcherinfo+xml": {
- "source": "iana"
- },
- "application/whoispp-query": {
- "source": "iana"
- },
- "application/whoispp-response": {
- "source": "iana"
- },
- "application/widget": {
- "source": "iana",
- "extensions": ["wgt"]
- },
- "application/winhlp": {
- "source": "apache",
- "extensions": ["hlp"]
- },
- "application/wita": {
- "source": "iana"
- },
- "application/wordperfect5.1": {
- "source": "iana"
- },
- "application/wsdl+xml": {
- "source": "iana",
- "extensions": ["wsdl"]
- },
- "application/wspolicy+xml": {
- "source": "iana",
- "extensions": ["wspolicy"]
- },
- "application/x-7z-compressed": {
- "source": "apache",
- "compressible": false,
- "extensions": ["7z"]
- },
- "application/x-abiword": {
- "source": "apache",
- "extensions": ["abw"]
- },
- "application/x-ace-compressed": {
- "source": "apache",
- "extensions": ["ace"]
- },
- "application/x-amf": {
- "source": "apache"
- },
- "application/x-apple-diskimage": {
- "source": "apache",
- "extensions": ["dmg"]
- },
- "application/x-authorware-bin": {
- "source": "apache",
- "extensions": ["aab","x32","u32","vox"]
- },
- "application/x-authorware-map": {
- "source": "apache",
- "extensions": ["aam"]
- },
- "application/x-authorware-seg": {
- "source": "apache",
- "extensions": ["aas"]
- },
- "application/x-bcpio": {
- "source": "apache",
- "extensions": ["bcpio"]
- },
- "application/x-bittorrent": {
- "source": "apache",
- "extensions": ["torrent"]
- },
- "application/x-blorb": {
- "source": "apache",
- "extensions": ["blb","blorb"]
- },
- "application/x-bzip": {
- "source": "apache",
- "compressible": false,
- "extensions": ["bz"]
- },
- "application/x-bzip2": {
- "source": "apache",
- "compressible": false,
- "extensions": ["bz2","boz"]
- },
- "application/x-cbr": {
- "source": "apache",
- "extensions": ["cbr","cba","cbt","cbz","cb7"]
- },
- "application/x-cdlink": {
- "source": "apache",
- "extensions": ["vcd"]
- },
- "application/x-cfs-compressed": {
- "source": "apache",
- "extensions": ["cfs"]
- },
- "application/x-chat": {
- "source": "apache",
- "extensions": ["chat"]
- },
- "application/x-chess-pgn": {
- "source": "apache",
- "extensions": ["pgn"]
- },
- "application/x-chrome-extension": {
- "extensions": ["crx"]
- },
- "application/x-compress": {
- "source": "apache"
- },
- "application/x-conference": {
- "source": "apache",
- "extensions": ["nsc"]
- },
- "application/x-cpio": {
- "source": "apache",
- "extensions": ["cpio"]
- },
- "application/x-csh": {
- "source": "apache",
- "extensions": ["csh"]
- },
- "application/x-deb": {
- "compressible": false
- },
- "application/x-debian-package": {
- "source": "apache",
- "extensions": ["deb","udeb"]
- },
- "application/x-dgc-compressed": {
- "source": "apache",
- "extensions": ["dgc"]
- },
- "application/x-director": {
- "source": "apache",
- "extensions": ["dir","dcr","dxr","cst","cct","cxt","w3d","fgd","swa"]
- },
- "application/x-doom": {
- "source": "apache",
- "extensions": ["wad"]
- },
- "application/x-dtbncx+xml": {
- "source": "apache",
- "extensions": ["ncx"]
- },
- "application/x-dtbook+xml": {
- "source": "apache",
- "extensions": ["dtb"]
- },
- "application/x-dtbresource+xml": {
- "source": "apache",
- "extensions": ["res"]
- },
- "application/x-dvi": {
- "source": "apache",
- "compressible": false,
- "extensions": ["dvi"]
- },
- "application/x-envoy": {
- "source": "apache",
- "extensions": ["evy"]
- },
- "application/x-eva": {
- "source": "apache",
- "extensions": ["eva"]
- },
- "application/x-font-bdf": {
- "source": "apache",
- "extensions": ["bdf"]
- },
- "application/x-font-dos": {
- "source": "apache"
- },
- "application/x-font-framemaker": {
- "source": "apache"
- },
- "application/x-font-ghostscript": {
- "source": "apache",
- "extensions": ["gsf"]
- },
- "application/x-font-libgrx": {
- "source": "apache"
- },
- "application/x-font-linux-psf": {
- "source": "apache",
- "extensions": ["psf"]
- },
- "application/x-font-otf": {
- "source": "apache",
- "compressible": true,
- "extensions": ["otf"]
- },
- "application/x-font-pcf": {
- "source": "apache",
- "extensions": ["pcf"]
- },
- "application/x-font-snf": {
- "source": "apache",
- "extensions": ["snf"]
- },
- "application/x-font-speedo": {
- "source": "apache"
- },
- "application/x-font-sunos-news": {
- "source": "apache"
- },
- "application/x-font-ttf": {
- "source": "apache",
- "compressible": true,
- "extensions": ["ttf","ttc"]
- },
- "application/x-font-type1": {
- "source": "apache",
- "extensions": ["pfa","pfb","pfm","afm"]
- },
- "application/x-font-vfont": {
- "source": "apache"
- },
- "application/x-freearc": {
- "source": "apache",
- "extensions": ["arc"]
- },
- "application/x-futuresplash": {
- "source": "apache",
- "extensions": ["spl"]
- },
- "application/x-gca-compressed": {
- "source": "apache",
- "extensions": ["gca"]
- },
- "application/x-glulx": {
- "source": "apache",
- "extensions": ["ulx"]
- },
- "application/x-gnumeric": {
- "source": "apache",
- "extensions": ["gnumeric"]
- },
- "application/x-gramps-xml": {
- "source": "apache",
- "extensions": ["gramps"]
- },
- "application/x-gtar": {
- "source": "apache",
- "extensions": ["gtar"]
- },
- "application/x-gzip": {
- "source": "apache"
- },
- "application/x-hdf": {
- "source": "apache",
- "extensions": ["hdf"]
- },
- "application/x-install-instructions": {
- "source": "apache",
- "extensions": ["install"]
- },
- "application/x-iso9660-image": {
- "source": "apache",
- "extensions": ["iso"]
- },
- "application/x-java-jnlp-file": {
- "source": "apache",
- "compressible": false,
- "extensions": ["jnlp"]
- },
- "application/x-javascript": {
- "compressible": true
- },
- "application/x-latex": {
- "source": "apache",
- "compressible": false,
- "extensions": ["latex"]
- },
- "application/x-lua-bytecode": {
- "extensions": ["luac"]
- },
- "application/x-lzh-compressed": {
- "source": "apache",
- "extensions": ["lzh","lha"]
- },
- "application/x-mie": {
- "source": "apache",
- "extensions": ["mie"]
- },
- "application/x-mobipocket-ebook": {
- "source": "apache",
- "extensions": ["prc","mobi"]
- },
- "application/x-mpegurl": {
- "compressible": false
- },
- "application/x-ms-application": {
- "source": "apache",
- "extensions": ["application"]
- },
- "application/x-ms-shortcut": {
- "source": "apache",
- "extensions": ["lnk"]
- },
- "application/x-ms-wmd": {
- "source": "apache",
- "extensions": ["wmd"]
- },
- "application/x-ms-wmz": {
- "source": "apache",
- "extensions": ["wmz"]
- },
- "application/x-ms-xbap": {
- "source": "apache",
- "extensions": ["xbap"]
- },
- "application/x-msaccess": {
- "source": "apache",
- "extensions": ["mdb"]
- },
- "application/x-msbinder": {
- "source": "apache",
- "extensions": ["obd"]
- },
- "application/x-mscardfile": {
- "source": "apache",
- "extensions": ["crd"]
- },
- "application/x-msclip": {
- "source": "apache",
- "extensions": ["clp"]
- },
- "application/x-msdownload": {
- "source": "apache",
- "extensions": ["exe","dll","com","bat","msi"]
- },
- "application/x-msmediaview": {
- "source": "apache",
- "extensions": ["mvb","m13","m14"]
- },
- "application/x-msmetafile": {
- "source": "apache",
- "extensions": ["wmf","wmz","emf","emz"]
- },
- "application/x-msmoney": {
- "source": "apache",
- "extensions": ["mny"]
- },
- "application/x-mspublisher": {
- "source": "apache",
- "extensions": ["pub"]
- },
- "application/x-msschedule": {
- "source": "apache",
- "extensions": ["scd"]
- },
- "application/x-msterminal": {
- "source": "apache",
- "extensions": ["trm"]
- },
- "application/x-mswrite": {
- "source": "apache",
- "extensions": ["wri"]
- },
- "application/x-netcdf": {
- "source": "apache",
- "extensions": ["nc","cdf"]
- },
- "application/x-nzb": {
- "source": "apache",
- "extensions": ["nzb"]
- },
- "application/x-pkcs12": {
- "source": "apache",
- "compressible": false,
- "extensions": ["p12","pfx"]
- },
- "application/x-pkcs7-certificates": {
- "source": "apache",
- "extensions": ["p7b","spc"]
- },
- "application/x-pkcs7-certreqresp": {
- "source": "apache",
- "extensions": ["p7r"]
- },
- "application/x-rar-compressed": {
- "source": "apache",
- "compressible": false,
- "extensions": ["rar"]
- },
- "application/x-research-info-systems": {
- "source": "apache",
- "extensions": ["ris"]
- },
- "application/x-sh": {
- "source": "apache",
- "compressible": true,
- "extensions": ["sh"]
- },
- "application/x-shar": {
- "source": "apache",
- "extensions": ["shar"]
- },
- "application/x-shockwave-flash": {
- "source": "apache",
- "compressible": false,
- "extensions": ["swf"]
- },
- "application/x-silverlight-app": {
- "source": "apache",
- "extensions": ["xap"]
- },
- "application/x-sql": {
- "source": "apache",
- "extensions": ["sql"]
- },
- "application/x-stuffit": {
- "source": "apache",
- "compressible": false,
- "extensions": ["sit"]
- },
- "application/x-stuffitx": {
- "source": "apache",
- "extensions": ["sitx"]
- },
- "application/x-subrip": {
- "source": "apache",
- "extensions": ["srt"]
- },
- "application/x-sv4cpio": {
- "source": "apache",
- "extensions": ["sv4cpio"]
- },
- "application/x-sv4crc": {
- "source": "apache",
- "extensions": ["sv4crc"]
- },
- "application/x-t3vm-image": {
- "source": "apache",
- "extensions": ["t3"]
- },
- "application/x-tads": {
- "source": "apache",
- "extensions": ["gam"]
- },
- "application/x-tar": {
- "source": "apache",
- "compressible": true,
- "extensions": ["tar"]
- },
- "application/x-tcl": {
- "source": "apache",
- "extensions": ["tcl"]
- },
- "application/x-tex": {
- "source": "apache",
- "extensions": ["tex"]
- },
- "application/x-tex-tfm": {
- "source": "apache",
- "extensions": ["tfm"]
- },
- "application/x-texinfo": {
- "source": "apache",
- "extensions": ["texinfo","texi"]
- },
- "application/x-tgif": {
- "source": "apache",
- "extensions": ["obj"]
- },
- "application/x-ustar": {
- "source": "apache",
- "extensions": ["ustar"]
- },
- "application/x-wais-source": {
- "source": "apache",
- "extensions": ["src"]
- },
- "application/x-web-app-manifest+json": {
- "compressible": true,
- "extensions": ["webapp"]
- },
- "application/x-www-form-urlencode": {
- "compressible": false
- },
- "application/x-www-form-urlencoded": {
- "source": "iana"
- },
- "application/x-x509-ca-cert": {
- "source": "apache",
- "extensions": ["der","crt"]
- },
- "application/x-xfig": {
- "source": "apache",
- "extensions": ["fig"]
- },
- "application/x-xliff+xml": {
- "source": "apache",
- "extensions": ["xlf"]
- },
- "application/x-xpinstall": {
- "source": "apache",
- "compressible": false,
- "extensions": ["xpi"]
- },
- "application/x-xz": {
- "source": "apache",
- "extensions": ["xz"]
- },
- "application/x-zmachine": {
- "source": "apache",
- "extensions": ["z1","z2","z3","z4","z5","z6","z7","z8"]
- },
- "application/x400-bp": {
- "source": "iana"
- },
- "application/xacml+xml": {
- "source": "iana"
- },
- "application/xaml+xml": {
- "source": "apache",
- "extensions": ["xaml"]
- },
- "application/xcap-att+xml": {
- "source": "iana"
- },
- "application/xcap-caps+xml": {
- "source": "iana"
- },
- "application/xcap-diff+xml": {
- "source": "iana",
- "extensions": ["xdf"]
- },
- "application/xcap-el+xml": {
- "source": "iana"
- },
- "application/xcap-error+xml": {
- "source": "iana"
- },
- "application/xcap-ns+xml": {
- "source": "iana"
- },
- "application/xcon-conference-info+xml": {
- "source": "iana"
- },
- "application/xcon-conference-info-diff+xml": {
- "source": "iana"
- },
- "application/xenc+xml": {
- "source": "iana",
- "extensions": ["xenc"]
- },
- "application/xhtml+xml": {
- "source": "iana",
- "compressible": true,
- "extensions": ["xhtml","xht"]
- },
- "application/xhtml-voice+xml": {
- "source": "iana"
- },
- "application/xml": {
- "source": "iana",
- "compressible": true,
- "extensions": ["xml","xsl","xsd"]
- },
- "application/xml-dtd": {
- "source": "iana",
- "compressible": true,
- "extensions": ["dtd"]
- },
- "application/xml-external-parsed-entity": {
- "source": "iana"
- },
- "application/xml-patch+xml": {
- "source": "iana"
- },
- "application/xmpp+xml": {
- "source": "iana"
- },
- "application/xop+xml": {
- "source": "iana",
- "compressible": true,
- "extensions": ["xop"]
- },
- "application/xproc+xml": {
- "source": "apache",
- "extensions": ["xpl"]
- },
- "application/xslt+xml": {
- "source": "iana",
- "extensions": ["xslt"]
- },
- "application/xspf+xml": {
- "source": "apache",
- "extensions": ["xspf"]
- },
- "application/xv+xml": {
- "source": "iana",
- "extensions": ["mxml","xhvml","xvml","xvm"]
- },
- "application/yang": {
- "source": "iana",
- "extensions": ["yang"]
- },
- "application/yin+xml": {
- "source": "iana",
- "extensions": ["yin"]
- },
- "application/zip": {
- "source": "iana",
- "compressible": false,
- "extensions": ["zip"]
- },
- "application/zlib": {
- "source": "iana"
- },
- "audio/1d-interleaved-parityfec": {
- "source": "iana"
- },
- "audio/32kadpcm": {
- "source": "iana"
- },
- "audio/3gpp": {
- "source": "iana"
- },
- "audio/3gpp2": {
- "source": "iana"
- },
- "audio/ac3": {
- "source": "iana"
- },
- "audio/adpcm": {
- "source": "apache",
- "extensions": ["adp"]
- },
- "audio/amr": {
- "source": "iana"
- },
- "audio/amr-wb": {
- "source": "iana"
- },
- "audio/amr-wb+": {
- "source": "iana"
- },
- "audio/aptx": {
- "source": "iana"
- },
- "audio/asc": {
- "source": "iana"
- },
- "audio/atrac-advanced-lossless": {
- "source": "iana"
- },
- "audio/atrac-x": {
- "source": "iana"
- },
- "audio/atrac3": {
- "source": "iana"
- },
- "audio/basic": {
- "source": "iana",
- "compressible": false,
- "extensions": ["au","snd"]
- },
- "audio/bv16": {
- "source": "iana"
- },
- "audio/bv32": {
- "source": "iana"
- },
- "audio/clearmode": {
- "source": "iana"
- },
- "audio/cn": {
- "source": "iana"
- },
- "audio/dat12": {
- "source": "iana"
- },
- "audio/dls": {
- "source": "iana"
- },
- "audio/dsr-es201108": {
- "source": "iana"
- },
- "audio/dsr-es202050": {
- "source": "iana"
- },
- "audio/dsr-es202211": {
- "source": "iana"
- },
- "audio/dsr-es202212": {
- "source": "iana"
- },
- "audio/dv": {
- "source": "iana"
- },
- "audio/dvi4": {
- "source": "iana"
- },
- "audio/eac3": {
- "source": "iana"
- },
- "audio/encaprtp": {
- "source": "iana"
- },
- "audio/evrc": {
- "source": "iana"
- },
- "audio/evrc-qcp": {
- "source": "iana"
- },
- "audio/evrc0": {
- "source": "iana"
- },
- "audio/evrc1": {
- "source": "iana"
- },
- "audio/evrcb": {
- "source": "iana"
- },
- "audio/evrcb0": {
- "source": "iana"
- },
- "audio/evrcb1": {
- "source": "iana"
- },
- "audio/evrcnw": {
- "source": "iana"
- },
- "audio/evrcnw0": {
- "source": "iana"
- },
- "audio/evrcnw1": {
- "source": "iana"
- },
- "audio/evrcwb": {
- "source": "iana"
- },
- "audio/evrcwb0": {
- "source": "iana"
- },
- "audio/evrcwb1": {
- "source": "iana"
- },
- "audio/example": {
- "source": "iana"
- },
- "audio/fwdred": {
- "source": "iana"
- },
- "audio/g719": {
- "source": "iana"
- },
- "audio/g721": {
- "source": "iana"
- },
- "audio/g722": {
- "source": "iana"
- },
- "audio/g7221": {
- "source": "apache"
- },
- "audio/g723": {
- "source": "iana"
- },
- "audio/g726-16": {
- "source": "iana"
- },
- "audio/g726-24": {
- "source": "iana"
- },
- "audio/g726-32": {
- "source": "iana"
- },
- "audio/g726-40": {
- "source": "iana"
- },
- "audio/g728": {
- "source": "iana"
- },
- "audio/g729": {
- "source": "iana"
- },
- "audio/g7291": {
- "source": "iana"
- },
- "audio/g729d": {
- "source": "iana"
- },
- "audio/g729e": {
- "source": "iana"
- },
- "audio/gsm": {
- "source": "iana"
- },
- "audio/gsm-efr": {
- "source": "iana"
- },
- "audio/gsm-hr-08": {
- "source": "iana"
- },
- "audio/ilbc": {
- "source": "iana"
- },
- "audio/ip-mr_v2.5": {
- "source": "iana"
- },
- "audio/isac": {
- "source": "apache"
- },
- "audio/l16": {
- "source": "iana"
- },
- "audio/l20": {
- "source": "iana"
- },
- "audio/l24": {
- "source": "iana",
- "compressible": false
- },
- "audio/l8": {
- "source": "iana"
- },
- "audio/lpc": {
- "source": "iana"
- },
- "audio/midi": {
- "source": "apache",
- "extensions": ["mid","midi","kar","rmi"]
- },
- "audio/mobile-xmf": {
- "source": "iana"
- },
- "audio/mp4": {
- "source": "iana",
- "compressible": false,
- "extensions": ["mp4a","m4a"]
- },
- "audio/mp4a-latm": {
- "source": "iana"
- },
- "audio/mpa": {
- "source": "iana"
- },
- "audio/mpa-robust": {
- "source": "iana"
- },
- "audio/mpeg": {
- "source": "iana",
- "compressible": false,
- "extensions": ["mpga","mp2","mp2a","mp3","m2a","m3a"]
- },
- "audio/mpeg4-generic": {
- "source": "iana"
- },
- "audio/musepack": {
- "source": "apache"
- },
- "audio/ogg": {
- "source": "iana",
- "compressible": false,
- "extensions": ["oga","ogg","spx"]
- },
- "audio/opus": {
- "source": "apache"
- },
- "audio/parityfec": {
- "source": "iana"
- },
- "audio/pcma": {
- "source": "iana"
- },
- "audio/pcma-wb": {
- "source": "iana"
- },
- "audio/pcmu": {
- "source": "iana"
- },
- "audio/pcmu-wb": {
- "source": "iana"
- },
- "audio/prs.sid": {
- "source": "iana"
- },
- "audio/qcelp": {
- "source": "iana"
- },
- "audio/raptorfec": {
- "source": "iana"
- },
- "audio/red": {
- "source": "iana"
- },
- "audio/rtp-enc-aescm128": {
- "source": "iana"
- },
- "audio/rtp-midi": {
- "source": "iana"
- },
- "audio/rtploopback": {
- "source": "iana"
- },
- "audio/rtx": {
- "source": "iana"
- },
- "audio/s3m": {
- "source": "apache",
- "extensions": ["s3m"]
- },
- "audio/silk": {
- "source": "apache",
- "extensions": ["sil"]
- },
- "audio/smv": {
- "source": "iana"
- },
- "audio/smv-qcp": {
- "source": "iana"
- },
- "audio/smv0": {
- "source": "iana"
- },
- "audio/sp-midi": {
- "source": "iana"
- },
- "audio/speex": {
- "source": "iana"
- },
- "audio/t140c": {
- "source": "iana"
- },
- "audio/t38": {
- "source": "iana"
- },
- "audio/telephone-event": {
- "source": "iana"
- },
- "audio/tone": {
- "source": "iana"
- },
- "audio/uemclip": {
- "source": "iana"
- },
- "audio/ulpfec": {
- "source": "iana"
- },
- "audio/vdvi": {
- "source": "iana"
- },
- "audio/vmr-wb": {
- "source": "iana"
- },
- "audio/vnd.3gpp.iufp": {
- "source": "iana"
- },
- "audio/vnd.4sb": {
- "source": "iana"
- },
- "audio/vnd.audiokoz": {
- "source": "iana"
- },
- "audio/vnd.celp": {
- "source": "iana"
- },
- "audio/vnd.cisco.nse": {
- "source": "iana"
- },
- "audio/vnd.cmles.radio-events": {
- "source": "iana"
- },
- "audio/vnd.cns.anp1": {
- "source": "iana"
- },
- "audio/vnd.cns.inf1": {
- "source": "iana"
- },
- "audio/vnd.dece.audio": {
- "source": "iana",
- "extensions": ["uva","uvva"]
- },
- "audio/vnd.digital-winds": {
- "source": "iana",
- "extensions": ["eol"]
- },
- "audio/vnd.dlna.adts": {
- "source": "iana"
- },
- "audio/vnd.dolby.heaac.1": {
- "source": "iana"
- },
- "audio/vnd.dolby.heaac.2": {
- "source": "iana"
- },
- "audio/vnd.dolby.mlp": {
- "source": "iana"
- },
- "audio/vnd.dolby.mps": {
- "source": "iana"
- },
- "audio/vnd.dolby.pl2": {
- "source": "iana"
- },
- "audio/vnd.dolby.pl2x": {
- "source": "iana"
- },
- "audio/vnd.dolby.pl2z": {
- "source": "iana"
- },
- "audio/vnd.dolby.pulse.1": {
- "source": "iana"
- },
- "audio/vnd.dra": {
- "source": "iana",
- "extensions": ["dra"]
- },
- "audio/vnd.dts": {
- "source": "iana",
- "extensions": ["dts"]
- },
- "audio/vnd.dts.hd": {
- "source": "iana",
- "extensions": ["dtshd"]
- },
- "audio/vnd.dvb.file": {
- "source": "iana"
- },
- "audio/vnd.everad.plj": {
- "source": "iana"
- },
- "audio/vnd.hns.audio": {
- "source": "iana"
- },
- "audio/vnd.lucent.voice": {
- "source": "iana",
- "extensions": ["lvp"]
- },
- "audio/vnd.ms-playready.media.pya": {
- "source": "iana",
- "extensions": ["pya"]
- },
- "audio/vnd.nokia.mobile-xmf": {
- "source": "iana"
- },
- "audio/vnd.nortel.vbk": {
- "source": "iana"
- },
- "audio/vnd.nuera.ecelp4800": {
- "source": "iana",
- "extensions": ["ecelp4800"]
- },
- "audio/vnd.nuera.ecelp7470": {
- "source": "iana",
- "extensions": ["ecelp7470"]
- },
- "audio/vnd.nuera.ecelp9600": {
- "source": "iana",
- "extensions": ["ecelp9600"]
- },
- "audio/vnd.octel.sbc": {
- "source": "iana"
- },
- "audio/vnd.qcelp": {
- "source": "iana"
- },
- "audio/vnd.rhetorex.32kadpcm": {
- "source": "iana"
- },
- "audio/vnd.rip": {
- "source": "iana",
- "extensions": ["rip"]
- },
- "audio/vnd.rn-realaudio": {
- "compressible": false
- },
- "audio/vnd.sealedmedia.softseal-mpeg": {
- "source": "iana"
- },
- "audio/vnd.sealedmedia.softseal.mpeg": {
- "source": "apache"
- },
- "audio/vnd.vmx.cvsd": {
- "source": "iana"
- },
- "audio/vnd.wave": {
- "compressible": false
- },
- "audio/vorbis": {
- "source": "iana",
- "compressible": false
- },
- "audio/vorbis-config": {
- "source": "iana"
- },
- "audio/webm": {
- "source": "apache",
- "compressible": false,
- "extensions": ["weba"]
- },
- "audio/x-aac": {
- "source": "apache",
- "compressible": false,
- "extensions": ["aac"]
- },
- "audio/x-aiff": {
- "source": "apache",
- "extensions": ["aif","aiff","aifc"]
- },
- "audio/x-caf": {
- "source": "apache",
- "compressible": false,
- "extensions": ["caf"]
- },
- "audio/x-flac": {
- "source": "apache",
- "extensions": ["flac"]
- },
- "audio/x-matroska": {
- "source": "apache",
- "extensions": ["mka"]
- },
- "audio/x-mpegurl": {
- "source": "apache",
- "extensions": ["m3u"]
- },
- "audio/x-ms-wax": {
- "source": "apache",
- "extensions": ["wax"]
- },
- "audio/x-ms-wma": {
- "source": "apache",
- "extensions": ["wma"]
- },
- "audio/x-pn-realaudio": {
- "source": "apache",
- "extensions": ["ram","ra"]
- },
- "audio/x-pn-realaudio-plugin": {
- "source": "apache",
- "extensions": ["rmp"]
- },
- "audio/x-tta": {
- "source": "apache"
- },
- "audio/x-wav": {
- "source": "apache",
- "extensions": ["wav"]
- },
- "audio/xm": {
- "source": "apache",
- "extensions": ["xm"]
- },
- "chemical/x-cdx": {
- "source": "apache",
- "extensions": ["cdx"]
- },
- "chemical/x-cif": {
- "source": "apache",
- "extensions": ["cif"]
- },
- "chemical/x-cmdf": {
- "source": "apache",
- "extensions": ["cmdf"]
- },
- "chemical/x-cml": {
- "source": "apache",
- "extensions": ["cml"]
- },
- "chemical/x-csml": {
- "source": "apache",
- "extensions": ["csml"]
- },
- "chemical/x-pdb": {
- "source": "apache"
- },
- "chemical/x-xyz": {
- "source": "apache",
- "extensions": ["xyz"]
- },
- "font/opentype": {
- "compressible": true,
- "extensions": ["otf"]
- },
- "image/bmp": {
- "source": "apache",
- "compressible": true,
- "extensions": ["bmp"]
- },
- "image/cgm": {
- "source": "iana",
- "extensions": ["cgm"]
- },
- "image/example": {
- "source": "iana"
- },
- "image/fits": {
- "source": "iana"
- },
- "image/g3fax": {
- "source": "iana",
- "extensions": ["g3"]
- },
- "image/gif": {
- "source": "iana",
- "compressible": false,
- "extensions": ["gif"]
- },
- "image/ief": {
- "source": "iana",
- "extensions": ["ief"]
- },
- "image/jp2": {
- "source": "iana"
- },
- "image/jpeg": {
- "source": "iana",
- "compressible": false,
- "extensions": ["jpeg","jpg","jpe"]
- },
- "image/jpm": {
- "source": "iana"
- },
- "image/jpx": {
- "source": "iana"
- },
- "image/ktx": {
- "source": "iana",
- "extensions": ["ktx"]
- },
- "image/naplps": {
- "source": "iana"
- },
- "image/pjpeg": {
- "compressible": false
- },
- "image/png": {
- "source": "iana",
- "compressible": false,
- "extensions": ["png"]
- },
- "image/prs.btif": {
- "source": "iana",
- "extensions": ["btif"]
- },
- "image/prs.pti": {
- "source": "iana"
- },
- "image/pwg-raster": {
- "source": "iana"
- },
- "image/sgi": {
- "source": "apache",
- "extensions": ["sgi"]
- },
- "image/svg+xml": {
- "source": "iana",
- "compressible": true,
- "extensions": ["svg","svgz"]
- },
- "image/t38": {
- "source": "iana"
- },
- "image/tiff": {
- "source": "iana",
- "compressible": false,
- "extensions": ["tiff","tif"]
- },
- "image/tiff-fx": {
- "source": "iana"
- },
- "image/vnd-djvu": {
- "source": "iana"
- },
- "image/vnd-svf": {
- "source": "iana"
- },
- "image/vnd-wap-wbmp": {
- "source": "iana"
- },
- "image/vnd.adobe.photoshop": {
- "source": "iana",
- "compressible": true,
- "extensions": ["psd"]
- },
- "image/vnd.airzip.accelerator.azv": {
- "source": "iana"
- },
- "image/vnd.cns.inf2": {
- "source": "iana"
- },
- "image/vnd.dece.graphic": {
- "source": "iana",
- "extensions": ["uvi","uvvi","uvg","uvvg"]
- },
- "image/vnd.djvu": {
- "source": "apache",
- "extensions": ["djvu","djv"]
- },
- "image/vnd.dvb.subtitle": {
- "source": "iana",
- "extensions": ["sub"]
- },
- "image/vnd.dwg": {
- "source": "iana",
- "extensions": ["dwg"]
- },
- "image/vnd.dxf": {
- "source": "iana",
- "extensions": ["dxf"]
- },
- "image/vnd.fastbidsheet": {
- "source": "iana",
- "extensions": ["fbs"]
- },
- "image/vnd.fpx": {
- "source": "iana",
- "extensions": ["fpx"]
- },
- "image/vnd.fst": {
- "source": "iana",
- "extensions": ["fst"]
- },
- "image/vnd.fujixerox.edmics-mmr": {
- "source": "iana",
- "extensions": ["mmr"]
- },
- "image/vnd.fujixerox.edmics-rlc": {
- "source": "iana",
- "extensions": ["rlc"]
- },
- "image/vnd.globalgraphics.pgb": {
- "source": "iana"
- },
- "image/vnd.microsoft.icon": {
- "source": "iana"
- },
- "image/vnd.mix": {
- "source": "iana"
- },
- "image/vnd.ms-modi": {
- "source": "iana",
- "extensions": ["mdi"]
- },
- "image/vnd.ms-photo": {
- "source": "apache",
- "extensions": ["wdp"]
- },
- "image/vnd.net-fpx": {
- "source": "iana",
- "extensions": ["npx"]
- },
- "image/vnd.radiance": {
- "source": "iana"
- },
- "image/vnd.sealed-png": {
- "source": "iana"
- },
- "image/vnd.sealed.png": {
- "source": "apache"
- },
- "image/vnd.sealedmedia.softseal-gif": {
- "source": "iana"
- },
- "image/vnd.sealedmedia.softseal-jpg": {
- "source": "iana"
- },
- "image/vnd.sealedmedia.softseal.gif": {
- "source": "apache"
- },
- "image/vnd.sealedmedia.softseal.jpg": {
- "source": "apache"
- },
- "image/vnd.svf": {
- "source": "apache"
- },
- "image/vnd.tencent.tap": {
- "source": "iana"
- },
- "image/vnd.valve.source.texture": {
- "source": "iana"
- },
- "image/vnd.wap.wbmp": {
- "source": "apache",
- "extensions": ["wbmp"]
- },
- "image/vnd.xiff": {
- "source": "iana",
- "extensions": ["xif"]
- },
- "image/webp": {
- "source": "apache",
- "extensions": ["webp"]
- },
- "image/x-3ds": {
- "source": "apache",
- "extensions": ["3ds"]
- },
- "image/x-cmu-raster": {
- "source": "apache",
- "extensions": ["ras"]
- },
- "image/x-cmx": {
- "source": "apache",
- "extensions": ["cmx"]
- },
- "image/x-freehand": {
- "source": "apache",
- "extensions": ["fh","fhc","fh4","fh5","fh7"]
- },
- "image/x-icon": {
- "source": "apache",
- "compressible": true,
- "extensions": ["ico"]
- },
- "image/x-mrsid-image": {
- "source": "apache",
- "extensions": ["sid"]
- },
- "image/x-pcx": {
- "source": "apache",
- "extensions": ["pcx"]
- },
- "image/x-pict": {
- "source": "apache",
- "extensions": ["pic","pct"]
- },
- "image/x-portable-anymap": {
- "source": "apache",
- "extensions": ["pnm"]
- },
- "image/x-portable-bitmap": {
- "source": "apache",
- "extensions": ["pbm"]
- },
- "image/x-portable-graymap": {
- "source": "apache",
- "extensions": ["pgm"]
- },
- "image/x-portable-pixmap": {
- "source": "apache",
- "extensions": ["ppm"]
- },
- "image/x-rgb": {
- "source": "apache",
- "extensions": ["rgb"]
- },
- "image/x-tga": {
- "source": "apache",
- "extensions": ["tga"]
- },
- "image/x-xbitmap": {
- "source": "apache",
- "extensions": ["xbm"]
- },
- "image/x-xcf": {
- "compressible": false
- },
- "image/x-xpixmap": {
- "source": "apache",
- "extensions": ["xpm"]
- },
- "image/x-xwindowdump": {
- "source": "apache",
- "extensions": ["xwd"]
- },
- "message/cpim": {
- "source": "iana"
- },
- "message/delivery-status": {
- "source": "iana"
- },
- "message/disposition-notification": {
- "source": "iana"
- },
- "message/example": {
- "source": "iana"
- },
- "message/external-body": {
- "source": "iana"
- },
- "message/feedback-report": {
- "source": "iana"
- },
- "message/global": {
- "source": "iana"
- },
- "message/global-delivery-status": {
- "source": "iana"
- },
- "message/global-disposition-notification": {
- "source": "iana"
- },
- "message/global-headers": {
- "source": "iana"
- },
- "message/http": {
- "source": "iana",
- "compressible": false
- },
- "message/imdn+xml": {
- "source": "iana",
- "compressible": true
- },
- "message/news": {
- "source": "iana"
- },
- "message/partial": {
- "source": "iana",
- "compressible": false
- },
- "message/rfc822": {
- "source": "iana",
- "compressible": true,
- "extensions": ["eml","mime"]
- },
- "message/s-http": {
- "source": "iana"
- },
- "message/sip": {
- "source": "iana"
- },
- "message/sipfrag": {
- "source": "iana"
- },
- "message/tracking-status": {
- "source": "iana"
- },
- "message/vnd.si.simp": {
- "source": "iana"
- },
- "message/vnd.wfa.wsc": {
- "source": "iana"
- },
- "model/example": {
- "source": "iana",
- "compressible": false
- },
- "model/iges": {
- "source": "iana",
- "compressible": false,
- "extensions": ["igs","iges"]
- },
- "model/mesh": {
- "source": "iana",
- "compressible": false,
- "extensions": ["msh","mesh","silo"]
- },
- "model/vnd-dwf": {
- "source": "iana"
- },
- "model/vnd.collada+xml": {
- "source": "iana",
- "extensions": ["dae"]
- },
- "model/vnd.dwf": {
- "source": "apache",
- "extensions": ["dwf"]
- },
- "model/vnd.flatland.3dml": {
- "source": "iana"
- },
- "model/vnd.gdl": {
- "source": "iana",
- "extensions": ["gdl"]
- },
- "model/vnd.gs-gdl": {
- "source": "iana"
- },
- "model/vnd.gs.gdl": {
- "source": "apache"
- },
- "model/vnd.gtw": {
- "source": "iana",
- "extensions": ["gtw"]
- },
- "model/vnd.moml+xml": {
- "source": "iana"
- },
- "model/vnd.mts": {
- "source": "iana",
- "extensions": ["mts"]
- },
- "model/vnd.opengex": {
- "source": "iana"
- },
- "model/vnd.parasolid.transmit-binary": {
- "source": "iana"
- },
- "model/vnd.parasolid.transmit-text": {
- "source": "iana"
- },
- "model/vnd.parasolid.transmit.binary": {
- "source": "apache"
- },
- "model/vnd.parasolid.transmit.text": {
- "source": "apache"
- },
- "model/vnd.valve.source.compiled-map": {
- "source": "iana"
- },
- "model/vnd.vtu": {
- "source": "iana",
- "extensions": ["vtu"]
- },
- "model/vrml": {
- "source": "iana",
- "compressible": false,
- "extensions": ["wrl","vrml"]
- },
- "model/x3d+binary": {
- "source": "apache",
- "compressible": false,
- "extensions": ["x3db","x3dbz"]
- },
- "model/x3d+fastinfoset": {
- "source": "iana"
- },
- "model/x3d+vrml": {
- "source": "apache",
- "compressible": false,
- "extensions": ["x3dv","x3dvz"]
- },
- "model/x3d+xml": {
- "source": "iana",
- "compressible": true,
- "extensions": ["x3d","x3dz"]
- },
- "model/x3d-vrml": {
- "source": "iana"
- },
- "multipart/alternative": {
- "source": "iana",
- "compressible": false
- },
- "multipart/appledouble": {
- "source": "iana"
- },
- "multipart/byteranges": {
- "source": "iana"
- },
- "multipart/digest": {
- "source": "iana"
- },
- "multipart/encrypted": {
- "source": "iana",
- "compressible": false
- },
- "multipart/example": {
- "source": "iana"
- },
- "multipart/form-data": {
- "source": "iana",
- "compressible": false
- },
- "multipart/header-set": {
- "source": "iana"
- },
- "multipart/mixed": {
- "source": "iana",
- "compressible": false
- },
- "multipart/parallel": {
- "source": "iana"
- },
- "multipart/related": {
- "source": "iana",
- "compressible": false
- },
- "multipart/report": {
- "source": "iana"
- },
- "multipart/signed": {
- "source": "iana",
- "compressible": false
- },
- "multipart/voice-message": {
- "source": "iana"
- },
- "multipart/x-mixed-replace": {
- "source": "iana"
- },
- "text/1d-interleaved-parityfec": {
- "source": "iana"
- },
- "text/cache-manifest": {
- "source": "iana",
- "compressible": true,
- "extensions": ["appcache","manifest"]
- },
- "text/calendar": {
- "source": "iana",
- "extensions": ["ics","ifb"]
- },
- "text/calender": {
- "compressible": true
- },
- "text/cmd": {
- "compressible": true
- },
- "text/coffeescript": {
- "extensions": ["coffee"]
- },
- "text/css": {
- "source": "iana",
- "compressible": true,
- "extensions": ["css"]
- },
- "text/csv": {
- "source": "iana",
- "compressible": true,
- "extensions": ["csv"]
- },
- "text/directory": {
- "source": "iana"
- },
- "text/dns": {
- "source": "iana"
- },
- "text/ecmascript": {
- "source": "iana"
- },
- "text/encaprtp": {
- "source": "iana"
- },
- "text/enriched": {
- "source": "iana"
- },
- "text/example": {
- "source": "iana"
- },
- "text/fwdred": {
- "source": "iana"
- },
- "text/grammar-ref-list": {
- "source": "iana"
- },
- "text/html": {
- "source": "iana",
- "compressible": true,
- "extensions": ["html","htm"]
- },
- "text/jade": {
- "extensions": ["jade"]
- },
- "text/javascript": {
- "source": "iana",
- "compressible": true
- },
- "text/jcr-cnd": {
- "source": "iana"
- },
- "text/jsx": {
- "compressible": true,
- "extensions": ["jsx"]
- },
- "text/less": {
- "extensions": ["less"]
- },
- "text/mizar": {
- "source": "iana"
- },
- "text/n3": {
- "source": "iana",
- "compressible": true,
- "extensions": ["n3"]
- },
- "text/parameters": {
- "source": "iana"
- },
- "text/parityfec": {
- "source": "iana"
- },
- "text/plain": {
- "source": "iana",
- "compressible": true,
- "extensions": ["txt","text","conf","def","list","log","in","ini"]
- },
- "text/provenance-notation": {
- "source": "iana"
- },
- "text/prs.fallenstein.rst": {
- "source": "iana"
- },
- "text/prs.lines.tag": {
- "source": "iana",
- "extensions": ["dsc"]
- },
- "text/raptorfec": {
- "source": "iana"
- },
- "text/red": {
- "source": "iana"
- },
- "text/rfc822-headers": {
- "source": "iana"
- },
- "text/richtext": {
- "source": "iana",
- "compressible": true,
- "extensions": ["rtx"]
- },
- "text/rtf": {
- "source": "iana"
- },
- "text/rtp-enc-aescm128": {
- "source": "iana"
- },
- "text/rtploopback": {
- "source": "iana"
- },
- "text/rtx": {
- "source": "iana"
- },
- "text/sgml": {
- "source": "iana",
- "extensions": ["sgml","sgm"]
- },
- "text/stylus": {
- "extensions": ["stylus","styl"]
- },
- "text/t140": {
- "source": "iana"
- },
- "text/tab-separated-values": {
- "source": "iana",
- "compressible": true,
- "extensions": ["tsv"]
- },
- "text/troff": {
- "source": "iana",
- "extensions": ["t","tr","roff","man","me","ms"]
- },
- "text/turtle": {
- "source": "iana",
- "extensions": ["ttl"]
- },
- "text/ulpfec": {
- "source": "iana"
- },
- "text/uri-list": {
- "source": "iana",
- "compressible": true,
- "extensions": ["uri","uris","urls"]
- },
- "text/vcard": {
- "source": "iana",
- "compressible": true,
- "extensions": ["vcard"]
- },
- "text/vnd-a": {
- "source": "iana"
- },
- "text/vnd-curl": {
- "source": "iana"
- },
- "text/vnd.abc": {
- "source": "iana"
- },
- "text/vnd.curl": {
- "source": "apache",
- "extensions": ["curl"]
- },
- "text/vnd.curl.dcurl": {
- "source": "apache",
- "extensions": ["dcurl"]
- },
- "text/vnd.curl.mcurl": {
- "source": "apache",
- "extensions": ["mcurl"]
- },
- "text/vnd.curl.scurl": {
- "source": "apache",
- "extensions": ["scurl"]
- },
- "text/vnd.debian.copyright": {
- "source": "iana"
- },
- "text/vnd.dmclientscript": {
- "source": "iana"
- },
- "text/vnd.dvb.subtitle": {
- "source": "iana",
- "extensions": ["sub"]
- },
- "text/vnd.esmertec.theme-descriptor": {
- "source": "iana"
- },
- "text/vnd.fly": {
- "source": "iana",
- "extensions": ["fly"]
- },
- "text/vnd.fmi.flexstor": {
- "source": "iana",
- "extensions": ["flx"]
- },
- "text/vnd.graphviz": {
- "source": "iana",
- "extensions": ["gv"]
- },
- "text/vnd.in3d.3dml": {
- "source": "iana",
- "extensions": ["3dml"]
- },
- "text/vnd.in3d.spot": {
- "source": "iana",
- "extensions": ["spot"]
- },
- "text/vnd.iptc.newsml": {
- "source": "iana"
- },
- "text/vnd.iptc.nitf": {
- "source": "iana"
- },
- "text/vnd.latex-z": {
- "source": "iana"
- },
- "text/vnd.motorola.reflex": {
- "source": "iana"
- },
- "text/vnd.ms-mediapackage": {
- "source": "iana"
- },
- "text/vnd.net2phone.commcenter.command": {
- "source": "iana"
- },
- "text/vnd.radisys.msml-basic-layout": {
- "source": "iana"
- },
- "text/vnd.si.uricatalogue": {
- "source": "iana"
- },
- "text/vnd.sun.j2me.app-descriptor": {
- "source": "iana",
- "extensions": ["jad"]
- },
- "text/vnd.trolltech.linguist": {
- "source": "iana"
- },
- "text/vnd.wap-wml": {
- "source": "iana"
- },
- "text/vnd.wap.si": {
- "source": "iana"
- },
- "text/vnd.wap.sl": {
- "source": "iana"
- },
- "text/vnd.wap.wml": {
- "source": "apache",
- "extensions": ["wml"]
- },
- "text/vnd.wap.wmlscript": {
- "source": "iana",
- "extensions": ["wmls"]
- },
- "text/vtt": {
- "charset": "UTF-8",
- "compressible": true,
- "extensions": ["vtt"]
- },
- "text/x-asm": {
- "source": "apache",
- "extensions": ["s","asm"]
- },
- "text/x-c": {
- "source": "apache",
- "extensions": ["c","cc","cxx","cpp","h","hh","dic"]
- },
- "text/x-component": {
- "extensions": ["htc"]
- },
- "text/x-fortran": {
- "source": "apache",
- "extensions": ["f","for","f77","f90"]
- },
- "text/x-gwt-rpc": {
- "compressible": true
- },
- "text/x-handlebars-template": {
- "extensions": ["hbs"]
- },
- "text/x-java-source": {
- "source": "apache",
- "extensions": ["java"]
- },
- "text/x-jquery-tmpl": {
- "compressible": true
- },
- "text/x-lua": {
- "extensions": ["lua"]
- },
- "text/x-markdown": {
- "compressible": true,
- "extensions": ["markdown","md","mkd"]
- },
- "text/x-nfo": {
- "source": "apache",
- "extensions": ["nfo"]
- },
- "text/x-opml": {
- "source": "apache",
- "extensions": ["opml"]
- },
- "text/x-pascal": {
- "source": "apache",
- "extensions": ["p","pas"]
- },
- "text/x-sass": {
- "extensions": ["sass"]
- },
- "text/x-scss": {
- "extensions": ["scss"]
- },
- "text/x-setext": {
- "source": "apache",
- "extensions": ["etx"]
- },
- "text/x-sfv": {
- "source": "apache",
- "extensions": ["sfv"]
- },
- "text/x-uuencode": {
- "source": "apache",
- "extensions": ["uu"]
- },
- "text/x-vcalendar": {
- "source": "apache",
- "extensions": ["vcs"]
- },
- "text/x-vcard": {
- "source": "apache",
- "extensions": ["vcf"]
- },
- "text/xml": {
- "source": "iana",
- "compressible": true
- },
- "text/xml-external-parsed-entity": {
- "source": "iana"
- },
- "video/1d-interleaved-parityfec": {
- "source": "apache"
- },
- "video/3gpp": {
- "source": "apache",
- "extensions": ["3gp"]
- },
- "video/3gpp-tt": {
- "source": "apache"
- },
- "video/3gpp2": {
- "source": "apache",
- "extensions": ["3g2"]
- },
- "video/bmpeg": {
- "source": "apache"
- },
- "video/bt656": {
- "source": "apache"
- },
- "video/celb": {
- "source": "apache"
- },
- "video/dv": {
- "source": "apache"
- },
- "video/example": {
- "source": "apache"
- },
- "video/h261": {
- "source": "apache",
- "extensions": ["h261"]
- },
- "video/h263": {
- "source": "apache",
- "extensions": ["h263"]
- },
- "video/h263-1998": {
- "source": "apache"
- },
- "video/h263-2000": {
- "source": "apache"
- },
- "video/h264": {
- "source": "apache",
- "extensions": ["h264"]
- },
- "video/h264-rcdo": {
- "source": "apache"
- },
- "video/h264-svc": {
- "source": "apache"
- },
- "video/jpeg": {
- "source": "apache",
- "extensions": ["jpgv"]
- },
- "video/jpeg2000": {
- "source": "apache"
- },
- "video/jpm": {
- "source": "apache",
- "extensions": ["jpm","jpgm"]
- },
- "video/mj2": {
- "source": "apache",
- "extensions": ["mj2","mjp2"]
- },
- "video/mp1s": {
- "source": "apache"
- },
- "video/mp2p": {
- "source": "apache"
- },
- "video/mp2t": {
- "source": "apache",
- "extensions": ["ts"]
- },
- "video/mp4": {
- "source": "apache",
- "compressible": false,
- "extensions": ["mp4","mp4v","mpg4"]
- },
- "video/mp4v-es": {
- "source": "apache"
- },
- "video/mpeg": {
- "source": "apache",
- "compressible": false,
- "extensions": ["mpeg","mpg","mpe","m1v","m2v"]
- },
- "video/mpeg4-generic": {
- "source": "apache"
- },
- "video/mpv": {
- "source": "apache"
- },
- "video/nv": {
- "source": "apache"
- },
- "video/ogg": {
- "source": "apache",
- "compressible": false,
- "extensions": ["ogv"]
- },
- "video/parityfec": {
- "source": "apache"
- },
- "video/pointer": {
- "source": "apache"
- },
- "video/quicktime": {
- "source": "apache",
- "compressible": false,
- "extensions": ["qt","mov"]
- },
- "video/raw": {
- "source": "apache"
- },
- "video/rtp-enc-aescm128": {
- "source": "apache"
- },
- "video/rtx": {
- "source": "apache"
- },
- "video/smpte292m": {
- "source": "apache"
- },
- "video/ulpfec": {
- "source": "apache"
- },
- "video/vc1": {
- "source": "apache"
- },
- "video/vnd.cctv": {
- "source": "apache"
- },
- "video/vnd.dece.hd": {
- "source": "apache",
- "extensions": ["uvh","uvvh"]
- },
- "video/vnd.dece.mobile": {
- "source": "apache",
- "extensions": ["uvm","uvvm"]
- },
- "video/vnd.dece.mp4": {
- "source": "apache"
- },
- "video/vnd.dece.pd": {
- "source": "apache",
- "extensions": ["uvp","uvvp"]
- },
- "video/vnd.dece.sd": {
- "source": "apache",
- "extensions": ["uvs","uvvs"]
- },
- "video/vnd.dece.video": {
- "source": "apache",
- "extensions": ["uvv","uvvv"]
- },
- "video/vnd.directv.mpeg": {
- "source": "apache"
- },
- "video/vnd.directv.mpeg-tts": {
- "source": "apache"
- },
- "video/vnd.dlna.mpeg-tts": {
- "source": "apache"
- },
- "video/vnd.dvb.file": {
- "source": "apache",
- "extensions": ["dvb"]
- },
- "video/vnd.fvt": {
- "source": "apache",
- "extensions": ["fvt"]
- },
- "video/vnd.hns.video": {
- "source": "apache"
- },
- "video/vnd.iptvforum.1dparityfec-1010": {
- "source": "apache"
- },
- "video/vnd.iptvforum.1dparityfec-2005": {
- "source": "apache"
- },
- "video/vnd.iptvforum.2dparityfec-1010": {
- "source": "apache"
- },
- "video/vnd.iptvforum.2dparityfec-2005": {
- "source": "apache"
- },
- "video/vnd.iptvforum.ttsavc": {
- "source": "apache"
- },
- "video/vnd.iptvforum.ttsmpeg2": {
- "source": "apache"
- },
- "video/vnd.motorola.video": {
- "source": "apache"
- },
- "video/vnd.motorola.videop": {
- "source": "apache"
- },
- "video/vnd.mpegurl": {
- "source": "apache",
- "extensions": ["mxu","m4u"]
- },
- "video/vnd.ms-playready.media.pyv": {
- "source": "apache",
- "extensions": ["pyv"]
- },
- "video/vnd.nokia.interleaved-multimedia": {
- "source": "apache"
- },
- "video/vnd.nokia.videovoip": {
- "source": "apache"
- },
- "video/vnd.objectvideo": {
- "source": "apache"
- },
- "video/vnd.sealed.mpeg1": {
- "source": "apache"
- },
- "video/vnd.sealed.mpeg4": {
- "source": "apache"
- },
- "video/vnd.sealed.swf": {
- "source": "apache"
- },
- "video/vnd.sealedmedia.softseal.mov": {
- "source": "apache"
- },
- "video/vnd.uvvu.mp4": {
- "source": "apache",
- "extensions": ["uvu","uvvu"]
- },
- "video/vnd.vivo": {
- "source": "apache",
- "extensions": ["viv"]
- },
- "video/webm": {
- "source": "apache",
- "compressible": false,
- "extensions": ["webm"]
- },
- "video/x-f4v": {
- "source": "apache",
- "extensions": ["f4v"]
- },
- "video/x-fli": {
- "source": "apache",
- "extensions": ["fli"]
- },
- "video/x-flv": {
- "source": "apache",
- "compressible": false,
- "extensions": ["flv"]
- },
- "video/x-m4v": {
- "source": "apache",
- "extensions": ["m4v"]
- },
- "video/x-matroska": {
- "source": "apache",
- "compressible": false,
- "extensions": ["mkv","mk3d","mks"]
- },
- "video/x-mng": {
- "source": "apache",
- "extensions": ["mng"]
- },
- "video/x-ms-asf": {
- "source": "apache",
- "extensions": ["asf","asx"]
- },
- "video/x-ms-vob": {
- "source": "apache",
- "extensions": ["vob"]
- },
- "video/x-ms-wm": {
- "source": "apache",
- "extensions": ["wm"]
- },
- "video/x-ms-wmv": {
- "source": "apache",
- "compressible": false,
- "extensions": ["wmv"]
- },
- "video/x-ms-wmx": {
- "source": "apache",
- "extensions": ["wmx"]
- },
- "video/x-ms-wvx": {
- "source": "apache",
- "extensions": ["wvx"]
- },
- "video/x-msvideo": {
- "source": "apache",
- "extensions": ["avi"]
- },
- "video/x-sgi-movie": {
- "source": "apache",
- "extensions": ["movie"]
- },
- "video/x-smv": {
- "source": "apache",
- "extensions": ["smv"]
- },
- "x-conference/x-cooltalk": {
- "source": "apache",
- "extensions": ["ice"]
- },
- "x-shader/x-fragment": {
- "compressible": true
- },
- "x-shader/x-vertex": {
- "compressible": true
- }
-}
diff --git a/CoAuthoring/node_modules/express/node_modules/accepts/node_modules/mime-types/node_modules/mime-db/index.js b/CoAuthoring/node_modules/express/node_modules/accepts/node_modules/mime-types/node_modules/mime-db/index.js
deleted file mode 100644
index 551031f690..0000000000
--- a/CoAuthoring/node_modules/express/node_modules/accepts/node_modules/mime-types/node_modules/mime-db/index.js
+++ /dev/null
@@ -1,11 +0,0 @@
-/*!
- * mime-db
- * Copyright(c) 2014 Jonathan Ong
- * MIT Licensed
- */
-
-/**
- * Module exports.
- */
-
-module.exports = require('./db.json')
diff --git a/CoAuthoring/node_modules/express/node_modules/accepts/node_modules/mime-types/node_modules/mime-db/package.json b/CoAuthoring/node_modules/express/node_modules/accepts/node_modules/mime-types/node_modules/mime-db/package.json
deleted file mode 100644
index 1a45988571..0000000000
--- a/CoAuthoring/node_modules/express/node_modules/accepts/node_modules/mime-types/node_modules/mime-db/package.json
+++ /dev/null
@@ -1,56 +0,0 @@
-{
- "name": "mime-db",
- "description": "Media Type Database",
- "version": "1.1.1",
- "author": {
- "name": "Jonathan Ong",
- "email": "me@jongleberry.com",
- "url": "http://jongleberry.com"
- },
- "license": "MIT",
- "repository": {
- "type": "git",
- "url": "git://github.com/jshttp/mime-db"
- },
- "devDependencies": {
- "co": "3",
- "cogent": "1",
- "csv-parse": "0",
- "gnode": "0.1.0",
- "istanbul": "0.3.2",
- "mocha": "~1.21.4",
- "stream-to-array": "2"
- },
- "engines": {
- "node": ">= 0.6"
- },
- "files": [
- "LICENSE",
- "db.json",
- "index.js"
- ],
- "scripts": {
- "update": "gnode scripts/extensions && gnode scripts/types && node scripts/build",
- "clean": "rm src/*",
- "test": "mocha --reporter spec --bail --check-leaks test/",
- "test-cov": "istanbul cover node_modules/mocha/bin/_mocha -- --reporter dot --check-leaks test/",
- "test-travis": "istanbul cover node_modules/mocha/bin/_mocha --report lcovonly -- --reporter spec --check-leaks test/"
- },
- "keywords": [
- "mime",
- "db",
- "type",
- "types",
- "database",
- "charset",
- "charsets"
- ],
- "readme": "# mime-db\n\n[![NPM Version][npm-version-image]][npm-url]\n[![NPM Downloads][npm-downloads-image]][npm-url]\n[![Node.js Version][node-image]][node-url]\n[![Build Status][travis-image]][travis-url]\n[![Coverage Status][coveralls-image]][coveralls-url]\n\nThis is a database of all mime types.\nIt consistents of a single, public JSON file and does not include any logic,\nallowing it to remain as unopinionated as possible with an API.\nIt aggregates data from the following sources:\n\n- http://www.iana.org/assignments/media-types/media-types.xhtml\n- http://svn.apache.org/repos/asf/httpd/httpd/trunk/docs/conf/mime.types\n\n## Usage\n\n```bash\nnpm i mime-db\n```\n\n```js\nvar db = require('mime-db');\n\n// grab data on .js files\nvar data = db['application/javascript'];\n```\n\nIf you're crazy enough to use this in the browser,\nyou can just grab the JSON file:\n\n```\nhttps://cdn.rawgit.com/jshttp/mime-db/master/db.json\n```\n\n## Data Structure\n\nThe JSON file is a map lookup for lowercased mime types.\nEach mime type has the following properties:\n\n- `.source` - where the mime type is defined.\n If not set, it's probably a custom media type.\n - `apache` - [Apache common media types](http://svn.apache.org/repos/asf/httpd/httpd/trunk/docs/conf/mime.types)\n - `iana` - [IANA-defined media types](http://www.iana.org/assignments/media-types/media-types.xhtml)\n- `.extensions[]` - known extensions associated with this mime type.\n- `.compressible` - whether a file of this type is can be gzipped.\n- `.charset` - the default charset associated with this type, if any.\n\nIf unknown, every property could be `undefined`.\n\n## Repository Structure\n\n- `scripts` - these are scripts to run to build the database\n- `src/` - this is a folder of files created from remote sources like Apache and IANA\n- `lib/` - this is a folder of our own custom sources and db, which will be merged into `db.json`\n- `db.json` - the final built JSON file for end-user usage\n\n## Contributing\n\nTo edit the database, only make PRs against files in the `lib/` folder.\nTo update the build, run `npm run update`.\n\n[npm-version-image]: https://img.shields.io/npm/v/mime-db.svg?style=flat\n[npm-downloads-image]: https://img.shields.io/npm/dm/mime-db.svg?style=flat\n[npm-url]: https://npmjs.org/package/mime-db\n[travis-image]: https://img.shields.io/travis/jshttp/mime-db.svg?style=flat\n[travis-url]: https://travis-ci.org/jshttp/mime-db\n[coveralls-image]: https://img.shields.io/coveralls/jshttp/mime-db.svg?style=flat\n[coveralls-url]: https://coveralls.io/r/jshttp/mime-db?branch=master\n[node-image]: https://img.shields.io/node/v/mime-db.svg?style=flat\n[node-url]: http://nodejs.org/download/\n",
- "readmeFilename": "README.md",
- "bugs": {
- "url": "https://github.com/jshttp/mime-db/issues"
- },
- "homepage": "https://github.com/jshttp/mime-db",
- "_id": "mime-db@1.1.1",
- "_from": "mime-db@~1.1.0"
-}
diff --git a/CoAuthoring/node_modules/express/node_modules/accepts/node_modules/mime-types/package.json b/CoAuthoring/node_modules/express/node_modules/accepts/node_modules/mime-types/package.json
deleted file mode 100644
index 45e7d2b8be..0000000000
--- a/CoAuthoring/node_modules/express/node_modules/accepts/node_modules/mime-types/package.json
+++ /dev/null
@@ -1,54 +0,0 @@
-{
- "name": "mime-types",
- "description": "The ultimate javascript content-type utility.",
- "version": "2.0.2",
- "contributors": [
- {
- "name": "Jeremiah Senkpiel",
- "email": "fishrock123@rocketmail.com",
- "url": "https://searchbeam.jit.su"
- },
- {
- "name": "Jonathan Ong",
- "email": "me@jongleberry.com",
- "url": "http://jongleberry.com"
- }
- ],
- "license": "MIT",
- "keywords": [
- "mime",
- "types"
- ],
- "repository": {
- "type": "git",
- "url": "git://github.com/jshttp/mime-types"
- },
- "dependencies": {
- "mime-db": "~1.1.0"
- },
- "devDependencies": {
- "istanbul": "0",
- "mocha": "1"
- },
- "files": [
- "HISTORY.md",
- "LICENSE",
- "index.js"
- ],
- "engines": {
- "node": ">= 0.6"
- },
- "scripts": {
- "test": "mocha --reporter spec test/test.js",
- "test-cov": "istanbul cover node_modules/mocha/bin/_mocha -- --reporter dot test/test.js",
- "test-travis": "istanbul cover node_modules/mocha/bin/_mocha --report lcovonly -- --reporter dot test/test.js"
- },
- "readme": "# mime-types\n\n[![NPM Version][npm-image]][npm-url]\n[![NPM Downloads][downloads-image]][downloads-url]\n[![Node.js Version][node-version-image]][node-version-url]\n[![Build Status][travis-image]][travis-url]\n[![Test Coverage][coveralls-image]][coveralls-url]\n\nThe ultimate javascript content-type utility.\n\nSimilar to [node-mime](https://github.com/broofa/node-mime), except:\n\n- __No fallbacks.__ Instead of naively returning the first available type, `mime-types` simply returns `false`,\n so do `var type = mime.lookup('unrecognized') || 'application/octet-stream'`.\n- No `new Mime()` business, so you could do `var lookup = require('mime-types').lookup`.\n- Additional mime types are added such as jade and stylus via [mime-db](https://github.com/jshttp/mime-db)\n- No `.define()` functionality\n\nOtherwise, the API is compatible.\n\n## Install\n\n```sh\n$ npm install mime-types\n```\n\n## Adding Types\n\nAll mime types are based on [mime-db](https://github.com/jshttp/mime-db),\nso open a PR there if you'd like to add mime types.\n\n## API\n\n```js\nvar mime = require('mime-types')\n```\n\nAll functions return `false` if input is invalid or not found.\n\n### mime.lookup(path)\n\nLookup the content-type associated with a file.\n\n```js\nmime.lookup('json') // 'application/json'\nmime.lookup('.md') // 'text/x-markdown'\nmime.lookup('file.html') // 'text/html'\nmime.lookup('folder/file.js') // 'application/javascript'\n\nmime.lookup('cats') // false\n```\n\n### mime.contentType(type)\n\nCreate a full content-type header given a content-type or extension.\n\n```js\nmime.contentType('markdown') // 'text/x-markdown; charset=utf-8'\nmime.contentType('file.json') // 'application/json; charset=utf-8'\n```\n\n### mime.extension(type)\n\nGet the default extension for a content-type.\n\n```js\nmime.extension('application/octet-stream') // 'bin'\n```\n\n### mime.charset(type)\n\nLookup the implied default charset of a content-type.\n\n```js\nmime.charset('text/x-markdown') // 'UTF-8'\n```\n\n### var type = mime.types[extension]\n\nA map of content-types by extension.\n\n### [extensions...] = mime.extensions[type]\n\nA map of extensions by content-type.\n\n## License\n\n[MIT](LICENSE)\n\n[npm-image]: https://img.shields.io/npm/v/mime-types.svg?style=flat\n[npm-url]: https://npmjs.org/package/mime-types\n[node-version-image]: https://img.shields.io/badge/node.js-%3E%3D_0.6-brightgreen.svg?style=flat\n[node-version-url]: http://nodejs.org/download/\n[travis-image]: https://img.shields.io/travis/jshttp/mime-types.svg?style=flat\n[travis-url]: https://travis-ci.org/jshttp/mime-types\n[coveralls-image]: https://img.shields.io/coveralls/jshttp/mime-types.svg?style=flat\n[coveralls-url]: https://coveralls.io/r/jshttp/mime-types\n[downloads-image]: https://img.shields.io/npm/dm/mime-types.svg?style=flat\n[downloads-url]: https://npmjs.org/package/mime-types\n",
- "readmeFilename": "README.md",
- "bugs": {
- "url": "https://github.com/jshttp/mime-types/issues"
- },
- "homepage": "https://github.com/jshttp/mime-types",
- "_id": "mime-types@2.0.2",
- "_from": "mime-types@~2.0.2"
-}
diff --git a/CoAuthoring/node_modules/express/node_modules/accepts/node_modules/negotiator/LICENSE b/CoAuthoring/node_modules/express/node_modules/accepts/node_modules/negotiator/LICENSE
deleted file mode 100644
index 692b53419e..0000000000
--- a/CoAuthoring/node_modules/express/node_modules/accepts/node_modules/negotiator/LICENSE
+++ /dev/null
@@ -1,23 +0,0 @@
-(The MIT License)
-
-Copyright (c) 2012 Federico Romero
-Copyright (c) 2012-2014 Isaac Z. Schlueter
-
-Permission is hereby granted, free of charge, to any person obtaining
-a copy of this software and associated documentation files (the
-'Software'), to deal in the Software without restriction, including
-without limitation the rights to use, copy, modify, merge, publish,
-distribute, sublicense, and/or sell copies of the Software, and to
-permit persons to whom the Software is furnished to do so, subject to
-the following conditions:
-
-The above copyright notice and this permission notice shall be
-included in all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
-EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
-IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
-CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
-TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
-SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
diff --git a/CoAuthoring/node_modules/express/node_modules/accepts/node_modules/negotiator/README.md b/CoAuthoring/node_modules/express/node_modules/accepts/node_modules/negotiator/README.md
deleted file mode 100644
index 2461eb1ede..0000000000
--- a/CoAuthoring/node_modules/express/node_modules/accepts/node_modules/negotiator/README.md
+++ /dev/null
@@ -1,161 +0,0 @@
-# negotiator
-
-[![NPM Version][npm-image]][npm-url]
-[![NPM Downloads][downloads-image]][downloads-url]
-[![Node.js Version][node-version-image]][node-version-url]
-[![Build Status][travis-image]][travis-url]
-[![Test Coverage][coveralls-image]][coveralls-url]
-
-An HTTP content negotiator for Node.js
-
-## Installation
-
-```sh
-$ npm install negotiator
-```
-
-## API
-
-```js
-var Negotiator = require('negotiator')
-```
-
-### Accept Negotiation
-
-```js
-availableMediaTypes = ['text/html', 'text/plain', 'application/json']
-
-// The negotiator constructor receives a request object
-negotiator = new Negotiator(request)
-
-// Let's say Accept header is 'text/html, application/*;q=0.2, image/jpeg;q=0.8'
-
-negotiator.mediaTypes()
-// -> ['text/html', 'image/jpeg', 'application/*']
-
-negotiator.mediaTypes(availableMediaTypes)
-// -> ['text/html', 'application/json']
-
-negotiator.mediaType(availableMediaTypes)
-// -> 'text/html'
-```
-
-You can check a working example at `examples/accept.js`.
-
-#### Methods
-
-##### mediaTypes(availableMediaTypes):
-
-Returns an array of preferred media types ordered by priority from a list of available media types.
-
-##### mediaType(availableMediaType):
-
-Returns the top preferred media type from a list of available media types.
-
-### Accept-Language Negotiation
-
-```js
-negotiator = new Negotiator(request)
-
-availableLanguages = 'en', 'es', 'fr'
-
-// Let's say Accept-Language header is 'en;q=0.8, es, pt'
-
-negotiator.languages()
-// -> ['es', 'pt', 'en']
-
-negotiator.languages(availableLanguages)
-// -> ['es', 'en']
-
-language = negotiator.language(availableLanguages)
-// -> 'es'
-```
-
-You can check a working example at `examples/language.js`.
-
-#### Methods
-
-##### languages(availableLanguages):
-
-Returns an array of preferred languages ordered by priority from a list of available languages.
-
-##### language(availableLanguages):
-
-Returns the top preferred language from a list of available languages.
-
-### Accept-Charset Negotiation
-
-```js
-availableCharsets = ['utf-8', 'iso-8859-1', 'iso-8859-5']
-
-negotiator = new Negotiator(request)
-
-// Let's say Accept-Charset header is 'utf-8, iso-8859-1;q=0.8, utf-7;q=0.2'
-
-negotiator.charsets()
-// -> ['utf-8', 'iso-8859-1', 'utf-7']
-
-negotiator.charsets(availableCharsets)
-// -> ['utf-8', 'iso-8859-1']
-
-negotiator.charset(availableCharsets)
-// -> 'utf-8'
-```
-
-You can check a working example at `examples/charset.js`.
-
-#### Methods
-
-##### charsets(availableCharsets):
-
-Returns an array of preferred charsets ordered by priority from a list of available charsets.
-
-##### charset(availableCharsets):
-
-Returns the top preferred charset from a list of available charsets.
-
-### Accept-Encoding Negotiation
-
-```js
-availableEncodings = ['identity', 'gzip']
-
-negotiator = new Negotiator(request)
-
-// Let's say Accept-Encoding header is 'gzip, compress;q=0.2, identity;q=0.5'
-
-negotiator.encodings()
-// -> ['gzip', 'identity', 'compress']
-
-negotiator.encodings(availableEncodings)
-// -> ['gzip', 'identity']
-
-negotiator.encoding(availableEncodings)
-// -> 'gzip'
-```
-
-You can check a working example at `examples/encoding.js`.
-
-#### Methods
-
-##### encodings(availableEncodings):
-
-Returns an array of preferred encodings ordered by priority from a list of available encodings.
-
-##### encoding(availableEncodings):
-
-Returns the top preferred encoding from a list of available encodings.
-
-## License
-
-[MIT](LICENSE)
-
-[npm-image]: https://img.shields.io/npm/v/negotiator.svg?style=flat
-[npm-url]: https://npmjs.org/package/negotiator
-[node-version-image]: https://img.shields.io/node/v/negotiator.svg?style=flat
-[node-version-url]: http://nodejs.org/download/
-[travis-image]: https://img.shields.io/travis/jshttp/negotiator.svg?style=flat
-[travis-url]: https://travis-ci.org/jshttp/negotiator
-[coveralls-image]: https://img.shields.io/coveralls/jshttp/negotiator.svg?style=flat
-[coveralls-url]: https://coveralls.io/r/jshttp/negotiator?branch=master
-[downloads-image]: https://img.shields.io/npm/dm/negotiator.svg?style=flat
-[downloads-url]: https://npmjs.org/package/negotiator
diff --git a/CoAuthoring/node_modules/express/node_modules/accepts/node_modules/negotiator/lib/charset.js b/CoAuthoring/node_modules/express/node_modules/accepts/node_modules/negotiator/lib/charset.js
deleted file mode 100644
index 58da58fcdf..0000000000
--- a/CoAuthoring/node_modules/express/node_modules/accepts/node_modules/negotiator/lib/charset.js
+++ /dev/null
@@ -1,87 +0,0 @@
-module.exports = preferredCharsets;
-preferredCharsets.preferredCharsets = preferredCharsets;
-
-function parseAcceptCharset(accept) {
- return accept.split(',').map(function(e, i) {
- return parseCharset(e.trim(), i);
- }).filter(function(e) {
- return e;
- });
-}
-
-function parseCharset(s, i) {
- var match = s.match(/^\s*(\S+?)\s*(?:;(.*))?$/);
- if (!match) return null;
-
- var charset = match[1];
- var q = 1;
- if (match[2]) {
- var params = match[2].split(';')
- for (var i = 0; i < params.length; i ++) {
- var p = params[i].trim().split('=');
- if (p[0] === 'q') {
- q = parseFloat(p[1]);
- break;
- }
- }
- }
-
- return {
- charset: charset,
- q: q,
- i: i
- };
-}
-
-function getCharsetPriority(charset, accepted) {
- return (accepted.map(function(a) {
- return specify(charset, a);
- }).filter(Boolean).sort(function (a, b) {
- if(a.s == b.s) {
- return a.q > b.q ? -1 : 1;
- } else {
- return a.s > b.s ? -1 : 1;
- }
- })[0] || {s: 0, q:0});
-}
-
-function specify(charset, spec) {
- var s = 0;
- if(spec.charset.toLowerCase() === charset.toLowerCase()){
- s |= 1;
- } else if (spec.charset !== '*' ) {
- return null
- }
-
- return {
- s: s,
- q: spec.q,
- }
-}
-
-function preferredCharsets(accept, provided) {
- // RFC 2616 sec 14.2: no header = *
- accept = parseAcceptCharset(accept === undefined ? '*' : accept || '');
- if (provided) {
- return provided.map(function(type) {
- return [type, getCharsetPriority(type, accept)];
- }).filter(function(pair) {
- return pair[1].q > 0;
- }).sort(function(a, b) {
- var pa = a[1];
- var pb = b[1];
- return (pb.q - pa.q) || (pb.s - pa.s) || (pa.i - pb.i);
- }).map(function(pair) {
- return pair[0];
- });
- } else {
- return accept.sort(function (a, b) {
- // revsort
- return (b.q - a.q) || (a.i - b.i);
- }).filter(function(type) {
- return type.q > 0;
- }).map(function(type) {
- return type.charset;
- });
- }
-}
diff --git a/CoAuthoring/node_modules/express/node_modules/accepts/node_modules/negotiator/lib/encoding.js b/CoAuthoring/node_modules/express/node_modules/accepts/node_modules/negotiator/lib/encoding.js
deleted file mode 100644
index 4b8acc1ae4..0000000000
--- a/CoAuthoring/node_modules/express/node_modules/accepts/node_modules/negotiator/lib/encoding.js
+++ /dev/null
@@ -1,117 +0,0 @@
-module.exports = preferredEncodings;
-preferredEncodings.preferredEncodings = preferredEncodings;
-
-function parseAcceptEncoding(accept) {
- var acceptableEncodings;
-
- if (accept) {
- acceptableEncodings = accept.split(',').map(function(e, i) {
- return parseEncoding(e.trim(), i);
- });
- } else {
- acceptableEncodings = [];
- }
-
- if (!acceptableEncodings.some(function(e) {
- return e && specify('identity', e);
- })) {
- /*
- * If identity doesn't explicitly appear in the accept-encoding header,
- * it's added to the list of acceptable encoding with the lowest q
- *
- */
- var lowestQ = 1;
-
- for(var i = 0; i < acceptableEncodings.length; i++){
- var e = acceptableEncodings[i];
- if(e && e.q < lowestQ){
- lowestQ = e.q;
- }
- }
- acceptableEncodings.push({
- encoding: 'identity',
- q: lowestQ / 2,
- });
- }
-
- return acceptableEncodings.filter(function(e) {
- return e;
- });
-}
-
-function parseEncoding(s, i) {
- var match = s.match(/^\s*(\S+?)\s*(?:;(.*))?$/);
-
- if (!match) return null;
-
- var encoding = match[1];
- var q = 1;
- if (match[2]) {
- var params = match[2].split(';');
- for (var i = 0; i < params.length; i ++) {
- var p = params[i].trim().split('=');
- if (p[0] === 'q') {
- q = parseFloat(p[1]);
- break;
- }
- }
- }
-
- return {
- encoding: encoding,
- q: q,
- i: i
- };
-}
-
-function getEncodingPriority(encoding, accepted) {
- return (accepted.map(function(a) {
- return specify(encoding, a);
- }).filter(Boolean).sort(function (a, b) {
- if(a.s == b.s) {
- return a.q > b.q ? -1 : 1;
- } else {
- return a.s > b.s ? -1 : 1;
- }
- })[0] || {s: 0, q: 0});
-}
-
-function specify(encoding, spec) {
- var s = 0;
- if(spec.encoding.toLowerCase() === encoding.toLowerCase()){
- s |= 1;
- } else if (spec.encoding !== '*' ) {
- return null
- }
-
- return {
- s: s,
- q: spec.q,
- }
-};
-
-function preferredEncodings(accept, provided) {
- accept = parseAcceptEncoding(accept || '');
- if (provided) {
- return provided.map(function(type) {
- return [type, getEncodingPriority(type, accept)];
- }).filter(function(pair) {
- return pair[1].q > 0;
- }).sort(function(a, b) {
- var pa = a[1];
- var pb = b[1];
- return (pb.q - pa.q) || (pb.s - pa.s) || (pa.i - pb.i);
- }).map(function(pair) {
- return pair[0];
- });
- } else {
- return accept.sort(function (a, b) {
- // revsort
- return (b.q - a.q) || (a.i - b.i);
- }).filter(function(type){
- return type.q > 0;
- }).map(function(type) {
- return type.encoding;
- });
- }
-}
diff --git a/CoAuthoring/node_modules/express/node_modules/accepts/node_modules/negotiator/lib/language.js b/CoAuthoring/node_modules/express/node_modules/accepts/node_modules/negotiator/lib/language.js
deleted file mode 100644
index 8fc63dfed0..0000000000
--- a/CoAuthoring/node_modules/express/node_modules/accepts/node_modules/negotiator/lib/language.js
+++ /dev/null
@@ -1,100 +0,0 @@
-module.exports = preferredLanguages;
-preferredLanguages.preferredLanguages = preferredLanguages;
-
-function parseAcceptLanguage(accept) {
- return accept.split(',').map(function(e, i) {
- return parseLanguage(e.trim(), i);
- }).filter(function(e) {
- return e;
- });
-}
-
-function parseLanguage(s, i) {
- var match = s.match(/^\s*(\S+?)(?:-(\S+?))?\s*(?:;(.*))?$/);
- if (!match) return null;
-
- var prefix = match[1],
- suffix = match[2],
- full = prefix;
-
- if (suffix) full += "-" + suffix;
-
- var q = 1;
- if (match[3]) {
- var params = match[3].split(';')
- for (var i = 0; i < params.length; i ++) {
- var p = params[i].split('=');
- if (p[0] === 'q') q = parseFloat(p[1]);
- }
- }
-
- return {
- prefix: prefix,
- suffix: suffix,
- q: q,
- i: i,
- full: full
- };
-}
-
-function getLanguagePriority(language, accepted) {
- return (accepted.map(function(a){
- return specify(language, a);
- }).filter(Boolean).sort(function (a, b) {
- if(a.s == b.s) {
- return a.q > b.q ? -1 : 1;
- } else {
- return a.s > b.s ? -1 : 1;
- }
- })[0] || {s: 0, q: 0});
-}
-
-function specify(language, spec) {
- var p = parseLanguage(language)
- if (!p) return null;
- var s = 0;
- if(spec.full.toLowerCase() === p.full.toLowerCase()){
- s |= 4;
- } else if (spec.prefix.toLowerCase() === p.full.toLowerCase()) {
- s |= 2;
- } else if (spec.full.toLowerCase() === p.prefix.toLowerCase()) {
- s |= 1;
- } else if (spec.full !== '*' ) {
- return null
- }
-
- return {
- s: s,
- q: spec.q,
- }
-};
-
-function preferredLanguages(accept, provided) {
- // RFC 2616 sec 14.4: no header = *
- accept = parseAcceptLanguage(accept === undefined ? '*' : accept || '');
- if (provided) {
-
- var ret = provided.map(function(type) {
- return [type, getLanguagePriority(type, accept)];
- }).filter(function(pair) {
- return pair[1].q > 0;
- }).sort(function(a, b) {
- var pa = a[1];
- var pb = b[1];
- return (pb.q - pa.q) || (pb.s - pa.s) || (pa.i - pb.i);
- }).map(function(pair) {
- return pair[0];
- });
- return ret;
-
- } else {
- return accept.sort(function (a, b) {
- // revsort
- return (b.q - a.q) || (a.i - b.i);
- }).filter(function(type) {
- return type.q > 0;
- }).map(function(type) {
- return type.full;
- });
- }
-}
diff --git a/CoAuthoring/node_modules/express/node_modules/accepts/node_modules/negotiator/lib/mediaType.js b/CoAuthoring/node_modules/express/node_modules/accepts/node_modules/negotiator/lib/mediaType.js
deleted file mode 100644
index e413cad404..0000000000
--- a/CoAuthoring/node_modules/express/node_modules/accepts/node_modules/negotiator/lib/mediaType.js
+++ /dev/null
@@ -1,122 +0,0 @@
-module.exports = preferredMediaTypes;
-preferredMediaTypes.preferredMediaTypes = preferredMediaTypes;
-
-function parseAccept(accept) {
- return accept.split(',').map(function(e, i) {
- return parseMediaType(e.trim(), i);
- }).filter(function(e) {
- return e;
- });
-};
-
-function parseMediaType(s, i) {
- var match = s.match(/\s*(\S+?)\/([^;\s]+)\s*(?:;(.*))?/);
- if (!match) return null;
-
- var type = match[1],
- subtype = match[2],
- full = "" + type + "/" + subtype,
- params = {},
- q = 1;
-
- if (match[3]) {
- params = match[3].split(';').map(function(s) {
- return s.trim().split('=');
- }).reduce(function (set, p) {
- set[p[0]] = p[1];
- return set
- }, params);
-
- if (params.q != null) {
- q = parseFloat(params.q);
- delete params.q;
- }
- }
-
- return {
- type: type,
- subtype: subtype,
- params: params,
- q: q,
- i: i,
- full: full
- };
-}
-
-function getMediaTypePriority(type, accepted) {
- return (accepted.map(function(a) {
- return specify(type, a);
- }).filter(Boolean).sort(function (a, b) {
- if(a.s == b.s) {
- return a.q > b.q ? -1 : 1;
- } else {
- return a.s > b.s ? -1 : 1;
- }
- })[0] || {s: 0, q: 0});
-}
-
-function specify(type, spec) {
- var p = parseMediaType(type);
- var s = 0;
-
- if (!p) {
- return null;
- }
-
- if(spec.type.toLowerCase() == p.type.toLowerCase()) {
- s |= 4
- } else if(spec.type != '*') {
- return null;
- }
-
- if(spec.subtype.toLowerCase() == p.subtype.toLowerCase()) {
- s |= 2
- } else if(spec.subtype != '*') {
- return null;
- }
-
- var keys = Object.keys(spec.params);
- if (keys.length > 0) {
- if (keys.every(function (k) {
- return spec.params[k] == '*' || (spec.params[k] || '').toLowerCase() == (p.params[k] || '').toLowerCase();
- })) {
- s |= 1
- } else {
- return null
- }
- }
-
- return {
- q: spec.q,
- s: s,
- }
-
-}
-
-function preferredMediaTypes(accept, provided) {
- // RFC 2616 sec 14.2: no header = */*
- accept = parseAccept(accept === undefined ? '*/*' : accept || '');
- if (provided) {
- return provided.map(function(type) {
- return [type, getMediaTypePriority(type, accept)];
- }).filter(function(pair) {
- return pair[1].q > 0;
- }).sort(function(a, b) {
- var pa = a[1];
- var pb = b[1];
- return (pb.q - pa.q) || (pb.s - pa.s) || (pa.i - pb.i);
- }).map(function(pair) {
- return pair[0];
- });
-
- } else {
- return accept.sort(function (a, b) {
- // revsort
- return (b.q - a.q) || (a.i - b.i);
- }).filter(function(type) {
- return type.q > 0;
- }).map(function(type) {
- return type.full;
- });
- }
-}
diff --git a/CoAuthoring/node_modules/express/node_modules/accepts/node_modules/negotiator/lib/negotiator.js b/CoAuthoring/node_modules/express/node_modules/accepts/node_modules/negotiator/lib/negotiator.js
deleted file mode 100644
index ba0c48b9d7..0000000000
--- a/CoAuthoring/node_modules/express/node_modules/accepts/node_modules/negotiator/lib/negotiator.js
+++ /dev/null
@@ -1,37 +0,0 @@
-module.exports = Negotiator;
-Negotiator.Negotiator = Negotiator;
-
-function Negotiator(request) {
- if (!(this instanceof Negotiator)) return new Negotiator(request);
- this.request = request;
-}
-
-var set = { charset: 'accept-charset',
- encoding: 'accept-encoding',
- language: 'accept-language',
- mediaType: 'accept' };
-
-
-function capitalize(string){
- return string.charAt(0).toUpperCase() + string.slice(1);
-}
-
-Object.keys(set).forEach(function (k) {
- var header = set[k],
- method = require('./'+k+'.js'),
- singular = k,
- plural = k + 's';
-
- Negotiator.prototype[plural] = function (available) {
- return method(this.request.headers[header], available);
- };
-
- Negotiator.prototype[singular] = function(available) {
- var set = this[plural](available);
- if (set) return set[0];
- };
-
- // Keep preferred* methods for legacy compatibility
- Negotiator.prototype['preferred'+capitalize(plural)] = Negotiator.prototype[plural];
- Negotiator.prototype['preferred'+capitalize(singular)] = Negotiator.prototype[singular];
-})
diff --git a/CoAuthoring/node_modules/express/node_modules/accepts/node_modules/negotiator/package.json b/CoAuthoring/node_modules/express/node_modules/accepts/node_modules/negotiator/package.json
deleted file mode 100644
index d50e519a4a..0000000000
--- a/CoAuthoring/node_modules/express/node_modules/accepts/node_modules/negotiator/package.json
+++ /dev/null
@@ -1,53 +0,0 @@
-{
- "name": "negotiator",
- "description": "HTTP content negotiation",
- "version": "0.4.9",
- "author": {
- "name": "Federico Romero",
- "email": "federico.romero@outboxlabs.com"
- },
- "contributors": [
- {
- "name": "Isaac Z. Schlueter",
- "email": "i@izs.me",
- "url": "http://blog.izs.me/"
- }
- ],
- "repository": {
- "type": "git",
- "url": "git://github.com/jshttp/negotiator"
- },
- "keywords": [
- "http",
- "content negotiation",
- "accept",
- "accept-language",
- "accept-encoding",
- "accept-charset"
- ],
- "license": "MIT",
- "devDependencies": {
- "istanbul": "~0.3.2",
- "nodeunit": "0.8.x"
- },
- "scripts": {
- "test": "nodeunit test",
- "test-cov": "istanbul cover ./node_modules/nodeunit/bin/nodeunit test"
- },
- "engines": {
- "node": ">= 0.6"
- },
- "main": "lib/negotiator.js",
- "files": [
- "lib",
- "LICENSE"
- ],
- "readme": "# negotiator\n\n[![NPM Version][npm-image]][npm-url]\n[![NPM Downloads][downloads-image]][downloads-url]\n[![Node.js Version][node-version-image]][node-version-url]\n[![Build Status][travis-image]][travis-url]\n[![Test Coverage][coveralls-image]][coveralls-url]\n\nAn HTTP content negotiator for Node.js\n\n## Installation\n\n```sh\n$ npm install negotiator\n```\n\n## API\n\n```js\nvar Negotiator = require('negotiator')\n```\n\n### Accept Negotiation\n\n```js\navailableMediaTypes = ['text/html', 'text/plain', 'application/json']\n\n// The negotiator constructor receives a request object\nnegotiator = new Negotiator(request)\n\n// Let's say Accept header is 'text/html, application/*;q=0.2, image/jpeg;q=0.8'\n\nnegotiator.mediaTypes()\n// -> ['text/html', 'image/jpeg', 'application/*']\n\nnegotiator.mediaTypes(availableMediaTypes)\n// -> ['text/html', 'application/json']\n\nnegotiator.mediaType(availableMediaTypes)\n// -> 'text/html'\n```\n\nYou can check a working example at `examples/accept.js`.\n\n#### Methods\n\n##### mediaTypes(availableMediaTypes):\n\nReturns an array of preferred media types ordered by priority from a list of available media types.\n\n##### mediaType(availableMediaType):\n\nReturns the top preferred media type from a list of available media types.\n\n### Accept-Language Negotiation\n\n```js\nnegotiator = new Negotiator(request)\n\navailableLanguages = 'en', 'es', 'fr'\n\n// Let's say Accept-Language header is 'en;q=0.8, es, pt'\n\nnegotiator.languages()\n// -> ['es', 'pt', 'en']\n\nnegotiator.languages(availableLanguages)\n// -> ['es', 'en']\n\nlanguage = negotiator.language(availableLanguages)\n// -> 'es'\n```\n\nYou can check a working example at `examples/language.js`.\n\n#### Methods\n\n##### languages(availableLanguages):\n\nReturns an array of preferred languages ordered by priority from a list of available languages.\n\n##### language(availableLanguages):\n\nReturns the top preferred language from a list of available languages.\n\n### Accept-Charset Negotiation\n\n```js\navailableCharsets = ['utf-8', 'iso-8859-1', 'iso-8859-5']\n\nnegotiator = new Negotiator(request)\n\n// Let's say Accept-Charset header is 'utf-8, iso-8859-1;q=0.8, utf-7;q=0.2'\n\nnegotiator.charsets()\n// -> ['utf-8', 'iso-8859-1', 'utf-7']\n\nnegotiator.charsets(availableCharsets)\n// -> ['utf-8', 'iso-8859-1']\n\nnegotiator.charset(availableCharsets)\n// -> 'utf-8'\n```\n\nYou can check a working example at `examples/charset.js`.\n\n#### Methods\n\n##### charsets(availableCharsets):\n\nReturns an array of preferred charsets ordered by priority from a list of available charsets.\n\n##### charset(availableCharsets):\n\nReturns the top preferred charset from a list of available charsets.\n\n### Accept-Encoding Negotiation\n\n```js\navailableEncodings = ['identity', 'gzip']\n\nnegotiator = new Negotiator(request)\n\n// Let's say Accept-Encoding header is 'gzip, compress;q=0.2, identity;q=0.5'\n\nnegotiator.encodings()\n// -> ['gzip', 'identity', 'compress']\n\nnegotiator.encodings(availableEncodings)\n// -> ['gzip', 'identity']\n\nnegotiator.encoding(availableEncodings)\n// -> 'gzip'\n```\n\nYou can check a working example at `examples/encoding.js`.\n\n#### Methods\n\n##### encodings(availableEncodings):\n\nReturns an array of preferred encodings ordered by priority from a list of available encodings.\n\n##### encoding(availableEncodings):\n\nReturns the top preferred encoding from a list of available encodings.\n\n## License\n\n[MIT](LICENSE)\n\n[npm-image]: https://img.shields.io/npm/v/negotiator.svg?style=flat\n[npm-url]: https://npmjs.org/package/negotiator\n[node-version-image]: https://img.shields.io/node/v/negotiator.svg?style=flat\n[node-version-url]: http://nodejs.org/download/\n[travis-image]: https://img.shields.io/travis/jshttp/negotiator.svg?style=flat\n[travis-url]: https://travis-ci.org/jshttp/negotiator\n[coveralls-image]: https://img.shields.io/coveralls/jshttp/negotiator.svg?style=flat\n[coveralls-url]: https://coveralls.io/r/jshttp/negotiator?branch=master\n[downloads-image]: https://img.shields.io/npm/dm/negotiator.svg?style=flat\n[downloads-url]: https://npmjs.org/package/negotiator\n",
- "readmeFilename": "README.md",
- "bugs": {
- "url": "https://github.com/jshttp/negotiator/issues"
- },
- "homepage": "https://github.com/jshttp/negotiator",
- "_id": "negotiator@0.4.9",
- "_from": "negotiator@0.4.9"
-}
diff --git a/CoAuthoring/node_modules/express/node_modules/accepts/package.json b/CoAuthoring/node_modules/express/node_modules/accepts/package.json
deleted file mode 100644
index c5e629abb8..0000000000
--- a/CoAuthoring/node_modules/express/node_modules/accepts/package.json
+++ /dev/null
@@ -1,50 +0,0 @@
-{
- "name": "accepts",
- "description": "Higher-level content negotiation",
- "version": "1.1.2",
- "author": {
- "name": "Jonathan Ong",
- "email": "me@jongleberry.com",
- "url": "http://jongleberry.com"
- },
- "license": "MIT",
- "repository": {
- "type": "git",
- "url": "git://github.com/jshttp/accepts"
- },
- "dependencies": {
- "mime-types": "~2.0.2",
- "negotiator": "0.4.9"
- },
- "devDependencies": {
- "istanbul": "~0.3.0",
- "mocha": "1"
- },
- "files": [
- "LICENSE",
- "HISTORY.md",
- "index.js"
- ],
- "engines": {
- "node": ">= 0.8.0"
- },
- "scripts": {
- "test": "mocha --reporter spec --check-leaks --bail test/",
- "test-cov": "istanbul cover node_modules/mocha/bin/_mocha -- --reporter dot --check-leaks test/",
- "test-travis": "istanbul cover node_modules/mocha/bin/_mocha --report lcovonly -- --reporter spec --check-leaks test/"
- },
- "keywords": [
- "content",
- "negotiation",
- "accept",
- "accepts"
- ],
- "readme": "# accepts\n\n[![NPM Version][npm-image]][npm-url]\n[![NPM Downloads][downloads-image]][downloads-url]\n[![Node.js Version][node-version-image]][node-version-url]\n[![Build Status][travis-image]][travis-url]\n[![Test Coverage][coveralls-image]][coveralls-url]\n\nHigher level content negotation based on [negotiator](https://github.com/federomero/negotiator). Extracted from [koa](https://github.com/koajs/koa) for general use.\n\nIn addition to negotatior, it allows:\n\n- Allows types as an array or arguments list, ie `(['text/html', 'application/json'])` as well as `('text/html', 'application/json')`.\n- Allows type shorthands such as `json`.\n- Returns `false` when no types match\n- Treats non-existent headers as `*`\n\n## API\n\n### var accept = new Accepts(req)\n\n```js\nvar accepts = require('accepts')\n\nhttp.createServer(function (req, res) {\n var accept = accepts(req)\n})\n```\n\n### accept\\[property\\]\\(\\)\n\nReturns all the explicitly accepted content property as an array in descending priority.\n\n- `accept.types()`\n- `accept.encodings()`\n- `accept.charsets()`\n- `accept.languages()`\n\nThey are also aliased in singular form such as `accept.type()`. `accept.languages()` is also aliased as `accept.langs()`, etc.\n\nNote: you should almost never do this in a real app as it defeats the purpose of content negotiation.\n\nExample:\n\n```js\n// in Google Chrome\nvar encodings = accept.encodings() // -> ['sdch', 'gzip', 'deflate']\n```\n\nSince you probably don't support `sdch`, you should just supply the encodings you support:\n\n```js\nvar encoding = accept.encodings('gzip', 'deflate') // -> 'gzip', probably\n```\n\n### accept\\[property\\]\\(values, ...\\)\n\nYou can either have `values` be an array or have an argument list of values.\n\nIf the client does not accept any `values`, `false` will be returned.\nIf the client accepts any `values`, the preferred `value` will be return.\n\nFor `accept.types()`, shorthand mime types are allowed.\n\nExample:\n\n```js\n// req.headers.accept = 'application/json'\n\naccept.types('json') // -> 'json'\naccept.types('html', 'json') // -> 'json'\naccept.types('html') // -> false\n\n// req.headers.accept = ''\n// which is equivalent to `*`\n\naccept.types() // -> [], no explicit types\naccept.types('text/html', 'text/json') // -> 'text/html', since it was first\n```\n\n## License\n\n[MIT](LICENSE)\n\n[npm-image]: https://img.shields.io/npm/v/accepts.svg?style=flat\n[npm-url]: https://npmjs.org/package/accepts\n[node-version-image]: https://img.shields.io/badge/node.js-%3E%3D_0.8-brightgreen.svg?style=flat\n[node-version-url]: http://nodejs.org/download/\n[travis-image]: https://img.shields.io/travis/jshttp/accepts.svg?style=flat\n[travis-url]: https://travis-ci.org/jshttp/accepts\n[coveralls-image]: https://img.shields.io/coveralls/jshttp/accepts.svg?style=flat\n[coveralls-url]: https://coveralls.io/r/jshttp/accepts\n[downloads-image]: https://img.shields.io/npm/dm/accepts.svg?style=flat\n[downloads-url]: https://npmjs.org/package/accepts\n",
- "readmeFilename": "README.md",
- "bugs": {
- "url": "https://github.com/jshttp/accepts/issues"
- },
- "homepage": "https://github.com/jshttp/accepts",
- "_id": "accepts@1.1.2",
- "_from": "accepts@~1.1.2"
-}
diff --git a/CoAuthoring/node_modules/express/node_modules/cookie-signature/.npmignore b/CoAuthoring/node_modules/express/node_modules/cookie-signature/.npmignore
deleted file mode 100644
index f1250e584c..0000000000
--- a/CoAuthoring/node_modules/express/node_modules/cookie-signature/.npmignore
+++ /dev/null
@@ -1,4 +0,0 @@
-support
-test
-examples
-*.sock
diff --git a/CoAuthoring/node_modules/express/node_modules/cookie-signature/History.md b/CoAuthoring/node_modules/express/node_modules/cookie-signature/History.md
deleted file mode 100644
index 2bbc4b3902..0000000000
--- a/CoAuthoring/node_modules/express/node_modules/cookie-signature/History.md
+++ /dev/null
@@ -1,27 +0,0 @@
-1.0.4 / 2014-06-25
-==================
-
- * corrected avoidance of timing attacks (thanks @tenbits!)
-
-
-1.0.3 / 2014-01-28
-==================
-
- * [incorrect] fix for timing attacks
-
-1.0.2 / 2014-01-28
-==================
-
- * fix missing repository warning
- * fix typo in test
-
-1.0.1 / 2013-04-15
-==================
-
- * Revert "Changed underlying HMAC algo. to sha512."
- * Revert "Fix for timing attacks on MAC verification."
-
-0.0.1 / 2010-01-03
-==================
-
- * Initial release
diff --git a/CoAuthoring/node_modules/express/node_modules/cookie-signature/Makefile b/CoAuthoring/node_modules/express/node_modules/cookie-signature/Makefile
deleted file mode 100644
index 4e9c8d36eb..0000000000
--- a/CoAuthoring/node_modules/express/node_modules/cookie-signature/Makefile
+++ /dev/null
@@ -1,7 +0,0 @@
-
-test:
- @./node_modules/.bin/mocha \
- --require should \
- --reporter spec
-
-.PHONY: test
\ No newline at end of file
diff --git a/CoAuthoring/node_modules/express/node_modules/cookie-signature/Readme.md b/CoAuthoring/node_modules/express/node_modules/cookie-signature/Readme.md
deleted file mode 100644
index 2559e841b0..0000000000
--- a/CoAuthoring/node_modules/express/node_modules/cookie-signature/Readme.md
+++ /dev/null
@@ -1,42 +0,0 @@
-
-# cookie-signature
-
- Sign and unsign cookies.
-
-## Example
-
-```js
-var cookie = require('cookie-signature');
-
-var val = cookie.sign('hello', 'tobiiscool');
-val.should.equal('hello.DGDUkGlIkCzPz+C0B064FNgHdEjox7ch8tOBGslZ5QI');
-
-var val = cookie.sign('hello', 'tobiiscool');
-cookie.unsign(val, 'tobiiscool').should.equal('hello');
-cookie.unsign(val, 'luna').should.be.false;
-```
-
-## License
-
-(The MIT License)
-
-Copyright (c) 2012 LearnBoost <tj@learnboost.com>
-
-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.
\ No newline at end of file
diff --git a/CoAuthoring/node_modules/express/node_modules/cookie-signature/index.js b/CoAuthoring/node_modules/express/node_modules/cookie-signature/index.js
deleted file mode 100644
index b63bf84a16..0000000000
--- a/CoAuthoring/node_modules/express/node_modules/cookie-signature/index.js
+++ /dev/null
@@ -1,51 +0,0 @@
-/**
- * Module dependencies.
- */
-
-var crypto = require('crypto');
-
-/**
- * Sign the given `val` with `secret`.
- *
- * @param {String} val
- * @param {String} secret
- * @return {String}
- * @api private
- */
-
-exports.sign = function(val, secret){
- if ('string' != typeof val) throw new TypeError('cookie required');
- if ('string' != typeof secret) throw new TypeError('secret required');
- return val + '.' + crypto
- .createHmac('sha256', secret)
- .update(val)
- .digest('base64')
- .replace(/\=+$/, '');
-};
-
-/**
- * Unsign and decode the given `val` with `secret`,
- * returning `false` if the signature is invalid.
- *
- * @param {String} val
- * @param {String} secret
- * @return {String|Boolean}
- * @api private
- */
-
-exports.unsign = function(val, secret){
- if ('string' != typeof val) throw new TypeError('cookie required');
- if ('string' != typeof secret) throw new TypeError('secret required');
- var str = val.slice(0, val.lastIndexOf('.'))
- , mac = exports.sign(str, secret);
-
- return sha1(mac) == sha1(val) ? str : false;
-};
-
-/**
- * Private
- */
-
-function sha1(str){
- return crypto.createHash('sha1').update(str).digest('hex');
-}
diff --git a/CoAuthoring/node_modules/express/node_modules/cookie-signature/package.json b/CoAuthoring/node_modules/express/node_modules/cookie-signature/package.json
deleted file mode 100644
index babe4e0c11..0000000000
--- a/CoAuthoring/node_modules/express/node_modules/cookie-signature/package.json
+++ /dev/null
@@ -1,33 +0,0 @@
-{
- "name": "cookie-signature",
- "version": "1.0.5",
- "description": "Sign and unsign cookies",
- "keywords": [
- "cookie",
- "sign",
- "unsign"
- ],
- "author": {
- "name": "TJ Holowaychuk",
- "email": "tj@learnboost.com"
- },
- "license": "MIT",
- "repository": {
- "type": "git",
- "url": "https://github.com/visionmedia/node-cookie-signature.git"
- },
- "dependencies": {},
- "devDependencies": {
- "mocha": "*",
- "should": "*"
- },
- "main": "index",
- "readme": "\n# cookie-signature\n\n Sign and unsign cookies.\n\n## Example\n\n```js\nvar cookie = require('cookie-signature');\n\nvar val = cookie.sign('hello', 'tobiiscool');\nval.should.equal('hello.DGDUkGlIkCzPz+C0B064FNgHdEjox7ch8tOBGslZ5QI');\n\nvar val = cookie.sign('hello', 'tobiiscool');\ncookie.unsign(val, 'tobiiscool').should.equal('hello');\ncookie.unsign(val, 'luna').should.be.false;\n```\n\n## License \n\n(The MIT License)\n\nCopyright (c) 2012 LearnBoost <tj@learnboost.com>\n\nPermission is hereby granted, free of charge, to any person obtaining\na copy of this software and associated documentation files (the\n'Software'), to deal in the Software without restriction, including\nwithout limitation the rights to use, copy, modify, merge, publish,\ndistribute, sublicense, and/or sell copies of the Software, and to\npermit persons to whom the Software is furnished to do so, subject to\nthe following conditions:\n\nThe above copyright notice and this permission notice shall be\nincluded in all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,\nEXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\nMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.\nIN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY\nCLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,\nTORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE\nSOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.",
- "readmeFilename": "Readme.md",
- "bugs": {
- "url": "https://github.com/visionmedia/node-cookie-signature/issues"
- },
- "homepage": "https://github.com/visionmedia/node-cookie-signature",
- "_id": "cookie-signature@1.0.5",
- "_from": "cookie-signature@1.0.5"
-}
diff --git a/CoAuthoring/node_modules/express/node_modules/cookie/.npmignore b/CoAuthoring/node_modules/express/node_modules/cookie/.npmignore
deleted file mode 100644
index efab07fb1b..0000000000
--- a/CoAuthoring/node_modules/express/node_modules/cookie/.npmignore
+++ /dev/null
@@ -1,2 +0,0 @@
-test
-.travis.yml
diff --git a/CoAuthoring/node_modules/express/node_modules/cookie/LICENSE b/CoAuthoring/node_modules/express/node_modules/cookie/LICENSE
deleted file mode 100644
index 249d9def92..0000000000
--- a/CoAuthoring/node_modules/express/node_modules/cookie/LICENSE
+++ /dev/null
@@ -1,9 +0,0 @@
-// MIT License
-
-Copyright (C) Roman Shtylman
-
-Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
diff --git a/CoAuthoring/node_modules/express/node_modules/cookie/README.md b/CoAuthoring/node_modules/express/node_modules/cookie/README.md
deleted file mode 100644
index 3170b4b87d..0000000000
--- a/CoAuthoring/node_modules/express/node_modules/cookie/README.md
+++ /dev/null
@@ -1,44 +0,0 @@
-# cookie [](http://travis-ci.org/defunctzombie/node-cookie) #
-
-cookie is a basic cookie parser and serializer. It doesn't make assumptions about how you are going to deal with your cookies. It basically just provides a way to read and write the HTTP cookie headers.
-
-See [RFC6265](http://tools.ietf.org/html/rfc6265) for details about the http header for cookies.
-
-## how?
-
-```
-npm install cookie
-```
-
-```javascript
-var cookie = require('cookie');
-
-var hdr = cookie.serialize('foo', 'bar');
-// hdr = 'foo=bar';
-
-var cookies = cookie.parse('foo=bar; cat=meow; dog=ruff');
-// cookies = { foo: 'bar', cat: 'meow', dog: 'ruff' };
-```
-
-## more
-
-The serialize function takes a third parameter, an object, to set cookie options. See the RFC for valid values.
-
-### path
-> cookie path
-
-### expires
-> absolute expiration date for the cookie (Date object)
-
-### maxAge
-> relative max age of the cookie from when the client receives it (seconds)
-
-### domain
-> domain for the cookie
-
-### secure
-> true or false
-
-### httpOnly
-> true or false
-
diff --git a/CoAuthoring/node_modules/express/node_modules/cookie/index.js b/CoAuthoring/node_modules/express/node_modules/cookie/index.js
deleted file mode 100644
index 00d54a7b6f..0000000000
--- a/CoAuthoring/node_modules/express/node_modules/cookie/index.js
+++ /dev/null
@@ -1,75 +0,0 @@
-
-/// Serialize the a name value pair into a cookie string suitable for
-/// http headers. An optional options object specified cookie parameters
-///
-/// serialize('foo', 'bar', { httpOnly: true })
-/// => "foo=bar; httpOnly"
-///
-/// @param {String} name
-/// @param {String} val
-/// @param {Object} options
-/// @return {String}
-var serialize = function(name, val, opt){
- opt = opt || {};
- var enc = opt.encode || encode;
- var pairs = [name + '=' + enc(val)];
-
- if (null != opt.maxAge) {
- var maxAge = opt.maxAge - 0;
- if (isNaN(maxAge)) throw new Error('maxAge should be a Number');
- pairs.push('Max-Age=' + maxAge);
- }
-
- if (opt.domain) pairs.push('Domain=' + opt.domain);
- if (opt.path) pairs.push('Path=' + opt.path);
- if (opt.expires) pairs.push('Expires=' + opt.expires.toUTCString());
- if (opt.httpOnly) pairs.push('HttpOnly');
- if (opt.secure) pairs.push('Secure');
-
- return pairs.join('; ');
-};
-
-/// Parse the given cookie header string into an object
-/// The object has the various cookies as keys(names) => values
-/// @param {String} str
-/// @return {Object}
-var parse = function(str, opt) {
- opt = opt || {};
- var obj = {}
- var pairs = str.split(/; */);
- var dec = opt.decode || decode;
-
- pairs.forEach(function(pair) {
- var eq_idx = pair.indexOf('=')
-
- // skip things that don't look like key=value
- if (eq_idx < 0) {
- return;
- }
-
- var key = pair.substr(0, eq_idx).trim()
- var val = pair.substr(++eq_idx, pair.length).trim();
-
- // quoted values
- if ('"' == val[0]) {
- val = val.slice(1, -1);
- }
-
- // only assign once
- if (undefined == obj[key]) {
- try {
- obj[key] = dec(val);
- } catch (e) {
- obj[key] = val;
- }
- }
- });
-
- return obj;
-};
-
-var encode = encodeURIComponent;
-var decode = decodeURIComponent;
-
-module.exports.serialize = serialize;
-module.exports.parse = parse;
diff --git a/CoAuthoring/node_modules/express/node_modules/cookie/package.json b/CoAuthoring/node_modules/express/node_modules/cookie/package.json
deleted file mode 100644
index 50100a50f0..0000000000
--- a/CoAuthoring/node_modules/express/node_modules/cookie/package.json
+++ /dev/null
@@ -1,37 +0,0 @@
-{
- "author": {
- "name": "Roman Shtylman",
- "email": "shtylman@gmail.com"
- },
- "name": "cookie",
- "description": "cookie parsing and serialization",
- "version": "0.1.2",
- "repository": {
- "type": "git",
- "url": "git://github.com/shtylman/node-cookie.git"
- },
- "keywords": [
- "cookie",
- "cookies"
- ],
- "main": "index.js",
- "scripts": {
- "test": "mocha"
- },
- "dependencies": {},
- "devDependencies": {
- "mocha": "1.x.x"
- },
- "optionalDependencies": {},
- "engines": {
- "node": "*"
- },
- "readme": "# cookie [](http://travis-ci.org/defunctzombie/node-cookie) #\n\ncookie is a basic cookie parser and serializer. It doesn't make assumptions about how you are going to deal with your cookies. It basically just provides a way to read and write the HTTP cookie headers.\n\nSee [RFC6265](http://tools.ietf.org/html/rfc6265) for details about the http header for cookies.\n\n## how?\n\n```\nnpm install cookie\n```\n\n```javascript\nvar cookie = require('cookie');\n\nvar hdr = cookie.serialize('foo', 'bar');\n// hdr = 'foo=bar';\n\nvar cookies = cookie.parse('foo=bar; cat=meow; dog=ruff');\n// cookies = { foo: 'bar', cat: 'meow', dog: 'ruff' };\n```\n\n## more\n\nThe serialize function takes a third parameter, an object, to set cookie options. See the RFC for valid values.\n\n### path\n> cookie path\n\n### expires\n> absolute expiration date for the cookie (Date object)\n\n### maxAge\n> relative max age of the cookie from when the client receives it (seconds)\n\n### domain\n> domain for the cookie\n\n### secure\n> true or false\n\n### httpOnly\n> true or false\n\n",
- "readmeFilename": "README.md",
- "bugs": {
- "url": "https://github.com/shtylman/node-cookie/issues"
- },
- "homepage": "https://github.com/shtylman/node-cookie",
- "_id": "cookie@0.1.2",
- "_from": "cookie@0.1.2"
-}
diff --git a/CoAuthoring/node_modules/express/node_modules/debug/.jshintrc b/CoAuthoring/node_modules/express/node_modules/debug/.jshintrc
deleted file mode 100644
index 299877f26a..0000000000
--- a/CoAuthoring/node_modules/express/node_modules/debug/.jshintrc
+++ /dev/null
@@ -1,3 +0,0 @@
-{
- "laxbreak": true
-}
diff --git a/CoAuthoring/node_modules/express/node_modules/debug/.npmignore b/CoAuthoring/node_modules/express/node_modules/debug/.npmignore
deleted file mode 100644
index 7e6163db02..0000000000
--- a/CoAuthoring/node_modules/express/node_modules/debug/.npmignore
+++ /dev/null
@@ -1,6 +0,0 @@
-support
-test
-examples
-example
-*.sock
-dist
diff --git a/CoAuthoring/node_modules/express/node_modules/debug/History.md b/CoAuthoring/node_modules/express/node_modules/debug/History.md
deleted file mode 100644
index 79429ff308..0000000000
--- a/CoAuthoring/node_modules/express/node_modules/debug/History.md
+++ /dev/null
@@ -1,150 +0,0 @@
-
-2.0.0 / 2014-09-01
-==================
-
- * package: update "browserify" to v5.11.0
- * node: use stderr rather than stdout for logging (#29, @stephenmathieson)
-
-1.0.4 / 2014-07-15
-==================
-
- * dist: recompile
- * example: remove `console.info()` log usage
- * example: add "Content-Type" UTF-8 header to browser example
- * browser: place %c marker after the space character
- * browser: reset the "content" color via `color: inherit`
- * browser: add colors support for Firefox >= v31
- * debug: prefer an instance `log()` function over the global one (#119)
- * Readme: update documentation about styled console logs for FF v31 (#116, @wryk)
-
-1.0.3 / 2014-07-09
-==================
-
- * Add support for multiple wildcards in namespaces (#122, @seegno)
- * browser: fix lint
-
-1.0.2 / 2014-06-10
-==================
-
- * browser: update color palette (#113, @gscottolson)
- * common: make console logging function configurable (#108, @timoxley)
- * node: fix %o colors on old node <= 0.8.x
- * Makefile: find node path using shell/which (#109, @timoxley)
-
-1.0.1 / 2014-06-06
-==================
-
- * browser: use `removeItem()` to clear localStorage
- * browser, node: don't set DEBUG if namespaces is undefined (#107, @leedm777)
- * package: add "contributors" section
- * node: fix comment typo
- * README: list authors
-
-1.0.0 / 2014-06-04
-==================
-
- * make ms diff be global, not be scope
- * debug: ignore empty strings in enable()
- * node: make DEBUG_COLORS able to disable coloring
- * *: export the `colors` array
- * npmignore: don't publish the `dist` dir
- * Makefile: refactor to use browserify
- * package: add "browserify" as a dev dependency
- * Readme: add Web Inspector Colors section
- * node: reset terminal color for the debug content
- * node: map "%o" to `util.inspect()`
- * browser: map "%j" to `JSON.stringify()`
- * debug: add custom "formatters"
- * debug: use "ms" module for humanizing the diff
- * Readme: add "bash" syntax highlighting
- * browser: add Firebug color support
- * browser: add colors for WebKit browsers
- * node: apply log to `console`
- * rewrite: abstract common logic for Node & browsers
- * add .jshintrc file
-
-0.8.1 / 2014-04-14
-==================
-
- * package: re-add the "component" section
-
-0.8.0 / 2014-03-30
-==================
-
- * add `enable()` method for nodejs. Closes #27
- * change from stderr to stdout
- * remove unnecessary index.js file
-
-0.7.4 / 2013-11-13
-==================
-
- * remove "browserify" key from package.json (fixes something in browserify)
-
-0.7.3 / 2013-10-30
-==================
-
- * fix: catch localStorage security error when cookies are blocked (Chrome)
- * add debug(err) support. Closes #46
- * add .browser prop to package.json. Closes #42
-
-0.7.2 / 2013-02-06
-==================
-
- * fix package.json
- * fix: Mobile Safari (private mode) is broken with debug
- * fix: Use unicode to send escape character to shell instead of octal to work with strict mode javascript
-
-0.7.1 / 2013-02-05
-==================
-
- * add repository URL to package.json
- * add DEBUG_COLORED to force colored output
- * add browserify support
- * fix component. Closes #24
-
-0.7.0 / 2012-05-04
-==================
-
- * Added .component to package.json
- * Added debug.component.js build
-
-0.6.0 / 2012-03-16
-==================
-
- * Added support for "-" prefix in DEBUG [Vinay Pulim]
- * Added `.enabled` flag to the node version [TooTallNate]
-
-0.5.0 / 2012-02-02
-==================
-
- * Added: humanize diffs. Closes #8
- * Added `debug.disable()` to the CS variant
- * Removed padding. Closes #10
- * Fixed: persist client-side variant again. Closes #9
-
-0.4.0 / 2012-02-01
-==================
-
- * Added browser variant support for older browsers [TooTallNate]
- * Added `debug.enable('project:*')` to browser variant [TooTallNate]
- * Added padding to diff (moved it to the right)
-
-0.3.0 / 2012-01-26
-==================
-
- * Added millisecond diff when isatty, otherwise UTC string
-
-0.2.0 / 2012-01-22
-==================
-
- * Added wildcard support
-
-0.1.0 / 2011-12-02
-==================
-
- * Added: remove colors unless stderr isatty [TooTallNate]
-
-0.0.1 / 2010-01-03
-==================
-
- * Initial release
diff --git a/CoAuthoring/node_modules/express/node_modules/debug/Makefile b/CoAuthoring/node_modules/express/node_modules/debug/Makefile
deleted file mode 100644
index b0bde6e63f..0000000000
--- a/CoAuthoring/node_modules/express/node_modules/debug/Makefile
+++ /dev/null
@@ -1,33 +0,0 @@
-
-# get Makefile directory name: http://stackoverflow.com/a/5982798/376773
-THIS_MAKEFILE_PATH:=$(word $(words $(MAKEFILE_LIST)),$(MAKEFILE_LIST))
-THIS_DIR:=$(shell cd $(dir $(THIS_MAKEFILE_PATH));pwd)
-
-# BIN directory
-BIN := $(THIS_DIR)/node_modules/.bin
-
-# applications
-NODE ?= $(shell which node)
-NPM ?= $(NODE) $(shell which npm)
-BROWSERIFY ?= $(NODE) $(BIN)/browserify
-
-all: dist/debug.js
-
-install: node_modules
-
-clean:
- @rm -rf node_modules dist
-
-dist:
- @mkdir -p $@
-
-dist/debug.js: node_modules browser.js debug.js dist
- @$(BROWSERIFY) \
- --standalone debug \
- . > $@
-
-node_modules: package.json
- @NODE_ENV= $(NPM) install
- @touch node_modules
-
-.PHONY: all install clean
diff --git a/CoAuthoring/node_modules/express/node_modules/debug/Readme.md b/CoAuthoring/node_modules/express/node_modules/debug/Readme.md
deleted file mode 100644
index e59b9adae9..0000000000
--- a/CoAuthoring/node_modules/express/node_modules/debug/Readme.md
+++ /dev/null
@@ -1,156 +0,0 @@
-# debug
-
- tiny node.js debugging utility modelled after node core's debugging technique.
-
-## Installation
-
-```bash
-$ npm install debug
-```
-
-## Usage
-
- With `debug` you simply invoke the exported function to generate your debug function, passing it a name which will determine if a noop function is returned, or a decorated `console.error`, so all of the `console` format string goodies you're used to work fine. A unique color is selected per-function for visibility.
-
-Example _app.js_:
-
-```js
-var debug = require('debug')('http')
- , http = require('http')
- , name = 'My App';
-
-// fake app
-
-debug('booting %s', name);
-
-http.createServer(function(req, res){
- debug(req.method + ' ' + req.url);
- res.end('hello\n');
-}).listen(3000, function(){
- debug('listening');
-});
-
-// fake worker of some kind
-
-require('./worker');
-```
-
-Example _worker.js_:
-
-```js
-var debug = require('debug')('worker');
-
-setInterval(function(){
- debug('doing some work');
-}, 1000);
-```
-
- The __DEBUG__ environment variable is then used to enable these based on space or comma-delimited names. Here are some examples:
-
- 
-
- 
-
-## Millisecond diff
-
- When actively developing an application it can be useful to see when the time spent between one `debug()` call and the next. Suppose for example you invoke `debug()` before requesting a resource, and after as well, the "+NNNms" will show you how much time was spent between calls.
-
- 
-
- When stdout is not a TTY, `Date#toUTCString()` is used, making it more useful for logging the debug information as shown below:
-
- 
-
-## Conventions
-
- If you're using this in one or more of your libraries, you _should_ use the name of your library so that developers may toggle debugging as desired without guessing names. If you have more than one debuggers you _should_ prefix them with your library name and use ":" to separate features. For example "bodyParser" from Connect would then be "connect:bodyParser".
-
-## Wildcards
-
- The `*` character may be used as a wildcard. Suppose for example your library has debuggers named "connect:bodyParser", "connect:compress", "connect:session", instead of listing all three with `DEBUG=connect:bodyParser,connect.compress,connect:session`, you may simply do `DEBUG=connect:*`, or to run everything using this module simply use `DEBUG=*`.
-
- You can also exclude specific debuggers by prefixing them with a "-" character. For example, `DEBUG=*,-connect:*` would include all debuggers except those starting with "connect:".
-
-## Browser support
-
- Debug works in the browser as well, currently persisted by `localStorage`. For example if you have `worker:a` and `worker:b` as shown below, and wish to debug both type `debug.enable('worker:*')` in the console and refresh the page, this will remain until you disable with `debug.disable()`.
-
-```js
-a = debug('worker:a');
-b = debug('worker:b');
-
-setInterval(function(){
- a('doing some work');
-}, 1000);
-
-setInterval(function(){
- b('doing some work');
-}, 1200);
-```
-
-#### Web Inspector Colors
-
- Colors are also enabled on "Web Inspectors" that understand the `%c` formatting
- option. These are WebKit web inspectors, Firefox ([since version
- 31](https://hacks.mozilla.org/2014/05/editable-box-model-multiple-selection-sublime-text-keys-much-more-firefox-developer-tools-episode-31/))
- and the Firebug plugin for Firefox (any version).
-
- Colored output looks something like:
-
- 
-
-### stderr vs stdout
-
-You can set an alternative logging method per-namespace by overriding the `log` method on a per-namespace or globally:
-
-Example _stderr.js_:
-
-```js
-var debug = require('../');
-var log = debug('app:log');
-
-// by default console.log is used
-log('goes to stdout!');
-
-var error = debug('app:error');
-// set this namespace to log via console.error
-error.log = console.error.bind(console); // don't forget to bind to console!
-error('goes to stderr');
-log('still goes to stdout!');
-
-// set all output to go via console.warn
-// overrides all per-namespace log settings
-debug.log = console.warn.bind(console);
-log('now goes to stderr via console.warn');
-error('still goes to stderr, but via console.warn now');
-```
-
-## Authors
-
- - TJ Holowaychuk
- - Nathan Rajlich
-
-## License
-
-(The MIT License)
-
-Copyright (c) 2014 TJ Holowaychuk <tj@vision-media.ca>
-
-Permission is hereby granted, free of charge, to any person obtaining
-a copy of this software and associated documentation files (the
-'Software'), to deal in the Software without restriction, including
-without limitation the rights to use, copy, modify, merge, publish,
-distribute, sublicense, and/or sell copies of the Software, and to
-permit persons to whom the Software is furnished to do so, subject to
-the following conditions:
-
-The above copyright notice and this permission notice shall be
-included in all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
-EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
-IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
-CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
-TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
-SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
diff --git a/CoAuthoring/node_modules/express/node_modules/debug/browser.js b/CoAuthoring/node_modules/express/node_modules/debug/browser.js
deleted file mode 100644
index ce6369f1cb..0000000000
--- a/CoAuthoring/node_modules/express/node_modules/debug/browser.js
+++ /dev/null
@@ -1,147 +0,0 @@
-
-/**
- * This is the web browser implementation of `debug()`.
- *
- * Expose `debug()` as the module.
- */
-
-exports = module.exports = require('./debug');
-exports.log = log;
-exports.formatArgs = formatArgs;
-exports.save = save;
-exports.load = load;
-exports.useColors = useColors;
-
-/**
- * Colors.
- */
-
-exports.colors = [
- 'lightseagreen',
- 'forestgreen',
- 'goldenrod',
- 'dodgerblue',
- 'darkorchid',
- 'crimson'
-];
-
-/**
- * Currently only WebKit-based Web Inspectors, Firefox >= v31,
- * and the Firebug extension (any Firefox version) are known
- * to support "%c" CSS customizations.
- *
- * TODO: add a `localStorage` variable to explicitly enable/disable colors
- */
-
-function useColors() {
- // is webkit? http://stackoverflow.com/a/16459606/376773
- return ('WebkitAppearance' in document.documentElement.style) ||
- // is firebug? http://stackoverflow.com/a/398120/376773
- (window.console && (console.firebug || (console.exception && console.table))) ||
- // is firefox >= v31?
- // https://developer.mozilla.org/en-US/docs/Tools/Web_Console#Styling_messages
- (navigator.userAgent.toLowerCase().match(/firefox\/(\d+)/) && parseInt(RegExp.$1, 10) >= 31);
-}
-
-/**
- * Map %j to `JSON.stringify()`, since no Web Inspectors do that by default.
- */
-
-exports.formatters.j = function(v) {
- return JSON.stringify(v);
-};
-
-
-/**
- * Colorize log arguments if enabled.
- *
- * @api public
- */
-
-function formatArgs() {
- var args = arguments;
- var useColors = this.useColors;
-
- args[0] = (useColors ? '%c' : '')
- + this.namespace
- + (useColors ? ' %c' : ' ')
- + args[0]
- + (useColors ? '%c ' : ' ')
- + '+' + exports.humanize(this.diff);
-
- if (!useColors) return args;
-
- var c = 'color: ' + this.color;
- args = [args[0], c, 'color: inherit'].concat(Array.prototype.slice.call(args, 1));
-
- // the final "%c" is somewhat tricky, because there could be other
- // arguments passed either before or after the %c, so we need to
- // figure out the correct index to insert the CSS into
- var index = 0;
- var lastC = 0;
- args[0].replace(/%[a-z%]/g, function(match) {
- if ('%%' === match) return;
- index++;
- if ('%c' === match) {
- // we only are interested in the *last* %c
- // (the user may have provided their own)
- lastC = index;
- }
- });
-
- args.splice(lastC, 0, c);
- return args;
-}
-
-/**
- * Invokes `console.log()` when available.
- * No-op when `console.log` is not a "function".
- *
- * @api public
- */
-
-function log() {
- // This hackery is required for IE8,
- // where the `console.log` function doesn't have 'apply'
- return 'object' == typeof console
- && 'function' == typeof console.log
- && Function.prototype.apply.call(console.log, console, arguments);
-}
-
-/**
- * Save `namespaces`.
- *
- * @param {String} namespaces
- * @api private
- */
-
-function save(namespaces) {
- try {
- if (null == namespaces) {
- localStorage.removeItem('debug');
- } else {
- localStorage.debug = namespaces;
- }
- } catch(e) {}
-}
-
-/**
- * Load `namespaces`.
- *
- * @return {String} returns the previously persisted debug modes
- * @api private
- */
-
-function load() {
- var r;
- try {
- r = localStorage.debug;
- } catch(e) {}
- return r;
-}
-
-/**
- * Enable namespaces listed in `localStorage.debug` initially.
- */
-
-exports.enable(load());
diff --git a/CoAuthoring/node_modules/express/node_modules/debug/component.json b/CoAuthoring/node_modules/express/node_modules/debug/component.json
deleted file mode 100644
index db1ceed124..0000000000
--- a/CoAuthoring/node_modules/express/node_modules/debug/component.json
+++ /dev/null
@@ -1,19 +0,0 @@
-{
- "name": "debug",
- "repo": "visionmedia/debug",
- "description": "small debugging utility",
- "version": "2.0.0",
- "keywords": [
- "debug",
- "log",
- "debugger"
- ],
- "main": "browser.js",
- "scripts": [
- "browser.js",
- "debug.js"
- ],
- "dependencies": {
- "guille/ms.js": "0.6.1"
- }
-}
diff --git a/CoAuthoring/node_modules/express/node_modules/debug/debug.js b/CoAuthoring/node_modules/express/node_modules/debug/debug.js
deleted file mode 100644
index 7571a86058..0000000000
--- a/CoAuthoring/node_modules/express/node_modules/debug/debug.js
+++ /dev/null
@@ -1,197 +0,0 @@
-
-/**
- * This is the common logic for both the Node.js and web browser
- * implementations of `debug()`.
- *
- * Expose `debug()` as the module.
- */
-
-exports = module.exports = debug;
-exports.coerce = coerce;
-exports.disable = disable;
-exports.enable = enable;
-exports.enabled = enabled;
-exports.humanize = require('ms');
-
-/**
- * The currently active debug mode names, and names to skip.
- */
-
-exports.names = [];
-exports.skips = [];
-
-/**
- * Map of special "%n" handling functions, for the debug "format" argument.
- *
- * Valid key names are a single, lowercased letter, i.e. "n".
- */
-
-exports.formatters = {};
-
-/**
- * Previously assigned color.
- */
-
-var prevColor = 0;
-
-/**
- * Previous log timestamp.
- */
-
-var prevTime;
-
-/**
- * Select a color.
- *
- * @return {Number}
- * @api private
- */
-
-function selectColor() {
- return exports.colors[prevColor++ % exports.colors.length];
-}
-
-/**
- * Create a debugger with the given `namespace`.
- *
- * @param {String} namespace
- * @return {Function}
- * @api public
- */
-
-function debug(namespace) {
-
- // define the `disabled` version
- function disabled() {
- }
- disabled.enabled = false;
-
- // define the `enabled` version
- function enabled() {
-
- var self = enabled;
-
- // set `diff` timestamp
- var curr = +new Date();
- var ms = curr - (prevTime || curr);
- self.diff = ms;
- self.prev = prevTime;
- self.curr = curr;
- prevTime = curr;
-
- // add the `color` if not set
- if (null == self.useColors) self.useColors = exports.useColors();
- if (null == self.color && self.useColors) self.color = selectColor();
-
- var args = Array.prototype.slice.call(arguments);
-
- args[0] = exports.coerce(args[0]);
-
- if ('string' !== typeof args[0]) {
- // anything else let's inspect with %o
- args = ['%o'].concat(args);
- }
-
- // apply any `formatters` transformations
- var index = 0;
- args[0] = args[0].replace(/%([a-z%])/g, function(match, format) {
- // if we encounter an escaped % then don't increase the array index
- if (match === '%%') return match;
- index++;
- var formatter = exports.formatters[format];
- if ('function' === typeof formatter) {
- var val = args[index];
- match = formatter.call(self, val);
-
- // now we need to remove `args[index]` since it's inlined in the `format`
- args.splice(index, 1);
- index--;
- }
- return match;
- });
-
- if ('function' === typeof exports.formatArgs) {
- args = exports.formatArgs.apply(self, args);
- }
- var logFn = enabled.log || exports.log || console.log.bind(console);
- logFn.apply(self, args);
- }
- enabled.enabled = true;
-
- var fn = exports.enabled(namespace) ? enabled : disabled;
-
- fn.namespace = namespace;
-
- return fn;
-}
-
-/**
- * Enables a debug mode by namespaces. This can include modes
- * separated by a colon and wildcards.
- *
- * @param {String} namespaces
- * @api public
- */
-
-function enable(namespaces) {
- exports.save(namespaces);
-
- var split = (namespaces || '').split(/[\s,]+/);
- var len = split.length;
-
- for (var i = 0; i < len; i++) {
- if (!split[i]) continue; // ignore empty strings
- namespaces = split[i].replace(/\*/g, '.*?');
- if (namespaces[0] === '-') {
- exports.skips.push(new RegExp('^' + namespaces.substr(1) + '$'));
- } else {
- exports.names.push(new RegExp('^' + namespaces + '$'));
- }
- }
-}
-
-/**
- * Disable debug output.
- *
- * @api public
- */
-
-function disable() {
- exports.enable('');
-}
-
-/**
- * Returns true if the given mode name is enabled, false otherwise.
- *
- * @param {String} name
- * @return {Boolean}
- * @api public
- */
-
-function enabled(name) {
- var i, len;
- for (i = 0, len = exports.skips.length; i < len; i++) {
- if (exports.skips[i].test(name)) {
- return false;
- }
- }
- for (i = 0, len = exports.names.length; i < len; i++) {
- if (exports.names[i].test(name)) {
- return true;
- }
- }
- return false;
-}
-
-/**
- * Coerce `val`.
- *
- * @param {Mixed} val
- * @return {Mixed}
- * @api private
- */
-
-function coerce(val) {
- if (val instanceof Error) return val.stack || val.message;
- return val;
-}
diff --git a/CoAuthoring/node_modules/express/node_modules/debug/node.js b/CoAuthoring/node_modules/express/node_modules/debug/node.js
deleted file mode 100644
index db86f64712..0000000000
--- a/CoAuthoring/node_modules/express/node_modules/debug/node.js
+++ /dev/null
@@ -1,129 +0,0 @@
-
-/**
- * Module dependencies.
- */
-
-var tty = require('tty');
-var util = require('util');
-
-/**
- * This is the Node.js implementation of `debug()`.
- *
- * Expose `debug()` as the module.
- */
-
-exports = module.exports = require('./debug');
-exports.log = log;
-exports.formatArgs = formatArgs;
-exports.save = save;
-exports.load = load;
-exports.useColors = useColors;
-
-/**
- * Colors.
- */
-
-exports.colors = [6, 2, 3, 4, 5, 1];
-
-/**
- * Is stdout a TTY? Colored output is enabled when `true`.
- */
-
-function useColors() {
- var debugColors = (process.env.DEBUG_COLORS || '').trim().toLowerCase();
- if (0 === debugColors.length) {
- return tty.isatty(1);
- } else {
- return '0' !== debugColors
- && 'no' !== debugColors
- && 'false' !== debugColors
- && 'disabled' !== debugColors;
- }
-}
-
-/**
- * Map %o to `util.inspect()`, since Node doesn't do that out of the box.
- */
-
-var inspect = (4 === util.inspect.length ?
- // node <= 0.8.x
- function (v, colors) {
- return util.inspect(v, void 0, void 0, colors);
- } :
- // node > 0.8.x
- function (v, colors) {
- return util.inspect(v, { colors: colors });
- }
-);
-
-exports.formatters.o = function(v) {
- return inspect(v, this.useColors)
- .replace(/\s*\n\s*/g, ' ');
-};
-
-/**
- * Adds ANSI color escape codes if enabled.
- *
- * @api public
- */
-
-function formatArgs() {
- var args = arguments;
- var useColors = this.useColors;
- var name = this.namespace;
-
- if (useColors) {
- var c = this.color;
-
- args[0] = ' \u001b[9' + c + 'm' + name + ' '
- + '\u001b[0m'
- + args[0] + '\u001b[3' + c + 'm'
- + ' +' + exports.humanize(this.diff) + '\u001b[0m';
- } else {
- args[0] = new Date().toUTCString()
- + ' ' + name + ' ' + args[0];
- }
- return args;
-}
-
-/**
- * Invokes `console.error()` with the specified arguments.
- */
-
-function log() {
- return console.error.apply(console, arguments);
-}
-
-/**
- * Save `namespaces`.
- *
- * @param {String} namespaces
- * @api private
- */
-
-function save(namespaces) {
- if (null == namespaces) {
- // If you set a process.env field to null or undefined, it gets cast to the
- // string 'null' or 'undefined'. Just delete instead.
- delete process.env.DEBUG;
- } else {
- process.env.DEBUG = namespaces;
- }
-}
-
-/**
- * Load `namespaces`.
- *
- * @return {String} returns the previously persisted debug modes
- * @api private
- */
-
-function load() {
- return process.env.DEBUG;
-}
-
-/**
- * Enable namespaces listed in `process.env.DEBUG` initially.
- */
-
-exports.enable(load());
diff --git a/CoAuthoring/node_modules/express/node_modules/debug/node_modules/ms/.npmignore b/CoAuthoring/node_modules/express/node_modules/debug/node_modules/ms/.npmignore
deleted file mode 100644
index d1aa0ce42e..0000000000
--- a/CoAuthoring/node_modules/express/node_modules/debug/node_modules/ms/.npmignore
+++ /dev/null
@@ -1,5 +0,0 @@
-node_modules
-test
-History.md
-Makefile
-component.json
diff --git a/CoAuthoring/node_modules/express/node_modules/debug/node_modules/ms/README.md b/CoAuthoring/node_modules/express/node_modules/debug/node_modules/ms/README.md
deleted file mode 100644
index d4ab12a730..0000000000
--- a/CoAuthoring/node_modules/express/node_modules/debug/node_modules/ms/README.md
+++ /dev/null
@@ -1,33 +0,0 @@
-# ms.js: miliseconds conversion utility
-
-```js
-ms('1d') // 86400000
-ms('10h') // 36000000
-ms('2h') // 7200000
-ms('1m') // 60000
-ms('5s') // 5000
-ms('100') // 100
-```
-
-```js
-ms(60000) // "1m"
-ms(2 * 60000) // "2m"
-ms(ms('10 hours')) // "10h"
-```
-
-```js
-ms(60000, { long: true }) // "1 minute"
-ms(2 * 60000, { long: true }) // "2 minutes"
-ms(ms('10 hours', { long: true })) // "10 hours"
-```
-
-- Node/Browser compatible. Published as `ms` in NPM.
-- If a number is supplied to `ms`, a string with a unit is returned.
-- If a string that contains the number is supplied, it returns it as
-a number (e.g: it returns `100` for `'100'`).
-- If you pass a string with a number and a valid unit, the number of
-equivalent ms is returned.
-
-## License
-
-MIT
\ No newline at end of file
diff --git a/CoAuthoring/node_modules/express/node_modules/debug/node_modules/ms/index.js b/CoAuthoring/node_modules/express/node_modules/debug/node_modules/ms/index.js
deleted file mode 100644
index c5847f8dd2..0000000000
--- a/CoAuthoring/node_modules/express/node_modules/debug/node_modules/ms/index.js
+++ /dev/null
@@ -1,111 +0,0 @@
-/**
- * Helpers.
- */
-
-var s = 1000;
-var m = s * 60;
-var h = m * 60;
-var d = h * 24;
-var y = d * 365.25;
-
-/**
- * Parse or format the given `val`.
- *
- * Options:
- *
- * - `long` verbose formatting [false]
- *
- * @param {String|Number} val
- * @param {Object} options
- * @return {String|Number}
- * @api public
- */
-
-module.exports = function(val, options){
- options = options || {};
- if ('string' == typeof val) return parse(val);
- return options.long
- ? long(val)
- : short(val);
-};
-
-/**
- * Parse the given `str` and return milliseconds.
- *
- * @param {String} str
- * @return {Number}
- * @api private
- */
-
-function parse(str) {
- var match = /^((?:\d+)?\.?\d+) *(ms|seconds?|s|minutes?|m|hours?|h|days?|d|years?|y)?$/i.exec(str);
- if (!match) return;
- var n = parseFloat(match[1]);
- var type = (match[2] || 'ms').toLowerCase();
- switch (type) {
- case 'years':
- case 'year':
- case 'y':
- return n * y;
- case 'days':
- case 'day':
- case 'd':
- return n * d;
- case 'hours':
- case 'hour':
- case 'h':
- return n * h;
- case 'minutes':
- case 'minute':
- case 'm':
- return n * m;
- case 'seconds':
- case 'second':
- case 's':
- return n * s;
- case 'ms':
- return n;
- }
-}
-
-/**
- * Short format for `ms`.
- *
- * @param {Number} ms
- * @return {String}
- * @api private
- */
-
-function short(ms) {
- if (ms >= d) return Math.round(ms / d) + 'd';
- if (ms >= h) return Math.round(ms / h) + 'h';
- if (ms >= m) return Math.round(ms / m) + 'm';
- if (ms >= s) return Math.round(ms / s) + 's';
- return ms + 'ms';
-}
-
-/**
- * Long format for `ms`.
- *
- * @param {Number} ms
- * @return {String}
- * @api private
- */
-
-function long(ms) {
- return plural(ms, d, 'day')
- || plural(ms, h, 'hour')
- || plural(ms, m, 'minute')
- || plural(ms, s, 'second')
- || ms + ' ms';
-}
-
-/**
- * Pluralization helper.
- */
-
-function plural(ms, n, name) {
- if (ms < n) return;
- if (ms < n * 1.5) return Math.floor(ms / n) + ' ' + name;
- return Math.ceil(ms / n) + ' ' + name + 's';
-}
diff --git a/CoAuthoring/node_modules/express/node_modules/debug/node_modules/ms/package.json b/CoAuthoring/node_modules/express/node_modules/debug/node_modules/ms/package.json
deleted file mode 100644
index fa2d2364be..0000000000
--- a/CoAuthoring/node_modules/express/node_modules/debug/node_modules/ms/package.json
+++ /dev/null
@@ -1,28 +0,0 @@
-{
- "name": "ms",
- "version": "0.6.2",
- "description": "Tiny ms conversion utility",
- "repository": {
- "type": "git",
- "url": "git://github.com/guille/ms.js.git"
- },
- "main": "./index",
- "devDependencies": {
- "mocha": "*",
- "expect.js": "*",
- "serve": "*"
- },
- "component": {
- "scripts": {
- "ms/index.js": "index.js"
- }
- },
- "readme": "# ms.js: miliseconds conversion utility\n\n```js\nms('1d') // 86400000\nms('10h') // 36000000\nms('2h') // 7200000\nms('1m') // 60000\nms('5s') // 5000\nms('100') // 100\n```\n\n```js\nms(60000) // \"1m\"\nms(2 * 60000) // \"2m\"\nms(ms('10 hours')) // \"10h\"\n```\n\n```js\nms(60000, { long: true }) // \"1 minute\"\nms(2 * 60000, { long: true }) // \"2 minutes\"\nms(ms('10 hours', { long: true })) // \"10 hours\"\n```\n\n- Node/Browser compatible. Published as `ms` in NPM.\n- If a number is supplied to `ms`, a string with a unit is returned.\n- If a string that contains the number is supplied, it returns it as\na number (e.g: it returns `100` for `'100'`).\n- If you pass a string with a number and a valid unit, the number of\nequivalent ms is returned.\n\n## License\n\nMIT",
- "readmeFilename": "README.md",
- "bugs": {
- "url": "https://github.com/guille/ms.js/issues"
- },
- "homepage": "https://github.com/guille/ms.js",
- "_id": "ms@0.6.2",
- "_from": "ms@0.6.2"
-}
diff --git a/CoAuthoring/node_modules/express/node_modules/debug/package.json b/CoAuthoring/node_modules/express/node_modules/debug/package.json
deleted file mode 100644
index f4b2adc7de..0000000000
--- a/CoAuthoring/node_modules/express/node_modules/debug/package.json
+++ /dev/null
@@ -1,48 +0,0 @@
-{
- "name": "debug",
- "version": "2.0.0",
- "repository": {
- "type": "git",
- "url": "git://github.com/visionmedia/debug.git"
- },
- "description": "small debugging utility",
- "keywords": [
- "debug",
- "log",
- "debugger"
- ],
- "author": {
- "name": "TJ Holowaychuk",
- "email": "tj@vision-media.ca"
- },
- "contributors": [
- {
- "name": "Nathan Rajlich",
- "email": "nathan@tootallnate.net",
- "url": "http://n8.io"
- }
- ],
- "dependencies": {
- "ms": "0.6.2"
- },
- "devDependencies": {
- "browserify": "5.11.0",
- "mocha": "*"
- },
- "main": "./node.js",
- "browser": "./browser.js",
- "component": {
- "scripts": {
- "debug/index.js": "browser.js",
- "debug/debug.js": "debug.js"
- }
- },
- "readme": "# debug\n\n tiny node.js debugging utility modelled after node core's debugging technique.\n\n## Installation\n\n```bash\n$ npm install debug\n```\n\n## Usage\n\n With `debug` you simply invoke the exported function to generate your debug function, passing it a name which will determine if a noop function is returned, or a decorated `console.error`, so all of the `console` format string goodies you're used to work fine. A unique color is selected per-function for visibility.\n\nExample _app.js_:\n\n```js\nvar debug = require('debug')('http')\n , http = require('http')\n , name = 'My App';\n\n// fake app\n\ndebug('booting %s', name);\n\nhttp.createServer(function(req, res){\n debug(req.method + ' ' + req.url);\n res.end('hello\\n');\n}).listen(3000, function(){\n debug('listening');\n});\n\n// fake worker of some kind\n\nrequire('./worker');\n```\n\nExample _worker.js_:\n\n```js\nvar debug = require('debug')('worker');\n\nsetInterval(function(){\n debug('doing some work');\n}, 1000);\n```\n\n The __DEBUG__ environment variable is then used to enable these based on space or comma-delimited names. Here are some examples:\n\n \n\n \n\n## Millisecond diff\n\n When actively developing an application it can be useful to see when the time spent between one `debug()` call and the next. Suppose for example you invoke `debug()` before requesting a resource, and after as well, the \"+NNNms\" will show you how much time was spent between calls.\n\n \n\n When stdout is not a TTY, `Date#toUTCString()` is used, making it more useful for logging the debug information as shown below:\n\n \n\n## Conventions\n\n If you're using this in one or more of your libraries, you _should_ use the name of your library so that developers may toggle debugging as desired without guessing names. If you have more than one debuggers you _should_ prefix them with your library name and use \":\" to separate features. For example \"bodyParser\" from Connect would then be \"connect:bodyParser\".\n\n## Wildcards\n\n The `*` character may be used as a wildcard. Suppose for example your library has debuggers named \"connect:bodyParser\", \"connect:compress\", \"connect:session\", instead of listing all three with `DEBUG=connect:bodyParser,connect.compress,connect:session`, you may simply do `DEBUG=connect:*`, or to run everything using this module simply use `DEBUG=*`.\n\n You can also exclude specific debuggers by prefixing them with a \"-\" character. For example, `DEBUG=*,-connect:*` would include all debuggers except those starting with \"connect:\".\n\n## Browser support\n\n Debug works in the browser as well, currently persisted by `localStorage`. For example if you have `worker:a` and `worker:b` as shown below, and wish to debug both type `debug.enable('worker:*')` in the console and refresh the page, this will remain until you disable with `debug.disable()`.\n\n```js\na = debug('worker:a');\nb = debug('worker:b');\n\nsetInterval(function(){\n a('doing some work');\n}, 1000);\n\nsetInterval(function(){\n b('doing some work');\n}, 1200);\n```\n\n#### Web Inspector Colors\n\n Colors are also enabled on \"Web Inspectors\" that understand the `%c` formatting\n option. These are WebKit web inspectors, Firefox ([since version\n 31](https://hacks.mozilla.org/2014/05/editable-box-model-multiple-selection-sublime-text-keys-much-more-firefox-developer-tools-episode-31/))\n and the Firebug plugin for Firefox (any version).\n\n Colored output looks something like:\n\n \n\n### stderr vs stdout\n\nYou can set an alternative logging method per-namespace by overriding the `log` method on a per-namespace or globally:\n\nExample _stderr.js_:\n\n```js\nvar debug = require('../');\nvar log = debug('app:log');\n\n// by default console.log is used\nlog('goes to stdout!');\n\nvar error = debug('app:error');\n// set this namespace to log via console.error\nerror.log = console.error.bind(console); // don't forget to bind to console!\nerror('goes to stderr');\nlog('still goes to stdout!');\n\n// set all output to go via console.warn\n// overrides all per-namespace log settings\ndebug.log = console.warn.bind(console);\nlog('now goes to stderr via console.warn');\nerror('still goes to stderr, but via console.warn now');\n```\n\n## Authors\n\n - TJ Holowaychuk\n - Nathan Rajlich\n\n## License\n\n(The MIT License)\n\nCopyright (c) 2014 TJ Holowaychuk <tj@vision-media.ca>\n\nPermission is hereby granted, free of charge, to any person obtaining\na copy of this software and associated documentation files (the\n'Software'), to deal in the Software without restriction, including\nwithout limitation the rights to use, copy, modify, merge, publish,\ndistribute, sublicense, and/or sell copies of the Software, and to\npermit persons to whom the Software is furnished to do so, subject to\nthe following conditions:\n\nThe above copyright notice and this permission notice shall be\nincluded in all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,\nEXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\nMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.\nIN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY\nCLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,\nTORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE\nSOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n",
- "readmeFilename": "Readme.md",
- "bugs": {
- "url": "https://github.com/visionmedia/debug/issues"
- },
- "homepage": "https://github.com/visionmedia/debug",
- "_id": "debug@2.0.0",
- "_from": "debug@~2.0.0"
-}
diff --git a/CoAuthoring/node_modules/express/node_modules/depd/History.md b/CoAuthoring/node_modules/express/node_modules/depd/History.md
deleted file mode 100644
index 800eab165a..0000000000
--- a/CoAuthoring/node_modules/express/node_modules/depd/History.md
+++ /dev/null
@@ -1,62 +0,0 @@
-0.4.5 / 2014-09-09
-==================
-
- * Improve call speed to functions using the function wrapper
- * Support Node.js 0.6
-
-0.4.4 / 2014-07-27
-==================
-
- * Work-around v8 generating empty stack traces
-
-0.4.3 / 2014-07-26
-==================
-
- * Fix exception when global `Error.stackTraceLimit` is too low
-
-0.4.2 / 2014-07-19
-==================
-
- * Correct call site for wrapped functions and properties
-
-0.4.1 / 2014-07-19
-==================
-
- * Improve automatic message generation for function properties
-
-0.4.0 / 2014-07-19
-==================
-
- * Add `TRACE_DEPRECATION` environment variable
- * Remove non-standard grey color from color output
- * Support `--no-deprecation` argument
- * Support `--trace-deprecation` argument
- * Support `deprecate.property(fn, prop, message)`
-
-0.3.0 / 2014-06-16
-==================
-
- * Add `NO_DEPRECATION` environment variable
-
-0.2.0 / 2014-06-15
-==================
-
- * Add `deprecate.property(obj, prop, message)`
- * Remove `supports-color` dependency for node.js 0.8
-
-0.1.0 / 2014-06-15
-==================
-
- * Add `deprecate.function(fn, message)`
- * Add `process.on('deprecation', fn)` emitter
- * Automatically generate message when omitted from `deprecate()`
-
-0.0.1 / 2014-06-15
-==================
-
- * Fix warning for dynamic calls at singe call site
-
-0.0.0 / 2014-06-15
-==================
-
- * Initial implementation
diff --git a/CoAuthoring/node_modules/express/node_modules/depd/LICENSE b/CoAuthoring/node_modules/express/node_modules/depd/LICENSE
deleted file mode 100644
index b7dce6cf9a..0000000000
--- a/CoAuthoring/node_modules/express/node_modules/depd/LICENSE
+++ /dev/null
@@ -1,22 +0,0 @@
-(The MIT License)
-
-Copyright (c) 2014 Douglas Christopher Wilson
-
-Permission is hereby granted, free of charge, to any person obtaining
-a copy of this software and associated documentation files (the
-'Software'), to deal in the Software without restriction, including
-without limitation the rights to use, copy, modify, merge, publish,
-distribute, sublicense, and/or sell copies of the Software, and to
-permit persons to whom the Software is furnished to do so, subject to
-the following conditions:
-
-The above copyright notice and this permission notice shall be
-included in all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
-EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
-IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
-CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
-TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
-SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
diff --git a/CoAuthoring/node_modules/express/node_modules/depd/Readme.md b/CoAuthoring/node_modules/express/node_modules/depd/Readme.md
deleted file mode 100644
index 098953e2d5..0000000000
--- a/CoAuthoring/node_modules/express/node_modules/depd/Readme.md
+++ /dev/null
@@ -1,266 +0,0 @@
-# depd
-
-[![NPM Version][npm-version-image]][npm-url]
-[![NPM Downloads][npm-downloads-image]][npm-url]
-[![Node.js Version][node-image]][node-url]
-[![Build Status][travis-image]][travis-url]
-[![Coverage Status][coveralls-image]][coveralls-url]
-[![Gittip][gittip-image]][gittip-url]
-
-Deprecate all the things
-
-> With great modules comes great responsibility; mark things deprecated!
-
-## Install
-
-```sh
-$ npm install depd
-```
-
-## API
-
-```js
-var deprecate = require('depd')('my-module')
-```
-
-This library allows you to display deprecation messages to your users.
-This library goes above and beyond with deprecation warnings by
-introspecting the call stack (but only the bits that it is interested
-in).
-
-Instead of just warning on the first invocation of a deprecated
-function and never again, this module will warn on the first invocation
-of a deprecated function per unique call site, making it ideal to alert
-users of all deprecated uses across the code base, rather than just
-whatever happens to execute first.
-
-The deprecation warnings from this module also include the file and line
-information for the call into the module that the deprecated function was
-in.
-
-### depd(namespace)
-
-Create a new deprecate function that uses the given namespace name in the
-messages and will display the call site prior to the stack entering the
-file this function was called from. It is highly suggested you use the
-name of your module as the namespace.
-
-### deprecate(message)
-
-Call this function from deprecated code to display a deprecation message.
-This message will appear once per unique caller site. Caller site is the
-first call site in the stack in a different file from the caller of this
-function.
-
-If the message is omitted, a message is generated for you based on the site
-of the `deprecate()` call and will display the name of the function called,
-similar to the name displayed in a stack trace.
-
-### deprecate.function(fn, message)
-
-Call this function to wrap a given function in a deprecation message on any
-call to the function. An optional message can be supplied to provide a custom
-message.
-
-### deprecate.property(obj, prop, message)
-
-Call this function to wrap a given property on object in a deprecation message
-on any accessing or setting of the property. An optional message can be supplied
-to provide a custom message.
-
-The method must be called on the object where the property belongs (not
-inherited from the prototype).
-
-If the property is a data descriptor, it will be converted to an accessor
-descriptor in order to display the deprecation message.
-
-### process.on('deprecation', fn)
-
-This module will allow easy capturing of deprecation errors by emitting the
-errors as the type "deprecation" on the global `process`. If there are no
-listeners for this type, the errors are written to STDERR as normal, but if
-there are any listeners, nothing will be written to STDERR and instead only
-emitted. From there, you can write the errors in a different format or to a
-logging source.
-
-The error represents the deprecation and is emitted only once with the same
-rules as writing to STDERR. The error has the following properties:
-
- - `message` - This is the message given by the library
- - `name` - This is always `'DeprecationError'`
- - `namespace` - This is the namespace the deprecation came from
- - `stack` - This is the stack of the call to the deprecated thing
-
-Example `error.stack` output:
-
-```
-DeprecationError: my-cool-module deprecated oldfunction
- at Object. ([eval]-wrapper:6:22)
- at Module._compile (module.js:456:26)
- at evalScript (node.js:532:25)
- at startup (node.js:80:7)
- at node.js:902:3
-```
-
-### process.env.NO_DEPRECATION
-
-As a user of modules that are deprecated, the environment variable `NO_DEPRECATION`
-is provided as a quick solution to silencing deprecation warnings from being
-output. The format of this is similar to that of `DEBUG`:
-
-```sh
-$ NO_DEPRECATION=my-module,othermod node app.js
-```
-
-This will suppress deprecations from being output for "my-module" and "othermod".
-The value is a list of comma-separated namespaces. To suppress every warning
-across all namespaces, use the value `*` for a namespace.
-
-Providing the argument `--no-deprecation` to the `node` executable will suppress
-all deprecations (only available in Node.js 0.8 or higher).
-
-**NOTE** This will not suppress the deperecations given to any "deprecation"
-event listeners, just the output to STDERR.
-
-### process.env.TRACE_DEPRECATION
-
-As a user of modules that are deprecated, the environment variable `TRACE_DEPRECATION`
-is provided as a solution to getting more detailed location information in deprecation
-warnings by including the entire stack trace. The format of this is the same as
-`NO_DEPRECATION`:
-
-```sh
-$ TRACE_DEPRECATION=my-module,othermod node app.js
-```
-
-This will include stack traces for deprecations being output for "my-module" and
-"othermod". The value is a list of comma-separated namespaces. To trace every
-warning across all namespaces, use the value `*` for a namespace.
-
-Providing the argument `--trace-deprecation` to the `node` executable will trace
-all deprecations (only available in Node.js 0.8 or higher).
-
-**NOTE** This will not trace the deperecations silenced by `NO_DEPRECATION`.
-
-## Display
-
-
-
-When a user calls a function in your library that you mark deprecated, they
-will see the following written to STDERR (in the given colors, similar colors
-and layout to the `debug` module):
-
-```
-bright cyan bright yellow
-| | reset cyan
-| | | |
-▼ ▼ ▼ ▼
-my-cool-module deprecated oldfunction [eval]-wrapper:6:22
-▲ ▲ ▲ ▲
-| | | |
-namespace | | location of mycoolmod.oldfunction() call
- | deprecation message
- the word "deprecated"
-```
-
-If the user redirects their STDERR to a file or somewhere that does not support
-colors, they see (similar layout to the `debug` module):
-
-```
-Sun, 15 Jun 2014 05:21:37 GMT my-cool-module deprecated oldfunction at [eval]-wrapper:6:22
-▲ ▲ ▲ ▲ ▲
-| | | | |
-timestamp of message namespace | | location of mycoolmod.oldfunction() call
- | deprecation message
- the word "deprecated"
-```
-
-## Examples
-
-### Deprecating all calls to a function
-
-This will display a deprecated message about "oldfunction" being deprecated
-from "my-module" on STDERR.
-
-```js
-var deprecate = require('depd')('my-cool-module')
-
-// message automatically derived from function name
-// Object.oldfunction
-exports.oldfunction = deprecate.function(function oldfunction() {
- // all calls to function are deprecated
-})
-
-// specific message
-exports.oldfunction = deprecate.function(function () {
- // all calls to function are deprecated
-}, 'oldfunction')
-```
-
-### Conditionally deprecating a function call
-
-This will display a deprecated message about "weirdfunction" being deprecated
-from "my-module" on STDERR when called with less than 2 arguments.
-
-```js
-var deprecate = require('depd')('my-cool-module')
-
-exports.weirdfunction = function () {
- if (arguments.length < 2) {
- // calls with 0 or 1 args are deprecated
- deprecate('weirdfunction args < 2')
- }
-}
-```
-
-When calling `deprecate` as a function, the warning is counted per call site
-within your own module, so you can display different deprecations depending
-on different situations and the users will still get all the warnings:
-
-```js
-var deprecate = require('depd')('my-cool-module')
-
-exports.weirdfunction = function () {
- if (arguments.length < 2) {
- // calls with 0 or 1 args are deprecated
- deprecate('weirdfunction args < 2')
- } else if (typeof arguments[0] !== 'string') {
- // calls with non-string first argument are deprecated
- deprecate('weirdfunction non-string first arg')
- }
-}
-```
-
-### Deprecating property access
-
-This will display a deprecated message about "oldprop" being deprecated
-from "my-module" on STDERR when accessed. A deprecation will be displayed
-when setting the value and when getting the value.
-
-```js
-var deprecate = require('depd')('my-cool-module')
-
-exports.oldprop = 'something'
-
-// message automatically derives from property name
-deprecate.property(exports, 'oldprop')
-
-// explicit message
-deprecate.property(exports, 'oldprop', 'oldprop >= 0.10')
-```
-
-## License
-
-[MIT](LICENSE)
-
-[npm-version-image]: https://img.shields.io/npm/v/depd.svg?style=flat
-[npm-downloads-image]: https://img.shields.io/npm/dm/depd.svg?style=flat
-[npm-url]: https://npmjs.org/package/depd
-[travis-image]: https://img.shields.io/travis/dougwilson/nodejs-depd.svg?style=flat
-[travis-url]: https://travis-ci.org/dougwilson/nodejs-depd
-[coveralls-image]: https://img.shields.io/coveralls/dougwilson/nodejs-depd.svg?style=flat
-[coveralls-url]: https://coveralls.io/r/dougwilson/nodejs-depd?branch=master
-[node-image]: https://img.shields.io/node/v/depd.svg?style=flat
-[node-url]: http://nodejs.org/download/
-[gittip-image]: https://img.shields.io/gittip/dougwilson.svg?style=flat
-[gittip-url]: https://www.gittip.com/dougwilson/
diff --git a/CoAuthoring/node_modules/express/node_modules/depd/index.js b/CoAuthoring/node_modules/express/node_modules/depd/index.js
deleted file mode 100644
index 4fee4d9869..0000000000
--- a/CoAuthoring/node_modules/express/node_modules/depd/index.js
+++ /dev/null
@@ -1,522 +0,0 @@
-/*!
- * depd
- * Copyright(c) 2014 Douglas Christopher Wilson
- * MIT Licensed
- */
-
-/**
- * Module dependencies.
- */
-
-var callSiteToString = require('./lib/compat').callSiteToString
-var EventEmitter = require('events').EventEmitter
-var relative = require('path').relative
-
-/**
- * Module exports.
- */
-
-module.exports = depd
-
-/**
- * Get the path to base files on.
- */
-
-var basePath = process.cwd()
-
-/**
- * Get listener count on event emitter.
- */
-
-/*istanbul ignore next*/
-var eventListenerCount = EventEmitter.listenerCount
- || function (emitter, type) { return emitter.listeners(type).length }
-
-/**
- * Determine if namespace is contained in the string.
- */
-
-function containsNamespace(str, namespace) {
- var val = str.split(/[ ,]+/)
-
- namespace = String(namespace).toLowerCase()
-
- for (var i = 0 ; i < val.length; i++) {
- if (!(str = val[i])) continue;
-
- // namespace contained
- if (str === '*' || str.toLowerCase() === namespace) {
- return true
- }
- }
-
- return false
-}
-
-/**
- * Convert a data descriptor to accessor descriptor.
- */
-
-function convertDataDescriptorToAccessor(obj, prop, message) {
- var descriptor = Object.getOwnPropertyDescriptor(obj, prop)
- var value = descriptor.value
-
- descriptor.get = function getter() { return value }
-
- if (descriptor.writable) {
- descriptor.set = function setter(val) { return value = val }
- }
-
- delete descriptor.value
- delete descriptor.writable
-
- Object.defineProperty(obj, prop, descriptor)
-
- return descriptor
-}
-
-/**
- * Create arguments string to keep arity.
- */
-
-function createArgumentsString(arity) {
- var str = ''
-
- for (var i = 0; i < arity; i++) {
- str += ', arg' + i
- }
-
- return str.substr(2)
-}
-
-/**
- * Create stack string from stack.
- */
-
-function createStackString(stack) {
- var str = this.name + ': ' + this.namespace
-
- if (this.message) {
- str += ' deprecated ' + this.message
- }
-
- for (var i = 0; i < stack.length; i++) {
- str += '\n at ' + callSiteToString(stack[i])
- }
-
- return str
-}
-
-/**
- * Create deprecate for namespace in caller.
- */
-
-function depd(namespace) {
- if (!namespace) {
- throw new TypeError('argument namespace is required')
- }
-
- var stack = getStack()
- var site = callSiteLocation(stack[1])
- var file = site[0]
-
- function deprecate(message) {
- // call to self as log
- log.call(deprecate, message)
- }
-
- deprecate._file = file
- deprecate._ignored = isignored(namespace)
- deprecate._namespace = namespace
- deprecate._traced = istraced(namespace)
- deprecate._warned = Object.create(null)
-
- deprecate.function = wrapfunction
- deprecate.property = wrapproperty
-
- return deprecate
-}
-
-/**
- * Determine if namespace is ignored.
- */
-
-function isignored(namespace) {
- /* istanbul ignore next: tested in a child processs */
- if (process.noDeprecation) {
- // --no-deprecation support
- return true
- }
-
- var str = process.env.NO_DEPRECATION || ''
-
- // namespace ignored
- return containsNamespace(str, namespace)
-}
-
-/**
- * Determine if namespace is traced.
- */
-
-function istraced(namespace) {
- /* istanbul ignore next: tested in a child processs */
- if (process.traceDeprecation) {
- // --trace-deprecation support
- return true
- }
-
- var str = process.env.TRACE_DEPRECATION || ''
-
- // namespace traced
- return containsNamespace(str, namespace)
-}
-
-/**
- * Display deprecation message.
- */
-
-function log(message, site) {
- var haslisteners = eventListenerCount(process, 'deprecation') !== 0
-
- // abort early if no destination
- if (!haslisteners && this._ignored) {
- return
- }
-
- var caller
- var callFile
- var callSite
- var i = 0
- var seen = false
- var stack = getStack()
- var file = this._file
-
- if (site) {
- // provided site
- callSite = callSiteLocation(stack[1])
- callSite.name = site.name
- file = callSite[0]
- } else {
- // get call site
- i = 2
- site = callSiteLocation(stack[i])
- callSite = site
- }
-
- // get caller of deprecated thing in relation to file
- for (; i < stack.length; i++) {
- caller = callSiteLocation(stack[i])
- callFile = caller[0]
-
- if (callFile === file) {
- seen = true
- } else if (callFile === this._file) {
- file = this._file
- } else if (seen) {
- break
- }
- }
-
- var key = caller
- ? site.join(':') + '__' + caller.join(':')
- : undefined
-
- if (key !== undefined && key in this._warned) {
- // already warned
- return
- }
-
- this._warned[key] = true
-
- // generate automatic message from call site
- if (!message) {
- message = callSite === site || !callSite.name
- ? defaultMessage(site)
- : defaultMessage(callSite)
- }
-
- // emit deprecation if listeners exist
- if (haslisteners) {
- var err = DeprecationError(this._namespace, message, stack.slice(i))
- process.emit('deprecation', err)
- return
- }
-
- // format and write message
- var format = process.stderr.isTTY
- ? formatColor
- : formatPlain
- var msg = format.call(this, message, caller, stack.slice(i))
- process.stderr.write(msg + '\n', 'utf8')
-
- return
-}
-
-/**
- * Get call site location as array.
- */
-
-function callSiteLocation(callSite) {
- var file = callSite.getFileName() || ''
- var line = callSite.getLineNumber()
- var colm = callSite.getColumnNumber()
-
- if (callSite.isEval()) {
- file = callSite.getEvalOrigin() + ', ' + file
- }
-
- var site = [file, line, colm]
-
- site.callSite = callSite
- site.name = callSite.getFunctionName()
-
- return site
-}
-
-/**
- * Generate a default message from the site.
- */
-
-function defaultMessage(site) {
- var callSite = site.callSite
- var funcName = site.name
- var typeName = callSite.getTypeName()
-
- // make useful anonymous name
- if (!funcName) {
- funcName = ''
- }
-
- // make useful type name
- if (typeName === 'Function') {
- typeName = callSite.getThis().name || typeName
- }
-
- return callSite.getMethodName()
- ? typeName + '.' + funcName
- : funcName
-}
-
-/**
- * Format deprecation message without color.
- */
-
-function formatPlain(msg, caller, stack) {
- var timestamp = new Date().toUTCString()
-
- var formatted = timestamp
- + ' ' + this._namespace
- + ' deprecated ' + msg
-
- // add stack trace
- if (this._traced) {
- for (var i = 0; i < stack.length; i++) {
- formatted += '\n at ' + callSiteToString(stack[i])
- }
-
- return formatted
- }
-
- if (caller) {
- formatted += ' at ' + formatLocation(caller)
- }
-
- return formatted
-}
-
-/**
- * Format deprecation message with color.
- */
-
-function formatColor(msg, caller, stack) {
- var formatted = '\x1b[36;1m' + this._namespace + '\x1b[22;39m' // bold cyan
- + ' \x1b[33;1mdeprecated\x1b[22;39m' // bold yellow
- + ' \x1b[0m' + msg + '\x1b[39m' // reset
-
- // add stack trace
- if (this._traced) {
- for (var i = 0; i < stack.length; i++) {
- formatted += '\n \x1b[36mat ' + callSiteToString(stack[i]) + '\x1b[39m' // cyan
- }
-
- return formatted
- }
-
- if (caller) {
- formatted += ' \x1b[36m' + formatLocation(caller) + '\x1b[39m' // cyan
- }
-
- return formatted
-}
-
-/**
- * Format call site location.
- */
-
-function formatLocation(callSite) {
- return relative(basePath, callSite[0])
- + ':' + callSite[1]
- + ':' + callSite[2]
-}
-
-/**
- * Get the stack as array of call sites.
- */
-
-function getStack() {
- var limit = Error.stackTraceLimit
- var obj = {}
- var prep = Error.prepareStackTrace
-
- Error.prepareStackTrace = prepareObjectStackTrace
- Error.stackTraceLimit = Math.max(10, limit)
-
- // capture the stack
- Error.captureStackTrace(obj)
-
- // slice this function off the top
- var stack = obj.stack.slice(1)
-
- Error.prepareStackTrace = prep
- Error.stackTraceLimit = limit
-
- return stack
-}
-
-/**
- * Capture call site stack from v8.
- */
-
-function prepareObjectStackTrace(obj, stack) {
- return stack
-}
-
-/**
- * Return a wrapped function in a deprecation message.
- */
-
-function wrapfunction(fn, message) {
- if (typeof fn !== 'function') {
- throw new TypeError('argument fn must be a function')
- }
-
- var args = createArgumentsString(fn.length)
- var deprecate = this
- var stack = getStack()
- var site = callSiteLocation(stack[1])
-
- site.name = fn.name
-
- var deprecatedfn = eval('(function (' + args + ') {\n'
- + '"use strict"\n'
- + 'log.call(deprecate, message, site)\n'
- + 'return fn.apply(this, arguments)\n'
- + '})')
-
- return deprecatedfn
-}
-
-/**
- * Wrap property in a deprecation message.
- */
-
-function wrapproperty(obj, prop, message) {
- if (!obj || (typeof obj !== 'object' && typeof obj !== 'function')) {
- throw new TypeError('argument obj must be object')
- }
-
- var descriptor = Object.getOwnPropertyDescriptor(obj, prop)
-
- if (!descriptor) {
- throw new TypeError('must call property on owner object')
- }
-
- if (!descriptor.configurable) {
- throw new TypeError('property must be configurable')
- }
-
- var deprecate = this
- var stack = getStack()
- var site = callSiteLocation(stack[1])
-
- // set site name
- site.name = prop
-
- // convert data descriptor
- if ('value' in descriptor) {
- descriptor = convertDataDescriptorToAccessor(obj, prop, message)
- }
-
- var get = descriptor.get
- var set = descriptor.set
-
- // wrap getter
- if (typeof get === 'function') {
- descriptor.get = function getter() {
- log.call(deprecate, message, site)
- return get.apply(this, arguments)
- }
- }
-
- // wrap setter
- if (typeof set === 'function') {
- descriptor.set = function setter() {
- log.call(deprecate, message, site)
- return set.apply(this, arguments)
- }
- }
-
- Object.defineProperty(obj, prop, descriptor)
-}
-
-/**
- * Create DeprecationError for deprecation
- */
-
-function DeprecationError(namespace, message, stack) {
- var error = new Error()
- var stackString
-
- Object.defineProperty(error, 'constructor', {
- value: DeprecationError
- })
-
- Object.defineProperty(error, 'message', {
- configurable: true,
- enumerable: false,
- value: message,
- writable: true
- })
-
- Object.defineProperty(error, 'name', {
- enumerable: false,
- configurable: true,
- value: 'DeprecationError',
- writable: true
- })
-
- Object.defineProperty(error, 'namespace', {
- configurable: true,
- enumerable: false,
- value: namespace,
- writable: true
- })
-
- Object.defineProperty(error, 'stack', {
- configurable: true,
- enumerable: false,
- get: function () {
- if (stackString !== undefined) {
- return stackString
- }
-
- // prepare stack trace
- return stackString = createStackString.call(this, stack)
- },
- set: function setter(val) {
- stackString = val
- }
- })
-
- return error
-}
diff --git a/CoAuthoring/node_modules/express/node_modules/depd/lib/compat/buffer-concat.js b/CoAuthoring/node_modules/express/node_modules/depd/lib/compat/buffer-concat.js
deleted file mode 100644
index 09d9721965..0000000000
--- a/CoAuthoring/node_modules/express/node_modules/depd/lib/compat/buffer-concat.js
+++ /dev/null
@@ -1,33 +0,0 @@
-/*!
- * depd
- * Copyright(c) 2014 Douglas Christopher Wilson
- * MIT Licensed
- */
-
-/**
- * Module exports.
- */
-
-module.exports = bufferConcat
-
-/**
- * Concatenate an array of Buffers.
- */
-
-function bufferConcat(bufs) {
- var length = 0
-
- for (var i = 0, len = bufs.length; i < len; i++) {
- length += bufs[i].length
- }
-
- var buf = new Buffer(length)
- var pos = 0
-
- for (var i = 0, len = bufs.length; i < len; i++) {
- bufs[i].copy(buf, pos)
- pos += bufs[i].length
- }
-
- return buf
-}
diff --git a/CoAuthoring/node_modules/express/node_modules/depd/lib/compat/callsite-tostring.js b/CoAuthoring/node_modules/express/node_modules/depd/lib/compat/callsite-tostring.js
deleted file mode 100644
index 17cf7ed1d9..0000000000
--- a/CoAuthoring/node_modules/express/node_modules/depd/lib/compat/callsite-tostring.js
+++ /dev/null
@@ -1,101 +0,0 @@
-/*!
- * depd
- * Copyright(c) 2014 Douglas Christopher Wilson
- * MIT Licensed
- */
-
-/**
- * Module exports.
- */
-
-module.exports = callSiteToString
-
-/**
- * Format a CallSite file location to a string.
- */
-
-function callSiteFileLocation(callSite) {
- var fileName
- var fileLocation = ''
-
- if (callSite.isNative()) {
- fileLocation = 'native'
- } else if (callSite.isEval()) {
- fileName = callSite.getScriptNameOrSourceURL()
- if (!fileName) {
- fileLocation = callSite.getEvalOrigin()
- }
- } else {
- fileName = callSite.getFileName()
- }
-
- if (fileName) {
- fileLocation += fileName
-
- var lineNumber = callSite.getLineNumber()
- if (lineNumber != null) {
- fileLocation += ':' + lineNumber
-
- var columnNumber = callSite.getColumnNumber()
- if (columnNumber) {
- fileLocation += ':' + columnNumber
- }
- }
- }
-
- return fileLocation || 'unknown source'
-}
-
-/**
- * Format a CallSite to a string.
- */
-
-function callSiteToString(callSite) {
- var addSuffix = true
- var fileLocation = callSiteFileLocation(callSite)
- var functionName = callSite.getFunctionName()
- var isConstructor = callSite.isConstructor()
- var isMethodCall = !(callSite.isToplevel() || isConstructor)
- var line = ''
-
- if (isMethodCall) {
- var methodName = callSite.getMethodName()
- var typeName = getConstructorName(callSite)
-
- if (functionName) {
- if (typeName && functionName.indexOf(typeName) !== 0) {
- line += typeName + '.'
- }
-
- line += functionName
-
- if (methodName && functionName.lastIndexOf('.' + methodName) !== functionName.length - methodName.length - 1) {
- line += ' [as ' + methodName + ']'
- }
- } else {
- line += typeName + '.' + (methodName || '')
- }
- } else if (isConstructor) {
- line += 'new ' + (functionName || '')
- } else if (functionName) {
- line += functionName
- } else {
- addSuffix = false
- line += fileLocation
- }
-
- if (addSuffix) {
- line += ' (' + fileLocation + ')'
- }
-
- return line
-}
-
-/**
- * Get constructor name of reviver.
- */
-
-function getConstructorName(obj) {
- var receiver = obj.receiver
- return (receiver.constructor && receiver.constructor.name) || null
-}
diff --git a/CoAuthoring/node_modules/express/node_modules/depd/lib/compat/index.js b/CoAuthoring/node_modules/express/node_modules/depd/lib/compat/index.js
deleted file mode 100644
index 7fee026eca..0000000000
--- a/CoAuthoring/node_modules/express/node_modules/depd/lib/compat/index.js
+++ /dev/null
@@ -1,69 +0,0 @@
-/*!
- * depd
- * Copyright(c) 2014 Douglas Christopher Wilson
- * MIT Licensed
- */
-
-/**
- * Module exports.
- */
-
-lazyProperty(module.exports, 'bufferConcat', function bufferConcat() {
- return Buffer.concat || require('./buffer-concat')
-})
-
-lazyProperty(module.exports, 'callSiteToString', function callSiteToString() {
- var limit = Error.stackTraceLimit
- var obj = {}
- var prep = Error.prepareStackTrace
-
- function prepareObjectStackTrace(obj, stack) {
- return stack
- }
-
- Error.prepareStackTrace = prepareObjectStackTrace
- Error.stackTraceLimit = 2
-
- // capture the stack
- Error.captureStackTrace(obj)
-
- // slice the stack
- var stack = obj.stack.slice()
-
- Error.prepareStackTrace = prep
- Error.stackTraceLimit = limit
-
- return stack[0].toString ? toString : require('./callsite-tostring')
-})
-
-/**
- * Define a lazy property.
- */
-
-function lazyProperty(obj, prop, getter) {
- function get() {
- var val = getter()
-
- Object.defineProperty(obj, prop, {
- configurable: true,
- enumerable: true,
- value: val
- })
-
- return val
- }
-
- Object.defineProperty(obj, prop, {
- configurable: true,
- enumerable: true,
- get: get
- })
-}
-
-/**
- * Call toString() on the obj
- */
-
-function toString(obj) {
- return obj.toString()
-}
diff --git a/CoAuthoring/node_modules/express/node_modules/depd/package.json b/CoAuthoring/node_modules/express/node_modules/depd/package.json
deleted file mode 100644
index b0fd79359b..0000000000
--- a/CoAuthoring/node_modules/express/node_modules/depd/package.json
+++ /dev/null
@@ -1,49 +0,0 @@
-{
- "name": "depd",
- "description": "Deprecate all the things",
- "version": "0.4.5",
- "author": {
- "name": "Douglas Christopher Wilson",
- "email": "doug@somethingdoug.com"
- },
- "license": "MIT",
- "keywords": [
- "deprecate",
- "deprecated"
- ],
- "repository": {
- "type": "git",
- "url": "git://github.com/dougwilson/nodejs-depd"
- },
- "devDependencies": {
- "benchmark": "1.0.0",
- "beautify-benchmark": "0.2.4",
- "istanbul": "0.3.2",
- "mocha": "~1.21.4",
- "should": "~4.0.4"
- },
- "files": [
- "lib/",
- "History.md",
- "LICENSE",
- "index.js",
- "Readme.md"
- ],
- "engines": {
- "node": ">= 0.6"
- },
- "scripts": {
- "bench": "node benchmark/index.js",
- "test": "mocha --reporter spec --bail --require should test/",
- "test-cov": "istanbul cover node_modules/mocha/bin/_mocha -- --reporter dot --require should test/",
- "test-travis": "istanbul cover node_modules/mocha/bin/_mocha --report lcovonly -- --reporter spec --require should test/"
- },
- "readme": "# depd\n\n[![NPM Version][npm-version-image]][npm-url]\n[![NPM Downloads][npm-downloads-image]][npm-url]\n[![Node.js Version][node-image]][node-url]\n[![Build Status][travis-image]][travis-url]\n[![Coverage Status][coveralls-image]][coveralls-url]\n[![Gittip][gittip-image]][gittip-url]\n\nDeprecate all the things\n\n> With great modules comes great responsibility; mark things deprecated!\n\n## Install\n\n```sh\n$ npm install depd\n```\n\n## API\n\n```js\nvar deprecate = require('depd')('my-module')\n```\n\nThis library allows you to display deprecation messages to your users.\nThis library goes above and beyond with deprecation warnings by\nintrospecting the call stack (but only the bits that it is interested\nin).\n\nInstead of just warning on the first invocation of a deprecated\nfunction and never again, this module will warn on the first invocation\nof a deprecated function per unique call site, making it ideal to alert\nusers of all deprecated uses across the code base, rather than just\nwhatever happens to execute first.\n\nThe deprecation warnings from this module also include the file and line\ninformation for the call into the module that the deprecated function was\nin.\n\n### depd(namespace)\n\nCreate a new deprecate function that uses the given namespace name in the\nmessages and will display the call site prior to the stack entering the\nfile this function was called from. It is highly suggested you use the\nname of your module as the namespace.\n\n### deprecate(message)\n\nCall this function from deprecated code to display a deprecation message.\nThis message will appear once per unique caller site. Caller site is the\nfirst call site in the stack in a different file from the caller of this\nfunction.\n\nIf the message is omitted, a message is generated for you based on the site\nof the `deprecate()` call and will display the name of the function called,\nsimilar to the name displayed in a stack trace.\n\n### deprecate.function(fn, message)\n\nCall this function to wrap a given function in a deprecation message on any\ncall to the function. An optional message can be supplied to provide a custom\nmessage.\n\n### deprecate.property(obj, prop, message)\n\nCall this function to wrap a given property on object in a deprecation message\non any accessing or setting of the property. An optional message can be supplied\nto provide a custom message.\n\nThe method must be called on the object where the property belongs (not\ninherited from the prototype).\n\nIf the property is a data descriptor, it will be converted to an accessor\ndescriptor in order to display the deprecation message.\n\n### process.on('deprecation', fn)\n\nThis module will allow easy capturing of deprecation errors by emitting the\nerrors as the type \"deprecation\" on the global `process`. If there are no\nlisteners for this type, the errors are written to STDERR as normal, but if\nthere are any listeners, nothing will be written to STDERR and instead only\nemitted. From there, you can write the errors in a different format or to a\nlogging source.\n\nThe error represents the deprecation and is emitted only once with the same\nrules as writing to STDERR. The error has the following properties:\n\n - `message` - This is the message given by the library\n - `name` - This is always `'DeprecationError'`\n - `namespace` - This is the namespace the deprecation came from\n - `stack` - This is the stack of the call to the deprecated thing\n\nExample `error.stack` output:\n\n```\nDeprecationError: my-cool-module deprecated oldfunction\n at Object. ([eval]-wrapper:6:22)\n at Module._compile (module.js:456:26)\n at evalScript (node.js:532:25)\n at startup (node.js:80:7)\n at node.js:902:3\n```\n\n### process.env.NO_DEPRECATION\n\nAs a user of modules that are deprecated, the environment variable `NO_DEPRECATION`\nis provided as a quick solution to silencing deprecation warnings from being\noutput. The format of this is similar to that of `DEBUG`:\n\n```sh\n$ NO_DEPRECATION=my-module,othermod node app.js\n```\n\nThis will suppress deprecations from being output for \"my-module\" and \"othermod\".\nThe value is a list of comma-separated namespaces. To suppress every warning\nacross all namespaces, use the value `*` for a namespace.\n\nProviding the argument `--no-deprecation` to the `node` executable will suppress\nall deprecations (only available in Node.js 0.8 or higher).\n\n**NOTE** This will not suppress the deperecations given to any \"deprecation\"\nevent listeners, just the output to STDERR.\n\n### process.env.TRACE_DEPRECATION\n\nAs a user of modules that are deprecated, the environment variable `TRACE_DEPRECATION`\nis provided as a solution to getting more detailed location information in deprecation\nwarnings by including the entire stack trace. The format of this is the same as\n`NO_DEPRECATION`:\n\n```sh\n$ TRACE_DEPRECATION=my-module,othermod node app.js\n```\n\nThis will include stack traces for deprecations being output for \"my-module\" and\n\"othermod\". The value is a list of comma-separated namespaces. To trace every\nwarning across all namespaces, use the value `*` for a namespace.\n\nProviding the argument `--trace-deprecation` to the `node` executable will trace\nall deprecations (only available in Node.js 0.8 or higher).\n\n**NOTE** This will not trace the deperecations silenced by `NO_DEPRECATION`.\n\n## Display\n\n\n\nWhen a user calls a function in your library that you mark deprecated, they\nwill see the following written to STDERR (in the given colors, similar colors\nand layout to the `debug` module):\n\n```\nbright cyan bright yellow\n| | reset cyan\n| | | |\n▼ ▼ ▼ ▼\nmy-cool-module deprecated oldfunction [eval]-wrapper:6:22\n▲ ▲ ▲ ▲\n| | | |\nnamespace | | location of mycoolmod.oldfunction() call\n | deprecation message\n the word \"deprecated\"\n```\n\nIf the user redirects their STDERR to a file or somewhere that does not support\ncolors, they see (similar layout to the `debug` module):\n\n```\nSun, 15 Jun 2014 05:21:37 GMT my-cool-module deprecated oldfunction at [eval]-wrapper:6:22\n▲ ▲ ▲ ▲ ▲\n| | | | |\ntimestamp of message namespace | | location of mycoolmod.oldfunction() call\n | deprecation message\n the word \"deprecated\"\n```\n\n## Examples\n\n### Deprecating all calls to a function\n\nThis will display a deprecated message about \"oldfunction\" being deprecated\nfrom \"my-module\" on STDERR.\n\n```js\nvar deprecate = require('depd')('my-cool-module')\n\n// message automatically derived from function name\n// Object.oldfunction\nexports.oldfunction = deprecate.function(function oldfunction() {\n // all calls to function are deprecated\n})\n\n// specific message\nexports.oldfunction = deprecate.function(function () {\n // all calls to function are deprecated\n}, 'oldfunction')\n```\n\n### Conditionally deprecating a function call\n\nThis will display a deprecated message about \"weirdfunction\" being deprecated\nfrom \"my-module\" on STDERR when called with less than 2 arguments.\n\n```js\nvar deprecate = require('depd')('my-cool-module')\n\nexports.weirdfunction = function () {\n if (arguments.length < 2) {\n // calls with 0 or 1 args are deprecated\n deprecate('weirdfunction args < 2')\n }\n}\n```\n\nWhen calling `deprecate` as a function, the warning is counted per call site\nwithin your own module, so you can display different deprecations depending\non different situations and the users will still get all the warnings:\n\n```js\nvar deprecate = require('depd')('my-cool-module')\n\nexports.weirdfunction = function () {\n if (arguments.length < 2) {\n // calls with 0 or 1 args are deprecated\n deprecate('weirdfunction args < 2')\n } else if (typeof arguments[0] !== 'string') {\n // calls with non-string first argument are deprecated\n deprecate('weirdfunction non-string first arg')\n }\n}\n```\n\n### Deprecating property access\n\nThis will display a deprecated message about \"oldprop\" being deprecated\nfrom \"my-module\" on STDERR when accessed. A deprecation will be displayed\nwhen setting the value and when getting the value.\n\n```js\nvar deprecate = require('depd')('my-cool-module')\n\nexports.oldprop = 'something'\n\n// message automatically derives from property name\ndeprecate.property(exports, 'oldprop')\n\n// explicit message\ndeprecate.property(exports, 'oldprop', 'oldprop >= 0.10')\n```\n\n## License\n\n[MIT](LICENSE)\n\n[npm-version-image]: https://img.shields.io/npm/v/depd.svg?style=flat\n[npm-downloads-image]: https://img.shields.io/npm/dm/depd.svg?style=flat\n[npm-url]: https://npmjs.org/package/depd\n[travis-image]: https://img.shields.io/travis/dougwilson/nodejs-depd.svg?style=flat\n[travis-url]: https://travis-ci.org/dougwilson/nodejs-depd\n[coveralls-image]: https://img.shields.io/coveralls/dougwilson/nodejs-depd.svg?style=flat\n[coveralls-url]: https://coveralls.io/r/dougwilson/nodejs-depd?branch=master\n[node-image]: https://img.shields.io/node/v/depd.svg?style=flat\n[node-url]: http://nodejs.org/download/\n[gittip-image]: https://img.shields.io/gittip/dougwilson.svg?style=flat\n[gittip-url]: https://www.gittip.com/dougwilson/\n",
- "readmeFilename": "Readme.md",
- "bugs": {
- "url": "https://github.com/dougwilson/nodejs-depd/issues"
- },
- "homepage": "https://github.com/dougwilson/nodejs-depd",
- "_id": "depd@0.4.5",
- "_from": "depd@0.4.5"
-}
diff --git a/CoAuthoring/node_modules/express/node_modules/escape-html/.npmignore b/CoAuthoring/node_modules/express/node_modules/escape-html/.npmignore
deleted file mode 100644
index 48a2e246c6..0000000000
--- a/CoAuthoring/node_modules/express/node_modules/escape-html/.npmignore
+++ /dev/null
@@ -1,2 +0,0 @@
-components
-build
diff --git a/CoAuthoring/node_modules/express/node_modules/escape-html/Makefile b/CoAuthoring/node_modules/express/node_modules/escape-html/Makefile
deleted file mode 100644
index 3f6119d227..0000000000
--- a/CoAuthoring/node_modules/express/node_modules/escape-html/Makefile
+++ /dev/null
@@ -1,11 +0,0 @@
-
-build: components index.js
- @component build
-
-components:
- @Component install
-
-clean:
- rm -fr build components template.js
-
-.PHONY: clean
diff --git a/CoAuthoring/node_modules/express/node_modules/escape-html/Readme.md b/CoAuthoring/node_modules/express/node_modules/escape-html/Readme.md
deleted file mode 100644
index 2cfcc99733..0000000000
--- a/CoAuthoring/node_modules/express/node_modules/escape-html/Readme.md
+++ /dev/null
@@ -1,15 +0,0 @@
-
-# escape-html
-
- Escape HTML entities
-
-## Example
-
-```js
-var escape = require('escape-html');
-escape(str);
-```
-
-## License
-
- MIT
\ No newline at end of file
diff --git a/CoAuthoring/node_modules/express/node_modules/escape-html/component.json b/CoAuthoring/node_modules/express/node_modules/escape-html/component.json
deleted file mode 100644
index cb9740fd4c..0000000000
--- a/CoAuthoring/node_modules/express/node_modules/escape-html/component.json
+++ /dev/null
@@ -1,10 +0,0 @@
-{
- "name": "escape-html",
- "description": "Escape HTML entities",
- "version": "1.0.1",
- "keywords": ["escape", "html", "utility"],
- "dependencies": {},
- "scripts": [
- "index.js"
- ]
-}
diff --git a/CoAuthoring/node_modules/express/node_modules/escape-html/index.js b/CoAuthoring/node_modules/express/node_modules/escape-html/index.js
deleted file mode 100644
index 276521145c..0000000000
--- a/CoAuthoring/node_modules/express/node_modules/escape-html/index.js
+++ /dev/null
@@ -1,16 +0,0 @@
-/**
- * Escape special characters in the given string of html.
- *
- * @param {String} html
- * @return {String}
- * @api private
- */
-
-module.exports = function(html) {
- return String(html)
- .replace(/&/g, '&')
- .replace(/"/g, '"')
- .replace(/'/g, ''')
- .replace(//g, '>');
-}
diff --git a/CoAuthoring/node_modules/express/node_modules/escape-html/package.json b/CoAuthoring/node_modules/express/node_modules/escape-html/package.json
deleted file mode 100644
index 46fe117baa..0000000000
--- a/CoAuthoring/node_modules/express/node_modules/escape-html/package.json
+++ /dev/null
@@ -1,29 +0,0 @@
-{
- "name": "escape-html",
- "description": "Escape HTML entities",
- "version": "1.0.1",
- "keywords": [
- "escape",
- "html",
- "utility"
- ],
- "dependencies": {},
- "main": "index.js",
- "component": {
- "scripts": {
- "escape-html/index.js": "index.js"
- }
- },
- "repository": {
- "type": "git",
- "url": "https://github.com/component/escape-html.git"
- },
- "readme": "\n# escape-html\n\n Escape HTML entities\n\n## Example\n\n```js\nvar escape = require('escape-html');\nescape(str);\n```\n\n## License\n\n MIT",
- "readmeFilename": "Readme.md",
- "bugs": {
- "url": "https://github.com/component/escape-html/issues"
- },
- "homepage": "https://github.com/component/escape-html",
- "_id": "escape-html@1.0.1",
- "_from": "escape-html@1.0.1"
-}
diff --git a/CoAuthoring/node_modules/express/node_modules/etag/HISTORY.md b/CoAuthoring/node_modules/express/node_modules/etag/HISTORY.md
deleted file mode 100644
index 3846cf0db9..0000000000
--- a/CoAuthoring/node_modules/express/node_modules/etag/HISTORY.md
+++ /dev/null
@@ -1,43 +0,0 @@
-1.4.0 / 2014-09-21
-==================
-
- * Support "fake" stats objects
- * Support Node.js 0.6
-
-1.3.1 / 2014-09-14
-==================
-
- * Use the (new and improved) `crc` for crc32
-
-1.3.0 / 2014-08-29
-==================
-
- * Default strings to strong ETags
- * Improve speed for weak ETags over 1KB
-
-1.2.1 / 2014-08-29
-==================
-
- * Use the (much faster) `buffer-crc32` for crc32
-
-1.2.0 / 2014-08-24
-==================
-
- * Add support for file stat objects
-
-1.1.0 / 2014-08-24
-==================
-
- * Add fast-path for empty entity
- * Add weak ETag generation
- * Shrink size of generated ETags
-
-1.0.1 / 2014-08-24
-==================
-
- * Fix behavior of string containing Unicode
-
-1.0.0 / 2014-05-18
-==================
-
- * Initial release
diff --git a/CoAuthoring/node_modules/express/node_modules/etag/LICENSE b/CoAuthoring/node_modules/express/node_modules/etag/LICENSE
deleted file mode 100644
index b7dce6cf9a..0000000000
--- a/CoAuthoring/node_modules/express/node_modules/etag/LICENSE
+++ /dev/null
@@ -1,22 +0,0 @@
-(The MIT License)
-
-Copyright (c) 2014 Douglas Christopher Wilson
-
-Permission is hereby granted, free of charge, to any person obtaining
-a copy of this software and associated documentation files (the
-'Software'), to deal in the Software without restriction, including
-without limitation the rights to use, copy, modify, merge, publish,
-distribute, sublicense, and/or sell copies of the Software, and to
-permit persons to whom the Software is furnished to do so, subject to
-the following conditions:
-
-The above copyright notice and this permission notice shall be
-included in all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
-EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
-IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
-CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
-TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
-SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
diff --git a/CoAuthoring/node_modules/express/node_modules/etag/README.md b/CoAuthoring/node_modules/express/node_modules/etag/README.md
deleted file mode 100644
index d770f4900a..0000000000
--- a/CoAuthoring/node_modules/express/node_modules/etag/README.md
+++ /dev/null
@@ -1,141 +0,0 @@
-# etag
-
-[![NPM Version][npm-image]][npm-url]
-[![NPM Downloads][downloads-image]][downloads-url]
-[![Node.js Version][node-version-image]][node-version-url]
-[![Build Status][travis-image]][travis-url]
-[![Test Coverage][coveralls-image]][coveralls-url]
-
-Create simple ETags
-
-## Installation
-
-```sh
-$ npm install etag
-```
-
-## API
-
-```js
-var etag = require('etag')
-```
-
-### etag(entity, [options])
-
-Generate a strong ETag for the given entity. This should be the complete
-body of the entity. Strings, `Buffer`s, and `fs.Stats` are accepted. By
-default, a strong ETag is generated except for `fs.Stats`, which will
-generate a weak ETag (this can be overwritten by `options.weak`).
-
-```js
-res.setHeader('ETag', etag(body))
-```
-
-#### Options
-
-`etag` accepts these properties in the options object.
-
-##### weak
-
-Specifies if a "strong" or a "weak" ETag will be generated. The ETag can only
-really be a strong as the given input.
-
-## Testing
-
-```sh
-$ npm test
-```
-
-## Benchmark
-
-```bash
-$ npm run-script bench
-
-> etag@1.2.0 bench nodejs-etag
-> node benchmark/index.js
-
-> node benchmark/body0-100b.js
-
- 100B body
-
- 1 test completed.
- 2 tests completed.
- 3 tests completed.
- 4 tests completed.
-
- buffer - strong x 518,895 ops/sec ±1.71% (185 runs sampled)
-* buffer - weak x 1,917,975 ops/sec ±0.34% (195 runs sampled)
- string - strong x 245,251 ops/sec ±0.90% (190 runs sampled)
- string - weak x 442,232 ops/sec ±0.21% (196 runs sampled)
-
-> node benchmark/body1-1kb.js
-
- 1KB body
-
- 1 test completed.
- 2 tests completed.
- 3 tests completed.
- 4 tests completed.
-
- buffer - strong x 309,748 ops/sec ±0.99% (191 runs sampled)
-* buffer - weak x 352,402 ops/sec ±0.20% (198 runs sampled)
- string - strong x 159,058 ops/sec ±1.83% (191 runs sampled)
- string - weak x 184,052 ops/sec ±1.30% (189 runs sampled)
-
-> node benchmark/body2-5kb.js
-
- 5KB body
-
- 1 test completed.
- 2 tests completed.
- 3 tests completed.
- 4 tests completed.
-
-* buffer - strong x 110,157 ops/sec ±0.60% (194 runs sampled)
-* buffer - weak x 111,333 ops/sec ±0.67% (194 runs sampled)
- string - strong x 62,091 ops/sec ±3.92% (186 runs sampled)
- string - weak x 60,681 ops/sec ±3.98% (186 runs sampled)
-
-> node benchmark/body3-10kb.js
-
- 10KB body
-
- 1 test completed.
- 2 tests completed.
- 3 tests completed.
- 4 tests completed.
-
-* buffer - strong x 61,843 ops/sec ±0.44% (197 runs sampled)
-* buffer - weak x 61,687 ops/sec ±0.52% (197 runs sampled)
- string - strong x 41,377 ops/sec ±3.33% (189 runs sampled)
- string - weak x 41,368 ops/sec ±3.29% (190 runs sampled)
-
-> node benchmark/body4-100kb.js
-
- 100KB body
-
- 1 test completed.
- 2 tests completed.
- 3 tests completed.
- 4 tests completed.
-
-* buffer - strong x 6,874 ops/sec ±0.17% (198 runs sampled)
-* buffer - weak x 6,880 ops/sec ±0.15% (198 runs sampled)
- string - strong x 5,382 ops/sec ±2.17% (192 runs sampled)
- string - weak x 5,361 ops/sec ±2.23% (192 runs sampled)
-```
-
-## License
-
-[MIT](LICENSE)
-
-[npm-image]: https://img.shields.io/npm/v/etag.svg?style=flat
-[npm-url]: https://npmjs.org/package/etag
-[node-version-image]: https://img.shields.io/node/v/etag.svg?style=flat
-[node-version-url]: http://nodejs.org/download/
-[travis-image]: https://img.shields.io/travis/jshttp/etag.svg?style=flat
-[travis-url]: https://travis-ci.org/jshttp/etag
-[coveralls-image]: https://img.shields.io/coveralls/jshttp/etag.svg?style=flat
-[coveralls-url]: https://coveralls.io/r/jshttp/etag?branch=master
-[downloads-image]: https://img.shields.io/npm/dm/etag.svg?style=flat
-[downloads-url]: https://npmjs.org/package/etag
diff --git a/CoAuthoring/node_modules/express/node_modules/etag/index.js b/CoAuthoring/node_modules/express/node_modules/etag/index.js
deleted file mode 100644
index 3366af8dbc..0000000000
--- a/CoAuthoring/node_modules/express/node_modules/etag/index.js
+++ /dev/null
@@ -1,161 +0,0 @@
-/*!
- * etag
- * Copyright(c) 2014 Douglas Christopher Wilson
- * MIT Licensed
- */
-
-/**
- * Module exports.
- */
-
-module.exports = etag
-
-/**
- * Module dependencies.
- */
-
-var crc = require('crc').crc32
-var crypto = require('crypto')
-var Stats = require('fs').Stats
-
-/**
- * Module variables.
- */
-
-var crc32threshold = 1000 // 1KB
-var NULL = new Buffer([0])
-var toString = Object.prototype.toString
-
-/**
- * Create a simple ETag.
- *
- * @param {string|Buffer|Stats} entity
- * @param {object} [options]
- * @param {boolean} [options.weak]
- * @return {String}
- * @api public
- */
-
-function etag(entity, options) {
- if (entity == null) {
- throw new TypeError('argument entity is required')
- }
-
- var isBuffer = Buffer.isBuffer(entity)
- var isStats = isstats(entity)
- var weak = options && typeof options.weak === 'boolean'
- ? options.weak
- : isStats
-
- // support fs.Stats object
- if (isStats) {
- return stattag(entity, weak)
- }
-
- if (!isBuffer && typeof entity !== 'string') {
- throw new TypeError('argument entity must be string, Buffer, or fs.Stats')
- }
-
- var buf = !isBuffer
- ? new Buffer(entity, 'utf8')
- : entity
- var hash = weak && buf.length <= crc32threshold
- ? weakhash(buf)
- : stronghash(buf)
-
- return weak
- ? 'W/"' + hash + '"'
- : '"' + hash + '"'
-}
-
-/**
- * Determine if object is a Stats object.
- *
- * @param {object} obj
- * @return {boolean}
- * @api private
- */
-
-function isstats(obj) {
- // not even an object
- if (obj === null || typeof obj !== 'object') {
- return false
- }
-
- // genuine fs.Stats
- if (obj instanceof Stats) {
- return true
- }
-
- // quack quack
- return 'atime' in obj && toString.call(obj.atime) === '[object Date]'
- && 'ctime' in obj && toString.call(obj.ctime) === '[object Date]'
- && 'mtime' in obj && toString.call(obj.mtime) === '[object Date]'
- && 'ino' in obj && typeof obj.ino === 'number'
- && 'size' in obj && typeof obj.size === 'number'
-}
-
-/**
- * Generate a tag for a stat.
- *
- * @param {Buffer} entity
- * @return {String}
- * @api private
- */
-
-function stattag(stat, weak) {
- var mtime = stat.mtime.toISOString()
- var size = stat.size.toString(16)
-
- if (weak) {
- return 'W/"' + size + '-' + crc(mtime) + '"'
- }
-
- var hash = crypto
- .createHash('md5')
- .update('file', 'utf8')
- .update(NULL)
- .update(size, 'utf8')
- .update(NULL)
- .update(mtime, 'utf8')
- .digest('base64')
-
- return '"' + hash + '"'
-}
-
-/**
- * Generate a strong hash.
- *
- * @param {Buffer} entity
- * @return {String}
- * @api private
- */
-
-function stronghash(buf) {
- if (buf.length === 0) {
- // fast-path empty
- return '1B2M2Y8AsgTpgAmY7PhCfg=='
- }
-
- return crypto
- .createHash('md5')
- .update(buf)
- .digest('base64')
-}
-
-/**
- * Generate a weak hash.
- *
- * @param {Buffer} entity
- * @return {String}
- * @api private
- */
-
-function weakhash(buf) {
- if (buf.length === 0) {
- // fast-path empty
- return '0-0'
- }
-
- return buf.length.toString(16) + '-' + crc(buf).toString(16)
-}
diff --git a/CoAuthoring/node_modules/express/node_modules/etag/node_modules/crc/.npmignore b/CoAuthoring/node_modules/express/node_modules/etag/node_modules/crc/.npmignore
deleted file mode 100644
index b84a00558a..0000000000
--- a/CoAuthoring/node_modules/express/node_modules/etag/node_modules/crc/.npmignore
+++ /dev/null
@@ -1,4 +0,0 @@
-benchmark
-src
-test
-.travis.yml
diff --git a/CoAuthoring/node_modules/express/node_modules/etag/node_modules/crc/LICENSE b/CoAuthoring/node_modules/express/node_modules/etag/node_modules/crc/LICENSE
deleted file mode 100644
index c49097c577..0000000000
--- a/CoAuthoring/node_modules/express/node_modules/etag/node_modules/crc/LICENSE
+++ /dev/null
@@ -1,22 +0,0 @@
-The MIT License (MIT)
-
-Copyright 2014 Alex Gorbatchev
-
-Permission is hereby granted, free of charge, to any person obtaining
-a copy of this software and associated documentation files (the
-"Software"), to deal in the Software without restriction, including
-without limitation the rights to use, copy, modify, merge, publish,
-distribute, sublicense, and/or sell copies of the Software, and to
-permit persons to whom the Software is furnished to do so, subject to
-the following conditions:
-
-The above copyright notice and this permission notice shall be
-included in all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
-LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
-OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
-WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
diff --git a/CoAuthoring/node_modules/express/node_modules/etag/node_modules/crc/README.md b/CoAuthoring/node_modules/express/node_modules/etag/node_modules/crc/README.md
deleted file mode 100644
index 3fdef99974..0000000000
--- a/CoAuthoring/node_modules/express/node_modules/etag/node_modules/crc/README.md
+++ /dev/null
@@ -1,89 +0,0 @@
-# crc
-
-[](https://www.gittip.com/alexgorbatchev/)
-[](https://david-dm.org/alexgorbatchev/node-crc)
-[](https://david-dm.org/alexgorbatchev/node-crc#info=devDependencies)
-[](https://travis-ci.org/alexgorbatchev/node-crc)
-
-[](https://npmjs.org/package/node-crc)
-
-Module for calculating Cyclic Redundancy Check (CRC).
-
-## Features
-
-* Version 3 is 3-4 times faster than version 2.
-* Pure JavaScript implementation, no dependencies.
-* Provides CRC Tables for optimized calculations.
-* Provides support for the following CRC algorithms:
- * CRC1 `crc.crc1(…)`
- * CRC8 `crc.crc8(…)`
- * CRC8 1-Wire `crc.crc81wire(…)`
- * CRC16 `crc.crc16(…)`
- * CRC16 CCITT `crc.crc16ccitt(…)`
- * CRC16 Modbus `crc.crc16modbus(…)`
- * CRC24 `crc.crc24(…)`
- * CRC32 `crc.crc32(…)`
-
-## Installation
-
- npm install crc
-
-## Running tests
-
- $ npm install
- $ npm test
-
-## Usage Example
-
-Calculate a CRC32:
-
- var crc = require('crc');
-
- crc.crc32('hello').toString(16);
- # => "3610a686"
-
-Calculate a CRC32 of a file:
-
- crc.crc32(fs.readFileSync('README.md', 'utf8')).toString(16);
- # => "127ad531"
-
-Or using a `Buffer`:
-
- crc.crc32(fs.readFileSync('README.md')).toString(16);
- # => "127ad531"
-
-Incrementally calculate a CRC32:
-
- value = crc32('one');
- value = crc32('two', value);
- value = crc32('three', value);
- value.toString(16);
- # => "09e1c092"
-
-## Thanks!
-
-[pycrc](http://www.tty1.net/pycrc/) library is which the source of all of the CRC tables.
-
-# License
-
-The MIT License (MIT)
-
-Copyright (c) 2014 Alex Gorbatchev
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in
-all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-THE SOFTWARE.
diff --git a/CoAuthoring/node_modules/express/node_modules/etag/node_modules/crc/lib/crc.js b/CoAuthoring/node_modules/express/node_modules/etag/node_modules/crc/lib/crc.js
deleted file mode 100644
index 1c342b7e12..0000000000
--- a/CoAuthoring/node_modules/express/node_modules/etag/node_modules/crc/lib/crc.js
+++ /dev/null
@@ -1,71 +0,0 @@
-// Generated by CoffeeScript 1.7.1
-var CRC, hex;
-
-hex = require('./hex');
-
-module.exports = CRC = (function() {
- CRC.prototype.INIT_CRC = 0x00;
-
- CRC.prototype.XOR_MASK = 0x00;
-
- CRC.prototype.WIDTH = 0;
-
- CRC.prototype.pack = function(crc) {
- return '';
- };
-
- CRC.prototype.each_byte = function(buf, cb) {
- var i, _i, _ref, _results;
- if (!Buffer.isBuffer(buf)) {
- buf = Buffer(buf);
- }
- _results = [];
- for (i = _i = 0, _ref = buf.length - 1; 0 <= _ref ? _i <= _ref : _i >= _ref; i = 0 <= _ref ? ++_i : --_i) {
- _results.push(cb(buf[i]));
- }
- return _results;
- };
-
- function CRC() {
- this.crc = this.INIT_CRC;
- }
-
- CRC.prototype.digest_length = function() {
- return Math.ceil(this.WIDTH / 8.0);
- };
-
- CRC.prototype.update = function(data) {};
-
- CRC.prototype.reset = function() {
- return this.crc = this.INIT_CRC;
- };
-
- CRC.prototype.checksum = function(signed) {
- var sum;
- if (signed == null) {
- signed = true;
- }
- sum = this.crc ^ this.XOR_MASK;
- if (signed) {
- sum = sum >>> 0;
- }
- return sum;
- };
-
- CRC.prototype.finish = function() {
- return this.pack(this.checksum());
- };
-
- CRC.prototype.hexdigest = function(value) {
- var result;
- if (value != null) {
- this.update(value);
- }
- result = this.finish();
- this.reset();
- return result;
- };
-
- return CRC;
-
-})();
diff --git a/CoAuthoring/node_modules/express/node_modules/etag/node_modules/crc/lib/crc1.js b/CoAuthoring/node_modules/express/node_modules/etag/node_modules/crc/lib/crc1.js
deleted file mode 100644
index 3cb4fa9919..0000000000
--- a/CoAuthoring/node_modules/express/node_modules/etag/node_modules/crc/lib/crc1.js
+++ /dev/null
@@ -1,21 +0,0 @@
-// Generated by CoffeeScript 1.7.1
-var Buffer, create;
-
-Buffer = require('buffer').Buffer;
-
-create = require('./create');
-
-module.exports = create(function(buf, previous) {
- var accum, byte, crc, _i, _len;
- if (!Buffer.isBuffer(buf)) {
- buf = Buffer(buf);
- }
- crc = ~~previous;
- accum = 0;
- for (_i = 0, _len = buf.length; _i < _len; _i++) {
- byte = buf[_i];
- accum += byte;
- }
- crc += accum % 256;
- return crc % 256;
-});
diff --git a/CoAuthoring/node_modules/express/node_modules/etag/node_modules/crc/lib/crc16.js b/CoAuthoring/node_modules/express/node_modules/etag/node_modules/crc/lib/crc16.js
deleted file mode 100644
index f19faa8b21..0000000000
--- a/CoAuthoring/node_modules/express/node_modules/etag/node_modules/crc/lib/crc16.js
+++ /dev/null
@@ -1,25 +0,0 @@
-// Generated by CoffeeScript 1.7.1
-var Buffer, TABLE, create;
-
-Buffer = require('buffer').Buffer;
-
-create = require('./create');
-
-TABLE = [0x0000, 0xc0c1, 0xc181, 0x0140, 0xc301, 0x03c0, 0x0280, 0xc241, 0xc601, 0x06c0, 0x0780, 0xc741, 0x0500, 0xc5c1, 0xc481, 0x0440, 0xcc01, 0x0cc0, 0x0d80, 0xcd41, 0x0f00, 0xcfc1, 0xce81, 0x0e40, 0x0a00, 0xcac1, 0xcb81, 0x0b40, 0xc901, 0x09c0, 0x0880, 0xc841, 0xd801, 0x18c0, 0x1980, 0xd941, 0x1b00, 0xdbc1, 0xda81, 0x1a40, 0x1e00, 0xdec1, 0xdf81, 0x1f40, 0xdd01, 0x1dc0, 0x1c80, 0xdc41, 0x1400, 0xd4c1, 0xd581, 0x1540, 0xd701, 0x17c0, 0x1680, 0xd641, 0xd201, 0x12c0, 0x1380, 0xd341, 0x1100, 0xd1c1, 0xd081, 0x1040, 0xf001, 0x30c0, 0x3180, 0xf141, 0x3300, 0xf3c1, 0xf281, 0x3240, 0x3600, 0xf6c1, 0xf781, 0x3740, 0xf501, 0x35c0, 0x3480, 0xf441, 0x3c00, 0xfcc1, 0xfd81, 0x3d40, 0xff01, 0x3fc0, 0x3e80, 0xfe41, 0xfa01, 0x3ac0, 0x3b80, 0xfb41, 0x3900, 0xf9c1, 0xf881, 0x3840, 0x2800, 0xe8c1, 0xe981, 0x2940, 0xeb01, 0x2bc0, 0x2a80, 0xea41, 0xee01, 0x2ec0, 0x2f80, 0xef41, 0x2d00, 0xedc1, 0xec81, 0x2c40, 0xe401, 0x24c0, 0x2580, 0xe541, 0x2700, 0xe7c1, 0xe681, 0x2640, 0x2200, 0xe2c1, 0xe381, 0x2340, 0xe101, 0x21c0, 0x2080, 0xe041, 0xa001, 0x60c0, 0x6180, 0xa141, 0x6300, 0xa3c1, 0xa281, 0x6240, 0x6600, 0xa6c1, 0xa781, 0x6740, 0xa501, 0x65c0, 0x6480, 0xa441, 0x6c00, 0xacc1, 0xad81, 0x6d40, 0xaf01, 0x6fc0, 0x6e80, 0xae41, 0xaa01, 0x6ac0, 0x6b80, 0xab41, 0x6900, 0xa9c1, 0xa881, 0x6840, 0x7800, 0xb8c1, 0xb981, 0x7940, 0xbb01, 0x7bc0, 0x7a80, 0xba41, 0xbe01, 0x7ec0, 0x7f80, 0xbf41, 0x7d00, 0xbdc1, 0xbc81, 0x7c40, 0xb401, 0x74c0, 0x7580, 0xb541, 0x7700, 0xb7c1, 0xb681, 0x7640, 0x7200, 0xb2c1, 0xb381, 0x7340, 0xb101, 0x71c0, 0x7080, 0xb041, 0x5000, 0x90c1, 0x9181, 0x5140, 0x9301, 0x53c0, 0x5280, 0x9241, 0x9601, 0x56c0, 0x5780, 0x9741, 0x5500, 0x95c1, 0x9481, 0x5440, 0x9c01, 0x5cc0, 0x5d80, 0x9d41, 0x5f00, 0x9fc1, 0x9e81, 0x5e40, 0x5a00, 0x9ac1, 0x9b81, 0x5b40, 0x9901, 0x59c0, 0x5880, 0x9841, 0x8801, 0x48c0, 0x4980, 0x8941, 0x4b00, 0x8bc1, 0x8a81, 0x4a40, 0x4e00, 0x8ec1, 0x8f81, 0x4f40, 0x8d01, 0x4dc0, 0x4c80, 0x8c41, 0x4400, 0x84c1, 0x8581, 0x4540, 0x8701, 0x47c0, 0x4680, 0x8641, 0x8201, 0x42c0, 0x4380, 0x8341, 0x4100, 0x81c1, 0x8081, 0x4040];
-
-if (typeof Int32Array !== 'undefined') {
- TABLE = new Int32Array(TABLE);
-}
-
-module.exports = create(function(buf, previous) {
- var byte, crc, _i, _len;
- if (!Buffer.isBuffer(buf)) {
- buf = Buffer(buf);
- }
- crc = ~~previous;
- for (_i = 0, _len = buf.length; _i < _len; _i++) {
- byte = buf[_i];
- crc = (TABLE[(crc ^ byte) & 0xff] ^ (crc >> 8)) & 0xffff;
- }
- return crc;
-});
diff --git a/CoAuthoring/node_modules/express/node_modules/etag/node_modules/crc/lib/crc16_ccitt.js b/CoAuthoring/node_modules/express/node_modules/etag/node_modules/crc/lib/crc16_ccitt.js
deleted file mode 100644
index 5331638e0c..0000000000
--- a/CoAuthoring/node_modules/express/node_modules/etag/node_modules/crc/lib/crc16_ccitt.js
+++ /dev/null
@@ -1,25 +0,0 @@
-// Generated by CoffeeScript 1.7.1
-var Buffer, TABLE, create;
-
-Buffer = require('buffer').Buffer;
-
-create = require('./create');
-
-TABLE = [0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50a5, 0x60c6, 0x70e7, 0x8108, 0x9129, 0xa14a, 0xb16b, 0xc18c, 0xd1ad, 0xe1ce, 0xf1ef, 0x1231, 0x0210, 0x3273, 0x2252, 0x52b5, 0x4294, 0x72f7, 0x62d6, 0x9339, 0x8318, 0xb37b, 0xa35a, 0xd3bd, 0xc39c, 0xf3ff, 0xe3de, 0x2462, 0x3443, 0x0420, 0x1401, 0x64e6, 0x74c7, 0x44a4, 0x5485, 0xa56a, 0xb54b, 0x8528, 0x9509, 0xe5ee, 0xf5cf, 0xc5ac, 0xd58d, 0x3653, 0x2672, 0x1611, 0x0630, 0x76d7, 0x66f6, 0x5695, 0x46b4, 0xb75b, 0xa77a, 0x9719, 0x8738, 0xf7df, 0xe7fe, 0xd79d, 0xc7bc, 0x48c4, 0x58e5, 0x6886, 0x78a7, 0x0840, 0x1861, 0x2802, 0x3823, 0xc9cc, 0xd9ed, 0xe98e, 0xf9af, 0x8948, 0x9969, 0xa90a, 0xb92b, 0x5af5, 0x4ad4, 0x7ab7, 0x6a96, 0x1a71, 0x0a50, 0x3a33, 0x2a12, 0xdbfd, 0xcbdc, 0xfbbf, 0xeb9e, 0x9b79, 0x8b58, 0xbb3b, 0xab1a, 0x6ca6, 0x7c87, 0x4ce4, 0x5cc5, 0x2c22, 0x3c03, 0x0c60, 0x1c41, 0xedae, 0xfd8f, 0xcdec, 0xddcd, 0xad2a, 0xbd0b, 0x8d68, 0x9d49, 0x7e97, 0x6eb6, 0x5ed5, 0x4ef4, 0x3e13, 0x2e32, 0x1e51, 0x0e70, 0xff9f, 0xefbe, 0xdfdd, 0xcffc, 0xbf1b, 0xaf3a, 0x9f59, 0x8f78, 0x9188, 0x81a9, 0xb1ca, 0xa1eb, 0xd10c, 0xc12d, 0xf14e, 0xe16f, 0x1080, 0x00a1, 0x30c2, 0x20e3, 0x5004, 0x4025, 0x7046, 0x6067, 0x83b9, 0x9398, 0xa3fb, 0xb3da, 0xc33d, 0xd31c, 0xe37f, 0xf35e, 0x02b1, 0x1290, 0x22f3, 0x32d2, 0x4235, 0x5214, 0x6277, 0x7256, 0xb5ea, 0xa5cb, 0x95a8, 0x8589, 0xf56e, 0xe54f, 0xd52c, 0xc50d, 0x34e2, 0x24c3, 0x14a0, 0x0481, 0x7466, 0x6447, 0x5424, 0x4405, 0xa7db, 0xb7fa, 0x8799, 0x97b8, 0xe75f, 0xf77e, 0xc71d, 0xd73c, 0x26d3, 0x36f2, 0x0691, 0x16b0, 0x6657, 0x7676, 0x4615, 0x5634, 0xd94c, 0xc96d, 0xf90e, 0xe92f, 0x99c8, 0x89e9, 0xb98a, 0xa9ab, 0x5844, 0x4865, 0x7806, 0x6827, 0x18c0, 0x08e1, 0x3882, 0x28a3, 0xcb7d, 0xdb5c, 0xeb3f, 0xfb1e, 0x8bf9, 0x9bd8, 0xabbb, 0xbb9a, 0x4a75, 0x5a54, 0x6a37, 0x7a16, 0x0af1, 0x1ad0, 0x2ab3, 0x3a92, 0xfd2e, 0xed0f, 0xdd6c, 0xcd4d, 0xbdaa, 0xad8b, 0x9de8, 0x8dc9, 0x7c26, 0x6c07, 0x5c64, 0x4c45, 0x3ca2, 0x2c83, 0x1ce0, 0x0cc1, 0xef1f, 0xff3e, 0xcf5d, 0xdf7c, 0xaf9b, 0xbfba, 0x8fd9, 0x9ff8, 0x6e17, 0x7e36, 0x4e55, 0x5e74, 0x2e93, 0x3eb2, 0x0ed1, 0x1ef0];
-
-if (typeof Int32Array !== 'undefined') {
- TABLE = new Int32Array(TABLE);
-}
-
-module.exports = create(function(buf, previous) {
- var byte, crc, _i, _len;
- if (!Buffer.isBuffer(buf)) {
- buf = Buffer(buf);
- }
- crc = ~~previous || 0xffff;
- for (_i = 0, _len = buf.length; _i < _len; _i++) {
- byte = buf[_i];
- crc = (TABLE[((crc >> 8) ^ byte) & 0xff] ^ (crc << 8)) & 0xffff;
- }
- return crc;
-});
diff --git a/CoAuthoring/node_modules/express/node_modules/etag/node_modules/crc/lib/crc16_modbus.js b/CoAuthoring/node_modules/express/node_modules/etag/node_modules/crc/lib/crc16_modbus.js
deleted file mode 100644
index dcbd41b53b..0000000000
--- a/CoAuthoring/node_modules/express/node_modules/etag/node_modules/crc/lib/crc16_modbus.js
+++ /dev/null
@@ -1,25 +0,0 @@
-// Generated by CoffeeScript 1.7.1
-var Buffer, TABLE, create;
-
-Buffer = require('buffer').Buffer;
-
-create = require('./create');
-
-TABLE = [0x0000, 0xc0c1, 0xc181, 0x0140, 0xc301, 0x03c0, 0x0280, 0xc241, 0xc601, 0x06c0, 0x0780, 0xc741, 0x0500, 0xc5c1, 0xc481, 0x0440, 0xcc01, 0x0cc0, 0x0d80, 0xcd41, 0x0f00, 0xcfc1, 0xce81, 0x0e40, 0x0a00, 0xcac1, 0xcb81, 0x0b40, 0xc901, 0x09c0, 0x0880, 0xc841, 0xd801, 0x18c0, 0x1980, 0xd941, 0x1b00, 0xdbc1, 0xda81, 0x1a40, 0x1e00, 0xdec1, 0xdf81, 0x1f40, 0xdd01, 0x1dc0, 0x1c80, 0xdc41, 0x1400, 0xd4c1, 0xd581, 0x1540, 0xd701, 0x17c0, 0x1680, 0xd641, 0xd201, 0x12c0, 0x1380, 0xd341, 0x1100, 0xd1c1, 0xd081, 0x1040, 0xf001, 0x30c0, 0x3180, 0xf141, 0x3300, 0xf3c1, 0xf281, 0x3240, 0x3600, 0xf6c1, 0xf781, 0x3740, 0xf501, 0x35c0, 0x3480, 0xf441, 0x3c00, 0xfcc1, 0xfd81, 0x3d40, 0xff01, 0x3fc0, 0x3e80, 0xfe41, 0xfa01, 0x3ac0, 0x3b80, 0xfb41, 0x3900, 0xf9c1, 0xf881, 0x3840, 0x2800, 0xe8c1, 0xe981, 0x2940, 0xeb01, 0x2bc0, 0x2a80, 0xea41, 0xee01, 0x2ec0, 0x2f80, 0xef41, 0x2d00, 0xedc1, 0xec81, 0x2c40, 0xe401, 0x24c0, 0x2580, 0xe541, 0x2700, 0xe7c1, 0xe681, 0x2640, 0x2200, 0xe2c1, 0xe381, 0x2340, 0xe101, 0x21c0, 0x2080, 0xe041, 0xa001, 0x60c0, 0x6180, 0xa141, 0x6300, 0xa3c1, 0xa281, 0x6240, 0x6600, 0xa6c1, 0xa781, 0x6740, 0xa501, 0x65c0, 0x6480, 0xa441, 0x6c00, 0xacc1, 0xad81, 0x6d40, 0xaf01, 0x6fc0, 0x6e80, 0xae41, 0xaa01, 0x6ac0, 0x6b80, 0xab41, 0x6900, 0xa9c1, 0xa881, 0x6840, 0x7800, 0xb8c1, 0xb981, 0x7940, 0xbb01, 0x7bc0, 0x7a80, 0xba41, 0xbe01, 0x7ec0, 0x7f80, 0xbf41, 0x7d00, 0xbdc1, 0xbc81, 0x7c40, 0xb401, 0x74c0, 0x7580, 0xb541, 0x7700, 0xb7c1, 0xb681, 0x7640, 0x7200, 0xb2c1, 0xb381, 0x7340, 0xb101, 0x71c0, 0x7080, 0xb041, 0x5000, 0x90c1, 0x9181, 0x5140, 0x9301, 0x53c0, 0x5280, 0x9241, 0x9601, 0x56c0, 0x5780, 0x9741, 0x5500, 0x95c1, 0x9481, 0x5440, 0x9c01, 0x5cc0, 0x5d80, 0x9d41, 0x5f00, 0x9fc1, 0x9e81, 0x5e40, 0x5a00, 0x9ac1, 0x9b81, 0x5b40, 0x9901, 0x59c0, 0x5880, 0x9841, 0x8801, 0x48c0, 0x4980, 0x8941, 0x4b00, 0x8bc1, 0x8a81, 0x4a40, 0x4e00, 0x8ec1, 0x8f81, 0x4f40, 0x8d01, 0x4dc0, 0x4c80, 0x8c41, 0x4400, 0x84c1, 0x8581, 0x4540, 0x8701, 0x47c0, 0x4680, 0x8641, 0x8201, 0x42c0, 0x4380, 0x8341, 0x4100, 0x81c1, 0x8081, 0x4040];
-
-if (typeof Int32Array !== 'undefined') {
- TABLE = new Int32Array(TABLE);
-}
-
-module.exports = create(function(buf, previous) {
- var byte, crc, _i, _len;
- if (!Buffer.isBuffer(buf)) {
- buf = Buffer(buf);
- }
- crc = ~~previous || 0xffff;
- for (_i = 0, _len = buf.length; _i < _len; _i++) {
- byte = buf[_i];
- crc = (TABLE[(crc ^ byte) & 0xff] ^ (crc >> 8)) & 0xffff;
- }
- return crc;
-});
diff --git a/CoAuthoring/node_modules/express/node_modules/etag/node_modules/crc/lib/crc24.js b/CoAuthoring/node_modules/express/node_modules/etag/node_modules/crc/lib/crc24.js
deleted file mode 100644
index 413d1590aa..0000000000
--- a/CoAuthoring/node_modules/express/node_modules/etag/node_modules/crc/lib/crc24.js
+++ /dev/null
@@ -1,25 +0,0 @@
-// Generated by CoffeeScript 1.7.1
-var Buffer, TABLE, create;
-
-Buffer = require('buffer').Buffer;
-
-create = require('./create');
-
-TABLE = [0x000000, 0x864cfb, 0x8ad50d, 0x0c99f6, 0x93e6e1, 0x15aa1a, 0x1933ec, 0x9f7f17, 0xa18139, 0x27cdc2, 0x2b5434, 0xad18cf, 0x3267d8, 0xb42b23, 0xb8b2d5, 0x3efe2e, 0xc54e89, 0x430272, 0x4f9b84, 0xc9d77f, 0x56a868, 0xd0e493, 0xdc7d65, 0x5a319e, 0x64cfb0, 0xe2834b, 0xee1abd, 0x685646, 0xf72951, 0x7165aa, 0x7dfc5c, 0xfbb0a7, 0x0cd1e9, 0x8a9d12, 0x8604e4, 0x00481f, 0x9f3708, 0x197bf3, 0x15e205, 0x93aefe, 0xad50d0, 0x2b1c2b, 0x2785dd, 0xa1c926, 0x3eb631, 0xb8faca, 0xb4633c, 0x322fc7, 0xc99f60, 0x4fd39b, 0x434a6d, 0xc50696, 0x5a7981, 0xdc357a, 0xd0ac8c, 0x56e077, 0x681e59, 0xee52a2, 0xe2cb54, 0x6487af, 0xfbf8b8, 0x7db443, 0x712db5, 0xf7614e, 0x19a3d2, 0x9fef29, 0x9376df, 0x153a24, 0x8a4533, 0x0c09c8, 0x00903e, 0x86dcc5, 0xb822eb, 0x3e6e10, 0x32f7e6, 0xb4bb1d, 0x2bc40a, 0xad88f1, 0xa11107, 0x275dfc, 0xdced5b, 0x5aa1a0, 0x563856, 0xd074ad, 0x4f0bba, 0xc94741, 0xc5deb7, 0x43924c, 0x7d6c62, 0xfb2099, 0xf7b96f, 0x71f594, 0xee8a83, 0x68c678, 0x645f8e, 0xe21375, 0x15723b, 0x933ec0, 0x9fa736, 0x19ebcd, 0x8694da, 0x00d821, 0x0c41d7, 0x8a0d2c, 0xb4f302, 0x32bff9, 0x3e260f, 0xb86af4, 0x2715e3, 0xa15918, 0xadc0ee, 0x2b8c15, 0xd03cb2, 0x567049, 0x5ae9bf, 0xdca544, 0x43da53, 0xc596a8, 0xc90f5e, 0x4f43a5, 0x71bd8b, 0xf7f170, 0xfb6886, 0x7d247d, 0xe25b6a, 0x641791, 0x688e67, 0xeec29c, 0x3347a4, 0xb50b5f, 0xb992a9, 0x3fde52, 0xa0a145, 0x26edbe, 0x2a7448, 0xac38b3, 0x92c69d, 0x148a66, 0x181390, 0x9e5f6b, 0x01207c, 0x876c87, 0x8bf571, 0x0db98a, 0xf6092d, 0x7045d6, 0x7cdc20, 0xfa90db, 0x65efcc, 0xe3a337, 0xef3ac1, 0x69763a, 0x578814, 0xd1c4ef, 0xdd5d19, 0x5b11e2, 0xc46ef5, 0x42220e, 0x4ebbf8, 0xc8f703, 0x3f964d, 0xb9dab6, 0xb54340, 0x330fbb, 0xac70ac, 0x2a3c57, 0x26a5a1, 0xa0e95a, 0x9e1774, 0x185b8f, 0x14c279, 0x928e82, 0x0df195, 0x8bbd6e, 0x872498, 0x016863, 0xfad8c4, 0x7c943f, 0x700dc9, 0xf64132, 0x693e25, 0xef72de, 0xe3eb28, 0x65a7d3, 0x5b59fd, 0xdd1506, 0xd18cf0, 0x57c00b, 0xc8bf1c, 0x4ef3e7, 0x426a11, 0xc426ea, 0x2ae476, 0xaca88d, 0xa0317b, 0x267d80, 0xb90297, 0x3f4e6c, 0x33d79a, 0xb59b61, 0x8b654f, 0x0d29b4, 0x01b042, 0x87fcb9, 0x1883ae, 0x9ecf55, 0x9256a3, 0x141a58, 0xefaaff, 0x69e604, 0x657ff2, 0xe33309, 0x7c4c1e, 0xfa00e5, 0xf69913, 0x70d5e8, 0x4e2bc6, 0xc8673d, 0xc4fecb, 0x42b230, 0xddcd27, 0x5b81dc, 0x57182a, 0xd154d1, 0x26359f, 0xa07964, 0xace092, 0x2aac69, 0xb5d37e, 0x339f85, 0x3f0673, 0xb94a88, 0x87b4a6, 0x01f85d, 0x0d61ab, 0x8b2d50, 0x145247, 0x921ebc, 0x9e874a, 0x18cbb1, 0xe37b16, 0x6537ed, 0x69ae1b, 0xefe2e0, 0x709df7, 0xf6d10c, 0xfa48fa, 0x7c0401, 0x42fa2f, 0xc4b6d4, 0xc82f22, 0x4e63d9, 0xd11cce, 0x575035, 0x5bc9c3, 0xdd8538];
-
-if (typeof Int32Array !== 'undefined') {
- TABLE = new Int32Array(TABLE);
-}
-
-module.exports = create(function(buf, previous) {
- var byte, crc, _i, _len;
- if (!Buffer.isBuffer(buf)) {
- buf = Buffer(buf);
- }
- crc = ~~previous || 0xb704ce;
- for (_i = 0, _len = buf.length; _i < _len; _i++) {
- byte = buf[_i];
- crc = (TABLE[((crc >> 16) ^ byte) & 0xff] ^ (crc << 8)) & 0xffffff;
- }
- return crc;
-});
diff --git a/CoAuthoring/node_modules/express/node_modules/etag/node_modules/crc/lib/crc32.js b/CoAuthoring/node_modules/express/node_modules/etag/node_modules/crc/lib/crc32.js
deleted file mode 100644
index eb2c85e472..0000000000
--- a/CoAuthoring/node_modules/express/node_modules/etag/node_modules/crc/lib/crc32.js
+++ /dev/null
@@ -1,25 +0,0 @@
-// Generated by CoffeeScript 1.7.1
-var Buffer, TABLE, create;
-
-Buffer = require('buffer').Buffer;
-
-create = require('./create');
-
-TABLE = [0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f, 0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988, 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91, 0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de, 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7, 0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9, 0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172, 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, 0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59, 0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423, 0xcfba9599, 0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924, 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190, 0x01db7106, 0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433, 0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01, 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e, 0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950, 0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65, 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, 0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0, 0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa, 0xbe0b1010, 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f, 0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, 0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a, 0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683, 0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8, 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1, 0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb, 0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc, 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, 0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b, 0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55, 0x316e8eef, 0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236, 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe, 0xb2bd0b28, 0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d, 0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a, 0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713, 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38, 0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242, 0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777, 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, 0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45, 0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2, 0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc, 0x40df0b66, 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9, 0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, 0xcdd70693, 0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94, 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d];
-
-if (typeof Int32Array !== 'undefined') {
- TABLE = new Int32Array(TABLE);
-}
-
-module.exports = create(function(buf, previous) {
- var byte, crc, _i, _len;
- if (!Buffer.isBuffer(buf)) {
- buf = Buffer(buf);
- }
- crc = ~~previous ^ -1;
- for (_i = 0, _len = buf.length; _i < _len; _i++) {
- byte = buf[_i];
- crc = TABLE[(crc ^ byte) & 0xff] ^ (crc >>> 8);
- }
- return crc ^ -1;
-});
diff --git a/CoAuthoring/node_modules/express/node_modules/etag/node_modules/crc/lib/crc8.js b/CoAuthoring/node_modules/express/node_modules/etag/node_modules/crc/lib/crc8.js
deleted file mode 100644
index d6518c1e41..0000000000
--- a/CoAuthoring/node_modules/express/node_modules/etag/node_modules/crc/lib/crc8.js
+++ /dev/null
@@ -1,25 +0,0 @@
-// Generated by CoffeeScript 1.7.1
-var Buffer, TABLE, create;
-
-Buffer = require('buffer').Buffer;
-
-create = require('./create');
-
-TABLE = [0x00, 0x07, 0x0e, 0x09, 0x1c, 0x1b, 0x12, 0x15, 0x38, 0x3f, 0x36, 0x31, 0x24, 0x23, 0x2a, 0x2d, 0x70, 0x77, 0x7e, 0x79, 0x6c, 0x6b, 0x62, 0x65, 0x48, 0x4f, 0x46, 0x41, 0x54, 0x53, 0x5a, 0x5d, 0xe0, 0xe7, 0xee, 0xe9, 0xfc, 0xfb, 0xf2, 0xf5, 0xd8, 0xdf, 0xd6, 0xd1, 0xc4, 0xc3, 0xca, 0xcd, 0x90, 0x97, 0x9e, 0x99, 0x8c, 0x8b, 0x82, 0x85, 0xa8, 0xaf, 0xa6, 0xa1, 0xb4, 0xb3, 0xba, 0xbd, 0xc7, 0xc0, 0xc9, 0xce, 0xdb, 0xdc, 0xd5, 0xd2, 0xff, 0xf8, 0xf1, 0xf6, 0xe3, 0xe4, 0xed, 0xea, 0xb7, 0xb0, 0xb9, 0xbe, 0xab, 0xac, 0xa5, 0xa2, 0x8f, 0x88, 0x81, 0x86, 0x93, 0x94, 0x9d, 0x9a, 0x27, 0x20, 0x29, 0x2e, 0x3b, 0x3c, 0x35, 0x32, 0x1f, 0x18, 0x11, 0x16, 0x03, 0x04, 0x0d, 0x0a, 0x57, 0x50, 0x59, 0x5e, 0x4b, 0x4c, 0x45, 0x42, 0x6f, 0x68, 0x61, 0x66, 0x73, 0x74, 0x7d, 0x7a, 0x89, 0x8e, 0x87, 0x80, 0x95, 0x92, 0x9b, 0x9c, 0xb1, 0xb6, 0xbf, 0xb8, 0xad, 0xaa, 0xa3, 0xa4, 0xf9, 0xfe, 0xf7, 0xf0, 0xe5, 0xe2, 0xeb, 0xec, 0xc1, 0xc6, 0xcf, 0xc8, 0xdd, 0xda, 0xd3, 0xd4, 0x69, 0x6e, 0x67, 0x60, 0x75, 0x72, 0x7b, 0x7c, 0x51, 0x56, 0x5f, 0x58, 0x4d, 0x4a, 0x43, 0x44, 0x19, 0x1e, 0x17, 0x10, 0x05, 0x02, 0x0b, 0x0c, 0x21, 0x26, 0x2f, 0x28, 0x3d, 0x3a, 0x33, 0x34, 0x4e, 0x49, 0x40, 0x47, 0x52, 0x55, 0x5c, 0x5b, 0x76, 0x71, 0x78, 0x7f, 0x6a, 0x6d, 0x64, 0x63, 0x3e, 0x39, 0x30, 0x37, 0x22, 0x25, 0x2c, 0x2b, 0x06, 0x01, 0x08, 0x0f, 0x1a, 0x1d, 0x14, 0x13, 0xae, 0xa9, 0xa0, 0xa7, 0xb2, 0xb5, 0xbc, 0xbb, 0x96, 0x91, 0x98, 0x9f, 0x8a, 0x8d, 0x84, 0x83, 0xde, 0xd9, 0xd0, 0xd7, 0xc2, 0xc5, 0xcc, 0xcb, 0xe6, 0xe1, 0xe8, 0xef, 0xfa, 0xfd, 0xf4, 0xf3];
-
-if (typeof Int32Array !== 'undefined') {
- TABLE = new Int32Array(TABLE);
-}
-
-module.exports = create(function(buf, previous) {
- var byte, crc, _i, _len;
- if (!Buffer.isBuffer(buf)) {
- buf = Buffer(buf);
- }
- crc = ~~previous;
- for (_i = 0, _len = buf.length; _i < _len; _i++) {
- byte = buf[_i];
- crc = (TABLE[(crc ^ byte) & 0xff] ^ (crc << 8)) & 0xff;
- }
- return crc;
-});
diff --git a/CoAuthoring/node_modules/express/node_modules/etag/node_modules/crc/lib/crc8_1wire.js b/CoAuthoring/node_modules/express/node_modules/etag/node_modules/crc/lib/crc8_1wire.js
deleted file mode 100644
index c63a422c58..0000000000
--- a/CoAuthoring/node_modules/express/node_modules/etag/node_modules/crc/lib/crc8_1wire.js
+++ /dev/null
@@ -1,25 +0,0 @@
-// Generated by CoffeeScript 1.7.1
-var Buffer, TABLE, create;
-
-Buffer = require('buffer').Buffer;
-
-create = require('./create');
-
-TABLE = [0x00, 0x5e, 0xbc, 0xe2, 0x61, 0x3f, 0xdd, 0x83, 0xc2, 0x9c, 0x7e, 0x20, 0xa3, 0xfd, 0x1f, 0x41, 0x9d, 0xc3, 0x21, 0x7f, 0xfc, 0xa2, 0x40, 0x1e, 0x5f, 0x01, 0xe3, 0xbd, 0x3e, 0x60, 0x82, 0xdc, 0x23, 0x7d, 0x9f, 0xc1, 0x42, 0x1c, 0xfe, 0xa0, 0xe1, 0xbf, 0x5d, 0x03, 0x80, 0xde, 0x3c, 0x62, 0xbe, 0xe0, 0x02, 0x5c, 0xdf, 0x81, 0x63, 0x3d, 0x7c, 0x22, 0xc0, 0x9e, 0x1d, 0x43, 0xa1, 0xff, 0x46, 0x18, 0xfa, 0xa4, 0x27, 0x79, 0x9b, 0xc5, 0x84, 0xda, 0x38, 0x66, 0xe5, 0xbb, 0x59, 0x07, 0xdb, 0x85, 0x67, 0x39, 0xba, 0xe4, 0x06, 0x58, 0x19, 0x47, 0xa5, 0xfb, 0x78, 0x26, 0xc4, 0x9a, 0x65, 0x3b, 0xd9, 0x87, 0x04, 0x5a, 0xb8, 0xe6, 0xa7, 0xf9, 0x1b, 0x45, 0xc6, 0x98, 0x7a, 0x24, 0xf8, 0xa6, 0x44, 0x1a, 0x99, 0xc7, 0x25, 0x7b, 0x3a, 0x64, 0x86, 0xd8, 0x5b, 0x05, 0xe7, 0xb9, 0x8c, 0xd2, 0x30, 0x6e, 0xed, 0xb3, 0x51, 0x0f, 0x4e, 0x10, 0xf2, 0xac, 0x2f, 0x71, 0x93, 0xcd, 0x11, 0x4f, 0xad, 0xf3, 0x70, 0x2e, 0xcc, 0x92, 0xd3, 0x8d, 0x6f, 0x31, 0xb2, 0xec, 0x0e, 0x50, 0xaf, 0xf1, 0x13, 0x4d, 0xce, 0x90, 0x72, 0x2c, 0x6d, 0x33, 0xd1, 0x8f, 0x0c, 0x52, 0xb0, 0xee, 0x32, 0x6c, 0x8e, 0xd0, 0x53, 0x0d, 0xef, 0xb1, 0xf0, 0xae, 0x4c, 0x12, 0x91, 0xcf, 0x2d, 0x73, 0xca, 0x94, 0x76, 0x28, 0xab, 0xf5, 0x17, 0x49, 0x08, 0x56, 0xb4, 0xea, 0x69, 0x37, 0xd5, 0x8b, 0x57, 0x09, 0xeb, 0xb5, 0x36, 0x68, 0x8a, 0xd4, 0x95, 0xcb, 0x29, 0x77, 0xf4, 0xaa, 0x48, 0x16, 0xe9, 0xb7, 0x55, 0x0b, 0x88, 0xd6, 0x34, 0x6a, 0x2b, 0x75, 0x97, 0xc9, 0x4a, 0x14, 0xf6, 0xa8, 0x74, 0x2a, 0xc8, 0x96, 0x15, 0x4b, 0xa9, 0xf7, 0xb6, 0xe8, 0x0a, 0x54, 0xd7, 0x89, 0x6b, 0x35];
-
-if (typeof Int32Array !== 'undefined') {
- TABLE = new Int32Array(TABLE);
-}
-
-module.exports = create(function(buf, previous) {
- var byte, crc, _i, _len;
- if (!Buffer.isBuffer(buf)) {
- buf = Buffer(buf);
- }
- crc = ~~previous;
- for (_i = 0, _len = buf.length; _i < _len; _i++) {
- byte = buf[_i];
- crc = (TABLE[(crc ^ byte) & 0xff] ^ (crc << 8)) & 0xff;
- }
- return crc;
-});
diff --git a/CoAuthoring/node_modules/express/node_modules/etag/node_modules/crc/lib/create.js b/CoAuthoring/node_modules/express/node_modules/etag/node_modules/crc/lib/create.js
deleted file mode 100644
index df4d9916c7..0000000000
--- a/CoAuthoring/node_modules/express/node_modules/etag/node_modules/crc/lib/create.js
+++ /dev/null
@@ -1,10 +0,0 @@
-// Generated by CoffeeScript 1.7.1
-module.exports = function(calc) {
- var fn;
- fn = function(buf, previous) {
- return calc(buf, previous) >>> 0;
- };
- fn.signed = calc;
- fn.unsigned = fn;
- return fn;
-};
diff --git a/CoAuthoring/node_modules/express/node_modules/etag/node_modules/crc/lib/hex.js b/CoAuthoring/node_modules/express/node_modules/etag/node_modules/crc/lib/hex.js
deleted file mode 100644
index 0a6aa4c535..0000000000
--- a/CoAuthoring/node_modules/express/node_modules/etag/node_modules/crc/lib/hex.js
+++ /dev/null
@@ -1,9 +0,0 @@
-// Generated by CoffeeScript 1.7.1
-module.exports = function(number) {
- var result;
- result = number.toString(16);
- while (result.length % 2) {
- result = "0" + result;
- }
- return result;
-};
diff --git a/CoAuthoring/node_modules/express/node_modules/etag/node_modules/crc/lib/index.js b/CoAuthoring/node_modules/express/node_modules/etag/node_modules/crc/lib/index.js
deleted file mode 100644
index 15ac34cd9d..0000000000
--- a/CoAuthoring/node_modules/express/node_modules/etag/node_modules/crc/lib/index.js
+++ /dev/null
@@ -1,11 +0,0 @@
-// Generated by CoffeeScript 1.7.1
-module.exports = {
- crc1: require('./crc1'),
- crc8: require('./crc8'),
- crc81wire: require('./crc8_1wire'),
- crc16: require('./crc16'),
- crc16ccitt: require('./crc16_ccitt'),
- crc16modbus: require('./crc16_modbus'),
- crc24: require('./crc24'),
- crc32: require('./crc32')
-};
diff --git a/CoAuthoring/node_modules/express/node_modules/etag/node_modules/crc/package.json b/CoAuthoring/node_modules/express/node_modules/etag/node_modules/crc/package.json
deleted file mode 100644
index 92cd235d6e..0000000000
--- a/CoAuthoring/node_modules/express/node_modules/etag/node_modules/crc/package.json
+++ /dev/null
@@ -1,40 +0,0 @@
-{
- "name": "crc",
- "version": "3.0.0",
- "description": "Various CRC JavaScript implementations",
- "keywords": [
- "crc"
- ],
- "main": "./lib/index.js",
- "scripts": {
- "test": "mocha test/*.spec.coffee",
- "pretest": "coffee --bare --output ./lib --compile ./src/*.coffee"
- },
- "author": {
- "name": "Alex Gorbatchev",
- "url": "https://github.com/alexgorbatchev"
- },
- "devDependencies": {
- "beautify-benchmark": "^0.2.4",
- "benchmark": "^1.0.0",
- "buffer-crc32": "^0.2.3",
- "chai": "~1.9.1",
- "coffee-errors": "~0.8.6",
- "coffee-script": "~1.7.1",
- "mocha": "*",
- "seedrandom": "^2.3.6"
- },
- "homepage": "https://github.com/alexgorbatchev/node-crc",
- "bugs": {
- "url": "https://github.com/alexgorbatchev/node-crc/issues"
- },
- "repository": {
- "type": "git",
- "url": "git://github.com/alexgorbatchev/node-crc.git"
- },
- "license": "MIT",
- "readme": "# crc\n\n[](https://www.gittip.com/alexgorbatchev/)\n[](https://david-dm.org/alexgorbatchev/node-crc)\n[](https://david-dm.org/alexgorbatchev/node-crc#info=devDependencies)\n[](https://travis-ci.org/alexgorbatchev/node-crc)\n\n[](https://npmjs.org/package/node-crc)\n\nModule for calculating Cyclic Redundancy Check (CRC).\n\n## Features\n\n* Version 3 is 3-4 times faster than version 2.\n* Pure JavaScript implementation, no dependencies.\n* Provides CRC Tables for optimized calculations.\n* Provides support for the following CRC algorithms:\n * CRC1 `crc.crc1(…)`\n * CRC8 `crc.crc8(…)`\n * CRC8 1-Wire `crc.crc81wire(…)`\n * CRC16 `crc.crc16(…)`\n * CRC16 CCITT `crc.crc16ccitt(…)`\n * CRC16 Modbus `crc.crc16modbus(…)`\n * CRC24 `crc.crc24(…)`\n * CRC32 `crc.crc32(…)`\n\n## Installation\n\n npm install crc\n\n## Running tests\n\n $ npm install\n $ npm test\n\n## Usage Example\n\nCalculate a CRC32:\n\n var crc = require('crc');\n\n crc.crc32('hello').toString(16);\n # => \"3610a686\"\n\nCalculate a CRC32 of a file:\n\n crc.crc32(fs.readFileSync('README.md', 'utf8')).toString(16);\n # => \"127ad531\"\n\nOr using a `Buffer`:\n\n crc.crc32(fs.readFileSync('README.md')).toString(16);\n # => \"127ad531\"\n\nIncrementally calculate a CRC32:\n\n value = crc32('one');\n value = crc32('two', value);\n value = crc32('three', value);\n value.toString(16);\n # => \"09e1c092\"\n\n## Thanks!\n\n[pycrc](http://www.tty1.net/pycrc/) library is which the source of all of the CRC tables.\n\n# License\n\nThe MIT License (MIT)\n\nCopyright (c) 2014 Alex Gorbatchev\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n",
- "readmeFilename": "README.md",
- "_id": "crc@3.0.0",
- "_from": "crc@3.0.0"
-}
diff --git a/CoAuthoring/node_modules/express/node_modules/etag/package.json b/CoAuthoring/node_modules/express/node_modules/etag/package.json
deleted file mode 100644
index b0b210b964..0000000000
--- a/CoAuthoring/node_modules/express/node_modules/etag/package.json
+++ /dev/null
@@ -1,57 +0,0 @@
-{
- "name": "etag",
- "description": "Create simple ETags",
- "version": "1.4.0",
- "contributors": [
- {
- "name": "Douglas Christopher Wilson",
- "email": "doug@somethingdoug.com"
- },
- {
- "name": "David Björklund",
- "email": "david.bjorklund@gmail.com"
- }
- ],
- "license": "MIT",
- "keywords": [
- "etag",
- "http",
- "res"
- ],
- "repository": {
- "type": "git",
- "url": "git://github.com/jshttp/etag"
- },
- "dependencies": {
- "crc": "3.0.0"
- },
- "devDependencies": {
- "benchmark": "1.0.0",
- "beautify-benchmark": "0.2.4",
- "istanbul": "0.3.2",
- "mocha": "~1.21.4",
- "seedrandom": "~2.3.6"
- },
- "files": [
- "LICENSE",
- "HISTORY.md",
- "index.js"
- ],
- "engines": {
- "node": ">= 0.6"
- },
- "scripts": {
- "bench": "node benchmark/index.js",
- "test": "mocha --reporter spec --bail --check-leaks test/",
- "test-cov": "istanbul cover node_modules/mocha/bin/_mocha -- --reporter dot --check-leaks test/",
- "test-travis": "istanbul cover node_modules/mocha/bin/_mocha --report lcovonly -- --reporter spec --check-leaks test/"
- },
- "readme": "# etag\n\n[![NPM Version][npm-image]][npm-url]\n[![NPM Downloads][downloads-image]][downloads-url]\n[![Node.js Version][node-version-image]][node-version-url]\n[![Build Status][travis-image]][travis-url]\n[![Test Coverage][coveralls-image]][coveralls-url]\n\nCreate simple ETags\n\n## Installation\n\n```sh\n$ npm install etag\n```\n\n## API\n\n```js\nvar etag = require('etag')\n```\n\n### etag(entity, [options])\n\nGenerate a strong ETag for the given entity. This should be the complete\nbody of the entity. Strings, `Buffer`s, and `fs.Stats` are accepted. By\ndefault, a strong ETag is generated except for `fs.Stats`, which will\ngenerate a weak ETag (this can be overwritten by `options.weak`).\n\n```js\nres.setHeader('ETag', etag(body))\n```\n\n#### Options\n\n`etag` accepts these properties in the options object.\n\n##### weak\n\nSpecifies if a \"strong\" or a \"weak\" ETag will be generated. The ETag can only\nreally be a strong as the given input.\n\n## Testing\n\n```sh\n$ npm test\n```\n\n## Benchmark\n\n```bash\n$ npm run-script bench\n\n> etag@1.2.0 bench nodejs-etag\n> node benchmark/index.js\n\n> node benchmark/body0-100b.js\n\n 100B body\n\n 1 test completed.\n 2 tests completed.\n 3 tests completed.\n 4 tests completed.\n\n buffer - strong x 518,895 ops/sec ±1.71% (185 runs sampled)\n* buffer - weak x 1,917,975 ops/sec ±0.34% (195 runs sampled)\n string - strong x 245,251 ops/sec ±0.90% (190 runs sampled)\n string - weak x 442,232 ops/sec ±0.21% (196 runs sampled)\n\n> node benchmark/body1-1kb.js\n\n 1KB body\n\n 1 test completed.\n 2 tests completed.\n 3 tests completed.\n 4 tests completed.\n\n buffer - strong x 309,748 ops/sec ±0.99% (191 runs sampled)\n* buffer - weak x 352,402 ops/sec ±0.20% (198 runs sampled)\n string - strong x 159,058 ops/sec ±1.83% (191 runs sampled)\n string - weak x 184,052 ops/sec ±1.30% (189 runs sampled)\n\n> node benchmark/body2-5kb.js\n\n 5KB body\n\n 1 test completed.\n 2 tests completed.\n 3 tests completed.\n 4 tests completed.\n\n* buffer - strong x 110,157 ops/sec ±0.60% (194 runs sampled)\n* buffer - weak x 111,333 ops/sec ±0.67% (194 runs sampled)\n string - strong x 62,091 ops/sec ±3.92% (186 runs sampled)\n string - weak x 60,681 ops/sec ±3.98% (186 runs sampled)\n\n> node benchmark/body3-10kb.js\n\n 10KB body\n\n 1 test completed.\n 2 tests completed.\n 3 tests completed.\n 4 tests completed.\n\n* buffer - strong x 61,843 ops/sec ±0.44% (197 runs sampled)\n* buffer - weak x 61,687 ops/sec ±0.52% (197 runs sampled)\n string - strong x 41,377 ops/sec ±3.33% (189 runs sampled)\n string - weak x 41,368 ops/sec ±3.29% (190 runs sampled)\n\n> node benchmark/body4-100kb.js\n\n 100KB body\n\n 1 test completed.\n 2 tests completed.\n 3 tests completed.\n 4 tests completed.\n\n* buffer - strong x 6,874 ops/sec ±0.17% (198 runs sampled)\n* buffer - weak x 6,880 ops/sec ±0.15% (198 runs sampled)\n string - strong x 5,382 ops/sec ±2.17% (192 runs sampled)\n string - weak x 5,361 ops/sec ±2.23% (192 runs sampled)\n```\n\n## License\n\n[MIT](LICENSE)\n\n[npm-image]: https://img.shields.io/npm/v/etag.svg?style=flat\n[npm-url]: https://npmjs.org/package/etag\n[node-version-image]: https://img.shields.io/node/v/etag.svg?style=flat\n[node-version-url]: http://nodejs.org/download/\n[travis-image]: https://img.shields.io/travis/jshttp/etag.svg?style=flat\n[travis-url]: https://travis-ci.org/jshttp/etag\n[coveralls-image]: https://img.shields.io/coveralls/jshttp/etag.svg?style=flat\n[coveralls-url]: https://coveralls.io/r/jshttp/etag?branch=master\n[downloads-image]: https://img.shields.io/npm/dm/etag.svg?style=flat\n[downloads-url]: https://npmjs.org/package/etag\n",
- "readmeFilename": "README.md",
- "bugs": {
- "url": "https://github.com/jshttp/etag/issues"
- },
- "homepage": "https://github.com/jshttp/etag",
- "_id": "etag@1.4.0",
- "_from": "etag@~1.4.0"
-}
diff --git a/CoAuthoring/node_modules/express/node_modules/finalhandler/HISTORY.md b/CoAuthoring/node_modules/express/node_modules/finalhandler/HISTORY.md
deleted file mode 100644
index 655d866a05..0000000000
--- a/CoAuthoring/node_modules/express/node_modules/finalhandler/HISTORY.md
+++ /dev/null
@@ -1,33 +0,0 @@
-0.2.0 / 2014-09-03
-==================
-
- * Set `X-Content-Type-Options: nosniff` header
- * deps: debug@~2.0.0
-
-0.1.0 / 2014-07-16
-==================
-
- * Respond after request fully read
- - prevents hung responses and socket hang ups
- * deps: debug@1.0.4
-
-0.0.3 / 2014-07-11
-==================
-
- * deps: debug@1.0.3
- - Add support for multiple wildcards in namespaces
-
-0.0.2 / 2014-06-19
-==================
-
- * Handle invalid status codes
-
-0.0.1 / 2014-06-05
-==================
-
- * deps: debug@1.0.2
-
-0.0.0 / 2014-06-05
-==================
-
- * Extracted from connect/express
diff --git a/CoAuthoring/node_modules/express/node_modules/finalhandler/LICENSE b/CoAuthoring/node_modules/express/node_modules/finalhandler/LICENSE
deleted file mode 100644
index eda23054b2..0000000000
--- a/CoAuthoring/node_modules/express/node_modules/finalhandler/LICENSE
+++ /dev/null
@@ -1,22 +0,0 @@
-(The MIT License)
-
-Copyright (c) 2014 Douglas Christopher Wilson
-
-Permission is hereby granted, free of charge, to any person obtaining
-a copy of this software and associated documentation files (the
-'Software'), to deal in the Software without restriction, including
-without limitation the rights to use, copy, modify, merge, publish,
-distribute, sublicense, and/or sell copies of the Software, and to
-permit persons to whom the Software is furnished to do so, subject to
-the following conditions:
-
-The above copyright notice and this permission notice shall be
-included in all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
-EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
-IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
-CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
-TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
-SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
diff --git a/CoAuthoring/node_modules/express/node_modules/finalhandler/README.md b/CoAuthoring/node_modules/express/node_modules/finalhandler/README.md
deleted file mode 100644
index fd7eb58f45..0000000000
--- a/CoAuthoring/node_modules/express/node_modules/finalhandler/README.md
+++ /dev/null
@@ -1,133 +0,0 @@
-# finalhandler
-
-[![NPM Version][npm-image]][npm-url]
-[![NPM Downloads][downloads-image]][downloads-url]
-[![Node.js Version][node-image]][node-url]
-[![Build Status][travis-image]][travis-url]
-[![Test Coverage][coveralls-image]][coveralls-url]
-
-Node.js function to invoke as the final step to respond to HTTP request.
-
-## Installation
-
-```sh
-$ npm install finalhandler
-```
-
-## API
-
-```js
-var finalhandler = require('finalhandler')
-```
-
-### finalhandler(req, res, [options])
-
-Returns function to be invoked as the final step for the given `req` and `res`.
-This function is to be invoked as `fn(err)`. If `err` is falsy, the handler will
-write out a 404 response to the `res`. If it is truthy, an error response will
-be written out to the `res`, and `res.statusCode` is set from `err.status`.
-
-The final handler will also unpipe anything from `req` when it is invoked.
-
-#### options.env
-
-By default, the environment is determined by `NODE_ENV` variable, but it can be
-overridden by this option.
-
-#### options.onerror
-
-Provide a function to be called with the `err` when it exists. Can be used for
-writing errors to a central location without excessive function generation. Called
-as `onerror(err, req, res)`.
-
-## Examples
-
-### always 404
-
-```js
-var finalhandler = require('finalhandler')
-var http = require('http')
-
-var server = http.createServer(function (req, res) {
- var done = finalhandler(req, res)
- done()
-})
-
-server.listen(3000)
-```
-
-### perform simple action
-
-```js
-var finalhandler = require('finalhandler')
-var fs = require('fs')
-var http = require('http')
-
-var server = http.createServer(function (req, res) {
- var done = finalhandler(req, res)
-
- fs.readFile('index.html', function (err, buf) {
- if (err) return done(err)
- res.setHeader('Content-Type', 'text/html')
- res.end(buf)
- })
-})
-
-server.listen(3000)
-```
-
-### use with middleware-style functions
-
-```js
-var finalhandler = require('finalhandler')
-var http = require('http')
-var serveStatic = require('serve-static')
-
-var serve = serveStatic('public')
-
-var server = http.createServer(function (req, res) {
- var done = finalhandler(req, res)
- serve(req, res, done)
-})
-
-server.listen(3000)
-```
-
-### keep log of all errors
-
-```js
-var finalhandler = require('finalhandler')
-var fs = require('fs')
-var http = require('http')
-
-var server = http.createServer(function (req, res) {
- var done = finalhandler(req, res, {onerror: logerror})
-
- fs.readFile('index.html', function (err, buf) {
- if (err) return done(err)
- res.setHeader('Content-Type', 'text/html')
- res.end(buf)
- })
-})
-
-server.listen(3000)
-
-function logerror(err) {
- console.error(err.stack || err.toString())
-}
-```
-
-## License
-
-[MIT](LICENSE)
-
-[npm-image]: https://img.shields.io/npm/v/finalhandler.svg?style=flat
-[npm-url]: https://npmjs.org/package/finalhandler
-[node-image]: http://img.shields.io/badge/node.js-%3E%3D_0.8-brightgreen.svg?style=flat
-[node-url]: http://nodejs.org/download/
-[travis-image]: https://img.shields.io/travis/pillarjs/finalhandler.svg?style=flat
-[travis-url]: https://travis-ci.org/pillarjs/finalhandler
-[coveralls-image]: https://img.shields.io/coveralls/pillarjs/finalhandler.svg?style=flat
-[coveralls-url]: https://coveralls.io/r/pillarjs/finalhandler?branch=master
-[downloads-image]: http://img.shields.io/npm/dm/finalhandler.svg?style=flat
-[downloads-url]: https://npmjs.org/package/finalhandler
diff --git a/CoAuthoring/node_modules/express/node_modules/finalhandler/index.js b/CoAuthoring/node_modules/express/node_modules/finalhandler/index.js
deleted file mode 100644
index d1a9b2f92c..0000000000
--- a/CoAuthoring/node_modules/express/node_modules/finalhandler/index.js
+++ /dev/null
@@ -1,163 +0,0 @@
-/*!
- * finalhandler
- * Copyright(c) 2014 Douglas Christopher Wilson
- * MIT Licensed
- */
-
-/**
- * Module dependencies.
- */
-
-var debug = require('debug')('finalhandler')
-var escapeHtml = require('escape-html')
-var http = require('http')
-
-/**
- * Variables.
- */
-
-/* istanbul ignore next */
-var defer = typeof setImmediate === 'function'
- ? setImmediate
- : function(fn){ process.nextTick(fn.bind.apply(fn, arguments)) }
-
-/**
- * Module exports.
- */
-
-module.exports = finalhandler
-
-/**
- * Final handler:
- *
- * @param {Request} req
- * @param {Response} res
- * @param {Object} [options]
- * @return {Function}
- * @api public
- */
-
-function finalhandler(req, res, options) {
- options = options || {}
-
- // get environment
- var env = options.env || process.env.NODE_ENV || 'development'
-
- // get error callback
- var onerror = options.onerror
-
- return function (err) {
- var msg
-
- // unhandled error
- if (err) {
- // default status code to 500
- if (!res.statusCode || res.statusCode < 400) {
- res.statusCode = 500
- }
-
- // respect err.status
- if (err.status) {
- res.statusCode = err.status
- }
-
- // production gets a basic error message
- var msg = env === 'production'
- ? http.STATUS_CODES[res.statusCode]
- : err.stack || err.toString()
- msg = escapeHtml(msg)
- .replace(/\n/g, ' ')
- .replace(/ /g, ' ') + '\n'
- } else {
- res.statusCode = 404
- msg = 'Cannot ' + escapeHtml(req.method) + ' ' + escapeHtml(req.originalUrl || req.url) + '\n'
- }
-
- debug('default %s', res.statusCode)
-
- // schedule onerror callback
- if (err && onerror) {
- defer(onerror, err, req, res)
- }
-
- // cannot actually respond
- if (res._header) {
- return req.socket.destroy()
- }
-
- send(req, res, res.statusCode, msg)
- }
-}
-
-/**
- * Send response.
- *
- * @param {IncomingMessage} req
- * @param {OutgoingMessage} res
- * @param {number} status
- * @param {string} body
- * @api private
- */
-
-function send(req, res, status, body) {
- function write() {
- res.statusCode = status
-
- // security header for content sniffing
- res.setHeader('X-Content-Type-Options', 'nosniff')
-
- // standard headers
- res.setHeader('Content-Type', 'text/html; charset=utf-8')
- res.setHeader('Content-Length', Buffer.byteLength(body, 'utf8'))
-
- if (req.method === 'HEAD') {
- res.end()
- return
- }
-
- res.end(body, 'utf8')
- }
-
- if (!req.readable) {
- write()
- return
- }
-
- // unpipe everything from the request
- unpipe(req)
-
- // flush the request
- req.once('end', write)
- req.resume()
-}
-
-/**
- * Unpipe everything from a stream.
- *
- * @param {Object} stream
- * @api private
- */
-
-/* istanbul ignore next: implementation differs between versions */
-function unpipe(stream) {
- if (typeof stream.unpipe === 'function') {
- // new-style
- stream.unpipe()
- return
- }
-
- // Node.js 0.8 hack
- var listener
- var listeners = stream.listeners('close')
-
- for (var i = 0; i < listeners.length; i++) {
- listener = listeners[i]
-
- if (listener.name !== 'cleanup' && listener.name !== 'onclose') {
- continue
- }
-
- // invoke the listener
- listener.call(stream)
- }
-}
diff --git a/CoAuthoring/node_modules/express/node_modules/finalhandler/package.json b/CoAuthoring/node_modules/express/node_modules/finalhandler/package.json
deleted file mode 100644
index 4f9f026bb5..0000000000
--- a/CoAuthoring/node_modules/express/node_modules/finalhandler/package.json
+++ /dev/null
@@ -1,46 +0,0 @@
-{
- "name": "finalhandler",
- "description": "Node.js final http responder",
- "version": "0.2.0",
- "author": {
- "name": "Douglas Christopher Wilson",
- "email": "doug@somethingdoug.com"
- },
- "license": "MIT",
- "repository": {
- "type": "git",
- "url": "git://github.com/pillarjs/finalhandler"
- },
- "dependencies": {
- "debug": "~2.0.0",
- "escape-html": "1.0.1"
- },
- "devDependencies": {
- "istanbul": "0.3.0",
- "mocha": "~1.21.4",
- "readable-stream": "~1.0.27",
- "should": "~4.0.1",
- "supertest": "~0.13.0"
- },
- "files": [
- "LICENSE",
- "HISTORY.md",
- "index.js"
- ],
- "engines": {
- "node": ">= 0.8.0"
- },
- "scripts": {
- "test": "mocha --reporter spec --bail --check-leaks test/",
- "test-cov": "istanbul cover node_modules/mocha/bin/_mocha -- --reporter dot --check-leaks test/",
- "test-travis": "istanbul cover node_modules/mocha/bin/_mocha --report lcovonly -- --reporter spec --check-leaks test/"
- },
- "readme": "# finalhandler\n\n[![NPM Version][npm-image]][npm-url]\n[![NPM Downloads][downloads-image]][downloads-url]\n[![Node.js Version][node-image]][node-url]\n[![Build Status][travis-image]][travis-url]\n[![Test Coverage][coveralls-image]][coveralls-url]\n\nNode.js function to invoke as the final step to respond to HTTP request.\n\n## Installation\n\n```sh\n$ npm install finalhandler\n```\n\n## API\n\n```js\nvar finalhandler = require('finalhandler')\n```\n\n### finalhandler(req, res, [options])\n\nReturns function to be invoked as the final step for the given `req` and `res`.\nThis function is to be invoked as `fn(err)`. If `err` is falsy, the handler will\nwrite out a 404 response to the `res`. If it is truthy, an error response will\nbe written out to the `res`, and `res.statusCode` is set from `err.status`.\n\nThe final handler will also unpipe anything from `req` when it is invoked.\n\n#### options.env\n\nBy default, the environment is determined by `NODE_ENV` variable, but it can be\noverridden by this option.\n\n#### options.onerror\n\nProvide a function to be called with the `err` when it exists. Can be used for\nwriting errors to a central location without excessive function generation. Called\nas `onerror(err, req, res)`.\n\n## Examples\n\n### always 404\n\n```js\nvar finalhandler = require('finalhandler')\nvar http = require('http')\n\nvar server = http.createServer(function (req, res) {\n var done = finalhandler(req, res)\n done()\n})\n\nserver.listen(3000)\n```\n\n### perform simple action\n\n```js\nvar finalhandler = require('finalhandler')\nvar fs = require('fs')\nvar http = require('http')\n\nvar server = http.createServer(function (req, res) {\n var done = finalhandler(req, res)\n\n fs.readFile('index.html', function (err, buf) {\n if (err) return done(err)\n res.setHeader('Content-Type', 'text/html')\n res.end(buf)\n })\n})\n\nserver.listen(3000)\n```\n\n### use with middleware-style functions\n\n```js\nvar finalhandler = require('finalhandler')\nvar http = require('http')\nvar serveStatic = require('serve-static')\n\nvar serve = serveStatic('public')\n\nvar server = http.createServer(function (req, res) {\n var done = finalhandler(req, res)\n serve(req, res, done)\n})\n\nserver.listen(3000)\n```\n\n### keep log of all errors\n\n```js\nvar finalhandler = require('finalhandler')\nvar fs = require('fs')\nvar http = require('http')\n\nvar server = http.createServer(function (req, res) {\n var done = finalhandler(req, res, {onerror: logerror})\n\n fs.readFile('index.html', function (err, buf) {\n if (err) return done(err)\n res.setHeader('Content-Type', 'text/html')\n res.end(buf)\n })\n})\n\nserver.listen(3000)\n\nfunction logerror(err) {\n console.error(err.stack || err.toString())\n}\n```\n\n## License\n\n[MIT](LICENSE)\n\n[npm-image]: https://img.shields.io/npm/v/finalhandler.svg?style=flat\n[npm-url]: https://npmjs.org/package/finalhandler\n[node-image]: http://img.shields.io/badge/node.js-%3E%3D_0.8-brightgreen.svg?style=flat\n[node-url]: http://nodejs.org/download/\n[travis-image]: https://img.shields.io/travis/pillarjs/finalhandler.svg?style=flat\n[travis-url]: https://travis-ci.org/pillarjs/finalhandler\n[coveralls-image]: https://img.shields.io/coveralls/pillarjs/finalhandler.svg?style=flat\n[coveralls-url]: https://coveralls.io/r/pillarjs/finalhandler?branch=master\n[downloads-image]: http://img.shields.io/npm/dm/finalhandler.svg?style=flat\n[downloads-url]: https://npmjs.org/package/finalhandler\n",
- "readmeFilename": "README.md",
- "bugs": {
- "url": "https://github.com/pillarjs/finalhandler/issues"
- },
- "homepage": "https://github.com/pillarjs/finalhandler",
- "_id": "finalhandler@0.2.0",
- "_from": "finalhandler@0.2.0"
-}
diff --git a/CoAuthoring/node_modules/express/node_modules/fresh/History.md b/CoAuthoring/node_modules/express/node_modules/fresh/History.md
deleted file mode 100644
index 56361df8d9..0000000000
--- a/CoAuthoring/node_modules/express/node_modules/fresh/History.md
+++ /dev/null
@@ -1,24 +0,0 @@
-0.2.4 / 2014-09-07
-==================
-
- * Support Node.js 0.6
-
-0.2.3 / 2014-09-07
-==================
-
- * Move repository to jshttp
-
-0.2.2 / 2014-02-19
-==================
-
- * Revert "Fix for blank page on Safari reload"
-
-0.2.1 / 2014-01-29
-==================
-
- * fix: support max-age=0 for end-to-end revalidation
-
-0.2.0 / 2013-08-11
-==================
-
- * fix: return false for no-cache
diff --git a/CoAuthoring/node_modules/express/node_modules/fresh/LICENSE b/CoAuthoring/node_modules/express/node_modules/fresh/LICENSE
deleted file mode 100644
index f5273943a3..0000000000
--- a/CoAuthoring/node_modules/express/node_modules/fresh/LICENSE
+++ /dev/null
@@ -1,22 +0,0 @@
-(The MIT License)
-
-Copyright (c) 2012 TJ Holowaychuk
-
-Permission is hereby granted, free of charge, to any person obtaining
-a copy of this software and associated documentation files (the
-'Software'), to deal in the Software without restriction, including
-without limitation the rights to use, copy, modify, merge, publish,
-distribute, sublicense, and/or sell copies of the Software, and to
-permit persons to whom the Software is furnished to do so, subject to
-the following conditions:
-
-The above copyright notice and this permission notice shall be
-included in all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
-EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
-IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
-CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
-TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
-SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
diff --git a/CoAuthoring/node_modules/express/node_modules/fresh/Readme.md b/CoAuthoring/node_modules/express/node_modules/fresh/Readme.md
deleted file mode 100644
index 54a885fbd5..0000000000
--- a/CoAuthoring/node_modules/express/node_modules/fresh/Readme.md
+++ /dev/null
@@ -1,58 +0,0 @@
-# fresh
-
-[![NPM Version][npm-image]][npm-url]
-[![NPM Downloads][downloads-image]][downloads-url]
-[![Node.js Version][node-version-image]][node-version-url]
-[![Build Status][travis-image]][travis-url]
-[![Test Coverage][coveralls-image]][coveralls-url]
-
-HTTP response freshness testing
-
-## Installation
-
-```
-$ npm install fresh
-```
-
-## API
-
-```js
-var fresh = require('fresh')
-```
-
-### fresh(req, res)
-
- Check freshness of `req` and `res` headers.
-
- When the cache is "fresh" __true__ is returned,
- otherwise __false__ is returned to indicate that
- the cache is now stale.
-
-## Example
-
-```js
-var req = { 'if-none-match': 'tobi' };
-var res = { 'etag': 'luna' };
-fresh(req, res);
-// => false
-
-var req = { 'if-none-match': 'tobi' };
-var res = { 'etag': 'tobi' };
-fresh(req, res);
-// => true
-```
-
-## License
-
-[MIT](LICENSE)
-
-[npm-image]: https://img.shields.io/npm/v/fresh.svg?style=flat
-[npm-url]: https://npmjs.org/package/fresh
-[node-version-image]: https://img.shields.io/badge/node.js-%3E%3D_0.6-brightgreen.svg?style=flat
-[node-version-url]: http://nodejs.org/download/
-[travis-image]: https://img.shields.io/travis/jshttp/fresh.svg?style=flat
-[travis-url]: https://travis-ci.org/jshttp/fresh
-[coveralls-image]: https://img.shields.io/coveralls/jshttp/fresh.svg?style=flat
-[coveralls-url]: https://coveralls.io/r/jshttp/fresh?branch=master
-[downloads-image]: https://img.shields.io/npm/dm/fresh.svg?style=flat
-[downloads-url]: https://npmjs.org/package/fresh
diff --git a/CoAuthoring/node_modules/express/node_modules/fresh/index.js b/CoAuthoring/node_modules/express/node_modules/fresh/index.js
deleted file mode 100644
index 9c3f47d1ea..0000000000
--- a/CoAuthoring/node_modules/express/node_modules/fresh/index.js
+++ /dev/null
@@ -1,53 +0,0 @@
-
-/**
- * Expose `fresh()`.
- */
-
-module.exports = fresh;
-
-/**
- * Check freshness of `req` and `res` headers.
- *
- * When the cache is "fresh" __true__ is returned,
- * otherwise __false__ is returned to indicate that
- * the cache is now stale.
- *
- * @param {Object} req
- * @param {Object} res
- * @return {Boolean}
- * @api public
- */
-
-function fresh(req, res) {
- // defaults
- var etagMatches = true;
- var notModified = true;
-
- // fields
- var modifiedSince = req['if-modified-since'];
- var noneMatch = req['if-none-match'];
- var lastModified = res['last-modified'];
- var etag = res['etag'];
- var cc = req['cache-control'];
-
- // unconditional request
- if (!modifiedSince && !noneMatch) return false;
-
- // check for no-cache cache request directive
- if (cc && cc.indexOf('no-cache') !== -1) return false;
-
- // parse if-none-match
- if (noneMatch) noneMatch = noneMatch.split(/ *, */);
-
- // if-none-match
- if (noneMatch) etagMatches = ~noneMatch.indexOf(etag) || '*' == noneMatch[0];
-
- // if-modified-since
- if (modifiedSince) {
- modifiedSince = new Date(modifiedSince);
- lastModified = new Date(lastModified);
- notModified = lastModified <= modifiedSince;
- }
-
- return !! (etagMatches && notModified);
-}
\ No newline at end of file
diff --git a/CoAuthoring/node_modules/express/node_modules/fresh/package.json b/CoAuthoring/node_modules/express/node_modules/fresh/package.json
deleted file mode 100644
index 5298608d80..0000000000
--- a/CoAuthoring/node_modules/express/node_modules/fresh/package.json
+++ /dev/null
@@ -1,47 +0,0 @@
-{
- "name": "fresh",
- "description": "HTTP response freshness testing",
- "version": "0.2.4",
- "author": {
- "name": "TJ Holowaychuk",
- "email": "tj@vision-media.ca",
- "url": "http://tjholowaychuk.com"
- },
- "license": "MIT",
- "keywords": [
- "fresh",
- "http",
- "conditional",
- "cache"
- ],
- "repository": {
- "type": "git",
- "url": "git://github.com/jshttp/fresh"
- },
- "devDependencies": {
- "istanbul": "0",
- "mocha": "1",
- "should": "3"
- },
- "files": [
- "HISTORY.md",
- "LICENSE",
- "index.js"
- ],
- "engines": {
- "node": ">= 0.6"
- },
- "scripts": {
- "test": "mocha --reporter spec --require should",
- "test-cov": "istanbul cover node_modules/mocha/bin/_mocha -- --reporter dot --require should",
- "test-travis": "istanbul cover node_modules/mocha/bin/_mocha --report lcovonly -- --reporter dot --require should"
- },
- "readme": "# fresh\n\n[![NPM Version][npm-image]][npm-url]\n[![NPM Downloads][downloads-image]][downloads-url]\n[![Node.js Version][node-version-image]][node-version-url]\n[![Build Status][travis-image]][travis-url]\n[![Test Coverage][coveralls-image]][coveralls-url]\n\nHTTP response freshness testing\n\n## Installation\n\n```\n$ npm install fresh\n```\n\n## API\n\n```js\nvar fresh = require('fresh')\n```\n\n### fresh(req, res)\n\n Check freshness of `req` and `res` headers.\n\n When the cache is \"fresh\" __true__ is returned,\n otherwise __false__ is returned to indicate that\n the cache is now stale.\n\n## Example\n\n```js\nvar req = { 'if-none-match': 'tobi' };\nvar res = { 'etag': 'luna' };\nfresh(req, res);\n// => false\n\nvar req = { 'if-none-match': 'tobi' };\nvar res = { 'etag': 'tobi' };\nfresh(req, res);\n// => true\n```\n\n## License\n\n[MIT](LICENSE)\n\n[npm-image]: https://img.shields.io/npm/v/fresh.svg?style=flat\n[npm-url]: https://npmjs.org/package/fresh\n[node-version-image]: https://img.shields.io/badge/node.js-%3E%3D_0.6-brightgreen.svg?style=flat\n[node-version-url]: http://nodejs.org/download/\n[travis-image]: https://img.shields.io/travis/jshttp/fresh.svg?style=flat\n[travis-url]: https://travis-ci.org/jshttp/fresh\n[coveralls-image]: https://img.shields.io/coveralls/jshttp/fresh.svg?style=flat\n[coveralls-url]: https://coveralls.io/r/jshttp/fresh?branch=master\n[downloads-image]: https://img.shields.io/npm/dm/fresh.svg?style=flat\n[downloads-url]: https://npmjs.org/package/fresh\n",
- "readmeFilename": "README.md",
- "bugs": {
- "url": "https://github.com/jshttp/fresh/issues"
- },
- "homepage": "https://github.com/jshttp/fresh",
- "_id": "fresh@0.2.4",
- "_from": "fresh@0.2.4"
-}
diff --git a/CoAuthoring/node_modules/express/node_modules/media-typer/HISTORY.md b/CoAuthoring/node_modules/express/node_modules/media-typer/HISTORY.md
deleted file mode 100644
index 62c2003168..0000000000
--- a/CoAuthoring/node_modules/express/node_modules/media-typer/HISTORY.md
+++ /dev/null
@@ -1,22 +0,0 @@
-0.3.0 / 2014-09-07
-==================
-
- * Support Node.js 0.6
- * Throw error when parameter format invalid on parse
-
-0.2.0 / 2014-06-18
-==================
-
- * Add `typer.format()` to format media types
-
-0.1.0 / 2014-06-17
-==================
-
- * Accept `req` as argument to `parse`
- * Accept `res` as argument to `parse`
- * Parse media type with extra LWS between type and first parameter
-
-0.0.0 / 2014-06-13
-==================
-
- * Initial implementation
diff --git a/CoAuthoring/node_modules/express/node_modules/media-typer/LICENSE b/CoAuthoring/node_modules/express/node_modules/media-typer/LICENSE
deleted file mode 100644
index b7dce6cf9a..0000000000
--- a/CoAuthoring/node_modules/express/node_modules/media-typer/LICENSE
+++ /dev/null
@@ -1,22 +0,0 @@
-(The MIT License)
-
-Copyright (c) 2014 Douglas Christopher Wilson
-
-Permission is hereby granted, free of charge, to any person obtaining
-a copy of this software and associated documentation files (the
-'Software'), to deal in the Software without restriction, including
-without limitation the rights to use, copy, modify, merge, publish,
-distribute, sublicense, and/or sell copies of the Software, and to
-permit persons to whom the Software is furnished to do so, subject to
-the following conditions:
-
-The above copyright notice and this permission notice shall be
-included in all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
-EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
-IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
-CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
-TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
-SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
diff --git a/CoAuthoring/node_modules/express/node_modules/media-typer/README.md b/CoAuthoring/node_modules/express/node_modules/media-typer/README.md
deleted file mode 100644
index d8df62347a..0000000000
--- a/CoAuthoring/node_modules/express/node_modules/media-typer/README.md
+++ /dev/null
@@ -1,81 +0,0 @@
-# media-typer
-
-[![NPM Version][npm-image]][npm-url]
-[![NPM Downloads][downloads-image]][downloads-url]
-[![Node.js Version][node-version-image]][node-version-url]
-[![Build Status][travis-image]][travis-url]
-[![Test Coverage][coveralls-image]][coveralls-url]
-
-Simple RFC 6838 media type parser
-
-## Installation
-
-```sh
-$ npm install media-typer
-```
-
-## API
-
-```js
-var typer = require('media-typer')
-```
-
-### typer.parse(string)
-
-```js
-var obj = typer.parse('image/svg+xml; charset=utf-8')
-```
-
-Parse a media type string. This will return an object with the following
-properties (examples are shown for the string `'image/svg+xml; charset=utf-8'`):
-
- - `type`: The type of the media type (always lower case). Example: `'image'`
-
- - `subtype`: The subtype of the media type (always lower case). Example: `'svg'`
-
- - `suffix`: The suffix of the media type (always lower case). Example: `'xml'`
-
- - `parameters`: An object of the parameters in the media type (name of parameter always lower case). Example: `{charset: 'utf-8'}`
-
-### typer.parse(req)
-
-```js
-var obj = typer.parse(req)
-```
-
-Parse the `content-type` header from the given `req`. Short-cut for
-`typer.parse(req.headers['content-type'])`.
-
-### typer.parse(res)
-
-```js
-var obj = typer.parse(res)
-```
-
-Parse the `content-type` header set on the given `res`. Short-cut for
-`typer.parse(res.getHeader('content-type'))`.
-
-### typer.format(obj)
-
-```js
-var obj = typer.format({type: 'image', subtype: 'svg', suffix: 'xml'})
-```
-
-Format an object into a media type string. This will return a string of the
-mime type for the given object. For the properties of the object, see the
-documentation for `typer.parse(string)`.
-
-## License
-
-[MIT](LICENSE)
-
-[npm-image]: https://img.shields.io/npm/v/media-typer.svg?style=flat
-[npm-url]: https://npmjs.org/package/media-typer
-[node-version-image]: https://img.shields.io/badge/node.js-%3E%3D_0.6-brightgreen.svg?style=flat
-[node-version-url]: http://nodejs.org/download/
-[travis-image]: https://img.shields.io/travis/jshttp/media-typer.svg?style=flat
-[travis-url]: https://travis-ci.org/jshttp/media-typer
-[coveralls-image]: https://img.shields.io/coveralls/jshttp/media-typer.svg?style=flat
-[coveralls-url]: https://coveralls.io/r/jshttp/media-typer
-[downloads-image]: https://img.shields.io/npm/dm/media-typer.svg?style=flat
-[downloads-url]: https://npmjs.org/package/media-typer
diff --git a/CoAuthoring/node_modules/express/node_modules/media-typer/index.js b/CoAuthoring/node_modules/express/node_modules/media-typer/index.js
deleted file mode 100644
index 07f7295ee7..0000000000
--- a/CoAuthoring/node_modules/express/node_modules/media-typer/index.js
+++ /dev/null
@@ -1,270 +0,0 @@
-/*!
- * media-typer
- * Copyright(c) 2014 Douglas Christopher Wilson
- * MIT Licensed
- */
-
-/**
- * RegExp to match *( ";" parameter ) in RFC 2616 sec 3.7
- *
- * parameter = token "=" ( token | quoted-string )
- * token = 1*
- * separators = "(" | ")" | "<" | ">" | "@"
- * | "," | ";" | ":" | "\" | <">
- * | "/" | "[" | "]" | "?" | "="
- * | "{" | "}" | SP | HT
- * quoted-string = ( <"> *(qdtext | quoted-pair ) <"> )
- * qdtext = >
- * quoted-pair = "\" CHAR
- * CHAR =
- * TEXT =
- * LWS = [CRLF] 1*( SP | HT )
- * CRLF = CR LF
- * CR =
- * LF =
- * SP =
- * SHT =
- * CTL =
- * OCTET =
- */
-var paramRegExp = /; *([!#$%&'\*\+\-\.0-9A-Z\^_`a-z\|~]+) *= *("(?:[ !\u0023-\u005b\u005d-\u007e\u0080-\u00ff]|\\[\u0020-\u007e])*"|[!#$%&'\*\+\-\.0-9A-Z\^_`a-z\|~]+) */g;
-var textRegExp = /^[\u0020-\u007e\u0080-\u00ff]+$/
-var tokenRegExp = /^[!#$%&'\*\+\-\.0-9A-Z\^_`a-z\|~]+$/
-
-/**
- * RegExp to match quoted-pair in RFC 2616
- *
- * quoted-pair = "\" CHAR
- * CHAR =
- */
-var qescRegExp = /\\([\u0000-\u007f])/g;
-
-/**
- * RegExp to match chars that must be quoted-pair in RFC 2616
- */
-var quoteRegExp = /([\\"])/g;
-
-/**
- * RegExp to match type in RFC 6838
- *
- * type-name = restricted-name
- * subtype-name = restricted-name
- * restricted-name = restricted-name-first *126restricted-name-chars
- * restricted-name-first = ALPHA / DIGIT
- * restricted-name-chars = ALPHA / DIGIT / "!" / "#" /
- * "$" / "&" / "-" / "^" / "_"
- * restricted-name-chars =/ "." ; Characters before first dot always
- * ; specify a facet name
- * restricted-name-chars =/ "+" ; Characters after last plus always
- * ; specify a structured syntax suffix
- * ALPHA = %x41-5A / %x61-7A ; A-Z / a-z
- * DIGIT = %x30-39 ; 0-9
- */
-var subtypeNameRegExp = /^[A-Za-z0-9][A-Za-z0-9!#$&^_.-]{0,126}$/
-var typeNameRegExp = /^[A-Za-z0-9][A-Za-z0-9!#$&^_-]{0,126}$/
-var typeRegExp = /^ *([A-Za-z0-9][A-Za-z0-9!#$&^_-]{0,126})\/([A-Za-z0-9][A-Za-z0-9!#$&^_.+-]{0,126}) *$/;
-
-/**
- * Module exports.
- */
-
-exports.format = format
-exports.parse = parse
-
-/**
- * Format object to media type.
- *
- * @param {object} obj
- * @return {string}
- * @api public
- */
-
-function format(obj) {
- if (!obj || typeof obj !== 'object') {
- throw new TypeError('argument obj is required')
- }
-
- var parameters = obj.parameters
- var subtype = obj.subtype
- var suffix = obj.suffix
- var type = obj.type
-
- if (!type || !typeNameRegExp.test(type)) {
- throw new TypeError('invalid type')
- }
-
- if (!subtype || !subtypeNameRegExp.test(subtype)) {
- throw new TypeError('invalid subtype')
- }
-
- // format as type/subtype
- var string = type + '/' + subtype
-
- // append +suffix
- if (suffix) {
- if (!typeNameRegExp.test(suffix)) {
- throw new TypeError('invalid suffix')
- }
-
- string += '+' + suffix
- }
-
- // append parameters
- if (parameters && typeof parameters === 'object') {
- var param
- var params = Object.keys(parameters).sort()
-
- for (var i = 0; i < params.length; i++) {
- param = params[i]
-
- if (!tokenRegExp.test(param)) {
- throw new TypeError('invalid parameter name')
- }
-
- string += '; ' + param + '=' + qstring(parameters[param])
- }
- }
-
- return string
-}
-
-/**
- * Parse media type to object.
- *
- * @param {string|object} string
- * @return {Object}
- * @api public
- */
-
-function parse(string) {
- if (!string) {
- throw new TypeError('argument string is required')
- }
-
- // support req/res-like objects as argument
- if (typeof string === 'object') {
- string = getcontenttype(string)
- }
-
- if (typeof string !== 'string') {
- throw new TypeError('argument string is required to be a string')
- }
-
- var index = string.indexOf(';')
- var type = index !== -1
- ? string.substr(0, index)
- : string
-
- var key
- var match
- var obj = splitType(type)
- var params = {}
- var value
-
- paramRegExp.lastIndex = index
-
- while (match = paramRegExp.exec(string)) {
- if (match.index !== index) {
- throw new TypeError('invalid parameter format')
- }
-
- index += match[0].length
- key = match[1].toLowerCase()
- value = match[2]
-
- if (value[0] === '"') {
- // remove quotes and escapes
- value = value
- .substr(1, value.length - 2)
- .replace(qescRegExp, '$1')
- }
-
- params[key] = value
- }
-
- if (index !== -1 && index !== string.length) {
- throw new TypeError('invalid parameter format')
- }
-
- obj.parameters = params
-
- return obj
-}
-
-/**
- * Get content-type from req/res objects.
- *
- * @param {object}
- * @return {Object}
- * @api private
- */
-
-function getcontenttype(obj) {
- if (typeof obj.getHeader === 'function') {
- // res-like
- return obj.getHeader('content-type')
- }
-
- if (typeof obj.headers === 'object') {
- // req-like
- return obj.headers && obj.headers['content-type']
- }
-}
-
-/**
- * Quote a string if necessary.
- *
- * @param {string} val
- * @return {string}
- * @api private
- */
-
-function qstring(val) {
- var str = String(val)
-
- // no need to quote tokens
- if (tokenRegExp.test(str)) {
- return str
- }
-
- if (str.length > 0 && !textRegExp.test(str)) {
- throw new TypeError('invalid parameter value')
- }
-
- return '"' + str.replace(quoteRegExp, '\\$1') + '"'
-}
-
-/**
- * Simply "type/subtype+siffx" into parts.
- *
- * @param {string} string
- * @return {Object}
- * @api private
- */
-
-function splitType(string) {
- var match = typeRegExp.exec(string.toLowerCase())
-
- if (!match) {
- throw new TypeError('invalid media type')
- }
-
- var type = match[1]
- var subtype = match[2]
- var suffix
-
- // suffix after last +
- var index = subtype.lastIndexOf('+')
- if (index !== -1) {
- suffix = subtype.substr(index + 1)
- subtype = subtype.substr(0, index)
- }
-
- var obj = {
- type: type,
- subtype: subtype,
- suffix: suffix
- }
-
- return obj
-}
diff --git a/CoAuthoring/node_modules/express/node_modules/media-typer/package.json b/CoAuthoring/node_modules/express/node_modules/media-typer/package.json
deleted file mode 100644
index 274e4cbd5b..0000000000
--- a/CoAuthoring/node_modules/express/node_modules/media-typer/package.json
+++ /dev/null
@@ -1,40 +0,0 @@
-{
- "name": "media-typer",
- "description": "Simple RFC 6838 media type parser and formatter",
- "version": "0.3.0",
- "author": {
- "name": "Douglas Christopher Wilson",
- "email": "doug@somethingdoug.com"
- },
- "license": "MIT",
- "repository": {
- "type": "git",
- "url": "git://github.com/jshttp/media-typer"
- },
- "devDependencies": {
- "istanbul": "0.3.2",
- "mocha": "~1.21.4",
- "should": "~4.0.4"
- },
- "files": [
- "LICENSE",
- "HISTORY.md",
- "index.js"
- ],
- "engines": {
- "node": ">= 0.6"
- },
- "scripts": {
- "test": "mocha --reporter spec --check-leaks --bail test/",
- "test-cov": "istanbul cover node_modules/mocha/bin/_mocha -- --reporter dot --check-leaks test/",
- "test-travis": "istanbul cover node_modules/mocha/bin/_mocha --report lcovonly -- --reporter spec --check-leaks test/"
- },
- "readme": "# media-typer\n\n[![NPM Version][npm-image]][npm-url]\n[![NPM Downloads][downloads-image]][downloads-url]\n[![Node.js Version][node-version-image]][node-version-url]\n[![Build Status][travis-image]][travis-url]\n[![Test Coverage][coveralls-image]][coveralls-url]\n\nSimple RFC 6838 media type parser\n\n## Installation\n\n```sh\n$ npm install media-typer\n```\n\n## API\n\n```js\nvar typer = require('media-typer')\n```\n\n### typer.parse(string)\n\n```js\nvar obj = typer.parse('image/svg+xml; charset=utf-8')\n```\n\nParse a media type string. This will return an object with the following\nproperties (examples are shown for the string `'image/svg+xml; charset=utf-8'`):\n\n - `type`: The type of the media type (always lower case). Example: `'image'`\n\n - `subtype`: The subtype of the media type (always lower case). Example: `'svg'`\n\n - `suffix`: The suffix of the media type (always lower case). Example: `'xml'`\n\n - `parameters`: An object of the parameters in the media type (name of parameter always lower case). Example: `{charset: 'utf-8'}`\n\n### typer.parse(req)\n\n```js\nvar obj = typer.parse(req)\n```\n\nParse the `content-type` header from the given `req`. Short-cut for\n`typer.parse(req.headers['content-type'])`.\n\n### typer.parse(res)\n\n```js\nvar obj = typer.parse(res)\n```\n\nParse the `content-type` header set on the given `res`. Short-cut for\n`typer.parse(res.getHeader('content-type'))`.\n\n### typer.format(obj)\n\n```js\nvar obj = typer.format({type: 'image', subtype: 'svg', suffix: 'xml'})\n```\n\nFormat an object into a media type string. This will return a string of the\nmime type for the given object. For the properties of the object, see the\ndocumentation for `typer.parse(string)`.\n\n## License\n\n[MIT](LICENSE)\n\n[npm-image]: https://img.shields.io/npm/v/media-typer.svg?style=flat\n[npm-url]: https://npmjs.org/package/media-typer\n[node-version-image]: https://img.shields.io/badge/node.js-%3E%3D_0.6-brightgreen.svg?style=flat\n[node-version-url]: http://nodejs.org/download/\n[travis-image]: https://img.shields.io/travis/jshttp/media-typer.svg?style=flat\n[travis-url]: https://travis-ci.org/jshttp/media-typer\n[coveralls-image]: https://img.shields.io/coveralls/jshttp/media-typer.svg?style=flat\n[coveralls-url]: https://coveralls.io/r/jshttp/media-typer\n[downloads-image]: https://img.shields.io/npm/dm/media-typer.svg?style=flat\n[downloads-url]: https://npmjs.org/package/media-typer\n",
- "readmeFilename": "README.md",
- "bugs": {
- "url": "https://github.com/jshttp/media-typer/issues"
- },
- "homepage": "https://github.com/jshttp/media-typer",
- "_id": "media-typer@0.3.0",
- "_from": "media-typer@0.3.0"
-}
diff --git a/CoAuthoring/node_modules/express/node_modules/merge-descriptors/.npmignore b/CoAuthoring/node_modules/express/node_modules/merge-descriptors/.npmignore
deleted file mode 100644
index f62e6050c5..0000000000
--- a/CoAuthoring/node_modules/express/node_modules/merge-descriptors/.npmignore
+++ /dev/null
@@ -1,59 +0,0 @@
-# Compiled source #
-###################
-*.com
-*.class
-*.dll
-*.exe
-*.o
-*.so
-
-# Packages #
-############
-# it's better to unpack these files and commit the raw source
-# git has its own built in compression methods
-*.7z
-*.dmg
-*.gz
-*.iso
-*.jar
-*.rar
-*.tar
-*.zip
-
-# Logs and databases #
-######################
-*.log
-*.sql
-*.sqlite
-
-# OS generated files #
-######################
-.DS_Store*
-ehthumbs.db
-Icon?
-Thumbs.db
-
-# Node.js #
-###########
-lib-cov
-*.seed
-*.log
-*.csv
-*.dat
-*.out
-*.pid
-*.gz
-
-pids
-logs
-results
-
-node_modules
-npm-debug.log
-
-# Components #
-##############
-
-/build
-/components
-/vendors
\ No newline at end of file
diff --git a/CoAuthoring/node_modules/express/node_modules/merge-descriptors/README.md b/CoAuthoring/node_modules/express/node_modules/merge-descriptors/README.md
deleted file mode 100644
index 50cf50c03e..0000000000
--- a/CoAuthoring/node_modules/express/node_modules/merge-descriptors/README.md
+++ /dev/null
@@ -1,49 +0,0 @@
-# Merge Descriptors [](https://travis-ci.org/component/merge-descriptors)
-
-Merge objects using descriptors.
-
-```js
-var thing = {
- get name() {
- return 'jon'
- }
-}
-
-var animal = {
-
-}
-
-merge(animal, thing)
-
-animal.name === 'jon'
-```
-
-## API
-
-### merge(destination, source)
-
-Overwrites `destination`'s descriptors with `source`'s.
-
-## License
-
-The MIT License (MIT)
-
-Copyright (c) 2013 Jonathan Ong me@jongleberry.com
-
-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.
\ No newline at end of file
diff --git a/CoAuthoring/node_modules/express/node_modules/merge-descriptors/component.json b/CoAuthoring/node_modules/express/node_modules/merge-descriptors/component.json
deleted file mode 100644
index 7653906b49..0000000000
--- a/CoAuthoring/node_modules/express/node_modules/merge-descriptors/component.json
+++ /dev/null
@@ -1,10 +0,0 @@
-{
- "name": "merge-descriptors",
- "description": "Merge objects using descriptors",
- "version": "0.0.2",
- "scripts": [
- "index.js"
- ],
- "repo": "component/merge-descriptors",
- "license": "MIT"
-}
\ No newline at end of file
diff --git a/CoAuthoring/node_modules/express/node_modules/merge-descriptors/index.js b/CoAuthoring/node_modules/express/node_modules/merge-descriptors/index.js
deleted file mode 100644
index e4e23793c0..0000000000
--- a/CoAuthoring/node_modules/express/node_modules/merge-descriptors/index.js
+++ /dev/null
@@ -1,8 +0,0 @@
-module.exports = function (dest, src) {
- Object.getOwnPropertyNames(src).forEach(function (name) {
- var descriptor = Object.getOwnPropertyDescriptor(src, name)
- Object.defineProperty(dest, name, descriptor)
- })
-
- return dest
-}
\ No newline at end of file
diff --git a/CoAuthoring/node_modules/express/node_modules/merge-descriptors/package.json b/CoAuthoring/node_modules/express/node_modules/merge-descriptors/package.json
deleted file mode 100644
index f3c0d486b0..0000000000
--- a/CoAuthoring/node_modules/express/node_modules/merge-descriptors/package.json
+++ /dev/null
@@ -1,26 +0,0 @@
-{
- "name": "merge-descriptors",
- "description": "Merge objects using descriptors",
- "version": "0.0.2",
- "author": {
- "name": "Jonathan Ong",
- "email": "me@jongleberry.com",
- "url": "http://jongleberry.com"
- },
- "license": "MIT",
- "repository": {
- "type": "git",
- "url": "https://github.com/component/merge-descriptors.git"
- },
- "bugs": {
- "url": "https://github.com/component/merge-descriptors/issues"
- },
- "scripts": {
- "test": "make test;"
- },
- "readme": "# Merge Descriptors [](https://travis-ci.org/component/merge-descriptors)\n\nMerge objects using descriptors.\n\n```js\nvar thing = {\n get name() {\n return 'jon'\n }\n}\n\nvar animal = {\n\n}\n\nmerge(animal, thing)\n\nanimal.name === 'jon'\n```\n\n## API\n\n### merge(destination, source)\n\nOverwrites `destination`'s descriptors with `source`'s.\n\n## License\n\nThe MIT License (MIT)\n\nCopyright (c) 2013 Jonathan Ong me@jongleberry.com\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.",
- "readmeFilename": "README.md",
- "homepage": "https://github.com/component/merge-descriptors",
- "_id": "merge-descriptors@0.0.2",
- "_from": "merge-descriptors@0.0.2"
-}
diff --git a/CoAuthoring/node_modules/express/node_modules/methods/.npmignore b/CoAuthoring/node_modules/express/node_modules/methods/.npmignore
deleted file mode 100644
index c2658d7d1b..0000000000
--- a/CoAuthoring/node_modules/express/node_modules/methods/.npmignore
+++ /dev/null
@@ -1 +0,0 @@
-node_modules/
diff --git a/CoAuthoring/node_modules/express/node_modules/methods/History.md b/CoAuthoring/node_modules/express/node_modules/methods/History.md
deleted file mode 100644
index d3996c2efc..0000000000
--- a/CoAuthoring/node_modules/express/node_modules/methods/History.md
+++ /dev/null
@@ -1,20 +0,0 @@
-
-1.1.0 / 2014-07-05
-==================
-
- * add CONNECT
-
-1.0.1 / 2014-06-02
-==================
-
- * fix index.js to work with harmony transform
-
-1.0.0 / 2014-05-08
-==================
-
- * add PURGE. Closes #9
-
-0.1.0 / 2013-10-28
-==================
-
- * add http.METHODS support
diff --git a/CoAuthoring/node_modules/express/node_modules/methods/LICENSE b/CoAuthoring/node_modules/express/node_modules/methods/LICENSE
deleted file mode 100644
index 8bce401dc2..0000000000
--- a/CoAuthoring/node_modules/express/node_modules/methods/LICENSE
+++ /dev/null
@@ -1,23 +0,0 @@
-(The MIT License)
-
-Copyright (c) 2013-2014 TJ Holowaychuk
-
-Permission is hereby granted, free of charge, to any person obtaining
-a copy of this software and associated documentation files (the
-'Software'), to deal in the Software without restriction, including
-without limitation the rights to use, copy, modify, merge, publish,
-distribute, sublicense, and/or sell copies of the Software, and to
-permit persons to whom the Software is furnished to do so, subject to
-the following conditions:
-
-The above copyright notice and this permission notice shall be
-included in all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
-EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
-IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
-CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
-TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
-SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-
diff --git a/CoAuthoring/node_modules/express/node_modules/methods/Readme.md b/CoAuthoring/node_modules/express/node_modules/methods/Readme.md
deleted file mode 100644
index ac0658e21c..0000000000
--- a/CoAuthoring/node_modules/express/node_modules/methods/Readme.md
+++ /dev/null
@@ -1,4 +0,0 @@
-
-# Methods
-
- HTTP verbs that node core's parser supports.
diff --git a/CoAuthoring/node_modules/express/node_modules/methods/index.js b/CoAuthoring/node_modules/express/node_modules/methods/index.js
deleted file mode 100644
index f7e3c48656..0000000000
--- a/CoAuthoring/node_modules/express/node_modules/methods/index.js
+++ /dev/null
@@ -1,41 +0,0 @@
-
-var http = require('http');
-
-if (http.METHODS) {
-
- module.exports = http.METHODS.map(function(method){
- return method.toLowerCase();
- });
-
-} else {
-
- module.exports = [
- 'get',
- 'post',
- 'put',
- 'head',
- 'delete',
- 'options',
- 'trace',
- 'copy',
- 'lock',
- 'mkcol',
- 'move',
- 'purge',
- 'propfind',
- 'proppatch',
- 'unlock',
- 'report',
- 'mkactivity',
- 'checkout',
- 'merge',
- 'm-search',
- 'notify',
- 'subscribe',
- 'unsubscribe',
- 'patch',
- 'search',
- 'connect'
- ];
-
-}
diff --git a/CoAuthoring/node_modules/express/node_modules/methods/package.json b/CoAuthoring/node_modules/express/node_modules/methods/package.json
deleted file mode 100644
index bc487c08fe..0000000000
--- a/CoAuthoring/node_modules/express/node_modules/methods/package.json
+++ /dev/null
@@ -1,32 +0,0 @@
-{
- "name": "methods",
- "version": "1.1.0",
- "description": "HTTP methods that node supports",
- "main": "index.js",
- "scripts": {
- "test": "./node_modules/mocha/bin/mocha"
- },
- "keywords": [
- "http",
- "methods"
- ],
- "author": {
- "name": "TJ Holowaychuk"
- },
- "license": "MIT",
- "repository": {
- "type": "git",
- "url": "git://github.com/visionmedia/node-methods.git"
- },
- "devDependencies": {
- "mocha": "1.17.x"
- },
- "readme": "\n# Methods\n\n HTTP verbs that node core's parser supports.\n",
- "readmeFilename": "Readme.md",
- "bugs": {
- "url": "https://github.com/visionmedia/node-methods/issues"
- },
- "homepage": "https://github.com/visionmedia/node-methods",
- "_id": "methods@1.1.0",
- "_from": "methods@1.1.0"
-}
diff --git a/CoAuthoring/node_modules/express/node_modules/methods/test/methods.js b/CoAuthoring/node_modules/express/node_modules/methods/test/methods.js
deleted file mode 100644
index 527beaba83..0000000000
--- a/CoAuthoring/node_modules/express/node_modules/methods/test/methods.js
+++ /dev/null
@@ -1,33 +0,0 @@
-var http = require('http');
-var assert = require('assert');
-var methods = require('..');
-
-describe('methods', function() {
-
- if (http.METHODS) {
-
- it('is a lowercased http.METHODS', function() {
- var lowercased = http.METHODS.map(function(method) {
- return method.toLowerCase();
- });
- assert.deepEqual(lowercased, methods);
- });
-
- } else {
-
- it('contains GET, POST, PUT, and DELETE', function() {
- assert.notEqual(methods.indexOf('get'), -1);
- assert.notEqual(methods.indexOf('post'), -1);
- assert.notEqual(methods.indexOf('put'), -1);
- assert.notEqual(methods.indexOf('delete'), -1);
- });
-
- it('is all lowercase', function() {
- for (var i = 0; i < methods.length; i ++) {
- assert(methods[i], methods[i].toLowerCase(), methods[i] + " isn't all lowercase");
- }
- });
-
- }
-
-});
diff --git a/CoAuthoring/node_modules/express/node_modules/on-finished/HISTORY.md b/CoAuthoring/node_modules/express/node_modules/on-finished/HISTORY.md
deleted file mode 100644
index 1a4063dc1e..0000000000
--- a/CoAuthoring/node_modules/express/node_modules/on-finished/HISTORY.md
+++ /dev/null
@@ -1,71 +0,0 @@
-2.1.1 / 2014-10-22
-==================
-
- * Fix handling of pipelined requests
-
-2.1.0 / 2014-08-16
-==================
-
- * Check if `socket` is detached
- * Return `undefined` for `isFinished` if state unknown
-
-2.0.0 / 2014-08-16
-==================
-
- * Add `isFinished` function
- * Move to `jshttp` organization
- * Remove support for plain socket argument
- * Rename to `on-finished`
- * Support both `req` and `res` as arguments
- * deps: ee-first@1.0.5
-
-1.2.2 / 2014-06-10
-==================
-
- * Reduce listeners added to emitters
- - avoids "event emitter leak" warnings when used multiple times on same request
-
-1.2.1 / 2014-06-08
-==================
-
- * Fix returned value when already finished
-
-1.2.0 / 2014-06-05
-==================
-
- * Call callback when called on already-finished socket
-
-1.1.4 / 2014-05-27
-==================
-
- * Support node.js 0.8
-
-1.1.3 / 2014-04-30
-==================
-
- * Make sure errors passed as instanceof `Error`
-
-1.1.2 / 2014-04-18
-==================
-
- * Default the `socket` to passed-in object
-
-1.1.1 / 2014-01-16
-==================
-
- * Rename module to `finished`
-
-1.1.0 / 2013-12-25
-==================
-
- * Call callback when called on already-errored socket
-
-1.0.1 / 2013-12-20
-==================
-
- * Actually pass the error to the callback
-
-1.0.0 / 2013-12-20
-==================
-
- * Initial release
diff --git a/CoAuthoring/node_modules/express/node_modules/on-finished/LICENSE b/CoAuthoring/node_modules/express/node_modules/on-finished/LICENSE
deleted file mode 100644
index 5931fd23ea..0000000000
--- a/CoAuthoring/node_modules/express/node_modules/on-finished/LICENSE
+++ /dev/null
@@ -1,23 +0,0 @@
-(The MIT License)
-
-Copyright (c) 2013 Jonathan Ong
-Copyright (c) 2014 Douglas Christopher Wilson
-
-Permission is hereby granted, free of charge, to any person obtaining
-a copy of this software and associated documentation files (the
-'Software'), to deal in the Software without restriction, including
-without limitation the rights to use, copy, modify, merge, publish,
-distribute, sublicense, and/or sell copies of the Software, and to
-permit persons to whom the Software is furnished to do so, subject to
-the following conditions:
-
-The above copyright notice and this permission notice shall be
-included in all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
-EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
-IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
-CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
-TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
-SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
diff --git a/CoAuthoring/node_modules/express/node_modules/on-finished/README.md b/CoAuthoring/node_modules/express/node_modules/on-finished/README.md
deleted file mode 100644
index 6fb0e4d4f8..0000000000
--- a/CoAuthoring/node_modules/express/node_modules/on-finished/README.md
+++ /dev/null
@@ -1,102 +0,0 @@
-# on-finished
-
-[![NPM Version][npm-image]][npm-url]
-[![NPM Downloads][downloads-image]][downloads-url]
-[![Node.js Version][node-version-image]][node-version-url]
-[![Build Status][travis-image]][travis-url]
-[![Test Coverage][coveralls-image]][coveralls-url]
-
-Execute a callback when a request closes, finishes, or errors.
-
-## Install
-
-```sh
-$ npm install on-finished
-```
-
-## API
-
-```js
-var onFinished = require('on-finished')
-```
-
-### onFinished(res, listener)
-
-Attach a listener to listen for the response to finish. The listener will
-be invoked only once when the response finished. If the response finished
-to to an error, the first argument will contain the error.
-
-Listening to the end of a response would be used to close things associated
-with the response, like open files.
-
-```js
-onFinished(res, function (err) {
- // clean up open fds, etc.
-})
-```
-
-### onFinished(req, listener)
-
-Attach a listener to listen for the request to finish. The listener will
-be invoked only once when the request finished. If the request finished
-to to an error, the first argument will contain the error.
-
-Listening to the end of a request would be used to know when to continue
-after reading the data.
-
-```js
-var data = ''
-
-req.setEncoding('utf8')
-res.on('data', function (str) {
- data += str
-})
-
-onFinished(req, function (err) {
- // data is read unless there is err
-})
-```
-
-### onFinished.isFinished(res)
-
-Determine if `res` is already finished. This would be useful to check and
-not even start certain operations if the response has already finished.
-
-### onFinished.isFinished(req)
-
-Determine if `req` is already finished. This would be useful to check and
-not even start certain operations if the request has already finished.
-
-### Example
-
-The following code ensures that file descriptors are always closed
-once the response finishes.
-
-```js
-var destroy = require('destroy')
-var http = require('http')
-var onFinished = require('on-finished')
-
-http.createServer(function onRequest(req, res) {
- var stream = fs.createReadStream('package.json')
- stream.pipe(res)
- onFinished(res, function (err) {
- destroy(stream)
- })
-})
-```
-
-## License
-
-[MIT](LICENSE)
-
-[npm-image]: https://img.shields.io/npm/v/on-finished.svg?style=flat
-[npm-url]: https://npmjs.org/package/on-finished
-[node-version-image]: https://img.shields.io/node/v/on-finished.svg?style=flat
-[node-version-url]: http://nodejs.org/download/
-[travis-image]: https://img.shields.io/travis/jshttp/on-finished.svg?style=flat
-[travis-url]: https://travis-ci.org/jshttp/on-finished
-[coveralls-image]: https://img.shields.io/coveralls/jshttp/on-finished.svg?style=flat
-[coveralls-url]: https://coveralls.io/r/jshttp/on-finished?branch=master
-[downloads-image]: https://img.shields.io/npm/dm/on-finished.svg?style=flat
-[downloads-url]: https://npmjs.org/package/on-finished
diff --git a/CoAuthoring/node_modules/express/node_modules/on-finished/index.js b/CoAuthoring/node_modules/express/node_modules/on-finished/index.js
deleted file mode 100644
index e75a7e9bca..0000000000
--- a/CoAuthoring/node_modules/express/node_modules/on-finished/index.js
+++ /dev/null
@@ -1,191 +0,0 @@
-/*!
- * on-finished
- * Copyright(c) 2013 Jonathan Ong
- * Copyright(c) 2014 Douglas Christopher Wilson
- * MIT Licensed
- */
-
-/**
- * Module exports.
- */
-
-module.exports = onFinished;
-module.exports.isFinished = isFinished;
-
-/**
-* Module dependencies.
-*/
-
-var first = require('ee-first')
-
-/**
-* Variables.
-*/
-
-/* istanbul ignore next */
-var defer = typeof setImmediate === 'function'
- ? setImmediate
- : function(fn){ process.nextTick(fn.bind.apply(fn, arguments)) }
-
-/**
- * Invoke callback when the response has finished, useful for
- * cleaning up resources afterwards.
- *
- * @param {object} msg
- * @param {function} listener
- * @return {object}
- * @api public
- */
-
-function onFinished(msg, listener) {
- if (isFinished(msg) !== false) {
- defer(listener)
- return msg
- }
-
- // attach the listener to the message
- attachListener(msg, listener)
-
- return msg
-}
-
-/**
- * Determine if message is already finished.
- *
- * @param {object} msg
- * @return {boolean}
- * @api public
- */
-
-function isFinished(msg) {
- var socket = msg.socket
-
- if (typeof msg.finished === 'boolean') {
- // OutgoingMessage
- return Boolean(msg.finished || (socket && !socket.writable))
- }
-
- if (typeof msg.complete === 'boolean') {
- // IncomingMessage
- return Boolean(!socket || msg.complete || !socket.readable)
- }
-
- // don't know
- return undefined
-}
-
-/**
- * Attach a finished listener to the message.
- *
- * @param {object} msg
- * @param {function} callback
- * @private
- */
-
-function attachFinishedListener(msg, callback) {
- var eeMsg
- var eeSocket
- var finished = false
-
- function onFinish(error) {
- eeMsg.cancel()
- eeSocket.cancel()
-
- finished = true
- callback(error)
- }
-
- // finished on first message event
- eeMsg = eeSocket = first([[msg, 'end', 'finish']], onFinish)
-
- function onSocket(socket) {
- // remove listener
- msg.removeListener('socket', onSocket)
-
- if (finished) return
- if (eeMsg !== eeSocket) return
-
- // finished on first socket event
- eeSocket = first([[socket, 'error', 'close']], onFinish)
- }
-
- if (msg.socket) {
- // socket already assigned
- onSocket(msg.socket)
- return
- }
-
- // wait for socket to be assigned
- msg.on('socket', onSocket)
-
- if (msg.socket === undefined) {
- // node.js 0.8 patch
- patchAssignSocket(msg, onSocket)
- }
-}
-
-/**
- * Attach the listener to the message.
- *
- * @param {object} msg
- * @return {function}
- * @api private
- */
-
-function attachListener(msg, listener) {
- var attached = msg.__onFinished
-
- // create a private single listener with queue
- if (!attached || !attached.queue) {
- attached = msg.__onFinished = createListener(msg)
- attachFinishedListener(msg, attached)
- }
-
- attached.queue.push(listener)
-}
-
-/**
- * Create listener on message.
- *
- * @param {object} msg
- * @return {function}
- * @api private
- */
-
-function createListener(msg) {
- function listener(err) {
- if (msg.__onFinished === listener) msg.__onFinished = null
- if (!listener.queue) return
-
- var queue = listener.queue
- listener.queue = null
-
- for (var i = 0; i < queue.length; i++) {
- queue[i](err)
- }
- }
-
- listener.queue = []
-
- return listener
-}
-
-/**
- * Patch ServerResponse.prototype.assignSocket for node.js 0.8.
- *
- * @param {ServerResponse} res
- * @param {function} callback
- * @private
- */
-
-function patchAssignSocket(res, callback) {
- var assignSocket = res.assignSocket
-
- if (typeof assignSocket !== 'function') return
-
- // res.on('socket', callback) is broken in 0.8
- res.assignSocket = function _assignSocket(socket) {
- assignSocket.call(this, socket)
- callback(socket)
- }
-}
diff --git a/CoAuthoring/node_modules/express/node_modules/on-finished/node_modules/ee-first/LICENSE b/CoAuthoring/node_modules/express/node_modules/on-finished/node_modules/ee-first/LICENSE
deleted file mode 100644
index c1b15a1db1..0000000000
--- a/CoAuthoring/node_modules/express/node_modules/on-finished/node_modules/ee-first/LICENSE
+++ /dev/null
@@ -1,22 +0,0 @@
-
-The MIT License (MIT)
-
-Copyright (c) 2014 Jonathan Ong me@jongleberry.com
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in
-all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-THE SOFTWARE.
diff --git a/CoAuthoring/node_modules/express/node_modules/on-finished/node_modules/ee-first/README.md b/CoAuthoring/node_modules/express/node_modules/on-finished/node_modules/ee-first/README.md
deleted file mode 100644
index bb16aabe2d..0000000000
--- a/CoAuthoring/node_modules/express/node_modules/on-finished/node_modules/ee-first/README.md
+++ /dev/null
@@ -1,80 +0,0 @@
-# EE First
-
-[![NPM version][npm-image]][npm-url]
-[![Build status][travis-image]][travis-url]
-[![Test coverage][coveralls-image]][coveralls-url]
-[![License][license-image]][license-url]
-[![Downloads][downloads-image]][downloads-url]
-[![Gittip][gittip-image]][gittip-url]
-
-Get the first event in a set of event emitters and event pairs,
-then clean up after itself.
-
-## Install
-
-```sh
-$ npm install ee-first
-```
-
-## API
-
-```js
-var first = require('ee-first')
-```
-
-### first(arr, listener)
-
-Invoke `listener` on the first event from the list specified in `arr`. `arr` is
-an array of arrays, with each array in the format `[ee, ...event]`. `listener`
-will be called only once, the first time any of the given events are emitted. If
-`error` is one of the listened events, then if that fires first, the `listener`
-will be given the `err` argument.
-
-The `listener` is invoked as `listener(err, ee, event, args)`, where `err` is the
-first argument emitted from an `error` event, if applicable; `ee` is the event
-emitter that fired; `event` is the string event name that fired; and `args` is an
-array of the arguments that were emitted on the event.
-
-```js
-var ee1 = new EventEmitter()
-var ee2 = new EventEmitter()
-
-first([
- [ee1, 'close', 'end', 'error'],
- [ee2, 'error']
-], function (err, ee, event, args) {
- // listener invoked
-})
-```
-
-#### .cancel()
-
-The group of listeners can be cancelled before being invoked and have all the event
-listeners removed from the underlying event emitters.
-
-```js
-var thunk = first([
- [ee1, 'close', 'end', 'error'],
- [ee2, 'error']
-], function (err, ee, event, args) {
- // listener invoked
-})
-
-// cancel and clean up
-thunk.cancel()
-```
-
-[npm-image]: https://img.shields.io/npm/v/ee-first.svg?style=flat-square
-[npm-url]: https://npmjs.org/package/ee-first
-[github-tag]: http://img.shields.io/github/tag/jonathanong/ee-first.svg?style=flat-square
-[github-url]: https://github.com/jonathanong/ee-first/tags
-[travis-image]: https://img.shields.io/travis/jonathanong/ee-first.svg?style=flat-square
-[travis-url]: https://travis-ci.org/jonathanong/ee-first
-[coveralls-image]: https://img.shields.io/coveralls/jonathanong/ee-first.svg?style=flat-square
-[coveralls-url]: https://coveralls.io/r/jonathanong/ee-first?branch=master
-[license-image]: http://img.shields.io/npm/l/ee-first.svg?style=flat-square
-[license-url]: LICENSE.md
-[downloads-image]: http://img.shields.io/npm/dm/ee-first.svg?style=flat-square
-[downloads-url]: https://npmjs.org/package/ee-first
-[gittip-image]: https://img.shields.io/gittip/jonathanong.svg?style=flat-square
-[gittip-url]: https://www.gittip.com/jonathanong/
diff --git a/CoAuthoring/node_modules/express/node_modules/on-finished/node_modules/ee-first/index.js b/CoAuthoring/node_modules/express/node_modules/on-finished/node_modules/ee-first/index.js
deleted file mode 100644
index 1d66203959..0000000000
--- a/CoAuthoring/node_modules/express/node_modules/on-finished/node_modules/ee-first/index.js
+++ /dev/null
@@ -1,68 +0,0 @@
-
-module.exports = function first(stuff, done) {
- if (!Array.isArray(stuff))
- throw new TypeError('arg must be an array of [ee, events...] arrays')
-
- var cleanups = []
-
- for (var i = 0; i < stuff.length; i++) {
- var arr = stuff[i]
-
- if (!Array.isArray(arr) || arr.length < 2)
- throw new TypeError('each array member must be [ee, events...]')
-
- var ee = arr[0]
-
- for (var j = 1; j < arr.length; j++) {
- var event = arr[j]
- var fn = listener(event, callback)
-
- // listen to the event
- ee.on(event, fn)
- // push this listener to the list of cleanups
- cleanups.push({
- ee: ee,
- event: event,
- fn: fn,
- })
- }
- }
-
- function callback() {
- cleanup()
- done.apply(null, arguments)
- }
-
- function cleanup() {
- var x
- for (var i = 0; i < cleanups.length; i++) {
- x = cleanups[i]
- x.ee.removeListener(x.event, x.fn)
- }
- }
-
- function thunk(fn) {
- done = fn
- }
-
- thunk.cancel = cleanup
-
- return thunk
-}
-
-function listener(event, done) {
- return function onevent(arg1) {
- var args = new Array(arguments.length)
- var ee = this
- var err = event === 'error'
- ? arg1
- : null
-
- // copy args to prevent arguments escaping scope
- for (var i = 0; i < args.length; i++) {
- args[i] = arguments[i]
- }
-
- done(err, ee, event, args)
- }
-}
diff --git a/CoAuthoring/node_modules/express/node_modules/on-finished/node_modules/ee-first/package.json b/CoAuthoring/node_modules/express/node_modules/on-finished/node_modules/ee-first/package.json
deleted file mode 100644
index dc3f93ada5..0000000000
--- a/CoAuthoring/node_modules/express/node_modules/on-finished/node_modules/ee-first/package.json
+++ /dev/null
@@ -1,42 +0,0 @@
-{
- "name": "ee-first",
- "description": "return the first event in a set of ee/event pairs",
- "version": "1.1.0",
- "author": {
- "name": "Jonathan Ong",
- "email": "me@jongleberry.com",
- "url": "http://jongleberry.com"
- },
- "contributors": [
- {
- "name": "Douglas Christopher Wilson",
- "email": "doug@somethingdoug.com"
- }
- ],
- "license": "MIT",
- "repository": {
- "type": "git",
- "url": "git://github.com/jonathanong/ee-first"
- },
- "devDependencies": {
- "istanbul": "0.3.2",
- "mocha": "1"
- },
- "files": [
- "index.js",
- "LICENSE"
- ],
- "scripts": {
- "test": "mocha --reporter spec --bail --check-leaks test/",
- "test-cov": "istanbul cover node_modules/mocha/bin/_mocha -- --reporter dot --check-leaks test/",
- "test-travis": "istanbul cover node_modules/mocha/bin/_mocha --report lcovonly -- --reporter spec --check-leaks test/"
- },
- "readme": "# EE First\r\n\r\n[![NPM version][npm-image]][npm-url]\r\n[![Build status][travis-image]][travis-url]\r\n[![Test coverage][coveralls-image]][coveralls-url]\r\n[![License][license-image]][license-url]\r\n[![Downloads][downloads-image]][downloads-url]\r\n[![Gittip][gittip-image]][gittip-url]\r\n\r\nGet the first event in a set of event emitters and event pairs,\r\nthen clean up after itself.\r\n\r\n## Install\r\n\r\n```sh\r\n$ npm install ee-first\r\n```\r\n\r\n## API\r\n\r\n```js\r\nvar first = require('ee-first')\r\n```\r\n\r\n### first(arr, listener)\r\n\r\nInvoke `listener` on the first event from the list specified in `arr`. `arr` is\r\nan array of arrays, with each array in the format `[ee, ...event]`. `listener`\r\nwill be called only once, the first time any of the given events are emitted. If\r\n`error` is one of the listened events, then if that fires first, the `listener`\r\nwill be given the `err` argument.\r\n\r\nThe `listener` is invoked as `listener(err, ee, event, args)`, where `err` is the\r\nfirst argument emitted from an `error` event, if applicable; `ee` is the event\r\nemitter that fired; `event` is the string event name that fired; and `args` is an\r\narray of the arguments that were emitted on the event.\r\n\r\n```js\r\nvar ee1 = new EventEmitter()\r\nvar ee2 = new EventEmitter()\r\n\r\nfirst([\r\n [ee1, 'close', 'end', 'error'],\r\n [ee2, 'error']\r\n], function (err, ee, event, args) {\r\n // listener invoked\r\n})\r\n```\r\n\r\n#### .cancel()\r\n\r\nThe group of listeners can be cancelled before being invoked and have all the event\r\nlisteners removed from the underlying event emitters.\r\n\r\n```js\r\nvar thunk = first([\r\n [ee1, 'close', 'end', 'error'],\r\n [ee2, 'error']\r\n], function (err, ee, event, args) {\r\n // listener invoked\r\n})\r\n\r\n// cancel and clean up\r\nthunk.cancel()\r\n```\r\n\r\n[npm-image]: https://img.shields.io/npm/v/ee-first.svg?style=flat-square\r\n[npm-url]: https://npmjs.org/package/ee-first\r\n[github-tag]: http://img.shields.io/github/tag/jonathanong/ee-first.svg?style=flat-square\r\n[github-url]: https://github.com/jonathanong/ee-first/tags\r\n[travis-image]: https://img.shields.io/travis/jonathanong/ee-first.svg?style=flat-square\r\n[travis-url]: https://travis-ci.org/jonathanong/ee-first\r\n[coveralls-image]: https://img.shields.io/coveralls/jonathanong/ee-first.svg?style=flat-square\r\n[coveralls-url]: https://coveralls.io/r/jonathanong/ee-first?branch=master\r\n[license-image]: http://img.shields.io/npm/l/ee-first.svg?style=flat-square\r\n[license-url]: LICENSE.md\r\n[downloads-image]: http://img.shields.io/npm/dm/ee-first.svg?style=flat-square\r\n[downloads-url]: https://npmjs.org/package/ee-first\r\n[gittip-image]: https://img.shields.io/gittip/jonathanong.svg?style=flat-square\r\n[gittip-url]: https://www.gittip.com/jonathanong/\r\n",
- "readmeFilename": "README.md",
- "bugs": {
- "url": "https://github.com/jonathanong/ee-first/issues"
- },
- "homepage": "https://github.com/jonathanong/ee-first",
- "_id": "ee-first@1.1.0",
- "_from": "ee-first@1.1.0"
-}
diff --git a/CoAuthoring/node_modules/express/node_modules/on-finished/package.json b/CoAuthoring/node_modules/express/node_modules/on-finished/package.json
deleted file mode 100644
index db80510467..0000000000
--- a/CoAuthoring/node_modules/express/node_modules/on-finished/package.json
+++ /dev/null
@@ -1,49 +0,0 @@
-{
- "name": "on-finished",
- "description": "Execute a callback when a request closes, finishes, or errors",
- "version": "2.1.1",
- "contributors": [
- {
- "name": "Douglas Christopher Wilson",
- "email": "doug@somethingdoug.com"
- },
- {
- "name": "Jonathan Ong",
- "email": "me@jongleberry.com",
- "url": "http://jongleberry.com"
- }
- ],
- "license": "MIT",
- "repository": {
- "type": "git",
- "url": "git://github.com/jshttp/on-finished"
- },
- "dependencies": {
- "ee-first": "1.1.0"
- },
- "devDependencies": {
- "istanbul": "0.3.2",
- "mocha": "~2.0.0"
- },
- "engines": {
- "node": ">= 0.8"
- },
- "files": [
- "HISTORY.md",
- "LICENSE",
- "index.js"
- ],
- "scripts": {
- "test": "mocha --reporter spec --bail --check-leaks test/",
- "test-cov": "istanbul cover node_modules/mocha/bin/_mocha -- --reporter dot --check-leaks test/",
- "test-travis": "istanbul cover node_modules/mocha/bin/_mocha --report lcovonly -- --reporter spec --check-leaks test/"
- },
- "readme": "# on-finished\n\n[![NPM Version][npm-image]][npm-url]\n[![NPM Downloads][downloads-image]][downloads-url]\n[![Node.js Version][node-version-image]][node-version-url]\n[![Build Status][travis-image]][travis-url]\n[![Test Coverage][coveralls-image]][coveralls-url]\n\nExecute a callback when a request closes, finishes, or errors.\n\n## Install\n\n```sh\n$ npm install on-finished\n```\n\n## API\n\n```js\nvar onFinished = require('on-finished')\n```\n\n### onFinished(res, listener)\n\nAttach a listener to listen for the response to finish. The listener will\nbe invoked only once when the response finished. If the response finished\nto to an error, the first argument will contain the error.\n\nListening to the end of a response would be used to close things associated\nwith the response, like open files.\n\n```js\nonFinished(res, function (err) {\n // clean up open fds, etc.\n})\n```\n\n### onFinished(req, listener)\n\nAttach a listener to listen for the request to finish. The listener will\nbe invoked only once when the request finished. If the request finished\nto to an error, the first argument will contain the error.\n\nListening to the end of a request would be used to know when to continue\nafter reading the data.\n\n```js\nvar data = ''\n\nreq.setEncoding('utf8')\nres.on('data', function (str) {\n data += str\n})\n\nonFinished(req, function (err) {\n // data is read unless there is err\n})\n```\n\n### onFinished.isFinished(res)\n\nDetermine if `res` is already finished. This would be useful to check and\nnot even start certain operations if the response has already finished.\n\n### onFinished.isFinished(req)\n\nDetermine if `req` is already finished. This would be useful to check and\nnot even start certain operations if the request has already finished.\n\n### Example\n\nThe following code ensures that file descriptors are always closed\nonce the response finishes.\n\n```js\nvar destroy = require('destroy')\nvar http = require('http')\nvar onFinished = require('on-finished')\n\nhttp.createServer(function onRequest(req, res) {\n var stream = fs.createReadStream('package.json')\n stream.pipe(res)\n onFinished(res, function (err) {\n destroy(stream)\n })\n})\n```\n\n## License\n\n[MIT](LICENSE)\n\n[npm-image]: https://img.shields.io/npm/v/on-finished.svg?style=flat\n[npm-url]: https://npmjs.org/package/on-finished\n[node-version-image]: https://img.shields.io/node/v/on-finished.svg?style=flat\n[node-version-url]: http://nodejs.org/download/\n[travis-image]: https://img.shields.io/travis/jshttp/on-finished.svg?style=flat\n[travis-url]: https://travis-ci.org/jshttp/on-finished\n[coveralls-image]: https://img.shields.io/coveralls/jshttp/on-finished.svg?style=flat\n[coveralls-url]: https://coveralls.io/r/jshttp/on-finished?branch=master\n[downloads-image]: https://img.shields.io/npm/dm/on-finished.svg?style=flat\n[downloads-url]: https://npmjs.org/package/on-finished\n",
- "readmeFilename": "README.md",
- "bugs": {
- "url": "https://github.com/jshttp/on-finished/issues"
- },
- "homepage": "https://github.com/jshttp/on-finished",
- "_id": "on-finished@2.1.1",
- "_from": "on-finished@~2.1.0"
-}
diff --git a/CoAuthoring/node_modules/express/node_modules/parseurl/.npmignore b/CoAuthoring/node_modules/express/node_modules/parseurl/.npmignore
deleted file mode 100644
index 85c82a5607..0000000000
--- a/CoAuthoring/node_modules/express/node_modules/parseurl/.npmignore
+++ /dev/null
@@ -1,4 +0,0 @@
-benchmark/
-coverage/
-test/
-.travis.yml
diff --git a/CoAuthoring/node_modules/express/node_modules/parseurl/HISTORY.md b/CoAuthoring/node_modules/express/node_modules/parseurl/HISTORY.md
deleted file mode 100644
index 65a0860682..0000000000
--- a/CoAuthoring/node_modules/express/node_modules/parseurl/HISTORY.md
+++ /dev/null
@@ -1,42 +0,0 @@
-1.3.0 / 2014-08-09
-==================
-
- * Add `parseurl.original` for parsing `req.originalUrl` with fallback
- * Return `undefined` if `req.url` is `undefined`
-
-1.2.0 / 2014-07-21
-==================
-
- * Cache URLs based on original value
- * Remove no-longer-needed URL mis-parse work-around
- * Simplify the "fast-path" `RegExp`
-
-1.1.3 / 2014-07-08
-==================
-
- * Fix typo
-
-1.1.2 / 2014-07-08
-==================
-
- * Seriously fix Node.js 0.8 compatibility
-
-1.1.1 / 2014-07-08
-==================
-
- * Fix Node.js 0.8 compatibility
-
-1.1.0 / 2014-07-08
-==================
-
- * Incorporate URL href-only parse fast-path
-
-1.0.1 / 2014-03-08
-==================
-
- * Add missing `require`
-
-1.0.0 / 2014-03-08
-==================
-
- * Genesis from `connect`
diff --git a/CoAuthoring/node_modules/express/node_modules/parseurl/LICENSE b/CoAuthoring/node_modules/express/node_modules/parseurl/LICENSE
deleted file mode 100644
index ec7dfe7be9..0000000000
--- a/CoAuthoring/node_modules/express/node_modules/parseurl/LICENSE
+++ /dev/null
@@ -1,24 +0,0 @@
-
-(The MIT License)
-
-Copyright (c) 2014 Jonathan Ong
-Copyright (c) 2014 Douglas Christopher Wilson
-
-Permission is hereby granted, free of charge, to any person obtaining
-a copy of this software and associated documentation files (the
-'Software'), to deal in the Software without restriction, including
-without limitation the rights to use, copy, modify, merge, publish,
-distribute, sublicense, and/or sell copies of the Software, and to
-permit persons to whom the Software is furnished to do so, subject to
-the following conditions:
-
-The above copyright notice and this permission notice shall be
-included in all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
-EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
-IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
-CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
-TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
-SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
diff --git a/CoAuthoring/node_modules/express/node_modules/parseurl/README.md b/CoAuthoring/node_modules/express/node_modules/parseurl/README.md
deleted file mode 100644
index 0db1d029f7..0000000000
--- a/CoAuthoring/node_modules/express/node_modules/parseurl/README.md
+++ /dev/null
@@ -1,107 +0,0 @@
-# parseurl
-
-[](http://badge.fury.io/js/parseurl)
-[](https://travis-ci.org/expressjs/parseurl)
-[](https://coveralls.io/r/expressjs/parseurl)
-
-Parse a URL with memoization.
-
-## Install
-
-```bash
-$ npm install parseurl
-```
-
-## API
-
-```js
-var parseurl = require('parseurl')
-```
-
-### parseurl(req)
-
-Parse the URL of the given request object (looks at the `req.url` property)
-and return the result. The result is the same as `url.parse` in Node.js core.
-Calling this function multiple times on the same `req` where `req.url` does
-not change will return a cached parsed object, rather than parsing again.
-
-### parseurl.original(req)
-
-Parse the original URL of the given request object and return the result.
-This works by trying to parse `req.originalUrl` if it is a string, otherwise
-parses `req.url`. The result is the same as `url.parse` in Node.js core.
-Calling this function multiple times on the same `req` where `req.originalUrl`
-does not change will return a cached parsed object, rather than parsing again.
-
-## Benchmark
-
-```bash
-$ npm run-script bench
-
-> parseurl@1.3.0 bench nodejs-parseurl
-> node benchmark/index.js
-
-> node benchmark/fullurl.js
-
- Parsing URL "http://localhost:8888/foo/bar?user=tj&pet=fluffy"
-
- 1 test completed.
- 2 tests completed.
- 3 tests completed.
-
- fasturl x 1,290,780 ops/sec ±0.46% (195 runs sampled)
- nativeurl x 56,401 ops/sec ±0.22% (196 runs sampled)
- parseurl x 55,231 ops/sec ±0.22% (194 runs sampled)
-
-> node benchmark/pathquery.js
-
- Parsing URL "/foo/bar?user=tj&pet=fluffy"
-
- 1 test completed.
- 2 tests completed.
- 3 tests completed.
-
- fasturl x 1,986,668 ops/sec ±0.27% (190 runs sampled)
- nativeurl x 98,740 ops/sec ±0.21% (195 runs sampled)
- parseurl x 2,628,171 ops/sec ±0.36% (195 runs sampled)
-
-> node benchmark/samerequest.js
-
- Parsing URL "/foo/bar?user=tj&pet=fluffy" on same request object
-
- 1 test completed.
- 2 tests completed.
- 3 tests completed.
-
- fasturl x 2,184,468 ops/sec ±0.40% (194 runs sampled)
- nativeurl x 99,437 ops/sec ±0.71% (194 runs sampled)
- parseurl x 10,498,005 ops/sec ±0.61% (186 runs sampled)
-
-> node benchmark/simplepath.js
-
- Parsing URL "/foo/bar"
-
- 1 test completed.
- 2 tests completed.
- 3 tests completed.
-
- fasturl x 4,535,825 ops/sec ±0.27% (191 runs sampled)
- nativeurl x 98,769 ops/sec ±0.54% (191 runs sampled)
- parseurl x 4,164,865 ops/sec ±0.34% (192 runs sampled)
-
-> node benchmark/slash.js
-
- Parsing URL "/"
-
- 1 test completed.
- 2 tests completed.
- 3 tests completed.
-
- fasturl x 4,908,405 ops/sec ±0.42% (191 runs sampled)
- nativeurl x 100,945 ops/sec ±0.59% (188 runs sampled)
- parseurl x 4,333,208 ops/sec ±0.27% (194 runs sampled)
-```
-
-## License
-
- [MIT](LICENSE)
diff --git a/CoAuthoring/node_modules/express/node_modules/parseurl/index.js b/CoAuthoring/node_modules/express/node_modules/parseurl/index.js
deleted file mode 100644
index 8632347278..0000000000
--- a/CoAuthoring/node_modules/express/node_modules/parseurl/index.js
+++ /dev/null
@@ -1,136 +0,0 @@
-/*!
- * parseurl
- * Copyright(c) 2014 Jonathan Ong
- * Copyright(c) 2014 Douglas Christopher Wilson
- * MIT Licensed
- */
-
-/**
- * Module dependencies.
- */
-
-var url = require('url')
-var parse = url.parse
-var Url = url.Url
-
-/**
- * Pattern for a simple path case.
- * See: https://github.com/joyent/node/pull/7878
- */
-
-var simplePathRegExp = /^(\/\/?(?!\/)[^\?#\s]*)(\?[^#\s]*)?$/
-
-/**
- * Exports.
- */
-
-module.exports = parseurl
-module.exports.original = originalurl
-
-/**
- * Parse the `req` url with memoization.
- *
- * @param {ServerRequest} req
- * @return {Object}
- * @api public
- */
-
-function parseurl(req) {
- var url = req.url
-
- if (url === undefined) {
- // URL is undefined
- return undefined
- }
-
- var parsed = req._parsedUrl
-
- if (fresh(url, parsed)) {
- // Return cached URL parse
- return parsed
- }
-
- // Parse the URL
- parsed = fastparse(url)
- parsed._raw = url
-
- return req._parsedUrl = parsed
-};
-
-/**
- * Parse the `req` original url with fallback and memoization.
- *
- * @param {ServerRequest} req
- * @return {Object}
- * @api public
- */
-
-function originalurl(req) {
- var url = req.originalUrl
-
- if (typeof url !== 'string') {
- // Fallback
- return parseurl(req)
- }
-
- var parsed = req._parsedOriginalUrl
-
- if (fresh(url, parsed)) {
- // Return cached URL parse
- return parsed
- }
-
- // Parse the URL
- parsed = fastparse(url)
- parsed._raw = url
-
- return req._parsedOriginalUrl = parsed
-};
-
-/**
- * Parse the `str` url with fast-path short-cut.
- *
- * @param {string} str
- * @return {Object}
- * @api private
- */
-
-function fastparse(str) {
- // Try fast path regexp
- // See: https://github.com/joyent/node/pull/7878
- var simplePath = typeof str === 'string' && simplePathRegExp.exec(str)
-
- // Construct simple URL
- if (simplePath) {
- var pathname = simplePath[1]
- var search = simplePath[2] || null
- var url = Url !== undefined
- ? new Url()
- : {}
- url.path = str
- url.href = str
- url.pathname = pathname
- url.search = search
- url.query = search && search.substr(1)
-
- return url
- }
-
- return parse(str)
-}
-
-/**
- * Determine if parsed is still fresh for url.
- *
- * @param {string} url
- * @param {object} parsedUrl
- * @return {boolean}
- * @api private
- */
-
-function fresh(url, parsedUrl) {
- return typeof parsedUrl === 'object'
- && parsedUrl !== null
- && (Url === undefined || parsedUrl instanceof Url)
- && parsedUrl._raw === url
-}
diff --git a/CoAuthoring/node_modules/express/node_modules/parseurl/package.json b/CoAuthoring/node_modules/express/node_modules/parseurl/package.json
deleted file mode 100644
index c23a63da83..0000000000
--- a/CoAuthoring/node_modules/express/node_modules/parseurl/package.json
+++ /dev/null
@@ -1,42 +0,0 @@
-{
- "name": "parseurl",
- "description": "parse a url with memoization",
- "version": "1.3.0",
- "author": {
- "name": "Jonathan Ong",
- "email": "me@jongleberry.com",
- "url": "http://jongleberry.com"
- },
- "contributors": [
- {
- "name": "Douglas Christopher Wilson",
- "email": "doug@somethingdoug.com"
- }
- ],
- "repository": {
- "type": "git",
- "url": "git://github.com/expressjs/parseurl"
- },
- "license": "MIT",
- "devDependencies": {
- "benchmark": "1.0.0",
- "beautify-benchmark": "0.2.4",
- "fast-url-parser": "~1.0.0",
- "istanbul": "0.3.0",
- "mocha": "~1.21.4"
- },
- "scripts": {
- "bench": "node benchmark/index.js",
- "test": "mocha --check-leaks --bail --reporter spec test/",
- "test-cov": "istanbul cover node_modules/mocha/bin/_mocha -- --check-leaks --reporter dot test/",
- "test-travis": "istanbul cover node_modules/mocha/bin/_mocha --report lcovonly -- --check-leaks --reporter spec test/"
- },
- "readme": "# parseurl\n\n[](http://badge.fury.io/js/parseurl)\n[](https://travis-ci.org/expressjs/parseurl)\n[](https://coveralls.io/r/expressjs/parseurl)\n\nParse a URL with memoization.\n\n## Install\n\n```bash\n$ npm install parseurl\n```\n\n## API\n\n```js\nvar parseurl = require('parseurl')\n```\n\n### parseurl(req)\n\nParse the URL of the given request object (looks at the `req.url` property)\nand return the result. The result is the same as `url.parse` in Node.js core.\nCalling this function multiple times on the same `req` where `req.url` does\nnot change will return a cached parsed object, rather than parsing again.\n\n### parseurl.original(req)\n\nParse the original URL of the given request object and return the result.\nThis works by trying to parse `req.originalUrl` if it is a string, otherwise\nparses `req.url`. The result is the same as `url.parse` in Node.js core.\nCalling this function multiple times on the same `req` where `req.originalUrl`\ndoes not change will return a cached parsed object, rather than parsing again.\n\n## Benchmark\n\n```bash\n$ npm run-script bench\n\n> parseurl@1.3.0 bench nodejs-parseurl\n> node benchmark/index.js\n\n> node benchmark/fullurl.js\n\n Parsing URL \"http://localhost:8888/foo/bar?user=tj&pet=fluffy\"\n\n 1 test completed.\n 2 tests completed.\n 3 tests completed.\n\n fasturl x 1,290,780 ops/sec ±0.46% (195 runs sampled)\n nativeurl x 56,401 ops/sec ±0.22% (196 runs sampled)\n parseurl x 55,231 ops/sec ±0.22% (194 runs sampled)\n\n> node benchmark/pathquery.js\n\n Parsing URL \"/foo/bar?user=tj&pet=fluffy\"\n\n 1 test completed.\n 2 tests completed.\n 3 tests completed.\n\n fasturl x 1,986,668 ops/sec ±0.27% (190 runs sampled)\n nativeurl x 98,740 ops/sec ±0.21% (195 runs sampled)\n parseurl x 2,628,171 ops/sec ±0.36% (195 runs sampled)\n\n> node benchmark/samerequest.js\n\n Parsing URL \"/foo/bar?user=tj&pet=fluffy\" on same request object\n\n 1 test completed.\n 2 tests completed.\n 3 tests completed.\n\n fasturl x 2,184,468 ops/sec ±0.40% (194 runs sampled)\n nativeurl x 99,437 ops/sec ±0.71% (194 runs sampled)\n parseurl x 10,498,005 ops/sec ±0.61% (186 runs sampled)\n\n> node benchmark/simplepath.js\n\n Parsing URL \"/foo/bar\"\n\n 1 test completed.\n 2 tests completed.\n 3 tests completed.\n\n fasturl x 4,535,825 ops/sec ±0.27% (191 runs sampled)\n nativeurl x 98,769 ops/sec ±0.54% (191 runs sampled)\n parseurl x 4,164,865 ops/sec ±0.34% (192 runs sampled)\n\n> node benchmark/slash.js\n\n Parsing URL \"/\"\n\n 1 test completed.\n 2 tests completed.\n 3 tests completed.\n\n fasturl x 4,908,405 ops/sec ±0.42% (191 runs sampled)\n nativeurl x 100,945 ops/sec ±0.59% (188 runs sampled)\n parseurl x 4,333,208 ops/sec ±0.27% (194 runs sampled)\n```\n\n## License\n\n [MIT](LICENSE)\n",
- "readmeFilename": "README.md",
- "bugs": {
- "url": "https://github.com/expressjs/parseurl/issues"
- },
- "homepage": "https://github.com/expressjs/parseurl",
- "_id": "parseurl@1.3.0",
- "_from": "parseurl@~1.3.0"
-}
diff --git a/CoAuthoring/node_modules/express/node_modules/path-to-regexp/.npmignore b/CoAuthoring/node_modules/express/node_modules/path-to-regexp/.npmignore
deleted file mode 100644
index ba2a97b57a..0000000000
--- a/CoAuthoring/node_modules/express/node_modules/path-to-regexp/.npmignore
+++ /dev/null
@@ -1,2 +0,0 @@
-node_modules
-coverage
diff --git a/CoAuthoring/node_modules/express/node_modules/path-to-regexp/History.md b/CoAuthoring/node_modules/express/node_modules/path-to-regexp/History.md
deleted file mode 100644
index f962cfad3c..0000000000
--- a/CoAuthoring/node_modules/express/node_modules/path-to-regexp/History.md
+++ /dev/null
@@ -1,16 +0,0 @@
-0.1.3 / 2014-07-06
-==================
-
- * Better array support
- * Improved support for trailing slash in non-ending mode
-
-0.1.0 / 2014-03-06
-==================
-
- * add options.end
-
-0.0.2 / 2013-02-10
-==================
-
- * Update to match current express
- * add .license property to component.json
diff --git a/CoAuthoring/node_modules/express/node_modules/path-to-regexp/Readme.md b/CoAuthoring/node_modules/express/node_modules/path-to-regexp/Readme.md
deleted file mode 100644
index 9199e38769..0000000000
--- a/CoAuthoring/node_modules/express/node_modules/path-to-regexp/Readme.md
+++ /dev/null
@@ -1,33 +0,0 @@
-
-# Path-to-RegExp
-
- Turn an Express-style path string such as `/user/:name` into a regular expression.
-
-## Usage
-
-```javascript
-var pathToRegexp = require('path-to-regexp');
-```
-### pathToRegexp(path, keys, options)
-
- - **path** A string in the express format, an array of such strings, or a regular expression
- - **keys** An array to be populated with the keys present in the url. Once the function completes, this will be an array of strings.
- - **options**
- - **options.sensitive** Defaults to false, set this to true to make routes case sensitive
- - **options.strict** Defaults to false, set this to true to make the trailing slash matter.
- - **options.end** Defaults to true, set this to false to only match the prefix of the URL.
-
-```javascript
-var keys = [];
-var exp = pathToRegexp('/foo/:bar', keys);
-//keys = ['bar']
-//exp = /^\/foo\/(?:([^\/]+?))\/?$/i
-```
-
-## Live Demo
-
-You can see a live demo of this library in use at [express-route-tester](http://forbeslindesay.github.com/express-route-tester/).
-
-## License
-
- MIT
\ No newline at end of file
diff --git a/CoAuthoring/node_modules/express/node_modules/path-to-regexp/component.json b/CoAuthoring/node_modules/express/node_modules/path-to-regexp/component.json
deleted file mode 100644
index 6ab37d366b..0000000000
--- a/CoAuthoring/node_modules/express/node_modules/path-to-regexp/component.json
+++ /dev/null
@@ -1,15 +0,0 @@
-{
- "name": "path-to-regexp",
- "description": "Express style path to RegExp utility",
- "version": "0.1.3",
- "keywords": [
- "express",
- "regexp",
- "route",
- "routing"
- ],
- "scripts": [
- "index.js"
- ],
- "license": "MIT"
-}
diff --git a/CoAuthoring/node_modules/express/node_modules/path-to-regexp/index.js b/CoAuthoring/node_modules/express/node_modules/path-to-regexp/index.js
deleted file mode 100644
index 2801f91468..0000000000
--- a/CoAuthoring/node_modules/express/node_modules/path-to-regexp/index.js
+++ /dev/null
@@ -1,70 +0,0 @@
-/**
- * Expose `pathtoRegexp`.
- */
-
-module.exports = pathtoRegexp;
-
-/**
- * Normalize the given path string,
- * returning a regular expression.
- *
- * An empty array should be passed,
- * which will contain the placeholder
- * key names. For example "/user/:id" will
- * then contain ["id"].
- *
- * @param {String|RegExp|Array} path
- * @param {Array} keys
- * @param {Object} options
- * @return {RegExp}
- * @api private
- */
-
-function pathtoRegexp(path, keys, options) {
- options = options || {};
- var strict = options.strict;
- var end = options.end !== false;
- var flags = options.sensitive ? '' : 'i';
- keys = keys || [];
-
- if (path instanceof RegExp) {
- return path;
- }
-
- if (Array.isArray(path)) {
- // Map array parts into regexps and return their source. We also pass
- // the same keys and options instance into every generation to get
- // consistent matching groups before we join the sources together.
- path = path.map(function (value) {
- return pathtoRegexp(value, keys, options).source;
- });
-
- return new RegExp('(?:' + path.join('|') + ')', flags);
- }
-
- path = ('^' + path + (strict ? '' : path[path.length - 1] === '/' ? '?' : '/?'))
- .replace(/\/\(/g, '/(?:')
- .replace(/([\/\.])/g, '\\$1')
- .replace(/(\\\/)?(\\\.)?:(\w+)(\(.*?\))?(\*)?(\?)?/g, function (match, slash, format, key, capture, star, optional) {
- slash = slash || '';
- format = format || '';
- capture = capture || '([^\\/' + format + ']+?)';
- optional = optional || '';
-
- keys.push({ name: key, optional: !!optional });
-
- return ''
- + (optional ? '' : slash)
- + '(?:'
- + format + (optional ? slash : '') + capture
- + (star ? '((?:[\\/' + format + '].+?)?)' : '')
- + ')'
- + optional;
- })
- .replace(/\*/g, '(.*)');
-
- // If the path is non-ending, match until the end or a slash.
- path += (end ? '$' : (path[path.length - 1] === '/' ? '' : '(?=\\/|$)'));
-
- return new RegExp(path, flags);
-};
diff --git a/CoAuthoring/node_modules/express/node_modules/path-to-regexp/package.json b/CoAuthoring/node_modules/express/node_modules/path-to-regexp/package.json
deleted file mode 100644
index f1ff62399b..0000000000
--- a/CoAuthoring/node_modules/express/node_modules/path-to-regexp/package.json
+++ /dev/null
@@ -1,33 +0,0 @@
-{
- "name": "path-to-regexp",
- "description": "Express style path to RegExp utility",
- "version": "0.1.3",
- "scripts": {
- "test": "istanbul cover _mocha -- -R spec"
- },
- "keywords": [
- "express",
- "regexp"
- ],
- "component": {
- "scripts": {
- "path-to-regexp": "index.js"
- }
- },
- "repository": {
- "type": "git",
- "url": "https://github.com/component/path-to-regexp.git"
- },
- "devDependencies": {
- "mocha": "^1.17.1",
- "istanbul": "^0.2.6"
- },
- "readme": "\n# Path-to-RegExp\n\n Turn an Express-style path string such as `/user/:name` into a regular expression.\n\n## Usage\n\n```javascript\nvar pathToRegexp = require('path-to-regexp');\n```\n### pathToRegexp(path, keys, options)\n\n - **path** A string in the express format, an array of such strings, or a regular expression\n - **keys** An array to be populated with the keys present in the url. Once the function completes, this will be an array of strings.\n - **options**\n - **options.sensitive** Defaults to false, set this to true to make routes case sensitive\n - **options.strict** Defaults to false, set this to true to make the trailing slash matter.\n - **options.end** Defaults to true, set this to false to only match the prefix of the URL.\n\n```javascript\nvar keys = [];\nvar exp = pathToRegexp('/foo/:bar', keys);\n//keys = ['bar']\n//exp = /^\\/foo\\/(?:([^\\/]+?))\\/?$/i\n```\n\n## Live Demo\n\nYou can see a live demo of this library in use at [express-route-tester](http://forbeslindesay.github.com/express-route-tester/).\n\n## License\n\n MIT",
- "readmeFilename": "Readme.md",
- "bugs": {
- "url": "https://github.com/component/path-to-regexp/issues"
- },
- "homepage": "https://github.com/component/path-to-regexp",
- "_id": "path-to-regexp@0.1.3",
- "_from": "path-to-regexp@0.1.3"
-}
diff --git a/CoAuthoring/node_modules/express/node_modules/path-to-regexp/test.js b/CoAuthoring/node_modules/express/node_modules/path-to-regexp/test.js
deleted file mode 100644
index 4a0c270973..0000000000
--- a/CoAuthoring/node_modules/express/node_modules/path-to-regexp/test.js
+++ /dev/null
@@ -1,616 +0,0 @@
-var pathToRegExp = require('./');
-var assert = require('assert');
-
-describe('path-to-regexp', function () {
- describe('strings', function () {
- it('should match simple paths', function () {
- var params = [];
- var m = pathToRegExp('/test', params).exec('/test');
-
- assert.equal(params.length, 0);
-
- assert.equal(m.length, 1);
- assert.equal(m[0], '/test');
- });
-
- it('should match express format params', function () {
- var params = [];
- var m = pathToRegExp('/:test', params).exec('/pathname');
-
- assert.equal(params.length, 1);
- assert.equal(params[0].name, 'test');
- assert.equal(params[0].optional, false);
-
- assert.equal(m.length, 2);
- assert.equal(m[0], '/pathname');
- assert.equal(m[1], 'pathname');
- });
-
- it('should do strict matches', function () {
- var params = [];
- var re = pathToRegExp('/:test', params, { strict: true });
- var m;
-
- assert.equal(params.length, 1);
- assert.equal(params[0].name, 'test');
- assert.equal(params[0].optional, false);
-
- m = re.exec('/route');
-
- assert.equal(m.length, 2);
- assert.equal(m[0], '/route');
- assert.equal(m[1], 'route');
-
- m = re.exec('/route/');
-
- assert.ok(!m);
- });
-
- it('should do strict matches with trailing slashes', function () {
- var params = [];
- var re = pathToRegExp('/:test/', params, { strict: true });
- var m;
-
- assert.equal(params.length, 1);
- assert.equal(params[0].name, 'test');
- assert.equal(params[0].optional, false);
-
- m = re.exec('/route');
-
- assert.ok(!m);
-
- m = re.exec('/route/');
-
- assert.equal(m.length, 2);
- assert.equal(m[0], '/route/');
- assert.equal(m[1], 'route');
-
- m = re.exec('/route//');
-
- assert.ok(!m);
- });
-
- it('should allow optional express format params', function () {
- var params = [];
- var re = pathToRegExp('/:test?', params);
- var m;
-
- assert.equal(params.length, 1);
- assert.equal(params[0].name, 'test');
- assert.equal(params[0].optional, true);
-
- m = re.exec('/route');
-
- assert.equal(m.length, 2);
- assert.equal(m[0], '/route');
- assert.equal(m[1], 'route');
-
- m = re.exec('/');
-
- assert.equal(m.length, 2);
- assert.equal(m[0], '/');
- assert.equal(m[1], undefined);
- });
-
- it('should allow express format param regexps', function () {
- var params = [];
- var m = pathToRegExp('/:page(\\d+)', params).exec('/56');
-
- assert.equal(params.length, 1);
- assert.equal(params[0].name, 'page');
- assert.equal(params[0].optional, false);
-
- assert.equal(m.length, 2);
- assert.equal(m[0], '/56');
- assert.equal(m[1], '56');
- });
-
- it('should match without a prefixed slash', function () {
- var params = [];
- var m = pathToRegExp(':test', params).exec('string');
-
- assert.equal(params.length, 1);
- assert.equal(params[0].name, 'test');
- assert.equal(params[0].optional, false);
-
- assert.equal(m.length, 2);
- assert.equal(m[0], 'string');
- assert.equal(m[1], 'string');
- });
-
- it('should not match format parts', function () {
- var params = [];
- var m = pathToRegExp('/:test.json', params).exec('/route.json');
-
- assert.equal(params.length, 1);
- assert.equal(params[0].name, 'test');
- assert.equal(params[0].optional, false);
-
- assert.equal(m.length, 2);
- assert.equal(m[0], '/route.json');
- assert.equal(m[1], 'route');
- });
-
- it('should match format parts', function () {
- var params = [];
- var re = pathToRegExp('/:test.:format', params);
- var m;
-
- assert.equal(params.length, 2);
- assert.equal(params[0].name, 'test');
- assert.equal(params[0].optional, false);
- assert.equal(params[1].name, 'format');
- assert.equal(params[1].optional, false);
-
- m = re.exec('/route.json');
-
- assert.equal(m.length, 3);
- assert.equal(m[0], '/route.json');
- assert.equal(m[1], 'route');
- assert.equal(m[2], 'json');
-
- m = re.exec('/route');
-
- assert.ok(!m);
- });
-
- it('should match route parts with a trailing format', function () {
- var params = [];
- var m = pathToRegExp('/:test.json', params).exec('/route.json');
-
- assert.equal(params.length, 1);
- assert.equal(params[0].name, 'test');
- assert.equal(params[0].optional, false);
-
- assert.equal(m.length, 2);
- assert.equal(m[0], '/route.json');
- assert.equal(m[1], 'route');
- });
-
- it('should match optional trailing routes', function () {
- var params = [];
- var m = pathToRegExp('/test*', params).exec('/test/route');
-
- assert.equal(params.length, 0);
-
- assert.equal(m.length, 2);
- assert.equal(m[0], '/test/route');
- assert.equal(m[1], '/route');
- });
-
- it('should match optional trailing routes after a param', function () {
- var params = [];
- var re = pathToRegExp('/:test*', params);
- var m;
-
- assert.equal(params.length, 1);
- assert.equal(params[0].name, 'test');
- assert.equal(params[0].optional, false);
-
- m = re.exec('/test/route');
-
- assert.equal(m.length, 3);
- assert.equal(m[0], '/test/route');
- assert.equal(m[1], 'test');
- assert.equal(m[2], '/route');
-
- m = re.exec('/testing');
-
- assert.equal(m.length, 3);
- assert.equal(m[0], '/testing');
- assert.equal(m[1], 'testing');
- assert.equal(m[2], '');
- });
-
- it('should match optional trailing routes before a format', function () {
- var params = [];
- var re = pathToRegExp('/test*.json', params);
- var m;
-
- assert.equal(params.length, 0);
-
- m = re.exec('/test.json');
-
- assert.equal(m.length, 2);
- assert.equal(m[0], '/test.json');
- assert.equal(m[1], '');
-
- m = re.exec('/testing.json');
-
- assert.equal(m.length, 2);
- assert.equal(m[0], '/testing.json');
- assert.equal(m[1], 'ing');
-
- m = re.exec('/test/route.json');
-
- assert.equal(m.length, 2);
- assert.equal(m[0], '/test/route.json');
- assert.equal(m[1], '/route');
- });
-
- it('should match optional trailing routes after a param and before a format', function () {
- var params = [];
- var re = pathToRegExp('/:test*.json', params);
- var m;
-
- assert.equal(params.length, 1);
- assert.equal(params[0].name, 'test');
- assert.equal(params[0].optional, false);
-
- m = re.exec('/testing.json');
-
- assert.equal(m.length, 3);
- assert.equal(m[0], '/testing.json');
- assert.equal(m[1], 'testing');
- assert.equal(m[2], '');
-
- m = re.exec('/test/route.json');
-
- assert.equal(m.length, 3);
- assert.equal(m[0], '/test/route.json');
- assert.equal(m[1], 'test');
- assert.equal(m[2], '/route');
-
- m = re.exec('.json');
-
- assert.ok(!m);
- });
-
- it('should match optional trailing routes between a normal param and a format param', function () {
- var params = [];
- var re = pathToRegExp('/:test*.:format', params);
- var m;
-
- assert.equal(params.length, 2);
- assert.equal(params[0].name, 'test');
- assert.equal(params[0].optional, false);
- assert.equal(params[1].name, 'format');
- assert.equal(params[1].optional, false);
-
- m = re.exec('/testing.json');
-
- assert.equal(m.length, 4);
- assert.equal(m[0], '/testing.json');
- assert.equal(m[1], 'testing');
- assert.equal(m[2], '');
- assert.equal(m[3], 'json');
-
- m = re.exec('/test/route.json');
-
- assert.equal(m.length, 4);
- assert.equal(m[0], '/test/route.json');
- assert.equal(m[1], 'test');
- assert.equal(m[2], '/route');
- assert.equal(m[3], 'json');
-
- m = re.exec('/test');
-
- assert.ok(!m);
-
- m = re.exec('.json');
-
- assert.ok(!m);
- });
-
- it('should match optional trailing routes after a param and before an optional format param', function () {
- var params = [];
- var re = pathToRegExp('/:test*.:format?', params);
- var m;
-
- assert.equal(params.length, 2);
- assert.equal(params[0].name, 'test');
- assert.equal(params[0].optional, false);
- assert.equal(params[1].name, 'format');
- assert.equal(params[1].optional, true);
-
- m = re.exec('/testing.json');
-
- assert.equal(m.length, 4);
- assert.equal(m[0], '/testing.json');
- assert.equal(m[1], 'testing');
- assert.equal(m[2], '');
- assert.equal(m[3], 'json');
-
- m = re.exec('/test/route.json');
-
- assert.equal(m.length, 4);
- assert.equal(m[0], '/test/route.json');
- assert.equal(m[1], 'test');
- assert.equal(m[2], '/route');
- assert.equal(m[3], 'json');
-
- m = re.exec('/test');
-
- assert.equal(m.length, 4);
- assert.equal(m[0], '/test');
- assert.equal(m[1], 'test');
- assert.equal(m[2], '');
- assert.equal(m[3], undefined);
-
- m = re.exec('.json');
-
- assert.ok(!m);
- });
-
- it('should match optional trailing routes inside optional express param', function () {
- var params = [];
- var re = pathToRegExp('/:test*?', params);
- var m;
-
- assert.equal(params.length, 1);
- assert.equal(params[0].name, 'test');
- assert.equal(params[0].optional, true);
-
- m = re.exec('/test/route');
-
- assert.equal(m.length, 3);
- assert.equal(m[0], '/test/route');
- assert.equal(m[1], 'test');
- assert.equal(m[2], '/route');
-
- m = re.exec('/test');
-
- assert.equal(m.length, 3);
- assert.equal(m[0], '/test');
- assert.equal(m[1], 'test');
- assert.equal(m[2], '');
-
- m = re.exec('/');
-
- assert.equal(m.length, 3);
- assert.equal(m[0], '/');
- assert.equal(m[1], undefined);
- assert.equal(m[2], undefined);
- });
-
- it('should do case insensitive matches', function () {
- var m = pathToRegExp('/test').exec('/TEST');
-
- assert.equal(m[0], '/TEST');
- });
-
- it('should do case sensitive matches', function () {
- var re = pathToRegExp('/test', null, { sensitive: true });
- var m;
-
- m = re.exec('/test');
-
- assert.equal(m.length, 1);
- assert.equal(m[0], '/test');
-
- m = re.exec('/TEST');
-
- assert.ok(!m);
- });
-
- it('should do non-ending matches', function () {
- var params = [];
- var m = pathToRegExp('/:test', params, { end: false }).exec('/test/route');
-
- assert.equal(params.length, 1);
- assert.equal(params[0].name, 'test');
- assert.equal(params[0].optional, false);
-
- assert.equal(m.length, 2);
- assert.equal(m[0], '/test');
- assert.equal(m[1], 'test');
- });
-
- it('should match trailing slashes in non-ending non-strict mode', function () {
- var params = [];
- var re = pathToRegExp('/:test', params, { end: false });
- var m;
-
- assert.equal(params.length, 1);
- assert.equal(params[0].name, 'test');
- assert.equal(params[0].optional, false);
-
- m = re.exec('/test/');
-
- assert.equal(m.length, 2);
- assert.equal(m[0], '/test/');
- assert.equal(m[1], 'test');
- });
-
- it('should match trailing slashes in non-ending non-strict mode', function () {
- var params = [];
- var re = pathToRegExp('/route/', params, { end: false });
- var m;
-
- assert.equal(params.length, 0);
-
- m = re.exec('/route/');
-
- assert.equal(m.length, 1);
- assert.equal(m[0], '/route/');
-
- m = re.exec('/route/test');
-
- assert.equal(m.length, 1);
- assert.equal(m[0], '/route');
-
- m = re.exec('/route');
-
- assert.equal(m.length, 1);
- assert.equal(m[0], '/route');
-
- m = re.exec('/route//');
-
- assert.equal(m.length, 1);
- assert.equal(m[0], '/route/');
- });
-
- it('should match trailing slashing in non-ending strict mode', function () {
- var params = [];
- var re = pathToRegExp('/route/', params, { end: false, strict: true });
-
- assert.equal(params.length, 0);
-
- m = re.exec('/route/');
-
- assert.equal(m.length, 1);
- assert.equal(m[0], '/route/');
-
- m = re.exec('/route/test');
-
- assert.equal(m.length, 1);
- assert.equal(m[0], '/route/');
-
- m = re.exec('/route');
-
- assert.ok(!m);
-
- m = re.exec('/route//');
-
- assert.equal(m.length, 1);
- assert.equal(m[0], '/route/');
- });
-
- it('should not match trailing slashes in non-ending strict mode', function () {
- var params = [];
- var re = pathToRegExp('/route', params, { end: false, strict: true });
-
- assert.equal(params.length, 0);
-
- m = re.exec('/route');
-
- assert.equal(m.length, 1);
- assert.equal(m[0], '/route');
-
- m = re.exec('/route/');
-
- assert.ok(m.length, 1);
- assert.equal(m[0], '/route');
- });
-
- it('should match text after an express param', function () {
- var params = [];
- var re = pathToRegExp('/(:test)route', params);
-
- assert.equal(params.length, 1);
- assert.equal(params[0].name, 'test');
- assert.equal(params[0].optional, false);
-
- m = re.exec('/route');
-
- assert.ok(!m);
-
- m = re.exec('/testroute');
-
- assert.equal(m.length, 2);
- assert.equal(m[0], '/testroute');
- assert.equal(m[1], 'test');
-
- m = re.exec('testroute');
-
- assert.ok(!m);
- });
-
- it('should match text after an optional express param', function () {
- var params = [];
- var re = pathToRegExp('/(:test?)route', params);
- var m;
-
- assert.equal(params.length, 1);
- assert.equal(params[0].name, 'test');
- assert.equal(params[0].optional, true);
-
- m = re.exec('/route');
-
- assert.equal(m.length, 2);
- assert.equal(m[0], '/route');
- assert.equal(m[1], undefined);
-
- m = re.exec('/testroute');
-
- assert.equal(m.length, 2);
- assert.equal(m[0], '/testroute');
- assert.equal(m[1], 'test');
-
- m = re.exec('route');
-
- assert.ok(!m);
- });
-
- it('should match optional formats', function () {
- var params = [];
- var re = pathToRegExp('/:test.:format?', params);
- var m;
-
- assert.equal(params.length, 2);
- assert.equal(params[0].name, 'test');
- assert.equal(params[0].optional, false);
- assert.equal(params[1].name, 'format');
- assert.equal(params[1].optional, true);
-
- m = re.exec('/route');
-
- assert.equal(m.length, 3);
- assert.equal(m[0], '/route');
- assert.equal(m[1], 'route');
- assert.equal(m[2], undefined);
-
- m = re.exec('/route.json');
-
- assert.equal(m.length, 3);
- assert.equal(m[0], '/route.json');
- assert.equal(m[1], 'route');
- assert.equal(m[2], 'json');
- });
-
- it('should match full paths with format by default', function () {
- var params = [];
- var m = pathToRegExp('/:test', params).exec('/test.json');
-
- assert.equal(params.length, 1);
- assert.equal(params[0].name, 'test');
- assert.equal(params[0].optional, false);
-
- assert.equal(m.length, 2);
- assert.equal(m[0], '/test.json');
- assert.equal(m[1], 'test.json');
- });
- });
-
- describe('regexps', function () {
- it('should return the regexp', function () {
- assert.deepEqual(pathToRegExp(/.*/), /.*/);
- });
- });
-
- describe('arrays', function () {
- it('should join arrays parts', function () {
- var re = pathToRegExp(['/test', '/route']);
-
- assert.ok(re.test('/test'));
- assert.ok(re.test('/route'));
- assert.ok(!re.test('/else'));
- });
-
- it('should match parts properly', function () {
- var params = [];
- var re = pathToRegExp(['/:test', '/test/:route'], params);
- var m;
-
- assert.equal(params.length, 2);
- assert.equal(params[0].name, 'test');
- assert.equal(params[0].optional, false);
- assert.equal(params[1].name, 'route');
- assert.equal(params[1].optional, false);
-
- m = re.exec('/route');
-
- assert.equal(m.length, 3);
- assert.equal(m[0], '/route');
- assert.equal(m[1], 'route');
- assert.equal(m[2], undefined);
-
- m = re.exec('/test/path');
-
- assert.equal(m.length, 3);
- assert.equal(m[0], '/test/path');
- assert.equal(m[1], undefined);
- assert.equal(m[2], 'path');
- });
- });
-});
diff --git a/CoAuthoring/node_modules/express/node_modules/proxy-addr/HISTORY.md b/CoAuthoring/node_modules/express/node_modules/proxy-addr/HISTORY.md
deleted file mode 100644
index c0ff10ed32..0000000000
--- a/CoAuthoring/node_modules/express/node_modules/proxy-addr/HISTORY.md
+++ /dev/null
@@ -1,39 +0,0 @@
-1.0.3 / 2014-09-21
-==================
-
- * Use `forwarded` npm module
-
-1.0.2 / 2014-09-18
-==================
-
- * Fix a global leak when multiple subnets are trusted
- * Support Node.js 0.6
- * deps: ipaddr.js@0.1.3
-
-1.0.1 / 2014-06-03
-==================
-
- * Fix links in npm package
-
-1.0.0 / 2014-05-08
-==================
-
- * Add `trust` argument to determine proxy trust on
- * Accepts custom function
- * Accepts IPv4/IPv6 address(es)
- * Accepts subnets
- * Accepts pre-defined names
- * Add optional `trust` argument to `proxyaddr.all` to
- stop at first untrusted
- * Add `proxyaddr.compile` to pre-compile `trust` function
- to make subsequent calls faster
-
-0.0.1 / 2014-05-04
-==================
-
- * Fix bad npm publish
-
-0.0.0 / 2014-05-04
-==================
-
- * Initial release
diff --git a/CoAuthoring/node_modules/express/node_modules/proxy-addr/LICENSE b/CoAuthoring/node_modules/express/node_modules/proxy-addr/LICENSE
deleted file mode 100644
index b7dce6cf9a..0000000000
--- a/CoAuthoring/node_modules/express/node_modules/proxy-addr/LICENSE
+++ /dev/null
@@ -1,22 +0,0 @@
-(The MIT License)
-
-Copyright (c) 2014 Douglas Christopher Wilson
-
-Permission is hereby granted, free of charge, to any person obtaining
-a copy of this software and associated documentation files (the
-'Software'), to deal in the Software without restriction, including
-without limitation the rights to use, copy, modify, merge, publish,
-distribute, sublicense, and/or sell copies of the Software, and to
-permit persons to whom the Software is furnished to do so, subject to
-the following conditions:
-
-The above copyright notice and this permission notice shall be
-included in all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
-EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
-IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
-CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
-TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
-SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
diff --git a/CoAuthoring/node_modules/express/node_modules/proxy-addr/README.md b/CoAuthoring/node_modules/express/node_modules/proxy-addr/README.md
deleted file mode 100644
index 57ec4cdbe7..0000000000
--- a/CoAuthoring/node_modules/express/node_modules/proxy-addr/README.md
+++ /dev/null
@@ -1,137 +0,0 @@
-# proxy-addr
-
-[![NPM Version][npm-image]][npm-url]
-[![NPM Downloads][downloads-image]][downloads-url]
-[![Node.js Version][node-version-image]][node-version-url]
-[![Build Status][travis-image]][travis-url]
-[![Test Coverage][coveralls-image]][coveralls-url]
-
-Determine address of proxied request
-
-## Install
-
-```sh
-$ npm install proxy-addr
-```
-
-## API
-
-```js
-var proxyaddr = require('proxy-addr')
-```
-
-### proxyaddr(req, trust)
-
-Return the address of the request, using the given `trust` parameter.
-
-The `trust` argument is a function that returns `true` if you trust
-the address, `false` if you don't. The closest untrusted address is
-returned.
-
-```js
-proxyaddr(req, function(addr){ return addr === '127.0.0.1' })
-proxyaddr(req, function(addr, i){ return i < 1 })
-```
-
-The `trust` arugment may also be a single IP address string or an
-array of trusted addresses, as plain IP addresses, CIDR-formatted
-strings, or IP/netmask strings.
-
-```js
-proxyaddr(req, '127.0.0.1')
-proxyaddr(req, ['127.0.0.0/8', '10.0.0.0/8'])
-proxyaddr(req, ['127.0.0.0/255.0.0.0', '192.168.0.0/255.255.0.0'])
-```
-
-This module also supports IPv6. Your IPv6 addresses will be normalized
-automatically (i.e. `fe80::00ed:1` equals `fe80:0:0:0:0:0:ed:1`).
-
-```js
-proxyaddr(req, '::1')
-proxyaddr(req, ['::1/128', 'fe80::/10'])
-proxyaddr(req, ['fe80::/ffc0::'])
-```
-
-This module will automatically work with IPv4-mapped IPv6 addresses
-as well to support node.js in IPv6-only mode. This means that you do
-not have to specify both `::ffff:a00:1` and `10.0.0.1`.
-
-As a convenience, this module also takes certain pre-defined names
-in addition to IP addresses, which expand into IP addresses:
-
-```js
-proxyaddr(req, 'loopback')
-proxyaddr(req, ['loopback', 'fc00:ac:1ab5:fff::1/64'])
-```
-
- * `loopback`: IPv4 and IPv6 loopback addresses (like `::1` and
- `127.0.0.1`).
- * `linklocal`: IPv4 and IPv6 link-local addresses (like
- `fe80::1:1:1:1` and `169.254.0.1`).
- * `uniquelocal`: IPv4 private addresses and IPv6 unique-local
- addresses (like `fc00:ac:1ab5:fff::1` and `192.168.0.1`).
-
-When `trust` is specified as a function, it will be called for each
-address to determine if it is a trusted address. The function is
-given two arguments: `addr` and `i`, where `addr` is a string of
-the address to check and `i` is a number that represents the distance
-from the socket address.
-
-### proxyaddr.all(req, [trust])
-
-Return all the addresses of the request, optionally stopping at the
-first untrusted. This array is ordered from closest to furthest
-(i.e. `arr[0] === req.connection.remoteAddress`).
-
-```js
-proxyaddr.all(req)
-```
-
-The optional `trust` argument takes the same arguments as `trust`
-does in `proxyaddr(req, trust)`.
-
-```js
-proxyaddr.all(req, 'loopback')
-```
-
-### proxyaddr.compile(val)
-
-Compiles argument `val` into a `trust` function. This function takes
-the same arguments as `trust` does in `proxyaddr(req, trust)` and
-returns a function suitable for `proxyaddr(req, trust)`.
-
-```js
-var trust = proxyaddr.compile('localhost')
-var addr = proxyaddr(req, trust)
-```
-
-This function is meant to be optimized for use against every request.
-It is recommend to compile a trust function up-front for the trusted
-configuration and pass that to `proxyaddr(req, trust)` for each request.
-
-## Testing
-
-```sh
-$ npm test
-```
-
-## Benchmarks
-
-```sh
-$ npm run-script bench
-```
-
-## License
-
-[MIT](LICENSE)
-
-[npm-image]: https://img.shields.io/npm/v/proxy-addr.svg?style=flat
-[npm-url]: https://npmjs.org/package/proxy-addr
-[node-version-image]: https://img.shields.io/node/v/proxy-addr.svg?style=flat
-[node-version-url]: http://nodejs.org/download/
-[travis-image]: https://img.shields.io/travis/jshttp/proxy-addr.svg?style=flat
-[travis-url]: https://travis-ci.org/jshttp/proxy-addr
-[coveralls-image]: https://img.shields.io/coveralls/jshttp/proxy-addr.svg?style=flat
-[coveralls-url]: https://coveralls.io/r/jshttp/proxy-addr?branch=master
-[downloads-image]: https://img.shields.io/npm/dm/proxy-addr.svg?style=flat
-[downloads-url]: https://npmjs.org/package/proxy-addr
diff --git a/CoAuthoring/node_modules/express/node_modules/proxy-addr/index.js b/CoAuthoring/node_modules/express/node_modules/proxy-addr/index.js
deleted file mode 100644
index d73951321e..0000000000
--- a/CoAuthoring/node_modules/express/node_modules/proxy-addr/index.js
+++ /dev/null
@@ -1,345 +0,0 @@
-/*!
- * proxy-addr
- * Copyright(c) 2014 Douglas Christopher Wilson
- * MIT Licensed
- */
-
-/**
- * Module exports.
- */
-
-module.exports = proxyaddr;
-module.exports.all = alladdrs;
-module.exports.compile = compile;
-
-/**
- * Module dependencies.
- */
-
-var forwarded = require('forwarded');
-var ipaddr = require('ipaddr.js');
-
-/**
- * Variables.
- */
-
-var digitre = /^[0-9]+$/;
-var isip = ipaddr.isValid;
-var parseip = ipaddr.parse;
-
-/**
- * Pre-defined IP ranges.
- */
-
-var ipranges = {
- linklocal: ['169.254.0.0/16', 'fe80::/10'],
- loopback: ['127.0.0.1/8', '::1/128'],
- uniquelocal: ['10.0.0.0/8', '172.16.0.0/12', '192.168.0.0/16', 'fc00::/7']
-};
-
-/**
- * Get all addresses in the request, optionally stopping
- * at the first untrusted.
- *
- * @param {Object} request
- * @param {Function|Array|String} [trust]
- * @api public
- */
-
-function alladdrs(req, trust) {
- // get addresses
- var addrs = forwarded(req);
-
- if (!trust) {
- // Return all addresses
- return addrs;
- }
-
- if (typeof trust !== 'function') {
- trust = compile(trust);
- }
-
- for (var i = 0; i < addrs.length - 1; i++) {
- if (trust(addrs[i], i)) continue;
-
- addrs.length = i + 1;
- }
-
- return addrs;
-}
-
-/**
- * Compile argument into trust function.
- *
- * @param {Array|String} val
- * @api private
- */
-
-function compile(val) {
- if (!val) {
- throw new TypeError('argument is required');
- }
-
- var trust = typeof val === 'string'
- ? [val]
- : val;
-
- if (!Array.isArray(trust)) {
- throw new TypeError('unsupported trust argument');
- }
-
- for (var i = 0; i < trust.length; i++) {
- val = trust[i];
-
- if (!ipranges.hasOwnProperty(val)) {
- continue;
- }
-
- // Splice in pre-defined range
- val = ipranges[val];
- trust.splice.apply(trust, [i, 1].concat(val));
- i += val.length - 1;
- }
-
- return compileTrust(compileRangeSubnets(trust));
-}
-
-/**
- * Compile `arr` elements into range subnets.
- *
- * @param {Array} arr
- * @api private
- */
-
-function compileRangeSubnets(arr) {
- var rangeSubnets = new Array(arr.length);
-
- for (var i = 0; i < arr.length; i++) {
- rangeSubnets[i] = parseipNotation(arr[i]);
- }
-
- return rangeSubnets;
-}
-
-/**
- * Compile range subnet array into trust function.
- *
- * @param {Array} rangeSubnets
- * @api private
- */
-
-function compileTrust(rangeSubnets) {
- // Return optimized function based on length
- var len = rangeSubnets.length;
- return len === 0
- ? trustNone
- : len === 1
- ? trustSingle(rangeSubnets[0])
- : trustMulti(rangeSubnets);
-}
-
-/**
- * Parse IP notation string into range subnet.
- *
- * @param {String} note
- * @api private
- */
-
-function parseipNotation(note) {
- var ip;
- var kind;
- var max;
- var pos = note.lastIndexOf('/');
- var range;
-
- ip = pos !== -1
- ? note.substring(0, pos)
- : note;
-
- if (!isip(ip)) {
- throw new TypeError('invalid IP address: ' + ip);
- }
-
- ip = parseip(ip);
-
- kind = ip.kind();
- max = kind === 'ipv6'
- ? 128
- : 32;
-
- range = pos !== -1
- ? note.substring(pos + 1, note.length)
- : max;
-
- if (typeof range !== 'number') {
- range = digitre.test(range)
- ? parseInt(range, 10)
- : isip(range)
- ? parseNetmask(range)
- : 0;
- }
-
- if (ip.kind() === 'ipv6' && ip.isIPv4MappedAddress()) {
- // Store as IPv4
- ip = ip.toIPv4Address();
- range = range <= max
- ? range - 96
- : range;
- }
-
- if (range <= 0 || range > max) {
- throw new TypeError('invalid range on address: ' + note);
- }
-
- return [ip, range];
-}
-
-/**
- * Parse netmask string into CIDR range.
- *
- * @param {String} note
- * @api private
- */
-
-function parseNetmask(netmask) {
- var ip = parseip(netmask);
- var parts;
- var size;
-
- switch (ip.kind()) {
- case 'ipv4':
- parts = ip.octets;
- size = 8;
- break;
- case 'ipv6':
- parts = ip.parts;
- size = 16;
- break;
- }
-
- var max = Math.pow(2, size) - 1;
- var part;
- var range = 0;
-
- for (var i = 0; i < parts.length; i++) {
- part = parts[i] & max;
-
- if (part === max) {
- range += size;
- continue;
- }
-
- while (part) {
- part = (part << 1) & max;
- range += 1;
- }
-
- break;
- }
-
- return range;
-}
-
-/**
- * Determine address of proxied request.
- *
- * @param {Object} request
- * @param {Function|Array|String} trust
- * @api public
- */
-
-function proxyaddr(req, trust) {
- if (!req) {
- throw new TypeError('req argument is required');
- }
-
- if (!trust) {
- throw new TypeError('trust argument is required');
- }
-
- var addrs = alladdrs(req, trust);
- var addr = addrs[addrs.length - 1];
-
- return addr;
-}
-
-/**
- * Static trust function to trust nothing.
- *
- * @api private
- */
-
-function trustNone() {
- return false;
-}
-
-/**
- * Compile trust function for multiple subnets.
- *
- * @param {Array} subnets
- * @api private
- */
-
-function trustMulti(subnets) {
- return function trust(addr) {
- if (!isip(addr)) return false;
-
- var ip = parseip(addr);
- var ipv4;
- var kind = ip.kind();
- var subnet;
- var subnetip;
- var subnetkind;
- var subnetrange;
- var trusted;
-
- for (var i = 0; i < subnets.length; i++) {
- subnet = subnets[i];
- subnetip = subnet[0];
- subnetkind = subnetip.kind();
- subnetrange = subnet[1];
- trusted = ip;
-
- if (kind !== subnetkind) {
- if (kind !== 'ipv6' || subnetkind !== 'ipv4' || !ip.isIPv4MappedAddress()) {
- continue;
- }
-
- // Store addr as IPv4
- ipv4 = ipv4 || ip.toIPv4Address();
- trusted = ipv4;
- }
-
- if (trusted.match(subnetip, subnetrange)) return true;
- }
-
- return false;
- };
-}
-
-/**
- * Compile trust function for single subnet.
- *
- * @param {Object} subnet
- * @api private
- */
-
-function trustSingle(subnet) {
- var subnetip = subnet[0];
- var subnetkind = subnetip.kind();
- var subnetisipv4 = subnetkind === 'ipv4';
- var subnetrange = subnet[1];
-
- return function trust(addr) {
- if (!isip(addr)) return false;
-
- var ip = parseip(addr);
- var kind = ip.kind();
-
- return kind === subnetkind
- ? ip.match(subnetip, subnetrange)
- : subnetisipv4 && kind === 'ipv6' && ip.isIPv4MappedAddress()
- ? ip.toIPv4Address().match(subnetip, subnetrange)
- : false;
- };
-}
diff --git a/CoAuthoring/node_modules/express/node_modules/proxy-addr/node_modules/forwarded/HISTORY.md b/CoAuthoring/node_modules/express/node_modules/proxy-addr/node_modules/forwarded/HISTORY.md
deleted file mode 100644
index 97fa1d1022..0000000000
--- a/CoAuthoring/node_modules/express/node_modules/proxy-addr/node_modules/forwarded/HISTORY.md
+++ /dev/null
@@ -1,4 +0,0 @@
-0.1.0 / 2014-09-21
-==================
-
- * Initial release
diff --git a/CoAuthoring/node_modules/express/node_modules/proxy-addr/node_modules/forwarded/LICENSE b/CoAuthoring/node_modules/express/node_modules/proxy-addr/node_modules/forwarded/LICENSE
deleted file mode 100644
index b7dce6cf9a..0000000000
--- a/CoAuthoring/node_modules/express/node_modules/proxy-addr/node_modules/forwarded/LICENSE
+++ /dev/null
@@ -1,22 +0,0 @@
-(The MIT License)
-
-Copyright (c) 2014 Douglas Christopher Wilson
-
-Permission is hereby granted, free of charge, to any person obtaining
-a copy of this software and associated documentation files (the
-'Software'), to deal in the Software without restriction, including
-without limitation the rights to use, copy, modify, merge, publish,
-distribute, sublicense, and/or sell copies of the Software, and to
-permit persons to whom the Software is furnished to do so, subject to
-the following conditions:
-
-The above copyright notice and this permission notice shall be
-included in all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
-EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
-IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
-CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
-TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
-SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
diff --git a/CoAuthoring/node_modules/express/node_modules/proxy-addr/node_modules/forwarded/README.md b/CoAuthoring/node_modules/express/node_modules/proxy-addr/node_modules/forwarded/README.md
deleted file mode 100644
index 2b4988fa22..0000000000
--- a/CoAuthoring/node_modules/express/node_modules/proxy-addr/node_modules/forwarded/README.md
+++ /dev/null
@@ -1,53 +0,0 @@
-# forwarded
-
-[![NPM Version][npm-image]][npm-url]
-[![NPM Downloads][downloads-image]][downloads-url]
-[![Node.js Version][node-version-image]][node-version-url]
-[![Build Status][travis-image]][travis-url]
-[![Test Coverage][coveralls-image]][coveralls-url]
-
-Parse HTTP X-Forwarded-For header
-
-## Installation
-
-```sh
-$ npm install forwarded
-```
-
-## API
-
-```js
-var forwarded = require('forwarded')
-```
-
-### forwarded(req)
-
-```js
-var addresses = forwarded(req)
-```
-
-Parse the `X-Forwarded-For` header from the request. Returns an array
-of the addresses, including the socket address for the `req`. In reverse
-order (i.e. index `0` is the socket address and the last index is the
-furthest address, typically the end-user).
-
-## Testing
-
-```sh
-$ npm test
-```
-
-## License
-
-[MIT](LICENSE)
-
-[npm-image]: https://img.shields.io/npm/v/forwarded.svg?style=flat
-[npm-url]: https://npmjs.org/package/forwarded
-[node-version-image]: https://img.shields.io/node/v/forwarded.svg?style=flat
-[node-version-url]: http://nodejs.org/download/
-[travis-image]: https://img.shields.io/travis/jshttp/forwarded.svg?style=flat
-[travis-url]: https://travis-ci.org/jshttp/forwarded
-[coveralls-image]: https://img.shields.io/coveralls/jshttp/forwarded.svg?style=flat
-[coveralls-url]: https://coveralls.io/r/jshttp/forwarded?branch=master
-[downloads-image]: https://img.shields.io/npm/dm/forwarded.svg?style=flat
-[downloads-url]: https://npmjs.org/package/forwarded
diff --git a/CoAuthoring/node_modules/express/node_modules/proxy-addr/node_modules/forwarded/index.js b/CoAuthoring/node_modules/express/node_modules/proxy-addr/node_modules/forwarded/index.js
deleted file mode 100644
index 2f5c340886..0000000000
--- a/CoAuthoring/node_modules/express/node_modules/proxy-addr/node_modules/forwarded/index.js
+++ /dev/null
@@ -1,35 +0,0 @@
-/*!
- * forwarded
- * Copyright(c) 2014 Douglas Christopher Wilson
- * MIT Licensed
- */
-
-/**
- * Module exports.
- */
-
-module.exports = forwarded
-
-/**
- * Get all addresses in the request, using the `X-Forwarded-For` header.
- *
- * @param {Object} req
- * @api public
- */
-
-function forwarded(req) {
- if (!req) {
- throw new TypeError('argument req is required')
- }
-
- // simple header parsing
- var proxyAddrs = (req.headers['x-forwarded-for'] || '')
- .split(/ *, */)
- .filter(Boolean)
- .reverse()
- var socketAddr = req.connection.remoteAddress
- var addrs = [socketAddr].concat(proxyAddrs)
-
- // return all addresses
- return addrs
-}
diff --git a/CoAuthoring/node_modules/express/node_modules/proxy-addr/node_modules/forwarded/package.json b/CoAuthoring/node_modules/express/node_modules/proxy-addr/node_modules/forwarded/package.json
deleted file mode 100644
index 508786849a..0000000000
--- a/CoAuthoring/node_modules/express/node_modules/proxy-addr/node_modules/forwarded/package.json
+++ /dev/null
@@ -1,47 +0,0 @@
-{
- "name": "forwarded",
- "description": "Parse HTTP X-Forwarded-For header",
- "version": "0.1.0",
- "contributors": [
- {
- "name": "Douglas Christopher Wilson",
- "email": "doug@somethingdoug.com"
- }
- ],
- "license": "MIT",
- "keywords": [
- "x-forwarded-for",
- "http",
- "req"
- ],
- "repository": {
- "type": "git",
- "url": "git://github.com/jshttp/forwarded"
- },
- "devDependencies": {
- "istanbul": "0.3.2",
- "mocha": "~1.21.4"
- },
- "files": [
- "LICENSE",
- "HISTORY.md",
- "README.md",
- "index.js"
- ],
- "engines": {
- "node": ">= 0.6"
- },
- "scripts": {
- "test": "mocha --reporter spec --bail --check-leaks test/",
- "test-cov": "istanbul cover node_modules/mocha/bin/_mocha -- --reporter dot --check-leaks test/",
- "test-travis": "istanbul cover node_modules/mocha/bin/_mocha --report lcovonly -- --reporter spec --check-leaks test/"
- },
- "readme": "# forwarded\n\n[![NPM Version][npm-image]][npm-url]\n[![NPM Downloads][downloads-image]][downloads-url]\n[![Node.js Version][node-version-image]][node-version-url]\n[![Build Status][travis-image]][travis-url]\n[![Test Coverage][coveralls-image]][coveralls-url]\n\nParse HTTP X-Forwarded-For header\n\n## Installation\n\n```sh\n$ npm install forwarded\n```\n\n## API\n\n```js\nvar forwarded = require('forwarded')\n```\n\n### forwarded(req)\n\n```js\nvar addresses = forwarded(req)\n```\n\nParse the `X-Forwarded-For` header from the request. Returns an array\nof the addresses, including the socket address for the `req`. In reverse\norder (i.e. index `0` is the socket address and the last index is the\nfurthest address, typically the end-user).\n\n## Testing\n\n```sh\n$ npm test\n```\n\n## License\n\n[MIT](LICENSE)\n\n[npm-image]: https://img.shields.io/npm/v/forwarded.svg?style=flat\n[npm-url]: https://npmjs.org/package/forwarded\n[node-version-image]: https://img.shields.io/node/v/forwarded.svg?style=flat\n[node-version-url]: http://nodejs.org/download/\n[travis-image]: https://img.shields.io/travis/jshttp/forwarded.svg?style=flat\n[travis-url]: https://travis-ci.org/jshttp/forwarded\n[coveralls-image]: https://img.shields.io/coveralls/jshttp/forwarded.svg?style=flat\n[coveralls-url]: https://coveralls.io/r/jshttp/forwarded?branch=master\n[downloads-image]: https://img.shields.io/npm/dm/forwarded.svg?style=flat\n[downloads-url]: https://npmjs.org/package/forwarded\n",
- "readmeFilename": "README.md",
- "bugs": {
- "url": "https://github.com/jshttp/forwarded/issues"
- },
- "homepage": "https://github.com/jshttp/forwarded",
- "_id": "forwarded@0.1.0",
- "_from": "forwarded@~0.1.0"
-}
diff --git a/CoAuthoring/node_modules/express/node_modules/proxy-addr/node_modules/ipaddr.js/.npmignore b/CoAuthoring/node_modules/express/node_modules/proxy-addr/node_modules/ipaddr.js/.npmignore
deleted file mode 100644
index 7a1537ba06..0000000000
--- a/CoAuthoring/node_modules/express/node_modules/proxy-addr/node_modules/ipaddr.js/.npmignore
+++ /dev/null
@@ -1,2 +0,0 @@
-.idea
-node_modules
diff --git a/CoAuthoring/node_modules/express/node_modules/proxy-addr/node_modules/ipaddr.js/Cakefile b/CoAuthoring/node_modules/express/node_modules/proxy-addr/node_modules/ipaddr.js/Cakefile
deleted file mode 100644
index 7fd355a7b0..0000000000
--- a/CoAuthoring/node_modules/express/node_modules/proxy-addr/node_modules/ipaddr.js/Cakefile
+++ /dev/null
@@ -1,18 +0,0 @@
-fs = require 'fs'
-CoffeeScript = require 'coffee-script'
-nodeunit = require 'nodeunit'
-UglifyJS = require 'uglify-js'
-
-task 'build', 'build the JavaScript files from CoffeeScript source', build = (cb) ->
- source = fs.readFileSync 'src/ipaddr.coffee'
- fs.writeFileSync 'lib/ipaddr.js', CoffeeScript.compile source.toString()
-
- invoke 'test'
- invoke 'compress'
-
-task 'test', 'run the bundled tests', (cb) ->
- nodeunit.reporters.default.run ['test']
-
-task 'compress', 'uglify the resulting javascript', (cb) ->
- result = UglifyJS.minify('lib/ipaddr.js')
- fs.writeFileSync('ipaddr.min.js', result.code)
diff --git a/CoAuthoring/node_modules/express/node_modules/proxy-addr/node_modules/ipaddr.js/LICENSE b/CoAuthoring/node_modules/express/node_modules/proxy-addr/node_modules/ipaddr.js/LICENSE
deleted file mode 100644
index 3493f0dfcf..0000000000
--- a/CoAuthoring/node_modules/express/node_modules/proxy-addr/node_modules/ipaddr.js/LICENSE
+++ /dev/null
@@ -1,19 +0,0 @@
-Copyright (C) 2011 Peter Zotov
-
-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.
\ No newline at end of file
diff --git a/CoAuthoring/node_modules/express/node_modules/proxy-addr/node_modules/ipaddr.js/README.md b/CoAuthoring/node_modules/express/node_modules/proxy-addr/node_modules/ipaddr.js/README.md
deleted file mode 100644
index a8166729b1..0000000000
--- a/CoAuthoring/node_modules/express/node_modules/proxy-addr/node_modules/ipaddr.js/README.md
+++ /dev/null
@@ -1,149 +0,0 @@
-# ipaddr.js — an IPv6 and IPv4 address manipulation library
-
-ipaddr.js is a small (1.9K minified and gzipped) library for manipulating
-IP addresses in JavaScript environments. It runs on both CommonJS runtimes
-(e.g. [nodejs]) and in a web browser.
-
-ipaddr.js allows you to verify and parse string representation of an IP
-address, match it against a CIDR range or range list, determine if it falls
-into some reserved ranges (examples include loopback and private ranges),
-and convert between IPv4 and IPv4-mapped IPv6 addresses.
-
-[nodejs]: http://nodejs.org
-
-## Installation
-
-`npm install ipaddr.js`
-
-## API
-
-ipaddr.js defines one object in the global scope: `ipaddr`. In CommonJS,
-it is exported from the module:
-
-```js
-var ipaddr = require('ipaddr.js');
-```
-
-The API consists of several global methods and two classes: ipaddr.IPv6 and ipaddr.IPv4.
-
-### Global methods
-
-There are three global methods defined: `ipaddr.isValid`, `ipaddr.parse` and
-`ipaddr.process`. All of them receive a string as a single parameter.
-
-The `ipaddr.isValid` method returns `true` if the address is a valid IPv4 or
-IPv6 address, and `false` otherwise. It does not throw any exceptions.
-
-The `ipaddr.parse` method returns an object representing the IP address,
-or throws an `Error` if the passed string is not a valid representation of an
-IP address.
-
-The `ipaddr.process` method works just like the `ipaddr.parse` one, but it
-automatically converts IPv4-mapped IPv6 addresses to their IPv4 couterparts
-before returning. It is useful when you have a Node.js instance listening
-on an IPv6 socket, and the `net.ivp6.bindv6only` sysctl parameter (or its
-equivalent on non-Linux OS) is set to 0. In this case, you can accept IPv4
-connections on your IPv6-only socket, but the remote address will be mangled.
-Use `ipaddr.process` method to automatically demangle it.
-
-### Object representation
-
-Parsing methods return an object which descends from `ipaddr.IPv6` or
-`ipaddr.IPv4`. These objects share some properties, but most of them differ.
-
-#### Shared properties
-
-One can determine the type of address by calling `addr.kind()`. It will return
-either `"ipv6"` or `"ipv4"`.
-
-An address can be converted back to its string representation with `addr.toString()`.
-Note that this method:
- * does not return the original string used to create the object (in fact, there is
- no way of getting that string)
- * returns a compact representation (when it is applicable)
-
-A `match(range, bits)` method can be used to check if the address falls into a
-certain CIDR range.
-Note that an address can be (obviously) matched only against an address of the same type.
-
-For example:
-
-```js
-var addr = ipaddr.parse("2001:db8:1234::1");
-var range = ipaddr.parse("2001:db8::");
-
-addr.match(range, 32); // => true
-```
-
-A `range()` method returns one of predefined names for several special ranges defined
-by IP protocols. The exact names (and their respective CIDR ranges) can be looked up
-in the source: [IPv6 ranges] and [IPv4 ranges]. Some common ones include `"unicast"`
-(the default one) and `"reserved"`.
-
-You can match against your own range list by using
-`ipaddr.subnetMatch(address, rangeList, defaultName)` method. It can work with both
-IPv6 and IPv4 addresses, and accepts a name-to-subnet map as the range list. For example:
-
-```js
-var rangeList = {
- documentationOnly: [ ipaddr.parse('2001:db8::'), 32 ],
- tunnelProviders: [
- [ ipaddr.parse('2001:470::'), 32 ], // he.net
- [ ipaddr.parse('2001:5c0::'), 32 ] // freenet6
- ]
-};
-ipaddr.subnetMatch(ipaddr.parse('2001:470:8:66::1'), rangeList, 'unknown'); // => "he.net"
-```
-
-The addresses can be converted to their byte representation with `toByteArray()`.
-(Actually, JavaScript mostly does not know about byte buffers. They are emulated with
-arrays of numbers, each in range of 0..255.)
-
-```js
-var bytes = ipaddr.parse('2a00:1450:8007::68').toByteArray(); // ipv6.google.com
-bytes // => [42, 0x00, 0x14, 0x50, 0x80, 0x07, 0x00, , 0x00, 0x68 ]
-```
-
-The `ipaddr.IPv4` and `ipaddr.IPv6` objects have some methods defined, too. All of them
-have the same interface for both protocols, and are similar to global methods.
-
-`ipaddr.IPvX.isValid(string)` can be used to check if the string is a valid address
-for particular protocol, and `ipaddr.IPvX.parse(string)` is the error-throwing parser.
-
-[IPv6 ranges]: https://github.com/whitequark/ipaddr.js/blob/master/src/ipaddr.coffee#L186
-[IPv4 ranges]: https://github.com/whitequark/ipaddr.js/blob/master/src/ipaddr.coffee#L71
-
-#### IPv6 properties
-
-Sometimes you will want to convert IPv6 not to a compact string representation (with
-the `::` substitution); the `toNormalizedString()` method will return an address where
-all zeroes are explicit.
-
-For example:
-
-```js
-var addr = ipaddr.parse("2001:0db8::0001");
-addr.toString(); // => "2001:db8::1"
-addr.toNormalizedString(); // => "2001:db8:0:0:0:0:0:1"
-```
-
-The `isIPv4MappedAddress()` method will return `true` if this address is an IPv4-mapped
-one, and `toIPv4Address()` will return an IPv4 object address.
-
-To access the underlying binary representation of the address, use `addr.parts`.
-
-```js
-var addr = ipaddr.parse("2001:db8:10::1234:DEAD");
-addr.parts // => [0x2001, 0xdb8, 0x10, 0, 0, 0, 0x1234, 0xdead]
-```
-
-#### IPv4 properties
-
-`toIPv4MappedAddress()` will return a corresponding IPv4-mapped IPv6 address.
-
-To access the underlying representation of the address, use `addr.octets`.
-
-```js
-var addr = ipaddr.parse("192.168.1.1");
-addr.octets // => [192, 168, 1, 1]
-```
diff --git a/CoAuthoring/node_modules/express/node_modules/proxy-addr/node_modules/ipaddr.js/ipaddr.min.js b/CoAuthoring/node_modules/express/node_modules/proxy-addr/node_modules/ipaddr.js/ipaddr.min.js
deleted file mode 100644
index 528d48b333..0000000000
--- a/CoAuthoring/node_modules/express/node_modules/proxy-addr/node_modules/ipaddr.js/ipaddr.min.js
+++ /dev/null
@@ -1 +0,0 @@
-(function(){var t,r,n,e,i,o,a,s;r={},s=this,"undefined"!=typeof module&&null!==module&&module.exports?module.exports=r:s.ipaddr=r,a=function(t,r,n,e){var i,o;if(t.length!==r.length)throw new Error("ipaddr: cannot match CIDR for objects with different lengths");for(i=0;e>0;){if(o=n-e,0>o&&(o=0),t[i]>>o!==r[i]>>o)return!1;e-=n,i+=1}return!0},r.subnetMatch=function(t,r,n){var e,i,o,a,s;null==n&&(n="unicast");for(e in r)for(i=r[e],"[object Array]"!==toString.call(i[0])&&(i=[i]),a=0,s=i.length;s>a;a++)if(o=i[a],t.match.apply(t,o))return e;return n},r.IPv4=function(){function t(t){var r,n,e;if(4!==t.length)throw new Error("ipaddr: ipv4 octet count should be 4");for(n=0,e=t.length;e>n;n++)if(r=t[n],!(r>=0&&255>=r))throw new Error("ipaddr: ipv4 octet is a byte");this.octets=t}return t.prototype.kind=function(){return"ipv4"},t.prototype.toString=function(){return this.octets.join(".")},t.prototype.toByteArray=function(){return this.octets.slice(0)},t.prototype.match=function(t,r){if("ipv4"!==t.kind())throw new Error("ipaddr: cannot match ipv4 address with non-ipv4 one");return a(this.octets,t.octets,8,r)},t.prototype.SpecialRanges={broadcast:[[new t([255,255,255,255]),32]],multicast:[[new t([224,0,0,0]),4]],linkLocal:[[new t([169,254,0,0]),16]],loopback:[[new t([127,0,0,0]),8]],"private":[[new t([10,0,0,0]),8],[new t([172,16,0,0]),12],[new t([192,168,0,0]),16]],reserved:[[new t([192,0,0,0]),24],[new t([192,0,2,0]),24],[new t([192,88,99,0]),24],[new t([198,51,100,0]),24],[new t([203,0,113,0]),24],[new t([240,0,0,0]),4]]},t.prototype.range=function(){return r.subnetMatch(this,this.SpecialRanges)},t.prototype.toIPv4MappedAddress=function(){return r.IPv6.parse("::ffff:"+this.toString())},t}(),n="(0?\\d+|0x[a-f0-9]+)",e={fourOctet:new RegExp("^"+n+"\\."+n+"\\."+n+"\\."+n+"$","i"),longValue:new RegExp("^"+n+"$","i")},r.IPv4.parser=function(t){var r,n,i,o,a;return n=function(t){return"0"===t[0]&&"x"!==t[1]?parseInt(t,8):parseInt(t)},(r=t.match(e.fourOctet))?function(){var t,e,o,a;for(o=r.slice(1,6),a=[],t=0,e=o.length;e>t;t++)i=o[t],a.push(n(i));return a}():(r=t.match(e.longValue))?(a=n(r[1]),function(){var t,r;for(r=[],o=t=0;24>=t;o=t+=8)r.push(a>>o&255);return r}().reverse()):null},r.IPv6=function(){function t(t){var r,n,e;if(8!==t.length)throw new Error("ipaddr: ipv6 part count should be 8");for(n=0,e=t.length;e>n;n++)if(r=t[n],!(r>=0&&65535>=r))throw new Error("ipaddr: ipv6 part should fit to two octets");this.parts=t}return t.prototype.kind=function(){return"ipv6"},t.prototype.toString=function(){var t,r,n,e,i,o,a;for(i=function(){var t,n,e,i;for(e=this.parts,i=[],t=0,n=e.length;n>t;t++)r=e[t],i.push(r.toString(16));return i}.call(this),t=[],n=function(r){return t.push(r)},e=0,o=0,a=i.length;a>o;o++)switch(r=i[o],e){case 0:"0"===r?n(""):n(r),e=1;break;case 1:"0"===r?e=2:n(r);break;case 2:"0"!==r&&(n(""),n(r),e=3);break;case 3:n(r)}return 2===e&&(n(""),n("")),t.join(":")},t.prototype.toByteArray=function(){var t,r,n,e,i;for(t=[],i=this.parts,n=0,e=i.length;e>n;n++)r=i[n],t.push(r>>8),t.push(255&r);return t},t.prototype.toNormalizedString=function(){var t;return function(){var r,n,e,i;for(e=this.parts,i=[],r=0,n=e.length;n>r;r++)t=e[r],i.push(t.toString(16));return i}.call(this).join(":")},t.prototype.match=function(t,r){if("ipv6"!==t.kind())throw new Error("ipaddr: cannot match ipv6 address with non-ipv6 one");return a(this.parts,t.parts,16,r)},t.prototype.SpecialRanges={unspecified:[new t([0,0,0,0,0,0,0,0]),128],linkLocal:[new t([65152,0,0,0,0,0,0,0]),10],multicast:[new t([65280,0,0,0,0,0,0,0]),8],loopback:[new t([0,0,0,0,0,0,0,1]),128],uniqueLocal:[new t([64512,0,0,0,0,0,0,0]),7],ipv4Mapped:[new t([0,0,0,0,0,65535,0,0]),96],rfc6145:[new t([0,0,0,0,65535,0,0,0]),96],rfc6052:[new t([100,65435,0,0,0,0,0,0]),96],"6to4":[new t([8194,0,0,0,0,0,0,0]),16],teredo:[new t([8193,0,0,0,0,0,0,0]),32],reserved:[[new t([8193,3512,0,0,0,0,0,0]),32]]},t.prototype.range=function(){return r.subnetMatch(this,this.SpecialRanges)},t.prototype.isIPv4MappedAddress=function(){return"ipv4Mapped"===this.range()},t.prototype.toIPv4Address=function(){var t,n,e;if(!this.isIPv4MappedAddress())throw new Error("ipaddr: trying to convert a generic ipv6 address to ipv4");return e=this.parts.slice(-2),t=e[0],n=e[1],new r.IPv4([t>>8,255&t,n>>8,255&n])},t}(),i="(?:[0-9a-f]+::?)+",o={"native":new RegExp("^(::)?("+i+")?([0-9a-f]+)?(::)?$","i"),transitional:new RegExp("^((?:"+i+")|(?:::)(?:"+i+")?)"+(""+n+"\\."+n+"\\."+n+"\\."+n+"$"),"i")},t=function(t,r){var n,e,i,o,a;if(t.indexOf("::")!==t.lastIndexOf("::"))return null;for(n=0,e=-1;(e=t.indexOf(":",e+1))>=0;)n++;for(":"===t[0]&&n--,":"===t[t.length-1]&&n--,a=r-n,o=":";a--;)o+="0:";return t=t.replace("::",o),":"===t[0]&&(t=t.slice(1)),":"===t[t.length-1]&&(t=t.slice(0,-1)),function(){var r,n,e,o;for(e=t.split(":"),o=[],r=0,n=e.length;n>r;r++)i=e[r],o.push(parseInt(i,16));return o}()},r.IPv6.parser=function(r){var n,e;return r.match(o["native"])?t(r,8):(n=r.match(o.transitional))&&(e=t(n[1].slice(0,-1),6))?(e.push(parseInt(n[2])<<8|parseInt(n[3])),e.push(parseInt(n[4])<<8|parseInt(n[5])),e):null},r.IPv4.isIPv4=r.IPv6.isIPv6=function(t){return null!==this.parser(t)},r.IPv4.isValid=r.IPv6.isValid=function(t){var r;try{return new this(this.parser(t)),!0}catch(n){return r=n,!1}},r.IPv4.parse=r.IPv6.parse=function(t){var r;if(r=this.parser(t),null===r)throw new Error("ipaddr: string is not formatted like ip address");return new this(r)},r.isValid=function(t){return r.IPv6.isValid(t)||r.IPv4.isValid(t)},r.parse=function(t){if(r.IPv6.isIPv6(t))return r.IPv6.parse(t);if(r.IPv4.isIPv4(t))return r.IPv4.parse(t);throw new Error("ipaddr: the address has neither IPv6 nor IPv4 format")},r.process=function(t){var r;return r=this.parse(t),"ipv6"===r.kind()&&r.isIPv4MappedAddress()?r.toIPv4Address():r}}).call(this);
\ No newline at end of file
diff --git a/CoAuthoring/node_modules/express/node_modules/proxy-addr/node_modules/ipaddr.js/lib/ipaddr.js b/CoAuthoring/node_modules/express/node_modules/proxy-addr/node_modules/ipaddr.js/lib/ipaddr.js
deleted file mode 100644
index 2319737fa3..0000000000
--- a/CoAuthoring/node_modules/express/node_modules/proxy-addr/node_modules/ipaddr.js/lib/ipaddr.js
+++ /dev/null
@@ -1,401 +0,0 @@
-(function() {
- var expandIPv6, ipaddr, ipv4Part, ipv4Regexes, ipv6Part, ipv6Regexes, matchCIDR, root;
-
- ipaddr = {};
-
- root = this;
-
- if ((typeof module !== "undefined" && module !== null) && module.exports) {
- module.exports = ipaddr;
- } else {
- root['ipaddr'] = ipaddr;
- }
-
- matchCIDR = function(first, second, partSize, cidrBits) {
- var part, shift;
- if (first.length !== second.length) {
- throw new Error("ipaddr: cannot match CIDR for objects with different lengths");
- }
- part = 0;
- while (cidrBits > 0) {
- shift = partSize - cidrBits;
- if (shift < 0) {
- shift = 0;
- }
- if (first[part] >> shift !== second[part] >> shift) {
- return false;
- }
- cidrBits -= partSize;
- part += 1;
- }
- return true;
- };
-
- ipaddr.subnetMatch = function(address, rangeList, defaultName) {
- var rangeName, rangeSubnets, subnet, _i, _len;
- if (defaultName == null) {
- defaultName = 'unicast';
- }
- for (rangeName in rangeList) {
- rangeSubnets = rangeList[rangeName];
- if (toString.call(rangeSubnets[0]) !== '[object Array]') {
- rangeSubnets = [rangeSubnets];
- }
- for (_i = 0, _len = rangeSubnets.length; _i < _len; _i++) {
- subnet = rangeSubnets[_i];
- if (address.match.apply(address, subnet)) {
- return rangeName;
- }
- }
- }
- return defaultName;
- };
-
- ipaddr.IPv4 = (function() {
- function IPv4(octets) {
- var octet, _i, _len;
- if (octets.length !== 4) {
- throw new Error("ipaddr: ipv4 octet count should be 4");
- }
- for (_i = 0, _len = octets.length; _i < _len; _i++) {
- octet = octets[_i];
- if (!((0 <= octet && octet <= 255))) {
- throw new Error("ipaddr: ipv4 octet is a byte");
- }
- }
- this.octets = octets;
- }
-
- IPv4.prototype.kind = function() {
- return 'ipv4';
- };
-
- IPv4.prototype.toString = function() {
- return this.octets.join(".");
- };
-
- IPv4.prototype.toByteArray = function() {
- return this.octets.slice(0);
- };
-
- IPv4.prototype.match = function(other, cidrRange) {
- if (other.kind() !== 'ipv4') {
- throw new Error("ipaddr: cannot match ipv4 address with non-ipv4 one");
- }
- return matchCIDR(this.octets, other.octets, 8, cidrRange);
- };
-
- IPv4.prototype.SpecialRanges = {
- broadcast: [[new IPv4([255, 255, 255, 255]), 32]],
- multicast: [[new IPv4([224, 0, 0, 0]), 4]],
- linkLocal: [[new IPv4([169, 254, 0, 0]), 16]],
- loopback: [[new IPv4([127, 0, 0, 0]), 8]],
- "private": [[new IPv4([10, 0, 0, 0]), 8], [new IPv4([172, 16, 0, 0]), 12], [new IPv4([192, 168, 0, 0]), 16]],
- reserved: [[new IPv4([192, 0, 0, 0]), 24], [new IPv4([192, 0, 2, 0]), 24], [new IPv4([192, 88, 99, 0]), 24], [new IPv4([198, 51, 100, 0]), 24], [new IPv4([203, 0, 113, 0]), 24], [new IPv4([240, 0, 0, 0]), 4]]
- };
-
- IPv4.prototype.range = function() {
- return ipaddr.subnetMatch(this, this.SpecialRanges);
- };
-
- IPv4.prototype.toIPv4MappedAddress = function() {
- return ipaddr.IPv6.parse("::ffff:" + (this.toString()));
- };
-
- return IPv4;
-
- })();
-
- ipv4Part = "(0?\\d+|0x[a-f0-9]+)";
-
- ipv4Regexes = {
- fourOctet: new RegExp("^" + ipv4Part + "\\." + ipv4Part + "\\." + ipv4Part + "\\." + ipv4Part + "$", 'i'),
- longValue: new RegExp("^" + ipv4Part + "$", 'i')
- };
-
- ipaddr.IPv4.parser = function(string) {
- var match, parseIntAuto, part, shift, value;
- parseIntAuto = function(string) {
- if (string[0] === "0" && string[1] !== "x") {
- return parseInt(string, 8);
- } else {
- return parseInt(string);
- }
- };
- if (match = string.match(ipv4Regexes.fourOctet)) {
- return (function() {
- var _i, _len, _ref, _results;
- _ref = match.slice(1, 6);
- _results = [];
- for (_i = 0, _len = _ref.length; _i < _len; _i++) {
- part = _ref[_i];
- _results.push(parseIntAuto(part));
- }
- return _results;
- })();
- } else if (match = string.match(ipv4Regexes.longValue)) {
- value = parseIntAuto(match[1]);
- return ((function() {
- var _i, _results;
- _results = [];
- for (shift = _i = 0; _i <= 24; shift = _i += 8) {
- _results.push((value >> shift) & 0xff);
- }
- return _results;
- })()).reverse();
- } else {
- return null;
- }
- };
-
- ipaddr.IPv6 = (function() {
- function IPv6(parts) {
- var part, _i, _len;
- if (parts.length !== 8) {
- throw new Error("ipaddr: ipv6 part count should be 8");
- }
- for (_i = 0, _len = parts.length; _i < _len; _i++) {
- part = parts[_i];
- if (!((0 <= part && part <= 0xffff))) {
- throw new Error("ipaddr: ipv6 part should fit to two octets");
- }
- }
- this.parts = parts;
- }
-
- IPv6.prototype.kind = function() {
- return 'ipv6';
- };
-
- IPv6.prototype.toString = function() {
- var compactStringParts, part, pushPart, state, stringParts, _i, _len;
- stringParts = (function() {
- var _i, _len, _ref, _results;
- _ref = this.parts;
- _results = [];
- for (_i = 0, _len = _ref.length; _i < _len; _i++) {
- part = _ref[_i];
- _results.push(part.toString(16));
- }
- return _results;
- }).call(this);
- compactStringParts = [];
- pushPart = function(part) {
- return compactStringParts.push(part);
- };
- state = 0;
- for (_i = 0, _len = stringParts.length; _i < _len; _i++) {
- part = stringParts[_i];
- switch (state) {
- case 0:
- if (part === '0') {
- pushPart('');
- } else {
- pushPart(part);
- }
- state = 1;
- break;
- case 1:
- if (part === '0') {
- state = 2;
- } else {
- pushPart(part);
- }
- break;
- case 2:
- if (part !== '0') {
- pushPart('');
- pushPart(part);
- state = 3;
- }
- break;
- case 3:
- pushPart(part);
- }
- }
- if (state === 2) {
- pushPart('');
- pushPart('');
- }
- return compactStringParts.join(":");
- };
-
- IPv6.prototype.toByteArray = function() {
- var bytes, part, _i, _len, _ref;
- bytes = [];
- _ref = this.parts;
- for (_i = 0, _len = _ref.length; _i < _len; _i++) {
- part = _ref[_i];
- bytes.push(part >> 8);
- bytes.push(part & 0xff);
- }
- return bytes;
- };
-
- IPv6.prototype.toNormalizedString = function() {
- var part;
- return ((function() {
- var _i, _len, _ref, _results;
- _ref = this.parts;
- _results = [];
- for (_i = 0, _len = _ref.length; _i < _len; _i++) {
- part = _ref[_i];
- _results.push(part.toString(16));
- }
- return _results;
- }).call(this)).join(":");
- };
-
- IPv6.prototype.match = function(other, cidrRange) {
- if (other.kind() !== 'ipv6') {
- throw new Error("ipaddr: cannot match ipv6 address with non-ipv6 one");
- }
- return matchCIDR(this.parts, other.parts, 16, cidrRange);
- };
-
- IPv6.prototype.SpecialRanges = {
- unspecified: [new IPv6([0, 0, 0, 0, 0, 0, 0, 0]), 128],
- linkLocal: [new IPv6([0xfe80, 0, 0, 0, 0, 0, 0, 0]), 10],
- multicast: [new IPv6([0xff00, 0, 0, 0, 0, 0, 0, 0]), 8],
- loopback: [new IPv6([0, 0, 0, 0, 0, 0, 0, 1]), 128],
- uniqueLocal: [new IPv6([0xfc00, 0, 0, 0, 0, 0, 0, 0]), 7],
- ipv4Mapped: [new IPv6([0, 0, 0, 0, 0, 0xffff, 0, 0]), 96],
- rfc6145: [new IPv6([0, 0, 0, 0, 0xffff, 0, 0, 0]), 96],
- rfc6052: [new IPv6([0x64, 0xff9b, 0, 0, 0, 0, 0, 0]), 96],
- '6to4': [new IPv6([0x2002, 0, 0, 0, 0, 0, 0, 0]), 16],
- teredo: [new IPv6([0x2001, 0, 0, 0, 0, 0, 0, 0]), 32],
- reserved: [[new IPv6([0x2001, 0xdb8, 0, 0, 0, 0, 0, 0]), 32]]
- };
-
- IPv6.prototype.range = function() {
- return ipaddr.subnetMatch(this, this.SpecialRanges);
- };
-
- IPv6.prototype.isIPv4MappedAddress = function() {
- return this.range() === 'ipv4Mapped';
- };
-
- IPv6.prototype.toIPv4Address = function() {
- var high, low, _ref;
- if (!this.isIPv4MappedAddress()) {
- throw new Error("ipaddr: trying to convert a generic ipv6 address to ipv4");
- }
- _ref = this.parts.slice(-2), high = _ref[0], low = _ref[1];
- return new ipaddr.IPv4([high >> 8, high & 0xff, low >> 8, low & 0xff]);
- };
-
- return IPv6;
-
- })();
-
- ipv6Part = "(?:[0-9a-f]+::?)+";
-
- ipv6Regexes = {
- "native": new RegExp("^(::)?(" + ipv6Part + ")?([0-9a-f]+)?(::)?$", 'i'),
- transitional: new RegExp(("^((?:" + ipv6Part + ")|(?:::)(?:" + ipv6Part + ")?)") + ("" + ipv4Part + "\\." + ipv4Part + "\\." + ipv4Part + "\\." + ipv4Part + "$"), 'i')
- };
-
- expandIPv6 = function(string, parts) {
- var colonCount, lastColon, part, replacement, replacementCount;
- if (string.indexOf('::') !== string.lastIndexOf('::')) {
- return null;
- }
- colonCount = 0;
- lastColon = -1;
- while ((lastColon = string.indexOf(':', lastColon + 1)) >= 0) {
- colonCount++;
- }
- if (string[0] === ':') {
- colonCount--;
- }
- if (string[string.length - 1] === ':') {
- colonCount--;
- }
- replacementCount = parts - colonCount;
- replacement = ':';
- while (replacementCount--) {
- replacement += '0:';
- }
- string = string.replace('::', replacement);
- if (string[0] === ':') {
- string = string.slice(1);
- }
- if (string[string.length - 1] === ':') {
- string = string.slice(0, -1);
- }
- return (function() {
- var _i, _len, _ref, _results;
- _ref = string.split(":");
- _results = [];
- for (_i = 0, _len = _ref.length; _i < _len; _i++) {
- part = _ref[_i];
- _results.push(parseInt(part, 16));
- }
- return _results;
- })();
- };
-
- ipaddr.IPv6.parser = function(string) {
- var match, parts;
- if (string.match(ipv6Regexes['native'])) {
- return expandIPv6(string, 8);
- } else if (match = string.match(ipv6Regexes['transitional'])) {
- parts = expandIPv6(match[1].slice(0, -1), 6);
- if (parts) {
- parts.push(parseInt(match[2]) << 8 | parseInt(match[3]));
- parts.push(parseInt(match[4]) << 8 | parseInt(match[5]));
- return parts;
- }
- }
- return null;
- };
-
- ipaddr.IPv4.isIPv4 = ipaddr.IPv6.isIPv6 = function(string) {
- return this.parser(string) !== null;
- };
-
- ipaddr.IPv4.isValid = ipaddr.IPv6.isValid = function(string) {
- var e;
- try {
- new this(this.parser(string));
- return true;
- } catch (_error) {
- e = _error;
- return false;
- }
- };
-
- ipaddr.IPv4.parse = ipaddr.IPv6.parse = function(string) {
- var parts;
- parts = this.parser(string);
- if (parts === null) {
- throw new Error("ipaddr: string is not formatted like ip address");
- }
- return new this(parts);
- };
-
- ipaddr.isValid = function(string) {
- return ipaddr.IPv6.isValid(string) || ipaddr.IPv4.isValid(string);
- };
-
- ipaddr.parse = function(string) {
- if (ipaddr.IPv6.isIPv6(string)) {
- return ipaddr.IPv6.parse(string);
- } else if (ipaddr.IPv4.isIPv4(string)) {
- return ipaddr.IPv4.parse(string);
- } else {
- throw new Error("ipaddr: the address has neither IPv6 nor IPv4 format");
- }
- };
-
- ipaddr.process = function(string) {
- var addr;
- addr = this.parse(string);
- if (addr.kind() === 'ipv6' && addr.isIPv4MappedAddress()) {
- return addr.toIPv4Address();
- } else {
- return addr;
- }
- };
-
-}).call(this);
diff --git a/CoAuthoring/node_modules/express/node_modules/proxy-addr/node_modules/ipaddr.js/package.json b/CoAuthoring/node_modules/express/node_modules/proxy-addr/node_modules/ipaddr.js/package.json
deleted file mode 100644
index 5d4d8ebcc0..0000000000
--- a/CoAuthoring/node_modules/express/node_modules/proxy-addr/node_modules/ipaddr.js/package.json
+++ /dev/null
@@ -1,42 +0,0 @@
-{
- "name": "ipaddr.js",
- "description": "A library for manipulating IPv4 and IPv6 addresses in JavaScript.",
- "version": "0.1.3",
- "author": {
- "name": "Peter Zotov",
- "email": "whitequark@whitequark.org"
- },
- "directories": {
- "lib": "./lib"
- },
- "dependencies": {},
- "devDependencies": {
- "coffee-script": "~1.6",
- "nodeunit": "~0.5.3",
- "uglify-js": "latest"
- },
- "scripts": {
- "test": "cake build test"
- },
- "keywords": [
- "ip",
- "ipv4",
- "ipv6"
- ],
- "repository": {
- "type": "git",
- "url": "git://github.com/whitequark/ipaddr.js"
- },
- "main": "./lib/ipaddr",
- "engines": {
- "node": ">= 0.2.5"
- },
- "readme": "# ipaddr.js — an IPv6 and IPv4 address manipulation library\n\nipaddr.js is a small (1.9K minified and gzipped) library for manipulating\nIP addresses in JavaScript environments. It runs on both CommonJS runtimes\n(e.g. [nodejs]) and in a web browser.\n\nipaddr.js allows you to verify and parse string representation of an IP\naddress, match it against a CIDR range or range list, determine if it falls\ninto some reserved ranges (examples include loopback and private ranges),\nand convert between IPv4 and IPv4-mapped IPv6 addresses.\n\n[nodejs]: http://nodejs.org\n\n## Installation\n\n`npm install ipaddr.js`\n\n## API\n\nipaddr.js defines one object in the global scope: `ipaddr`. In CommonJS,\nit is exported from the module:\n\n```js\nvar ipaddr = require('ipaddr.js');\n```\n\nThe API consists of several global methods and two classes: ipaddr.IPv6 and ipaddr.IPv4.\n\n### Global methods\n\nThere are three global methods defined: `ipaddr.isValid`, `ipaddr.parse` and\n`ipaddr.process`. All of them receive a string as a single parameter.\n\nThe `ipaddr.isValid` method returns `true` if the address is a valid IPv4 or\nIPv6 address, and `false` otherwise. It does not throw any exceptions.\n\nThe `ipaddr.parse` method returns an object representing the IP address,\nor throws an `Error` if the passed string is not a valid representation of an\nIP address.\n\nThe `ipaddr.process` method works just like the `ipaddr.parse` one, but it\nautomatically converts IPv4-mapped IPv6 addresses to their IPv4 couterparts\nbefore returning. It is useful when you have a Node.js instance listening\non an IPv6 socket, and the `net.ivp6.bindv6only` sysctl parameter (or its\nequivalent on non-Linux OS) is set to 0. In this case, you can accept IPv4\nconnections on your IPv6-only socket, but the remote address will be mangled.\nUse `ipaddr.process` method to automatically demangle it.\n\n### Object representation\n\nParsing methods return an object which descends from `ipaddr.IPv6` or\n`ipaddr.IPv4`. These objects share some properties, but most of them differ.\n\n#### Shared properties\n\nOne can determine the type of address by calling `addr.kind()`. It will return\neither `\"ipv6\"` or `\"ipv4\"`.\n\nAn address can be converted back to its string representation with `addr.toString()`.\nNote that this method:\n * does not return the original string used to create the object (in fact, there is\n no way of getting that string)\n * returns a compact representation (when it is applicable)\n\nA `match(range, bits)` method can be used to check if the address falls into a\ncertain CIDR range.\nNote that an address can be (obviously) matched only against an address of the same type.\n\nFor example:\n\n```js\nvar addr = ipaddr.parse(\"2001:db8:1234::1\");\nvar range = ipaddr.parse(\"2001:db8::\");\n\naddr.match(range, 32); // => true\n```\n\nA `range()` method returns one of predefined names for several special ranges defined\nby IP protocols. The exact names (and their respective CIDR ranges) can be looked up\nin the source: [IPv6 ranges] and [IPv4 ranges]. Some common ones include `\"unicast\"`\n(the default one) and `\"reserved\"`.\n\nYou can match against your own range list by using\n`ipaddr.subnetMatch(address, rangeList, defaultName)` method. It can work with both\nIPv6 and IPv4 addresses, and accepts a name-to-subnet map as the range list. For example:\n\n```js\nvar rangeList = {\n documentationOnly: [ ipaddr.parse('2001:db8::'), 32 ],\n tunnelProviders: [\n [ ipaddr.parse('2001:470::'), 32 ], // he.net\n [ ipaddr.parse('2001:5c0::'), 32 ] // freenet6\n ]\n};\nipaddr.subnetMatch(ipaddr.parse('2001:470:8:66::1'), rangeList, 'unknown'); // => \"he.net\"\n```\n\nThe addresses can be converted to their byte representation with `toByteArray()`.\n(Actually, JavaScript mostly does not know about byte buffers. They are emulated with\narrays of numbers, each in range of 0..255.)\n\n```js\nvar bytes = ipaddr.parse('2a00:1450:8007::68').toByteArray(); // ipv6.google.com\nbytes // => [42, 0x00, 0x14, 0x50, 0x80, 0x07, 0x00, , 0x00, 0x68 ]\n```\n\nThe `ipaddr.IPv4` and `ipaddr.IPv6` objects have some methods defined, too. All of them\nhave the same interface for both protocols, and are similar to global methods.\n\n`ipaddr.IPvX.isValid(string)` can be used to check if the string is a valid address\nfor particular protocol, and `ipaddr.IPvX.parse(string)` is the error-throwing parser.\n\n[IPv6 ranges]: https://github.com/whitequark/ipaddr.js/blob/master/src/ipaddr.coffee#L186\n[IPv4 ranges]: https://github.com/whitequark/ipaddr.js/blob/master/src/ipaddr.coffee#L71\n\n#### IPv6 properties\n\nSometimes you will want to convert IPv6 not to a compact string representation (with\nthe `::` substitution); the `toNormalizedString()` method will return an address where\nall zeroes are explicit.\n\nFor example:\n\n```js\nvar addr = ipaddr.parse(\"2001:0db8::0001\");\naddr.toString(); // => \"2001:db8::1\"\naddr.toNormalizedString(); // => \"2001:db8:0:0:0:0:0:1\"\n```\n\nThe `isIPv4MappedAddress()` method will return `true` if this address is an IPv4-mapped\none, and `toIPv4Address()` will return an IPv4 object address.\n\nTo access the underlying binary representation of the address, use `addr.parts`.\n\n```js\nvar addr = ipaddr.parse(\"2001:db8:10::1234:DEAD\");\naddr.parts // => [0x2001, 0xdb8, 0x10, 0, 0, 0, 0x1234, 0xdead]\n```\n\n#### IPv4 properties\n\n`toIPv4MappedAddress()` will return a corresponding IPv4-mapped IPv6 address.\n\nTo access the underlying representation of the address, use `addr.octets`.\n\n```js\nvar addr = ipaddr.parse(\"192.168.1.1\");\naddr.octets // => [192, 168, 1, 1]\n```\n",
- "readmeFilename": "README.md",
- "bugs": {
- "url": "https://github.com/whitequark/ipaddr.js/issues"
- },
- "homepage": "https://github.com/whitequark/ipaddr.js",
- "_id": "ipaddr.js@0.1.3",
- "_from": "ipaddr.js@0.1.3"
-}
diff --git a/CoAuthoring/node_modules/express/node_modules/proxy-addr/node_modules/ipaddr.js/src/ipaddr.coffee b/CoAuthoring/node_modules/express/node_modules/proxy-addr/node_modules/ipaddr.js/src/ipaddr.coffee
deleted file mode 100644
index 4c89ded65c..0000000000
--- a/CoAuthoring/node_modules/express/node_modules/proxy-addr/node_modules/ipaddr.js/src/ipaddr.coffee
+++ /dev/null
@@ -1,344 +0,0 @@
-# Define the main object
-ipaddr = {}
-
-root = this
-
-# Export for both the CommonJS and browser-like environment
-if module? && module.exports
- module.exports = ipaddr
-else
- root['ipaddr'] = ipaddr
-
-# A generic CIDR (Classless Inter-Domain Routing) RFC1518 range matcher.
-matchCIDR = (first, second, partSize, cidrBits) ->
- if first.length != second.length
- throw new Error "ipaddr: cannot match CIDR for objects with different lengths"
-
- part = 0
- while cidrBits > 0
- shift = partSize - cidrBits
- shift = 0 if shift < 0
-
- if first[part] >> shift != second[part] >> shift
- return false
-
- cidrBits -= partSize
- part += 1
-
- return true
-
-# An utility function to ease named range matching. See examples below.
-ipaddr.subnetMatch = (address, rangeList, defaultName='unicast') ->
- for rangeName, rangeSubnets of rangeList
- # ECMA5 Array.isArray isn't available everywhere
- if toString.call(rangeSubnets[0]) != '[object Array]'
- rangeSubnets = [ rangeSubnets ]
-
- for subnet in rangeSubnets
- return rangeName if address.match.apply(address, subnet)
-
- return defaultName
-
-# An IPv4 address (RFC791).
-class ipaddr.IPv4
- # Constructs a new IPv4 address from an array of four octets.
- # Verifies the input.
- constructor: (octets) ->
- if octets.length != 4
- throw new Error "ipaddr: ipv4 octet count should be 4"
-
- for octet in octets
- if !(0 <= octet <= 255)
- throw new Error "ipaddr: ipv4 octet is a byte"
-
- @octets = octets
-
- # The 'kind' method exists on both IPv4 and IPv6 classes.
- kind: ->
- return 'ipv4'
-
- # Returns the address in convenient, decimal-dotted format.
- toString: ->
- return @octets.join "."
-
- # Returns an array of byte-sized values in network order
- toByteArray: ->
- return @octets.slice(0) # octets.clone
-
- # Checks if this address matches other one within given CIDR range.
- match: (other, cidrRange) ->
- if other.kind() != 'ipv4'
- throw new Error "ipaddr: cannot match ipv4 address with non-ipv4 one"
-
- return matchCIDR(this.octets, other.octets, 8, cidrRange)
-
- # Special IPv4 address ranges.
- SpecialRanges:
- broadcast: [
- [ new IPv4([255, 255, 255, 255]), 32 ]
- ]
- multicast: [ # RFC3171
- [ new IPv4([224, 0, 0, 0]), 4 ]
- ]
- linkLocal: [ # RFC3927
- [ new IPv4([169, 254, 0, 0]), 16 ]
- ]
- loopback: [ # RFC5735
- [ new IPv4([127, 0, 0, 0]), 8 ]
- ]
- private: [ # RFC1918
- [ new IPv4([10, 0, 0, 0]), 8 ]
- [ new IPv4([172, 16, 0, 0]), 12 ]
- [ new IPv4([192, 168, 0, 0]), 16 ]
- ]
- reserved: [ # Reserved and testing-only ranges; RFCs 5735, 5737, 2544, 1700
- [ new IPv4([192, 0, 0, 0]), 24 ]
- [ new IPv4([192, 0, 2, 0]), 24 ]
- [ new IPv4([192, 88, 99, 0]), 24 ]
- [ new IPv4([198, 51, 100, 0]), 24 ]
- [ new IPv4([203, 0, 113, 0]), 24 ]
- [ new IPv4([240, 0, 0, 0]), 4 ]
- ]
-
- # Checks if the address corresponds to one of the special ranges.
- range: ->
- return ipaddr.subnetMatch(this, @SpecialRanges)
-
- # Convrets this IPv4 address to an IPv4-mapped IPv6 address.
- toIPv4MappedAddress: ->
- return ipaddr.IPv6.parse "::ffff:#{@toString()}"
-
-# A list of regular expressions that match arbitrary IPv4 addresses,
-# for which a number of weird notations exist.
-# Note that an address like 0010.0xa5.1.1 is considered legal.
-ipv4Part = "(0?\\d+|0x[a-f0-9]+)"
-ipv4Regexes =
- fourOctet: new RegExp "^#{ipv4Part}\\.#{ipv4Part}\\.#{ipv4Part}\\.#{ipv4Part}$", 'i'
- longValue: new RegExp "^#{ipv4Part}$", 'i'
-
-# Classful variants (like a.b, where a is an octet, and b is a 24-bit
-# value representing last three octets; this corresponds to a class C
-# address) are omitted due to classless nature of modern Internet.
-ipaddr.IPv4.parser = (string) ->
- parseIntAuto = (string) ->
- if string[0] == "0" && string[1] != "x"
- parseInt(string, 8)
- else
- parseInt(string)
-
- # parseInt recognizes all that octal & hexadecimal weirdness for us
- if match = string.match(ipv4Regexes.fourOctet)
- return (parseIntAuto(part) for part in match[1..5])
- else if match = string.match(ipv4Regexes.longValue)
- value = parseIntAuto(match[1])
- return ((value >> shift) & 0xff for shift in [0..24] by 8).reverse()
- else
- return null
-
-# An IPv6 address (RFC2460)
-class ipaddr.IPv6
- # Constructs an IPv6 address from an array of eight 16-bit parts.
- # Throws an error if the input is invalid.
- constructor: (parts) ->
- if parts.length != 8
- throw new Error "ipaddr: ipv6 part count should be 8"
-
- for part in parts
- if !(0 <= part <= 0xffff)
- throw new Error "ipaddr: ipv6 part should fit to two octets"
-
- @parts = parts
-
- # The 'kind' method exists on both IPv4 and IPv6 classes.
- kind: ->
- return 'ipv6'
-
- # Returns the address in compact, human-readable format like
- # 2001:db8:8:66::1
- toString: ->
- stringParts = (part.toString(16) for part in @parts)
-
- compactStringParts = []
- pushPart = (part) -> compactStringParts.push part
-
- state = 0
- for part in stringParts
- switch state
- when 0
- if part == '0'
- pushPart('')
- else
- pushPart(part)
-
- state = 1
- when 1
- if part == '0'
- state = 2
- else
- pushPart(part)
- when 2
- unless part == '0'
- pushPart('')
- pushPart(part)
- state = 3
- when 3
- pushPart(part)
-
- if state == 2
- pushPart('')
- pushPart('')
-
- return compactStringParts.join ":"
-
- # Returns an array of byte-sized values in network order
- toByteArray: ->
- bytes = []
- for part in @parts
- bytes.push(part >> 8)
- bytes.push(part & 0xff)
-
- return bytes
-
- # Returns the address in expanded format with all zeroes included, like
- # 2001:db8:8:66:0:0:0:1
- toNormalizedString: ->
- return (part.toString(16) for part in @parts).join ":"
-
- # Checks if this address matches other one within given CIDR range.
- match: (other, cidrRange) ->
- if other.kind() != 'ipv6'
- throw new Error "ipaddr: cannot match ipv6 address with non-ipv6 one"
-
- return matchCIDR(this.parts, other.parts, 16, cidrRange)
-
- # Special IPv6 ranges
- SpecialRanges:
- unspecified: [ new IPv6([0, 0, 0, 0, 0, 0, 0, 0]), 128 ] # RFC4291, here and after
- linkLocal: [ new IPv6([0xfe80, 0, 0, 0, 0, 0, 0, 0]), 10 ]
- multicast: [ new IPv6([0xff00, 0, 0, 0, 0, 0, 0, 0]), 8 ]
- loopback: [ new IPv6([0, 0, 0, 0, 0, 0, 0, 1]), 128 ]
- uniqueLocal: [ new IPv6([0xfc00, 0, 0, 0, 0, 0, 0, 0]), 7 ]
- ipv4Mapped: [ new IPv6([0, 0, 0, 0, 0, 0xffff, 0, 0]), 96 ]
- rfc6145: [ new IPv6([0, 0, 0, 0, 0xffff, 0, 0, 0]), 96 ] # RFC6145
- rfc6052: [ new IPv6([0x64, 0xff9b, 0, 0, 0, 0, 0, 0]), 96 ] # RFC6052
- '6to4': [ new IPv6([0x2002, 0, 0, 0, 0, 0, 0, 0]), 16 ] # RFC3056
- teredo: [ new IPv6([0x2001, 0, 0, 0, 0, 0, 0, 0]), 32 ] # RFC6052, RFC6146
- reserved: [
- [ new IPv6([ 0x2001, 0xdb8, 0, 0, 0, 0, 0, 0]), 32 ] # RFC4291
- ]
-
- # Checks if the address corresponds to one of the special ranges.
- range: ->
- return ipaddr.subnetMatch(this, @SpecialRanges)
-
- # Checks if this address is an IPv4-mapped IPv6 address.
- isIPv4MappedAddress: ->
- return @range() == 'ipv4Mapped'
-
- # Converts this address to IPv4 address if it is an IPv4-mapped IPv6 address.
- # Throws an error otherwise.
- toIPv4Address: ->
- unless @isIPv4MappedAddress()
- throw new Error "ipaddr: trying to convert a generic ipv6 address to ipv4"
-
- [high, low] = @parts[-2..-1]
-
- return new ipaddr.IPv4([high >> 8, high & 0xff, low >> 8, low & 0xff])
-
-# IPv6-matching regular expressions.
-# For IPv6, the task is simpler: it is enough to match the colon-delimited
-# hexadecimal IPv6 and a transitional variant with dotted-decimal IPv4 at
-# the end.
-ipv6Part = "(?:[0-9a-f]+::?)+"
-ipv6Regexes =
- native: new RegExp "^(::)?(#{ipv6Part})?([0-9a-f]+)?(::)?$", 'i'
- transitional: new RegExp "^((?:#{ipv6Part})|(?:::)(?:#{ipv6Part})?)" +
- "#{ipv4Part}\\.#{ipv4Part}\\.#{ipv4Part}\\.#{ipv4Part}$", 'i'
-
-# Expand :: in an IPv6 address or address part consisting of `parts` groups.
-expandIPv6 = (string, parts) ->
- # More than one '::' means invalid adddress
- if string.indexOf('::') != string.lastIndexOf('::')
- return null
-
- # How many parts do we already have?
- colonCount = 0
- lastColon = -1
- while (lastColon = string.indexOf(':', lastColon + 1)) >= 0
- colonCount++
-
- # 0::0 is two parts more than ::
- colonCount-- if string[0] == ':'
- colonCount-- if string[string.length-1] == ':'
-
- # replacement = ':' + '0:' * (parts - colonCount)
- replacementCount = parts - colonCount
- replacement = ':'
- while replacementCount--
- replacement += '0:'
-
- # Insert the missing zeroes
- string = string.replace('::', replacement)
-
- # Trim any garbage which may be hanging around if :: was at the edge in
- # the source string
- string = string[1..-1] if string[0] == ':'
- string = string[0..-2] if string[string.length-1] == ':'
-
- return (parseInt(part, 16) for part in string.split(":"))
-
-# Parse an IPv6 address.
-ipaddr.IPv6.parser = (string) ->
- if string.match(ipv6Regexes['native'])
- return expandIPv6(string, 8)
-
- else if match = string.match(ipv6Regexes['transitional'])
- parts = expandIPv6(match[1][0..-2], 6)
- if parts
- parts.push(parseInt(match[2]) << 8 | parseInt(match[3]))
- parts.push(parseInt(match[4]) << 8 | parseInt(match[5]))
- return parts
-
- return null
-
-# Checks if a given string is formatted like IPv4/IPv6 address.
-ipaddr.IPv4.isIPv4 = ipaddr.IPv6.isIPv6 = (string) ->
- return @parser(string) != null
-
-# Checks if a given string is a valid IPv4/IPv6 address.
-ipaddr.IPv4.isValid = ipaddr.IPv6.isValid = (string) ->
- try
- new this(@parser(string))
- return true
- catch e
- return false
-
-# Tries to parse and validate a string with IPv4/IPv6 address.
-# Throws an error if it fails.
-ipaddr.IPv4.parse = ipaddr.IPv6.parse = (string) ->
- parts = @parser(string)
- if parts == null
- throw new Error "ipaddr: string is not formatted like ip address"
-
- return new this(parts)
-
-# Checks if the address is valid IP address
-ipaddr.isValid = (string) ->
- return ipaddr.IPv6.isValid(string) || ipaddr.IPv4.isValid(string)
-
-# Try to parse an address and throw an error if it is impossible
-ipaddr.parse = (string) ->
- if ipaddr.IPv6.isIPv6(string)
- return ipaddr.IPv6.parse(string)
- else if ipaddr.IPv4.isIPv4(string)
- return ipaddr.IPv4.parse(string)
- else
- throw new Error "ipaddr: the address has neither IPv6 nor IPv4 format"
-
-# Parse an address and return plain IPv4 address if it is an IPv4-mapped address
-ipaddr.process = (string) ->
- addr = @parse(string)
- if addr.kind() == 'ipv6' && addr.isIPv4MappedAddress()
- return addr.toIPv4Address()
- else
- return addr
diff --git a/CoAuthoring/node_modules/express/node_modules/proxy-addr/node_modules/ipaddr.js/test/ipaddr.test.coffee b/CoAuthoring/node_modules/express/node_modules/proxy-addr/node_modules/ipaddr.js/test/ipaddr.test.coffee
deleted file mode 100644
index 56751dabf1..0000000000
--- a/CoAuthoring/node_modules/express/node_modules/proxy-addr/node_modules/ipaddr.js/test/ipaddr.test.coffee
+++ /dev/null
@@ -1,209 +0,0 @@
-ipaddr = require '../lib/ipaddr'
-
-module.exports =
- 'should define main classes': (test) ->
- test.ok(ipaddr.IPv4?, 'defines IPv4 class')
- test.ok(ipaddr.IPv6?, 'defines IPv6 class')
- test.done()
-
- 'can construct IPv4 from octets': (test) ->
- test.doesNotThrow ->
- new ipaddr.IPv4([192, 168, 1, 2])
- test.done()
-
- 'refuses to construct invalid IPv4': (test) ->
- test.throws ->
- new ipaddr.IPv4([300, 1, 2, 3])
- test.throws ->
- new ipaddr.IPv4([8, 8, 8])
- test.done()
-
- 'converts IPv4 to string correctly': (test) ->
- addr = new ipaddr.IPv4([192, 168, 1, 1])
- test.equal(addr.toString(), '192.168.1.1')
- test.done()
-
- 'returns correct kind for IPv4': (test) ->
- addr = new ipaddr.IPv4([1, 2, 3, 4])
- test.equal(addr.kind(), 'ipv4')
- test.done()
-
- 'allows to access IPv4 octets': (test) ->
- addr = new ipaddr.IPv4([42, 0, 0, 0])
- test.equal(addr.octets[0], 42)
- test.done()
-
- 'checks IPv4 address format': (test) ->
- test.equal(ipaddr.IPv4.isIPv4('192.168.007.0xa'), true)
- test.equal(ipaddr.IPv4.isIPv4('1024.0.0.1'), true)
- test.equal(ipaddr.IPv4.isIPv4('8.0xa.wtf.6'), false)
- test.done()
-
- 'validates IPv4 addresses': (test) ->
- test.equal(ipaddr.IPv4.isValid('192.168.007.0xa'), true)
- test.equal(ipaddr.IPv4.isValid('1024.0.0.1'), false)
- test.equal(ipaddr.IPv4.isValid('8.0xa.wtf.6'), false)
- test.done()
-
- 'parses IPv4 in several weird formats': (test) ->
- test.deepEqual(ipaddr.IPv4.parse('192.168.1.1').octets, [192, 168, 1, 1])
- test.deepEqual(ipaddr.IPv4.parse('0xc0.168.1.1').octets, [192, 168, 1, 1])
- test.deepEqual(ipaddr.IPv4.parse('192.0250.1.1').octets, [192, 168, 1, 1])
- test.deepEqual(ipaddr.IPv4.parse('0xc0a80101').octets, [192, 168, 1, 1])
- test.deepEqual(ipaddr.IPv4.parse('030052000401').octets, [192, 168, 1, 1])
- test.deepEqual(ipaddr.IPv4.parse('3232235777').octets, [192, 168, 1, 1])
- test.done()
-
- 'barfs at invalid IPv4': (test) ->
- test.throws ->
- ipaddr.IPv4.parse('10.0.0.wtf')
- test.done()
-
- 'matches IPv4 CIDR correctly': (test) ->
- addr = new ipaddr.IPv4([10, 5, 0, 1])
- test.equal(addr.match(ipaddr.IPv4.parse('0.0.0.0'), 0), true)
- test.equal(addr.match(ipaddr.IPv4.parse('11.0.0.0'), 8), false)
- test.equal(addr.match(ipaddr.IPv4.parse('10.0.0.0'), 8), true)
- test.equal(addr.match(ipaddr.IPv4.parse('10.0.0.1'), 8), true)
- test.equal(addr.match(ipaddr.IPv4.parse('10.0.0.10'), 8), true)
- test.equal(addr.match(ipaddr.IPv4.parse('10.5.5.0'), 16), true)
- test.equal(addr.match(ipaddr.IPv4.parse('10.4.5.0'), 16), false)
- test.equal(addr.match(ipaddr.IPv4.parse('10.4.5.0'), 15), true)
- test.equal(addr.match(ipaddr.IPv4.parse('10.5.0.2'), 32), false)
- test.equal(addr.match(addr, 32), true)
- test.done()
-
- 'detects reserved IPv4 networks': (test) ->
- test.equal(ipaddr.IPv4.parse('10.1.0.1').range(), 'private')
- test.equal(ipaddr.IPv4.parse('192.168.2.1').range(), 'private')
- test.equal(ipaddr.IPv4.parse('224.100.0.1').range(), 'multicast')
- test.equal(ipaddr.IPv4.parse('169.254.15.0').range(), 'linkLocal')
- test.equal(ipaddr.IPv4.parse('127.1.1.1').range(), 'loopback')
- test.equal(ipaddr.IPv4.parse('255.255.255.255').range(), 'broadcast')
- test.equal(ipaddr.IPv4.parse('240.1.2.3').range(), 'reserved')
- test.equal(ipaddr.IPv4.parse('8.8.8.8').range(), 'unicast')
- test.done()
-
- 'can construct IPv6 from parts': (test) ->
- test.doesNotThrow ->
- new ipaddr.IPv6([0x2001, 0xdb8, 0xf53a, 0, 0, 0, 0, 1])
- test.done()
-
- 'refuses to construct invalid IPv6': (test) ->
- test.throws ->
- new ipaddr.IPv6([0xfffff, 0, 0, 0, 0, 0, 0, 1])
- test.throws ->
- new ipaddr.IPv6([0xfffff, 0, 0, 0, 0, 0, 1])
- test.done()
-
- 'converts IPv6 to string correctly': (test) ->
- addr = new ipaddr.IPv6([0x2001, 0xdb8, 0xf53a, 0, 0, 0, 0, 1])
- test.equal(addr.toNormalizedString(), '2001:db8:f53a:0:0:0:0:1')
- test.equal(addr.toString(), '2001:db8:f53a::1')
- test.equal(new ipaddr.IPv6([0, 0, 0, 0, 0, 0, 0, 1]).toString(), '::1')
- test.equal(new ipaddr.IPv6([0x2001, 0xdb8, 0, 0, 0, 0, 0, 0]).toString(), '2001:db8::')
- test.done()
-
- 'returns correct kind for IPv6': (test) ->
- addr = new ipaddr.IPv6([0x2001, 0xdb8, 0xf53a, 0, 0, 0, 0, 1])
- test.equal(addr.kind(), 'ipv6')
- test.done()
-
- 'allows to access IPv6 address parts': (test) ->
- addr = new ipaddr.IPv6([0x2001, 0xdb8, 0xf53a, 0, 0, 42, 0, 1])
- test.equal(addr.parts[5], 42)
- test.done()
-
- 'checks IPv6 address format': (test) ->
- test.equal(ipaddr.IPv6.isIPv6('2001:db8:F53A::1'), true)
- test.equal(ipaddr.IPv6.isIPv6('200001::1'), true)
- test.equal(ipaddr.IPv6.isIPv6('::ffff:192.168.1.1'), true)
- test.equal(ipaddr.IPv6.isIPv6('::ffff:300.168.1.1'), true)
- test.equal(ipaddr.IPv6.isIPv6('::ffff:300.168.1.1:0'), false)
- test.equal(ipaddr.IPv6.isIPv6('fe80::wtf'), false)
- test.done()
-
- 'validates IPv6 addresses': (test) ->
- test.equal(ipaddr.IPv6.isValid('2001:db8:F53A::1'), true)
- test.equal(ipaddr.IPv6.isValid('200001::1'), false)
- test.equal(ipaddr.IPv6.isValid('::ffff:192.168.1.1'), true)
- test.equal(ipaddr.IPv6.isValid('::ffff:300.168.1.1'), false)
- test.equal(ipaddr.IPv6.isValid('::ffff:300.168.1.1:0'), false)
- test.equal(ipaddr.IPv6.isValid('2001:db8::F53A::1'), false)
- test.equal(ipaddr.IPv6.isValid('fe80::wtf'), false)
- test.done()
-
- 'parses IPv6 in different formats': (test) ->
- test.deepEqual(ipaddr.IPv6.parse('2001:db8:F53A:0:0:0:0:1').parts, [0x2001, 0xdb8, 0xf53a, 0, 0, 0, 0, 1])
- test.deepEqual(ipaddr.IPv6.parse('fe80::10').parts, [0xfe80, 0, 0, 0, 0, 0, 0, 0x10])
- test.deepEqual(ipaddr.IPv6.parse('2001:db8:F53A::').parts, [0x2001, 0xdb8, 0xf53a, 0, 0, 0, 0, 0])
- test.deepEqual(ipaddr.IPv6.parse('::1').parts, [0, 0, 0, 0, 0, 0, 0, 1])
- test.deepEqual(ipaddr.IPv6.parse('::').parts, [0, 0, 0, 0, 0, 0, 0, 0])
- test.done()
-
- 'barfs at invalid IPv6': (test) ->
- test.throws ->
- ipaddr.IPv6.parse('fe80::0::1')
- test.done()
-
- 'matches IPv6 CIDR correctly': (test) ->
- addr = ipaddr.IPv6.parse('2001:db8:f53a::1')
- test.equal(addr.match(ipaddr.IPv6.parse('::'), 0), true)
- test.equal(addr.match(ipaddr.IPv6.parse('2001:db8:f53a::1:1'), 64), true)
- test.equal(addr.match(ipaddr.IPv6.parse('2001:db8:f53b::1:1'), 48), false)
- test.equal(addr.match(ipaddr.IPv6.parse('2001:db8:f531::1:1'), 44), true)
- test.equal(addr.match(ipaddr.IPv6.parse('2001:db8:f500::1'), 40), true)
- test.equal(addr.match(ipaddr.IPv6.parse('2001:db9:f500::1'), 40), false)
- test.equal(addr.match(addr, 128), true)
- test.done()
-
- 'converts between IPv4-mapped IPv6 addresses and IPv4 addresses': (test) ->
- addr = ipaddr.IPv4.parse('77.88.21.11')
- mapped = addr.toIPv4MappedAddress()
- test.deepEqual(mapped.parts, [0, 0, 0, 0, 0, 0xffff, 0x4d58, 0x150b])
- test.deepEqual(mapped.toIPv4Address().octets, addr.octets)
- test.done()
-
- 'refuses to convert non-IPv4-mapped IPv6 address to IPv4 address': (test) ->
- test.throws ->
- ipaddr.IPv6.parse('2001:db8::1').toIPv4Address()
- test.done()
-
- 'detects reserved IPv6 networks': (test) ->
- test.equal(ipaddr.IPv6.parse('::').range(), 'unspecified')
- test.equal(ipaddr.IPv6.parse('fe80::1234:5678:abcd:0123').range(), 'linkLocal')
- test.equal(ipaddr.IPv6.parse('ff00::1234').range(), 'multicast')
- test.equal(ipaddr.IPv6.parse('::1').range(), 'loopback')
- test.equal(ipaddr.IPv6.parse('fc00::').range(), 'uniqueLocal')
- test.equal(ipaddr.IPv6.parse('::ffff:192.168.1.10').range(), 'ipv4Mapped')
- test.equal(ipaddr.IPv6.parse('::ffff:0:192.168.1.10').range(), 'rfc6145')
- test.equal(ipaddr.IPv6.parse('64:ff9b::1234').range(), 'rfc6052')
- test.equal(ipaddr.IPv6.parse('2002:1f63:45e8::1').range(), '6to4')
- test.equal(ipaddr.IPv6.parse('2001::4242').range(), 'teredo')
- test.equal(ipaddr.IPv6.parse('2001:db8::3210').range(), 'reserved')
- test.equal(ipaddr.IPv6.parse('2001:470:8:66::1').range(), 'unicast')
- test.done()
-
- 'is able to determine IP address type': (test) ->
- test.equal(ipaddr.parse('8.8.8.8').kind(), 'ipv4')
- test.equal(ipaddr.parse('2001:db8:3312::1').kind(), 'ipv6')
- test.done()
-
- 'throws an error if tried to parse an invalid address': (test) ->
- test.throws ->
- ipaddr.parse('::some.nonsense')
- test.done()
-
- 'correctly processes IPv4-mapped addresses': (test) ->
- test.equal(ipaddr.process('8.8.8.8').kind(), 'ipv4')
- test.equal(ipaddr.process('2001:db8:3312::1').kind(), 'ipv6')
- test.equal(ipaddr.process('::ffff:192.168.1.1').kind(), 'ipv4')
- test.done()
-
- 'correctly converts IPv6 and IPv4 addresses to byte arrays': (test) ->
- test.deepEqual(ipaddr.parse('1.2.3.4').toByteArray(),
- [0x1, 0x2, 0x3, 0x4]);
- # Fuck yeah. The first byte of Google's IPv6 address is 42. 42!
- test.deepEqual(ipaddr.parse('2a00:1450:8007::68').toByteArray(),
- [42, 0x00, 0x14, 0x50, 0x80, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x68 ])
- test.done()
diff --git a/CoAuthoring/node_modules/express/node_modules/proxy-addr/package.json b/CoAuthoring/node_modules/express/node_modules/proxy-addr/package.json
deleted file mode 100644
index 54a3beb3ea..0000000000
--- a/CoAuthoring/node_modules/express/node_modules/proxy-addr/package.json
+++ /dev/null
@@ -1,53 +0,0 @@
-{
- "name": "proxy-addr",
- "description": "Determine address of proxied request",
- "version": "1.0.3",
- "author": {
- "name": "Douglas Christopher Wilson",
- "email": "doug@somethingdoug.com"
- },
- "license": "MIT",
- "keywords": [
- "ip",
- "proxy",
- "x-forwarded-for"
- ],
- "repository": {
- "type": "git",
- "url": "git://github.com/jshttp/proxy-addr"
- },
- "dependencies": {
- "forwarded": "~0.1.0",
- "ipaddr.js": "0.1.3"
- },
- "devDependencies": {
- "benchmark": "1.0.0",
- "beautify-benchmark": "0.2.4",
- "istanbul": "0.3.2",
- "mocha": "~1.21.4",
- "should": "~4.0.0"
- },
- "files": [
- "LICENSE",
- "HISTORY.md",
- "README.md",
- "index.js"
- ],
- "engines": {
- "node": ">= 0.6"
- },
- "scripts": {
- "bench": "node benchmark/index.js",
- "test": "mocha --reporter spec --bail --check-leaks test/",
- "test-cov": "istanbul cover node_modules/mocha/bin/_mocha -- --reporter dot --check-leaks test/",
- "test-travis": "istanbul cover node_modules/mocha/bin/_mocha --report lcovonly -- --reporter spec --check-leaks test/"
- },
- "readme": "# proxy-addr\n\n[![NPM Version][npm-image]][npm-url]\n[![NPM Downloads][downloads-image]][downloads-url]\n[![Node.js Version][node-version-image]][node-version-url]\n[![Build Status][travis-image]][travis-url]\n[![Test Coverage][coveralls-image]][coveralls-url]\n\nDetermine address of proxied request\n\n## Install\n\n```sh\n$ npm install proxy-addr\n```\n\n## API\n\n```js\nvar proxyaddr = require('proxy-addr')\n```\n\n### proxyaddr(req, trust)\n\nReturn the address of the request, using the given `trust` parameter.\n\nThe `trust` argument is a function that returns `true` if you trust\nthe address, `false` if you don't. The closest untrusted address is\nreturned.\n\n```js\nproxyaddr(req, function(addr){ return addr === '127.0.0.1' })\nproxyaddr(req, function(addr, i){ return i < 1 })\n```\n\nThe `trust` arugment may also be a single IP address string or an\narray of trusted addresses, as plain IP addresses, CIDR-formatted\nstrings, or IP/netmask strings.\n\n```js\nproxyaddr(req, '127.0.0.1')\nproxyaddr(req, ['127.0.0.0/8', '10.0.0.0/8'])\nproxyaddr(req, ['127.0.0.0/255.0.0.0', '192.168.0.0/255.255.0.0'])\n```\n\nThis module also supports IPv6. Your IPv6 addresses will be normalized\nautomatically (i.e. `fe80::00ed:1` equals `fe80:0:0:0:0:0:ed:1`).\n\n```js\nproxyaddr(req, '::1')\nproxyaddr(req, ['::1/128', 'fe80::/10'])\nproxyaddr(req, ['fe80::/ffc0::'])\n```\n\nThis module will automatically work with IPv4-mapped IPv6 addresses\nas well to support node.js in IPv6-only mode. This means that you do\nnot have to specify both `::ffff:a00:1` and `10.0.0.1`.\n\nAs a convenience, this module also takes certain pre-defined names\nin addition to IP addresses, which expand into IP addresses:\n\n```js\nproxyaddr(req, 'loopback')\nproxyaddr(req, ['loopback', 'fc00:ac:1ab5:fff::1/64'])\n```\n\n * `loopback`: IPv4 and IPv6 loopback addresses (like `::1` and\n `127.0.0.1`).\n * `linklocal`: IPv4 and IPv6 link-local addresses (like\n `fe80::1:1:1:1` and `169.254.0.1`).\n * `uniquelocal`: IPv4 private addresses and IPv6 unique-local\n addresses (like `fc00:ac:1ab5:fff::1` and `192.168.0.1`).\n\nWhen `trust` is specified as a function, it will be called for each\naddress to determine if it is a trusted address. The function is\ngiven two arguments: `addr` and `i`, where `addr` is a string of\nthe address to check and `i` is a number that represents the distance\nfrom the socket address.\n\n### proxyaddr.all(req, [trust])\n\nReturn all the addresses of the request, optionally stopping at the\nfirst untrusted. This array is ordered from closest to furthest\n(i.e. `arr[0] === req.connection.remoteAddress`).\n\n```js\nproxyaddr.all(req)\n```\n\nThe optional `trust` argument takes the same arguments as `trust`\ndoes in `proxyaddr(req, trust)`.\n\n```js\nproxyaddr.all(req, 'loopback')\n```\n\n### proxyaddr.compile(val)\n\nCompiles argument `val` into a `trust` function. This function takes\nthe same arguments as `trust` does in `proxyaddr(req, trust)` and\nreturns a function suitable for `proxyaddr(req, trust)`.\n\n```js\nvar trust = proxyaddr.compile('localhost')\nvar addr = proxyaddr(req, trust)\n```\n\nThis function is meant to be optimized for use against every request.\nIt is recommend to compile a trust function up-front for the trusted\nconfiguration and pass that to `proxyaddr(req, trust)` for each request.\n\n## Testing\n\n```sh\n$ npm test\n```\n\n## Benchmarks\n\n```sh\n$ npm run-script bench\n```\n\n## License\n\n[MIT](LICENSE)\n\n[npm-image]: https://img.shields.io/npm/v/proxy-addr.svg?style=flat\n[npm-url]: https://npmjs.org/package/proxy-addr\n[node-version-image]: https://img.shields.io/node/v/proxy-addr.svg?style=flat\n[node-version-url]: http://nodejs.org/download/\n[travis-image]: https://img.shields.io/travis/jshttp/proxy-addr.svg?style=flat\n[travis-url]: https://travis-ci.org/jshttp/proxy-addr\n[coveralls-image]: https://img.shields.io/coveralls/jshttp/proxy-addr.svg?style=flat\n[coveralls-url]: https://coveralls.io/r/jshttp/proxy-addr?branch=master\n[downloads-image]: https://img.shields.io/npm/dm/proxy-addr.svg?style=flat\n[downloads-url]: https://npmjs.org/package/proxy-addr\n",
- "readmeFilename": "README.md",
- "bugs": {
- "url": "https://github.com/jshttp/proxy-addr/issues"
- },
- "homepage": "https://github.com/jshttp/proxy-addr",
- "_id": "proxy-addr@1.0.3",
- "_from": "proxy-addr@~1.0.3"
-}
diff --git a/CoAuthoring/node_modules/express/node_modules/qs/.jshintignore b/CoAuthoring/node_modules/express/node_modules/qs/.jshintignore
deleted file mode 100644
index 3c3629e647..0000000000
--- a/CoAuthoring/node_modules/express/node_modules/qs/.jshintignore
+++ /dev/null
@@ -1 +0,0 @@
-node_modules
diff --git a/CoAuthoring/node_modules/express/node_modules/qs/.jshintrc b/CoAuthoring/node_modules/express/node_modules/qs/.jshintrc
deleted file mode 100644
index 997b3f7d45..0000000000
--- a/CoAuthoring/node_modules/express/node_modules/qs/.jshintrc
+++ /dev/null
@@ -1,10 +0,0 @@
-{
- "node": true,
-
- "curly": true,
- "latedef": true,
- "quotmark": true,
- "undef": true,
- "unused": true,
- "trailing": true
-}
diff --git a/CoAuthoring/node_modules/express/node_modules/qs/.npmignore b/CoAuthoring/node_modules/express/node_modules/qs/.npmignore
deleted file mode 100644
index 7e1574dc5c..0000000000
--- a/CoAuthoring/node_modules/express/node_modules/qs/.npmignore
+++ /dev/null
@@ -1,18 +0,0 @@
-.idea
-*.iml
-npm-debug.log
-dump.rdb
-node_modules
-results.tap
-results.xml
-npm-shrinkwrap.json
-config.json
-.DS_Store
-*/.DS_Store
-*/*/.DS_Store
-._*
-*/._*
-*/*/._*
-coverage.*
-lib-cov
-complexity.md
diff --git a/CoAuthoring/node_modules/express/node_modules/qs/.travis.yml b/CoAuthoring/node_modules/express/node_modules/qs/.travis.yml
deleted file mode 100644
index c891dd0e04..0000000000
--- a/CoAuthoring/node_modules/express/node_modules/qs/.travis.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-language: node_js
-
-node_js:
- - 0.10
\ No newline at end of file
diff --git a/CoAuthoring/node_modules/express/node_modules/qs/CHANGELOG.md b/CoAuthoring/node_modules/express/node_modules/qs/CHANGELOG.md
deleted file mode 100644
index ed42edce80..0000000000
--- a/CoAuthoring/node_modules/express/node_modules/qs/CHANGELOG.md
+++ /dev/null
@@ -1,47 +0,0 @@
-
-## [**2.2.3**](https://github.com/hapijs/qs/issues?milestone=12&state=closed)
-- [**#37**](https://github.com/hapijs/qs/issues/37) parser discards first empty value in array
-- [**#36**](https://github.com/hapijs/qs/issues/36) Update to lab 4.x
-
-## [**2.2.2**](https://github.com/hapijs/qs/issues?milestone=11&state=closed)
-- [**#33**](https://github.com/hapijs/qs/issues/33) Error when plain object in a value
-- [**#34**](https://github.com/hapijs/qs/issues/34) use Object.prototype.hasOwnProperty.call instead of obj.hasOwnProperty
-- [**#24**](https://github.com/hapijs/qs/issues/24) Changelog? Semver?
-
-## [**2.2.1**](https://github.com/hapijs/qs/issues?milestone=10&state=closed)
-- [**#32**](https://github.com/hapijs/qs/issues/32) account for circular references properly, closes #31
-- [**#31**](https://github.com/hapijs/qs/issues/31) qs.parse stackoverflow on circular objects
-
-## [**2.2.0**](https://github.com/hapijs/qs/issues?milestone=9&state=closed)
-- [**#26**](https://github.com/hapijs/qs/issues/26) Don't use Buffer global if it's not present
-- [**#30**](https://github.com/hapijs/qs/issues/30) Bug when merging non-object values into arrays
-- [**#29**](https://github.com/hapijs/qs/issues/29) Don't call Utils.clone at the top of Utils.merge
-- [**#23**](https://github.com/hapijs/qs/issues/23) Ability to not limit parameters?
-
-## [**2.1.0**](https://github.com/hapijs/qs/issues?milestone=8&state=closed)
-- [**#22**](https://github.com/hapijs/qs/issues/22) Enable using a RegExp as delimiter
-
-## [**2.0.0**](https://github.com/hapijs/qs/issues?milestone=7&state=closed)
-- [**#18**](https://github.com/hapijs/qs/issues/18) Why is there arrayLimit?
-- [**#20**](https://github.com/hapijs/qs/issues/20) Configurable parametersLimit
-- [**#21**](https://github.com/hapijs/qs/issues/21) make all limits optional, for #18, for #20
-
-## [**1.2.2**](https://github.com/hapijs/qs/issues?milestone=6&state=closed)
-- [**#19**](https://github.com/hapijs/qs/issues/19) Don't overwrite null values
-
-## [**1.2.1**](https://github.com/hapijs/qs/issues?milestone=5&state=closed)
-- [**#16**](https://github.com/hapijs/qs/issues/16) ignore non-string delimiters
-- [**#15**](https://github.com/hapijs/qs/issues/15) Close code block
-
-## [**1.2.0**](https://github.com/hapijs/qs/issues?milestone=4&state=closed)
-- [**#12**](https://github.com/hapijs/qs/issues/12) Add optional delim argument
-- [**#13**](https://github.com/hapijs/qs/issues/13) fix #11: flattened keys in array are now correctly parsed
-
-## [**1.1.0**](https://github.com/hapijs/qs/issues?milestone=3&state=closed)
-- [**#7**](https://github.com/hapijs/qs/issues/7) Empty values of a POST array disappear after being submitted
-- [**#9**](https://github.com/hapijs/qs/issues/9) Should not omit equals signs (=) when value is null
-- [**#6**](https://github.com/hapijs/qs/issues/6) Minor grammar fix in README
-
-## [**1.0.2**](https://github.com/hapijs/qs/issues?milestone=2&state=closed)
-- [**#5**](https://github.com/hapijs/qs/issues/5) array holes incorrectly copied into object on large index
-
diff --git a/CoAuthoring/node_modules/express/node_modules/qs/CONTRIBUTING.md b/CoAuthoring/node_modules/express/node_modules/qs/CONTRIBUTING.md
deleted file mode 100644
index 892836159b..0000000000
--- a/CoAuthoring/node_modules/express/node_modules/qs/CONTRIBUTING.md
+++ /dev/null
@@ -1 +0,0 @@
-Please view our [hapijs contributing guide](https://github.com/hapijs/hapi/blob/master/CONTRIBUTING.md).
diff --git a/CoAuthoring/node_modules/express/node_modules/qs/LICENSE b/CoAuthoring/node_modules/express/node_modules/qs/LICENSE
deleted file mode 100644
index d4569487a0..0000000000
--- a/CoAuthoring/node_modules/express/node_modules/qs/LICENSE
+++ /dev/null
@@ -1,28 +0,0 @@
-Copyright (c) 2014 Nathan LaFreniere and other contributors.
-All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are met:
- * Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
- * Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
- * The names of any contributors may not be used to endorse or promote
- products derived from this software without specific prior written
- permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
-ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS AND CONTRIBUTORS BE LIABLE FOR ANY
-DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
-(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
-LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
-ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
-SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
- * * *
-
-The complete list of contributors can be found at: https://github.com/hapijs/qs/graphs/contributors
diff --git a/CoAuthoring/node_modules/express/node_modules/qs/Makefile b/CoAuthoring/node_modules/express/node_modules/qs/Makefile
deleted file mode 100644
index 600a700ec6..0000000000
--- a/CoAuthoring/node_modules/express/node_modules/qs/Makefile
+++ /dev/null
@@ -1,8 +0,0 @@
-test:
- @node node_modules/lab/bin/lab
-test-cov:
- @node node_modules/lab/bin/lab -t 100
-test-cov-html:
- @node node_modules/lab/bin/lab -r html -o coverage.html
-
-.PHONY: test test-cov test-cov-html
\ No newline at end of file
diff --git a/CoAuthoring/node_modules/express/node_modules/qs/README.md b/CoAuthoring/node_modules/express/node_modules/qs/README.md
deleted file mode 100644
index a6f99aba04..0000000000
--- a/CoAuthoring/node_modules/express/node_modules/qs/README.md
+++ /dev/null
@@ -1,213 +0,0 @@
-# qs
-
-A querystring parsing and stringifying library with some added security.
-
-[](http://travis-ci.org/hapijs/qs)
-
-Lead Maintainer: [Nathan LaFreniere](https://github.com/nlf)
-
-The **qs** module was originally created and maintained by [TJ Holowaychuk](https://github.com/visionmedia/node-querystring).
-
-## Usage
-
-```javascript
-var Qs = require('qs');
-
-var obj = Qs.parse('a=c'); // { a: 'c' }
-var str = Qs.stringify(obj); // 'a=c'
-```
-
-### Parsing Objects
-
-```javascript
-Qs.parse(string, [options]);
-```
-
-**qs** allows you to create nested objects within your query strings, by surrounding the name of sub-keys with square brackets `[]`.
-For example, the string `'foo[bar]=baz'` converts to:
-
-```javascript
-{
- foo: {
- bar: 'baz'
- }
-}
-```
-
-URI encoded strings work too:
-
-```javascript
-Qs.parse('a%5Bb%5D=c');
-// { a: { b: 'c' } }
-```
-
-You can also nest your objects, like `'foo[bar][baz]=foobarbaz'`:
-
-```javascript
-{
- foo: {
- bar: {
- baz: 'foobarbaz'
- }
- }
-}
-```
-
-By default, when nesting objects **qs** will only parse up to 5 children deep. This means if you attempt to parse a string like
-`'a[b][c][d][e][f][g][h][i]=j'` your resulting object will be:
-
-```javascript
-{
- a: {
- b: {
- c: {
- d: {
- e: {
- f: {
- '[g][h][i]': 'j'
- }
- }
- }
- }
- }
- }
-}
-```
-
-This depth can be overridden by passing a `depth` option to `Qs.parse(string, [options])`:
-
-```javascript
-Qs.parse('a[b][c][d][e][f][g][h][i]=j', { depth: 1 });
-// { a: { b: { '[c][d][e][f][g][h][i]': 'j' } } }
-```
-
-The depth limit helps mitigate abuse when **qs** is used to parse user input, and it is recommended to keep it a reasonably small number.
-
-For similar reasons, by default **qs** will only parse up to 1000 parameters. This can be overridden by passing a `parameterLimit` option:
-
-```javascript
-Qs.parse('a=b&c=d', { parameterLimit: 1 });
-// { a: 'b' }
-```
-
-An optional delimiter can also be passed:
-
-```javascript
-Qs.parse('a=b;c=d', { delimiter: ';' });
-// { a: 'b', c: 'd' }
-```
-
-Delimiters can be a regular expression too:
-
-```javascript
-Qs.parse('a=b;c=d,e=f', { delimiter: /[;,]/ });
-// { a: 'b', c: 'd', e: 'f' }
-```
-
-### Parsing Arrays
-
-**qs** can also parse arrays using a similar `[]` notation:
-
-```javascript
-Qs.parse('a[]=b&a[]=c');
-// { a: ['b', 'c'] }
-```
-
-You may specify an index as well:
-
-```javascript
-Qs.parse('a[1]=c&a[0]=b');
-// { a: ['b', 'c'] }
-```
-
-Note that the only difference between an index in an array and a key in an object is that the value between the brackets must be a number
-to create an array. When creating arrays with specific indices, **qs** will compact a sparse array to only the existing values preserving
-their order:
-
-```javascript
-Qs.parse('a[1]=b&a[15]=c');
-// { a: ['b', 'c'] }
-```
-
-Note that an empty string is also a value, and will be preserved:
-
-```javascript
-Qs.parse('a[]=&a[]=b');
-// { a: ['', 'b'] }
-Qs.parse('a[0]=b&a[1]=&a[2]=c');
-// { a: ['b', '', 'c'] }
-```
-
-**qs** will also limit specifying indices in an array to a maximum index of `20`. Any array members with an index of greater than `20` will
-instead be converted to an object with the index as the key:
-
-```javascript
-Qs.parse('a[100]=b');
-// { a: { '100': 'b' } }
-```
-
-This limit can be overridden by passing an `arrayLimit` option:
-
-```javascript
-Qs.parse('a[1]=b', { arrayLimit: 0 });
-// { a: { '1': 'b' } }
-```
-
-If you mix notations, **qs** will merge the two items into an object:
-
-```javascript
-Qs.parse('a[0]=b&a[b]=c');
-// { a: { '0': 'b', b: 'c' } }
-```
-
-You can also create arrays of objects:
-
-```javascript
-Qs.parse('a[][b]=c');
-// { a: [{ b: 'c' }] }
-```
-
-### Stringifying
-
-```javascript
-Qs.stringify(object, [options]);
-```
-
-When stringifying, **qs** always URI encodes output. Objects are stringified as you would expect:
-
-```javascript
-Qs.stringify({ a: 'b' });
-// 'a=b'
-Qs.stringify({ a: { b: 'c' } });
-// 'a%5Bb%5D=c'
-```
-
-Examples beyond this point will be shown as though the output is not URI encoded for clarity. Please note that the return values in these cases *will* be URI encoded during real usage.
-
-When arrays are stringified, they are always given explicit indices:
-
-```javascript
-Qs.stringify({ a: ['b', 'c', 'd'] });
-// 'a[0]=b&a[1]=c&a[2]=d'
-```
-
-Empty strings and null values will omit the value, but the equals sign (=) remains in place:
-
-```javascript
-Qs.stringify({ a: '' });
-// 'a='
-```
-
-Properties that are set to `undefined` will be omitted entirely:
-
-```javascript
-Qs.stringify({ a: null, b: undefined });
-// 'a='
-```
-
-The delimiter may be overridden with stringify as well:
-
-```javascript
-Qs.stringify({ a: 'b', c: 'd' }, { delimiter: ';' });
-// 'a=b;c=d'
-```
diff --git a/CoAuthoring/node_modules/express/node_modules/qs/index.js b/CoAuthoring/node_modules/express/node_modules/qs/index.js
deleted file mode 100644
index bb0a047c4f..0000000000
--- a/CoAuthoring/node_modules/express/node_modules/qs/index.js
+++ /dev/null
@@ -1 +0,0 @@
-module.exports = require('./lib');
diff --git a/CoAuthoring/node_modules/express/node_modules/qs/lib/index.js b/CoAuthoring/node_modules/express/node_modules/qs/lib/index.js
deleted file mode 100644
index 0e094933d1..0000000000
--- a/CoAuthoring/node_modules/express/node_modules/qs/lib/index.js
+++ /dev/null
@@ -1,15 +0,0 @@
-// Load modules
-
-var Stringify = require('./stringify');
-var Parse = require('./parse');
-
-
-// Declare internals
-
-var internals = {};
-
-
-module.exports = {
- stringify: Stringify,
- parse: Parse
-};
diff --git a/CoAuthoring/node_modules/express/node_modules/qs/lib/parse.js b/CoAuthoring/node_modules/express/node_modules/qs/lib/parse.js
deleted file mode 100644
index 362739783d..0000000000
--- a/CoAuthoring/node_modules/express/node_modules/qs/lib/parse.js
+++ /dev/null
@@ -1,156 +0,0 @@
-// Load modules
-
-var Utils = require('./utils');
-
-
-// Declare internals
-
-var internals = {
- delimiter: '&',
- depth: 5,
- arrayLimit: 20,
- parameterLimit: 1000
-};
-
-
-internals.parseValues = function (str, options) {
-
- var obj = {};
- var parts = str.split(options.delimiter, options.parameterLimit === Infinity ? undefined : options.parameterLimit);
-
- for (var i = 0, il = parts.length; i < il; ++i) {
- var part = parts[i];
- var pos = part.indexOf(']=') === -1 ? part.indexOf('=') : part.indexOf(']=') + 1;
-
- if (pos === -1) {
- obj[Utils.decode(part)] = '';
- }
- else {
- var key = Utils.decode(part.slice(0, pos));
- var val = Utils.decode(part.slice(pos + 1));
-
- if (!obj.hasOwnProperty(key)) {
- obj[key] = val;
- }
- else {
- obj[key] = [].concat(obj[key]).concat(val);
- }
- }
- }
-
- return obj;
-};
-
-
-internals.parseObject = function (chain, val, options) {
-
- if (!chain.length) {
- return val;
- }
-
- var root = chain.shift();
-
- var obj = {};
- if (root === '[]') {
- obj = [];
- obj = obj.concat(internals.parseObject(chain, val, options));
- }
- else {
- var cleanRoot = root[0] === '[' && root[root.length - 1] === ']' ? root.slice(1, root.length - 1) : root;
- var index = parseInt(cleanRoot, 10);
- var indexString = '' + index;
- if (!isNaN(index) &&
- root !== cleanRoot &&
- indexString === cleanRoot &&
- index <= options.arrayLimit) {
-
- obj = [];
- obj[index] = internals.parseObject(chain, val, options);
- }
- else {
- obj[cleanRoot] = internals.parseObject(chain, val, options);
- }
- }
-
- return obj;
-};
-
-
-internals.parseKeys = function (key, val, options) {
-
- if (!key) {
- return;
- }
-
- // The regex chunks
-
- var parent = /^([^\[\]]*)/;
- var child = /(\[[^\[\]]*\])/g;
-
- // Get the parent
-
- var segment = parent.exec(key);
-
- // Don't allow them to overwrite object prototype properties
-
- if (Object.prototype.hasOwnProperty(segment[1])) {
- return;
- }
-
- // Stash the parent if it exists
-
- var keys = [];
- if (segment[1]) {
- keys.push(segment[1]);
- }
-
- // Loop through children appending to the array until we hit depth
-
- var i = 0;
- while ((segment = child.exec(key)) !== null && i < options.depth) {
-
- ++i;
- if (!Object.prototype.hasOwnProperty(segment[1].replace(/\[|\]/g, ''))) {
- keys.push(segment[1]);
- }
- }
-
- // If there's a remainder, just add whatever is left
-
- if (segment) {
- keys.push('[' + key.slice(segment.index) + ']');
- }
-
- return internals.parseObject(keys, val, options);
-};
-
-
-module.exports = function (str, options) {
-
- if (str === '' ||
- str === null ||
- typeof str === 'undefined') {
-
- return {};
- }
-
- options = options || {};
- options.delimiter = typeof options.delimiter === 'string' || Utils.isRegExp(options.delimiter) ? options.delimiter : internals.delimiter;
- options.depth = typeof options.depth === 'number' ? options.depth : internals.depth;
- options.arrayLimit = typeof options.arrayLimit === 'number' ? options.arrayLimit : internals.arrayLimit;
- options.parameterLimit = typeof options.parameterLimit === 'number' ? options.parameterLimit : internals.parameterLimit;
-
- var tempObj = typeof str === 'string' ? internals.parseValues(str, options) : str;
- var obj = {};
-
- // Iterate over the keys and setup the new object
-
- var keys = Object.keys(tempObj);
- for (var i = 0, il = keys.length; i < il; ++i) {
- var key = keys[i];
- var newObj = internals.parseKeys(key, tempObj[key], options);
- obj = Utils.merge(obj, newObj);
- }
-
- return Utils.compact(obj);
-};
diff --git a/CoAuthoring/node_modules/express/node_modules/qs/lib/stringify.js b/CoAuthoring/node_modules/express/node_modules/qs/lib/stringify.js
deleted file mode 100644
index 582577a00c..0000000000
--- a/CoAuthoring/node_modules/express/node_modules/qs/lib/stringify.js
+++ /dev/null
@@ -1,58 +0,0 @@
-// Load modules
-
-var Utils = require('./utils');
-
-
-// Declare internals
-
-var internals = {
- delimiter: '&'
-};
-
-
-internals.stringify = function (obj, prefix) {
-
- if (Utils.isBuffer(obj)) {
- obj = obj.toString();
- }
- else if (obj instanceof Date) {
- obj = obj.toISOString();
- }
- else if (obj === null) {
- obj = '';
- }
-
- if (typeof obj === 'string' ||
- typeof obj === 'number' ||
- typeof obj === 'boolean') {
-
- return [encodeURIComponent(prefix) + '=' + encodeURIComponent(obj)];
- }
-
- var values = [];
-
- for (var key in obj) {
- if (obj.hasOwnProperty(key)) {
- values = values.concat(internals.stringify(obj[key], prefix + '[' + key + ']'));
- }
- }
-
- return values;
-};
-
-
-module.exports = function (obj, options) {
-
- options = options || {};
- var delimiter = typeof options.delimiter === 'undefined' ? internals.delimiter : options.delimiter;
-
- var keys = [];
-
- for (var key in obj) {
- if (obj.hasOwnProperty(key)) {
- keys = keys.concat(internals.stringify(obj[key], key));
- }
- }
-
- return keys.join(delimiter);
-};
diff --git a/CoAuthoring/node_modules/express/node_modules/qs/lib/utils.js b/CoAuthoring/node_modules/express/node_modules/qs/lib/utils.js
deleted file mode 100644
index c0b915df0c..0000000000
--- a/CoAuthoring/node_modules/express/node_modules/qs/lib/utils.js
+++ /dev/null
@@ -1,139 +0,0 @@
-// Load modules
-
-
-// Declare internals
-
-var internals = {};
-
-
-exports.arrayToObject = function (source) {
-
- var obj = {};
- for (var i = 0, il = source.length; i < il; ++i) {
- if (typeof source[i] !== 'undefined') {
-
- obj[i] = source[i];
- }
- }
-
- return obj;
-};
-
-
-exports.merge = function (target, source) {
-
- if (!source) {
- return target;
- }
-
- if (Array.isArray(source)) {
- for (var i = 0, il = source.length; i < il; ++i) {
- if (typeof source[i] !== 'undefined') {
- if (typeof target[i] === 'object') {
- target[i] = exports.merge(target[i], source[i]);
- }
- else {
- target[i] = source[i];
- }
- }
- }
-
- return target;
- }
-
- if (Array.isArray(target)) {
- if (typeof source !== 'object') {
- target.push(source);
- return target;
- }
- else {
- target = exports.arrayToObject(target);
- }
- }
-
- var keys = Object.keys(source);
- for (var k = 0, kl = keys.length; k < kl; ++k) {
- var key = keys[k];
- var value = source[key];
-
- if (value &&
- typeof value === 'object') {
-
- if (!target[key]) {
- target[key] = value;
- }
- else {
- target[key] = exports.merge(target[key], value);
- }
- }
- else {
- target[key] = value;
- }
- }
-
- return target;
-};
-
-
-exports.decode = function (str) {
-
- try {
- return decodeURIComponent(str.replace(/\+/g, ' '));
- } catch (e) {
- return str;
- }
-};
-
-
-exports.compact = function (obj, refs) {
-
- if (typeof obj !== 'object' ||
- obj === null) {
-
- return obj;
- }
-
- refs = refs || [];
- var lookup = refs.indexOf(obj);
- if (lookup !== -1) {
- return refs[lookup];
- }
-
- refs.push(obj);
-
- if (Array.isArray(obj)) {
- var compacted = [];
-
- for (var i = 0, l = obj.length; i < l; ++i) {
- if (typeof obj[i] !== 'undefined') {
- compacted.push(obj[i]);
- }
- }
-
- return compacted;
- }
-
- var keys = Object.keys(obj);
- for (var i = 0, il = keys.length; i < il; ++i) {
- var key = keys[i];
- obj[key] = exports.compact(obj[key], refs);
- }
-
- return obj;
-};
-
-
-exports.isRegExp = function (obj) {
- return Object.prototype.toString.call(obj) === '[object RegExp]';
-};
-
-
-exports.isBuffer = function (obj) {
-
- if (typeof Buffer !== 'undefined') {
- return Buffer.isBuffer(obj);
- }
- else {
- return false;
- }
-};
diff --git a/CoAuthoring/node_modules/express/node_modules/qs/package.json b/CoAuthoring/node_modules/express/node_modules/qs/package.json
deleted file mode 100644
index f541416866..0000000000
--- a/CoAuthoring/node_modules/express/node_modules/qs/package.json
+++ /dev/null
@@ -1,39 +0,0 @@
-{
- "name": "qs",
- "version": "2.2.4",
- "description": "A querystring parser that supports nesting and arrays, with a depth limit",
- "homepage": "https://github.com/hapijs/qs",
- "main": "index.js",
- "dependencies": {},
- "devDependencies": {
- "lab": "4.x.x"
- },
- "scripts": {
- "test": "make test-cov"
- },
- "repository": {
- "type": "git",
- "url": "https://github.com/hapijs/qs.git"
- },
- "keywords": [
- "querystring",
- "qs"
- ],
- "author": {
- "name": "Nathan LaFreniere",
- "email": "quitlahok@gmail.com"
- },
- "licenses": [
- {
- "type": "BSD",
- "url": "http://github.com/hapijs/qs/raw/master/LICENSE"
- }
- ],
- "readme": "# qs\n\nA querystring parsing and stringifying library with some added security.\n\n[](http://travis-ci.org/hapijs/qs)\n\nLead Maintainer: [Nathan LaFreniere](https://github.com/nlf)\n\nThe **qs** module was originally created and maintained by [TJ Holowaychuk](https://github.com/visionmedia/node-querystring).\n\n## Usage\n\n```javascript\nvar Qs = require('qs');\n\nvar obj = Qs.parse('a=c'); // { a: 'c' }\nvar str = Qs.stringify(obj); // 'a=c'\n```\n\n### Parsing Objects\n\n```javascript\nQs.parse(string, [options]);\n```\n\n**qs** allows you to create nested objects within your query strings, by surrounding the name of sub-keys with square brackets `[]`.\nFor example, the string `'foo[bar]=baz'` converts to:\n\n```javascript\n{\n foo: {\n bar: 'baz'\n }\n}\n```\n\nURI encoded strings work too:\n\n```javascript\nQs.parse('a%5Bb%5D=c');\n// { a: { b: 'c' } }\n```\n\nYou can also nest your objects, like `'foo[bar][baz]=foobarbaz'`:\n\n```javascript\n{\n foo: {\n bar: {\n baz: 'foobarbaz'\n }\n }\n}\n```\n\nBy default, when nesting objects **qs** will only parse up to 5 children deep. This means if you attempt to parse a string like\n`'a[b][c][d][e][f][g][h][i]=j'` your resulting object will be:\n\n```javascript\n{\n a: {\n b: {\n c: {\n d: {\n e: {\n f: {\n '[g][h][i]': 'j'\n }\n }\n }\n }\n }\n }\n}\n```\n\nThis depth can be overridden by passing a `depth` option to `Qs.parse(string, [options])`:\n\n```javascript\nQs.parse('a[b][c][d][e][f][g][h][i]=j', { depth: 1 });\n// { a: { b: { '[c][d][e][f][g][h][i]': 'j' } } }\n```\n\nThe depth limit helps mitigate abuse when **qs** is used to parse user input, and it is recommended to keep it a reasonably small number.\n\nFor similar reasons, by default **qs** will only parse up to 1000 parameters. This can be overridden by passing a `parameterLimit` option:\n\n```javascript\nQs.parse('a=b&c=d', { parameterLimit: 1 });\n// { a: 'b' }\n```\n\nAn optional delimiter can also be passed:\n\n```javascript\nQs.parse('a=b;c=d', { delimiter: ';' });\n// { a: 'b', c: 'd' }\n```\n\nDelimiters can be a regular expression too:\n\n```javascript\nQs.parse('a=b;c=d,e=f', { delimiter: /[;,]/ });\n// { a: 'b', c: 'd', e: 'f' }\n```\n\n### Parsing Arrays\n\n**qs** can also parse arrays using a similar `[]` notation:\n\n```javascript\nQs.parse('a[]=b&a[]=c');\n// { a: ['b', 'c'] }\n```\n\nYou may specify an index as well:\n\n```javascript\nQs.parse('a[1]=c&a[0]=b');\n// { a: ['b', 'c'] }\n```\n\nNote that the only difference between an index in an array and a key in an object is that the value between the brackets must be a number\nto create an array. When creating arrays with specific indices, **qs** will compact a sparse array to only the existing values preserving\ntheir order:\n\n```javascript\nQs.parse('a[1]=b&a[15]=c');\n// { a: ['b', 'c'] }\n```\n\nNote that an empty string is also a value, and will be preserved:\n\n```javascript\nQs.parse('a[]=&a[]=b');\n// { a: ['', 'b'] }\nQs.parse('a[0]=b&a[1]=&a[2]=c');\n// { a: ['b', '', 'c'] }\n```\n\n**qs** will also limit specifying indices in an array to a maximum index of `20`. Any array members with an index of greater than `20` will\ninstead be converted to an object with the index as the key:\n\n```javascript\nQs.parse('a[100]=b');\n// { a: { '100': 'b' } }\n```\n\nThis limit can be overridden by passing an `arrayLimit` option:\n\n```javascript\nQs.parse('a[1]=b', { arrayLimit: 0 });\n// { a: { '1': 'b' } }\n```\n\nIf you mix notations, **qs** will merge the two items into an object:\n\n```javascript\nQs.parse('a[0]=b&a[b]=c');\n// { a: { '0': 'b', b: 'c' } }\n```\n\nYou can also create arrays of objects:\n\n```javascript\nQs.parse('a[][b]=c');\n// { a: [{ b: 'c' }] }\n```\n\n### Stringifying\n\n```javascript\nQs.stringify(object, [options]);\n```\n\nWhen stringifying, **qs** always URI encodes output. Objects are stringified as you would expect:\n\n```javascript\nQs.stringify({ a: 'b' });\n// 'a=b'\nQs.stringify({ a: { b: 'c' } });\n// 'a%5Bb%5D=c'\n```\n\nExamples beyond this point will be shown as though the output is not URI encoded for clarity. Please note that the return values in these cases *will* be URI encoded during real usage.\n\nWhen arrays are stringified, they are always given explicit indices:\n\n```javascript\nQs.stringify({ a: ['b', 'c', 'd'] });\n// 'a[0]=b&a[1]=c&a[2]=d'\n```\n\nEmpty strings and null values will omit the value, but the equals sign (=) remains in place:\n\n```javascript\nQs.stringify({ a: '' });\n// 'a='\n```\n\nProperties that are set to `undefined` will be omitted entirely:\n\n```javascript\nQs.stringify({ a: null, b: undefined });\n// 'a='\n```\n\nThe delimiter may be overridden with stringify as well:\n\n```javascript\nQs.stringify({ a: 'b', c: 'd' }, { delimiter: ';' });\n// 'a=b;c=d'\n```\n",
- "readmeFilename": "README.md",
- "bugs": {
- "url": "https://github.com/hapijs/qs/issues"
- },
- "_id": "qs@2.2.4",
- "_from": "qs@2.2.4"
-}
diff --git a/CoAuthoring/node_modules/express/node_modules/qs/test/parse.js b/CoAuthoring/node_modules/express/node_modules/qs/test/parse.js
deleted file mode 100644
index 22083f6c9e..0000000000
--- a/CoAuthoring/node_modules/express/node_modules/qs/test/parse.js
+++ /dev/null
@@ -1,391 +0,0 @@
-// Load modules
-
-var Lab = require('lab');
-var Qs = require('../');
-
-
-// Declare internals
-
-var internals = {};
-
-
-// Test shortcuts
-
-var lab = exports.lab = Lab.script();
-var expect = Lab.expect;
-var before = lab.before;
-var after = lab.after;
-var describe = lab.experiment;
-var it = lab.test;
-
-
-describe('#parse', function () {
-
- it('parses a simple string', function (done) {
-
- expect(Qs.parse('0=foo')).to.deep.equal({ '0': 'foo' });
- expect(Qs.parse('foo=c++')).to.deep.equal({ foo: 'c ' });
- expect(Qs.parse('a[>=]=23')).to.deep.equal({ a: { '>=': '23' } });
- expect(Qs.parse('a[<=>]==23')).to.deep.equal({ a: { '<=>': '=23' } });
- expect(Qs.parse('a[==]=23')).to.deep.equal({ a: { '==': '23' } });
- expect(Qs.parse('foo')).to.deep.equal({ foo: '' });
- expect(Qs.parse('foo=bar')).to.deep.equal({ foo: 'bar' });
- expect(Qs.parse(' foo = bar = baz ')).to.deep.equal({ ' foo ': ' bar = baz ' });
- expect(Qs.parse('foo=bar=baz')).to.deep.equal({ foo: 'bar=baz' });
- expect(Qs.parse('foo=bar&bar=baz')).to.deep.equal({ foo: 'bar', bar: 'baz' });
- expect(Qs.parse('foo=bar&baz')).to.deep.equal({ foo: 'bar', baz: '' });
- expect(Qs.parse('cht=p3&chd=t:60,40&chs=250x100&chl=Hello|World')).to.deep.equal({
- cht: 'p3',
- chd: 't:60,40',
- chs: '250x100',
- chl: 'Hello|World'
- });
- done();
- });
-
- it('parses a single nested string', function (done) {
-
- expect(Qs.parse('a[b]=c')).to.deep.equal({ a: { b: 'c' } });
- done();
- });
-
- it('parses a double nested string', function (done) {
-
- expect(Qs.parse('a[b][c]=d')).to.deep.equal({ a: { b: { c: 'd' } } });
- done();
- });
-
- it('defaults to a depth of 5', function (done) {
-
- expect(Qs.parse('a[b][c][d][e][f][g][h]=i')).to.deep.equal({ a: { b: { c: { d: { e: { f: { '[g][h]': 'i' } } } } } } });
- done();
- });
-
- it('only parses one level when depth = 1', function (done) {
-
- expect(Qs.parse('a[b][c]=d', { depth: 1 })).to.deep.equal({ a: { b: { '[c]': 'd' } } });
- expect(Qs.parse('a[b][c][d]=e', { depth: 1 })).to.deep.equal({ a: { b: { '[c][d]': 'e' } } });
- done();
- });
-
- it('parses a simple array', function (done) {
-
- expect(Qs.parse('a=b&a=c')).to.deep.equal({ a: ['b', 'c'] });
- done();
- });
-
- it('parses an explicit array', function (done) {
-
- expect(Qs.parse('a[]=b')).to.deep.equal({ a: ['b'] });
- expect(Qs.parse('a[]=b&a[]=c')).to.deep.equal({ a: ['b', 'c'] });
- expect(Qs.parse('a[]=b&a[]=c&a[]=d')).to.deep.equal({ a: ['b', 'c', 'd'] });
- done();
- });
-
- it('parses a nested array', function (done) {
-
- expect(Qs.parse('a[b][]=c&a[b][]=d')).to.deep.equal({ a: { b: ['c', 'd'] } });
- expect(Qs.parse('a[>=]=25')).to.deep.equal({ a: { '>=': '25' } });
- done();
- });
-
- it('allows to specify array indices', function (done) {
-
- expect(Qs.parse('a[1]=c&a[0]=b&a[2]=d')).to.deep.equal({ a: ['b', 'c', 'd'] });
- expect(Qs.parse('a[1]=c&a[0]=b')).to.deep.equal({ a: ['b', 'c'] });
- expect(Qs.parse('a[1]=c')).to.deep.equal({ a: ['c'] });
- done();
- });
-
- it('limits specific array indices to 20', function (done) {
-
- expect(Qs.parse('a[20]=a')).to.deep.equal({ a: ['a'] });
- expect(Qs.parse('a[21]=a')).to.deep.equal({ a: { '21': 'a' } });
- done();
- });
-
- it('supports keys that begin with a number', function (done) {
-
- expect(Qs.parse('a[12b]=c')).to.deep.equal({ a: { '12b': 'c' } });
- done();
- });
-
- it('supports encoded = signs', function (done) {
-
- expect(Qs.parse('he%3Dllo=th%3Dere')).to.deep.equal({ 'he=llo': 'th=ere' });
- done();
- });
-
- it('is ok with url encoded strings', function (done) {
-
- expect(Qs.parse('a[b%20c]=d')).to.deep.equal({ a: { 'b c': 'd' } });
- expect(Qs.parse('a[b]=c%20d')).to.deep.equal({ a: { b: 'c d' } });
- done();
- });
-
- it('allows brackets in the value', function (done) {
-
- expect(Qs.parse('pets=["tobi"]')).to.deep.equal({ pets: '["tobi"]' });
- expect(Qs.parse('operators=[">=", "<="]')).to.deep.equal({ operators: '[">=", "<="]' });
- done();
- });
-
- it('allows empty values', function (done) {
-
- expect(Qs.parse('')).to.deep.equal({});
- expect(Qs.parse(null)).to.deep.equal({});
- expect(Qs.parse(undefined)).to.deep.equal({});
- done();
- });
-
- it('transforms arrays to objects', function (done) {
-
- expect(Qs.parse('foo[0]=bar&foo[bad]=baz')).to.deep.equal({ foo: { '0': 'bar', bad: 'baz' } });
- expect(Qs.parse('foo[bad]=baz&foo[0]=bar')).to.deep.equal({ foo: { bad: 'baz', '0': 'bar' } });
- expect(Qs.parse('foo[bad]=baz&foo[]=bar')).to.deep.equal({ foo: { bad: 'baz', '0': 'bar' } });
- expect(Qs.parse('foo[]=bar&foo[bad]=baz')).to.deep.equal({ foo: { '0': 'bar', bad: 'baz' } });
- expect(Qs.parse('foo[bad]=baz&foo[]=bar&foo[]=foo')).to.deep.equal({ foo: { bad: 'baz', '0': 'bar', '1': 'foo' } });
- expect(Qs.parse('foo[0][a]=a&foo[0][b]=b&foo[1][a]=aa&foo[1][b]=bb')).to.deep.equal({foo: [ {a: 'a', b: 'b'}, {a: 'aa', b: 'bb'} ]});
- done();
- });
-
- it('correctly prunes undefined values when converting an array to an object', function (done) {
-
- expect(Qs.parse('a[2]=b&a[99999999]=c')).to.deep.equal({ a: { '2': 'b', '99999999': 'c' } });
- done();
- });
-
- it('supports malformed uri characters', function (done) {
-
- expect(Qs.parse('{%:%}')).to.deep.equal({ '{%:%}': '' });
- expect(Qs.parse('foo=%:%}')).to.deep.equal({ foo: '%:%}' });
- done();
- });
-
- it('doesn\'t produce empty keys', function (done) {
-
- expect(Qs.parse('_r=1&')).to.deep.equal({ '_r': '1' });
- done();
- });
-
- it('cannot override prototypes', function (done) {
-
- var obj = Qs.parse('toString=bad&bad[toString]=bad&constructor=bad');
- expect(typeof obj.toString).to.equal('function');
- expect(typeof obj.bad.toString).to.equal('function');
- expect(typeof obj.constructor).to.equal('function');
- done();
- });
-
- it('cannot access Object prototype', function (done) {
-
- Qs.parse('constructor[prototype][bad]=bad');
- Qs.parse('bad[constructor][prototype][bad]=bad');
- expect(typeof Object.prototype.bad).to.equal('undefined');
- done();
- });
-
- it('parses arrays of objects', function (done) {
-
- expect(Qs.parse('a[][b]=c')).to.deep.equal({ a: [{ b: 'c' }] });
- expect(Qs.parse('a[0][b]=c')).to.deep.equal({ a: [{ b: 'c' }] });
- done();
- });
-
- it('allows for empty strings in arrays', function (done) {
-
- expect(Qs.parse('a[]=b&a[]=&a[]=c')).to.deep.equal({ a: ['b', '', 'c'] });
- expect(Qs.parse('a[0]=b&a[1]=&a[2]=c&a[19]=')).to.deep.equal({ a: ['b', '', 'c', ''] });
- expect(Qs.parse('a[]=&a[]=b&a[]=c')).to.deep.equal({ a: ['', 'b', 'c'] });
- done();
- });
-
- it('compacts sparse arrays', function (done) {
-
- expect(Qs.parse('a[10]=1&a[2]=2')).to.deep.equal({ a: ['2', '1'] });
- done();
- });
-
- it('parses semi-parsed strings', function (done) {
-
- expect(Qs.parse({ 'a[b]': 'c' })).to.deep.equal({ a: { b: 'c' } });
- expect(Qs.parse({ 'a[b]': 'c', 'a[d]': 'e' })).to.deep.equal({ a: { b: 'c', d: 'e' } });
- done();
- });
-
- it('parses buffers correctly', function (done) {
-
- var b = new Buffer('test');
- expect(Qs.parse({ a: b })).to.deep.equal({ a: b });
- done();
- });
-
- it('continues parsing when no parent is found', function (done) {
-
- expect(Qs.parse('[]&a=b')).to.deep.equal({ '0': '', a: 'b' });
- expect(Qs.parse('[foo]=bar')).to.deep.equal({ foo: 'bar' });
- done();
- });
-
- it('does not error when parsing a very long array', function (done) {
-
- var str = 'a[]=a';
- while (Buffer.byteLength(str) < 128 * 1024) {
- str += '&' + str;
- }
-
- expect(function () {
-
- Qs.parse(str);
- }).to.not.throw();
-
- done();
- });
-
- it('should not throw when a native prototype has an enumerable property', { parallel: false }, function (done) {
-
- Object.prototype.crash = '';
- Array.prototype.crash = '';
- expect(Qs.parse.bind(null, 'a=b')).to.not.throw();
- expect(Qs.parse('a=b')).to.deep.equal({ a: 'b' });
- expect(Qs.parse.bind(null, 'a[][b]=c')).to.not.throw();
- expect(Qs.parse('a[][b]=c')).to.deep.equal({ a: [{ b: 'c' }] });
- delete Object.prototype.crash;
- delete Array.prototype.crash;
- done();
- });
-
- it('parses a string with an alternative string delimiter', function (done) {
-
- expect(Qs.parse('a=b;c=d', { delimiter: ';' })).to.deep.equal({ a: 'b', c: 'd' });
- done();
- });
-
- it('parses a string with an alternative RegExp delimiter', function (done) {
-
- expect(Qs.parse('a=b; c=d', { delimiter: /[;,] */ })).to.deep.equal({ a: 'b', c: 'd' });
- done();
- });
-
- it('does not use non-splittable objects as delimiters', function (done) {
-
- expect(Qs.parse('a=b&c=d', { delimiter: true })).to.deep.equal({ a: 'b', c: 'd' });
- done();
- });
-
- it('allows overriding parameter limit', function (done) {
-
- expect(Qs.parse('a=b&c=d', { parameterLimit: 1 })).to.deep.equal({ a: 'b' });
- done();
- });
-
- it('allows setting the parameter limit to Infinity', function (done) {
-
- expect(Qs.parse('a=b&c=d', { parameterLimit: Infinity })).to.deep.equal({ a: 'b', c: 'd' });
- done();
- });
-
- it('allows overriding array limit', function (done) {
-
- expect(Qs.parse('a[0]=b&a[1]=c', { arrayLimit: 0 })).to.deep.equal({ a: { '0': 'b', '1': 'c' } });
- done();
- });
-
- it('parses an object', function (done) {
-
- var input = {
- "user[name]": {"pop[bob]": 3},
- "user[email]": null
- };
-
- var expected = {
- "user": {
- "name": {"pop[bob]": 3},
- "email": null
- }
- };
-
- var result = Qs.parse(input);
-
- expect(result).to.deep.equal(expected);
- done();
- });
-
- it('parses an object and not child values', function (done) {
-
- var input = {
- "user[name]": {"pop[bob]": { "test": 3 }},
- "user[email]": null
- };
-
- var expected = {
- "user": {
- "name": {"pop[bob]": { "test": 3 }},
- "email": null
- }
- };
-
- var result = Qs.parse(input);
-
- expect(result).to.deep.equal(expected);
- done();
- });
-
- it('does not blow up when Buffer global is missing', function (done) {
-
- var tempBuffer = global.Buffer;
- delete global.Buffer;
- expect(Qs.parse('a=b&c=d')).to.deep.equal({ a: 'b', c: 'd' });
- global.Buffer = tempBuffer;
- done();
- });
-
- it('does not crash when using invalid dot notation', function (done) {
-
- expect(Qs.parse('roomInfoList[0].childrenAges[0]=15&roomInfoList[0].numberOfAdults=2')).to.deep.equal({ roomInfoList: [['15', '2']] });
- done();
- });
-
- it('does not crash when parsing circular references', function (done) {
-
- var a = {};
- a.b = a;
-
- var parsed;
-
- expect(function () {
-
- parsed = Qs.parse({ 'foo[bar]': 'baz', 'foo[baz]': a });
- }).to.not.throw(Error);
-
- expect(parsed).to.have.key('foo');
- expect(parsed.foo).to.have.keys('bar', 'baz');
- expect(parsed.foo.bar).to.equal('baz');
- expect(parsed.foo.baz).to.deep.equal(a);
- done();
- });
-
- it('parses plain objects correctly', function (done) {
-
- var a = Object.create(null);
- a.b = 'c';
-
- expect(Qs.parse(a)).to.deep.equal({ b: 'c' });
- expect(Qs.parse({ a: a })).to.deep.equal({ a: { b: 'c' } });
- done();
- });
-
- it('parses dates correctly', function (done) {
-
- var now = new Date();
- expect(Qs.parse({ a: now })).to.deep.equal({ a: now });
- done();
- });
-
- it('parses regular expressions correctly', function (done) {
-
- var re = /^test$/;
- expect(Qs.parse({ a: re })).to.deep.equal({ a: re });
- done();
- });
-});
diff --git a/CoAuthoring/node_modules/express/node_modules/qs/test/stringify.js b/CoAuthoring/node_modules/express/node_modules/qs/test/stringify.js
deleted file mode 100644
index b96b52bf1f..0000000000
--- a/CoAuthoring/node_modules/express/node_modules/qs/test/stringify.js
+++ /dev/null
@@ -1,139 +0,0 @@
-// Load modules
-
-var Lab = require('lab');
-var Qs = require('../');
-
-
-// Declare internals
-
-var internals = {};
-
-
-// Test shortcuts
-
-var lab = exports.lab = Lab.script();
-var expect = Lab.expect;
-var before = lab.before;
-var after = lab.after;
-var describe = lab.experiment;
-var it = lab.test;
-
-
-describe('#stringify', function () {
-
- it('stringifies a querystring object', function (done) {
-
- expect(Qs.stringify({ a: 'b' })).to.equal('a=b');
- expect(Qs.stringify({ a: 1 })).to.equal('a=1');
- expect(Qs.stringify({ a: 1, b: 2 })).to.equal('a=1&b=2');
- done();
- });
-
- it('stringifies a nested object', function (done) {
-
- expect(Qs.stringify({ a: { b: 'c' } })).to.equal('a%5Bb%5D=c');
- expect(Qs.stringify({ a: { b: { c: { d: 'e' } } } })).to.equal('a%5Bb%5D%5Bc%5D%5Bd%5D=e');
- done();
- });
-
- it('stringifies an array value', function (done) {
-
- expect(Qs.stringify({ a: ['b', 'c', 'd'] })).to.equal('a%5B0%5D=b&a%5B1%5D=c&a%5B2%5D=d');
- done();
- });
-
- it('stringifies a nested array value', function (done) {
-
- expect(Qs.stringify({ a: { b: ['c', 'd'] } })).to.equal('a%5Bb%5D%5B0%5D=c&a%5Bb%5D%5B1%5D=d');
- done();
- });
-
- it('stringifies an object inside an array', function (done) {
-
- expect(Qs.stringify({ a: [{ b: 'c' }] })).to.equal('a%5B0%5D%5Bb%5D=c');
- expect(Qs.stringify({ a: [{ b: { c: [1] } }] })).to.equal('a%5B0%5D%5Bb%5D%5Bc%5D%5B0%5D=1');
- done();
- });
-
- it('stringifies a complicated object', function (done) {
-
- expect(Qs.stringify({ a: { b: 'c', d: 'e' } })).to.equal('a%5Bb%5D=c&a%5Bd%5D=e');
- done();
- });
-
- it('stringifies an empty value', function (done) {
-
- expect(Qs.stringify({ a: '' })).to.equal('a=');
- expect(Qs.stringify({ a: '', b: '' })).to.equal('a=&b=');
- expect(Qs.stringify({ a: null })).to.equal('a=');
- expect(Qs.stringify({ a: { b: null } })).to.equal('a%5Bb%5D=');
- done();
- });
-
- it('drops keys with a value of undefined', function (done) {
-
- expect(Qs.stringify({ a: undefined })).to.equal('');
- expect(Qs.stringify({ a: { b: undefined, c: null } })).to.equal('a%5Bc%5D=');
- done();
- });
-
- it('url encodes values', function (done) {
-
- expect(Qs.stringify({ a: 'b c' })).to.equal('a=b%20c');
- done();
- });
-
- it('stringifies a date', function (done) {
-
- var now = new Date();
- var str = 'a=' + encodeURIComponent(now.toISOString());
- expect(Qs.stringify({ a: now })).to.equal(str);
- done();
- });
-
- it('stringifies the weird object from qs', function (done) {
-
- expect(Qs.stringify({ 'my weird field': 'q1!2"\'w$5&7/z8)?' })).to.equal('my%20weird%20field=q1!2%22\'w%245%267%2Fz8)%3F');
- done();
- });
-
- it('skips properties that are part of the object prototype', function (done) {
-
- Object.prototype.crash = 'test';
- expect(Qs.stringify({ a: 'b'})).to.equal('a=b');
- expect(Qs.stringify({ a: { b: 'c' } })).to.equal('a%5Bb%5D=c');
- delete Object.prototype.crash;
- done();
- });
-
- it('stringifies boolean values', function (done) {
-
- expect(Qs.stringify({ a: true })).to.equal('a=true');
- expect(Qs.stringify({ a: { b: true } })).to.equal('a%5Bb%5D=true');
- expect(Qs.stringify({ b: false })).to.equal('b=false');
- expect(Qs.stringify({ b: { c: false } })).to.equal('b%5Bc%5D=false');
- done();
- });
-
- it('stringifies buffer values', function (done) {
-
- expect(Qs.stringify({ a: new Buffer('test') })).to.equal('a=test');
- expect(Qs.stringify({ a: { b: new Buffer('test') } })).to.equal('a%5Bb%5D=test');
- done();
- });
-
- it('stringifies an object using an alternative delimiter', function (done) {
-
- expect(Qs.stringify({ a: 'b', c: 'd' }, { delimiter: ';' })).to.equal('a=b;c=d');
- done();
- });
-
- it('doesn\'t blow up when Buffer global is missing', function (done) {
-
- var tempBuffer = global.Buffer;
- delete global.Buffer;
- expect(Qs.stringify({ a: 'b', c: 'd' })).to.equal('a=b&c=d');
- global.Buffer = tempBuffer;
- done();
- });
-});
diff --git a/CoAuthoring/node_modules/express/node_modules/range-parser/History.md b/CoAuthoring/node_modules/express/node_modules/range-parser/History.md
deleted file mode 100644
index 1bb53bd1ec..0000000000
--- a/CoAuthoring/node_modules/express/node_modules/range-parser/History.md
+++ /dev/null
@@ -1,35 +0,0 @@
-1.0.2 / 2014-09-08
-==================
-
- * Support Node.js 0.6
-
-1.0.1 / 2014-09-07
-==================
-
- * Move repository to jshttp
-
-1.0.0 / 2013-12-11
-==================
-
- * Add repository to package.json
- * Add MIT license
-
-0.0.4 / 2012-06-17
-==================
-
- * Change ret -1 for unsatisfiable and -2 when invalid
-
-0.0.3 / 2012-06-17
-==================
-
- * Fix last-byte-pos default to len - 1
-
-0.0.2 / 2012-06-14
-==================
-
- * Add `.type`
-
-0.0.1 / 2012-06-11
-==================
-
- * Initial release
diff --git a/CoAuthoring/node_modules/express/node_modules/range-parser/LICENSE b/CoAuthoring/node_modules/express/node_modules/range-parser/LICENSE
deleted file mode 100644
index a491841b24..0000000000
--- a/CoAuthoring/node_modules/express/node_modules/range-parser/LICENSE
+++ /dev/null
@@ -1,22 +0,0 @@
-(The MIT License)
-
-Copyright (c) 2012-2014 TJ Holowaychuk
-
-Permission is hereby granted, free of charge, to any person obtaining
-a copy of this software and associated documentation files (the
-'Software'), to deal in the Software without restriction, including
-without limitation the rights to use, copy, modify, merge, publish,
-distribute, sublicense, and/or sell copies of the Software, and to
-permit persons to whom the Software is furnished to do so, subject to
-the following conditions:
-
-The above copyright notice and this permission notice shall be
-included in all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
-EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
-IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
-CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
-TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
-SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
diff --git a/CoAuthoring/node_modules/express/node_modules/range-parser/Readme.md b/CoAuthoring/node_modules/express/node_modules/range-parser/Readme.md
deleted file mode 100644
index 6a2682f372..0000000000
--- a/CoAuthoring/node_modules/express/node_modules/range-parser/Readme.md
+++ /dev/null
@@ -1,48 +0,0 @@
-# range-parser
-
-[![NPM Version][npm-image]][npm-url]
-[![NPM Downloads][downloads-image]][downloads-url]
-[![Node.js Version][node-version-image]][node-version-url]
-[![Build Status][travis-image]][travis-url]
-[![Test Coverage][coveralls-image]][coveralls-url]
-
-Range header field parser.
-
-## Installation
-
-```
-$ npm install range-parser
-```
-
-## Examples
-
-```js
-assert(-1 == parse(200, 'bytes=500-20'));
-assert(-2 == parse(200, 'bytes=malformed'));
-parse(200, 'bytes=0-499').should.eql(arr('bytes', [{ start: 0, end: 199 }]));
-parse(1000, 'bytes=0-499').should.eql(arr('bytes', [{ start: 0, end: 499 }]));
-parse(1000, 'bytes=40-80').should.eql(arr('bytes', [{ start: 40, end: 80 }]));
-parse(1000, 'bytes=-500').should.eql(arr('bytes', [{ start: 500, end: 999 }]));
-parse(1000, 'bytes=-400').should.eql(arr('bytes', [{ start: 600, end: 999 }]));
-parse(1000, 'bytes=500-').should.eql(arr('bytes', [{ start: 500, end: 999 }]));
-parse(1000, 'bytes=400-').should.eql(arr('bytes', [{ start: 400, end: 999 }]));
-parse(1000, 'bytes=0-0').should.eql(arr('bytes', [{ start: 0, end: 0 }]));
-parse(1000, 'bytes=-1').should.eql(arr('bytes', [{ start: 999, end: 999 }]));
-parse(1000, 'items=0-5').should.eql(arr('items', [{ start: 0, end: 5 }]));
-parse(1000, 'bytes=40-80,-1').should.eql(arr('bytes', [{ start: 40, end: 80 }, { start: 999, end: 999 }]));
-```
-
-## License
-
-[MIT](LICENSE)
-
-[npm-image]: https://img.shields.io/npm/v/range-parser.svg?style=flat
-[npm-url]: https://npmjs.org/package/range-parser
-[node-version-image]: https://img.shields.io/badge/node.js-%3E%3D_0.6-brightgreen.svg?style=flat
-[node-version-url]: http://nodejs.org/download/
-[travis-image]: https://img.shields.io/travis/jshttp/range-parser.svg?style=flat
-[travis-url]: https://travis-ci.org/jshttp/range-parser
-[coveralls-image]: https://img.shields.io/coveralls/jshttp/range-parser.svg?style=flat
-[coveralls-url]: https://coveralls.io/r/jshttp/range-parser
-[downloads-image]: https://img.shields.io/npm/dm/range-parser.svg?style=flat
-[downloads-url]: https://npmjs.org/package/range-parser
diff --git a/CoAuthoring/node_modules/express/node_modules/range-parser/index.js b/CoAuthoring/node_modules/express/node_modules/range-parser/index.js
deleted file mode 100644
index 09a6c40e77..0000000000
--- a/CoAuthoring/node_modules/express/node_modules/range-parser/index.js
+++ /dev/null
@@ -1,49 +0,0 @@
-
-/**
- * Parse "Range" header `str` relative to the given file `size`.
- *
- * @param {Number} size
- * @param {String} str
- * @return {Array}
- * @api public
- */
-
-module.exports = function(size, str){
- var valid = true;
- var i = str.indexOf('=');
-
- if (-1 == i) return -2;
-
- var arr = str.slice(i + 1).split(',').map(function(range){
- var range = range.split('-')
- , start = parseInt(range[0], 10)
- , end = parseInt(range[1], 10);
-
- // -nnn
- if (isNaN(start)) {
- start = size - end;
- end = size - 1;
- // nnn-
- } else if (isNaN(end)) {
- end = size - 1;
- }
-
- // limit last-byte-pos to current length
- if (end > size - 1) end = size - 1;
-
- // invalid
- if (isNaN(start)
- || isNaN(end)
- || start > end
- || start < 0) valid = false;
-
- return {
- start: start,
- end: end
- };
- });
-
- arr.type = str.slice(0, i);
-
- return valid ? arr : -1;
-};
diff --git a/CoAuthoring/node_modules/express/node_modules/range-parser/package.json b/CoAuthoring/node_modules/express/node_modules/range-parser/package.json
deleted file mode 100644
index 900e357cca..0000000000
--- a/CoAuthoring/node_modules/express/node_modules/range-parser/package.json
+++ /dev/null
@@ -1,46 +0,0 @@
-{
- "name": "range-parser",
- "author": {
- "name": "TJ Holowaychuk",
- "email": "tj@vision-media.ca",
- "url": "http://tjholowaychuk.com"
- },
- "description": "Range header field string parser",
- "version": "1.0.2",
- "license": "MIT",
- "keywords": [
- "range",
- "parser",
- "http"
- ],
- "repository": {
- "type": "git",
- "url": "git://github.com/jshttp/range-parser"
- },
- "devDependencies": {
- "istanbul": "0",
- "mocha": "1",
- "should": "2"
- },
- "files": [
- "HISTORY.md",
- "LICENSE",
- "index.js"
- ],
- "engines": {
- "node": ">= 0.6"
- },
- "scripts": {
- "test": "mocha --reporter spec --require should",
- "test-cov": "istanbul cover node_modules/mocha/bin/_mocha -- --reporter dot --require should",
- "test-travis": "istanbul cover node_modules/mocha/bin/_mocha --report lcovonly -- --reporter dot --require should"
- },
- "readme": "# range-parser\n\n[![NPM Version][npm-image]][npm-url]\n[![NPM Downloads][downloads-image]][downloads-url]\n[![Node.js Version][node-version-image]][node-version-url]\n[![Build Status][travis-image]][travis-url]\n[![Test Coverage][coveralls-image]][coveralls-url]\n\nRange header field parser.\n\n## Installation\n\n```\n$ npm install range-parser\n```\n\n## Examples\n\n```js\nassert(-1 == parse(200, 'bytes=500-20'));\nassert(-2 == parse(200, 'bytes=malformed'));\nparse(200, 'bytes=0-499').should.eql(arr('bytes', [{ start: 0, end: 199 }]));\nparse(1000, 'bytes=0-499').should.eql(arr('bytes', [{ start: 0, end: 499 }]));\nparse(1000, 'bytes=40-80').should.eql(arr('bytes', [{ start: 40, end: 80 }]));\nparse(1000, 'bytes=-500').should.eql(arr('bytes', [{ start: 500, end: 999 }]));\nparse(1000, 'bytes=-400').should.eql(arr('bytes', [{ start: 600, end: 999 }]));\nparse(1000, 'bytes=500-').should.eql(arr('bytes', [{ start: 500, end: 999 }]));\nparse(1000, 'bytes=400-').should.eql(arr('bytes', [{ start: 400, end: 999 }]));\nparse(1000, 'bytes=0-0').should.eql(arr('bytes', [{ start: 0, end: 0 }]));\nparse(1000, 'bytes=-1').should.eql(arr('bytes', [{ start: 999, end: 999 }]));\nparse(1000, 'items=0-5').should.eql(arr('items', [{ start: 0, end: 5 }]));\nparse(1000, 'bytes=40-80,-1').should.eql(arr('bytes', [{ start: 40, end: 80 }, { start: 999, end: 999 }]));\n```\n\n## License\n\n[MIT](LICENSE)\n\n[npm-image]: https://img.shields.io/npm/v/range-parser.svg?style=flat\n[npm-url]: https://npmjs.org/package/range-parser\n[node-version-image]: https://img.shields.io/badge/node.js-%3E%3D_0.6-brightgreen.svg?style=flat\n[node-version-url]: http://nodejs.org/download/\n[travis-image]: https://img.shields.io/travis/jshttp/range-parser.svg?style=flat\n[travis-url]: https://travis-ci.org/jshttp/range-parser\n[coveralls-image]: https://img.shields.io/coveralls/jshttp/range-parser.svg?style=flat\n[coveralls-url]: https://coveralls.io/r/jshttp/range-parser\n[downloads-image]: https://img.shields.io/npm/dm/range-parser.svg?style=flat\n[downloads-url]: https://npmjs.org/package/range-parser\n",
- "readmeFilename": "README.md",
- "bugs": {
- "url": "https://github.com/jshttp/range-parser/issues"
- },
- "homepage": "https://github.com/jshttp/range-parser",
- "_id": "range-parser@1.0.2",
- "_from": "range-parser@~1.0.2"
-}
diff --git a/CoAuthoring/node_modules/express/node_modules/send/History.md b/CoAuthoring/node_modules/express/node_modules/send/History.md
deleted file mode 100644
index 6927b7e5b8..0000000000
--- a/CoAuthoring/node_modules/express/node_modules/send/History.md
+++ /dev/null
@@ -1,205 +0,0 @@
-0.9.3 / 2014-09-24
-==================
-
- * deps: etag@~1.4.0
- - Support "fake" stats objects
-
-0.9.2 / 2014-09-15
-==================
-
- * deps: depd@0.4.5
- * deps: etag@~1.3.1
- * deps: range-parser@~1.0.2
-
-0.9.1 / 2014-09-07
-==================
-
- * deps: fresh@0.2.4
-
-0.9.0 / 2014-09-07
-==================
-
- * Add `lastModified` option
- * Use `etag` to generate `ETag` header
- * deps: debug@~2.0.0
-
-0.8.5 / 2014-09-04
-==================
-
- * Fix malicious path detection for empty string path
-
-0.8.4 / 2014-09-04
-==================
-
- * Fix a path traversal issue when using `root`
-
-0.8.3 / 2014-08-16
-==================
-
- * deps: destroy@1.0.3
- - renamed from dethroy
- * deps: on-finished@2.1.0
-
-0.8.2 / 2014-08-14
-==================
-
- * Work around `fd` leak in Node.js 0.10 for `fs.ReadStream`
- * deps: dethroy@1.0.2
-
-0.8.1 / 2014-08-05
-==================
-
- * Fix `extensions` behavior when file already has extension
-
-0.8.0 / 2014-08-05
-==================
-
- * Add `extensions` option
-
-0.7.4 / 2014-08-04
-==================
-
- * Fix serving index files without root dir
-
-0.7.3 / 2014-07-29
-==================
-
- * Fix incorrect 403 on Windows and Node.js 0.11
-
-0.7.2 / 2014-07-27
-==================
-
- * deps: depd@0.4.4
- - Work-around v8 generating empty stack traces
-
-0.7.1 / 2014-07-26
-==================
-
- * deps: depd@0.4.3
- - Fix exception when global `Error.stackTraceLimit` is too low
-
-0.7.0 / 2014-07-20
-==================
-
- * Deprecate `hidden` option; use `dotfiles` option
- * Add `dotfiles` option
- * deps: debug@1.0.4
- * deps: depd@0.4.2
- - Add `TRACE_DEPRECATION` environment variable
- - Remove non-standard grey color from color output
- - Support `--no-deprecation` argument
- - Support `--trace-deprecation` argument
-
-0.6.0 / 2014-07-11
-==================
-
- * Deprecate `from` option; use `root` option
- * Deprecate `send.etag()` -- use `etag` in `options`
- * Deprecate `send.hidden()` -- use `hidden` in `options`
- * Deprecate `send.index()` -- use `index` in `options`
- * Deprecate `send.maxage()` -- use `maxAge` in `options`
- * Deprecate `send.root()` -- use `root` in `options`
- * Cap `maxAge` value to 1 year
- * deps: debug@1.0.3
- - Add support for multiple wildcards in namespaces
-
-0.5.0 / 2014-06-28
-==================
-
- * Accept string for `maxAge` (converted by `ms`)
- * Add `headers` event
- * Include link in default redirect response
- * Use `EventEmitter.listenerCount` to count listeners
-
-0.4.3 / 2014-06-11
-==================
-
- * Do not throw un-catchable error on file open race condition
- * Use `escape-html` for HTML escaping
- * deps: debug@1.0.2
- - fix some debugging output colors on node.js 0.8
- * deps: finished@1.2.2
- * deps: fresh@0.2.2
-
-0.4.2 / 2014-06-09
-==================
-
- * fix "event emitter leak" warnings
- * deps: debug@1.0.1
- * deps: finished@1.2.1
-
-0.4.1 / 2014-06-02
-==================
-
- * Send `max-age` in `Cache-Control` in correct format
-
-0.4.0 / 2014-05-27
-==================
-
- * Calculate ETag with md5 for reduced collisions
- * Fix wrong behavior when index file matches directory
- * Ignore stream errors after request ends
- - Goodbye `EBADF, read`
- * Skip directories in index file search
- * deps: debug@0.8.1
-
-0.3.0 / 2014-04-24
-==================
-
- * Fix sending files with dots without root set
- * Coerce option types
- * Accept API options in options object
- * Set etags to "weak"
- * Include file path in etag
- * Make "Can't set headers after they are sent." catchable
- * Send full entity-body for multi range requests
- * Default directory access to 403 when index disabled
- * Support multiple index paths
- * Support "If-Range" header
- * Control whether to generate etags
- * deps: mime@1.2.11
-
-0.2.0 / 2014-01-29
-==================
-
- * update range-parser and fresh
-
-0.1.4 / 2013-08-11
-==================
-
- * update fresh
-
-0.1.3 / 2013-07-08
-==================
-
- * Revert "Fix fd leak"
-
-0.1.2 / 2013-07-03
-==================
-
- * Fix fd leak
-
-0.1.0 / 2012-08-25
-==================
-
- * add options parameter to send() that is passed to fs.createReadStream() [kanongil]
-
-0.0.4 / 2012-08-16
-==================
-
- * allow custom "Accept-Ranges" definition
-
-0.0.3 / 2012-07-16
-==================
-
- * fix normalization of the root directory. Closes #3
-
-0.0.2 / 2012-07-09
-==================
-
- * add passing of req explicitly for now (YUCK)
-
-0.0.1 / 2010-01-03
-==================
-
- * Initial release
diff --git a/CoAuthoring/node_modules/express/node_modules/send/LICENSE b/CoAuthoring/node_modules/express/node_modules/send/LICENSE
deleted file mode 100644
index 3b87e2db77..0000000000
--- a/CoAuthoring/node_modules/express/node_modules/send/LICENSE
+++ /dev/null
@@ -1,23 +0,0 @@
-(The MIT License)
-
-Copyright (c) 2012 TJ Holowaychuk
-Copyright (c) 2014 Douglas Christopher Wilson
-
-Permission is hereby granted, free of charge, to any person obtaining
-a copy of this software and associated documentation files (the
-'Software'), to deal in the Software without restriction, including
-without limitation the rights to use, copy, modify, merge, publish,
-distribute, sublicense, and/or sell copies of the Software, and to
-permit persons to whom the Software is furnished to do so, subject to
-the following conditions:
-
-The above copyright notice and this permission notice shall be
-included in all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
-EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
-IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
-CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
-TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
-SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
diff --git a/CoAuthoring/node_modules/express/node_modules/send/Readme.md b/CoAuthoring/node_modules/express/node_modules/send/Readme.md
deleted file mode 100644
index aa83608b93..0000000000
--- a/CoAuthoring/node_modules/express/node_modules/send/Readme.md
+++ /dev/null
@@ -1,182 +0,0 @@
-# send
-
-[![NPM Version][npm-image]][npm-url]
-[![NPM Downloads][downloads-image]][downloads-url]
-[![Build Status][travis-image]][travis-url]
-[![Test Coverage][coveralls-image]][coveralls-url]
-[![Gittip][gittip-image]][gittip-url]
-
- Send is Connect's `static()` extracted for generalized use, a streaming static file
- server supporting partial responses (Ranges), conditional-GET negotiation, high test coverage, and granular events which may be leveraged to take appropriate actions in your application or framework.
-
-## Installation
-
-```bash
-$ npm install send
-```
-
-## API
-
-```js
-var send = require('send')
-```
-
-### send(req, path, [options])
-
-Create a new `SendStream` for the given path to send to a `res`. The `req` is
-the Node.js HTTP request and the `path` is a urlencoded path to send (urlencoded,
-not the actual file-system path).
-
-#### Options
-
-##### dotfiles
-
- Set how "dotfiles" are treated when encountered. A dotfile is a file
- or directory that begins with a dot ("."). Note this check is done on
- the path itself without checking if the path actually exists on the
- disk. If `root` is specified, only the dotfiles above the root are
- checked (i.e. the root itself can be within a dotfile when when set
- to "deny").
-
- The default value is `'ignore'`.
-
- - `'allow'` No special treatment for dotfiles.
- - `'deny'` Send a 403 for any request for a dotfile.
- - `'ignore'` Pretend like the dotfile does not exist and 404.
-
-##### etag
-
- Enable or disable etag generation, defaults to true.
-
-##### extensions
-
- If a given file doesn't exist, try appending one of the given extensions,
- in the given order. By default, this is disabled (set to `false`). An
- example value that will serve extension-less HTML files: `['html', 'htm']`.
- This is skipped if the requested file already has an extension.
-
-##### index
-
- By default send supports "index.html" files, to disable this
- set `false` or to supply a new index pass a string or an array
- in preferred order.
-
-##### lastModified
-
- Enable or disable `Last-Modified` header, defaults to true. Uses the file
- system's last modified value.
-
-##### maxAge
-
- Provide a max-age in milliseconds for http caching, defaults to 0.
- This can also be a string accepted by the
- [ms](https://www.npmjs.org/package/ms#readme) module.
-
-##### root
-
- Serve files relative to `path`.
-
-### Events
-
-The `SendStream` is an event emitter and will emit the following events:
-
- - `error` an error occurred `(err)`
- - `directory` a directory was requested
- - `file` a file was requested `(path, stat)`
- - `headers` the headers are about to be set on a file `(res, path, stat)`
- - `stream` file streaming has started `(stream)`
- - `end` streaming has completed
-
-### .pipe
-
-The `pipe` method is used to pipe the response into the Node.js HTTP response
-object, typically `send(req, path, options).pipe(res)`.
-
-## Error-handling
-
- By default when no `error` listeners are present an automatic response will be made, otherwise you have full control over the response, aka you may show a 5xx page etc.
-
-## Caching
-
- It does _not_ perform internal caching, you should use a reverse proxy cache such
- as Varnish for this, or those fancy things called CDNs. If your application is small enough that it would benefit from single-node memory caching, it's small enough that it does not need caching at all ;).
-
-## Debugging
-
- To enable `debug()` instrumentation output export __DEBUG__:
-
-```
-$ DEBUG=send node app
-```
-
-## Running tests
-
-```
-$ npm install
-$ npm test
-```
-
-## Examples
-
- Small:
-
-```js
-var http = require('http');
-var send = require('send');
-
-var app = http.createServer(function(req, res){
- send(req, req.url).pipe(res);
-}).listen(3000);
-```
-
- Serving from a root directory with custom error-handling:
-
-```js
-var http = require('http');
-var send = require('send');
-var url = require('url');
-
-var app = http.createServer(function(req, res){
- // your custom error-handling logic:
- function error(err) {
- res.statusCode = err.status || 500;
- res.end(err.message);
- }
-
- // your custom headers
- function headers(res, path, stat) {
- // serve all files for download
- res.setHeader('Content-Disposition', 'attachment');
- }
-
- // your custom directory handling logic:
- function redirect() {
- res.statusCode = 301;
- res.setHeader('Location', req.url + '/');
- res.end('Redirecting to ' + req.url + '/');
- }
-
- // transfer arbitrary files from within
- // /www/example.com/public/*
- send(req, url.parse(req.url).pathname, {root: '/www/example.com/public'})
- .on('error', error)
- .on('directory', redirect)
- .on('headers', headers)
- .pipe(res);
-}).listen(3000);
-```
-
-## License
-
-[MIT](LICENSE)
-
-[npm-image]: https://img.shields.io/npm/v/send.svg?style=flat
-[npm-url]: https://npmjs.org/package/send
-[travis-image]: https://img.shields.io/travis/visionmedia/send.svg?style=flat
-[travis-url]: https://travis-ci.org/visionmedia/send
-[coveralls-image]: https://img.shields.io/coveralls/visionmedia/send.svg?style=flat
-[coveralls-url]: https://coveralls.io/r/visionmedia/send?branch=master
-[downloads-image]: https://img.shields.io/npm/dm/send.svg?style=flat
-[downloads-url]: https://npmjs.org/package/send
-[gittip-image]: https://img.shields.io/gittip/dougwilson.svg?style=flat
-[gittip-url]: https://www.gittip.com/dougwilson/
diff --git a/CoAuthoring/node_modules/express/node_modules/send/index.js b/CoAuthoring/node_modules/express/node_modules/send/index.js
deleted file mode 100644
index 64b6d641f4..0000000000
--- a/CoAuthoring/node_modules/express/node_modules/send/index.js
+++ /dev/null
@@ -1,773 +0,0 @@
-
-/**
- * Module dependencies.
- */
-
-var debug = require('debug')('send')
-var deprecate = require('depd')('send')
-var destroy = require('destroy')
-var escapeHtml = require('escape-html')
- , parseRange = require('range-parser')
- , Stream = require('stream')
- , mime = require('mime')
- , fresh = require('fresh')
- , path = require('path')
- , http = require('http')
- , fs = require('fs')
- , normalize = path.normalize
- , join = path.join
-var etag = require('etag')
-var EventEmitter = require('events').EventEmitter;
-var ms = require('ms');
-var onFinished = require('on-finished')
-
-/**
- * Variables.
- */
-var extname = path.extname
-var maxMaxAge = 60 * 60 * 24 * 365 * 1000; // 1 year
-var resolve = path.resolve
-var sep = path.sep
-var toString = Object.prototype.toString
-var upPathRegexp = /(?:^|[\\\/])\.\.(?:[\\\/]|$)/
-
-/**
- * Expose `send`.
- */
-
-exports = module.exports = send;
-
-/**
- * Expose mime module.
- */
-
-exports.mime = mime;
-
-/**
- * Shim EventEmitter.listenerCount for node.js < 0.10
- */
-
-/* istanbul ignore next */
-var listenerCount = EventEmitter.listenerCount
- || function(emitter, type){ return emitter.listeners(type).length; };
-
-/**
- * Return a `SendStream` for `req` and `path`.
- *
- * @param {Request} req
- * @param {String} path
- * @param {Object} options
- * @return {SendStream}
- * @api public
- */
-
-function send(req, path, options) {
- return new SendStream(req, path, options);
-}
-
-/**
- * Initialize a `SendStream` with the given `path`.
- *
- * @param {Request} req
- * @param {String} path
- * @param {Object} options
- * @api private
- */
-
-function SendStream(req, path, options) {
- var self = this;
- options = options || {};
- this.req = req;
- this.path = path;
- this.options = options;
-
- this._etag = options.etag !== undefined
- ? Boolean(options.etag)
- : true
-
- this._dotfiles = options.dotfiles !== undefined
- ? options.dotfiles
- : 'ignore'
-
- if (['allow', 'deny', 'ignore'].indexOf(this._dotfiles) === -1) {
- throw new TypeError('dotfiles option must be "allow", "deny", or "ignore"')
- }
-
- this._hidden = Boolean(options.hidden)
-
- if ('hidden' in options) {
- deprecate('hidden: use dotfiles: \'' + (this._hidden ? 'allow' : 'ignore') + '\' instead')
- }
-
- // legacy support
- if (!('dotfiles' in options)) {
- this._dotfiles = undefined
- }
-
- this._extensions = options.extensions !== undefined
- ? normalizeList(options.extensions)
- : []
-
- this._index = options.index !== undefined
- ? normalizeList(options.index)
- : ['index.html']
-
- this._lastModified = options.lastModified !== undefined
- ? Boolean(options.lastModified)
- : true
-
- this._maxage = options.maxAge || options.maxage
- this._maxage = typeof this._maxage === 'string'
- ? ms(this._maxage)
- : Number(this._maxage)
- this._maxage = !isNaN(this._maxage)
- ? Math.min(Math.max(0, this._maxage), maxMaxAge)
- : 0
-
- this._root = options.root
- ? resolve(options.root)
- : null
-
- if (!this._root && options.from) {
- this.from(options.from);
- }
-}
-
-/**
- * Inherits from `Stream.prototype`.
- */
-
-SendStream.prototype.__proto__ = Stream.prototype;
-
-/**
- * Enable or disable etag generation.
- *
- * @param {Boolean} val
- * @return {SendStream}
- * @api public
- */
-
-SendStream.prototype.etag = deprecate.function(function etag(val) {
- val = Boolean(val);
- debug('etag %s', val);
- this._etag = val;
- return this;
-}, 'send.etag: pass etag as option');
-
-/**
- * Enable or disable "hidden" (dot) files.
- *
- * @param {Boolean} path
- * @return {SendStream}
- * @api public
- */
-
-SendStream.prototype.hidden = deprecate.function(function hidden(val) {
- val = Boolean(val);
- debug('hidden %s', val);
- this._hidden = val;
- this._dotfiles = undefined
- return this;
-}, 'send.hidden: use dotfiles option');
-
-/**
- * Set index `paths`, set to a falsy
- * value to disable index support.
- *
- * @param {String|Boolean|Array} paths
- * @return {SendStream}
- * @api public
- */
-
-SendStream.prototype.index = deprecate.function(function index(paths) {
- var index = !paths ? [] : normalizeList(paths);
- debug('index %o', paths);
- this._index = index;
- return this;
-}, 'send.index: pass index as option');
-
-/**
- * Set root `path`.
- *
- * @param {String} path
- * @return {SendStream}
- * @api public
- */
-
-SendStream.prototype.root = function(path){
- path = String(path);
- this._root = resolve(path)
- return this;
-};
-
-SendStream.prototype.from = deprecate.function(SendStream.prototype.root,
- 'send.from: pass root as option');
-
-SendStream.prototype.root = deprecate.function(SendStream.prototype.root,
- 'send.root: pass root as option');
-
-/**
- * Set max-age to `maxAge`.
- *
- * @param {Number} maxAge
- * @return {SendStream}
- * @api public
- */
-
-SendStream.prototype.maxage = deprecate.function(function maxage(maxAge) {
- maxAge = typeof maxAge === 'string'
- ? ms(maxAge)
- : Number(maxAge);
- if (isNaN(maxAge)) maxAge = 0;
- if (Infinity == maxAge) maxAge = 60 * 60 * 24 * 365 * 1000;
- debug('max-age %d', maxAge);
- this._maxage = maxAge;
- return this;
-}, 'send.maxage: pass maxAge as option');
-
-/**
- * Emit error with `status`.
- *
- * @param {Number} status
- * @api private
- */
-
-SendStream.prototype.error = function(status, err){
- var res = this.res;
- var msg = http.STATUS_CODES[status];
-
- err = err || new Error(msg);
- err.status = status;
-
- // emit if listeners instead of responding
- if (listenerCount(this, 'error') !== 0) {
- return this.emit('error', err);
- }
-
- // wipe all existing headers
- res._headers = undefined;
-
- res.statusCode = err.status;
- res.end(msg);
-};
-
-/**
- * Check if the pathname ends with "/".
- *
- * @return {Boolean}
- * @api private
- */
-
-SendStream.prototype.hasTrailingSlash = function(){
- return '/' == this.path[this.path.length - 1];
-};
-
-/**
- * Check if this is a conditional GET request.
- *
- * @return {Boolean}
- * @api private
- */
-
-SendStream.prototype.isConditionalGET = function(){
- return this.req.headers['if-none-match']
- || this.req.headers['if-modified-since'];
-};
-
-/**
- * Strip content-* header fields.
- *
- * @api private
- */
-
-SendStream.prototype.removeContentHeaderFields = function(){
- var res = this.res;
- Object.keys(res._headers).forEach(function(field){
- if (0 == field.indexOf('content')) {
- res.removeHeader(field);
- }
- });
-};
-
-/**
- * Respond with 304 not modified.
- *
- * @api private
- */
-
-SendStream.prototype.notModified = function(){
- var res = this.res;
- debug('not modified');
- this.removeContentHeaderFields();
- res.statusCode = 304;
- res.end();
-};
-
-/**
- * Raise error that headers already sent.
- *
- * @api private
- */
-
-SendStream.prototype.headersAlreadySent = function headersAlreadySent(){
- var err = new Error('Can\'t set headers after they are sent.');
- debug('headers already sent');
- this.error(500, err);
-};
-
-/**
- * Check if the request is cacheable, aka
- * responded with 2xx or 304 (see RFC 2616 section 14.2{5,6}).
- *
- * @return {Boolean}
- * @api private
- */
-
-SendStream.prototype.isCachable = function(){
- var res = this.res;
- return (res.statusCode >= 200 && res.statusCode < 300) || 304 == res.statusCode;
-};
-
-/**
- * Handle stat() error.
- *
- * @param {Error} err
- * @api private
- */
-
-SendStream.prototype.onStatError = function(err){
- var notfound = ['ENOENT', 'ENAMETOOLONG', 'ENOTDIR'];
- if (~notfound.indexOf(err.code)) return this.error(404, err);
- this.error(500, err);
-};
-
-/**
- * Check if the cache is fresh.
- *
- * @return {Boolean}
- * @api private
- */
-
-SendStream.prototype.isFresh = function(){
- return fresh(this.req.headers, this.res._headers);
-};
-
-/**
- * Check if the range is fresh.
- *
- * @return {Boolean}
- * @api private
- */
-
-SendStream.prototype.isRangeFresh = function isRangeFresh(){
- var ifRange = this.req.headers['if-range'];
-
- if (!ifRange) return true;
-
- return ~ifRange.indexOf('"')
- ? ~ifRange.indexOf(this.res._headers['etag'])
- : Date.parse(this.res._headers['last-modified']) <= Date.parse(ifRange);
-};
-
-/**
- * Redirect to `path`.
- *
- * @param {String} path
- * @api private
- */
-
-SendStream.prototype.redirect = function(path){
- if (listenerCount(this, 'directory') !== 0) {
- return this.emit('directory');
- }
-
- if (this.hasTrailingSlash()) return this.error(403);
- var res = this.res;
- path += '/';
- res.statusCode = 301;
- res.setHeader('Content-Type', 'text/html; charset=utf-8');
- res.setHeader('Location', path);
- res.end('Redirecting to ' + escapeHtml(path) + ' \n');
-};
-
-/**
- * Pipe to `res.
- *
- * @param {Stream} res
- * @return {Stream} res
- * @api public
- */
-
-SendStream.prototype.pipe = function(res){
- var self = this
- , args = arguments
- , root = this._root;
-
- // references
- this.res = res;
-
- // decode the path
- var path = decode(this.path)
- if (path === -1) return this.error(400)
-
- // null byte(s)
- if (~path.indexOf('\0')) return this.error(400);
-
- var parts
- if (root !== null) {
- // join / normalize from optional root dir
- path = normalize(join(root, path))
- root = normalize(root + sep)
-
- // malicious path
- if ((path + sep).substr(0, root.length) !== root) {
- debug('malicious path "%s"', path)
- return this.error(403)
- }
-
- // explode path parts
- parts = path.substr(root.length).split(sep)
- } else {
- // ".." is malicious without "root"
- if (upPathRegexp.test(path)) {
- debug('malicious path "%s"', path)
- return this.error(403)
- }
-
- // explode path parts
- parts = normalize(path).split(sep)
-
- // resolve the path
- path = resolve(path)
- }
-
- // dotfile handling
- if (containsDotFile(parts)) {
- var access = this._dotfiles
-
- // legacy support
- if (access === undefined) {
- access = parts[parts.length - 1][0] === '.'
- ? (this._hidden ? 'allow' : 'ignore')
- : 'allow'
- }
-
- debug('%s dotfile "%s"', access, path)
- switch (access) {
- case 'allow':
- break
- case 'deny':
- return this.error(403)
- case 'ignore':
- default:
- return this.error(404)
- }
- }
-
- // index file support
- if (this._index.length && this.path[this.path.length - 1] === '/') {
- this.sendIndex(path);
- return res;
- }
-
- this.sendFile(path);
- return res;
-};
-
-/**
- * Transfer `path`.
- *
- * @param {String} path
- * @api public
- */
-
-SendStream.prototype.send = function(path, stat){
- var options = this.options;
- var len = stat.size;
- var res = this.res;
- var req = this.req;
- var ranges = req.headers.range;
- var offset = options.start || 0;
-
- if (res._header) {
- // impossible to send now
- return this.headersAlreadySent();
- }
-
- debug('pipe "%s"', path)
-
- // set header fields
- this.setHeader(path, stat);
-
- // set content-type
- this.type(path);
-
- // conditional GET support
- if (this.isConditionalGET()
- && this.isCachable()
- && this.isFresh()) {
- return this.notModified();
- }
-
- // adjust len to start/end options
- len = Math.max(0, len - offset);
- if (options.end !== undefined) {
- var bytes = options.end - offset + 1;
- if (len > bytes) len = bytes;
- }
-
- // Range support
- if (ranges) {
- ranges = parseRange(len, ranges);
-
- // If-Range support
- if (!this.isRangeFresh()) {
- debug('range stale');
- ranges = -2;
- }
-
- // unsatisfiable
- if (-1 == ranges) {
- debug('range unsatisfiable');
- res.setHeader('Content-Range', 'bytes */' + stat.size);
- return this.error(416);
- }
-
- // valid (syntactically invalid/multiple ranges are treated as a regular response)
- if (-2 != ranges && ranges.length === 1) {
- debug('range %j', ranges);
-
- options.start = offset + ranges[0].start;
- options.end = offset + ranges[0].end;
-
- // Content-Range
- res.statusCode = 206;
- res.setHeader('Content-Range', 'bytes '
- + ranges[0].start
- + '-'
- + ranges[0].end
- + '/'
- + len);
- len = options.end - options.start + 1;
- }
- }
-
- // content-length
- res.setHeader('Content-Length', len);
-
- // HEAD support
- if ('HEAD' == req.method) return res.end();
-
- this.stream(path, options);
-};
-
-/**
- * Transfer file for `path`.
- *
- * @param {String} path
- * @api private
- */
-SendStream.prototype.sendFile = function sendFile(path) {
- var i = 0
- var self = this
-
- debug('stat "%s"', path);
- fs.stat(path, function onstat(err, stat) {
- if (err && err.code === 'ENOENT'
- && !extname(path)
- && path[path.length - 1] !== sep) {
- // not found, check extensions
- return next(err)
- }
- if (err) return self.onStatError(err)
- if (stat.isDirectory()) return self.redirect(self.path)
- self.emit('file', path, stat)
- self.send(path, stat)
- })
-
- function next(err) {
- if (self._extensions.length <= i) {
- return err
- ? self.onStatError(err)
- : self.error(404)
- }
-
- var p = path + '.' + self._extensions[i++]
-
- debug('stat "%s"', p)
- fs.stat(p, function (err, stat) {
- if (err) return next(err)
- if (stat.isDirectory()) return next()
- self.emit('file', p, stat)
- self.send(p, stat)
- })
- }
-}
-
-/**
- * Transfer index for `path`.
- *
- * @param {String} path
- * @api private
- */
-SendStream.prototype.sendIndex = function sendIndex(path){
- var i = -1;
- var self = this;
-
- function next(err){
- if (++i >= self._index.length) {
- if (err) return self.onStatError(err);
- return self.error(404);
- }
-
- var p = join(path, self._index[i]);
-
- debug('stat "%s"', p);
- fs.stat(p, function(err, stat){
- if (err) return next(err);
- if (stat.isDirectory()) return next();
- self.emit('file', p, stat);
- self.send(p, stat);
- });
- }
-
- next();
-};
-
-/**
- * Stream `path` to the response.
- *
- * @param {String} path
- * @param {Object} options
- * @api private
- */
-
-SendStream.prototype.stream = function(path, options){
- // TODO: this is all lame, refactor meeee
- var finished = false;
- var self = this;
- var res = this.res;
- var req = this.req;
-
- // pipe
- var stream = fs.createReadStream(path, options);
- this.emit('stream', stream);
- stream.pipe(res);
-
- // response finished, done with the fd
- onFinished(res, function onfinished(){
- finished = true;
- destroy(stream);
- });
-
- // error handling code-smell
- stream.on('error', function onerror(err){
- // request already finished
- if (finished) return;
-
- // clean up stream
- finished = true;
- destroy(stream);
-
- // error
- self.onStatError(err);
- });
-
- // end
- stream.on('end', function onend(){
- self.emit('end');
- });
-};
-
-/**
- * Set content-type based on `path`
- * if it hasn't been explicitly set.
- *
- * @param {String} path
- * @api private
- */
-
-SendStream.prototype.type = function(path){
- var res = this.res;
- if (res.getHeader('Content-Type')) return;
- var type = mime.lookup(path);
- var charset = mime.charsets.lookup(type);
- debug('content-type %s', type);
- res.setHeader('Content-Type', type + (charset ? '; charset=' + charset : ''));
-};
-
-/**
- * Set response header fields, most
- * fields may be pre-defined.
- *
- * @param {String} path
- * @param {Object} stat
- * @api private
- */
-
-SendStream.prototype.setHeader = function setHeader(path, stat){
- var res = this.res;
-
- this.emit('headers', res, path, stat);
-
- if (!res.getHeader('Accept-Ranges')) res.setHeader('Accept-Ranges', 'bytes');
- if (!res.getHeader('Date')) res.setHeader('Date', new Date().toUTCString());
- if (!res.getHeader('Cache-Control')) res.setHeader('Cache-Control', 'public, max-age=' + Math.floor(this._maxage / 1000));
-
- if (this._lastModified && !res.getHeader('Last-Modified')) {
- var modified = stat.mtime.toUTCString()
- debug('modified %s', modified)
- res.setHeader('Last-Modified', modified)
- }
-
- if (this._etag && !res.getHeader('ETag')) {
- var val = etag(stat)
- debug('etag %s', val)
- res.setHeader('ETag', val)
- }
-};
-
-/**
- * Determine if path parts contain a dotfile.
- *
- * @api private
- */
-
-function containsDotFile(parts) {
- for (var i = 0; i < parts.length; i++) {
- if (parts[i][0] === '.') {
- return true
- }
- }
-
- return false
-}
-
-/**
- * decodeURIComponent.
- *
- * Allows V8 to only deoptimize this fn instead of all
- * of send().
- *
- * @param {String} path
- * @api private
- */
-
-function decode(path) {
- try {
- return decodeURIComponent(path)
- } catch (err) {
- return -1
- }
-}
-
-/**
- * Normalize the index option into an array.
- *
- * @param {boolean|string|array} val
- * @api private
- */
-
-function normalizeList(val){
- return [].concat(val || [])
-}
diff --git a/CoAuthoring/node_modules/express/node_modules/send/node_modules/destroy/README.md b/CoAuthoring/node_modules/express/node_modules/send/node_modules/destroy/README.md
deleted file mode 100644
index 665acb7f15..0000000000
--- a/CoAuthoring/node_modules/express/node_modules/send/node_modules/destroy/README.md
+++ /dev/null
@@ -1,38 +0,0 @@
-# Destroy
-
-[![NPM version][npm-image]][npm-url]
-[![Build status][travis-image]][travis-url]
-[![Test coverage][coveralls-image]][coveralls-url]
-[![Dependency Status][david-image]][david-url]
-[![License][license-image]][license-url]
-[![Downloads][downloads-image]][downloads-url]
-[![Gittip][gittip-image]][gittip-url]
-
-Destroy a stream.
-
-## API
-
-```js
-var destroy = require('destroy')
-
-var fs = require('fs')
-var stream = fs.createReadStream('package.json')
-destroy(stream)
-```
-
-[npm-image]: https://img.shields.io/npm/v/destroy.svg?style=flat-square
-[npm-url]: https://npmjs.org/package/destroy
-[github-tag]: http://img.shields.io/github/tag/stream-utils/destroy.svg?style=flat-square
-[github-url]: https://github.com/stream-utils/destroy/tags
-[travis-image]: https://img.shields.io/travis/stream-utils/destroy.svg?style=flat-square
-[travis-url]: https://travis-ci.org/stream-utils/destroy
-[coveralls-image]: https://img.shields.io/coveralls/stream-utils/destroy.svg?style=flat-square
-[coveralls-url]: https://coveralls.io/r/stream-utils/destroy?branch=master
-[david-image]: http://img.shields.io/david/stream-utils/destroy.svg?style=flat-square
-[david-url]: https://david-dm.org/stream-utils/destroy
-[license-image]: http://img.shields.io/npm/l/destroy.svg?style=flat-square
-[license-url]: LICENSE.md
-[downloads-image]: http://img.shields.io/npm/dm/destroy.svg?style=flat-square
-[downloads-url]: https://npmjs.org/package/destroy
-[gittip-image]: https://img.shields.io/gittip/jonathanong.svg?style=flat-square
-[gittip-url]: https://www.gittip.com/jonathanong/
diff --git a/CoAuthoring/node_modules/express/node_modules/send/node_modules/destroy/index.js b/CoAuthoring/node_modules/express/node_modules/send/node_modules/destroy/index.js
deleted file mode 100644
index b455217770..0000000000
--- a/CoAuthoring/node_modules/express/node_modules/send/node_modules/destroy/index.js
+++ /dev/null
@@ -1,36 +0,0 @@
-var ReadStream = require('fs').ReadStream
-var Stream = require('stream')
-
-module.exports = function destroy(stream) {
- if (stream instanceof ReadStream) {
- return destroyReadStream(stream)
- }
-
- if (!(stream instanceof Stream)) {
- return stream
- }
-
- if (typeof stream.destroy === 'function') {
- stream.destroy()
- }
-
- return stream
-}
-
-function destroyReadStream(stream) {
- stream.destroy()
-
- if (typeof stream.close === 'function') {
- // node.js core bug work-around
- stream.on('open', onopenClose)
- }
-
- return stream
-}
-
-function onopenClose() {
- if (typeof this.fd === 'number') {
- // actually close down the fd
- this.close()
- }
-}
diff --git a/CoAuthoring/node_modules/express/node_modules/send/node_modules/destroy/package.json b/CoAuthoring/node_modules/express/node_modules/send/node_modules/destroy/package.json
deleted file mode 100644
index 2c14a89ee0..0000000000
--- a/CoAuthoring/node_modules/express/node_modules/send/node_modules/destroy/package.json
+++ /dev/null
@@ -1,49 +0,0 @@
-{
- "name": "destroy",
- "description": "destroy a stream if possible",
- "version": "1.0.3",
- "author": {
- "name": "Jonathan Ong",
- "email": "me@jongleberry.com",
- "url": "http://jongleberry.com"
- },
- "contributors": [
- {
- "name": "Douglas Christopher Wilson",
- "email": "doug@somethingdoug.com"
- }
- ],
- "license": "MIT",
- "repository": {
- "type": "git",
- "url": "git://github.com/stream-utils/destroy"
- },
- "devDependencies": {
- "istanbul": "0",
- "mocha": "1"
- },
- "scripts": {
- "test": "mocha --reporter spec",
- "test-cov": "istanbul cover node_modules/mocha/bin/_mocha -- --reporter dot",
- "test-travis": "istanbul cover node_modules/mocha/bin/_mocha --report lcovonly -- --reporter dot"
- },
- "files": [
- "index.js"
- ],
- "keywords": [
- "stream",
- "streams",
- "destroy",
- "cleanup",
- "leak",
- "fd"
- ],
- "readme": "# Destroy\n\n[![NPM version][npm-image]][npm-url]\n[![Build status][travis-image]][travis-url]\n[![Test coverage][coveralls-image]][coveralls-url]\n[![Dependency Status][david-image]][david-url]\n[![License][license-image]][license-url]\n[![Downloads][downloads-image]][downloads-url]\n[![Gittip][gittip-image]][gittip-url]\n\nDestroy a stream.\n\n## API\n\n```js\nvar destroy = require('destroy')\n\nvar fs = require('fs')\nvar stream = fs.createReadStream('package.json')\ndestroy(stream)\n```\n\n[npm-image]: https://img.shields.io/npm/v/destroy.svg?style=flat-square\n[npm-url]: https://npmjs.org/package/destroy\n[github-tag]: http://img.shields.io/github/tag/stream-utils/destroy.svg?style=flat-square\n[github-url]: https://github.com/stream-utils/destroy/tags\n[travis-image]: https://img.shields.io/travis/stream-utils/destroy.svg?style=flat-square\n[travis-url]: https://travis-ci.org/stream-utils/destroy\n[coveralls-image]: https://img.shields.io/coveralls/stream-utils/destroy.svg?style=flat-square\n[coveralls-url]: https://coveralls.io/r/stream-utils/destroy?branch=master\n[david-image]: http://img.shields.io/david/stream-utils/destroy.svg?style=flat-square\n[david-url]: https://david-dm.org/stream-utils/destroy\n[license-image]: http://img.shields.io/npm/l/destroy.svg?style=flat-square\n[license-url]: LICENSE.md\n[downloads-image]: http://img.shields.io/npm/dm/destroy.svg?style=flat-square\n[downloads-url]: https://npmjs.org/package/destroy\n[gittip-image]: https://img.shields.io/gittip/jonathanong.svg?style=flat-square\n[gittip-url]: https://www.gittip.com/jonathanong/\n",
- "readmeFilename": "README.md",
- "bugs": {
- "url": "https://github.com/stream-utils/destroy/issues"
- },
- "homepage": "https://github.com/stream-utils/destroy",
- "_id": "destroy@1.0.3",
- "_from": "destroy@1.0.3"
-}
diff --git a/CoAuthoring/node_modules/express/node_modules/send/node_modules/mime/LICENSE b/CoAuthoring/node_modules/express/node_modules/send/node_modules/mime/LICENSE
deleted file mode 100644
index 451fc4550c..0000000000
--- a/CoAuthoring/node_modules/express/node_modules/send/node_modules/mime/LICENSE
+++ /dev/null
@@ -1,19 +0,0 @@
-Copyright (c) 2010 Benjamin Thomas, Robert Kieffer
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in
-all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-THE SOFTWARE.
diff --git a/CoAuthoring/node_modules/express/node_modules/send/node_modules/mime/README.md b/CoAuthoring/node_modules/express/node_modules/send/node_modules/mime/README.md
deleted file mode 100644
index 6ca19bd1e8..0000000000
--- a/CoAuthoring/node_modules/express/node_modules/send/node_modules/mime/README.md
+++ /dev/null
@@ -1,66 +0,0 @@
-# mime
-
-Comprehensive MIME type mapping API. Includes all 600+ types and 800+ extensions defined by the Apache project, plus additional types submitted by the node.js community.
-
-## Install
-
-Install with [npm](http://github.com/isaacs/npm):
-
- npm install mime
-
-## API - Queries
-
-### mime.lookup(path)
-Get the mime type associated with a file, if no mime type is found `application/octet-stream` is returned. Performs a case-insensitive lookup using the extension in `path` (the substring after the last '/' or '.'). E.g.
-
- var mime = require('mime');
-
- mime.lookup('/path/to/file.txt'); // => 'text/plain'
- mime.lookup('file.txt'); // => 'text/plain'
- mime.lookup('.TXT'); // => 'text/plain'
- mime.lookup('htm'); // => 'text/html'
-
-### mime.default_type
-Sets the mime type returned when `mime.lookup` fails to find the extension searched for. (Default is `application/octet-stream`.)
-
-### mime.extension(type)
-Get the default extension for `type`
-
- mime.extension('text/html'); // => 'html'
- mime.extension('application/octet-stream'); // => 'bin'
-
-### mime.charsets.lookup()
-
-Map mime-type to charset
-
- mime.charsets.lookup('text/plain'); // => 'UTF-8'
-
-(The logic for charset lookups is pretty rudimentary. Feel free to suggest improvements.)
-
-## API - Defining Custom Types
-
-The following APIs allow you to add your own type mappings within your project. If you feel a type should be included as part of node-mime, see [requesting new types](https://github.com/broofa/node-mime/wiki/Requesting-New-Types).
-
-### mime.define()
-
-Add custom mime/extension mappings
-
- mime.define({
- 'text/x-some-format': ['x-sf', 'x-sft', 'x-sfml'],
- 'application/x-my-type': ['x-mt', 'x-mtt'],
- // etc ...
- });
-
- mime.lookup('x-sft'); // => 'text/x-some-format'
-
-The first entry in the extensions array is returned by `mime.extension()`. E.g.
-
- mime.extension('text/x-some-format'); // => 'x-sf'
-
-### mime.load(filepath)
-
-Load mappings from an Apache ".types" format file
-
- mime.load('./my_project.types');
-
-The .types file format is simple - See the `types` dir for examples.
diff --git a/CoAuthoring/node_modules/express/node_modules/send/node_modules/mime/mime.js b/CoAuthoring/node_modules/express/node_modules/send/node_modules/mime/mime.js
deleted file mode 100644
index 48be0c5e42..0000000000
--- a/CoAuthoring/node_modules/express/node_modules/send/node_modules/mime/mime.js
+++ /dev/null
@@ -1,114 +0,0 @@
-var path = require('path');
-var fs = require('fs');
-
-function Mime() {
- // Map of extension -> mime type
- this.types = Object.create(null);
-
- // Map of mime type -> extension
- this.extensions = Object.create(null);
-}
-
-/**
- * Define mimetype -> extension mappings. Each key is a mime-type that maps
- * to an array of extensions associated with the type. The first extension is
- * used as the default extension for the type.
- *
- * e.g. mime.define({'audio/ogg', ['oga', 'ogg', 'spx']});
- *
- * @param map (Object) type definitions
- */
-Mime.prototype.define = function (map) {
- for (var type in map) {
- var exts = map[type];
-
- for (var i = 0; i < exts.length; i++) {
- if (process.env.DEBUG_MIME && this.types[exts]) {
- console.warn(this._loading.replace(/.*\//, ''), 'changes "' + exts[i] + '" extension type from ' +
- this.types[exts] + ' to ' + type);
- }
-
- this.types[exts[i]] = type;
- }
-
- // Default extension is the first one we encounter
- if (!this.extensions[type]) {
- this.extensions[type] = exts[0];
- }
- }
-};
-
-/**
- * Load an Apache2-style ".types" file
- *
- * This may be called multiple times (it's expected). Where files declare
- * overlapping types/extensions, the last file wins.
- *
- * @param file (String) path of file to load.
- */
-Mime.prototype.load = function(file) {
-
- this._loading = file;
- // Read file and split into lines
- var map = {},
- content = fs.readFileSync(file, 'ascii'),
- lines = content.split(/[\r\n]+/);
-
- lines.forEach(function(line) {
- // Clean up whitespace/comments, and split into fields
- var fields = line.replace(/\s*#.*|^\s*|\s*$/g, '').split(/\s+/);
- map[fields.shift()] = fields;
- });
-
- this.define(map);
-
- this._loading = null;
-};
-
-/**
- * Lookup a mime type based on extension
- */
-Mime.prototype.lookup = function(path, fallback) {
- var ext = path.replace(/.*[\.\/\\]/, '').toLowerCase();
-
- return this.types[ext] || fallback || this.default_type;
-};
-
-/**
- * Return file extension associated with a mime type
- */
-Mime.prototype.extension = function(mimeType) {
- var type = mimeType.match(/^\s*([^;\s]*)(?:;|\s|$)/)[1].toLowerCase();
- return this.extensions[type];
-};
-
-// Default instance
-var mime = new Mime();
-
-// Load local copy of
-// http://svn.apache.org/repos/asf/httpd/httpd/trunk/docs/conf/mime.types
-mime.load(path.join(__dirname, 'types/mime.types'));
-
-// Load additional types from node.js community
-mime.load(path.join(__dirname, 'types/node.types'));
-
-// Default type
-mime.default_type = mime.lookup('bin');
-
-//
-// Additional API specific to the default instance
-//
-
-mime.Mime = Mime;
-
-/**
- * Lookup a charset based on mime type.
- */
-mime.charsets = {
- lookup: function(mimeType, fallback) {
- // Assume text types are utf8
- return (/^text\//).test(mimeType) ? 'UTF-8' : fallback;
- }
-};
-
-module.exports = mime;
diff --git a/CoAuthoring/node_modules/express/node_modules/send/node_modules/mime/package.json b/CoAuthoring/node_modules/express/node_modules/send/node_modules/mime/package.json
deleted file mode 100644
index d0bd381ea3..0000000000
--- a/CoAuthoring/node_modules/express/node_modules/send/node_modules/mime/package.json
+++ /dev/null
@@ -1,36 +0,0 @@
-{
- "author": {
- "name": "Robert Kieffer",
- "email": "robert@broofa.com",
- "url": "http://github.com/broofa"
- },
- "contributors": [
- {
- "name": "Benjamin Thomas",
- "email": "benjamin@benjaminthomas.org",
- "url": "http://github.com/bentomas"
- }
- ],
- "dependencies": {},
- "description": "A comprehensive library for mime-type mapping",
- "devDependencies": {},
- "keywords": [
- "util",
- "mime"
- ],
- "main": "mime.js",
- "name": "mime",
- "repository": {
- "url": "https://github.com/broofa/node-mime",
- "type": "git"
- },
- "version": "1.2.11",
- "readme": "# mime\n\nComprehensive MIME type mapping API. Includes all 600+ types and 800+ extensions defined by the Apache project, plus additional types submitted by the node.js community.\n\n## Install\n\nInstall with [npm](http://github.com/isaacs/npm):\n\n npm install mime\n\n## API - Queries\n\n### mime.lookup(path)\nGet the mime type associated with a file, if no mime type is found `application/octet-stream` is returned. Performs a case-insensitive lookup using the extension in `path` (the substring after the last '/' or '.'). E.g.\n\n var mime = require('mime');\n\n mime.lookup('/path/to/file.txt'); // => 'text/plain'\n mime.lookup('file.txt'); // => 'text/plain'\n mime.lookup('.TXT'); // => 'text/plain'\n mime.lookup('htm'); // => 'text/html'\n\n### mime.default_type\nSets the mime type returned when `mime.lookup` fails to find the extension searched for. (Default is `application/octet-stream`.)\n\n### mime.extension(type)\nGet the default extension for `type`\n\n mime.extension('text/html'); // => 'html'\n mime.extension('application/octet-stream'); // => 'bin'\n\n### mime.charsets.lookup()\n\nMap mime-type to charset\n\n mime.charsets.lookup('text/plain'); // => 'UTF-8'\n\n(The logic for charset lookups is pretty rudimentary. Feel free to suggest improvements.)\n\n## API - Defining Custom Types\n\nThe following APIs allow you to add your own type mappings within your project. If you feel a type should be included as part of node-mime, see [requesting new types](https://github.com/broofa/node-mime/wiki/Requesting-New-Types).\n\n### mime.define()\n\nAdd custom mime/extension mappings\n\n mime.define({\n 'text/x-some-format': ['x-sf', 'x-sft', 'x-sfml'],\n 'application/x-my-type': ['x-mt', 'x-mtt'],\n // etc ...\n });\n\n mime.lookup('x-sft'); // => 'text/x-some-format'\n\nThe first entry in the extensions array is returned by `mime.extension()`. E.g.\n\n mime.extension('text/x-some-format'); // => 'x-sf'\n\n### mime.load(filepath)\n\nLoad mappings from an Apache \".types\" format file\n\n mime.load('./my_project.types');\n\nThe .types file format is simple - See the `types` dir for examples.\n",
- "readmeFilename": "README.md",
- "bugs": {
- "url": "https://github.com/broofa/node-mime/issues"
- },
- "homepage": "https://github.com/broofa/node-mime",
- "_id": "mime@1.2.11",
- "_from": "mime@1.2.11"
-}
diff --git a/CoAuthoring/node_modules/express/node_modules/send/node_modules/mime/test.js b/CoAuthoring/node_modules/express/node_modules/send/node_modules/mime/test.js
deleted file mode 100644
index 2cda1c7ad1..0000000000
--- a/CoAuthoring/node_modules/express/node_modules/send/node_modules/mime/test.js
+++ /dev/null
@@ -1,84 +0,0 @@
-/**
- * Usage: node test.js
- */
-
-var mime = require('./mime');
-var assert = require('assert');
-var path = require('path');
-
-function eq(a, b) {
- console.log('Test: ' + a + ' === ' + b);
- assert.strictEqual.apply(null, arguments);
-}
-
-console.log(Object.keys(mime.extensions).length + ' types');
-console.log(Object.keys(mime.types).length + ' extensions\n');
-
-//
-// Test mime lookups
-//
-
-eq('text/plain', mime.lookup('text.txt')); // normal file
-eq('text/plain', mime.lookup('TEXT.TXT')); // uppercase
-eq('text/plain', mime.lookup('dir/text.txt')); // dir + file
-eq('text/plain', mime.lookup('.text.txt')); // hidden file
-eq('text/plain', mime.lookup('.txt')); // nameless
-eq('text/plain', mime.lookup('txt')); // extension-only
-eq('text/plain', mime.lookup('/txt')); // extension-less ()
-eq('text/plain', mime.lookup('\\txt')); // Windows, extension-less
-eq('application/octet-stream', mime.lookup('text.nope')); // unrecognized
-eq('fallback', mime.lookup('text.fallback', 'fallback')); // alternate default
-
-//
-// Test extensions
-//
-
-eq('txt', mime.extension(mime.types.text));
-eq('html', mime.extension(mime.types.htm));
-eq('bin', mime.extension('application/octet-stream'));
-eq('bin', mime.extension('application/octet-stream '));
-eq('html', mime.extension(' text/html; charset=UTF-8'));
-eq('html', mime.extension('text/html; charset=UTF-8 '));
-eq('html', mime.extension('text/html; charset=UTF-8'));
-eq('html', mime.extension('text/html ; charset=UTF-8'));
-eq('html', mime.extension('text/html;charset=UTF-8'));
-eq('html', mime.extension('text/Html;charset=UTF-8'));
-eq(undefined, mime.extension('unrecognized'));
-
-//
-// Test node.types lookups
-//
-
-eq('application/font-woff', mime.lookup('file.woff'));
-eq('application/octet-stream', mime.lookup('file.buffer'));
-eq('audio/mp4', mime.lookup('file.m4a'));
-eq('font/opentype', mime.lookup('file.otf'));
-
-//
-// Test charsets
-//
-
-eq('UTF-8', mime.charsets.lookup('text/plain'));
-eq(undefined, mime.charsets.lookup(mime.types.js));
-eq('fallback', mime.charsets.lookup('application/octet-stream', 'fallback'));
-
-//
-// Test for overlaps between mime.types and node.types
-//
-
-var apacheTypes = new mime.Mime(), nodeTypes = new mime.Mime();
-apacheTypes.load(path.join(__dirname, 'types/mime.types'));
-nodeTypes.load(path.join(__dirname, 'types/node.types'));
-
-var keys = [].concat(Object.keys(apacheTypes.types))
- .concat(Object.keys(nodeTypes.types));
-keys.sort();
-for (var i = 1; i < keys.length; i++) {
- if (keys[i] == keys[i-1]) {
- console.warn('Warning: ' +
- 'node.types defines ' + keys[i] + '->' + nodeTypes.types[keys[i]] +
- ', mime.types defines ' + keys[i] + '->' + apacheTypes.types[keys[i]]);
- }
-}
-
-console.log('\nOK');
diff --git a/CoAuthoring/node_modules/express/node_modules/send/node_modules/mime/types/mime.types b/CoAuthoring/node_modules/express/node_modules/send/node_modules/mime/types/mime.types
deleted file mode 100644
index da8cd69187..0000000000
--- a/CoAuthoring/node_modules/express/node_modules/send/node_modules/mime/types/mime.types
+++ /dev/null
@@ -1,1588 +0,0 @@
-# This file maps Internet media types to unique file extension(s).
-# Although created for httpd, this file is used by many software systems
-# and has been placed in the public domain for unlimited redisribution.
-#
-# The table below contains both registered and (common) unregistered types.
-# A type that has no unique extension can be ignored -- they are listed
-# here to guide configurations toward known types and to make it easier to
-# identify "new" types. File extensions are also commonly used to indicate
-# content languages and encodings, so choose them carefully.
-#
-# Internet media types should be registered as described in RFC 4288.
-# The registry is at .
-#
-# MIME type (lowercased) Extensions
-# ============================================ ==========
-# application/1d-interleaved-parityfec
-# application/3gpp-ims+xml
-# application/activemessage
-application/andrew-inset ez
-# application/applefile
-application/applixware aw
-application/atom+xml atom
-application/atomcat+xml atomcat
-# application/atomicmail
-application/atomsvc+xml atomsvc
-# application/auth-policy+xml
-# application/batch-smtp
-# application/beep+xml
-# application/calendar+xml
-# application/cals-1840
-# application/ccmp+xml
-application/ccxml+xml ccxml
-application/cdmi-capability cdmia
-application/cdmi-container cdmic
-application/cdmi-domain cdmid
-application/cdmi-object cdmio
-application/cdmi-queue cdmiq
-# application/cea-2018+xml
-# application/cellml+xml
-# application/cfw
-# application/cnrp+xml
-# application/commonground
-# application/conference-info+xml
-# application/cpl+xml
-# application/csta+xml
-# application/cstadata+xml
-application/cu-seeme cu
-# application/cybercash
-application/davmount+xml davmount
-# application/dca-rft
-# application/dec-dx
-# application/dialog-info+xml
-# application/dicom
-# application/dns
-application/docbook+xml dbk
-# application/dskpp+xml
-application/dssc+der dssc
-application/dssc+xml xdssc
-# application/dvcs
-application/ecmascript ecma
-# application/edi-consent
-# application/edi-x12
-# application/edifact
-application/emma+xml emma
-# application/epp+xml
-application/epub+zip epub
-# application/eshop
-# application/example
-application/exi exi
-# application/fastinfoset
-# application/fastsoap
-# application/fits
-application/font-tdpfr pfr
-# application/framework-attributes+xml
-application/gml+xml gml
-application/gpx+xml gpx
-application/gxf gxf
-# application/h224
-# application/held+xml
-# application/http
-application/hyperstudio stk
-# application/ibe-key-request+xml
-# application/ibe-pkg-reply+xml
-# application/ibe-pp-data
-# application/iges
-# application/im-iscomposing+xml
-# application/index
-# application/index.cmd
-# application/index.obj
-# application/index.response
-# application/index.vnd
-application/inkml+xml ink inkml
-# application/iotp
-application/ipfix ipfix
-# application/ipp
-# application/isup
-application/java-archive jar
-application/java-serialized-object ser
-application/java-vm class
-application/javascript js
-application/json json
-application/jsonml+json jsonml
-# application/kpml-request+xml
-# application/kpml-response+xml
-application/lost+xml lostxml
-application/mac-binhex40 hqx
-application/mac-compactpro cpt
-# application/macwriteii
-application/mads+xml mads
-application/marc mrc
-application/marcxml+xml mrcx
-application/mathematica ma nb mb
-# application/mathml-content+xml
-# application/mathml-presentation+xml
-application/mathml+xml mathml
-# application/mbms-associated-procedure-description+xml
-# application/mbms-deregister+xml
-# application/mbms-envelope+xml
-# application/mbms-msk+xml
-# application/mbms-msk-response+xml
-# application/mbms-protection-description+xml
-# application/mbms-reception-report+xml
-# application/mbms-register+xml
-# application/mbms-register-response+xml
-# application/mbms-user-service-description+xml
-application/mbox mbox
-# application/media_control+xml
-application/mediaservercontrol+xml mscml
-application/metalink+xml metalink
-application/metalink4+xml meta4
-application/mets+xml mets
-# application/mikey
-application/mods+xml mods
-# application/moss-keys
-# application/moss-signature
-# application/mosskey-data
-# application/mosskey-request
-application/mp21 m21 mp21
-application/mp4 mp4s
-# application/mpeg4-generic
-# application/mpeg4-iod
-# application/mpeg4-iod-xmt
-# application/msc-ivr+xml
-# application/msc-mixer+xml
-application/msword doc dot
-application/mxf mxf
-# application/nasdata
-# application/news-checkgroups
-# application/news-groupinfo
-# application/news-transmission
-# application/nss
-# application/ocsp-request
-# application/ocsp-response
-application/octet-stream bin dms lrf mar so dist distz pkg bpk dump elc deploy
-application/oda oda
-application/oebps-package+xml opf
-application/ogg ogx
-application/omdoc+xml omdoc
-application/onenote onetoc onetoc2 onetmp onepkg
-application/oxps oxps
-# application/parityfec
-application/patch-ops-error+xml xer
-application/pdf pdf
-application/pgp-encrypted pgp
-# application/pgp-keys
-application/pgp-signature asc sig
-application/pics-rules prf
-# application/pidf+xml
-# application/pidf-diff+xml
-application/pkcs10 p10
-application/pkcs7-mime p7m p7c
-application/pkcs7-signature p7s
-application/pkcs8 p8
-application/pkix-attr-cert ac
-application/pkix-cert cer
-application/pkix-crl crl
-application/pkix-pkipath pkipath
-application/pkixcmp pki
-application/pls+xml pls
-# application/poc-settings+xml
-application/postscript ai eps ps
-# application/prs.alvestrand.titrax-sheet
-application/prs.cww cww
-# application/prs.nprend
-# application/prs.plucker
-# application/prs.rdf-xml-crypt
-# application/prs.xsf+xml
-application/pskc+xml pskcxml
-# application/qsig
-application/rdf+xml rdf
-application/reginfo+xml rif
-application/relax-ng-compact-syntax rnc
-# application/remote-printing
-application/resource-lists+xml rl
-application/resource-lists-diff+xml rld
-# application/riscos
-# application/rlmi+xml
-application/rls-services+xml rs
-application/rpki-ghostbusters gbr
-application/rpki-manifest mft
-application/rpki-roa roa
-# application/rpki-updown
-application/rsd+xml rsd
-application/rss+xml rss
-application/rtf rtf
-# application/rtx
-# application/samlassertion+xml
-# application/samlmetadata+xml
-application/sbml+xml sbml
-application/scvp-cv-request scq
-application/scvp-cv-response scs
-application/scvp-vp-request spq
-application/scvp-vp-response spp
-application/sdp sdp
-# application/set-payment
-application/set-payment-initiation setpay
-# application/set-registration
-application/set-registration-initiation setreg
-# application/sgml
-# application/sgml-open-catalog
-application/shf+xml shf
-# application/sieve
-# application/simple-filter+xml
-# application/simple-message-summary
-# application/simplesymbolcontainer
-# application/slate
-# application/smil
-application/smil+xml smi smil
-# application/soap+fastinfoset
-# application/soap+xml
-application/sparql-query rq
-application/sparql-results+xml srx
-# application/spirits-event+xml
-application/srgs gram
-application/srgs+xml grxml
-application/sru+xml sru
-application/ssdl+xml ssdl
-application/ssml+xml ssml
-# application/tamp-apex-update
-# application/tamp-apex-update-confirm
-# application/tamp-community-update
-# application/tamp-community-update-confirm
-# application/tamp-error
-# application/tamp-sequence-adjust
-# application/tamp-sequence-adjust-confirm
-# application/tamp-status-query
-# application/tamp-status-response
-# application/tamp-update
-# application/tamp-update-confirm
-application/tei+xml tei teicorpus
-application/thraud+xml tfi
-# application/timestamp-query
-# application/timestamp-reply
-application/timestamped-data tsd
-# application/tve-trigger
-# application/ulpfec
-# application/vcard+xml
-# application/vemmi
-# application/vividence.scriptfile
-# application/vnd.3gpp.bsf+xml
-application/vnd.3gpp.pic-bw-large plb
-application/vnd.3gpp.pic-bw-small psb
-application/vnd.3gpp.pic-bw-var pvb
-# application/vnd.3gpp.sms
-# application/vnd.3gpp2.bcmcsinfo+xml
-# application/vnd.3gpp2.sms
-application/vnd.3gpp2.tcap tcap
-application/vnd.3m.post-it-notes pwn
-application/vnd.accpac.simply.aso aso
-application/vnd.accpac.simply.imp imp
-application/vnd.acucobol acu
-application/vnd.acucorp atc acutc
-application/vnd.adobe.air-application-installer-package+zip air
-application/vnd.adobe.formscentral.fcdt fcdt
-application/vnd.adobe.fxp fxp fxpl
-# application/vnd.adobe.partial-upload
-application/vnd.adobe.xdp+xml xdp
-application/vnd.adobe.xfdf xfdf
-# application/vnd.aether.imp
-# application/vnd.ah-barcode
-application/vnd.ahead.space ahead
-application/vnd.airzip.filesecure.azf azf
-application/vnd.airzip.filesecure.azs azs
-application/vnd.amazon.ebook azw
-application/vnd.americandynamics.acc acc
-application/vnd.amiga.ami ami
-# application/vnd.amundsen.maze+xml
-application/vnd.android.package-archive apk
-application/vnd.anser-web-certificate-issue-initiation cii
-application/vnd.anser-web-funds-transfer-initiation fti
-application/vnd.antix.game-component atx
-application/vnd.apple.installer+xml mpkg
-application/vnd.apple.mpegurl m3u8
-# application/vnd.arastra.swi
-application/vnd.aristanetworks.swi swi
-application/vnd.astraea-software.iota iota
-application/vnd.audiograph aep
-# application/vnd.autopackage
-# application/vnd.avistar+xml
-application/vnd.blueice.multipass mpm
-# application/vnd.bluetooth.ep.oob
-application/vnd.bmi bmi
-application/vnd.businessobjects rep
-# application/vnd.cab-jscript
-# application/vnd.canon-cpdl
-# application/vnd.canon-lips
-# application/vnd.cendio.thinlinc.clientconf
-application/vnd.chemdraw+xml cdxml
-application/vnd.chipnuts.karaoke-mmd mmd
-application/vnd.cinderella cdy
-# application/vnd.cirpack.isdn-ext
-application/vnd.claymore cla
-application/vnd.cloanto.rp9 rp9
-application/vnd.clonk.c4group c4g c4d c4f c4p c4u
-application/vnd.cluetrust.cartomobile-config c11amc
-application/vnd.cluetrust.cartomobile-config-pkg c11amz
-# application/vnd.collection+json
-# application/vnd.commerce-battelle
-application/vnd.commonspace csp
-application/vnd.contact.cmsg cdbcmsg
-application/vnd.cosmocaller cmc
-application/vnd.crick.clicker clkx
-application/vnd.crick.clicker.keyboard clkk
-application/vnd.crick.clicker.palette clkp
-application/vnd.crick.clicker.template clkt
-application/vnd.crick.clicker.wordbank clkw
-application/vnd.criticaltools.wbs+xml wbs
-application/vnd.ctc-posml pml
-# application/vnd.ctct.ws+xml
-# application/vnd.cups-pdf
-# application/vnd.cups-postscript
-application/vnd.cups-ppd ppd
-# application/vnd.cups-raster
-# application/vnd.cups-raw
-# application/vnd.curl
-application/vnd.curl.car car
-application/vnd.curl.pcurl pcurl
-# application/vnd.cybank
-application/vnd.dart dart
-application/vnd.data-vision.rdz rdz
-application/vnd.dece.data uvf uvvf uvd uvvd
-application/vnd.dece.ttml+xml uvt uvvt
-application/vnd.dece.unspecified uvx uvvx
-application/vnd.dece.zip uvz uvvz
-application/vnd.denovo.fcselayout-link fe_launch
-# application/vnd.dir-bi.plate-dl-nosuffix
-application/vnd.dna dna
-application/vnd.dolby.mlp mlp
-# application/vnd.dolby.mobile.1
-# application/vnd.dolby.mobile.2
-application/vnd.dpgraph dpg
-application/vnd.dreamfactory dfac
-application/vnd.ds-keypoint kpxx
-application/vnd.dvb.ait ait
-# application/vnd.dvb.dvbj
-# application/vnd.dvb.esgcontainer
-# application/vnd.dvb.ipdcdftnotifaccess
-# application/vnd.dvb.ipdcesgaccess
-# application/vnd.dvb.ipdcesgaccess2
-# application/vnd.dvb.ipdcesgpdd
-# application/vnd.dvb.ipdcroaming
-# application/vnd.dvb.iptv.alfec-base
-# application/vnd.dvb.iptv.alfec-enhancement
-# application/vnd.dvb.notif-aggregate-root+xml
-# application/vnd.dvb.notif-container+xml
-# application/vnd.dvb.notif-generic+xml
-# application/vnd.dvb.notif-ia-msglist+xml
-# application/vnd.dvb.notif-ia-registration-request+xml
-# application/vnd.dvb.notif-ia-registration-response+xml
-# application/vnd.dvb.notif-init+xml
-# application/vnd.dvb.pfr
-application/vnd.dvb.service svc
-# application/vnd.dxr
-application/vnd.dynageo geo
-# application/vnd.easykaraoke.cdgdownload
-# application/vnd.ecdis-update
-application/vnd.ecowin.chart mag
-# application/vnd.ecowin.filerequest
-# application/vnd.ecowin.fileupdate
-# application/vnd.ecowin.series
-# application/vnd.ecowin.seriesrequest
-# application/vnd.ecowin.seriesupdate
-# application/vnd.emclient.accessrequest+xml
-application/vnd.enliven nml
-# application/vnd.eprints.data+xml
-application/vnd.epson.esf esf
-application/vnd.epson.msf msf
-application/vnd.epson.quickanime qam
-application/vnd.epson.salt slt
-application/vnd.epson.ssf ssf
-# application/vnd.ericsson.quickcall
-application/vnd.eszigno3+xml es3 et3
-# application/vnd.etsi.aoc+xml
-# application/vnd.etsi.cug+xml
-# application/vnd.etsi.iptvcommand+xml
-# application/vnd.etsi.iptvdiscovery+xml
-# application/vnd.etsi.iptvprofile+xml
-# application/vnd.etsi.iptvsad-bc+xml
-# application/vnd.etsi.iptvsad-cod+xml
-# application/vnd.etsi.iptvsad-npvr+xml
-# application/vnd.etsi.iptvservice+xml
-# application/vnd.etsi.iptvsync+xml
-# application/vnd.etsi.iptvueprofile+xml
-# application/vnd.etsi.mcid+xml
-# application/vnd.etsi.overload-control-policy-dataset+xml
-# application/vnd.etsi.sci+xml
-# application/vnd.etsi.simservs+xml
-# application/vnd.etsi.tsl+xml
-# application/vnd.etsi.tsl.der
-# application/vnd.eudora.data
-application/vnd.ezpix-album ez2
-application/vnd.ezpix-package ez3
-# application/vnd.f-secure.mobile
-application/vnd.fdf fdf
-application/vnd.fdsn.mseed mseed
-application/vnd.fdsn.seed seed dataless
-# application/vnd.ffsns
-# application/vnd.fints
-application/vnd.flographit gph
-application/vnd.fluxtime.clip ftc
-# application/vnd.font-fontforge-sfd
-application/vnd.framemaker fm frame maker book
-application/vnd.frogans.fnc fnc
-application/vnd.frogans.ltf ltf
-application/vnd.fsc.weblaunch fsc
-application/vnd.fujitsu.oasys oas
-application/vnd.fujitsu.oasys2 oa2
-application/vnd.fujitsu.oasys3 oa3
-application/vnd.fujitsu.oasysgp fg5
-application/vnd.fujitsu.oasysprs bh2
-# application/vnd.fujixerox.art-ex
-# application/vnd.fujixerox.art4
-# application/vnd.fujixerox.hbpl
-application/vnd.fujixerox.ddd ddd
-application/vnd.fujixerox.docuworks xdw
-application/vnd.fujixerox.docuworks.binder xbd
-# application/vnd.fut-misnet
-application/vnd.fuzzysheet fzs
-application/vnd.genomatix.tuxedo txd
-# application/vnd.geocube+xml
-application/vnd.geogebra.file ggb
-application/vnd.geogebra.tool ggt
-application/vnd.geometry-explorer gex gre
-application/vnd.geonext gxt
-application/vnd.geoplan g2w
-application/vnd.geospace g3w
-# application/vnd.globalplatform.card-content-mgt
-# application/vnd.globalplatform.card-content-mgt-response
-application/vnd.gmx gmx
-application/vnd.google-earth.kml+xml kml
-application/vnd.google-earth.kmz kmz
-application/vnd.grafeq gqf gqs
-# application/vnd.gridmp
-application/vnd.groove-account gac
-application/vnd.groove-help ghf
-application/vnd.groove-identity-message gim
-application/vnd.groove-injector grv
-application/vnd.groove-tool-message gtm
-application/vnd.groove-tool-template tpl
-application/vnd.groove-vcard vcg
-# application/vnd.hal+json
-application/vnd.hal+xml hal
-application/vnd.handheld-entertainment+xml zmm
-application/vnd.hbci hbci
-# application/vnd.hcl-bireports
-application/vnd.hhe.lesson-player les
-application/vnd.hp-hpgl hpgl
-application/vnd.hp-hpid hpid
-application/vnd.hp-hps hps
-application/vnd.hp-jlyt jlt
-application/vnd.hp-pcl pcl
-application/vnd.hp-pclxl pclxl
-# application/vnd.httphone
-application/vnd.hydrostatix.sof-data sfd-hdstx
-# application/vnd.hzn-3d-crossword
-# application/vnd.ibm.afplinedata
-# application/vnd.ibm.electronic-media
-application/vnd.ibm.minipay mpy
-application/vnd.ibm.modcap afp listafp list3820
-application/vnd.ibm.rights-management irm
-application/vnd.ibm.secure-container sc
-application/vnd.iccprofile icc icm
-application/vnd.igloader igl
-application/vnd.immervision-ivp ivp
-application/vnd.immervision-ivu ivu
-# application/vnd.informedcontrol.rms+xml
-# application/vnd.informix-visionary
-# application/vnd.infotech.project
-# application/vnd.infotech.project+xml
-# application/vnd.innopath.wamp.notification
-application/vnd.insors.igm igm
-application/vnd.intercon.formnet xpw xpx
-application/vnd.intergeo i2g
-# application/vnd.intertrust.digibox
-# application/vnd.intertrust.nncp
-application/vnd.intu.qbo qbo
-application/vnd.intu.qfx qfx
-# application/vnd.iptc.g2.conceptitem+xml
-# application/vnd.iptc.g2.knowledgeitem+xml
-# application/vnd.iptc.g2.newsitem+xml
-# application/vnd.iptc.g2.newsmessage+xml
-# application/vnd.iptc.g2.packageitem+xml
-# application/vnd.iptc.g2.planningitem+xml
-application/vnd.ipunplugged.rcprofile rcprofile
-application/vnd.irepository.package+xml irp
-application/vnd.is-xpr xpr
-application/vnd.isac.fcs fcs
-application/vnd.jam jam
-# application/vnd.japannet-directory-service
-# application/vnd.japannet-jpnstore-wakeup
-# application/vnd.japannet-payment-wakeup
-# application/vnd.japannet-registration
-# application/vnd.japannet-registration-wakeup
-# application/vnd.japannet-setstore-wakeup
-# application/vnd.japannet-verification
-# application/vnd.japannet-verification-wakeup
-application/vnd.jcp.javame.midlet-rms rms
-application/vnd.jisp jisp
-application/vnd.joost.joda-archive joda
-application/vnd.kahootz ktz ktr
-application/vnd.kde.karbon karbon
-application/vnd.kde.kchart chrt
-application/vnd.kde.kformula kfo
-application/vnd.kde.kivio flw
-application/vnd.kde.kontour kon
-application/vnd.kde.kpresenter kpr kpt
-application/vnd.kde.kspread ksp
-application/vnd.kde.kword kwd kwt
-application/vnd.kenameaapp htke
-application/vnd.kidspiration kia
-application/vnd.kinar kne knp
-application/vnd.koan skp skd skt skm
-application/vnd.kodak-descriptor sse
-application/vnd.las.las+xml lasxml
-# application/vnd.liberty-request+xml
-application/vnd.llamagraphics.life-balance.desktop lbd
-application/vnd.llamagraphics.life-balance.exchange+xml lbe
-application/vnd.lotus-1-2-3 123
-application/vnd.lotus-approach apr
-application/vnd.lotus-freelance pre
-application/vnd.lotus-notes nsf
-application/vnd.lotus-organizer org
-application/vnd.lotus-screencam scm
-application/vnd.lotus-wordpro lwp
-application/vnd.macports.portpkg portpkg
-# application/vnd.marlin.drm.actiontoken+xml
-# application/vnd.marlin.drm.conftoken+xml
-# application/vnd.marlin.drm.license+xml
-# application/vnd.marlin.drm.mdcf
-application/vnd.mcd mcd
-application/vnd.medcalcdata mc1
-application/vnd.mediastation.cdkey cdkey
-# application/vnd.meridian-slingshot
-application/vnd.mfer mwf
-application/vnd.mfmp mfm
-application/vnd.micrografx.flo flo
-application/vnd.micrografx.igx igx
-application/vnd.mif mif
-# application/vnd.minisoft-hp3000-save
-# application/vnd.mitsubishi.misty-guard.trustweb
-application/vnd.mobius.daf daf
-application/vnd.mobius.dis dis
-application/vnd.mobius.mbk mbk
-application/vnd.mobius.mqy mqy
-application/vnd.mobius.msl msl
-application/vnd.mobius.plc plc
-application/vnd.mobius.txf txf
-application/vnd.mophun.application mpn
-application/vnd.mophun.certificate mpc
-# application/vnd.motorola.flexsuite
-# application/vnd.motorola.flexsuite.adsi
-# application/vnd.motorola.flexsuite.fis
-# application/vnd.motorola.flexsuite.gotap
-# application/vnd.motorola.flexsuite.kmr
-# application/vnd.motorola.flexsuite.ttc
-# application/vnd.motorola.flexsuite.wem
-# application/vnd.motorola.iprm
-application/vnd.mozilla.xul+xml xul
-application/vnd.ms-artgalry cil
-# application/vnd.ms-asf
-application/vnd.ms-cab-compressed cab
-# application/vnd.ms-color.iccprofile
-application/vnd.ms-excel xls xlm xla xlc xlt xlw
-application/vnd.ms-excel.addin.macroenabled.12 xlam
-application/vnd.ms-excel.sheet.binary.macroenabled.12 xlsb
-application/vnd.ms-excel.sheet.macroenabled.12 xlsm
-application/vnd.ms-excel.template.macroenabled.12 xltm
-application/vnd.ms-fontobject eot
-application/vnd.ms-htmlhelp chm
-application/vnd.ms-ims ims
-application/vnd.ms-lrm lrm
-# application/vnd.ms-office.activex+xml
-application/vnd.ms-officetheme thmx
-# application/vnd.ms-opentype
-# application/vnd.ms-package.obfuscated-opentype
-application/vnd.ms-pki.seccat cat
-application/vnd.ms-pki.stl stl
-# application/vnd.ms-playready.initiator+xml
-application/vnd.ms-powerpoint ppt pps pot
-application/vnd.ms-powerpoint.addin.macroenabled.12 ppam
-application/vnd.ms-powerpoint.presentation.macroenabled.12 pptm
-application/vnd.ms-powerpoint.slide.macroenabled.12 sldm
-application/vnd.ms-powerpoint.slideshow.macroenabled.12 ppsm
-application/vnd.ms-powerpoint.template.macroenabled.12 potm
-# application/vnd.ms-printing.printticket+xml
-application/vnd.ms-project mpp mpt
-# application/vnd.ms-tnef
-# application/vnd.ms-wmdrm.lic-chlg-req
-# application/vnd.ms-wmdrm.lic-resp
-# application/vnd.ms-wmdrm.meter-chlg-req
-# application/vnd.ms-wmdrm.meter-resp
-application/vnd.ms-word.document.macroenabled.12 docm
-application/vnd.ms-word.template.macroenabled.12 dotm
-application/vnd.ms-works wps wks wcm wdb
-application/vnd.ms-wpl wpl
-application/vnd.ms-xpsdocument xps
-application/vnd.mseq mseq
-# application/vnd.msign
-# application/vnd.multiad.creator
-# application/vnd.multiad.creator.cif
-# application/vnd.music-niff
-application/vnd.musician mus
-application/vnd.muvee.style msty
-application/vnd.mynfc taglet
-# application/vnd.ncd.control
-# application/vnd.ncd.reference
-# application/vnd.nervana
-# application/vnd.netfpx
-application/vnd.neurolanguage.nlu nlu
-application/vnd.nitf ntf nitf
-application/vnd.noblenet-directory nnd
-application/vnd.noblenet-sealer nns
-application/vnd.noblenet-web nnw
-# application/vnd.nokia.catalogs
-# application/vnd.nokia.conml+wbxml
-# application/vnd.nokia.conml+xml
-# application/vnd.nokia.isds-radio-presets
-# application/vnd.nokia.iptv.config+xml
-# application/vnd.nokia.landmark+wbxml
-# application/vnd.nokia.landmark+xml
-# application/vnd.nokia.landmarkcollection+xml
-# application/vnd.nokia.n-gage.ac+xml
-application/vnd.nokia.n-gage.data ngdat
-application/vnd.nokia.n-gage.symbian.install n-gage
-# application/vnd.nokia.ncd
-# application/vnd.nokia.pcd+wbxml
-# application/vnd.nokia.pcd+xml
-application/vnd.nokia.radio-preset rpst
-application/vnd.nokia.radio-presets rpss
-application/vnd.novadigm.edm edm
-application/vnd.novadigm.edx edx
-application/vnd.novadigm.ext ext
-# application/vnd.ntt-local.file-transfer
-# application/vnd.ntt-local.sip-ta_remote
-# application/vnd.ntt-local.sip-ta_tcp_stream
-application/vnd.oasis.opendocument.chart odc
-application/vnd.oasis.opendocument.chart-template otc
-application/vnd.oasis.opendocument.database odb
-application/vnd.oasis.opendocument.formula odf
-application/vnd.oasis.opendocument.formula-template odft
-application/vnd.oasis.opendocument.graphics odg
-application/vnd.oasis.opendocument.graphics-template otg
-application/vnd.oasis.opendocument.image odi
-application/vnd.oasis.opendocument.image-template oti
-application/vnd.oasis.opendocument.presentation odp
-application/vnd.oasis.opendocument.presentation-template otp
-application/vnd.oasis.opendocument.spreadsheet ods
-application/vnd.oasis.opendocument.spreadsheet-template ots
-application/vnd.oasis.opendocument.text odt
-application/vnd.oasis.opendocument.text-master odm
-application/vnd.oasis.opendocument.text-template ott
-application/vnd.oasis.opendocument.text-web oth
-# application/vnd.obn
-# application/vnd.oftn.l10n+json
-# application/vnd.oipf.contentaccessdownload+xml
-# application/vnd.oipf.contentaccessstreaming+xml
-# application/vnd.oipf.cspg-hexbinary
-# application/vnd.oipf.dae.svg+xml
-# application/vnd.oipf.dae.xhtml+xml
-# application/vnd.oipf.mippvcontrolmessage+xml
-# application/vnd.oipf.pae.gem
-# application/vnd.oipf.spdiscovery+xml
-# application/vnd.oipf.spdlist+xml
-# application/vnd.oipf.ueprofile+xml
-# application/vnd.oipf.userprofile+xml
-application/vnd.olpc-sugar xo
-# application/vnd.oma-scws-config
-# application/vnd.oma-scws-http-request
-# application/vnd.oma-scws-http-response
-# application/vnd.oma.bcast.associated-procedure-parameter+xml
-# application/vnd.oma.bcast.drm-trigger+xml
-# application/vnd.oma.bcast.imd+xml
-# application/vnd.oma.bcast.ltkm
-# application/vnd.oma.bcast.notification+xml
-# application/vnd.oma.bcast.provisioningtrigger
-# application/vnd.oma.bcast.sgboot
-# application/vnd.oma.bcast.sgdd+xml
-# application/vnd.oma.bcast.sgdu
-# application/vnd.oma.bcast.simple-symbol-container
-# application/vnd.oma.bcast.smartcard-trigger+xml
-# application/vnd.oma.bcast.sprov+xml
-# application/vnd.oma.bcast.stkm
-# application/vnd.oma.cab-address-book+xml
-# application/vnd.oma.cab-feature-handler+xml
-# application/vnd.oma.cab-pcc+xml
-# application/vnd.oma.cab-user-prefs+xml
-# application/vnd.oma.dcd
-# application/vnd.oma.dcdc
-application/vnd.oma.dd2+xml dd2
-# application/vnd.oma.drm.risd+xml
-# application/vnd.oma.group-usage-list+xml
-# application/vnd.oma.pal+xml
-# application/vnd.oma.poc.detailed-progress-report+xml
-# application/vnd.oma.poc.final-report+xml
-# application/vnd.oma.poc.groups+xml
-# application/vnd.oma.poc.invocation-descriptor+xml
-# application/vnd.oma.poc.optimized-progress-report+xml
-# application/vnd.oma.push
-# application/vnd.oma.scidm.messages+xml
-# application/vnd.oma.xcap-directory+xml
-# application/vnd.omads-email+xml
-# application/vnd.omads-file+xml
-# application/vnd.omads-folder+xml
-# application/vnd.omaloc-supl-init
-application/vnd.openofficeorg.extension oxt
-# application/vnd.openxmlformats-officedocument.custom-properties+xml
-# application/vnd.openxmlformats-officedocument.customxmlproperties+xml
-# application/vnd.openxmlformats-officedocument.drawing+xml
-# application/vnd.openxmlformats-officedocument.drawingml.chart+xml
-# application/vnd.openxmlformats-officedocument.drawingml.chartshapes+xml
-# application/vnd.openxmlformats-officedocument.drawingml.diagramcolors+xml
-# application/vnd.openxmlformats-officedocument.drawingml.diagramdata+xml
-# application/vnd.openxmlformats-officedocument.drawingml.diagramlayout+xml
-# application/vnd.openxmlformats-officedocument.drawingml.diagramstyle+xml
-# application/vnd.openxmlformats-officedocument.extended-properties+xml
-# application/vnd.openxmlformats-officedocument.presentationml.commentauthors+xml
-# application/vnd.openxmlformats-officedocument.presentationml.comments+xml
-# application/vnd.openxmlformats-officedocument.presentationml.handoutmaster+xml
-# application/vnd.openxmlformats-officedocument.presentationml.notesmaster+xml
-# application/vnd.openxmlformats-officedocument.presentationml.notesslide+xml
-application/vnd.openxmlformats-officedocument.presentationml.presentation pptx
-# application/vnd.openxmlformats-officedocument.presentationml.presentation.main+xml
-# application/vnd.openxmlformats-officedocument.presentationml.presprops+xml
-application/vnd.openxmlformats-officedocument.presentationml.slide sldx
-# application/vnd.openxmlformats-officedocument.presentationml.slide+xml
-# application/vnd.openxmlformats-officedocument.presentationml.slidelayout+xml
-# application/vnd.openxmlformats-officedocument.presentationml.slidemaster+xml
-application/vnd.openxmlformats-officedocument.presentationml.slideshow ppsx
-# application/vnd.openxmlformats-officedocument.presentationml.slideshow.main+xml
-# application/vnd.openxmlformats-officedocument.presentationml.slideupdateinfo+xml
-# application/vnd.openxmlformats-officedocument.presentationml.tablestyles+xml
-# application/vnd.openxmlformats-officedocument.presentationml.tags+xml
-application/vnd.openxmlformats-officedocument.presentationml.template potx
-# application/vnd.openxmlformats-officedocument.presentationml.template.main+xml
-# application/vnd.openxmlformats-officedocument.presentationml.viewprops+xml
-# application/vnd.openxmlformats-officedocument.spreadsheetml.calcchain+xml
-# application/vnd.openxmlformats-officedocument.spreadsheetml.chartsheet+xml
-# application/vnd.openxmlformats-officedocument.spreadsheetml.comments+xml
-# application/vnd.openxmlformats-officedocument.spreadsheetml.connections+xml
-# application/vnd.openxmlformats-officedocument.spreadsheetml.dialogsheet+xml
-# application/vnd.openxmlformats-officedocument.spreadsheetml.externallink+xml
-# application/vnd.openxmlformats-officedocument.spreadsheetml.pivotcachedefinition+xml
-# application/vnd.openxmlformats-officedocument.spreadsheetml.pivotcacherecords+xml
-# application/vnd.openxmlformats-officedocument.spreadsheetml.pivottable+xml
-# application/vnd.openxmlformats-officedocument.spreadsheetml.querytable+xml
-# application/vnd.openxmlformats-officedocument.spreadsheetml.revisionheaders+xml
-# application/vnd.openxmlformats-officedocument.spreadsheetml.revisionlog+xml
-# application/vnd.openxmlformats-officedocument.spreadsheetml.sharedstrings+xml
-application/vnd.openxmlformats-officedocument.spreadsheetml.sheet xlsx
-# application/vnd.openxmlformats-officedocument.spreadsheetml.sheet.main+xml
-# application/vnd.openxmlformats-officedocument.spreadsheetml.sheetmetadata+xml
-# application/vnd.openxmlformats-officedocument.spreadsheetml.styles+xml
-# application/vnd.openxmlformats-officedocument.spreadsheetml.table+xml
-# application/vnd.openxmlformats-officedocument.spreadsheetml.tablesinglecells+xml
-application/vnd.openxmlformats-officedocument.spreadsheetml.template xltx
-# application/vnd.openxmlformats-officedocument.spreadsheetml.template.main+xml
-# application/vnd.openxmlformats-officedocument.spreadsheetml.usernames+xml
-# application/vnd.openxmlformats-officedocument.spreadsheetml.volatiledependencies+xml
-# application/vnd.openxmlformats-officedocument.spreadsheetml.worksheet+xml
-# application/vnd.openxmlformats-officedocument.theme+xml
-# application/vnd.openxmlformats-officedocument.themeoverride+xml
-# application/vnd.openxmlformats-officedocument.vmldrawing
-# application/vnd.openxmlformats-officedocument.wordprocessingml.comments+xml
-application/vnd.openxmlformats-officedocument.wordprocessingml.document docx
-# application/vnd.openxmlformats-officedocument.wordprocessingml.document.glossary+xml
-# application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml
-# application/vnd.openxmlformats-officedocument.wordprocessingml.endnotes+xml
-# application/vnd.openxmlformats-officedocument.wordprocessingml.fonttable+xml
-# application/vnd.openxmlformats-officedocument.wordprocessingml.footer+xml
-# application/vnd.openxmlformats-officedocument.wordprocessingml.footnotes+xml
-# application/vnd.openxmlformats-officedocument.wordprocessingml.numbering+xml
-# application/vnd.openxmlformats-officedocument.wordprocessingml.settings+xml
-# application/vnd.openxmlformats-officedocument.wordprocessingml.styles+xml
-application/vnd.openxmlformats-officedocument.wordprocessingml.template dotx
-# application/vnd.openxmlformats-officedocument.wordprocessingml.template.main+xml
-# application/vnd.openxmlformats-officedocument.wordprocessingml.websettings+xml
-# application/vnd.openxmlformats-package.core-properties+xml
-# application/vnd.openxmlformats-package.digital-signature-xmlsignature+xml
-# application/vnd.openxmlformats-package.relationships+xml
-# application/vnd.quobject-quoxdocument
-# application/vnd.osa.netdeploy
-application/vnd.osgeo.mapguide.package mgp
-# application/vnd.osgi.bundle
-application/vnd.osgi.dp dp
-application/vnd.osgi.subsystem esa
-# application/vnd.otps.ct-kip+xml
-application/vnd.palm pdb pqa oprc
-# application/vnd.paos.xml
-application/vnd.pawaafile paw
-application/vnd.pg.format str
-application/vnd.pg.osasli ei6
-# application/vnd.piaccess.application-licence
-application/vnd.picsel efif
-application/vnd.pmi.widget wg
-# application/vnd.poc.group-advertisement+xml
-application/vnd.pocketlearn plf
-application/vnd.powerbuilder6 pbd
-# application/vnd.powerbuilder6-s
-# application/vnd.powerbuilder7
-# application/vnd.powerbuilder7-s
-# application/vnd.powerbuilder75
-# application/vnd.powerbuilder75-s
-# application/vnd.preminet
-application/vnd.previewsystems.box box
-application/vnd.proteus.magazine mgz
-application/vnd.publishare-delta-tree qps
-application/vnd.pvi.ptid1 ptid
-# application/vnd.pwg-multiplexed
-# application/vnd.pwg-xhtml-print+xml
-# application/vnd.qualcomm.brew-app-res
-application/vnd.quark.quarkxpress qxd qxt qwd qwt qxl qxb
-# application/vnd.radisys.moml+xml
-# application/vnd.radisys.msml+xml
-# application/vnd.radisys.msml-audit+xml
-# application/vnd.radisys.msml-audit-conf+xml
-# application/vnd.radisys.msml-audit-conn+xml
-# application/vnd.radisys.msml-audit-dialog+xml
-# application/vnd.radisys.msml-audit-stream+xml
-# application/vnd.radisys.msml-conf+xml
-# application/vnd.radisys.msml-dialog+xml
-# application/vnd.radisys.msml-dialog-base+xml
-# application/vnd.radisys.msml-dialog-fax-detect+xml
-# application/vnd.radisys.msml-dialog-fax-sendrecv+xml
-# application/vnd.radisys.msml-dialog-group+xml
-# application/vnd.radisys.msml-dialog-speech+xml
-# application/vnd.radisys.msml-dialog-transform+xml
-# application/vnd.rainstor.data
-# application/vnd.rapid
-application/vnd.realvnc.bed bed
-application/vnd.recordare.musicxml mxl
-application/vnd.recordare.musicxml+xml musicxml
-# application/vnd.renlearn.rlprint
-application/vnd.rig.cryptonote cryptonote
-application/vnd.rim.cod cod
-application/vnd.rn-realmedia rm
-application/vnd.rn-realmedia-vbr rmvb
-application/vnd.route66.link66+xml link66
-# application/vnd.rs-274x
-# application/vnd.ruckus.download
-# application/vnd.s3sms
-application/vnd.sailingtracker.track st
-# application/vnd.sbm.cid
-# application/vnd.sbm.mid2
-# application/vnd.scribus
-# application/vnd.sealed.3df
-# application/vnd.sealed.csf
-# application/vnd.sealed.doc
-# application/vnd.sealed.eml
-# application/vnd.sealed.mht
-# application/vnd.sealed.net
-# application/vnd.sealed.ppt
-# application/vnd.sealed.tiff
-# application/vnd.sealed.xls
-# application/vnd.sealedmedia.softseal.html
-# application/vnd.sealedmedia.softseal.pdf
-application/vnd.seemail see
-application/vnd.sema sema
-application/vnd.semd semd
-application/vnd.semf semf
-application/vnd.shana.informed.formdata ifm
-application/vnd.shana.informed.formtemplate itp
-application/vnd.shana.informed.interchange iif
-application/vnd.shana.informed.package ipk
-application/vnd.simtech-mindmapper twd twds
-application/vnd.smaf mmf
-# application/vnd.smart.notebook
-application/vnd.smart.teacher teacher
-# application/vnd.software602.filler.form+xml
-# application/vnd.software602.filler.form-xml-zip
-application/vnd.solent.sdkm+xml sdkm sdkd
-application/vnd.spotfire.dxp dxp
-application/vnd.spotfire.sfs sfs
-# application/vnd.sss-cod
-# application/vnd.sss-dtf
-# application/vnd.sss-ntf
-application/vnd.stardivision.calc sdc
-application/vnd.stardivision.draw sda
-application/vnd.stardivision.impress sdd
-application/vnd.stardivision.math smf
-application/vnd.stardivision.writer sdw vor
-application/vnd.stardivision.writer-global sgl
-application/vnd.stepmania.package smzip
-application/vnd.stepmania.stepchart sm
-# application/vnd.street-stream
-application/vnd.sun.xml.calc sxc
-application/vnd.sun.xml.calc.template stc
-application/vnd.sun.xml.draw sxd
-application/vnd.sun.xml.draw.template std
-application/vnd.sun.xml.impress sxi
-application/vnd.sun.xml.impress.template sti
-application/vnd.sun.xml.math sxm
-application/vnd.sun.xml.writer sxw
-application/vnd.sun.xml.writer.global sxg
-application/vnd.sun.xml.writer.template stw
-# application/vnd.sun.wadl+xml
-application/vnd.sus-calendar sus susp
-application/vnd.svd svd
-# application/vnd.swiftview-ics
-application/vnd.symbian.install sis sisx
-application/vnd.syncml+xml xsm
-application/vnd.syncml.dm+wbxml bdm
-application/vnd.syncml.dm+xml xdm
-# application/vnd.syncml.dm.notification
-# application/vnd.syncml.ds.notification
-application/vnd.tao.intent-module-archive tao
-application/vnd.tcpdump.pcap pcap cap dmp
-application/vnd.tmobile-livetv tmo
-application/vnd.trid.tpt tpt
-application/vnd.triscape.mxs mxs
-application/vnd.trueapp tra
-# application/vnd.truedoc
-# application/vnd.ubisoft.webplayer
-application/vnd.ufdl ufd ufdl
-application/vnd.uiq.theme utz
-application/vnd.umajin umj
-application/vnd.unity unityweb
-application/vnd.uoml+xml uoml
-# application/vnd.uplanet.alert
-# application/vnd.uplanet.alert-wbxml
-# application/vnd.uplanet.bearer-choice
-# application/vnd.uplanet.bearer-choice-wbxml
-# application/vnd.uplanet.cacheop
-# application/vnd.uplanet.cacheop-wbxml
-# application/vnd.uplanet.channel
-# application/vnd.uplanet.channel-wbxml
-# application/vnd.uplanet.list
-# application/vnd.uplanet.list-wbxml
-# application/vnd.uplanet.listcmd
-# application/vnd.uplanet.listcmd-wbxml
-# application/vnd.uplanet.signal
-application/vnd.vcx vcx
-# application/vnd.vd-study
-# application/vnd.vectorworks
-# application/vnd.verimatrix.vcas
-# application/vnd.vidsoft.vidconference
-application/vnd.visio vsd vst vss vsw
-application/vnd.visionary vis
-# application/vnd.vividence.scriptfile
-application/vnd.vsf vsf
-# application/vnd.wap.sic
-# application/vnd.wap.slc
-application/vnd.wap.wbxml wbxml
-application/vnd.wap.wmlc wmlc
-application/vnd.wap.wmlscriptc wmlsc
-application/vnd.webturbo wtb
-# application/vnd.wfa.wsc
-# application/vnd.wmc
-# application/vnd.wmf.bootstrap
-# application/vnd.wolfram.mathematica
-# application/vnd.wolfram.mathematica.package
-application/vnd.wolfram.player nbp
-application/vnd.wordperfect wpd
-application/vnd.wqd wqd
-# application/vnd.wrq-hp3000-labelled
-application/vnd.wt.stf stf
-# application/vnd.wv.csp+wbxml
-# application/vnd.wv.csp+xml
-# application/vnd.wv.ssp+xml
-application/vnd.xara xar
-application/vnd.xfdl xfdl
-# application/vnd.xfdl.webform
-# application/vnd.xmi+xml
-# application/vnd.xmpie.cpkg
-# application/vnd.xmpie.dpkg
-# application/vnd.xmpie.plan
-# application/vnd.xmpie.ppkg
-# application/vnd.xmpie.xlim
-application/vnd.yamaha.hv-dic hvd
-application/vnd.yamaha.hv-script hvs
-application/vnd.yamaha.hv-voice hvp
-application/vnd.yamaha.openscoreformat osf
-application/vnd.yamaha.openscoreformat.osfpvg+xml osfpvg
-# application/vnd.yamaha.remote-setup
-application/vnd.yamaha.smaf-audio saf
-application/vnd.yamaha.smaf-phrase spf
-# application/vnd.yamaha.through-ngn
-# application/vnd.yamaha.tunnel-udpencap
-application/vnd.yellowriver-custom-menu cmp
-application/vnd.zul zir zirz
-application/vnd.zzazz.deck+xml zaz
-application/voicexml+xml vxml
-# application/vq-rtcpxr
-# application/watcherinfo+xml
-# application/whoispp-query
-# application/whoispp-response
-application/widget wgt
-application/winhlp hlp
-# application/wita
-# application/wordperfect5.1
-application/wsdl+xml wsdl
-application/wspolicy+xml wspolicy
-application/x-7z-compressed 7z
-application/x-abiword abw
-application/x-ace-compressed ace
-# application/x-amf
-application/x-apple-diskimage dmg
-application/x-authorware-bin aab x32 u32 vox
-application/x-authorware-map aam
-application/x-authorware-seg aas
-application/x-bcpio bcpio
-application/x-bittorrent torrent
-application/x-blorb blb blorb
-application/x-bzip bz
-application/x-bzip2 bz2 boz
-application/x-cbr cbr cba cbt cbz cb7
-application/x-cdlink vcd
-application/x-cfs-compressed cfs
-application/x-chat chat
-application/x-chess-pgn pgn
-application/x-conference nsc
-# application/x-compress
-application/x-cpio cpio
-application/x-csh csh
-application/x-debian-package deb udeb
-application/x-dgc-compressed dgc
-application/x-director dir dcr dxr cst cct cxt w3d fgd swa
-application/x-doom wad
-application/x-dtbncx+xml ncx
-application/x-dtbook+xml dtb
-application/x-dtbresource+xml res
-application/x-dvi dvi
-application/x-envoy evy
-application/x-eva eva
-application/x-font-bdf bdf
-# application/x-font-dos
-# application/x-font-framemaker
-application/x-font-ghostscript gsf
-# application/x-font-libgrx
-application/x-font-linux-psf psf
-application/x-font-otf otf
-application/x-font-pcf pcf
-application/x-font-snf snf
-# application/x-font-speedo
-# application/x-font-sunos-news
-application/x-font-ttf ttf ttc
-application/x-font-type1 pfa pfb pfm afm
-application/font-woff woff
-# application/x-font-vfont
-application/x-freearc arc
-application/x-futuresplash spl
-application/x-gca-compressed gca
-application/x-glulx ulx
-application/x-gnumeric gnumeric
-application/x-gramps-xml gramps
-application/x-gtar gtar
-# application/x-gzip
-application/x-hdf hdf
-application/x-install-instructions install
-application/x-iso9660-image iso
-application/x-java-jnlp-file jnlp
-application/x-latex latex
-application/x-lzh-compressed lzh lha
-application/x-mie mie
-application/x-mobipocket-ebook prc mobi
-application/x-ms-application application
-application/x-ms-shortcut lnk
-application/x-ms-wmd wmd
-application/x-ms-wmz wmz
-application/x-ms-xbap xbap
-application/x-msaccess mdb
-application/x-msbinder obd
-application/x-mscardfile crd
-application/x-msclip clp
-application/x-msdownload exe dll com bat msi
-application/x-msmediaview mvb m13 m14
-application/x-msmetafile wmf wmz emf emz
-application/x-msmoney mny
-application/x-mspublisher pub
-application/x-msschedule scd
-application/x-msterminal trm
-application/x-mswrite wri
-application/x-netcdf nc cdf
-application/x-nzb nzb
-application/x-pkcs12 p12 pfx
-application/x-pkcs7-certificates p7b spc
-application/x-pkcs7-certreqresp p7r
-application/x-rar-compressed rar
-application/x-research-info-systems ris
-application/x-sh sh
-application/x-shar shar
-application/x-shockwave-flash swf
-application/x-silverlight-app xap
-application/x-sql sql
-application/x-stuffit sit
-application/x-stuffitx sitx
-application/x-subrip srt
-application/x-sv4cpio sv4cpio
-application/x-sv4crc sv4crc
-application/x-t3vm-image t3
-application/x-tads gam
-application/x-tar tar
-application/x-tcl tcl
-application/x-tex tex
-application/x-tex-tfm tfm
-application/x-texinfo texinfo texi
-application/x-tgif obj
-application/x-ustar ustar
-application/x-wais-source src
-application/x-x509-ca-cert der crt
-application/x-xfig fig
-application/x-xliff+xml xlf
-application/x-xpinstall xpi
-application/x-xz xz
-application/x-zmachine z1 z2 z3 z4 z5 z6 z7 z8
-# application/x400-bp
-application/xaml+xml xaml
-# application/xcap-att+xml
-# application/xcap-caps+xml
-application/xcap-diff+xml xdf
-# application/xcap-el+xml
-# application/xcap-error+xml
-# application/xcap-ns+xml
-# application/xcon-conference-info-diff+xml
-# application/xcon-conference-info+xml
-application/xenc+xml xenc
-application/xhtml+xml xhtml xht
-# application/xhtml-voice+xml
-application/xml xml xsl
-application/xml-dtd dtd
-# application/xml-external-parsed-entity
-# application/xmpp+xml
-application/xop+xml xop
-application/xproc+xml xpl
-application/xslt+xml xslt
-application/xspf+xml xspf
-application/xv+xml mxml xhvml xvml xvm
-application/yang yang
-application/yin+xml yin
-application/zip zip
-# audio/1d-interleaved-parityfec
-# audio/32kadpcm
-# audio/3gpp
-# audio/3gpp2
-# audio/ac3
-audio/adpcm adp
-# audio/amr
-# audio/amr-wb
-# audio/amr-wb+
-# audio/asc
-# audio/atrac-advanced-lossless
-# audio/atrac-x
-# audio/atrac3
-audio/basic au snd
-# audio/bv16
-# audio/bv32
-# audio/clearmode
-# audio/cn
-# audio/dat12
-# audio/dls
-# audio/dsr-es201108
-# audio/dsr-es202050
-# audio/dsr-es202211
-# audio/dsr-es202212
-# audio/dv
-# audio/dvi4
-# audio/eac3
-# audio/evrc
-# audio/evrc-qcp
-# audio/evrc0
-# audio/evrc1
-# audio/evrcb
-# audio/evrcb0
-# audio/evrcb1
-# audio/evrcwb
-# audio/evrcwb0
-# audio/evrcwb1
-# audio/example
-# audio/fwdred
-# audio/g719
-# audio/g722
-# audio/g7221
-# audio/g723
-# audio/g726-16
-# audio/g726-24
-# audio/g726-32
-# audio/g726-40
-# audio/g728
-# audio/g729
-# audio/g7291
-# audio/g729d
-# audio/g729e
-# audio/gsm
-# audio/gsm-efr
-# audio/gsm-hr-08
-# audio/ilbc
-# audio/ip-mr_v2.5
-# audio/isac
-# audio/l16
-# audio/l20
-# audio/l24
-# audio/l8
-# audio/lpc
-audio/midi mid midi kar rmi
-# audio/mobile-xmf
-audio/mp4 mp4a
-# audio/mp4a-latm
-# audio/mpa
-# audio/mpa-robust
-audio/mpeg mpga mp2 mp2a mp3 m2a m3a
-# audio/mpeg4-generic
-# audio/musepack
-audio/ogg oga ogg spx
-# audio/opus
-# audio/parityfec
-# audio/pcma
-# audio/pcma-wb
-# audio/pcmu-wb
-# audio/pcmu
-# audio/prs.sid
-# audio/qcelp
-# audio/red
-# audio/rtp-enc-aescm128
-# audio/rtp-midi
-# audio/rtx
-audio/s3m s3m
-audio/silk sil
-# audio/smv
-# audio/smv0
-# audio/smv-qcp
-# audio/sp-midi
-# audio/speex
-# audio/t140c
-# audio/t38
-# audio/telephone-event
-# audio/tone
-# audio/uemclip
-# audio/ulpfec
-# audio/vdvi
-# audio/vmr-wb
-# audio/vnd.3gpp.iufp
-# audio/vnd.4sb
-# audio/vnd.audiokoz
-# audio/vnd.celp
-# audio/vnd.cisco.nse
-# audio/vnd.cmles.radio-events
-# audio/vnd.cns.anp1
-# audio/vnd.cns.inf1
-audio/vnd.dece.audio uva uvva
-audio/vnd.digital-winds eol
-# audio/vnd.dlna.adts
-# audio/vnd.dolby.heaac.1
-# audio/vnd.dolby.heaac.2
-# audio/vnd.dolby.mlp
-# audio/vnd.dolby.mps
-# audio/vnd.dolby.pl2
-# audio/vnd.dolby.pl2x
-# audio/vnd.dolby.pl2z
-# audio/vnd.dolby.pulse.1
-audio/vnd.dra dra
-audio/vnd.dts dts
-audio/vnd.dts.hd dtshd
-# audio/vnd.dvb.file
-# audio/vnd.everad.plj
-# audio/vnd.hns.audio
-audio/vnd.lucent.voice lvp
-audio/vnd.ms-playready.media.pya pya
-# audio/vnd.nokia.mobile-xmf
-# audio/vnd.nortel.vbk
-audio/vnd.nuera.ecelp4800 ecelp4800
-audio/vnd.nuera.ecelp7470 ecelp7470
-audio/vnd.nuera.ecelp9600 ecelp9600
-# audio/vnd.octel.sbc
-# audio/vnd.qcelp
-# audio/vnd.rhetorex.32kadpcm
-audio/vnd.rip rip
-# audio/vnd.sealedmedia.softseal.mpeg
-# audio/vnd.vmx.cvsd
-# audio/vorbis
-# audio/vorbis-config
-audio/webm weba
-audio/x-aac aac
-audio/x-aiff aif aiff aifc
-audio/x-caf caf
-audio/x-flac flac
-audio/x-matroska mka
-audio/x-mpegurl m3u
-audio/x-ms-wax wax
-audio/x-ms-wma wma
-audio/x-pn-realaudio ram ra
-audio/x-pn-realaudio-plugin rmp
-# audio/x-tta
-audio/x-wav wav
-audio/xm xm
-chemical/x-cdx cdx
-chemical/x-cif cif
-chemical/x-cmdf cmdf
-chemical/x-cml cml
-chemical/x-csml csml
-# chemical/x-pdb
-chemical/x-xyz xyz
-image/bmp bmp
-image/cgm cgm
-# image/example
-# image/fits
-image/g3fax g3
-image/gif gif
-image/ief ief
-# image/jp2
-image/jpeg jpeg jpg jpe
-# image/jpm
-# image/jpx
-image/ktx ktx
-# image/naplps
-image/png png
-image/prs.btif btif
-# image/prs.pti
-image/sgi sgi
-image/svg+xml svg svgz
-# image/t38
-image/tiff tiff tif
-# image/tiff-fx
-image/vnd.adobe.photoshop psd
-# image/vnd.cns.inf2
-image/vnd.dece.graphic uvi uvvi uvg uvvg
-image/vnd.dvb.subtitle sub
-image/vnd.djvu djvu djv
-image/vnd.dwg dwg
-image/vnd.dxf dxf
-image/vnd.fastbidsheet fbs
-image/vnd.fpx fpx
-image/vnd.fst fst
-image/vnd.fujixerox.edmics-mmr mmr
-image/vnd.fujixerox.edmics-rlc rlc
-# image/vnd.globalgraphics.pgb
-# image/vnd.microsoft.icon
-# image/vnd.mix
-image/vnd.ms-modi mdi
-image/vnd.ms-photo wdp
-image/vnd.net-fpx npx
-# image/vnd.radiance
-# image/vnd.sealed.png
-# image/vnd.sealedmedia.softseal.gif
-# image/vnd.sealedmedia.softseal.jpg
-# image/vnd.svf
-image/vnd.wap.wbmp wbmp
-image/vnd.xiff xif
-image/webp webp
-image/x-3ds 3ds
-image/x-cmu-raster ras
-image/x-cmx cmx
-image/x-freehand fh fhc fh4 fh5 fh7
-image/x-icon ico
-image/x-mrsid-image sid
-image/x-pcx pcx
-image/x-pict pic pct
-image/x-portable-anymap pnm
-image/x-portable-bitmap pbm
-image/x-portable-graymap pgm
-image/x-portable-pixmap ppm
-image/x-rgb rgb
-image/x-tga tga
-image/x-xbitmap xbm
-image/x-xpixmap xpm
-image/x-xwindowdump xwd
-# message/cpim
-# message/delivery-status
-# message/disposition-notification
-# message/example
-# message/external-body
-# message/feedback-report
-# message/global
-# message/global-delivery-status
-# message/global-disposition-notification
-# message/global-headers
-# message/http
-# message/imdn+xml
-# message/news
-# message/partial
-message/rfc822 eml mime
-# message/s-http
-# message/sip
-# message/sipfrag
-# message/tracking-status
-# message/vnd.si.simp
-# model/example
-model/iges igs iges
-model/mesh msh mesh silo
-model/vnd.collada+xml dae
-model/vnd.dwf dwf
-# model/vnd.flatland.3dml
-model/vnd.gdl gdl
-# model/vnd.gs-gdl
-# model/vnd.gs.gdl
-model/vnd.gtw gtw
-# model/vnd.moml+xml
-model/vnd.mts mts
-# model/vnd.parasolid.transmit.binary
-# model/vnd.parasolid.transmit.text
-model/vnd.vtu vtu
-model/vrml wrl vrml
-model/x3d+binary x3db x3dbz
-model/x3d+vrml x3dv x3dvz
-model/x3d+xml x3d x3dz
-# multipart/alternative
-# multipart/appledouble
-# multipart/byteranges
-# multipart/digest
-# multipart/encrypted
-# multipart/example
-# multipart/form-data
-# multipart/header-set
-# multipart/mixed
-# multipart/parallel
-# multipart/related
-# multipart/report
-# multipart/signed
-# multipart/voice-message
-# text/1d-interleaved-parityfec
-text/cache-manifest appcache
-text/calendar ics ifb
-text/css css
-text/csv csv
-# text/directory
-# text/dns
-# text/ecmascript
-# text/enriched
-# text/example
-# text/fwdred
-text/html html htm
-# text/javascript
-text/n3 n3
-# text/parityfec
-text/plain txt text conf def list log in
-# text/prs.fallenstein.rst
-text/prs.lines.tag dsc
-# text/vnd.radisys.msml-basic-layout
-# text/red
-# text/rfc822-headers
-text/richtext rtx
-# text/rtf
-# text/rtp-enc-aescm128
-# text/rtx
-text/sgml sgml sgm
-# text/t140
-text/tab-separated-values tsv
-text/troff t tr roff man me ms
-text/turtle ttl
-# text/ulpfec
-text/uri-list uri uris urls
-text/vcard vcard
-# text/vnd.abc
-text/vnd.curl curl
-text/vnd.curl.dcurl dcurl
-text/vnd.curl.scurl scurl
-text/vnd.curl.mcurl mcurl
-# text/vnd.dmclientscript
-text/vnd.dvb.subtitle sub
-# text/vnd.esmertec.theme-descriptor
-text/vnd.fly fly
-text/vnd.fmi.flexstor flx
-text/vnd.graphviz gv
-text/vnd.in3d.3dml 3dml
-text/vnd.in3d.spot spot
-# text/vnd.iptc.newsml
-# text/vnd.iptc.nitf
-# text/vnd.latex-z
-# text/vnd.motorola.reflex
-# text/vnd.ms-mediapackage
-# text/vnd.net2phone.commcenter.command
-# text/vnd.si.uricatalogue
-text/vnd.sun.j2me.app-descriptor jad
-# text/vnd.trolltech.linguist
-# text/vnd.wap.si
-# text/vnd.wap.sl
-text/vnd.wap.wml wml
-text/vnd.wap.wmlscript wmls
-text/x-asm s asm
-text/x-c c cc cxx cpp h hh dic
-text/x-fortran f for f77 f90
-text/x-java-source java
-text/x-opml opml
-text/x-pascal p pas
-text/x-nfo nfo
-text/x-setext etx
-text/x-sfv sfv
-text/x-uuencode uu
-text/x-vcalendar vcs
-text/x-vcard vcf
-# text/xml
-# text/xml-external-parsed-entity
-# video/1d-interleaved-parityfec
-video/3gpp 3gp
-# video/3gpp-tt
-video/3gpp2 3g2
-# video/bmpeg
-# video/bt656
-# video/celb
-# video/dv
-# video/example
-video/h261 h261
-video/h263 h263
-# video/h263-1998
-# video/h263-2000
-video/h264 h264
-# video/h264-rcdo
-# video/h264-svc
-video/jpeg jpgv
-# video/jpeg2000
-video/jpm jpm jpgm
-video/mj2 mj2 mjp2
-# video/mp1s
-# video/mp2p
-# video/mp2t
-video/mp4 mp4 mp4v mpg4
-# video/mp4v-es
-video/mpeg mpeg mpg mpe m1v m2v
-# video/mpeg4-generic
-# video/mpv
-# video/nv
-video/ogg ogv
-# video/parityfec
-# video/pointer
-video/quicktime qt mov
-# video/raw
-# video/rtp-enc-aescm128
-# video/rtx
-# video/smpte292m
-# video/ulpfec
-# video/vc1
-# video/vnd.cctv
-video/vnd.dece.hd uvh uvvh
-video/vnd.dece.mobile uvm uvvm
-# video/vnd.dece.mp4
-video/vnd.dece.pd uvp uvvp
-video/vnd.dece.sd uvs uvvs
-video/vnd.dece.video uvv uvvv
-# video/vnd.directv.mpeg
-# video/vnd.directv.mpeg-tts
-# video/vnd.dlna.mpeg-tts
-video/vnd.dvb.file dvb
-video/vnd.fvt fvt
-# video/vnd.hns.video
-# video/vnd.iptvforum.1dparityfec-1010
-# video/vnd.iptvforum.1dparityfec-2005
-# video/vnd.iptvforum.2dparityfec-1010
-# video/vnd.iptvforum.2dparityfec-2005
-# video/vnd.iptvforum.ttsavc
-# video/vnd.iptvforum.ttsmpeg2
-# video/vnd.motorola.video
-# video/vnd.motorola.videop
-video/vnd.mpegurl mxu m4u
-video/vnd.ms-playready.media.pyv pyv
-# video/vnd.nokia.interleaved-multimedia
-# video/vnd.nokia.videovoip
-# video/vnd.objectvideo
-# video/vnd.sealed.mpeg1
-# video/vnd.sealed.mpeg4
-# video/vnd.sealed.swf
-# video/vnd.sealedmedia.softseal.mov
-video/vnd.uvvu.mp4 uvu uvvu
-video/vnd.vivo viv
-video/webm webm
-video/x-f4v f4v
-video/x-fli fli
-video/x-flv flv
-video/x-m4v m4v
-video/x-matroska mkv mk3d mks
-video/x-mng mng
-video/x-ms-asf asf asx
-video/x-ms-vob vob
-video/x-ms-wm wm
-video/x-ms-wmv wmv
-video/x-ms-wmx wmx
-video/x-ms-wvx wvx
-video/x-msvideo avi
-video/x-sgi-movie movie
-video/x-smv smv
-x-conference/x-cooltalk ice
diff --git a/CoAuthoring/node_modules/express/node_modules/send/node_modules/mime/types/node.types b/CoAuthoring/node_modules/express/node_modules/send/node_modules/mime/types/node.types
deleted file mode 100644
index 55b2cf794e..0000000000
--- a/CoAuthoring/node_modules/express/node_modules/send/node_modules/mime/types/node.types
+++ /dev/null
@@ -1,77 +0,0 @@
-# What: WebVTT
-# Why: To allow formats intended for marking up external text track resources.
-# http://dev.w3.org/html5/webvtt/
-# Added by: niftylettuce
-text/vtt vtt
-
-# What: Google Chrome Extension
-# Why: To allow apps to (work) be served with the right content type header.
-# http://codereview.chromium.org/2830017
-# Added by: niftylettuce
-application/x-chrome-extension crx
-
-# What: HTC support
-# Why: To properly render .htc files such as CSS3PIE
-# Added by: niftylettuce
-text/x-component htc
-
-# What: HTML5 application cache manifes ('.manifest' extension)
-# Why: De-facto standard. Required by Mozilla browser when serving HTML5 apps
-# per https://developer.mozilla.org/en/offline_resources_in_firefox
-# Added by: louisremi
-text/cache-manifest manifest
-
-# What: node binary buffer format
-# Why: semi-standard extension w/in the node community
-# Added by: tootallnate
-application/octet-stream buffer
-
-# What: The "protected" MP-4 formats used by iTunes.
-# Why: Required for streaming music to browsers (?)
-# Added by: broofa
-application/mp4 m4p
-audio/mp4 m4a
-
-# What: Video format, Part of RFC1890
-# Why: See https://github.com/bentomas/node-mime/pull/6
-# Added by: mjrusso
-video/MP2T ts
-
-# What: EventSource mime type
-# Why: mime type of Server-Sent Events stream
-# http://www.w3.org/TR/eventsource/#text-event-stream
-# Added by: francois2metz
-text/event-stream event-stream
-
-# What: Mozilla App manifest mime type
-# Why: https://developer.mozilla.org/en/Apps/Manifest#Serving_manifests
-# Added by: ednapiranha
-application/x-web-app-manifest+json webapp
-
-# What: Lua file types
-# Why: Googling around shows de-facto consensus on these
-# Added by: creationix (Issue #45)
-text/x-lua lua
-application/x-lua-bytecode luac
-
-# What: Markdown files, as per http://daringfireball.net/projects/markdown/syntax
-# Why: http://stackoverflow.com/questions/10701983/what-is-the-mime-type-for-markdown
-# Added by: avoidwork
-text/x-markdown markdown md mkd
-
-# What: ini files
-# Why: because they're just text files
-# Added by: Matthew Kastor
-text/plain ini
-
-# What: DASH Adaptive Streaming manifest
-# Why: https://developer.mozilla.org/en-US/docs/DASH_Adaptive_Streaming_for_HTML_5_Video
-# Added by: eelcocramer
-application/dash+xml mdp
-
-# What: OpenType font files - http://www.microsoft.com/typography/otspec/
-# Why: Browsers usually ignore the font MIME types and sniff the content,
-# but Chrome, shows a warning if OpenType fonts aren't served with
-# the `font/opentype` MIME type: http://i.imgur.com/8c5RN8M.png.
-# Added by: alrra
-font/opentype otf
diff --git a/CoAuthoring/node_modules/express/node_modules/send/node_modules/ms/.npmignore b/CoAuthoring/node_modules/express/node_modules/send/node_modules/ms/.npmignore
deleted file mode 100644
index d1aa0ce42e..0000000000
--- a/CoAuthoring/node_modules/express/node_modules/send/node_modules/ms/.npmignore
+++ /dev/null
@@ -1,5 +0,0 @@
-node_modules
-test
-History.md
-Makefile
-component.json
diff --git a/CoAuthoring/node_modules/express/node_modules/send/node_modules/ms/README.md b/CoAuthoring/node_modules/express/node_modules/send/node_modules/ms/README.md
deleted file mode 100644
index d4ab12a730..0000000000
--- a/CoAuthoring/node_modules/express/node_modules/send/node_modules/ms/README.md
+++ /dev/null
@@ -1,33 +0,0 @@
-# ms.js: miliseconds conversion utility
-
-```js
-ms('1d') // 86400000
-ms('10h') // 36000000
-ms('2h') // 7200000
-ms('1m') // 60000
-ms('5s') // 5000
-ms('100') // 100
-```
-
-```js
-ms(60000) // "1m"
-ms(2 * 60000) // "2m"
-ms(ms('10 hours')) // "10h"
-```
-
-```js
-ms(60000, { long: true }) // "1 minute"
-ms(2 * 60000, { long: true }) // "2 minutes"
-ms(ms('10 hours', { long: true })) // "10 hours"
-```
-
-- Node/Browser compatible. Published as `ms` in NPM.
-- If a number is supplied to `ms`, a string with a unit is returned.
-- If a string that contains the number is supplied, it returns it as
-a number (e.g: it returns `100` for `'100'`).
-- If you pass a string with a number and a valid unit, the number of
-equivalent ms is returned.
-
-## License
-
-MIT
\ No newline at end of file
diff --git a/CoAuthoring/node_modules/express/node_modules/send/node_modules/ms/index.js b/CoAuthoring/node_modules/express/node_modules/send/node_modules/ms/index.js
deleted file mode 100644
index c5847f8dd2..0000000000
--- a/CoAuthoring/node_modules/express/node_modules/send/node_modules/ms/index.js
+++ /dev/null
@@ -1,111 +0,0 @@
-/**
- * Helpers.
- */
-
-var s = 1000;
-var m = s * 60;
-var h = m * 60;
-var d = h * 24;
-var y = d * 365.25;
-
-/**
- * Parse or format the given `val`.
- *
- * Options:
- *
- * - `long` verbose formatting [false]
- *
- * @param {String|Number} val
- * @param {Object} options
- * @return {String|Number}
- * @api public
- */
-
-module.exports = function(val, options){
- options = options || {};
- if ('string' == typeof val) return parse(val);
- return options.long
- ? long(val)
- : short(val);
-};
-
-/**
- * Parse the given `str` and return milliseconds.
- *
- * @param {String} str
- * @return {Number}
- * @api private
- */
-
-function parse(str) {
- var match = /^((?:\d+)?\.?\d+) *(ms|seconds?|s|minutes?|m|hours?|h|days?|d|years?|y)?$/i.exec(str);
- if (!match) return;
- var n = parseFloat(match[1]);
- var type = (match[2] || 'ms').toLowerCase();
- switch (type) {
- case 'years':
- case 'year':
- case 'y':
- return n * y;
- case 'days':
- case 'day':
- case 'd':
- return n * d;
- case 'hours':
- case 'hour':
- case 'h':
- return n * h;
- case 'minutes':
- case 'minute':
- case 'm':
- return n * m;
- case 'seconds':
- case 'second':
- case 's':
- return n * s;
- case 'ms':
- return n;
- }
-}
-
-/**
- * Short format for `ms`.
- *
- * @param {Number} ms
- * @return {String}
- * @api private
- */
-
-function short(ms) {
- if (ms >= d) return Math.round(ms / d) + 'd';
- if (ms >= h) return Math.round(ms / h) + 'h';
- if (ms >= m) return Math.round(ms / m) + 'm';
- if (ms >= s) return Math.round(ms / s) + 's';
- return ms + 'ms';
-}
-
-/**
- * Long format for `ms`.
- *
- * @param {Number} ms
- * @return {String}
- * @api private
- */
-
-function long(ms) {
- return plural(ms, d, 'day')
- || plural(ms, h, 'hour')
- || plural(ms, m, 'minute')
- || plural(ms, s, 'second')
- || ms + ' ms';
-}
-
-/**
- * Pluralization helper.
- */
-
-function plural(ms, n, name) {
- if (ms < n) return;
- if (ms < n * 1.5) return Math.floor(ms / n) + ' ' + name;
- return Math.ceil(ms / n) + ' ' + name + 's';
-}
diff --git a/CoAuthoring/node_modules/express/node_modules/send/node_modules/ms/package.json b/CoAuthoring/node_modules/express/node_modules/send/node_modules/ms/package.json
deleted file mode 100644
index 6ea0544b95..0000000000
--- a/CoAuthoring/node_modules/express/node_modules/send/node_modules/ms/package.json
+++ /dev/null
@@ -1,29 +0,0 @@
-{
- "name": "ms",
- "version": "0.6.2",
- "description": "Tiny ms conversion utility",
- "repository": {
- "type": "git",
- "url": "git://github.com/guille/ms.js.git"
- },
- "main": "./index",
- "devDependencies": {
- "mocha": "*",
- "expect.js": "*",
- "serve": "*"
- },
- "component": {
- "scripts": {
- "ms/index.js": "index.js"
- }
- },
- "readme": "# ms.js: miliseconds conversion utility\n\n```js\nms('1d') // 86400000\nms('10h') // 36000000\nms('2h') // 7200000\nms('1m') // 60000\nms('5s') // 5000\nms('100') // 100\n```\n\n```js\nms(60000) // \"1m\"\nms(2 * 60000) // \"2m\"\nms(ms('10 hours')) // \"10h\"\n```\n\n```js\nms(60000, { long: true }) // \"1 minute\"\nms(2 * 60000, { long: true }) // \"2 minutes\"\nms(ms('10 hours', { long: true })) // \"10 hours\"\n```\n\n- Node/Browser compatible. Published as `ms` in NPM.\n- If a number is supplied to `ms`, a string with a unit is returned.\n- If a string that contains the number is supplied, it returns it as\na number (e.g: it returns `100` for `'100'`).\n- If you pass a string with a number and a valid unit, the number of\nequivalent ms is returned.\n\n## License\n\nMIT",
- "readmeFilename": "README.md",
- "bugs": {
- "url": "https://github.com/guille/ms.js/issues"
- },
- "homepage": "https://github.com/guille/ms.js",
- "_id": "ms@0.6.2",
- "_from": "ms@0.6.2",
- "scripts": {}
-}
diff --git a/CoAuthoring/node_modules/express/node_modules/send/node_modules/on-finished/HISTORY.md b/CoAuthoring/node_modules/express/node_modules/send/node_modules/on-finished/HISTORY.md
deleted file mode 100644
index 0aa241b194..0000000000
--- a/CoAuthoring/node_modules/express/node_modules/send/node_modules/on-finished/HISTORY.md
+++ /dev/null
@@ -1,66 +0,0 @@
-2.1.0 / 2014-08-16
-==================
-
- * Check if `socket` is detached
- * Return `undefined` for `isFinished` if state unknown
-
-2.0.0 / 2014-08-16
-==================
-
- * Add `isFinished` function
- * Move to `jshttp` organization
- * Remove support for plain socket argument
- * Rename to `on-finished`
- * Support both `req` and `res` as arguments
- * deps: ee-first@1.0.5
-
-1.2.2 / 2014-06-10
-==================
-
- * Reduce listeners added to emitters
- - avoids "event emitter leak" warnings when used multiple times on same request
-
-1.2.1 / 2014-06-08
-==================
-
- * Fix returned value when already finished
-
-1.2.0 / 2014-06-05
-==================
-
- * Call callback when called on already-finished socket
-
-1.1.4 / 2014-05-27
-==================
-
- * Support node.js 0.8
-
-1.1.3 / 2014-04-30
-==================
-
- * Make sure errors passed as instanceof `Error`
-
-1.1.2 / 2014-04-18
-==================
-
- * Default the `socket` to passed-in object
-
-1.1.1 / 2014-01-16
-==================
-
- * Rename module to `finished`
-
-1.1.0 / 2013-12-25
-==================
-
- * Call callback when called on already-errored socket
-
-1.0.1 / 2013-12-20
-==================
-
- * Actually pass the error to the callback
-
-1.0.0 / 2013-12-20
-==================
-
- * Initial release
diff --git a/CoAuthoring/node_modules/express/node_modules/send/node_modules/on-finished/LICENSE b/CoAuthoring/node_modules/express/node_modules/send/node_modules/on-finished/LICENSE
deleted file mode 100644
index 5931fd23ea..0000000000
--- a/CoAuthoring/node_modules/express/node_modules/send/node_modules/on-finished/LICENSE
+++ /dev/null
@@ -1,23 +0,0 @@
-(The MIT License)
-
-Copyright (c) 2013 Jonathan Ong
-Copyright (c) 2014 Douglas Christopher Wilson
-
-Permission is hereby granted, free of charge, to any person obtaining
-a copy of this software and associated documentation files (the
-'Software'), to deal in the Software without restriction, including
-without limitation the rights to use, copy, modify, merge, publish,
-distribute, sublicense, and/or sell copies of the Software, and to
-permit persons to whom the Software is furnished to do so, subject to
-the following conditions:
-
-The above copyright notice and this permission notice shall be
-included in all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
-EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
-IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
-CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
-TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
-SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
diff --git a/CoAuthoring/node_modules/express/node_modules/send/node_modules/on-finished/README.md b/CoAuthoring/node_modules/express/node_modules/send/node_modules/on-finished/README.md
deleted file mode 100644
index 887b5c3890..0000000000
--- a/CoAuthoring/node_modules/express/node_modules/send/node_modules/on-finished/README.md
+++ /dev/null
@@ -1,90 +0,0 @@
-# on-finished
-
-[](https://www.npmjs.org/package/on-finished)
-[](http://nodejs.org/download/)
-[](https://travis-ci.org/jshttp/on-finished)
-[](https://coveralls.io/r/jshttp/on-finished)
-
-Execute a callback when a request closes, finishes, or errors.
-
-## Install
-
-```sh
-$ npm install on-finished
-```
-
-## API
-
-```js
-var onFinished = require('on-finished')
-```
-
-### onFinished(res, listener)
-
-Attach a listener to listen for the response to finish. The listener will
-be invoked only once when the response finished. If the response finished
-to to an error, the first argument will contain the error.
-
-Listening to the end of a response would be used to close things associated
-with the response, like open files.
-
-```js
-onFinished(res, function (err) {
- // clean up open fds, etc.
-})
-```
-
-### onFinished(req, listener)
-
-Attach a listener to listen for the request to finish. The listener will
-be invoked only once when the request finished. If the request finished
-to to an error, the first argument will contain the error.
-
-Listening to the end of a request would be used to know when to continue
-after reading the data.
-
-```js
-var data = ''
-
-req.setEncoding('utf8')
-res.on('data', function (str) {
- data += str
-})
-
-onFinished(req, function (err) {
- // data is read unless there is err
-})
-```
-
-### onFinished.isFinished(res)
-
-Determine if `res` is already finished. This would be useful to check and
-not even start certain operations if the response has already finished.
-
-### onFinished.isFinished(req)
-
-Determine if `req` is already finished. This would be useful to check and
-not even start certain operations if the request has already finished.
-
-### Example
-
-The following code ensures that file descriptors are always closed
-once the response finishes.
-
-```js
-var destroy = require('destroy')
-var http = require('http')
-var onFinished = require('finished')
-
-http.createServer(function onRequest(req, res) {
- var stream = fs.createReadStream('package.json')
- stream.pipe(res)
- onFinished(res, function (err) {
- destroy(stream)
- })
-})
-```
-
-## License
-
-[MIT](LICENSE)
diff --git a/CoAuthoring/node_modules/express/node_modules/send/node_modules/on-finished/index.js b/CoAuthoring/node_modules/express/node_modules/send/node_modules/on-finished/index.js
deleted file mode 100644
index a5055610b7..0000000000
--- a/CoAuthoring/node_modules/express/node_modules/send/node_modules/on-finished/index.js
+++ /dev/null
@@ -1,127 +0,0 @@
-/*!
- * on-finished
- * Copyright(c) 2013 Jonathan Ong
- * Copyright(c) 2014 Douglas Christopher Wilson
- * MIT Licensed
- */
-
-/**
- * Module exports.
- */
-
-module.exports = onFinished;
-module.exports.isFinished = isFinished;
-
-/**
-* Module dependencies.
-*/
-
-var first = require('ee-first')
-
-/**
-* Variables.
-*/
-
-/* istanbul ignore next */
-var defer = typeof setImmediate === 'function'
- ? setImmediate
- : function(fn){ process.nextTick(fn.bind.apply(fn, arguments)) }
-
-/**
- * Invoke callback when the response has finished, useful for
- * cleaning up resources afterwards.
- *
- * @param {object} msg
- * @param {function} listener
- * @return {object}
- * @api public
- */
-
-function onFinished(msg, listener) {
- if (isFinished(msg) !== false) {
- defer(listener)
- return msg
- }
-
- // attach the listener to the message
- attachListener(msg, listener)
-
- return msg
-}
-
-/**
- * Determine is message is already finished.
- *
- * @param {object} msg
- * @return {boolean}
- * @api public
- */
-
-function isFinished(msg) {
- var socket = msg.socket
-
- if (typeof msg.finished === 'boolean') {
- // OutgoingMessage
- return Boolean(!socket || msg.finished || !socket.writable)
- }
-
- if (typeof msg.complete === 'boolean') {
- // IncomingMessage
- return Boolean(!socket || msg.complete || !socket.readable)
- }
-
- // don't know
- return undefined
-}
-
-/**
- * Attach the listener to the message.
- *
- * @param {object} msg
- * @return {function}
- * @api private
- */
-
-function attachListener(msg, listener) {
- var attached = msg.__onFinished
- var socket = msg.socket
-
- // create a private single listener with queue
- if (!attached || !attached.queue) {
- attached = msg.__onFinished = createListener(msg)
-
- // finished on first event
- first([
- [socket, 'error', 'close'],
- [msg, 'end', 'finish'],
- ], attached)
- }
-
- attached.queue.push(listener)
-}
-
-/**
- * Create listener on message.
- *
- * @param {object} msg
- * @return {function}
- * @api private
- */
-
-function createListener(msg) {
- function listener(err) {
- if (msg.__onFinished === listener) msg.__onFinished = null
- if (!listener.queue) return
-
- var queue = listener.queue
- listener.queue = null
-
- for (var i = 0; i < queue.length; i++) {
- queue[i](err)
- }
- }
-
- listener.queue = []
-
- return listener
-}
diff --git a/CoAuthoring/node_modules/express/node_modules/send/node_modules/on-finished/node_modules/ee-first/LICENSE b/CoAuthoring/node_modules/express/node_modules/send/node_modules/on-finished/node_modules/ee-first/LICENSE
deleted file mode 100644
index a7ae8ee9b8..0000000000
--- a/CoAuthoring/node_modules/express/node_modules/send/node_modules/on-finished/node_modules/ee-first/LICENSE
+++ /dev/null
@@ -1,22 +0,0 @@
-
-The MIT License (MIT)
-
-Copyright (c) 2014 Jonathan Ong me@jongleberry.com
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in
-all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-THE SOFTWARE.
diff --git a/CoAuthoring/node_modules/express/node_modules/send/node_modules/on-finished/node_modules/ee-first/README.md b/CoAuthoring/node_modules/express/node_modules/send/node_modules/on-finished/node_modules/ee-first/README.md
deleted file mode 100644
index 0ebc0aa4f4..0000000000
--- a/CoAuthoring/node_modules/express/node_modules/send/node_modules/on-finished/node_modules/ee-first/README.md
+++ /dev/null
@@ -1,63 +0,0 @@
-# EE First
-
-[![NPM version][npm-image]][npm-url]
-[![Build status][travis-image]][travis-url]
-[![Test coverage][coveralls-image]][coveralls-url]
-[![License][license-image]][license-url]
-[![Downloads][downloads-image]][downloads-url]
-[![Gittip][gittip-image]][gittip-url]
-
-Get the first event in a set of event emitters and event pairs,
-then clean up after itself.
-
-## Install
-
-```sh
-$ npm install ee-first
-```
-
-## API
-
-```js
-var first = require('ee-first')
-```
-
-### first(arr, listener)
-
-Invoke `listener` on the first event from the list specified in `arr`. `arr` is
-an array of arrays, with each array in the format `[ee, ...event]`. `listener`
-will be called only once, the first time any of the given events are emitted. If
-`error` is one of the listened events, then if that fires first, the `listener`
-will be given the `err` argument.
-
-The `listener` is invoked as `listener(err, ee, event, args)`, where `err` is the
-first argument emitted from an `error` event, if applicable; `ee` is the event
-emitter that fired; `event` is the string event name that fired; and `args` is an
-array of the arguments that were emitted on the event.
-
-```js
-var ee1 = new EventEmitter()
-var ee2 = new EventEmitter()
-
-first([
- [ee1, 'close', 'end', 'error'],
- [ee2, 'error']
-], function (err, ee, event, args) {
- // listener invoked
-})
-```
-
-[npm-image]: https://img.shields.io/npm/v/ee-first.svg?style=flat-square
-[npm-url]: https://npmjs.org/package/ee-first
-[github-tag]: http://img.shields.io/github/tag/jonathanong/ee-first.svg?style=flat-square
-[github-url]: https://github.com/jonathanong/ee-first/tags
-[travis-image]: https://img.shields.io/travis/jonathanong/ee-first.svg?style=flat-square
-[travis-url]: https://travis-ci.org/jonathanong/ee-first
-[coveralls-image]: https://img.shields.io/coveralls/jonathanong/ee-first.svg?style=flat-square
-[coveralls-url]: https://coveralls.io/r/jonathanong/ee-first?branch=master
-[license-image]: http://img.shields.io/npm/l/ee-first.svg?style=flat-square
-[license-url]: LICENSE.md
-[downloads-image]: http://img.shields.io/npm/dm/ee-first.svg?style=flat-square
-[downloads-url]: https://npmjs.org/package/ee-first
-[gittip-image]: https://img.shields.io/gittip/jonathanong.svg?style=flat-square
-[gittip-url]: https://www.gittip.com/jonathanong/
diff --git a/CoAuthoring/node_modules/express/node_modules/send/node_modules/on-finished/node_modules/ee-first/index.js b/CoAuthoring/node_modules/express/node_modules/send/node_modules/on-finished/node_modules/ee-first/index.js
deleted file mode 100644
index d0c48c9949..0000000000
--- a/CoAuthoring/node_modules/express/node_modules/send/node_modules/on-finished/node_modules/ee-first/index.js
+++ /dev/null
@@ -1,60 +0,0 @@
-
-module.exports = function first(stuff, done) {
- if (!Array.isArray(stuff))
- throw new TypeError('arg must be an array of [ee, events...] arrays')
-
- var cleanups = []
-
- for (var i = 0; i < stuff.length; i++) {
- var arr = stuff[i]
-
- if (!Array.isArray(arr) || arr.length < 2)
- throw new TypeError('each array member must be [ee, events...]')
-
- var ee = arr[0]
-
- for (var j = 1; j < arr.length; j++) {
- var event = arr[j]
- var fn = listener(event, cleanup)
-
- // listen to the event
- ee.on(event, fn)
- // push this listener to the list of cleanups
- cleanups.push({
- ee: ee,
- event: event,
- fn: fn,
- })
- }
- }
-
- return function (fn) {
- done = fn
- }
-
- function cleanup() {
- var x
- for (var i = 0; i < cleanups.length; i++) {
- x = cleanups[i]
- x.ee.removeListener(x.event, x.fn)
- }
- done.apply(null, arguments)
- }
-}
-
-function listener(event, done) {
- return function onevent(arg1) {
- var args = new Array(arguments.length)
- var ee = this
- var err = event === 'error'
- ? arg1
- : null
-
- // copy args to prevent arguments escaping scope
- for (var i = 0; i < args.length; i++) {
- args[i] = arguments[i]
- }
-
- done(err, ee, event, args)
- }
-}
diff --git a/CoAuthoring/node_modules/express/node_modules/send/node_modules/on-finished/node_modules/ee-first/package.json b/CoAuthoring/node_modules/express/node_modules/send/node_modules/on-finished/node_modules/ee-first/package.json
deleted file mode 100644
index 07af0b430f..0000000000
--- a/CoAuthoring/node_modules/express/node_modules/send/node_modules/on-finished/node_modules/ee-first/package.json
+++ /dev/null
@@ -1,42 +0,0 @@
-{
- "name": "ee-first",
- "description": "return the first event in a set of ee/event pairs",
- "version": "1.0.5",
- "author": {
- "name": "Jonathan Ong",
- "email": "me@jongleberry.com",
- "url": "http://jongleberry.com"
- },
- "contributors": [
- {
- "name": "Douglas Christopher Wilson",
- "email": "doug@somethingdoug.com"
- }
- ],
- "license": "MIT",
- "repository": {
- "type": "git",
- "url": "git://github.com/jonathanong/ee-first"
- },
- "devDependencies": {
- "istanbul": "0.3.0",
- "mocha": "1"
- },
- "files": [
- "index.js",
- "LICENSE"
- ],
- "scripts": {
- "test": "mocha --reporter spec --bail --check-leaks test/",
- "test-cov": "istanbul cover node_modules/mocha/bin/_mocha -- --reporter dot --check-leaks test/",
- "test-travis": "istanbul cover node_modules/mocha/bin/_mocha --report lcovonly -- --reporter spec --check-leaks test/"
- },
- "readme": "# EE First\n\n[![NPM version][npm-image]][npm-url]\n[![Build status][travis-image]][travis-url]\n[![Test coverage][coveralls-image]][coveralls-url]\n[![License][license-image]][license-url]\n[![Downloads][downloads-image]][downloads-url]\n[![Gittip][gittip-image]][gittip-url]\n\nGet the first event in a set of event emitters and event pairs,\nthen clean up after itself.\n\n## Install\n\n```sh\n$ npm install ee-first\n```\n\n## API\n\n```js\nvar first = require('ee-first')\n```\n\n### first(arr, listener)\n\nInvoke `listener` on the first event from the list specified in `arr`. `arr` is\nan array of arrays, with each array in the format `[ee, ...event]`. `listener`\nwill be called only once, the first time any of the given events are emitted. If\n`error` is one of the listened events, then if that fires first, the `listener`\nwill be given the `err` argument.\n\nThe `listener` is invoked as `listener(err, ee, event, args)`, where `err` is the\nfirst argument emitted from an `error` event, if applicable; `ee` is the event\nemitter that fired; `event` is the string event name that fired; and `args` is an\narray of the arguments that were emitted on the event.\n\n```js\nvar ee1 = new EventEmitter()\nvar ee2 = new EventEmitter()\n\nfirst([\n [ee1, 'close', 'end', 'error'],\n [ee2, 'error']\n], function (err, ee, event, args) {\n // listener invoked\n})\n```\n\n[npm-image]: https://img.shields.io/npm/v/ee-first.svg?style=flat-square\n[npm-url]: https://npmjs.org/package/ee-first\n[github-tag]: http://img.shields.io/github/tag/jonathanong/ee-first.svg?style=flat-square\n[github-url]: https://github.com/jonathanong/ee-first/tags\n[travis-image]: https://img.shields.io/travis/jonathanong/ee-first.svg?style=flat-square\n[travis-url]: https://travis-ci.org/jonathanong/ee-first\n[coveralls-image]: https://img.shields.io/coveralls/jonathanong/ee-first.svg?style=flat-square\n[coveralls-url]: https://coveralls.io/r/jonathanong/ee-first?branch=master\n[license-image]: http://img.shields.io/npm/l/ee-first.svg?style=flat-square\n[license-url]: LICENSE.md\n[downloads-image]: http://img.shields.io/npm/dm/ee-first.svg?style=flat-square\n[downloads-url]: https://npmjs.org/package/ee-first\n[gittip-image]: https://img.shields.io/gittip/jonathanong.svg?style=flat-square\n[gittip-url]: https://www.gittip.com/jonathanong/\n",
- "readmeFilename": "README.md",
- "bugs": {
- "url": "https://github.com/jonathanong/ee-first/issues"
- },
- "homepage": "https://github.com/jonathanong/ee-first",
- "_id": "ee-first@1.0.5",
- "_from": "ee-first@1.0.5"
-}
diff --git a/CoAuthoring/node_modules/express/node_modules/send/node_modules/on-finished/package.json b/CoAuthoring/node_modules/express/node_modules/send/node_modules/on-finished/package.json
deleted file mode 100644
index c0479a1c51..0000000000
--- a/CoAuthoring/node_modules/express/node_modules/send/node_modules/on-finished/package.json
+++ /dev/null
@@ -1,49 +0,0 @@
-{
- "name": "on-finished",
- "description": "Execute a callback when a request closes, finishes, or errors",
- "version": "2.1.0",
- "contributors": [
- {
- "name": "Douglas Christopher Wilson",
- "email": "doug@somethingdoug.com"
- },
- {
- "name": "Jonathan Ong",
- "email": "me@jongleberry.com",
- "url": "http://jongleberry.com"
- }
- ],
- "license": "MIT",
- "repository": {
- "type": "git",
- "url": "git://github.com/jshttp/on-finished"
- },
- "dependencies": {
- "ee-first": "1.0.5"
- },
- "devDependencies": {
- "istanbul": "0.3.0",
- "mocha": "~1.21.4"
- },
- "engine": {
- "node": ">= 0.8.0"
- },
- "files": [
- "HISTORY.md",
- "LICENSE",
- "index.js"
- ],
- "scripts": {
- "test": "mocha --reporter spec --bail --check-leaks test/",
- "test-cov": "istanbul cover node_modules/mocha/bin/_mocha -- --reporter dot --check-leaks test/",
- "test-travis": "istanbul cover node_modules/mocha/bin/_mocha --report lcovonly -- --reporter spec --check-leaks test/"
- },
- "readme": "# on-finished\n\n[](https://www.npmjs.org/package/on-finished)\n[](http://nodejs.org/download/)\n[](https://travis-ci.org/jshttp/on-finished)\n[](https://coveralls.io/r/jshttp/on-finished)\n\nExecute a callback when a request closes, finishes, or errors.\n\n## Install\n\n```sh\n$ npm install on-finished\n```\n\n## API\n\n```js\nvar onFinished = require('on-finished')\n```\n\n### onFinished(res, listener)\n\nAttach a listener to listen for the response to finish. The listener will\nbe invoked only once when the response finished. If the response finished\nto to an error, the first argument will contain the error.\n\nListening to the end of a response would be used to close things associated\nwith the response, like open files.\n\n```js\nonFinished(res, function (err) {\n // clean up open fds, etc.\n})\n```\n\n### onFinished(req, listener)\n\nAttach a listener to listen for the request to finish. The listener will\nbe invoked only once when the request finished. If the request finished\nto to an error, the first argument will contain the error.\n\nListening to the end of a request would be used to know when to continue\nafter reading the data.\n\n```js\nvar data = ''\n\nreq.setEncoding('utf8')\nres.on('data', function (str) {\n data += str\n})\n\nonFinished(req, function (err) {\n // data is read unless there is err\n})\n```\n\n### onFinished.isFinished(res)\n\nDetermine if `res` is already finished. This would be useful to check and\nnot even start certain operations if the response has already finished.\n\n### onFinished.isFinished(req)\n\nDetermine if `req` is already finished. This would be useful to check and\nnot even start certain operations if the request has already finished.\n\n### Example\n\nThe following code ensures that file descriptors are always closed\nonce the response finishes.\n\n```js\nvar destroy = require('destroy')\nvar http = require('http')\nvar onFinished = require('finished')\n\nhttp.createServer(function onRequest(req, res) {\n var stream = fs.createReadStream('package.json')\n stream.pipe(res)\n onFinished(res, function (err) {\n destroy(stream)\n })\n})\n```\n\n## License\n\n[MIT](LICENSE)\n",
- "readmeFilename": "README.md",
- "bugs": {
- "url": "https://github.com/jshttp/on-finished/issues"
- },
- "homepage": "https://github.com/jshttp/on-finished",
- "_id": "on-finished@2.1.0",
- "_from": "on-finished@2.1.0"
-}
diff --git a/CoAuthoring/node_modules/express/node_modules/send/package.json b/CoAuthoring/node_modules/express/node_modules/send/package.json
deleted file mode 100644
index 5977a03cdd..0000000000
--- a/CoAuthoring/node_modules/express/node_modules/send/package.json
+++ /dev/null
@@ -1,64 +0,0 @@
-{
- "name": "send",
- "description": "Better streaming static file server with Range and conditional-GET support",
- "version": "0.9.3",
- "author": {
- "name": "TJ Holowaychuk",
- "email": "tj@vision-media.ca"
- },
- "contributors": [
- {
- "name": "Douglas Christopher Wilson",
- "email": "doug@somethingdoug.com"
- }
- ],
- "license": "MIT",
- "repository": {
- "type": "git",
- "url": "git://github.com/visionmedia/send"
- },
- "keywords": [
- "static",
- "file",
- "server"
- ],
- "dependencies": {
- "debug": "~2.0.0",
- "depd": "0.4.5",
- "destroy": "1.0.3",
- "escape-html": "1.0.1",
- "etag": "~1.4.0",
- "fresh": "0.2.4",
- "mime": "1.2.11",
- "ms": "0.6.2",
- "on-finished": "2.1.0",
- "range-parser": "~1.0.2"
- },
- "devDependencies": {
- "istanbul": "0.3.2",
- "mocha": "~1.21.0",
- "should": "~4.0.0",
- "supertest": "~0.13.0"
- },
- "files": [
- "History.md",
- "LICENSE",
- "index.js"
- ],
- "engines": {
- "node": ">= 0.8.0"
- },
- "scripts": {
- "test": "mocha --check-leaks --reporter spec --bail",
- "test-cov": "istanbul cover node_modules/mocha/bin/_mocha -- --check-leaks --reporter dot",
- "test-travis": "istanbul cover node_modules/mocha/bin/_mocha --report lcovonly -- --check-leaks --reporter spec"
- },
- "readme": "# send\n\n[![NPM Version][npm-image]][npm-url]\n[![NPM Downloads][downloads-image]][downloads-url]\n[![Build Status][travis-image]][travis-url]\n[![Test Coverage][coveralls-image]][coveralls-url]\n[![Gittip][gittip-image]][gittip-url]\n\n Send is Connect's `static()` extracted for generalized use, a streaming static file\n server supporting partial responses (Ranges), conditional-GET negotiation, high test coverage, and granular events which may be leveraged to take appropriate actions in your application or framework.\n\n## Installation\n\n```bash\n$ npm install send\n```\n\n## API\n\n```js\nvar send = require('send')\n```\n\n### send(req, path, [options])\n\nCreate a new `SendStream` for the given path to send to a `res`. The `req` is\nthe Node.js HTTP request and the `path` is a urlencoded path to send (urlencoded,\nnot the actual file-system path).\n\n#### Options\n\n##### dotfiles\n\n Set how \"dotfiles\" are treated when encountered. A dotfile is a file\n or directory that begins with a dot (\".\"). Note this check is done on\n the path itself without checking if the path actually exists on the\n disk. If `root` is specified, only the dotfiles above the root are\n checked (i.e. the root itself can be within a dotfile when when set\n to \"deny\").\n\n The default value is `'ignore'`.\n\n - `'allow'` No special treatment for dotfiles.\n - `'deny'` Send a 403 for any request for a dotfile.\n - `'ignore'` Pretend like the dotfile does not exist and 404.\n\n##### etag\n\n Enable or disable etag generation, defaults to true.\n\n##### extensions\n\n If a given file doesn't exist, try appending one of the given extensions,\n in the given order. By default, this is disabled (set to `false`). An\n example value that will serve extension-less HTML files: `['html', 'htm']`.\n This is skipped if the requested file already has an extension.\n\n##### index\n\n By default send supports \"index.html\" files, to disable this\n set `false` or to supply a new index pass a string or an array\n in preferred order.\n\n##### lastModified\n\n Enable or disable `Last-Modified` header, defaults to true. Uses the file\n system's last modified value.\n\n##### maxAge\n\n Provide a max-age in milliseconds for http caching, defaults to 0.\n This can also be a string accepted by the\n [ms](https://www.npmjs.org/package/ms#readme) module.\n\n##### root\n\n Serve files relative to `path`.\n\n### Events\n\nThe `SendStream` is an event emitter and will emit the following events:\n\n - `error` an error occurred `(err)`\n - `directory` a directory was requested\n - `file` a file was requested `(path, stat)`\n - `headers` the headers are about to be set on a file `(res, path, stat)`\n - `stream` file streaming has started `(stream)`\n - `end` streaming has completed\n\n### .pipe\n\nThe `pipe` method is used to pipe the response into the Node.js HTTP response\nobject, typically `send(req, path, options).pipe(res)`.\n\n## Error-handling\n\n By default when no `error` listeners are present an automatic response will be made, otherwise you have full control over the response, aka you may show a 5xx page etc.\n\n## Caching\n\n It does _not_ perform internal caching, you should use a reverse proxy cache such\n as Varnish for this, or those fancy things called CDNs. If your application is small enough that it would benefit from single-node memory caching, it's small enough that it does not need caching at all ;).\n\n## Debugging\n\n To enable `debug()` instrumentation output export __DEBUG__:\n\n```\n$ DEBUG=send node app\n```\n\n## Running tests\n\n```\n$ npm install\n$ npm test\n```\n\n## Examples\n\n Small:\n\n```js\nvar http = require('http');\nvar send = require('send');\n\nvar app = http.createServer(function(req, res){\n send(req, req.url).pipe(res);\n}).listen(3000);\n```\n\n Serving from a root directory with custom error-handling:\n\n```js\nvar http = require('http');\nvar send = require('send');\nvar url = require('url');\n\nvar app = http.createServer(function(req, res){\n // your custom error-handling logic:\n function error(err) {\n res.statusCode = err.status || 500;\n res.end(err.message);\n }\n\n // your custom headers\n function headers(res, path, stat) {\n // serve all files for download\n res.setHeader('Content-Disposition', 'attachment');\n }\n\n // your custom directory handling logic:\n function redirect() {\n res.statusCode = 301;\n res.setHeader('Location', req.url + '/');\n res.end('Redirecting to ' + req.url + '/');\n }\n\n // transfer arbitrary files from within\n // /www/example.com/public/*\n send(req, url.parse(req.url).pathname, {root: '/www/example.com/public'})\n .on('error', error)\n .on('directory', redirect)\n .on('headers', headers)\n .pipe(res);\n}).listen(3000);\n```\n\n## License \n\n[MIT](LICENSE)\n\n[npm-image]: https://img.shields.io/npm/v/send.svg?style=flat\n[npm-url]: https://npmjs.org/package/send\n[travis-image]: https://img.shields.io/travis/visionmedia/send.svg?style=flat\n[travis-url]: https://travis-ci.org/visionmedia/send\n[coveralls-image]: https://img.shields.io/coveralls/visionmedia/send.svg?style=flat\n[coveralls-url]: https://coveralls.io/r/visionmedia/send?branch=master\n[downloads-image]: https://img.shields.io/npm/dm/send.svg?style=flat\n[downloads-url]: https://npmjs.org/package/send\n[gittip-image]: https://img.shields.io/gittip/dougwilson.svg?style=flat\n[gittip-url]: https://www.gittip.com/dougwilson/\n",
- "readmeFilename": "Readme.md",
- "bugs": {
- "url": "https://github.com/visionmedia/send/issues"
- },
- "homepage": "https://github.com/visionmedia/send",
- "_id": "send@0.9.3",
- "_from": "send@0.9.3"
-}
diff --git a/CoAuthoring/node_modules/express/node_modules/serve-static/HISTORY.md b/CoAuthoring/node_modules/express/node_modules/serve-static/HISTORY.md
deleted file mode 100644
index 5435e83d59..0000000000
--- a/CoAuthoring/node_modules/express/node_modules/serve-static/HISTORY.md
+++ /dev/null
@@ -1,187 +0,0 @@
-1.6.4 / 2014-10-08
-==================
-
- * Fix redirect loop when index file serving disabled
-
-1.6.3 / 2014-09-24
-==================
-
- * deps: send@0.9.3
- - deps: etag@~1.4.0
-
-1.6.2 / 2014-09-15
-==================
-
- * deps: send@0.9.2
- - deps: depd@0.4.5
- - deps: etag@~1.3.1
- - deps: range-parser@~1.0.2
-
-1.6.1 / 2014-09-07
-==================
-
- * deps: send@0.9.1
- - deps: fresh@0.2.4
-
-1.6.0 / 2014-09-07
-==================
-
- * deps: send@0.9.0
- - Add `lastModified` option
- - Use `etag` to generate `ETag` header
- - deps: debug@~2.0.0
-
-1.5.4 / 2014-09-04
-==================
-
- * deps: send@0.8.5
- - Fix a path traversal issue when using `root`
- - Fix malicious path detection for empty string path
-
-1.5.3 / 2014-08-17
-==================
-
- * deps: send@0.8.3
-
-1.5.2 / 2014-08-14
-==================
-
- * deps: send@0.8.2
- - Work around `fd` leak in Node.js 0.10 for `fs.ReadStream`
-
-1.5.1 / 2014-08-09
-==================
-
- * Fix parsing of weird `req.originalUrl` values
- * deps: parseurl@~1.3.0
- * deps: utils-merge@1.0.0
-
-1.5.0 / 2014-08-05
-==================
-
- * deps: send@0.8.1
- - Add `extensions` option
-
-1.4.4 / 2014-08-04
-==================
-
- * deps: send@0.7.4
- - Fix serving index files without root dir
-
-1.4.3 / 2014-07-29
-==================
-
- * deps: send@0.7.3
- - Fix incorrect 403 on Windows and Node.js 0.11
-
-1.4.2 / 2014-07-27
-==================
-
- * deps: send@0.7.2
- - deps: depd@0.4.4
-
-1.4.1 / 2014-07-26
-==================
-
- * deps: send@0.7.1
- - deps: depd@0.4.3
-
-1.4.0 / 2014-07-21
-==================
-
- * deps: parseurl@~1.2.0
- - Cache URLs based on original value
- - Remove no-longer-needed URL mis-parse work-around
- - Simplify the "fast-path" `RegExp`
- * deps: send@0.7.0
- - Add `dotfiles` option
- - deps: debug@1.0.4
- - deps: depd@0.4.2
-
-1.3.2 / 2014-07-11
-==================
-
- * deps: send@0.6.0
- - Cap `maxAge` value to 1 year
- - deps: debug@1.0.3
-
-1.3.1 / 2014-07-09
-==================
-
- * deps: parseurl@~1.1.3
- - faster parsing of href-only URLs
-
-1.3.0 / 2014-06-28
-==================
-
- * Add `setHeaders` option
- * Include HTML link in redirect response
- * deps: send@0.5.0
- - Accept string for `maxAge` (converted by `ms`)
-
-1.2.3 / 2014-06-11
-==================
-
- * deps: send@0.4.3
- - Do not throw un-catchable error on file open race condition
- - Use `escape-html` for HTML escaping
- - deps: debug@1.0.2
- - deps: finished@1.2.2
- - deps: fresh@0.2.2
-
-1.2.2 / 2014-06-09
-==================
-
- * deps: send@0.4.2
- - fix "event emitter leak" warnings
- - deps: debug@1.0.1
- - deps: finished@1.2.1
-
-1.2.1 / 2014-06-02
-==================
-
- * use `escape-html` for escaping
- * deps: send@0.4.1
- - Send `max-age` in `Cache-Control` in correct format
-
-1.2.0 / 2014-05-29
-==================
-
- * deps: send@0.4.0
- - Calculate ETag with md5 for reduced collisions
- - Fix wrong behavior when index file matches directory
- - Ignore stream errors after request ends
- - Skip directories in index file search
- - deps: debug@0.8.1
-
-1.1.0 / 2014-04-24
-==================
-
- * Accept options directly to `send` module
- * deps: send@0.3.0
-
-1.0.4 / 2014-04-07
-==================
-
- * Resolve relative paths at middleware setup
- * Use parseurl to parse the URL from request
-
-1.0.3 / 2014-03-20
-==================
-
- * Do not rely on connect-like environments
-
-1.0.2 / 2014-03-06
-==================
-
- * deps: send@0.2.0
-
-1.0.1 / 2014-03-05
-==================
-
- * Add mime export for back-compat
-
-1.0.0 / 2014-03-05
-==================
-
- * Genesis from `connect`
diff --git a/CoAuthoring/node_modules/express/node_modules/serve-static/LICENSE b/CoAuthoring/node_modules/express/node_modules/serve-static/LICENSE
deleted file mode 100644
index b7bc0852e3..0000000000
--- a/CoAuthoring/node_modules/express/node_modules/serve-static/LICENSE
+++ /dev/null
@@ -1,25 +0,0 @@
-(The MIT License)
-
-Copyright (c) 2010 Sencha Inc.
-Copyright (c) 2011 LearnBoost
-Copyright (c) 2011 TJ Holowaychuk
-Copyright (c) 2014 Douglas Christopher Wilson
-
-Permission is hereby granted, free of charge, to any person obtaining
-a copy of this software and associated documentation files (the
-'Software'), to deal in the Software without restriction, including
-without limitation the rights to use, copy, modify, merge, publish,
-distribute, sublicense, and/or sell copies of the Software, and to
-permit persons to whom the Software is furnished to do so, subject to
-the following conditions:
-
-The above copyright notice and this permission notice shall be
-included in all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
-EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
-IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
-CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
-TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
-SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
diff --git a/CoAuthoring/node_modules/express/node_modules/serve-static/README.md b/CoAuthoring/node_modules/express/node_modules/serve-static/README.md
deleted file mode 100644
index 96574b30a4..0000000000
--- a/CoAuthoring/node_modules/express/node_modules/serve-static/README.md
+++ /dev/null
@@ -1,159 +0,0 @@
-# serve-static
-
-[![NPM Version][npm-image]][npm-url]
-[![NPM Downloads][downloads-image]][downloads-url]
-[![Build Status][travis-image]][travis-url]
-[![Test Coverage][coveralls-image]][coveralls-url]
-[![Gratipay][gratipay-image]][gratipay-url]
-
-## Install
-
-```sh
-$ npm install serve-static
-```
-
-## API
-
-```js
-var serveStatic = require('serve-static')
-```
-
-### serveStatic(root, options)
-
-Create a new middleware function to serve files from within a given root
-directory. The file to serve will be determined by combining `req.url`
-with the provided root directory. When a file is not found, instead of
-sending a 404 response, this module will instead call `next()` to move on
-to the next middleware, allowing for stacking and fall-backs.
-
-#### Options
-
-##### dotfiles
-
- Set how "dotfiles" are treated when encountered. A dotfile is a file
-or directory that begins with a dot ("."). Note this check is done on
-the path itself without checking if the path actually exists on the
-disk. If `root` is specified, only the dotfiles above the root are
-checked (i.e. the root itself can be within a dotfile when when set
-to "deny").
-
-The default value is `'ignore'`.
-
- - `'allow'` No special treatment for dotfiles.
- - `'deny'` Send a 403 for any request for a dotfile.
- - `'ignore'` Pretend like the dotfile does not exist and call `next()`.
-
-##### etag
-
-Enable or disable etag generation, defaults to true.
-
-##### extensions
-
-Set file extension fallbacks. When set, if a file is not found, the given
-extensions will be added to the file name and search for. The first that
-exists will be served. Example: `['html', 'htm']`.
-
-The default value is `false`.
-
-##### index
-
-By default this module will send "index.html" files in response to a request
-on a directory. To disable this set `false` or to supply a new index pass a
-string or an array in preferred order.
-
-##### lastModified
-
-Enable or disable `Last-Modified` header, defaults to true. Uses the file
-system's last modified value.
-
-##### maxAge
-
-Provide a max-age in milliseconds for http caching, defaults to 0. This
-can also be a string accepted by the [ms](https://www.npmjs.org/package/ms#readme)
-module.
-
-##### redirect
-
-Redirect to trailing "/" when the pathname is a dir. Defaults to `true`.
-
-##### setHeaders
-
-Function to set custom headers on response.
-
-## Examples
-
-### Serve files with vanilla node.js http server
-
-```js
-var finalhandler = require('finalhandler')
-var http = require('http')
-var serveStatic = require('serve-static')
-
-// Serve up public/ftp folder
-var serve = serveStatic('public/ftp', {'index': ['index.html', 'index.htm']})
-
-// Create server
-var server = http.createServer(function(req, res){
- var done = finalhandler(req, res)
- serve(req, res, done)
-})
-
-// Listen
-server.listen(3000)
-```
-
-### Serve all files as downloads
-
-```js
-var contentDisposition = require('content-disposition')
-var finalhandler = require('finalhandler')
-var http = require('http')
-var serveStatic = require('serve-static')
-
-// Serve up public/ftp folder
-app.use(serveStatic('public/ftp', {
- 'index': false,
- 'setHeaders': setHeaders
-}))
-
-// Set header to force download
-function setHeaders(res, path) {
- res.setHeader('Content-Disposition', contentDisposition(path))
-}
-
-// Create server
-var server = http.createServer(function(req, res){
- var done = finalhandler(req, res)
- serve(req, res, done)
-})
-
-// Listen
-server.listen(3000)
-```
-
-### Serving using express
-
-```js
-var connect = require('connect')
-var serveStatic = require('serve-static')
-
-var app = connect()
-
-app.use(serveStatic('public/ftp', {'index': ['default.html', 'default.htm']}))
-app.listen(3000)
-```
-
-## License
-
-[MIT](LICENSE)
-
-[npm-image]: https://img.shields.io/npm/v/serve-static.svg?style=flat
-[npm-url]: https://npmjs.org/package/serve-static
-[travis-image]: https://img.shields.io/travis/expressjs/serve-static.svg?style=flat
-[travis-url]: https://travis-ci.org/expressjs/serve-static
-[coveralls-image]: https://img.shields.io/coveralls/expressjs/serve-static.svg?style=flat
-[coveralls-url]: https://coveralls.io/r/expressjs/serve-static
-[downloads-image]: https://img.shields.io/npm/dm/serve-static.svg?style=flat
-[downloads-url]: https://npmjs.org/package/serve-static
-[gratipay-image]: https://img.shields.io/gratipay/dougwilson.svg?style=flat
-[gratipay-url]: https://gratipay.com/dougwilson/
diff --git a/CoAuthoring/node_modules/express/node_modules/serve-static/index.js b/CoAuthoring/node_modules/express/node_modules/serve-static/index.js
deleted file mode 100644
index 12ea65949e..0000000000
--- a/CoAuthoring/node_modules/express/node_modules/serve-static/index.js
+++ /dev/null
@@ -1,118 +0,0 @@
-/*!
- * serve-static
- * Copyright(c) 2010 Sencha Inc.
- * Copyright(c) 2011 TJ Holowaychuk
- * Copyright(c) 2014 Douglas Christopher Wilson
- * MIT Licensed
- */
-
-/**
- * Module dependencies.
- */
-
-var escapeHtml = require('escape-html');
-var merge = require('utils-merge');
-var parseurl = require('parseurl');
-var resolve = require('path').resolve;
-var send = require('send');
-var url = require('url');
-
-/**
- * @param {String} root
- * @param {Object} options
- * @return {Function}
- * @api public
- */
-
-exports = module.exports = function serveStatic(root, options) {
- if (!root) {
- throw new TypeError('root path required')
- }
-
- if (typeof root !== 'string') {
- throw new TypeError('root path must be a string')
- }
-
- // copy options object
- options = merge({}, options)
-
- // resolve root to absolute
- root = resolve(root)
-
- // default redirect
- var redirect = options.redirect !== false
-
- // headers listener
- var setHeaders = options.setHeaders
- delete options.setHeaders
-
- if (setHeaders && typeof setHeaders !== 'function') {
- throw new TypeError('option setHeaders must be function')
- }
-
- // setup options for send
- options.maxage = options.maxage || options.maxAge || 0
- options.root = root
-
- return function serveStatic(req, res, next) {
- if (req.method !== 'GET' && req.method !== 'HEAD') {
- return next()
- }
-
- var opts = merge({}, options)
- var originalUrl = parseurl.original(req)
- var path = parseurl(req).pathname
- var hasTrailingSlash = originalUrl.pathname[originalUrl.pathname.length - 1] === '/'
-
- if (path === '/' && !hasTrailingSlash) {
- // make sure redirect occurs at mount
- path = ''
- }
-
- // create send stream
- var stream = send(req, path, opts)
-
- if (redirect) {
- // redirect relative to originalUrl
- stream.on('directory', function redirect() {
- if (hasTrailingSlash) {
- return next()
- }
-
- originalUrl.pathname += '/'
-
- var target = url.format(originalUrl)
-
- res.statusCode = 303
- res.setHeader('Content-Type', 'text/html; charset=utf-8')
- res.setHeader('Location', target)
- res.end('Redirecting to ' + escapeHtml(target) + ' \n')
- })
- } else {
- // forward to next middleware on directory
- stream.on('directory', next)
- }
-
- // add headers listener
- if (setHeaders) {
- stream.on('headers', setHeaders)
- }
-
- // forward non-404 errors
- stream.on('error', function error(err) {
- next(err.status === 404 ? null : err)
- })
-
- // pipe
- stream.pipe(res)
- }
-}
-
-/**
- * Expose mime module.
- *
- * If you wish to extend the mime table use this
- * reference to the "mime" module in the npm registry.
- */
-
-exports.mime = send.mime
diff --git a/CoAuthoring/node_modules/express/node_modules/serve-static/package.json b/CoAuthoring/node_modules/express/node_modules/serve-static/package.json
deleted file mode 100644
index d9cbeed070..0000000000
--- a/CoAuthoring/node_modules/express/node_modules/serve-static/package.json
+++ /dev/null
@@ -1,47 +0,0 @@
-{
- "name": "serve-static",
- "description": "Serve static files",
- "version": "1.6.4",
- "author": {
- "name": "Douglas Christopher Wilson",
- "email": "doug@somethingdoug.com"
- },
- "license": "MIT",
- "repository": {
- "type": "git",
- "url": "git://github.com/expressjs/serve-static"
- },
- "dependencies": {
- "escape-html": "1.0.1",
- "parseurl": "~1.3.0",
- "send": "0.9.3",
- "utils-merge": "1.0.0"
- },
- "devDependencies": {
- "istanbul": "0.3.2",
- "mocha": "~1.21.0",
- "should": "~4.0.0",
- "supertest": "~0.14.0"
- },
- "files": [
- "LICENSE",
- "HISTORY.md",
- "index.js"
- ],
- "engines": {
- "node": ">= 0.8.0"
- },
- "scripts": {
- "test": "mocha --reporter spec --bail --check-leaks --require should test/",
- "test-cov": "istanbul cover node_modules/mocha/bin/_mocha -- --reporter dot --check-leaks --require should test/",
- "test-travis": "istanbul cover node_modules/mocha/bin/_mocha --report lcovonly -- --reporter spec --check-leaks --require should test/"
- },
- "readme": "# serve-static\n\n[![NPM Version][npm-image]][npm-url]\n[![NPM Downloads][downloads-image]][downloads-url]\n[![Build Status][travis-image]][travis-url]\n[![Test Coverage][coveralls-image]][coveralls-url]\n[![Gratipay][gratipay-image]][gratipay-url]\n\n## Install\n\n```sh\n$ npm install serve-static\n```\n\n## API\n\n```js\nvar serveStatic = require('serve-static')\n```\n\n### serveStatic(root, options)\n\nCreate a new middleware function to serve files from within a given root\ndirectory. The file to serve will be determined by combining `req.url`\nwith the provided root directory. When a file is not found, instead of\nsending a 404 response, this module will instead call `next()` to move on\nto the next middleware, allowing for stacking and fall-backs.\n\n#### Options\n\n##### dotfiles\n\n Set how \"dotfiles\" are treated when encountered. A dotfile is a file\nor directory that begins with a dot (\".\"). Note this check is done on\nthe path itself without checking if the path actually exists on the\ndisk. If `root` is specified, only the dotfiles above the root are\nchecked (i.e. the root itself can be within a dotfile when when set\nto \"deny\").\n\nThe default value is `'ignore'`.\n\n - `'allow'` No special treatment for dotfiles.\n - `'deny'` Send a 403 for any request for a dotfile.\n - `'ignore'` Pretend like the dotfile does not exist and call `next()`.\n\n##### etag\n\nEnable or disable etag generation, defaults to true.\n\n##### extensions\n\nSet file extension fallbacks. When set, if a file is not found, the given\nextensions will be added to the file name and search for. The first that\nexists will be served. Example: `['html', 'htm']`.\n\nThe default value is `false`.\n\n##### index\n\nBy default this module will send \"index.html\" files in response to a request\non a directory. To disable this set `false` or to supply a new index pass a\nstring or an array in preferred order.\n\n##### lastModified\n\nEnable or disable `Last-Modified` header, defaults to true. Uses the file\nsystem's last modified value.\n\n##### maxAge\n\nProvide a max-age in milliseconds for http caching, defaults to 0. This\ncan also be a string accepted by the [ms](https://www.npmjs.org/package/ms#readme)\nmodule.\n\n##### redirect\n\nRedirect to trailing \"/\" when the pathname is a dir. Defaults to `true`.\n\n##### setHeaders\n\nFunction to set custom headers on response.\n\n## Examples\n\n### Serve files with vanilla node.js http server\n\n```js\nvar finalhandler = require('finalhandler')\nvar http = require('http')\nvar serveStatic = require('serve-static')\n\n// Serve up public/ftp folder\nvar serve = serveStatic('public/ftp', {'index': ['index.html', 'index.htm']})\n\n// Create server\nvar server = http.createServer(function(req, res){\n var done = finalhandler(req, res)\n serve(req, res, done)\n})\n\n// Listen\nserver.listen(3000)\n```\n\n### Serve all files as downloads\n\n```js\nvar contentDisposition = require('content-disposition')\nvar finalhandler = require('finalhandler')\nvar http = require('http')\nvar serveStatic = require('serve-static')\n\n// Serve up public/ftp folder\napp.use(serveStatic('public/ftp', {\n 'index': false,\n 'setHeaders': setHeaders\n}))\n\n// Set header to force download\nfunction setHeaders(res, path) {\n res.setHeader('Content-Disposition', contentDisposition(path))\n}\n\n// Create server\nvar server = http.createServer(function(req, res){\n var done = finalhandler(req, res)\n serve(req, res, done)\n})\n\n// Listen\nserver.listen(3000)\n```\n\n### Serving using express\n\n```js\nvar connect = require('connect')\nvar serveStatic = require('serve-static')\n\nvar app = connect()\n\napp.use(serveStatic('public/ftp', {'index': ['default.html', 'default.htm']}))\napp.listen(3000)\n```\n\n## License\n\n[MIT](LICENSE)\n\n[npm-image]: https://img.shields.io/npm/v/serve-static.svg?style=flat\n[npm-url]: https://npmjs.org/package/serve-static\n[travis-image]: https://img.shields.io/travis/expressjs/serve-static.svg?style=flat\n[travis-url]: https://travis-ci.org/expressjs/serve-static\n[coveralls-image]: https://img.shields.io/coveralls/expressjs/serve-static.svg?style=flat\n[coveralls-url]: https://coveralls.io/r/expressjs/serve-static\n[downloads-image]: https://img.shields.io/npm/dm/serve-static.svg?style=flat\n[downloads-url]: https://npmjs.org/package/serve-static\n[gratipay-image]: https://img.shields.io/gratipay/dougwilson.svg?style=flat\n[gratipay-url]: https://gratipay.com/dougwilson/\n",
- "readmeFilename": "README.md",
- "bugs": {
- "url": "https://github.com/expressjs/serve-static/issues"
- },
- "homepage": "https://github.com/expressjs/serve-static",
- "_id": "serve-static@1.6.4",
- "_from": "serve-static@~1.6.4"
-}
diff --git a/CoAuthoring/node_modules/express/node_modules/type-is/HISTORY.md b/CoAuthoring/node_modules/express/node_modules/type-is/HISTORY.md
deleted file mode 100644
index c8097f1a61..0000000000
--- a/CoAuthoring/node_modules/express/node_modules/type-is/HISTORY.md
+++ /dev/null
@@ -1,78 +0,0 @@
-1.5.2 / 2014-09-28
-==================
-
- * deps: mime-types@~2.0.2
- - Add new mime types
- - deps: mime-db@~1.1.0
-
-1.5.1 / 2014-09-07
-==================
-
- * Support Node.js 0.6
- * deps: media-typer@0.3.0
- * deps: mime-types@~2.0.1
- - Support Node.js 0.6
-
-1.5.0 / 2014-09-05
-==================
-
- * fix `hasbody` to be true for `content-length: 0`
-
-1.4.0 / 2014-09-02
-==================
-
- * update mime-types
-
-1.3.2 / 2014-06-24
-==================
-
- * use `~` range on mime-types
-
-1.3.1 / 2014-06-19
-==================
-
- * fix global variable leak
-
-1.3.0 / 2014-06-19
-==================
-
- * improve type parsing
-
- - invalid media type never matches
- - media type not case-sensitive
- - extra LWS does not affect results
-
-1.2.2 / 2014-06-19
-==================
-
- * fix behavior on unknown type argument
-
-1.2.1 / 2014-06-03
-==================
-
- * switch dependency from `mime` to `mime-types@1.0.0`
-
-1.2.0 / 2014-05-11
-==================
-
- * support suffix matching:
-
- - `+json` matches `application/vnd+json`
- - `*/vnd+json` matches `application/vnd+json`
- - `application/*+json` matches `application/vnd+json`
-
-1.1.0 / 2014-04-12
-==================
-
- * add non-array values support
- * expose internal utilities:
-
- - `.is()`
- - `.hasBody()`
- - `.normalize()`
- - `.match()`
-
-1.0.1 / 2014-03-30
-==================
-
- * add `multipart` as a shorthand
diff --git a/CoAuthoring/node_modules/express/node_modules/type-is/LICENSE b/CoAuthoring/node_modules/express/node_modules/type-is/LICENSE
deleted file mode 100644
index 4164d08a61..0000000000
--- a/CoAuthoring/node_modules/express/node_modules/type-is/LICENSE
+++ /dev/null
@@ -1,21 +0,0 @@
-The MIT License (MIT)
-
-Copyright (c) 2014 Jonathan Ong me@jongleberry.com
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in
-all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-THE SOFTWARE.
diff --git a/CoAuthoring/node_modules/express/node_modules/type-is/README.md b/CoAuthoring/node_modules/express/node_modules/type-is/README.md
deleted file mode 100644
index 99e5320053..0000000000
--- a/CoAuthoring/node_modules/express/node_modules/type-is/README.md
+++ /dev/null
@@ -1,100 +0,0 @@
-# type-is
-
-[![NPM Version][npm-image]][npm-url]
-[![NPM Downloads][downloads-image]][downloads-url]
-[![Node.js Version][node-version-image]][node-version-url]
-[![Build Status][travis-image]][travis-url]
-[![Test Coverage][coveralls-image]][coveralls-url]
-
-Infer the content-type of a request.
-
-### Install
-
-```sh
-$ npm install type-is
-```
-
-## API
-
-```js
-var http = require('http')
-var is = require('type-is')
-
-http.createServer(function (req, res) {
- var istext = is(req, ['text/*'])
- res.end('you ' + (istext ? 'sent' : 'did not send') + ' me text')
-})
-```
-
-### type = is(request, types)
-
-`request` is the node HTTP request. `types` is an array of types.
-
-```js
-// req.headers.content-type = 'application/json'
-
-is(req, ['json']) // 'json'
-is(req, ['html', 'json']) // 'json'
-is(req, ['application/*']) // 'application/json'
-is(req, ['application/json']) // 'application/json'
-
-is(req, ['html']) // false
-```
-
-#### Each type can be:
-
-- An extension name such as `json`. This name will be returned if matched.
-- A mime type such as `application/json`.
-- A mime type with a wildcard such as `*/json` or `application/*`. The full mime type will be returned if matched
-- A suffix such as `+json`. This can be combined with a wildcard such as `*/vnd+json` or `application/*+json`. The full mime type will be returned if matched.
-
-`false` will be returned if no type matches.
-
-## Examples
-
-#### Example body parser
-
-```js
-var is = require('type-is');
-
-function bodyParser(req, res, next) {
- if (!is.hasBody(req)) {
- return next()
- }
-
- switch (is(req, ['urlencoded', 'json', 'multipart'])) {
- case 'urlencoded':
- // parse urlencoded body
- throw new Error('implement urlencoded body parsing')
- break
- case 'json':
- // parse json body
- throw new Error('implement json body parsing')
- break
- case 'multipart':
- // parse multipart body
- throw new Error('implement multipart body parsing')
- break
- default:
- // 415 error code
- res.statusCode = 415
- res.end()
- return
- }
-}
-```
-
-## License
-
-[MIT](LICENSE)
-
-[npm-image]: https://img.shields.io/npm/v/type-is.svg?style=flat
-[npm-url]: https://npmjs.org/package/type-is
-[node-version-image]: https://img.shields.io/node/v/type-is.svg?style=flat
-[node-version-url]: http://nodejs.org/download/
-[travis-image]: https://img.shields.io/travis/jshttp/type-is.svg?style=flat
-[travis-url]: https://travis-ci.org/jshttp/type-is
-[coveralls-image]: https://img.shields.io/coveralls/jshttp/type-is.svg?style=flat
-[coveralls-url]: https://coveralls.io/r/jshttp/type-is?branch=master
-[downloads-image]: https://img.shields.io/npm/dm/type-is.svg?style=flat
-[downloads-url]: https://npmjs.org/package/type-is
diff --git a/CoAuthoring/node_modules/express/node_modules/type-is/index.js b/CoAuthoring/node_modules/express/node_modules/type-is/index.js
deleted file mode 100644
index 8d220d17a3..0000000000
--- a/CoAuthoring/node_modules/express/node_modules/type-is/index.js
+++ /dev/null
@@ -1,226 +0,0 @@
-
-var typer = require('media-typer')
-var mime = require('mime-types')
-
-module.exports = typeofrequest;
-typeofrequest.is = typeis;
-typeofrequest.hasBody = hasbody;
-typeofrequest.normalize = normalize;
-typeofrequest.match = mimeMatch;
-
-/**
- * Compare a `value` content-type with `types`.
- * Each `type` can be an extension like `html`,
- * a special shortcut like `multipart` or `urlencoded`,
- * or a mime type.
- *
- * If no types match, `false` is returned.
- * Otherwise, the first `type` that matches is returned.
- *
- * @param {String} value
- * @param {Array} types
- * @return String
- */
-
-function typeis(value, types_) {
- var i
- var types = types_
-
- // remove parameters and normalize
- value = typenormalize(value)
-
- // no type or invalid
- if (!value) {
- return false
- }
-
- // support flattened arguments
- if (types && !Array.isArray(types)) {
- types = new Array(arguments.length - 1)
- for (i = 0; i < types.length; i++) {
- types[i] = arguments[i + 1]
- }
- }
-
- // no types, return the content type
- if (!types || !types.length) return value;
-
- var type
- for (i = 0; i < types.length; i++) {
- if (mimeMatch(normalize(type = types[i]), value)) {
- return type[0] === '+' || ~type.indexOf('*')
- ? value
- : type
- }
- }
-
- // no matches
- return false;
-}
-
-/**
- * Check if a request has a request body.
- * A request with a body __must__ either have `transfer-encoding`
- * or `content-length` headers set.
- * http://www.w3.org/Protocols/rfc2616/rfc2616-sec4.html#sec4.3
- *
- * @param {Object} request
- * @return {Boolean}
- * @api public
- */
-
-function hasbody(req) {
- var headers = req.headers;
- if ('transfer-encoding' in headers) return true;
- return !isNaN(headers['content-length']);
-}
-
-/**
- * Check if the incoming request contains the "Content-Type"
- * header field, and it contains any of the give mime `type`s.
- * If there is no request body, `null` is returned.
- * If there is no content type, `false` is returned.
- * Otherwise, it returns the first `type` that matches.
- *
- * Examples:
- *
- * // With Content-Type: text/html; charset=utf-8
- * this.is('html'); // => 'html'
- * this.is('text/html'); // => 'text/html'
- * this.is('text/*', 'application/json'); // => 'text/html'
- *
- * // When Content-Type is application/json
- * this.is('json', 'urlencoded'); // => 'json'
- * this.is('application/json'); // => 'application/json'
- * this.is('html', 'application/*'); // => 'application/json'
- *
- * this.is('html'); // => false
- *
- * @param {String|Array} types...
- * @return {String|false|null}
- * @api public
- */
-
-function typeofrequest(req, types_) {
- var types = types_
-
- // no body
- if (!hasbody(req)) {
- return null
- }
-
- // support flattened arguments
- if (arguments.length > 2) {
- types = new Array(arguments.length - 1)
- for (var i = 0; i < types.length; i++) {
- types[i] = arguments[i + 1]
- }
- }
-
- // request content type
- var value = req.headers['content-type']
-
- return typeis(value, types);
-}
-
-/**
- * Normalize a mime type.
- * If it's a shorthand, expand it to a valid mime type.
- *
- * In general, you probably want:
- *
- * var type = is(req, ['urlencoded', 'json', 'multipart']);
- *
- * Then use the appropriate body parsers.
- * These three are the most common request body types
- * and are thus ensured to work.
- *
- * @param {String} type
- * @api private
- */
-
-function normalize(type) {
- switch (type) {
- case 'urlencoded': return 'application/x-www-form-urlencoded';
- case 'multipart':
- type = 'multipart/*';
- break;
- }
-
- return type[0] === '+' || ~type.indexOf('/')
- ? type
- : mime.lookup(type)
-}
-
-/**
- * Check if `exected` mime type
- * matches `actual` mime type with
- * wildcard and +suffix support.
- *
- * @param {String} expected
- * @param {String} actual
- * @return {Boolean}
- * @api private
- */
-
-function mimeMatch(expected, actual) {
- // invalid type
- if (expected === false) {
- return false
- }
-
- // exact match
- if (expected === actual) {
- return true
- }
-
- actual = actual.split('/');
-
- if (expected[0] === '+') {
- // support +suffix
- return Boolean(actual[1])
- && expected.length <= actual[1].length
- && expected === actual[1].substr(0 - expected.length)
- }
-
- if (!~expected.indexOf('*')) return false;
-
- expected = expected.split('/');
-
- if (expected[0] === '*') {
- // support */yyy
- return expected[1] === actual[1]
- }
-
- if (expected[1] === '*') {
- // support xxx/*
- return expected[0] === actual[0]
- }
-
- if (expected[1][0] === '*' && expected[1][1] === '+') {
- // support xxx/*+zzz
- return expected[0] === actual[0]
- && expected[1].length <= actual[1].length + 1
- && expected[1].substr(1) === actual[1].substr(1 - expected[1].length)
- }
-
- return false
-}
-
-/**
- * Normalize a type and remove parameters.
- *
- * @param {string} value
- * @return {string}
- * @api private
- */
-
-function typenormalize(value) {
- try {
- var type = typer.parse(value)
- delete type.parameters
- return typer.format(type)
- } catch (err) {
- return null
- }
-}
diff --git a/CoAuthoring/node_modules/express/node_modules/type-is/node_modules/mime-types/HISTORY.md b/CoAuthoring/node_modules/express/node_modules/type-is/node_modules/mime-types/HISTORY.md
deleted file mode 100644
index 6071381665..0000000000
--- a/CoAuthoring/node_modules/express/node_modules/type-is/node_modules/mime-types/HISTORY.md
+++ /dev/null
@@ -1,39 +0,0 @@
-2.0.2 / 2014-09-28
-==================
-
- * deps: mime-db@~1.1.0
- - Add new mime types
- - Add additional compressible
- - Update charsets
-
-2.0.1 / 2014-09-07
-==================
-
- * Support Node.js 0.6
-
-2.0.0 / 2014-09-02
-==================
-
- * Use `mime-db`
- * Remove `.define()`
-
-1.0.2 / 2014-08-04
-==================
-
- * Set charset=utf-8 for `text/javascript`
-
-1.0.1 / 2014-06-24
-==================
-
- * Add `text/jsx` type
-
-1.0.0 / 2014-05-12
-==================
-
- * Return `false` for unknown types
- * Set charset=utf-8 for `application/json`
-
-0.1.0 / 2014-05-02
-==================
-
- * Initial release
diff --git a/CoAuthoring/node_modules/express/node_modules/type-is/node_modules/mime-types/LICENSE b/CoAuthoring/node_modules/express/node_modules/type-is/node_modules/mime-types/LICENSE
deleted file mode 100644
index a7ae8ee9b8..0000000000
--- a/CoAuthoring/node_modules/express/node_modules/type-is/node_modules/mime-types/LICENSE
+++ /dev/null
@@ -1,22 +0,0 @@
-
-The MIT License (MIT)
-
-Copyright (c) 2014 Jonathan Ong me@jongleberry.com
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in
-all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-THE SOFTWARE.
diff --git a/CoAuthoring/node_modules/express/node_modules/type-is/node_modules/mime-types/README.md b/CoAuthoring/node_modules/express/node_modules/type-is/node_modules/mime-types/README.md
deleted file mode 100644
index 99d658b8b3..0000000000
--- a/CoAuthoring/node_modules/express/node_modules/type-is/node_modules/mime-types/README.md
+++ /dev/null
@@ -1,99 +0,0 @@
-# mime-types
-
-[![NPM Version][npm-image]][npm-url]
-[![NPM Downloads][downloads-image]][downloads-url]
-[![Node.js Version][node-version-image]][node-version-url]
-[![Build Status][travis-image]][travis-url]
-[![Test Coverage][coveralls-image]][coveralls-url]
-
-The ultimate javascript content-type utility.
-
-Similar to [node-mime](https://github.com/broofa/node-mime), except:
-
-- __No fallbacks.__ Instead of naively returning the first available type, `mime-types` simply returns `false`,
- so do `var type = mime.lookup('unrecognized') || 'application/octet-stream'`.
-- No `new Mime()` business, so you could do `var lookup = require('mime-types').lookup`.
-- Additional mime types are added such as jade and stylus via [mime-db](https://github.com/jshttp/mime-db)
-- No `.define()` functionality
-
-Otherwise, the API is compatible.
-
-## Install
-
-```sh
-$ npm install mime-types
-```
-
-## Adding Types
-
-All mime types are based on [mime-db](https://github.com/jshttp/mime-db),
-so open a PR there if you'd like to add mime types.
-
-## API
-
-```js
-var mime = require('mime-types')
-```
-
-All functions return `false` if input is invalid or not found.
-
-### mime.lookup(path)
-
-Lookup the content-type associated with a file.
-
-```js
-mime.lookup('json') // 'application/json'
-mime.lookup('.md') // 'text/x-markdown'
-mime.lookup('file.html') // 'text/html'
-mime.lookup('folder/file.js') // 'application/javascript'
-
-mime.lookup('cats') // false
-```
-
-### mime.contentType(type)
-
-Create a full content-type header given a content-type or extension.
-
-```js
-mime.contentType('markdown') // 'text/x-markdown; charset=utf-8'
-mime.contentType('file.json') // 'application/json; charset=utf-8'
-```
-
-### mime.extension(type)
-
-Get the default extension for a content-type.
-
-```js
-mime.extension('application/octet-stream') // 'bin'
-```
-
-### mime.charset(type)
-
-Lookup the implied default charset of a content-type.
-
-```js
-mime.charset('text/x-markdown') // 'UTF-8'
-```
-
-### var type = mime.types[extension]
-
-A map of content-types by extension.
-
-### [extensions...] = mime.extensions[type]
-
-A map of extensions by content-type.
-
-## License
-
-[MIT](LICENSE)
-
-[npm-image]: https://img.shields.io/npm/v/mime-types.svg?style=flat
-[npm-url]: https://npmjs.org/package/mime-types
-[node-version-image]: https://img.shields.io/badge/node.js-%3E%3D_0.6-brightgreen.svg?style=flat
-[node-version-url]: http://nodejs.org/download/
-[travis-image]: https://img.shields.io/travis/jshttp/mime-types.svg?style=flat
-[travis-url]: https://travis-ci.org/jshttp/mime-types
-[coveralls-image]: https://img.shields.io/coveralls/jshttp/mime-types.svg?style=flat
-[coveralls-url]: https://coveralls.io/r/jshttp/mime-types
-[downloads-image]: https://img.shields.io/npm/dm/mime-types.svg?style=flat
-[downloads-url]: https://npmjs.org/package/mime-types
diff --git a/CoAuthoring/node_modules/express/node_modules/type-is/node_modules/mime-types/index.js b/CoAuthoring/node_modules/express/node_modules/type-is/node_modules/mime-types/index.js
deleted file mode 100644
index b46a202f53..0000000000
--- a/CoAuthoring/node_modules/express/node_modules/type-is/node_modules/mime-types/index.js
+++ /dev/null
@@ -1,63 +0,0 @@
-
-var db = require('mime-db')
-
-// types[extension] = type
-exports.types = Object.create(null)
-// extensions[type] = [extensions]
-exports.extensions = Object.create(null)
-
-Object.keys(db).forEach(function (name) {
- var mime = db[name]
- var exts = mime.extensions
- if (!exts || !exts.length) return
- exports.extensions[name] = exts
- exts.forEach(function (ext) {
- exports.types[ext] = name
- })
-})
-
-exports.lookup = function (string) {
- if (!string || typeof string !== "string") return false
- // remove any leading paths, though we should just use path.basename
- string = string.replace(/.*[\.\/\\]/, '').toLowerCase()
- if (!string) return false
- return exports.types[string] || false
-}
-
-exports.extension = function (type) {
- if (!type || typeof type !== "string") return false
- // to do: use media-typer
- type = type.match(/^\s*([^;\s]*)(?:;|\s|$)/)
- if (!type) return false
- var exts = exports.extensions[type[1].toLowerCase()]
- if (!exts || !exts.length) return false
- return exts[0]
-}
-
-// type has to be an exact mime type
-exports.charset = function (type) {
- var mime = db[type]
- if (mime && mime.charset) return mime.charset
-
- // default text/* to utf-8
- if (/^text\//.test(type)) return 'UTF-8'
-
- return false
-}
-
-// backwards compatibility
-exports.charsets = {
- lookup: exports.charset
-}
-
-// to do: maybe use set-type module or something
-exports.contentType = function (type) {
- if (!type || typeof type !== "string") return false
- if (!~type.indexOf('/')) type = exports.lookup(type)
- if (!type) return false
- if (!~type.indexOf('charset')) {
- var charset = exports.charset(type)
- if (charset) type += '; charset=' + charset.toLowerCase()
- }
- return type
-}
diff --git a/CoAuthoring/node_modules/express/node_modules/type-is/node_modules/mime-types/node_modules/mime-db/LICENSE b/CoAuthoring/node_modules/express/node_modules/type-is/node_modules/mime-types/node_modules/mime-db/LICENSE
deleted file mode 100644
index a7ae8ee9b8..0000000000
--- a/CoAuthoring/node_modules/express/node_modules/type-is/node_modules/mime-types/node_modules/mime-db/LICENSE
+++ /dev/null
@@ -1,22 +0,0 @@
-
-The MIT License (MIT)
-
-Copyright (c) 2014 Jonathan Ong me@jongleberry.com
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in
-all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-THE SOFTWARE.
diff --git a/CoAuthoring/node_modules/express/node_modules/type-is/node_modules/mime-types/node_modules/mime-db/README.md b/CoAuthoring/node_modules/express/node_modules/type-is/node_modules/mime-types/node_modules/mime-db/README.md
deleted file mode 100644
index 3b6364ebb8..0000000000
--- a/CoAuthoring/node_modules/express/node_modules/type-is/node_modules/mime-types/node_modules/mime-db/README.md
+++ /dev/null
@@ -1,72 +0,0 @@
-# mime-db
-
-[![NPM Version][npm-version-image]][npm-url]
-[![NPM Downloads][npm-downloads-image]][npm-url]
-[![Node.js Version][node-image]][node-url]
-[![Build Status][travis-image]][travis-url]
-[![Coverage Status][coveralls-image]][coveralls-url]
-
-This is a database of all mime types.
-It consistents of a single, public JSON file and does not include any logic,
-allowing it to remain as unopinionated as possible with an API.
-It aggregates data from the following sources:
-
-- http://www.iana.org/assignments/media-types/media-types.xhtml
-- http://svn.apache.org/repos/asf/httpd/httpd/trunk/docs/conf/mime.types
-
-## Usage
-
-```bash
-npm i mime-db
-```
-
-```js
-var db = require('mime-db');
-
-// grab data on .js files
-var data = db['application/javascript'];
-```
-
-If you're crazy enough to use this in the browser,
-you can just grab the JSON file:
-
-```
-https://cdn.rawgit.com/jshttp/mime-db/master/db.json
-```
-
-## Data Structure
-
-The JSON file is a map lookup for lowercased mime types.
-Each mime type has the following properties:
-
-- `.source` - where the mime type is defined.
- If not set, it's probably a custom media type.
- - `apache` - [Apache common media types](http://svn.apache.org/repos/asf/httpd/httpd/trunk/docs/conf/mime.types)
- - `iana` - [IANA-defined media types](http://www.iana.org/assignments/media-types/media-types.xhtml)
-- `.extensions[]` - known extensions associated with this mime type.
-- `.compressible` - whether a file of this type is can be gzipped.
-- `.charset` - the default charset associated with this type, if any.
-
-If unknown, every property could be `undefined`.
-
-## Repository Structure
-
-- `scripts` - these are scripts to run to build the database
-- `src/` - this is a folder of files created from remote sources like Apache and IANA
-- `lib/` - this is a folder of our own custom sources and db, which will be merged into `db.json`
-- `db.json` - the final built JSON file for end-user usage
-
-## Contributing
-
-To edit the database, only make PRs against files in the `lib/` folder.
-To update the build, run `npm run update`.
-
-[npm-version-image]: https://img.shields.io/npm/v/mime-db.svg?style=flat
-[npm-downloads-image]: https://img.shields.io/npm/dm/mime-db.svg?style=flat
-[npm-url]: https://npmjs.org/package/mime-db
-[travis-image]: https://img.shields.io/travis/jshttp/mime-db.svg?style=flat
-[travis-url]: https://travis-ci.org/jshttp/mime-db
-[coveralls-image]: https://img.shields.io/coveralls/jshttp/mime-db.svg?style=flat
-[coveralls-url]: https://coveralls.io/r/jshttp/mime-db?branch=master
-[node-image]: https://img.shields.io/node/v/mime-db.svg?style=flat
-[node-url]: http://nodejs.org/download/
diff --git a/CoAuthoring/node_modules/express/node_modules/type-is/node_modules/mime-types/node_modules/mime-db/db.json b/CoAuthoring/node_modules/express/node_modules/type-is/node_modules/mime-types/node_modules/mime-db/db.json
deleted file mode 100644
index 6887056691..0000000000
--- a/CoAuthoring/node_modules/express/node_modules/type-is/node_modules/mime-types/node_modules/mime-db/db.json
+++ /dev/null
@@ -1,6327 +0,0 @@
-{
- "application/1d-interleaved-parityfec": {
- "source": "iana"
- },
- "application/3gpdash-qoe-report+xml": {
- "source": "iana"
- },
- "application/3gpp-ims+xml": {
- "source": "iana"
- },
- "application/activemessage": {
- "source": "iana"
- },
- "application/alto-costmap+json": {
- "source": "iana",
- "compressible": true
- },
- "application/alto-costmapfilter+json": {
- "source": "iana",
- "compressible": true
- },
- "application/alto-directory+json": {
- "source": "iana",
- "compressible": true
- },
- "application/alto-endpointcost+json": {
- "source": "iana",
- "compressible": true
- },
- "application/alto-endpointcostparams+json": {
- "source": "iana",
- "compressible": true
- },
- "application/alto-endpointprop+json": {
- "source": "iana",
- "compressible": true
- },
- "application/alto-endpointpropparams+json": {
- "source": "iana",
- "compressible": true
- },
- "application/alto-error+json": {
- "source": "iana",
- "compressible": true
- },
- "application/alto-networkmap+json": {
- "source": "iana",
- "compressible": true
- },
- "application/alto-networkmapfilter+json": {
- "source": "iana",
- "compressible": true
- },
- "application/andrew-inset": {
- "source": "iana",
- "extensions": ["ez"]
- },
- "application/applefile": {
- "source": "iana"
- },
- "application/applixware": {
- "source": "apache",
- "extensions": ["aw"]
- },
- "application/atf": {
- "source": "iana"
- },
- "application/atom+xml": {
- "source": "iana",
- "compressible": true,
- "extensions": ["atom"]
- },
- "application/atomcat+xml": {
- "source": "iana",
- "extensions": ["atomcat"]
- },
- "application/atomdeleted+xml": {
- "source": "iana"
- },
- "application/atomicmail": {
- "source": "iana"
- },
- "application/atomsvc+xml": {
- "source": "iana",
- "extensions": ["atomsvc"]
- },
- "application/auth-policy+xml": {
- "source": "iana"
- },
- "application/bacnet-xdd+zip": {
- "source": "iana"
- },
- "application/batch-smtp": {
- "source": "iana"
- },
- "application/beep+xml": {
- "source": "iana"
- },
- "application/calendar+json": {
- "source": "iana",
- "compressible": true
- },
- "application/calendar+xml": {
- "source": "iana"
- },
- "application/call-completion": {
- "source": "iana"
- },
- "application/cals-1840": {
- "source": "iana"
- },
- "application/cbor": {
- "source": "iana"
- },
- "application/ccmp+xml": {
- "source": "iana"
- },
- "application/ccxml+xml": {
- "source": "iana",
- "extensions": ["ccxml"]
- },
- "application/cdmi-capability": {
- "source": "iana",
- "extensions": ["cdmia"]
- },
- "application/cdmi-container": {
- "source": "iana",
- "extensions": ["cdmic"]
- },
- "application/cdmi-domain": {
- "source": "iana",
- "extensions": ["cdmid"]
- },
- "application/cdmi-object": {
- "source": "iana",
- "extensions": ["cdmio"]
- },
- "application/cdmi-queue": {
- "source": "iana",
- "extensions": ["cdmiq"]
- },
- "application/cea-2018+xml": {
- "source": "iana"
- },
- "application/cellml+xml": {
- "source": "iana"
- },
- "application/cfw": {
- "source": "iana"
- },
- "application/cms": {
- "source": "iana"
- },
- "application/cnrp+xml": {
- "source": "iana"
- },
- "application/coap-group+json": {
- "source": "iana",
- "compressible": true
- },
- "application/commonground": {
- "source": "iana"
- },
- "application/conference-info+xml": {
- "source": "iana"
- },
- "application/cpl+xml": {
- "source": "iana"
- },
- "application/csrattrs": {
- "source": "iana"
- },
- "application/csta+xml": {
- "source": "iana"
- },
- "application/cstadata+xml": {
- "source": "iana"
- },
- "application/cu-seeme": {
- "source": "apache",
- "extensions": ["cu"]
- },
- "application/cybercash": {
- "source": "iana"
- },
- "application/dart": {
- "compressible": true
- },
- "application/dash+xml": {
- "source": "iana",
- "extensions": ["mdp"]
- },
- "application/dashdelta": {
- "source": "iana"
- },
- "application/davmount+xml": {
- "source": "iana",
- "extensions": ["davmount"]
- },
- "application/dca-rft": {
- "source": "iana"
- },
- "application/dcd": {
- "source": "iana"
- },
- "application/dec-dx": {
- "source": "iana"
- },
- "application/dialog-info+xml": {
- "source": "iana"
- },
- "application/dicom": {
- "source": "iana"
- },
- "application/dns": {
- "source": "iana"
- },
- "application/docbook+xml": {
- "source": "apache",
- "extensions": ["dbk"]
- },
- "application/dskpp+xml": {
- "source": "iana"
- },
- "application/dssc+der": {
- "source": "iana",
- "extensions": ["dssc"]
- },
- "application/dssc+xml": {
- "source": "iana",
- "extensions": ["xdssc"]
- },
- "application/dvcs": {
- "source": "iana"
- },
- "application/ecmascript": {
- "source": "iana",
- "compressible": true,
- "extensions": ["ecma"]
- },
- "application/edi-consent": {
- "source": "iana"
- },
- "application/edi-x12": {
- "source": "iana",
- "compressible": false
- },
- "application/edifact": {
- "source": "iana",
- "compressible": false
- },
- "application/emma+xml": {
- "source": "iana",
- "extensions": ["emma"]
- },
- "application/emotionml+xml": {
- "source": "iana"
- },
- "application/encaprtp": {
- "source": "iana"
- },
- "application/epp+xml": {
- "source": "iana"
- },
- "application/epub+zip": {
- "source": "apache",
- "extensions": ["epub"]
- },
- "application/eshop": {
- "source": "iana"
- },
- "application/example": {
- "source": "iana"
- },
- "application/exi": {
- "source": "iana",
- "extensions": ["exi"]
- },
- "application/fastinfoset": {
- "source": "iana"
- },
- "application/fastsoap": {
- "source": "iana"
- },
- "application/fdt+xml": {
- "source": "iana"
- },
- "application/fits": {
- "source": "iana"
- },
- "application/font-sfnt": {
- "source": "iana"
- },
- "application/font-tdpfr": {
- "source": "iana",
- "extensions": ["pfr"]
- },
- "application/font-woff": {
- "source": "iana",
- "compressible": false,
- "extensions": ["woff"]
- },
- "application/font-woff2": {
- "compressible": false,
- "extensions": ["woff2"]
- },
- "application/framework-attributes+xml": {
- "source": "iana"
- },
- "application/gml+xml": {
- "source": "apache",
- "extensions": ["gml"]
- },
- "application/gpx+xml": {
- "source": "apache",
- "extensions": ["gpx"]
- },
- "application/gxf": {
- "source": "apache",
- "extensions": ["gxf"]
- },
- "application/gzip": {
- "source": "iana",
- "compressible": false
- },
- "application/h224": {
- "source": "iana"
- },
- "application/held+xml": {
- "source": "iana"
- },
- "application/http": {
- "source": "iana"
- },
- "application/hyperstudio": {
- "source": "iana",
- "extensions": ["stk"]
- },
- "application/ibe-key-request+xml": {
- "source": "iana"
- },
- "application/ibe-pkg-reply+xml": {
- "source": "iana"
- },
- "application/ibe-pp-data": {
- "source": "iana"
- },
- "application/iges": {
- "source": "iana"
- },
- "application/im-iscomposing+xml": {
- "source": "iana"
- },
- "application/index": {
- "source": "iana"
- },
- "application/index.cmd": {
- "source": "iana"
- },
- "application/index.obj": {
- "source": "iana"
- },
- "application/index.response": {
- "source": "iana"
- },
- "application/index.vnd": {
- "source": "iana"
- },
- "application/inkml+xml": {
- "source": "iana",
- "extensions": ["ink","inkml"]
- },
- "application/iotp": {
- "source": "iana"
- },
- "application/ipfix": {
- "source": "iana",
- "extensions": ["ipfix"]
- },
- "application/ipp": {
- "source": "iana"
- },
- "application/isup": {
- "source": "iana"
- },
- "application/its+xml": {
- "source": "iana"
- },
- "application/java-archive": {
- "source": "apache",
- "compressible": false,
- "extensions": ["jar"]
- },
- "application/java-serialized-object": {
- "source": "apache",
- "compressible": false,
- "extensions": ["ser"]
- },
- "application/java-vm": {
- "source": "apache",
- "compressible": false,
- "extensions": ["class"]
- },
- "application/javascript": {
- "source": "iana",
- "charset": "UTF-8",
- "compressible": true,
- "extensions": ["js"]
- },
- "application/jrd+json": {
- "source": "iana",
- "compressible": true
- },
- "application/json": {
- "source": "iana",
- "charset": "UTF-8",
- "compressible": true,
- "extensions": ["json","map"]
- },
- "application/json-patch+json": {
- "source": "iana",
- "compressible": true
- },
- "application/jsonml+json": {
- "source": "apache",
- "compressible": true,
- "extensions": ["jsonml"]
- },
- "application/kpml-request+xml": {
- "source": "iana"
- },
- "application/kpml-response+xml": {
- "source": "iana"
- },
- "application/ld+json": {
- "source": "iana",
- "compressible": true
- },
- "application/link-format": {
- "source": "iana"
- },
- "application/load-control+xml": {
- "source": "iana"
- },
- "application/lost+xml": {
- "source": "iana",
- "extensions": ["lostxml"]
- },
- "application/lostsync+xml": {
- "source": "iana"
- },
- "application/mac-binhex40": {
- "source": "iana",
- "extensions": ["hqx"]
- },
- "application/mac-compactpro": {
- "source": "apache",
- "extensions": ["cpt"]
- },
- "application/macwriteii": {
- "source": "iana"
- },
- "application/mads+xml": {
- "source": "iana",
- "extensions": ["mads"]
- },
- "application/marc": {
- "source": "iana",
- "extensions": ["mrc"]
- },
- "application/marcxml+xml": {
- "source": "iana",
- "extensions": ["mrcx"]
- },
- "application/mathematica": {
- "source": "iana",
- "extensions": ["ma","nb","mb"]
- },
- "application/mathml+xml": {
- "source": "iana",
- "extensions": ["mathml"]
- },
- "application/mathml-content+xml": {
- "source": "iana"
- },
- "application/mathml-presentation+xml": {
- "source": "iana"
- },
- "application/mbms-associated-procedure-description+xml": {
- "source": "iana"
- },
- "application/mbms-deregister+xml": {
- "source": "iana"
- },
- "application/mbms-envelope+xml": {
- "source": "iana"
- },
- "application/mbms-msk+xml": {
- "source": "iana"
- },
- "application/mbms-msk-response+xml": {
- "source": "iana"
- },
- "application/mbms-protection-description+xml": {
- "source": "iana"
- },
- "application/mbms-reception-report+xml": {
- "source": "iana"
- },
- "application/mbms-register+xml": {
- "source": "iana"
- },
- "application/mbms-register-response+xml": {
- "source": "iana"
- },
- "application/mbms-schedule+xml": {
- "source": "iana"
- },
- "application/mbms-user-service-description+xml": {
- "source": "iana"
- },
- "application/mbox": {
- "source": "apache",
- "extensions": ["mbox"]
- },
- "application/mbox+xml": {
- "source": "iana"
- },
- "application/media-policy-dataset+xml": {
- "source": "iana"
- },
- "application/media_control+xml": {
- "source": "iana"
- },
- "application/mediaservercontrol+xml": {
- "source": "iana",
- "extensions": ["mscml"]
- },
- "application/merge-patch+json": {
- "source": "iana",
- "compressible": true
- },
- "application/metalink+xml": {
- "source": "apache",
- "extensions": ["metalink"]
- },
- "application/metalink4+xml": {
- "source": "iana",
- "extensions": ["meta4"]
- },
- "application/mets+xml": {
- "source": "iana",
- "extensions": ["mets"]
- },
- "application/mikey": {
- "source": "iana"
- },
- "application/mods+xml": {
- "source": "iana",
- "extensions": ["mods"]
- },
- "application/moss-keys": {
- "source": "iana"
- },
- "application/moss-signature": {
- "source": "iana"
- },
- "application/mosskey-data": {
- "source": "iana"
- },
- "application/mosskey-request": {
- "source": "iana"
- },
- "application/mp21": {
- "source": "iana",
- "extensions": ["m21","mp21"]
- },
- "application/mp4": {
- "source": "iana",
- "extensions": ["mp4s","m4p"]
- },
- "application/mpeg4-generic": {
- "source": "iana"
- },
- "application/mpeg4-iod": {
- "source": "iana"
- },
- "application/mpeg4-iod-xmt": {
- "source": "iana"
- },
- "application/mrb-consumer+xml": {
- "source": "iana"
- },
- "application/mrb-publish+xml": {
- "source": "iana"
- },
- "application/msc-ivr+xml": {
- "source": "iana"
- },
- "application/msc-mixer+xml": {
- "source": "iana"
- },
- "application/msword": {
- "source": "iana",
- "compressible": false,
- "extensions": ["doc","dot"]
- },
- "application/mxf": {
- "source": "iana",
- "extensions": ["mxf"]
- },
- "application/nasdata": {
- "source": "iana"
- },
- "application/news-checkgroups": {
- "source": "iana"
- },
- "application/news-groupinfo": {
- "source": "iana"
- },
- "application/news-transmission": {
- "source": "iana"
- },
- "application/nlsml+xml": {
- "source": "iana"
- },
- "application/nss": {
- "source": "iana"
- },
- "application/ocsp-request": {
- "source": "iana"
- },
- "application/ocsp-response": {
- "source": "apache"
- },
- "application/octet-stream": {
- "source": "iana",
- "compressible": false,
- "extensions": ["bin","dms","lrf","mar","so","dist","distz","pkg","bpk","dump","elc","deploy","buffer"]
- },
- "application/oda": {
- "source": "iana",
- "extensions": ["oda"]
- },
- "application/odx": {
- "source": "iana"
- },
- "application/oebps-package+xml": {
- "source": "iana",
- "extensions": ["opf"]
- },
- "application/ogg": {
- "source": "iana",
- "compressible": false,
- "extensions": ["ogx"]
- },
- "application/omdoc+xml": {
- "source": "apache",
- "extensions": ["omdoc"]
- },
- "application/onenote": {
- "source": "apache",
- "extensions": ["onetoc","onetoc2","onetmp","onepkg"]
- },
- "application/oscp-response": {
- "source": "iana"
- },
- "application/oxps": {
- "source": "iana",
- "extensions": ["oxps"]
- },
- "application/p2p-overlay+xml": {
- "source": "iana"
- },
- "application/parityfec": {
- "source": "iana"
- },
- "application/patch-ops-error+xml": {
- "source": "iana",
- "extensions": ["xer"]
- },
- "application/pdf": {
- "source": "iana",
- "compressible": false,
- "extensions": ["pdf"]
- },
- "application/pdx": {
- "source": "iana"
- },
- "application/pgp-encrypted": {
- "source": "iana",
- "compressible": false,
- "extensions": ["pgp"]
- },
- "application/pgp-keys": {
- "source": "iana"
- },
- "application/pgp-signature": {
- "source": "iana",
- "extensions": ["asc","sig"]
- },
- "application/pics-rules": {
- "source": "apache",
- "extensions": ["prf"]
- },
- "application/pidf+xml": {
- "source": "iana"
- },
- "application/pidf-diff+xml": {
- "source": "iana"
- },
- "application/pkcs10": {
- "source": "iana",
- "extensions": ["p10"]
- },
- "application/pkcs7-mime": {
- "source": "iana",
- "extensions": ["p7m","p7c"]
- },
- "application/pkcs7-signature": {
- "source": "iana",
- "extensions": ["p7s"]
- },
- "application/pkcs8": {
- "source": "iana",
- "extensions": ["p8"]
- },
- "application/pkix-attr-cert": {
- "source": "iana",
- "extensions": ["ac"]
- },
- "application/pkix-cert": {
- "source": "iana",
- "extensions": ["cer"]
- },
- "application/pkix-crl": {
- "source": "iana",
- "extensions": ["crl"]
- },
- "application/pkix-pkipath": {
- "source": "iana",
- "extensions": ["pkipath"]
- },
- "application/pkixcmp": {
- "source": "iana",
- "extensions": ["pki"]
- },
- "application/pls+xml": {
- "source": "iana",
- "extensions": ["pls"]
- },
- "application/poc-settings+xml": {
- "source": "iana"
- },
- "application/postscript": {
- "source": "iana",
- "compressible": true,
- "extensions": ["ai","eps","ps"]
- },
- "application/provenance+xml": {
- "source": "iana"
- },
- "application/prs.alvestrand.titrax-sheet": {
- "source": "iana"
- },
- "application/prs.cww": {
- "source": "iana",
- "extensions": ["cww"]
- },
- "application/prs.hpub+zip": {
- "source": "iana"
- },
- "application/prs.nprend": {
- "source": "iana"
- },
- "application/prs.plucker": {
- "source": "iana"
- },
- "application/prs.rdf-xml-crypt": {
- "source": "iana"
- },
- "application/prs.xsf+xml": {
- "source": "iana"
- },
- "application/pskc+xml": {
- "source": "iana",
- "extensions": ["pskcxml"]
- },
- "application/qsig": {
- "source": "iana"
- },
- "application/raptorfec": {
- "source": "iana"
- },
- "application/rdf+xml": {
- "source": "iana",
- "compressible": true,
- "extensions": ["rdf"]
- },
- "application/reginfo+xml": {
- "source": "iana",
- "extensions": ["rif"]
- },
- "application/relax-ng-compact-syntax": {
- "source": "iana",
- "extensions": ["rnc"]
- },
- "application/remote-printing": {
- "source": "iana"
- },
- "application/reputon+json": {
- "source": "iana",
- "compressible": true
- },
- "application/resource-lists+xml": {
- "source": "iana",
- "extensions": ["rl"]
- },
- "application/resource-lists-diff+xml": {
- "source": "iana",
- "extensions": ["rld"]
- },
- "application/riscos": {
- "source": "iana"
- },
- "application/rlmi+xml": {
- "source": "iana"
- },
- "application/rls-services+xml": {
- "source": "iana",
- "extensions": ["rs"]
- },
- "application/rpki-ghostbusters": {
- "source": "iana",
- "extensions": ["gbr"]
- },
- "application/rpki-manifest": {
- "source": "iana",
- "extensions": ["mft"]
- },
- "application/rpki-roa": {
- "source": "iana",
- "extensions": ["roa"]
- },
- "application/rpki-updown": {
- "source": "iana"
- },
- "application/rsd+xml": {
- "source": "apache",
- "extensions": ["rsd"]
- },
- "application/rss+xml": {
- "source": "apache",
- "compressible": true,
- "extensions": ["rss"]
- },
- "application/rtf": {
- "source": "iana",
- "compressible": true,
- "extensions": ["rtf"]
- },
- "application/rtploopback": {
- "source": "iana"
- },
- "application/rtx": {
- "source": "iana"
- },
- "application/samlassertion+xml": {
- "source": "iana"
- },
- "application/samlmetadata+xml": {
- "source": "iana"
- },
- "application/sbml+xml": {
- "source": "iana",
- "extensions": ["sbml"]
- },
- "application/scaip+xml": {
- "source": "iana"
- },
- "application/scvp-cv-request": {
- "source": "iana",
- "extensions": ["scq"]
- },
- "application/scvp-cv-response": {
- "source": "iana",
- "extensions": ["scs"]
- },
- "application/scvp-vp-request": {
- "source": "iana",
- "extensions": ["spq"]
- },
- "application/scvp-vp-response": {
- "source": "iana",
- "extensions": ["spp"]
- },
- "application/sdp": {
- "source": "iana",
- "extensions": ["sdp"]
- },
- "application/sep+xml": {
- "source": "iana"
- },
- "application/sep-exi": {
- "source": "iana"
- },
- "application/session-info": {
- "source": "iana"
- },
- "application/set-payment": {
- "source": "iana"
- },
- "application/set-payment-initiation": {
- "source": "iana",
- "extensions": ["setpay"]
- },
- "application/set-registration": {
- "source": "iana"
- },
- "application/set-registration-initiation": {
- "source": "iana",
- "extensions": ["setreg"]
- },
- "application/sgml": {
- "source": "iana"
- },
- "application/sgml-open-catalog": {
- "source": "iana"
- },
- "application/shf+xml": {
- "source": "iana",
- "extensions": ["shf"]
- },
- "application/sieve": {
- "source": "iana"
- },
- "application/simple-filter+xml": {
- "source": "iana"
- },
- "application/simple-message-summary": {
- "source": "iana"
- },
- "application/simplesymbolcontainer": {
- "source": "iana"
- },
- "application/slate": {
- "source": "iana"
- },
- "application/smil": {
- "source": "iana"
- },
- "application/smil+xml": {
- "source": "iana",
- "extensions": ["smi","smil"]
- },
- "application/smpte336m": {
- "source": "iana"
- },
- "application/soap+fastinfoset": {
- "source": "iana"
- },
- "application/soap+xml": {
- "source": "iana",
- "compressible": true
- },
- "application/sparql-query": {
- "source": "iana",
- "extensions": ["rq"]
- },
- "application/sparql-results+xml": {
- "source": "iana",
- "extensions": ["srx"]
- },
- "application/spirits-event+xml": {
- "source": "iana"
- },
- "application/sql": {
- "source": "iana"
- },
- "application/srgs": {
- "source": "iana",
- "extensions": ["gram"]
- },
- "application/srgs+xml": {
- "source": "iana",
- "extensions": ["grxml"]
- },
- "application/sru+xml": {
- "source": "iana",
- "extensions": ["sru"]
- },
- "application/ssdl+xml": {
- "source": "apache",
- "extensions": ["ssdl"]
- },
- "application/ssml+xml": {
- "source": "iana",
- "extensions": ["ssml"]
- },
- "application/tamp-apex-update": {
- "source": "iana"
- },
- "application/tamp-apex-update-confirm": {
- "source": "iana"
- },
- "application/tamp-community-update": {
- "source": "iana"
- },
- "application/tamp-community-update-confirm": {
- "source": "iana"
- },
- "application/tamp-error": {
- "source": "iana"
- },
- "application/tamp-sequence-adjust": {
- "source": "iana"
- },
- "application/tamp-sequence-adjust-confirm": {
- "source": "iana"
- },
- "application/tamp-status-query": {
- "source": "iana"
- },
- "application/tamp-status-response": {
- "source": "iana"
- },
- "application/tamp-update": {
- "source": "iana"
- },
- "application/tamp-update-confirm": {
- "source": "iana"
- },
- "application/tar": {
- "compressible": true
- },
- "application/tei+xml": {
- "source": "iana",
- "extensions": ["tei","teicorpus"]
- },
- "application/thraud+xml": {
- "source": "iana",
- "extensions": ["tfi"]
- },
- "application/timestamp-query": {
- "source": "iana"
- },
- "application/timestamp-reply": {
- "source": "iana"
- },
- "application/timestamped-data": {
- "source": "iana",
- "extensions": ["tsd"]
- },
- "application/ttml+xml": {
- "source": "iana"
- },
- "application/tve-trigger": {
- "source": "iana"
- },
- "application/ulpfec": {
- "source": "iana"
- },
- "application/urc-grpsheet+xml": {
- "source": "iana"
- },
- "application/urc-ressheet+xml": {
- "source": "iana"
- },
- "application/urc-targetdesc+xml": {
- "source": "iana"
- },
- "application/urc-uisocketdesc+xml": {
- "source": "iana"
- },
- "application/vcard+json": {
- "source": "iana",
- "compressible": true
- },
- "application/vcard+xml": {
- "source": "iana"
- },
- "application/vemmi": {
- "source": "iana"
- },
- "application/vividence.scriptfile": {
- "source": "apache"
- },
- "application/vnd-acucobol": {
- "source": "iana"
- },
- "application/vnd-curl": {
- "source": "iana"
- },
- "application/vnd-dart": {
- "source": "iana"
- },
- "application/vnd-dxr": {
- "source": "iana"
- },
- "application/vnd-fdf": {
- "source": "iana"
- },
- "application/vnd-mif": {
- "source": "iana"
- },
- "application/vnd-sema": {
- "source": "iana"
- },
- "application/vnd-wap-wmlc": {
- "source": "iana"
- },
- "application/vnd.3gpp.bsf+xml": {
- "source": "iana"
- },
- "application/vnd.3gpp.pic-bw-large": {
- "source": "iana",
- "extensions": ["plb"]
- },
- "application/vnd.3gpp.pic-bw-small": {
- "source": "iana",
- "extensions": ["psb"]
- },
- "application/vnd.3gpp.pic-bw-var": {
- "source": "iana",
- "extensions": ["pvb"]
- },
- "application/vnd.3gpp.sms": {
- "source": "iana"
- },
- "application/vnd.3gpp2.bcmcsinfo+xml": {
- "source": "iana"
- },
- "application/vnd.3gpp2.sms": {
- "source": "iana"
- },
- "application/vnd.3gpp2.tcap": {
- "source": "iana",
- "extensions": ["tcap"]
- },
- "application/vnd.3m.post-it-notes": {
- "source": "iana",
- "extensions": ["pwn"]
- },
- "application/vnd.accpac.simply.aso": {
- "source": "iana",
- "extensions": ["aso"]
- },
- "application/vnd.accpac.simply.imp": {
- "source": "iana",
- "extensions": ["imp"]
- },
- "application/vnd.acucobol": {
- "source": "apache",
- "extensions": ["acu"]
- },
- "application/vnd.acucorp": {
- "source": "iana",
- "extensions": ["atc","acutc"]
- },
- "application/vnd.adobe.air-application-installer-package+zip": {
- "source": "apache",
- "extensions": ["air"]
- },
- "application/vnd.adobe.flash-movie": {
- "source": "iana"
- },
- "application/vnd.adobe.formscentral.fcdt": {
- "source": "iana",
- "extensions": ["fcdt"]
- },
- "application/vnd.adobe.fxp": {
- "source": "iana",
- "extensions": ["fxp","fxpl"]
- },
- "application/vnd.adobe.partial-upload": {
- "source": "iana"
- },
- "application/vnd.adobe.xdp+xml": {
- "source": "iana",
- "extensions": ["xdp"]
- },
- "application/vnd.adobe.xfdf": {
- "source": "iana",
- "extensions": ["xfdf"]
- },
- "application/vnd.aether.imp": {
- "source": "iana"
- },
- "application/vnd.ah-barcode": {
- "source": "iana"
- },
- "application/vnd.ahead.space": {
- "source": "iana",
- "extensions": ["ahead"]
- },
- "application/vnd.airzip.filesecure.azf": {
- "source": "iana",
- "extensions": ["azf"]
- },
- "application/vnd.airzip.filesecure.azs": {
- "source": "iana",
- "extensions": ["azs"]
- },
- "application/vnd.amazon.ebook": {
- "source": "apache",
- "extensions": ["azw"]
- },
- "application/vnd.americandynamics.acc": {
- "source": "iana",
- "extensions": ["acc"]
- },
- "application/vnd.amiga.ami": {
- "source": "iana",
- "extensions": ["ami"]
- },
- "application/vnd.amundsen.maze+xml": {
- "source": "iana"
- },
- "application/vnd.android.package-archive": {
- "source": "apache",
- "compressible": false,
- "extensions": ["apk"]
- },
- "application/vnd.anser-web-certificate-issue-initiation": {
- "source": "iana",
- "extensions": ["cii"]
- },
- "application/vnd.anser-web-funds-transfer-initiation": {
- "source": "apache",
- "extensions": ["fti"]
- },
- "application/vnd.antix.game-component": {
- "source": "iana",
- "extensions": ["atx"]
- },
- "application/vnd.apache.thrift.binary": {
- "source": "iana"
- },
- "application/vnd.api+json": {
- "source": "iana",
- "compressible": true
- },
- "application/vnd.apple.installer+xml": {
- "source": "iana",
- "extensions": ["mpkg"]
- },
- "application/vnd.apple.mpegurl": {
- "source": "iana",
- "extensions": ["m3u8"]
- },
- "application/vnd.arastra.swi": {
- "source": "iana"
- },
- "application/vnd.aristanetworks.swi": {
- "source": "iana",
- "extensions": ["swi"]
- },
- "application/vnd.artsquare": {
- "source": "iana"
- },
- "application/vnd.astraea-software.iota": {
- "source": "iana",
- "extensions": ["iota"]
- },
- "application/vnd.audiograph": {
- "source": "iana",
- "extensions": ["aep"]
- },
- "application/vnd.autopackage": {
- "source": "iana"
- },
- "application/vnd.avistar+xml": {
- "source": "iana"
- },
- "application/vnd.balsamiq.bmml+xml": {
- "source": "iana"
- },
- "application/vnd.bekitzur-stech+json": {
- "source": "iana",
- "compressible": true
- },
- "application/vnd.blueice.multipass": {
- "source": "iana",
- "extensions": ["mpm"]
- },
- "application/vnd.bluetooth.ep.oob": {
- "source": "iana"
- },
- "application/vnd.bluetooth.le.oob": {
- "source": "iana"
- },
- "application/vnd.bmi": {
- "source": "iana",
- "extensions": ["bmi"]
- },
- "application/vnd.businessobjects": {
- "source": "iana",
- "extensions": ["rep"]
- },
- "application/vnd.cab-jscript": {
- "source": "iana"
- },
- "application/vnd.canon-cpdl": {
- "source": "iana"
- },
- "application/vnd.canon-lips": {
- "source": "iana"
- },
- "application/vnd.cendio.thinlinc.clientconf": {
- "source": "iana"
- },
- "application/vnd.century-systems.tcp_stream": {
- "source": "iana"
- },
- "application/vnd.chemdraw+xml": {
- "source": "iana",
- "extensions": ["cdxml"]
- },
- "application/vnd.chipnuts.karaoke-mmd": {
- "source": "iana",
- "extensions": ["mmd"]
- },
- "application/vnd.cinderella": {
- "source": "iana",
- "extensions": ["cdy"]
- },
- "application/vnd.cirpack.isdn-ext": {
- "source": "iana"
- },
- "application/vnd.claymore": {
- "source": "iana",
- "extensions": ["cla"]
- },
- "application/vnd.cloanto.rp9": {
- "source": "iana",
- "extensions": ["rp9"]
- },
- "application/vnd.clonk.c4group": {
- "source": "iana",
- "extensions": ["c4g","c4d","c4f","c4p","c4u"]
- },
- "application/vnd.cluetrust.cartomobile-config": {
- "source": "iana",
- "extensions": ["c11amc"]
- },
- "application/vnd.cluetrust.cartomobile-config-pkg": {
- "source": "iana",
- "extensions": ["c11amz"]
- },
- "application/vnd.collection+json": {
- "source": "iana",
- "compressible": true
- },
- "application/vnd.collection.doc+json": {
- "source": "iana",
- "compressible": true
- },
- "application/vnd.collection.next+json": {
- "source": "iana",
- "compressible": true
- },
- "application/vnd.commerce-battelle": {
- "source": "iana"
- },
- "application/vnd.commonspace": {
- "source": "iana",
- "extensions": ["csp"]
- },
- "application/vnd.contact.cmsg": {
- "source": "iana",
- "extensions": ["cdbcmsg"]
- },
- "application/vnd.cosmocaller": {
- "source": "iana",
- "extensions": ["cmc"]
- },
- "application/vnd.crick.clicker": {
- "source": "iana",
- "extensions": ["clkx"]
- },
- "application/vnd.crick.clicker.keyboard": {
- "source": "iana",
- "extensions": ["clkk"]
- },
- "application/vnd.crick.clicker.palette": {
- "source": "iana",
- "extensions": ["clkp"]
- },
- "application/vnd.crick.clicker.template": {
- "source": "iana",
- "extensions": ["clkt"]
- },
- "application/vnd.crick.clicker.wordbank": {
- "source": "iana",
- "extensions": ["clkw"]
- },
- "application/vnd.criticaltools.wbs+xml": {
- "source": "iana",
- "extensions": ["wbs"]
- },
- "application/vnd.ctc-posml": {
- "source": "iana",
- "extensions": ["pml"]
- },
- "application/vnd.ctct.ws+xml": {
- "source": "iana"
- },
- "application/vnd.cups-pdf": {
- "source": "iana"
- },
- "application/vnd.cups-postscript": {
- "source": "iana"
- },
- "application/vnd.cups-ppd": {
- "source": "iana",
- "extensions": ["ppd"]
- },
- "application/vnd.cups-raster": {
- "source": "iana"
- },
- "application/vnd.cups-raw": {
- "source": "iana"
- },
- "application/vnd.curl": {
- "source": "apache"
- },
- "application/vnd.curl.car": {
- "source": "apache",
- "extensions": ["car"]
- },
- "application/vnd.curl.pcurl": {
- "source": "apache",
- "extensions": ["pcurl"]
- },
- "application/vnd.cyan.dean.root+xml": {
- "source": "iana"
- },
- "application/vnd.cybank": {
- "source": "iana"
- },
- "application/vnd.dart": {
- "source": "apache",
- "compressible": true,
- "extensions": ["dart"]
- },
- "application/vnd.data-vision.rdz": {
- "source": "iana",
- "extensions": ["rdz"]
- },
- "application/vnd.debian.binary-package": {
- "source": "iana"
- },
- "application/vnd.dece-zip": {
- "source": "iana"
- },
- "application/vnd.dece.data": {
- "source": "iana",
- "extensions": ["uvf","uvvf","uvd","uvvd"]
- },
- "application/vnd.dece.ttml+xml": {
- "source": "iana",
- "extensions": ["uvt","uvvt"]
- },
- "application/vnd.dece.unspecified": {
- "source": "iana",
- "extensions": ["uvx","uvvx"]
- },
- "application/vnd.dece.zip": {
- "source": "apache",
- "extensions": ["uvz","uvvz"]
- },
- "application/vnd.denovo.fcselayout-link": {
- "source": "iana",
- "extensions": ["fe_launch"]
- },
- "application/vnd.desmume-movie": {
- "source": "iana"
- },
- "application/vnd.dir-bi.plate-dl-nosuffix": {
- "source": "iana"
- },
- "application/vnd.dm.delegation+xml": {
- "source": "iana"
- },
- "application/vnd.dna": {
- "source": "iana",
- "extensions": ["dna"]
- },
- "application/vnd.document+json": {
- "source": "iana",
- "compressible": true
- },
- "application/vnd.dolby.mlp": {
- "source": "apache",
- "extensions": ["mlp"]
- },
- "application/vnd.dolby.mobile.1": {
- "source": "iana"
- },
- "application/vnd.dolby.mobile.2": {
- "source": "iana"
- },
- "application/vnd.doremir.scorecloud-binary-document": {
- "source": "iana"
- },
- "application/vnd.dpgraph": {
- "source": "iana",
- "extensions": ["dpg"]
- },
- "application/vnd.dreamfactory": {
- "source": "iana",
- "extensions": ["dfac"]
- },
- "application/vnd.ds-keypoint": {
- "source": "apache",
- "extensions": ["kpxx"]
- },
- "application/vnd.dtg.local": {
- "source": "iana"
- },
- "application/vnd.dtg.local.flash": {
- "source": "iana"
- },
- "application/vnd.dtg.local.html": {
- "source": "iana"
- },
- "application/vnd.dvb.ait": {
- "source": "iana",
- "extensions": ["ait"]
- },
- "application/vnd.dvb.dvbj": {
- "source": "iana"
- },
- "application/vnd.dvb.esgcontainer": {
- "source": "iana"
- },
- "application/vnd.dvb.ipdcdftnotifaccess": {
- "source": "iana"
- },
- "application/vnd.dvb.ipdcesgaccess": {
- "source": "iana"
- },
- "application/vnd.dvb.ipdcesgaccess2": {
- "source": "iana"
- },
- "application/vnd.dvb.ipdcesgpdd": {
- "source": "iana"
- },
- "application/vnd.dvb.ipdcroaming": {
- "source": "iana"
- },
- "application/vnd.dvb.iptv.alfec-base": {
- "source": "iana"
- },
- "application/vnd.dvb.iptv.alfec-enhancement": {
- "source": "iana"
- },
- "application/vnd.dvb.notif-aggregate-root+xml": {
- "source": "iana"
- },
- "application/vnd.dvb.notif-container+xml": {
- "source": "iana"
- },
- "application/vnd.dvb.notif-generic+xml": {
- "source": "iana"
- },
- "application/vnd.dvb.notif-ia-msglist+xml": {
- "source": "iana"
- },
- "application/vnd.dvb.notif-ia-registration-request+xml": {
- "source": "iana"
- },
- "application/vnd.dvb.notif-ia-registration-response+xml": {
- "source": "iana"
- },
- "application/vnd.dvb.notif-init+xml": {
- "source": "iana"
- },
- "application/vnd.dvb.pfr": {
- "source": "iana"
- },
- "application/vnd.dvb.service": {
- "source": "apache",
- "extensions": ["svc"]
- },
- "application/vnd.dvb_service": {
- "source": "iana"
- },
- "application/vnd.dxr": {
- "source": "apache"
- },
- "application/vnd.dynageo": {
- "source": "iana",
- "extensions": ["geo"]
- },
- "application/vnd.dzr": {
- "source": "iana"
- },
- "application/vnd.easykaraoke.cdgdownload": {
- "source": "iana"
- },
- "application/vnd.ecdis-update": {
- "source": "iana"
- },
- "application/vnd.ecowin.chart": {
- "source": "iana",
- "extensions": ["mag"]
- },
- "application/vnd.ecowin.filerequest": {
- "source": "iana"
- },
- "application/vnd.ecowin.fileupdate": {
- "source": "iana"
- },
- "application/vnd.ecowin.series": {
- "source": "iana"
- },
- "application/vnd.ecowin.seriesrequest": {
- "source": "iana"
- },
- "application/vnd.ecowin.seriesupdate": {
- "source": "iana"
- },
- "application/vnd.emclient.accessrequest+xml": {
- "source": "iana"
- },
- "application/vnd.enliven": {
- "source": "iana",
- "extensions": ["nml"]
- },
- "application/vnd.eprints.data+xml": {
- "source": "iana"
- },
- "application/vnd.epson.esf": {
- "source": "iana",
- "extensions": ["esf"]
- },
- "application/vnd.epson.msf": {
- "source": "iana",
- "extensions": ["msf"]
- },
- "application/vnd.epson.quickanime": {
- "source": "iana",
- "extensions": ["qam"]
- },
- "application/vnd.epson.salt": {
- "source": "iana",
- "extensions": ["slt"]
- },
- "application/vnd.epson.ssf": {
- "source": "iana",
- "extensions": ["ssf"]
- },
- "application/vnd.ericsson.quickcall": {
- "source": "iana"
- },
- "application/vnd.eszigno3+xml": {
- "source": "iana",
- "extensions": ["es3","et3"]
- },
- "application/vnd.etsi.aoc+xml": {
- "source": "iana"
- },
- "application/vnd.etsi.asic-e+zip": {
- "source": "iana"
- },
- "application/vnd.etsi.asic-s+zip": {
- "source": "iana"
- },
- "application/vnd.etsi.cug+xml": {
- "source": "iana"
- },
- "application/vnd.etsi.iptvcommand+xml": {
- "source": "iana"
- },
- "application/vnd.etsi.iptvdiscovery+xml": {
- "source": "iana"
- },
- "application/vnd.etsi.iptvprofile+xml": {
- "source": "iana"
- },
- "application/vnd.etsi.iptvsad-bc+xml": {
- "source": "iana"
- },
- "application/vnd.etsi.iptvsad-cod+xml": {
- "source": "iana"
- },
- "application/vnd.etsi.iptvsad-npvr+xml": {
- "source": "iana"
- },
- "application/vnd.etsi.iptvservice+xml": {
- "source": "iana"
- },
- "application/vnd.etsi.iptvsync+xml": {
- "source": "iana"
- },
- "application/vnd.etsi.iptvueprofile+xml": {
- "source": "iana"
- },
- "application/vnd.etsi.mcid+xml": {
- "source": "iana"
- },
- "application/vnd.etsi.mheg5": {
- "source": "iana"
- },
- "application/vnd.etsi.overload-control-policy-dataset+xml": {
- "source": "iana"
- },
- "application/vnd.etsi.pstn+xml": {
- "source": "iana"
- },
- "application/vnd.etsi.sci+xml": {
- "source": "iana"
- },
- "application/vnd.etsi.simservs+xml": {
- "source": "iana"
- },
- "application/vnd.etsi.timestamp-token": {
- "source": "iana"
- },
- "application/vnd.etsi.tsl+xml": {
- "source": "iana"
- },
- "application/vnd.etsi.tsl.der": {
- "source": "iana"
- },
- "application/vnd.eudora.data": {
- "source": "iana"
- },
- "application/vnd.ezpix-album": {
- "source": "iana",
- "extensions": ["ez2"]
- },
- "application/vnd.ezpix-package": {
- "source": "iana",
- "extensions": ["ez3"]
- },
- "application/vnd.f-secure.mobile": {
- "source": "iana"
- },
- "application/vnd.fdf": {
- "source": "apache",
- "extensions": ["fdf"]
- },
- "application/vnd.fdsn.mseed": {
- "source": "iana",
- "extensions": ["mseed"]
- },
- "application/vnd.fdsn.seed": {
- "source": "iana",
- "extensions": ["seed","dataless"]
- },
- "application/vnd.ffsns": {
- "source": "iana"
- },
- "application/vnd.fints": {
- "source": "iana"
- },
- "application/vnd.flographit": {
- "source": "iana",
- "extensions": ["gph"]
- },
- "application/vnd.fluxtime.clip": {
- "source": "iana",
- "extensions": ["ftc"]
- },
- "application/vnd.font-fontforge-sfd": {
- "source": "iana"
- },
- "application/vnd.framemaker": {
- "source": "iana",
- "extensions": ["fm","frame","maker","book"]
- },
- "application/vnd.frogans.fnc": {
- "source": "iana",
- "extensions": ["fnc"]
- },
- "application/vnd.frogans.ltf": {
- "source": "iana",
- "extensions": ["ltf"]
- },
- "application/vnd.fsc.weblaunch": {
- "source": "iana",
- "extensions": ["fsc"]
- },
- "application/vnd.fujitsu.oasys": {
- "source": "iana",
- "extensions": ["oas"]
- },
- "application/vnd.fujitsu.oasys2": {
- "source": "iana",
- "extensions": ["oa2"]
- },
- "application/vnd.fujitsu.oasys3": {
- "source": "iana",
- "extensions": ["oa3"]
- },
- "application/vnd.fujitsu.oasysgp": {
- "source": "iana",
- "extensions": ["fg5"]
- },
- "application/vnd.fujitsu.oasysprs": {
- "source": "iana",
- "extensions": ["bh2"]
- },
- "application/vnd.fujixerox.art-ex": {
- "source": "iana"
- },
- "application/vnd.fujixerox.art4": {
- "source": "iana"
- },
- "application/vnd.fujixerox.ddd": {
- "source": "iana",
- "extensions": ["ddd"]
- },
- "application/vnd.fujixerox.docuworks": {
- "source": "iana",
- "extensions": ["xdw"]
- },
- "application/vnd.fujixerox.docuworks.binder": {
- "source": "iana",
- "extensions": ["xbd"]
- },
- "application/vnd.fujixerox.docuworks.container": {
- "source": "iana"
- },
- "application/vnd.fujixerox.hbpl": {
- "source": "iana"
- },
- "application/vnd.fut-misnet": {
- "source": "iana"
- },
- "application/vnd.fuzzysheet": {
- "source": "iana",
- "extensions": ["fzs"]
- },
- "application/vnd.genomatix.tuxedo": {
- "source": "iana",
- "extensions": ["txd"]
- },
- "application/vnd.geo+json": {
- "source": "iana",
- "compressible": true
- },
- "application/vnd.geocube+xml": {
- "source": "iana"
- },
- "application/vnd.geogebra.file": {
- "source": "iana",
- "extensions": ["ggb"]
- },
- "application/vnd.geogebra.tool": {
- "source": "iana",
- "extensions": ["ggt"]
- },
- "application/vnd.geometry-explorer": {
- "source": "iana",
- "extensions": ["gex","gre"]
- },
- "application/vnd.geonext": {
- "source": "iana",
- "extensions": ["gxt"]
- },
- "application/vnd.geoplan": {
- "source": "iana",
- "extensions": ["g2w"]
- },
- "application/vnd.geospace": {
- "source": "iana",
- "extensions": ["g3w"]
- },
- "application/vnd.globalplatform.card-content-mgt": {
- "source": "iana"
- },
- "application/vnd.globalplatform.card-content-mgt-response": {
- "source": "iana"
- },
- "application/vnd.gmx": {
- "source": "iana",
- "extensions": ["gmx"]
- },
- "application/vnd.google-earth.kml+xml": {
- "source": "iana",
- "compressible": true,
- "extensions": ["kml"]
- },
- "application/vnd.google-earth.kmz": {
- "source": "iana",
- "compressible": false,
- "extensions": ["kmz"]
- },
- "application/vnd.grafeq": {
- "source": "iana",
- "extensions": ["gqf","gqs"]
- },
- "application/vnd.gridmp": {
- "source": "iana"
- },
- "application/vnd.groove-account": {
- "source": "iana",
- "extensions": ["gac"]
- },
- "application/vnd.groove-help": {
- "source": "iana",
- "extensions": ["ghf"]
- },
- "application/vnd.groove-identity-message": {
- "source": "iana",
- "extensions": ["gim"]
- },
- "application/vnd.groove-injector": {
- "source": "iana",
- "extensions": ["grv"]
- },
- "application/vnd.groove-tool-message": {
- "source": "iana",
- "extensions": ["gtm"]
- },
- "application/vnd.groove-tool-template": {
- "source": "iana",
- "extensions": ["tpl"]
- },
- "application/vnd.groove-vcard": {
- "source": "iana",
- "extensions": ["vcg"]
- },
- "application/vnd.hal+json": {
- "source": "iana",
- "compressible": true
- },
- "application/vnd.hal+xml": {
- "source": "iana",
- "extensions": ["hal"]
- },
- "application/vnd.handheld-entertainment+xml": {
- "source": "iana",
- "extensions": ["zmm"]
- },
- "application/vnd.hbci": {
- "source": "iana",
- "extensions": ["hbci"]
- },
- "application/vnd.hcl-bireports": {
- "source": "iana"
- },
- "application/vnd.heroku+json": {
- "source": "iana",
- "compressible": true
- },
- "application/vnd.hhe.lesson-player": {
- "source": "iana",
- "extensions": ["les"]
- },
- "application/vnd.hp-hpgl": {
- "source": "iana",
- "extensions": ["hpgl"]
- },
- "application/vnd.hp-hpid": {
- "source": "iana",
- "extensions": ["hpid"]
- },
- "application/vnd.hp-hps": {
- "source": "iana",
- "extensions": ["hps"]
- },
- "application/vnd.hp-jlyt": {
- "source": "iana",
- "extensions": ["jlt"]
- },
- "application/vnd.hp-pcl": {
- "source": "iana",
- "extensions": ["pcl"]
- },
- "application/vnd.hp-pclxl": {
- "source": "iana",
- "extensions": ["pclxl"]
- },
- "application/vnd.httphone": {
- "source": "iana"
- },
- "application/vnd.hydrostatix.sof-data": {
- "source": "iana"
- },
- "application/vnd.hzn-3d-crossword": {
- "source": "iana"
- },
- "application/vnd.ibm.afplinedata": {
- "source": "iana"
- },
- "application/vnd.ibm.electronic-media": {
- "source": "iana"
- },
- "application/vnd.ibm.minipay": {
- "source": "iana",
- "extensions": ["mpy"]
- },
- "application/vnd.ibm.modcap": {
- "source": "iana",
- "extensions": ["afp","listafp","list3820"]
- },
- "application/vnd.ibm.rights-management": {
- "source": "iana",
- "extensions": ["irm"]
- },
- "application/vnd.ibm.secure-container": {
- "source": "iana",
- "extensions": ["sc"]
- },
- "application/vnd.iccprofile": {
- "source": "iana",
- "extensions": ["icc","icm"]
- },
- "application/vnd.ieee.1905": {
- "source": "iana"
- },
- "application/vnd.igloader": {
- "source": "iana",
- "extensions": ["igl"]
- },
- "application/vnd.immervision-ivp": {
- "source": "iana",
- "extensions": ["ivp"]
- },
- "application/vnd.immervision-ivu": {
- "source": "iana",
- "extensions": ["ivu"]
- },
- "application/vnd.ims.lis.v2.result+json": {
- "source": "iana",
- "compressible": true
- },
- "application/vnd.ims.lti.v2.toolconsumerprofile+json": {
- "source": "iana",
- "compressible": true
- },
- "application/vnd.ims.lti.v2.toolproxy+json": {
- "source": "iana",
- "compressible": true
- },
- "application/vnd.ims.lti.v2.toolproxy.id+json": {
- "source": "iana",
- "compressible": true
- },
- "application/vnd.ims.lti.v2.toolsettings+json": {
- "source": "iana",
- "compressible": true
- },
- "application/vnd.ims.lti.v2.toolsettings.simple+json": {
- "source": "iana",
- "compressible": true
- },
- "application/vnd.informedcontrol.rms+xml": {
- "source": "iana"
- },
- "application/vnd.informix-visionary": {
- "source": "iana"
- },
- "application/vnd.infotech.project": {
- "source": "iana"
- },
- "application/vnd.infotech.project+xml": {
- "source": "iana"
- },
- "application/vnd.innopath.wamp.notification": {
- "source": "iana"
- },
- "application/vnd.insors.igm": {
- "source": "iana",
- "extensions": ["igm"]
- },
- "application/vnd.intercon.formnet": {
- "source": "iana",
- "extensions": ["xpw","xpx"]
- },
- "application/vnd.intergeo": {
- "source": "iana",
- "extensions": ["i2g"]
- },
- "application/vnd.intertrust.digibox": {
- "source": "iana"
- },
- "application/vnd.intertrust.nncp": {
- "source": "iana"
- },
- "application/vnd.intu.qbo": {
- "source": "iana",
- "extensions": ["qbo"]
- },
- "application/vnd.intu.qfx": {
- "source": "iana",
- "extensions": ["qfx"]
- },
- "application/vnd.iptc.g2.catalogitem+xml": {
- "source": "iana"
- },
- "application/vnd.iptc.g2.conceptitem+xml": {
- "source": "iana"
- },
- "application/vnd.iptc.g2.knowledgeitem+xml": {
- "source": "iana"
- },
- "application/vnd.iptc.g2.newsitem+xml": {
- "source": "iana"
- },
- "application/vnd.iptc.g2.newsmessage+xml": {
- "source": "iana"
- },
- "application/vnd.iptc.g2.packageitem+xml": {
- "source": "iana"
- },
- "application/vnd.iptc.g2.planningitem+xml": {
- "source": "iana"
- },
- "application/vnd.ipunplugged.rcprofile": {
- "source": "iana",
- "extensions": ["rcprofile"]
- },
- "application/vnd.irepository.package+xml": {
- "source": "iana",
- "extensions": ["irp"]
- },
- "application/vnd.is-xpr": {
- "source": "iana",
- "extensions": ["xpr"]
- },
- "application/vnd.isac.fcs": {
- "source": "iana",
- "extensions": ["fcs"]
- },
- "application/vnd.jam": {
- "source": "iana",
- "extensions": ["jam"]
- },
- "application/vnd.japannet-directory-service": {
- "source": "iana"
- },
- "application/vnd.japannet-jpnstore-wakeup": {
- "source": "iana"
- },
- "application/vnd.japannet-payment-wakeup": {
- "source": "iana"
- },
- "application/vnd.japannet-registration": {
- "source": "iana"
- },
- "application/vnd.japannet-registration-wakeup": {
- "source": "iana"
- },
- "application/vnd.japannet-setstore-wakeup": {
- "source": "iana"
- },
- "application/vnd.japannet-verification": {
- "source": "iana"
- },
- "application/vnd.japannet-verification-wakeup": {
- "source": "iana"
- },
- "application/vnd.jcp.javame.midlet-rms": {
- "source": "iana",
- "extensions": ["rms"]
- },
- "application/vnd.jisp": {
- "source": "iana",
- "extensions": ["jisp"]
- },
- "application/vnd.joost.joda-archive": {
- "source": "iana",
- "extensions": ["joda"]
- },
- "application/vnd.jsk.isdn-ngn": {
- "source": "iana"
- },
- "application/vnd.kahootz": {
- "source": "iana",
- "extensions": ["ktz","ktr"]
- },
- "application/vnd.kde.karbon": {
- "source": "iana",
- "extensions": ["karbon"]
- },
- "application/vnd.kde.kchart": {
- "source": "iana",
- "extensions": ["chrt"]
- },
- "application/vnd.kde.kformula": {
- "source": "iana",
- "extensions": ["kfo"]
- },
- "application/vnd.kde.kivio": {
- "source": "iana",
- "extensions": ["flw"]
- },
- "application/vnd.kde.kontour": {
- "source": "iana",
- "extensions": ["kon"]
- },
- "application/vnd.kde.kpresenter": {
- "source": "iana",
- "extensions": ["kpr","kpt"]
- },
- "application/vnd.kde.kspread": {
- "source": "iana",
- "extensions": ["ksp"]
- },
- "application/vnd.kde.kword": {
- "source": "iana",
- "extensions": ["kwd","kwt"]
- },
- "application/vnd.kenameaapp": {
- "source": "iana",
- "extensions": ["htke"]
- },
- "application/vnd.kidspiration": {
- "source": "iana",
- "extensions": ["kia"]
- },
- "application/vnd.kinar": {
- "source": "iana",
- "extensions": ["kne","knp"]
- },
- "application/vnd.koan": {
- "source": "iana",
- "extensions": ["skp","skd","skt","skm"]
- },
- "application/vnd.kodak-descriptor": {
- "source": "iana",
- "extensions": ["sse"]
- },
- "application/vnd.las.las+xml": {
- "source": "iana",
- "extensions": ["lasxml"]
- },
- "application/vnd.liberty-request+xml": {
- "source": "iana"
- },
- "application/vnd.llamagraphics.life-balance.desktop": {
- "source": "iana",
- "extensions": ["lbd"]
- },
- "application/vnd.llamagraphics.life-balance.exchange+xml": {
- "source": "iana",
- "extensions": ["lbe"]
- },
- "application/vnd.lotus-1-2-3": {
- "source": "iana",
- "extensions": ["123"]
- },
- "application/vnd.lotus-approach": {
- "source": "iana",
- "extensions": ["apr"]
- },
- "application/vnd.lotus-freelance": {
- "source": "iana",
- "extensions": ["pre"]
- },
- "application/vnd.lotus-notes": {
- "source": "iana",
- "extensions": ["nsf"]
- },
- "application/vnd.lotus-organizer": {
- "source": "iana",
- "extensions": ["org"]
- },
- "application/vnd.lotus-screencam": {
- "source": "iana",
- "extensions": ["scm"]
- },
- "application/vnd.lotus-wordpro": {
- "source": "iana",
- "extensions": ["lwp"]
- },
- "application/vnd.macports.portpkg": {
- "source": "iana",
- "extensions": ["portpkg"]
- },
- "application/vnd.marlin.drm.actiontoken+xml": {
- "source": "iana"
- },
- "application/vnd.marlin.drm.conftoken+xml": {
- "source": "iana"
- },
- "application/vnd.marlin.drm.license+xml": {
- "source": "iana"
- },
- "application/vnd.marlin.drm.mdcf": {
- "source": "iana"
- },
- "application/vnd.mason+json": {
- "source": "iana",
- "compressible": true
- },
- "application/vnd.maxmind.maxmind-db": {
- "source": "iana"
- },
- "application/vnd.mcd": {
- "source": "iana",
- "extensions": ["mcd"]
- },
- "application/vnd.medcalcdata": {
- "source": "iana",
- "extensions": ["mc1"]
- },
- "application/vnd.mediastation.cdkey": {
- "source": "iana",
- "extensions": ["cdkey"]
- },
- "application/vnd.meridian-slingshot": {
- "source": "iana"
- },
- "application/vnd.mfer": {
- "source": "iana",
- "extensions": ["mwf"]
- },
- "application/vnd.mfmp": {
- "source": "iana",
- "extensions": ["mfm"]
- },
- "application/vnd.micrografx-igx": {
- "source": "iana"
- },
- "application/vnd.micrografx.flo": {
- "source": "iana",
- "extensions": ["flo"]
- },
- "application/vnd.micrografx.igx": {
- "source": "apache",
- "extensions": ["igx"]
- },
- "application/vnd.miele+json": {
- "source": "iana",
- "compressible": true
- },
- "application/vnd.mif": {
- "source": "apache",
- "extensions": ["mif"]
- },
- "application/vnd.minisoft-hp3000-save": {
- "source": "iana"
- },
- "application/vnd.mitsubishi.misty-guard.trustweb": {
- "source": "iana"
- },
- "application/vnd.mobius.daf": {
- "source": "iana",
- "extensions": ["daf"]
- },
- "application/vnd.mobius.dis": {
- "source": "iana",
- "extensions": ["dis"]
- },
- "application/vnd.mobius.mbk": {
- "source": "iana",
- "extensions": ["mbk"]
- },
- "application/vnd.mobius.mqy": {
- "source": "iana",
- "extensions": ["mqy"]
- },
- "application/vnd.mobius.msl": {
- "source": "iana",
- "extensions": ["msl"]
- },
- "application/vnd.mobius.plc": {
- "source": "iana",
- "extensions": ["plc"]
- },
- "application/vnd.mobius.txf": {
- "source": "iana",
- "extensions": ["txf"]
- },
- "application/vnd.mophun.application": {
- "source": "iana",
- "extensions": ["mpn"]
- },
- "application/vnd.mophun.certificate": {
- "source": "iana",
- "extensions": ["mpc"]
- },
- "application/vnd.motorola.flexsuite": {
- "source": "iana"
- },
- "application/vnd.motorola.flexsuite.adsi": {
- "source": "iana"
- },
- "application/vnd.motorola.flexsuite.fis": {
- "source": "iana"
- },
- "application/vnd.motorola.flexsuite.gotap": {
- "source": "iana"
- },
- "application/vnd.motorola.flexsuite.kmr": {
- "source": "iana"
- },
- "application/vnd.motorola.flexsuite.ttc": {
- "source": "iana"
- },
- "application/vnd.motorola.flexsuite.wem": {
- "source": "iana"
- },
- "application/vnd.motorola.iprm": {
- "source": "iana"
- },
- "application/vnd.mozilla.xul+xml": {
- "source": "iana",
- "compressible": true,
- "extensions": ["xul"]
- },
- "application/vnd.ms-3mfdocument": {
- "source": "iana"
- },
- "application/vnd.ms-artgalry": {
- "source": "iana",
- "extensions": ["cil"]
- },
- "application/vnd.ms-asf": {
- "source": "iana"
- },
- "application/vnd.ms-cab-compressed": {
- "source": "iana",
- "extensions": ["cab"]
- },
- "application/vnd.ms-color.iccprofile": {
- "source": "apache"
- },
- "application/vnd.ms-excel": {
- "source": "iana",
- "compressible": false,
- "extensions": ["xls","xlm","xla","xlc","xlt","xlw"]
- },
- "application/vnd.ms-excel.addin.macroenabled.12": {
- "source": "iana",
- "extensions": ["xlam"]
- },
- "application/vnd.ms-excel.sheet.binary.macroenabled.12": {
- "source": "iana",
- "extensions": ["xlsb"]
- },
- "application/vnd.ms-excel.sheet.macroenabled.12": {
- "source": "iana",
- "extensions": ["xlsm"]
- },
- "application/vnd.ms-excel.template.macroenabled.12": {
- "source": "iana",
- "extensions": ["xltm"]
- },
- "application/vnd.ms-fontobject": {
- "source": "iana",
- "compressible": true,
- "extensions": ["eot"]
- },
- "application/vnd.ms-htmlhelp": {
- "source": "iana",
- "extensions": ["chm"]
- },
- "application/vnd.ms-ims": {
- "source": "iana",
- "extensions": ["ims"]
- },
- "application/vnd.ms-lrm": {
- "source": "iana",
- "extensions": ["lrm"]
- },
- "application/vnd.ms-office.activex+xml": {
- "source": "iana"
- },
- "application/vnd.ms-officetheme": {
- "source": "iana",
- "extensions": ["thmx"]
- },
- "application/vnd.ms-opentype": {
- "source": "apache",
- "compressible": true
- },
- "application/vnd.ms-package.obfuscated-opentype": {
- "source": "apache"
- },
- "application/vnd.ms-pki.seccat": {
- "source": "apache",
- "extensions": ["cat"]
- },
- "application/vnd.ms-pki.stl": {
- "source": "apache",
- "extensions": ["stl"]
- },
- "application/vnd.ms-playready.initiator+xml": {
- "source": "iana"
- },
- "application/vnd.ms-powerpoint": {
- "source": "iana",
- "compressible": false,
- "extensions": ["ppt","pps","pot"]
- },
- "application/vnd.ms-powerpoint.addin.macroenabled.12": {
- "source": "iana",
- "extensions": ["ppam"]
- },
- "application/vnd.ms-powerpoint.presentation.macroenabled.12": {
- "source": "iana",
- "extensions": ["pptm"]
- },
- "application/vnd.ms-powerpoint.slide.macroenabled.12": {
- "source": "iana",
- "extensions": ["sldm"]
- },
- "application/vnd.ms-powerpoint.slideshow.macroenabled.12": {
- "source": "iana",
- "extensions": ["ppsm"]
- },
- "application/vnd.ms-powerpoint.template.macroenabled.12": {
- "source": "iana",
- "extensions": ["potm"]
- },
- "application/vnd.ms-printing.printticket+xml": {
- "source": "apache"
- },
- "application/vnd.ms-project": {
- "source": "iana",
- "extensions": ["mpp","mpt"]
- },
- "application/vnd.ms-tnef": {
- "source": "iana"
- },
- "application/vnd.ms-windows.printerpairing": {
- "source": "iana"
- },
- "application/vnd.ms-wmdrm.lic-chlg-req": {
- "source": "iana"
- },
- "application/vnd.ms-wmdrm.lic-resp": {
- "source": "iana"
- },
- "application/vnd.ms-wmdrm.meter-chlg-req": {
- "source": "iana"
- },
- "application/vnd.ms-wmdrm.meter-resp": {
- "source": "iana"
- },
- "application/vnd.ms-word.document.macroenabled.12": {
- "source": "iana",
- "extensions": ["docm"]
- },
- "application/vnd.ms-word.template.macroenabled.12": {
- "source": "iana",
- "extensions": ["dotm"]
- },
- "application/vnd.ms-works": {
- "source": "iana",
- "extensions": ["wps","wks","wcm","wdb"]
- },
- "application/vnd.ms-wpl": {
- "source": "iana",
- "extensions": ["wpl"]
- },
- "application/vnd.ms-xpsdocument": {
- "source": "iana",
- "compressible": false,
- "extensions": ["xps"]
- },
- "application/vnd.mseq": {
- "source": "iana",
- "extensions": ["mseq"]
- },
- "application/vnd.msign": {
- "source": "iana"
- },
- "application/vnd.multiad.creator": {
- "source": "iana"
- },
- "application/vnd.multiad.creator.cif": {
- "source": "iana"
- },
- "application/vnd.music-niff": {
- "source": "iana"
- },
- "application/vnd.musician": {
- "source": "iana",
- "extensions": ["mus"]
- },
- "application/vnd.muvee.style": {
- "source": "iana",
- "extensions": ["msty"]
- },
- "application/vnd.mynfc": {
- "source": "iana",
- "extensions": ["taglet"]
- },
- "application/vnd.ncd.control": {
- "source": "iana"
- },
- "application/vnd.ncd.reference": {
- "source": "iana"
- },
- "application/vnd.nervana": {
- "source": "iana"
- },
- "application/vnd.netfpx": {
- "source": "iana"
- },
- "application/vnd.neurolanguage.nlu": {
- "source": "iana",
- "extensions": ["nlu"]
- },
- "application/vnd.nintendo.nitro.rom": {
- "source": "iana"
- },
- "application/vnd.nintendo.snes.rom": {
- "source": "iana"
- },
- "application/vnd.nitf": {
- "source": "iana",
- "extensions": ["ntf","nitf"]
- },
- "application/vnd.noblenet-directory": {
- "source": "iana",
- "extensions": ["nnd"]
- },
- "application/vnd.noblenet-sealer": {
- "source": "iana",
- "extensions": ["nns"]
- },
- "application/vnd.noblenet-web": {
- "source": "iana",
- "extensions": ["nnw"]
- },
- "application/vnd.nokia.catalogs": {
- "source": "iana"
- },
- "application/vnd.nokia.conml+wbxml": {
- "source": "iana"
- },
- "application/vnd.nokia.conml+xml": {
- "source": "iana"
- },
- "application/vnd.nokia.iptv.config+xml": {
- "source": "iana"
- },
- "application/vnd.nokia.isds-radio-presets": {
- "source": "iana"
- },
- "application/vnd.nokia.landmark+wbxml": {
- "source": "iana"
- },
- "application/vnd.nokia.landmark+xml": {
- "source": "iana"
- },
- "application/vnd.nokia.landmarkcollection+xml": {
- "source": "iana"
- },
- "application/vnd.nokia.n-gage.ac+xml": {
- "source": "iana"
- },
- "application/vnd.nokia.n-gage.data": {
- "source": "iana",
- "extensions": ["ngdat"]
- },
- "application/vnd.nokia.n-gage.symbian.install": {
- "source": "iana"
- },
- "application/vnd.nokia.ncd": {
- "source": "iana"
- },
- "application/vnd.nokia.pcd+wbxml": {
- "source": "iana"
- },
- "application/vnd.nokia.pcd+xml": {
- "source": "iana"
- },
- "application/vnd.nokia.radio-preset": {
- "source": "iana",
- "extensions": ["rpst"]
- },
- "application/vnd.nokia.radio-presets": {
- "source": "iana",
- "extensions": ["rpss"]
- },
- "application/vnd.novadigm.edm": {
- "source": "iana",
- "extensions": ["edm"]
- },
- "application/vnd.novadigm.edx": {
- "source": "iana",
- "extensions": ["edx"]
- },
- "application/vnd.novadigm.ext": {
- "source": "iana",
- "extensions": ["ext"]
- },
- "application/vnd.ntt-local.content-share": {
- "source": "iana"
- },
- "application/vnd.ntt-local.file-transfer": {
- "source": "iana"
- },
- "application/vnd.ntt-local.ogw_remote-access": {
- "source": "iana"
- },
- "application/vnd.ntt-local.sip-ta_remote": {
- "source": "iana"
- },
- "application/vnd.ntt-local.sip-ta_tcp_stream": {
- "source": "iana"
- },
- "application/vnd.oasis.opendocument.chart": {
- "source": "iana",
- "extensions": ["odc"]
- },
- "application/vnd.oasis.opendocument.chart-template": {
- "source": "iana",
- "extensions": ["otc"]
- },
- "application/vnd.oasis.opendocument.database": {
- "source": "iana",
- "extensions": ["odb"]
- },
- "application/vnd.oasis.opendocument.formula": {
- "source": "iana",
- "extensions": ["odf"]
- },
- "application/vnd.oasis.opendocument.formula-template": {
- "source": "iana",
- "extensions": ["odft"]
- },
- "application/vnd.oasis.opendocument.graphics": {
- "source": "iana",
- "compressible": false,
- "extensions": ["odg"]
- },
- "application/vnd.oasis.opendocument.graphics-template": {
- "source": "iana",
- "extensions": ["otg"]
- },
- "application/vnd.oasis.opendocument.image": {
- "source": "iana",
- "extensions": ["odi"]
- },
- "application/vnd.oasis.opendocument.image-template": {
- "source": "iana",
- "extensions": ["oti"]
- },
- "application/vnd.oasis.opendocument.presentation": {
- "source": "iana",
- "compressible": false,
- "extensions": ["odp"]
- },
- "application/vnd.oasis.opendocument.presentation-template": {
- "source": "iana",
- "extensions": ["otp"]
- },
- "application/vnd.oasis.opendocument.spreadsheet": {
- "source": "iana",
- "compressible": false,
- "extensions": ["ods"]
- },
- "application/vnd.oasis.opendocument.spreadsheet-template": {
- "source": "iana",
- "extensions": ["ots"]
- },
- "application/vnd.oasis.opendocument.text": {
- "source": "iana",
- "compressible": false,
- "extensions": ["odt"]
- },
- "application/vnd.oasis.opendocument.text-master": {
- "source": "iana",
- "extensions": ["odm"]
- },
- "application/vnd.oasis.opendocument.text-template": {
- "source": "iana",
- "extensions": ["ott"]
- },
- "application/vnd.oasis.opendocument.text-web": {
- "source": "iana",
- "extensions": ["oth"]
- },
- "application/vnd.obn": {
- "source": "iana"
- },
- "application/vnd.oftn.l10n+json": {
- "source": "iana",
- "compressible": true
- },
- "application/vnd.oipf.contentaccessdownload+xml": {
- "source": "iana"
- },
- "application/vnd.oipf.contentaccessstreaming+xml": {
- "source": "iana"
- },
- "application/vnd.oipf.cspg-hexbinary": {
- "source": "iana"
- },
- "application/vnd.oipf.dae.svg+xml": {
- "source": "iana"
- },
- "application/vnd.oipf.dae.xhtml+xml": {
- "source": "iana"
- },
- "application/vnd.oipf.mippvcontrolmessage+xml": {
- "source": "iana"
- },
- "application/vnd.oipf.pae.gem": {
- "source": "iana"
- },
- "application/vnd.oipf.spdiscovery+xml": {
- "source": "iana"
- },
- "application/vnd.oipf.spdlist+xml": {
- "source": "iana"
- },
- "application/vnd.oipf.ueprofile+xml": {
- "source": "iana"
- },
- "application/vnd.oipf.userprofile+xml": {
- "source": "iana"
- },
- "application/vnd.olpc-sugar": {
- "source": "iana",
- "extensions": ["xo"]
- },
- "application/vnd.oma-scws-config": {
- "source": "iana"
- },
- "application/vnd.oma-scws-http-request": {
- "source": "iana"
- },
- "application/vnd.oma-scws-http-response": {
- "source": "iana"
- },
- "application/vnd.oma.bcast.associated-procedure-parameter+xml": {
- "source": "iana"
- },
- "application/vnd.oma.bcast.drm-trigger+xml": {
- "source": "iana"
- },
- "application/vnd.oma.bcast.imd+xml": {
- "source": "iana"
- },
- "application/vnd.oma.bcast.ltkm": {
- "source": "iana"
- },
- "application/vnd.oma.bcast.notification+xml": {
- "source": "iana"
- },
- "application/vnd.oma.bcast.provisioningtrigger": {
- "source": "iana"
- },
- "application/vnd.oma.bcast.sgboot": {
- "source": "iana"
- },
- "application/vnd.oma.bcast.sgdd+xml": {
- "source": "iana"
- },
- "application/vnd.oma.bcast.sgdu": {
- "source": "iana"
- },
- "application/vnd.oma.bcast.simple-symbol-container": {
- "source": "iana"
- },
- "application/vnd.oma.bcast.smartcard-trigger+xml": {
- "source": "iana"
- },
- "application/vnd.oma.bcast.sprov+xml": {
- "source": "iana"
- },
- "application/vnd.oma.bcast.stkm": {
- "source": "iana"
- },
- "application/vnd.oma.cab-address-book+xml": {
- "source": "iana"
- },
- "application/vnd.oma.cab-feature-handler+xml": {
- "source": "iana"
- },
- "application/vnd.oma.cab-pcc+xml": {
- "source": "iana"
- },
- "application/vnd.oma.cab-subs-invite+xml": {
- "source": "iana"
- },
- "application/vnd.oma.cab-user-prefs+xml": {
- "source": "iana"
- },
- "application/vnd.oma.dcd": {
- "source": "iana"
- },
- "application/vnd.oma.dcdc": {
- "source": "iana"
- },
- "application/vnd.oma.dd2+xml": {
- "source": "iana",
- "extensions": ["dd2"]
- },
- "application/vnd.oma.drm.risd+xml": {
- "source": "iana"
- },
- "application/vnd.oma.group-usage-list+xml": {
- "source": "iana"
- },
- "application/vnd.oma.pal+xml": {
- "source": "iana"
- },
- "application/vnd.oma.poc.detailed-progress-report+xml": {
- "source": "iana"
- },
- "application/vnd.oma.poc.final-report+xml": {
- "source": "iana"
- },
- "application/vnd.oma.poc.groups+xml": {
- "source": "iana"
- },
- "application/vnd.oma.poc.invocation-descriptor+xml": {
- "source": "iana"
- },
- "application/vnd.oma.poc.optimized-progress-report+xml": {
- "source": "iana"
- },
- "application/vnd.oma.push": {
- "source": "iana"
- },
- "application/vnd.oma.scidm.messages+xml": {
- "source": "iana"
- },
- "application/vnd.oma.xcap-directory+xml": {
- "source": "iana"
- },
- "application/vnd.omads-email+xml": {
- "source": "iana"
- },
- "application/vnd.omads-file+xml": {
- "source": "iana"
- },
- "application/vnd.omads-folder+xml": {
- "source": "iana"
- },
- "application/vnd.omaloc-supl-init": {
- "source": "iana"
- },
- "application/vnd.openeye.oeb": {
- "source": "iana"
- },
- "application/vnd.openofficeorg.extension": {
- "source": "apache",
- "extensions": ["oxt"]
- },
- "application/vnd.openxmlformats-officedocument.custom-properties+xml": {
- "source": "iana"
- },
- "application/vnd.openxmlformats-officedocument.customxmlproperties+xml": {
- "source": "iana"
- },
- "application/vnd.openxmlformats-officedocument.drawing+xml": {
- "source": "iana"
- },
- "application/vnd.openxmlformats-officedocument.drawingml.chart+xml": {
- "source": "iana"
- },
- "application/vnd.openxmlformats-officedocument.drawingml.chartshapes+xml": {
- "source": "iana"
- },
- "application/vnd.openxmlformats-officedocument.drawingml.diagramcolors+xml": {
- "source": "iana"
- },
- "application/vnd.openxmlformats-officedocument.drawingml.diagramdata+xml": {
- "source": "iana"
- },
- "application/vnd.openxmlformats-officedocument.drawingml.diagramlayout+xml": {
- "source": "iana"
- },
- "application/vnd.openxmlformats-officedocument.drawingml.diagramstyle+xml": {
- "source": "iana"
- },
- "application/vnd.openxmlformats-officedocument.extended-properties+xml": {
- "source": "iana"
- },
- "application/vnd.openxmlformats-officedocument.presentationml-template": {
- "source": "iana"
- },
- "application/vnd.openxmlformats-officedocument.presentationml.commentauthors+xml": {
- "source": "iana"
- },
- "application/vnd.openxmlformats-officedocument.presentationml.comments+xml": {
- "source": "iana"
- },
- "application/vnd.openxmlformats-officedocument.presentationml.handoutmaster+xml": {
- "source": "iana"
- },
- "application/vnd.openxmlformats-officedocument.presentationml.notesmaster+xml": {
- "source": "iana"
- },
- "application/vnd.openxmlformats-officedocument.presentationml.notesslide+xml": {
- "source": "iana"
- },
- "application/vnd.openxmlformats-officedocument.presentationml.presentation": {
- "source": "iana",
- "compressible": false,
- "extensions": ["pptx"]
- },
- "application/vnd.openxmlformats-officedocument.presentationml.presentation.main+xml": {
- "source": "iana"
- },
- "application/vnd.openxmlformats-officedocument.presentationml.presprops+xml": {
- "source": "iana"
- },
- "application/vnd.openxmlformats-officedocument.presentationml.slide": {
- "source": "iana",
- "extensions": ["sldx"]
- },
- "application/vnd.openxmlformats-officedocument.presentationml.slide+xml": {
- "source": "iana"
- },
- "application/vnd.openxmlformats-officedocument.presentationml.slidelayout+xml": {
- "source": "iana"
- },
- "application/vnd.openxmlformats-officedocument.presentationml.slidemaster+xml": {
- "source": "iana"
- },
- "application/vnd.openxmlformats-officedocument.presentationml.slideshow": {
- "source": "iana",
- "extensions": ["ppsx"]
- },
- "application/vnd.openxmlformats-officedocument.presentationml.slideshow.main+xml": {
- "source": "iana"
- },
- "application/vnd.openxmlformats-officedocument.presentationml.slideupdateinfo+xml": {
- "source": "iana"
- },
- "application/vnd.openxmlformats-officedocument.presentationml.tablestyles+xml": {
- "source": "iana"
- },
- "application/vnd.openxmlformats-officedocument.presentationml.tags+xml": {
- "source": "iana"
- },
- "application/vnd.openxmlformats-officedocument.presentationml.template": {
- "source": "apache",
- "extensions": ["potx"]
- },
- "application/vnd.openxmlformats-officedocument.presentationml.template.main+xml": {
- "source": "iana"
- },
- "application/vnd.openxmlformats-officedocument.presentationml.viewprops+xml": {
- "source": "iana"
- },
- "application/vnd.openxmlformats-officedocument.spreadsheetml-template": {
- "source": "iana"
- },
- "application/vnd.openxmlformats-officedocument.spreadsheetml.calcchain+xml": {
- "source": "iana"
- },
- "application/vnd.openxmlformats-officedocument.spreadsheetml.chartsheet+xml": {
- "source": "iana"
- },
- "application/vnd.openxmlformats-officedocument.spreadsheetml.comments+xml": {
- "source": "iana"
- },
- "application/vnd.openxmlformats-officedocument.spreadsheetml.connections+xml": {
- "source": "iana"
- },
- "application/vnd.openxmlformats-officedocument.spreadsheetml.dialogsheet+xml": {
- "source": "iana"
- },
- "application/vnd.openxmlformats-officedocument.spreadsheetml.externallink+xml": {
- "source": "iana"
- },
- "application/vnd.openxmlformats-officedocument.spreadsheetml.pivotcachedefinition+xml": {
- "source": "iana"
- },
- "application/vnd.openxmlformats-officedocument.spreadsheetml.pivotcacherecords+xml": {
- "source": "iana"
- },
- "application/vnd.openxmlformats-officedocument.spreadsheetml.pivottable+xml": {
- "source": "iana"
- },
- "application/vnd.openxmlformats-officedocument.spreadsheetml.querytable+xml": {
- "source": "iana"
- },
- "application/vnd.openxmlformats-officedocument.spreadsheetml.revisionheaders+xml": {
- "source": "iana"
- },
- "application/vnd.openxmlformats-officedocument.spreadsheetml.revisionlog+xml": {
- "source": "iana"
- },
- "application/vnd.openxmlformats-officedocument.spreadsheetml.sharedstrings+xml": {
- "source": "iana"
- },
- "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet": {
- "source": "iana",
- "compressible": false,
- "extensions": ["xlsx"]
- },
- "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet.main+xml": {
- "source": "iana"
- },
- "application/vnd.openxmlformats-officedocument.spreadsheetml.sheetmetadata+xml": {
- "source": "iana"
- },
- "application/vnd.openxmlformats-officedocument.spreadsheetml.styles+xml": {
- "source": "iana"
- },
- "application/vnd.openxmlformats-officedocument.spreadsheetml.table+xml": {
- "source": "iana"
- },
- "application/vnd.openxmlformats-officedocument.spreadsheetml.tablesinglecells+xml": {
- "source": "iana"
- },
- "application/vnd.openxmlformats-officedocument.spreadsheetml.template": {
- "source": "apache",
- "extensions": ["xltx"]
- },
- "application/vnd.openxmlformats-officedocument.spreadsheetml.template.main+xml": {
- "source": "iana"
- },
- "application/vnd.openxmlformats-officedocument.spreadsheetml.usernames+xml": {
- "source": "iana"
- },
- "application/vnd.openxmlformats-officedocument.spreadsheetml.volatiledependencies+xml": {
- "source": "iana"
- },
- "application/vnd.openxmlformats-officedocument.spreadsheetml.worksheet+xml": {
- "source": "iana"
- },
- "application/vnd.openxmlformats-officedocument.theme+xml": {
- "source": "iana"
- },
- "application/vnd.openxmlformats-officedocument.themeoverride+xml": {
- "source": "iana"
- },
- "application/vnd.openxmlformats-officedocument.vmldrawing": {
- "source": "iana"
- },
- "application/vnd.openxmlformats-officedocument.wordprocessingml-template": {
- "source": "iana"
- },
- "application/vnd.openxmlformats-officedocument.wordprocessingml.comments+xml": {
- "source": "iana"
- },
- "application/vnd.openxmlformats-officedocument.wordprocessingml.document": {
- "source": "iana",
- "compressible": false,
- "extensions": ["docx"]
- },
- "application/vnd.openxmlformats-officedocument.wordprocessingml.document.glossary+xml": {
- "source": "iana"
- },
- "application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml": {
- "source": "iana"
- },
- "application/vnd.openxmlformats-officedocument.wordprocessingml.endnotes+xml": {
- "source": "iana"
- },
- "application/vnd.openxmlformats-officedocument.wordprocessingml.fonttable+xml": {
- "source": "iana"
- },
- "application/vnd.openxmlformats-officedocument.wordprocessingml.footer+xml": {
- "source": "iana"
- },
- "application/vnd.openxmlformats-officedocument.wordprocessingml.footnotes+xml": {
- "source": "iana"
- },
- "application/vnd.openxmlformats-officedocument.wordprocessingml.numbering+xml": {
- "source": "iana"
- },
- "application/vnd.openxmlformats-officedocument.wordprocessingml.settings+xml": {
- "source": "iana"
- },
- "application/vnd.openxmlformats-officedocument.wordprocessingml.styles+xml": {
- "source": "iana"
- },
- "application/vnd.openxmlformats-officedocument.wordprocessingml.template": {
- "source": "apache",
- "extensions": ["dotx"]
- },
- "application/vnd.openxmlformats-officedocument.wordprocessingml.template.main+xml": {
- "source": "iana"
- },
- "application/vnd.openxmlformats-officedocument.wordprocessingml.websettings+xml": {
- "source": "iana"
- },
- "application/vnd.openxmlformats-package.core-properties+xml": {
- "source": "iana"
- },
- "application/vnd.openxmlformats-package.digital-signature-xmlsignature+xml": {
- "source": "iana"
- },
- "application/vnd.openxmlformats-package.relationships+xml": {
- "source": "iana"
- },
- "application/vnd.orange.indata": {
- "source": "iana"
- },
- "application/vnd.osa.netdeploy": {
- "source": "iana"
- },
- "application/vnd.osgeo.mapguide.package": {
- "source": "iana",
- "extensions": ["mgp"]
- },
- "application/vnd.osgi.bundle": {
- "source": "iana"
- },
- "application/vnd.osgi.dp": {
- "source": "iana",
- "extensions": ["dp"]
- },
- "application/vnd.osgi.subsystem": {
- "source": "iana",
- "extensions": ["esa"]
- },
- "application/vnd.otps.ct-kip+xml": {
- "source": "iana"
- },
- "application/vnd.palm": {
- "source": "iana",
- "extensions": ["pdb","pqa","oprc"]
- },
- "application/vnd.panoply": {
- "source": "iana"
- },
- "application/vnd.paos+xml": {
- "source": "iana"
- },
- "application/vnd.paos.xml": {
- "source": "apache"
- },
- "application/vnd.pawaafile": {
- "source": "iana",
- "extensions": ["paw"]
- },
- "application/vnd.pcos": {
- "source": "iana"
- },
- "application/vnd.pg.format": {
- "source": "iana",
- "extensions": ["str"]
- },
- "application/vnd.pg.osasli": {
- "source": "iana",
- "extensions": ["ei6"]
- },
- "application/vnd.piaccess.application-licence": {
- "source": "iana"
- },
- "application/vnd.picsel": {
- "source": "iana",
- "extensions": ["efif"]
- },
- "application/vnd.pmi.widget": {
- "source": "iana",
- "extensions": ["wg"]
- },
- "application/vnd.poc.group-advertisement+xml": {
- "source": "iana"
- },
- "application/vnd.pocketlearn": {
- "source": "iana",
- "extensions": ["plf"]
- },
- "application/vnd.powerbuilder6": {
- "source": "iana",
- "extensions": ["pbd"]
- },
- "application/vnd.powerbuilder6-s": {
- "source": "iana"
- },
- "application/vnd.powerbuilder7": {
- "source": "iana"
- },
- "application/vnd.powerbuilder7-s": {
- "source": "iana"
- },
- "application/vnd.powerbuilder75": {
- "source": "iana"
- },
- "application/vnd.powerbuilder75-s": {
- "source": "iana"
- },
- "application/vnd.preminet": {
- "source": "iana"
- },
- "application/vnd.previewsystems.box": {
- "source": "iana",
- "extensions": ["box"]
- },
- "application/vnd.proteus.magazine": {
- "source": "iana",
- "extensions": ["mgz"]
- },
- "application/vnd.publishare-delta-tree": {
- "source": "iana",
- "extensions": ["qps"]
- },
- "application/vnd.pvi.ptid1": {
- "source": "iana",
- "extensions": ["ptid"]
- },
- "application/vnd.pwg-multiplexed": {
- "source": "apache"
- },
- "application/vnd.pwg-xhtml-print+xml": {
- "source": "iana"
- },
- "application/vnd.qualcomm.brew-app-res": {
- "source": "iana"
- },
- "application/vnd.quark.quarkxpress": {
- "source": "iana",
- "extensions": ["qxd","qxt","qwd","qwt","qxl","qxb"]
- },
- "application/vnd.quobject-quoxdocument": {
- "source": "iana"
- },
- "application/vnd.radisys.moml+xml": {
- "source": "iana"
- },
- "application/vnd.radisys.msml+xml": {
- "source": "iana"
- },
- "application/vnd.radisys.msml-audit+xml": {
- "source": "iana"
- },
- "application/vnd.radisys.msml-audit-conf+xml": {
- "source": "iana"
- },
- "application/vnd.radisys.msml-audit-conn+xml": {
- "source": "iana"
- },
- "application/vnd.radisys.msml-audit-dialog+xml": {
- "source": "iana"
- },
- "application/vnd.radisys.msml-audit-stream+xml": {
- "source": "iana"
- },
- "application/vnd.radisys.msml-conf+xml": {
- "source": "iana"
- },
- "application/vnd.radisys.msml-dialog+xml": {
- "source": "iana"
- },
- "application/vnd.radisys.msml-dialog-base+xml": {
- "source": "iana"
- },
- "application/vnd.radisys.msml-dialog-fax-detect+xml": {
- "source": "iana"
- },
- "application/vnd.radisys.msml-dialog-fax-sendrecv+xml": {
- "source": "iana"
- },
- "application/vnd.radisys.msml-dialog-group+xml": {
- "source": "iana"
- },
- "application/vnd.radisys.msml-dialog-speech+xml": {
- "source": "iana"
- },
- "application/vnd.radisys.msml-dialog-transform+xml": {
- "source": "iana"
- },
- "application/vnd.rainstor.data": {
- "source": "iana"
- },
- "application/vnd.rapid": {
- "source": "iana"
- },
- "application/vnd.realvnc.bed": {
- "source": "iana",
- "extensions": ["bed"]
- },
- "application/vnd.recordare.musicxml": {
- "source": "iana",
- "extensions": ["mxl"]
- },
- "application/vnd.recordare.musicxml+xml": {
- "source": "iana",
- "extensions": ["musicxml"]
- },
- "application/vnd.renlearn.rlprint": {
- "source": "iana"
- },
- "application/vnd.rig.cryptonote": {
- "source": "iana",
- "extensions": ["cryptonote"]
- },
- "application/vnd.rim.cod": {
- "source": "apache",
- "extensions": ["cod"]
- },
- "application/vnd.rn-realmedia": {
- "source": "apache",
- "extensions": ["rm"]
- },
- "application/vnd.rn-realmedia-vbr": {
- "source": "apache",
- "extensions": ["rmvb"]
- },
- "application/vnd.route66.link66+xml": {
- "source": "iana",
- "extensions": ["link66"]
- },
- "application/vnd.rs-274x": {
- "source": "iana"
- },
- "application/vnd.ruckus.download": {
- "source": "iana"
- },
- "application/vnd.s3sms": {
- "source": "iana"
- },
- "application/vnd.sailingtracker.track": {
- "source": "iana",
- "extensions": ["st"]
- },
- "application/vnd.sbm.cid": {
- "source": "iana"
- },
- "application/vnd.sbm.mid2": {
- "source": "iana"
- },
- "application/vnd.scribus": {
- "source": "iana"
- },
- "application/vnd.sealed-doc": {
- "source": "iana"
- },
- "application/vnd.sealed-eml": {
- "source": "iana"
- },
- "application/vnd.sealed-mht": {
- "source": "iana"
- },
- "application/vnd.sealed-ppt": {
- "source": "iana"
- },
- "application/vnd.sealed-tiff": {
- "source": "iana"
- },
- "application/vnd.sealed-xls": {
- "source": "iana"
- },
- "application/vnd.sealed.3df": {
- "source": "iana"
- },
- "application/vnd.sealed.csf": {
- "source": "iana"
- },
- "application/vnd.sealed.doc": {
- "source": "apache"
- },
- "application/vnd.sealed.eml": {
- "source": "apache"
- },
- "application/vnd.sealed.mht": {
- "source": "apache"
- },
- "application/vnd.sealed.net": {
- "source": "iana"
- },
- "application/vnd.sealed.ppt": {
- "source": "apache"
- },
- "application/vnd.sealed.tiff": {
- "source": "apache"
- },
- "application/vnd.sealed.xls": {
- "source": "apache"
- },
- "application/vnd.sealedmedia.softseal-html": {
- "source": "iana"
- },
- "application/vnd.sealedmedia.softseal-pdf": {
- "source": "iana"
- },
- "application/vnd.sealedmedia.softseal.html": {
- "source": "apache"
- },
- "application/vnd.sealedmedia.softseal.pdf": {
- "source": "apache"
- },
- "application/vnd.seemail": {
- "source": "iana",
- "extensions": ["see"]
- },
- "application/vnd.sema": {
- "source": "apache",
- "extensions": ["sema"]
- },
- "application/vnd.semd": {
- "source": "iana",
- "extensions": ["semd"]
- },
- "application/vnd.semf": {
- "source": "iana",
- "extensions": ["semf"]
- },
- "application/vnd.shana.informed.formdata": {
- "source": "iana",
- "extensions": ["ifm"]
- },
- "application/vnd.shana.informed.formtemplate": {
- "source": "iana",
- "extensions": ["itp"]
- },
- "application/vnd.shana.informed.interchange": {
- "source": "iana",
- "extensions": ["iif"]
- },
- "application/vnd.shana.informed.package": {
- "source": "iana",
- "extensions": ["ipk"]
- },
- "application/vnd.simtech-mindmapper": {
- "source": "iana",
- "extensions": ["twd","twds"]
- },
- "application/vnd.siren+json": {
- "source": "iana",
- "compressible": true
- },
- "application/vnd.smaf": {
- "source": "iana",
- "extensions": ["mmf"]
- },
- "application/vnd.smart.notebook": {
- "source": "iana"
- },
- "application/vnd.smart.teacher": {
- "source": "iana",
- "extensions": ["teacher"]
- },
- "application/vnd.software602.filler.form+xml": {
- "source": "iana"
- },
- "application/vnd.software602.filler.form-xml-zip": {
- "source": "iana"
- },
- "application/vnd.solent.sdkm+xml": {
- "source": "iana",
- "extensions": ["sdkm","sdkd"]
- },
- "application/vnd.spotfire.dxp": {
- "source": "iana",
- "extensions": ["dxp"]
- },
- "application/vnd.spotfire.sfs": {
- "source": "iana",
- "extensions": ["sfs"]
- },
- "application/vnd.sss-cod": {
- "source": "iana"
- },
- "application/vnd.sss-dtf": {
- "source": "iana"
- },
- "application/vnd.sss-ntf": {
- "source": "iana"
- },
- "application/vnd.stardivision.calc": {
- "source": "apache",
- "extensions": ["sdc"]
- },
- "application/vnd.stardivision.draw": {
- "source": "apache",
- "extensions": ["sda"]
- },
- "application/vnd.stardivision.impress": {
- "source": "apache",
- "extensions": ["sdd"]
- },
- "application/vnd.stardivision.math": {
- "source": "apache",
- "extensions": ["smf"]
- },
- "application/vnd.stardivision.writer": {
- "source": "apache",
- "extensions": ["sdw","vor"]
- },
- "application/vnd.stardivision.writer-global": {
- "source": "apache",
- "extensions": ["sgl"]
- },
- "application/vnd.stepmania.package": {
- "source": "iana",
- "extensions": ["smzip"]
- },
- "application/vnd.stepmania.stepchart": {
- "source": "iana",
- "extensions": ["sm"]
- },
- "application/vnd.street-stream": {
- "source": "iana"
- },
- "application/vnd.sun.wadl+xml": {
- "source": "iana"
- },
- "application/vnd.sun.xml.calc": {
- "source": "apache",
- "extensions": ["sxc"]
- },
- "application/vnd.sun.xml.calc.template": {
- "source": "apache",
- "extensions": ["stc"]
- },
- "application/vnd.sun.xml.draw": {
- "source": "apache",
- "extensions": ["sxd"]
- },
- "application/vnd.sun.xml.draw.template": {
- "source": "apache",
- "extensions": ["std"]
- },
- "application/vnd.sun.xml.impress": {
- "source": "apache",
- "extensions": ["sxi"]
- },
- "application/vnd.sun.xml.impress.template": {
- "source": "apache",
- "extensions": ["sti"]
- },
- "application/vnd.sun.xml.math": {
- "source": "apache",
- "extensions": ["sxm"]
- },
- "application/vnd.sun.xml.writer": {
- "source": "apache",
- "extensions": ["sxw"]
- },
- "application/vnd.sun.xml.writer.global": {
- "source": "apache",
- "extensions": ["sxg"]
- },
- "application/vnd.sun.xml.writer.template": {
- "source": "apache",
- "extensions": ["stw"]
- },
- "application/vnd.sus-calendar": {
- "source": "iana",
- "extensions": ["sus","susp"]
- },
- "application/vnd.svd": {
- "source": "iana",
- "extensions": ["svd"]
- },
- "application/vnd.swiftview-ics": {
- "source": "iana"
- },
- "application/vnd.symbian.install": {
- "source": "apache",
- "extensions": ["sis","sisx"]
- },
- "application/vnd.syncml+xml": {
- "source": "iana",
- "extensions": ["xsm"]
- },
- "application/vnd.syncml.dm+wbxml": {
- "source": "iana",
- "extensions": ["bdm"]
- },
- "application/vnd.syncml.dm+xml": {
- "source": "iana",
- "extensions": ["xdm"]
- },
- "application/vnd.syncml.dm.notification": {
- "source": "iana"
- },
- "application/vnd.syncml.dmddf+wbxml": {
- "source": "iana"
- },
- "application/vnd.syncml.dmddf+xml": {
- "source": "iana"
- },
- "application/vnd.syncml.dmtnds+wbxml": {
- "source": "iana"
- },
- "application/vnd.syncml.dmtnds+xml": {
- "source": "iana"
- },
- "application/vnd.syncml.ds.notification": {
- "source": "iana"
- },
- "application/vnd.tao.intent-module-archive": {
- "source": "iana",
- "extensions": ["tao"]
- },
- "application/vnd.tcpdump.pcap": {
- "source": "iana",
- "extensions": ["pcap","cap","dmp"]
- },
- "application/vnd.tmobile-livetv": {
- "source": "iana",
- "extensions": ["tmo"]
- },
- "application/vnd.trid.tpt": {
- "source": "iana",
- "extensions": ["tpt"]
- },
- "application/vnd.triscape.mxs": {
- "source": "iana",
- "extensions": ["mxs"]
- },
- "application/vnd.trueapp": {
- "source": "iana",
- "extensions": ["tra"]
- },
- "application/vnd.truedoc": {
- "source": "iana"
- },
- "application/vnd.ubisoft.webplayer": {
- "source": "iana"
- },
- "application/vnd.ufdl": {
- "source": "iana",
- "extensions": ["ufd","ufdl"]
- },
- "application/vnd.uiq.theme": {
- "source": "iana",
- "extensions": ["utz"]
- },
- "application/vnd.umajin": {
- "source": "iana",
- "extensions": ["umj"]
- },
- "application/vnd.unity": {
- "source": "iana",
- "extensions": ["unityweb"]
- },
- "application/vnd.uoml+xml": {
- "source": "iana",
- "extensions": ["uoml"]
- },
- "application/vnd.uplanet.alert": {
- "source": "iana"
- },
- "application/vnd.uplanet.alert-wbxml": {
- "source": "iana"
- },
- "application/vnd.uplanet.bearer-choice": {
- "source": "iana"
- },
- "application/vnd.uplanet.bearer-choice-wbxml": {
- "source": "iana"
- },
- "application/vnd.uplanet.cacheop": {
- "source": "iana"
- },
- "application/vnd.uplanet.cacheop-wbxml": {
- "source": "iana"
- },
- "application/vnd.uplanet.channel": {
- "source": "iana"
- },
- "application/vnd.uplanet.channel-wbxml": {
- "source": "iana"
- },
- "application/vnd.uplanet.list": {
- "source": "iana"
- },
- "application/vnd.uplanet.list-wbxml": {
- "source": "iana"
- },
- "application/vnd.uplanet.listcmd": {
- "source": "iana"
- },
- "application/vnd.uplanet.listcmd-wbxml": {
- "source": "iana"
- },
- "application/vnd.uplanet.signal": {
- "source": "iana"
- },
- "application/vnd.valve.source.material": {
- "source": "iana"
- },
- "application/vnd.vcx": {
- "source": "iana",
- "extensions": ["vcx"]
- },
- "application/vnd.vd-study": {
- "source": "iana"
- },
- "application/vnd.vectorworks": {
- "source": "iana"
- },
- "application/vnd.verimatrix.vcas": {
- "source": "iana"
- },
- "application/vnd.vidsoft.vidconference": {
- "source": "iana"
- },
- "application/vnd.visio": {
- "source": "iana",
- "extensions": ["vsd","vst","vss","vsw"]
- },
- "application/vnd.visionary": {
- "source": "iana",
- "extensions": ["vis"]
- },
- "application/vnd.vividence.scriptfile": {
- "source": "iana"
- },
- "application/vnd.vsf": {
- "source": "iana",
- "extensions": ["vsf"]
- },
- "application/vnd.wap-slc": {
- "source": "iana"
- },
- "application/vnd.wap-wbxml": {
- "source": "iana"
- },
- "application/vnd.wap.sic": {
- "source": "iana"
- },
- "application/vnd.wap.slc": {
- "source": "apache"
- },
- "application/vnd.wap.wbxml": {
- "source": "apache",
- "extensions": ["wbxml"]
- },
- "application/vnd.wap.wmlc": {
- "source": "apache",
- "extensions": ["wmlc"]
- },
- "application/vnd.wap.wmlscriptc": {
- "source": "iana",
- "extensions": ["wmlsc"]
- },
- "application/vnd.webturbo": {
- "source": "iana",
- "extensions": ["wtb"]
- },
- "application/vnd.wfa.p2p": {
- "source": "iana"
- },
- "application/vnd.wfa.wsc": {
- "source": "iana"
- },
- "application/vnd.windows.devicepairing": {
- "source": "iana"
- },
- "application/vnd.wmc": {
- "source": "iana"
- },
- "application/vnd.wmf.bootstrap": {
- "source": "iana"
- },
- "application/vnd.wolfram.mathematica": {
- "source": "iana"
- },
- "application/vnd.wolfram.mathematica.package": {
- "source": "iana"
- },
- "application/vnd.wolfram.player": {
- "source": "iana",
- "extensions": ["nbp"]
- },
- "application/vnd.wordperfect": {
- "source": "iana",
- "extensions": ["wpd"]
- },
- "application/vnd.wqd": {
- "source": "iana",
- "extensions": ["wqd"]
- },
- "application/vnd.wrq-hp3000-labelled": {
- "source": "iana"
- },
- "application/vnd.wt.stf": {
- "source": "iana",
- "extensions": ["stf"]
- },
- "application/vnd.wv.csp+wbxml": {
- "source": "iana"
- },
- "application/vnd.wv.csp+xml": {
- "source": "iana"
- },
- "application/vnd.wv.ssp+xml": {
- "source": "iana"
- },
- "application/vnd.xacml+json": {
- "source": "iana",
- "compressible": true
- },
- "application/vnd.xara": {
- "source": "iana",
- "extensions": ["xar"]
- },
- "application/vnd.xfdl": {
- "source": "iana",
- "extensions": ["xfdl"]
- },
- "application/vnd.xfdl.webform": {
- "source": "iana"
- },
- "application/vnd.xmi+xml": {
- "source": "iana"
- },
- "application/vnd.xmpie.cpkg": {
- "source": "iana"
- },
- "application/vnd.xmpie.dpkg": {
- "source": "iana"
- },
- "application/vnd.xmpie.plan": {
- "source": "iana"
- },
- "application/vnd.xmpie.ppkg": {
- "source": "iana"
- },
- "application/vnd.xmpie.xlim": {
- "source": "iana"
- },
- "application/vnd.yamaha.hv-dic": {
- "source": "iana",
- "extensions": ["hvd"]
- },
- "application/vnd.yamaha.hv-script": {
- "source": "iana",
- "extensions": ["hvs"]
- },
- "application/vnd.yamaha.hv-voice": {
- "source": "iana",
- "extensions": ["hvp"]
- },
- "application/vnd.yamaha.openscoreformat": {
- "source": "iana",
- "extensions": ["osf"]
- },
- "application/vnd.yamaha.openscoreformat.osfpvg+xml": {
- "source": "iana",
- "extensions": ["osfpvg"]
- },
- "application/vnd.yamaha.remote-setup": {
- "source": "iana"
- },
- "application/vnd.yamaha.smaf-audio": {
- "source": "iana",
- "extensions": ["saf"]
- },
- "application/vnd.yamaha.smaf-phrase": {
- "source": "iana",
- "extensions": ["spf"]
- },
- "application/vnd.yamaha.through-ngn": {
- "source": "iana"
- },
- "application/vnd.yamaha.tunnel-udpencap": {
- "source": "iana"
- },
- "application/vnd.yaoweme": {
- "source": "iana"
- },
- "application/vnd.yellowriver-custom-menu": {
- "source": "iana",
- "extensions": ["cmp"]
- },
- "application/vnd.zul": {
- "source": "iana",
- "extensions": ["zir","zirz"]
- },
- "application/vnd.zzazz.deck+xml": {
- "source": "iana",
- "extensions": ["zaz"]
- },
- "application/voicexml+xml": {
- "source": "iana",
- "extensions": ["vxml"]
- },
- "application/vq-rtcpxr": {
- "source": "iana"
- },
- "application/vwg-multiplexed": {
- "source": "iana"
- },
- "application/watcherinfo+xml": {
- "source": "iana"
- },
- "application/whoispp-query": {
- "source": "iana"
- },
- "application/whoispp-response": {
- "source": "iana"
- },
- "application/widget": {
- "source": "iana",
- "extensions": ["wgt"]
- },
- "application/winhlp": {
- "source": "apache",
- "extensions": ["hlp"]
- },
- "application/wita": {
- "source": "iana"
- },
- "application/wordperfect5.1": {
- "source": "iana"
- },
- "application/wsdl+xml": {
- "source": "iana",
- "extensions": ["wsdl"]
- },
- "application/wspolicy+xml": {
- "source": "iana",
- "extensions": ["wspolicy"]
- },
- "application/x-7z-compressed": {
- "source": "apache",
- "compressible": false,
- "extensions": ["7z"]
- },
- "application/x-abiword": {
- "source": "apache",
- "extensions": ["abw"]
- },
- "application/x-ace-compressed": {
- "source": "apache",
- "extensions": ["ace"]
- },
- "application/x-amf": {
- "source": "apache"
- },
- "application/x-apple-diskimage": {
- "source": "apache",
- "extensions": ["dmg"]
- },
- "application/x-authorware-bin": {
- "source": "apache",
- "extensions": ["aab","x32","u32","vox"]
- },
- "application/x-authorware-map": {
- "source": "apache",
- "extensions": ["aam"]
- },
- "application/x-authorware-seg": {
- "source": "apache",
- "extensions": ["aas"]
- },
- "application/x-bcpio": {
- "source": "apache",
- "extensions": ["bcpio"]
- },
- "application/x-bittorrent": {
- "source": "apache",
- "extensions": ["torrent"]
- },
- "application/x-blorb": {
- "source": "apache",
- "extensions": ["blb","blorb"]
- },
- "application/x-bzip": {
- "source": "apache",
- "compressible": false,
- "extensions": ["bz"]
- },
- "application/x-bzip2": {
- "source": "apache",
- "compressible": false,
- "extensions": ["bz2","boz"]
- },
- "application/x-cbr": {
- "source": "apache",
- "extensions": ["cbr","cba","cbt","cbz","cb7"]
- },
- "application/x-cdlink": {
- "source": "apache",
- "extensions": ["vcd"]
- },
- "application/x-cfs-compressed": {
- "source": "apache",
- "extensions": ["cfs"]
- },
- "application/x-chat": {
- "source": "apache",
- "extensions": ["chat"]
- },
- "application/x-chess-pgn": {
- "source": "apache",
- "extensions": ["pgn"]
- },
- "application/x-chrome-extension": {
- "extensions": ["crx"]
- },
- "application/x-compress": {
- "source": "apache"
- },
- "application/x-conference": {
- "source": "apache",
- "extensions": ["nsc"]
- },
- "application/x-cpio": {
- "source": "apache",
- "extensions": ["cpio"]
- },
- "application/x-csh": {
- "source": "apache",
- "extensions": ["csh"]
- },
- "application/x-deb": {
- "compressible": false
- },
- "application/x-debian-package": {
- "source": "apache",
- "extensions": ["deb","udeb"]
- },
- "application/x-dgc-compressed": {
- "source": "apache",
- "extensions": ["dgc"]
- },
- "application/x-director": {
- "source": "apache",
- "extensions": ["dir","dcr","dxr","cst","cct","cxt","w3d","fgd","swa"]
- },
- "application/x-doom": {
- "source": "apache",
- "extensions": ["wad"]
- },
- "application/x-dtbncx+xml": {
- "source": "apache",
- "extensions": ["ncx"]
- },
- "application/x-dtbook+xml": {
- "source": "apache",
- "extensions": ["dtb"]
- },
- "application/x-dtbresource+xml": {
- "source": "apache",
- "extensions": ["res"]
- },
- "application/x-dvi": {
- "source": "apache",
- "compressible": false,
- "extensions": ["dvi"]
- },
- "application/x-envoy": {
- "source": "apache",
- "extensions": ["evy"]
- },
- "application/x-eva": {
- "source": "apache",
- "extensions": ["eva"]
- },
- "application/x-font-bdf": {
- "source": "apache",
- "extensions": ["bdf"]
- },
- "application/x-font-dos": {
- "source": "apache"
- },
- "application/x-font-framemaker": {
- "source": "apache"
- },
- "application/x-font-ghostscript": {
- "source": "apache",
- "extensions": ["gsf"]
- },
- "application/x-font-libgrx": {
- "source": "apache"
- },
- "application/x-font-linux-psf": {
- "source": "apache",
- "extensions": ["psf"]
- },
- "application/x-font-otf": {
- "source": "apache",
- "compressible": true,
- "extensions": ["otf"]
- },
- "application/x-font-pcf": {
- "source": "apache",
- "extensions": ["pcf"]
- },
- "application/x-font-snf": {
- "source": "apache",
- "extensions": ["snf"]
- },
- "application/x-font-speedo": {
- "source": "apache"
- },
- "application/x-font-sunos-news": {
- "source": "apache"
- },
- "application/x-font-ttf": {
- "source": "apache",
- "compressible": true,
- "extensions": ["ttf","ttc"]
- },
- "application/x-font-type1": {
- "source": "apache",
- "extensions": ["pfa","pfb","pfm","afm"]
- },
- "application/x-font-vfont": {
- "source": "apache"
- },
- "application/x-freearc": {
- "source": "apache",
- "extensions": ["arc"]
- },
- "application/x-futuresplash": {
- "source": "apache",
- "extensions": ["spl"]
- },
- "application/x-gca-compressed": {
- "source": "apache",
- "extensions": ["gca"]
- },
- "application/x-glulx": {
- "source": "apache",
- "extensions": ["ulx"]
- },
- "application/x-gnumeric": {
- "source": "apache",
- "extensions": ["gnumeric"]
- },
- "application/x-gramps-xml": {
- "source": "apache",
- "extensions": ["gramps"]
- },
- "application/x-gtar": {
- "source": "apache",
- "extensions": ["gtar"]
- },
- "application/x-gzip": {
- "source": "apache"
- },
- "application/x-hdf": {
- "source": "apache",
- "extensions": ["hdf"]
- },
- "application/x-install-instructions": {
- "source": "apache",
- "extensions": ["install"]
- },
- "application/x-iso9660-image": {
- "source": "apache",
- "extensions": ["iso"]
- },
- "application/x-java-jnlp-file": {
- "source": "apache",
- "compressible": false,
- "extensions": ["jnlp"]
- },
- "application/x-javascript": {
- "compressible": true
- },
- "application/x-latex": {
- "source": "apache",
- "compressible": false,
- "extensions": ["latex"]
- },
- "application/x-lua-bytecode": {
- "extensions": ["luac"]
- },
- "application/x-lzh-compressed": {
- "source": "apache",
- "extensions": ["lzh","lha"]
- },
- "application/x-mie": {
- "source": "apache",
- "extensions": ["mie"]
- },
- "application/x-mobipocket-ebook": {
- "source": "apache",
- "extensions": ["prc","mobi"]
- },
- "application/x-mpegurl": {
- "compressible": false
- },
- "application/x-ms-application": {
- "source": "apache",
- "extensions": ["application"]
- },
- "application/x-ms-shortcut": {
- "source": "apache",
- "extensions": ["lnk"]
- },
- "application/x-ms-wmd": {
- "source": "apache",
- "extensions": ["wmd"]
- },
- "application/x-ms-wmz": {
- "source": "apache",
- "extensions": ["wmz"]
- },
- "application/x-ms-xbap": {
- "source": "apache",
- "extensions": ["xbap"]
- },
- "application/x-msaccess": {
- "source": "apache",
- "extensions": ["mdb"]
- },
- "application/x-msbinder": {
- "source": "apache",
- "extensions": ["obd"]
- },
- "application/x-mscardfile": {
- "source": "apache",
- "extensions": ["crd"]
- },
- "application/x-msclip": {
- "source": "apache",
- "extensions": ["clp"]
- },
- "application/x-msdownload": {
- "source": "apache",
- "extensions": ["exe","dll","com","bat","msi"]
- },
- "application/x-msmediaview": {
- "source": "apache",
- "extensions": ["mvb","m13","m14"]
- },
- "application/x-msmetafile": {
- "source": "apache",
- "extensions": ["wmf","wmz","emf","emz"]
- },
- "application/x-msmoney": {
- "source": "apache",
- "extensions": ["mny"]
- },
- "application/x-mspublisher": {
- "source": "apache",
- "extensions": ["pub"]
- },
- "application/x-msschedule": {
- "source": "apache",
- "extensions": ["scd"]
- },
- "application/x-msterminal": {
- "source": "apache",
- "extensions": ["trm"]
- },
- "application/x-mswrite": {
- "source": "apache",
- "extensions": ["wri"]
- },
- "application/x-netcdf": {
- "source": "apache",
- "extensions": ["nc","cdf"]
- },
- "application/x-nzb": {
- "source": "apache",
- "extensions": ["nzb"]
- },
- "application/x-pkcs12": {
- "source": "apache",
- "compressible": false,
- "extensions": ["p12","pfx"]
- },
- "application/x-pkcs7-certificates": {
- "source": "apache",
- "extensions": ["p7b","spc"]
- },
- "application/x-pkcs7-certreqresp": {
- "source": "apache",
- "extensions": ["p7r"]
- },
- "application/x-rar-compressed": {
- "source": "apache",
- "compressible": false,
- "extensions": ["rar"]
- },
- "application/x-research-info-systems": {
- "source": "apache",
- "extensions": ["ris"]
- },
- "application/x-sh": {
- "source": "apache",
- "compressible": true,
- "extensions": ["sh"]
- },
- "application/x-shar": {
- "source": "apache",
- "extensions": ["shar"]
- },
- "application/x-shockwave-flash": {
- "source": "apache",
- "compressible": false,
- "extensions": ["swf"]
- },
- "application/x-silverlight-app": {
- "source": "apache",
- "extensions": ["xap"]
- },
- "application/x-sql": {
- "source": "apache",
- "extensions": ["sql"]
- },
- "application/x-stuffit": {
- "source": "apache",
- "compressible": false,
- "extensions": ["sit"]
- },
- "application/x-stuffitx": {
- "source": "apache",
- "extensions": ["sitx"]
- },
- "application/x-subrip": {
- "source": "apache",
- "extensions": ["srt"]
- },
- "application/x-sv4cpio": {
- "source": "apache",
- "extensions": ["sv4cpio"]
- },
- "application/x-sv4crc": {
- "source": "apache",
- "extensions": ["sv4crc"]
- },
- "application/x-t3vm-image": {
- "source": "apache",
- "extensions": ["t3"]
- },
- "application/x-tads": {
- "source": "apache",
- "extensions": ["gam"]
- },
- "application/x-tar": {
- "source": "apache",
- "compressible": true,
- "extensions": ["tar"]
- },
- "application/x-tcl": {
- "source": "apache",
- "extensions": ["tcl"]
- },
- "application/x-tex": {
- "source": "apache",
- "extensions": ["tex"]
- },
- "application/x-tex-tfm": {
- "source": "apache",
- "extensions": ["tfm"]
- },
- "application/x-texinfo": {
- "source": "apache",
- "extensions": ["texinfo","texi"]
- },
- "application/x-tgif": {
- "source": "apache",
- "extensions": ["obj"]
- },
- "application/x-ustar": {
- "source": "apache",
- "extensions": ["ustar"]
- },
- "application/x-wais-source": {
- "source": "apache",
- "extensions": ["src"]
- },
- "application/x-web-app-manifest+json": {
- "compressible": true,
- "extensions": ["webapp"]
- },
- "application/x-www-form-urlencode": {
- "compressible": false
- },
- "application/x-www-form-urlencoded": {
- "source": "iana"
- },
- "application/x-x509-ca-cert": {
- "source": "apache",
- "extensions": ["der","crt"]
- },
- "application/x-xfig": {
- "source": "apache",
- "extensions": ["fig"]
- },
- "application/x-xliff+xml": {
- "source": "apache",
- "extensions": ["xlf"]
- },
- "application/x-xpinstall": {
- "source": "apache",
- "compressible": false,
- "extensions": ["xpi"]
- },
- "application/x-xz": {
- "source": "apache",
- "extensions": ["xz"]
- },
- "application/x-zmachine": {
- "source": "apache",
- "extensions": ["z1","z2","z3","z4","z5","z6","z7","z8"]
- },
- "application/x400-bp": {
- "source": "iana"
- },
- "application/xacml+xml": {
- "source": "iana"
- },
- "application/xaml+xml": {
- "source": "apache",
- "extensions": ["xaml"]
- },
- "application/xcap-att+xml": {
- "source": "iana"
- },
- "application/xcap-caps+xml": {
- "source": "iana"
- },
- "application/xcap-diff+xml": {
- "source": "iana",
- "extensions": ["xdf"]
- },
- "application/xcap-el+xml": {
- "source": "iana"
- },
- "application/xcap-error+xml": {
- "source": "iana"
- },
- "application/xcap-ns+xml": {
- "source": "iana"
- },
- "application/xcon-conference-info+xml": {
- "source": "iana"
- },
- "application/xcon-conference-info-diff+xml": {
- "source": "iana"
- },
- "application/xenc+xml": {
- "source": "iana",
- "extensions": ["xenc"]
- },
- "application/xhtml+xml": {
- "source": "iana",
- "compressible": true,
- "extensions": ["xhtml","xht"]
- },
- "application/xhtml-voice+xml": {
- "source": "iana"
- },
- "application/xml": {
- "source": "iana",
- "compressible": true,
- "extensions": ["xml","xsl","xsd"]
- },
- "application/xml-dtd": {
- "source": "iana",
- "compressible": true,
- "extensions": ["dtd"]
- },
- "application/xml-external-parsed-entity": {
- "source": "iana"
- },
- "application/xml-patch+xml": {
- "source": "iana"
- },
- "application/xmpp+xml": {
- "source": "iana"
- },
- "application/xop+xml": {
- "source": "iana",
- "compressible": true,
- "extensions": ["xop"]
- },
- "application/xproc+xml": {
- "source": "apache",
- "extensions": ["xpl"]
- },
- "application/xslt+xml": {
- "source": "iana",
- "extensions": ["xslt"]
- },
- "application/xspf+xml": {
- "source": "apache",
- "extensions": ["xspf"]
- },
- "application/xv+xml": {
- "source": "iana",
- "extensions": ["mxml","xhvml","xvml","xvm"]
- },
- "application/yang": {
- "source": "iana",
- "extensions": ["yang"]
- },
- "application/yin+xml": {
- "source": "iana",
- "extensions": ["yin"]
- },
- "application/zip": {
- "source": "iana",
- "compressible": false,
- "extensions": ["zip"]
- },
- "application/zlib": {
- "source": "iana"
- },
- "audio/1d-interleaved-parityfec": {
- "source": "iana"
- },
- "audio/32kadpcm": {
- "source": "iana"
- },
- "audio/3gpp": {
- "source": "iana"
- },
- "audio/3gpp2": {
- "source": "iana"
- },
- "audio/ac3": {
- "source": "iana"
- },
- "audio/adpcm": {
- "source": "apache",
- "extensions": ["adp"]
- },
- "audio/amr": {
- "source": "iana"
- },
- "audio/amr-wb": {
- "source": "iana"
- },
- "audio/amr-wb+": {
- "source": "iana"
- },
- "audio/aptx": {
- "source": "iana"
- },
- "audio/asc": {
- "source": "iana"
- },
- "audio/atrac-advanced-lossless": {
- "source": "iana"
- },
- "audio/atrac-x": {
- "source": "iana"
- },
- "audio/atrac3": {
- "source": "iana"
- },
- "audio/basic": {
- "source": "iana",
- "compressible": false,
- "extensions": ["au","snd"]
- },
- "audio/bv16": {
- "source": "iana"
- },
- "audio/bv32": {
- "source": "iana"
- },
- "audio/clearmode": {
- "source": "iana"
- },
- "audio/cn": {
- "source": "iana"
- },
- "audio/dat12": {
- "source": "iana"
- },
- "audio/dls": {
- "source": "iana"
- },
- "audio/dsr-es201108": {
- "source": "iana"
- },
- "audio/dsr-es202050": {
- "source": "iana"
- },
- "audio/dsr-es202211": {
- "source": "iana"
- },
- "audio/dsr-es202212": {
- "source": "iana"
- },
- "audio/dv": {
- "source": "iana"
- },
- "audio/dvi4": {
- "source": "iana"
- },
- "audio/eac3": {
- "source": "iana"
- },
- "audio/encaprtp": {
- "source": "iana"
- },
- "audio/evrc": {
- "source": "iana"
- },
- "audio/evrc-qcp": {
- "source": "iana"
- },
- "audio/evrc0": {
- "source": "iana"
- },
- "audio/evrc1": {
- "source": "iana"
- },
- "audio/evrcb": {
- "source": "iana"
- },
- "audio/evrcb0": {
- "source": "iana"
- },
- "audio/evrcb1": {
- "source": "iana"
- },
- "audio/evrcnw": {
- "source": "iana"
- },
- "audio/evrcnw0": {
- "source": "iana"
- },
- "audio/evrcnw1": {
- "source": "iana"
- },
- "audio/evrcwb": {
- "source": "iana"
- },
- "audio/evrcwb0": {
- "source": "iana"
- },
- "audio/evrcwb1": {
- "source": "iana"
- },
- "audio/example": {
- "source": "iana"
- },
- "audio/fwdred": {
- "source": "iana"
- },
- "audio/g719": {
- "source": "iana"
- },
- "audio/g721": {
- "source": "iana"
- },
- "audio/g722": {
- "source": "iana"
- },
- "audio/g7221": {
- "source": "apache"
- },
- "audio/g723": {
- "source": "iana"
- },
- "audio/g726-16": {
- "source": "iana"
- },
- "audio/g726-24": {
- "source": "iana"
- },
- "audio/g726-32": {
- "source": "iana"
- },
- "audio/g726-40": {
- "source": "iana"
- },
- "audio/g728": {
- "source": "iana"
- },
- "audio/g729": {
- "source": "iana"
- },
- "audio/g7291": {
- "source": "iana"
- },
- "audio/g729d": {
- "source": "iana"
- },
- "audio/g729e": {
- "source": "iana"
- },
- "audio/gsm": {
- "source": "iana"
- },
- "audio/gsm-efr": {
- "source": "iana"
- },
- "audio/gsm-hr-08": {
- "source": "iana"
- },
- "audio/ilbc": {
- "source": "iana"
- },
- "audio/ip-mr_v2.5": {
- "source": "iana"
- },
- "audio/isac": {
- "source": "apache"
- },
- "audio/l16": {
- "source": "iana"
- },
- "audio/l20": {
- "source": "iana"
- },
- "audio/l24": {
- "source": "iana",
- "compressible": false
- },
- "audio/l8": {
- "source": "iana"
- },
- "audio/lpc": {
- "source": "iana"
- },
- "audio/midi": {
- "source": "apache",
- "extensions": ["mid","midi","kar","rmi"]
- },
- "audio/mobile-xmf": {
- "source": "iana"
- },
- "audio/mp4": {
- "source": "iana",
- "compressible": false,
- "extensions": ["mp4a","m4a"]
- },
- "audio/mp4a-latm": {
- "source": "iana"
- },
- "audio/mpa": {
- "source": "iana"
- },
- "audio/mpa-robust": {
- "source": "iana"
- },
- "audio/mpeg": {
- "source": "iana",
- "compressible": false,
- "extensions": ["mpga","mp2","mp2a","mp3","m2a","m3a"]
- },
- "audio/mpeg4-generic": {
- "source": "iana"
- },
- "audio/musepack": {
- "source": "apache"
- },
- "audio/ogg": {
- "source": "iana",
- "compressible": false,
- "extensions": ["oga","ogg","spx"]
- },
- "audio/opus": {
- "source": "apache"
- },
- "audio/parityfec": {
- "source": "iana"
- },
- "audio/pcma": {
- "source": "iana"
- },
- "audio/pcma-wb": {
- "source": "iana"
- },
- "audio/pcmu": {
- "source": "iana"
- },
- "audio/pcmu-wb": {
- "source": "iana"
- },
- "audio/prs.sid": {
- "source": "iana"
- },
- "audio/qcelp": {
- "source": "iana"
- },
- "audio/raptorfec": {
- "source": "iana"
- },
- "audio/red": {
- "source": "iana"
- },
- "audio/rtp-enc-aescm128": {
- "source": "iana"
- },
- "audio/rtp-midi": {
- "source": "iana"
- },
- "audio/rtploopback": {
- "source": "iana"
- },
- "audio/rtx": {
- "source": "iana"
- },
- "audio/s3m": {
- "source": "apache",
- "extensions": ["s3m"]
- },
- "audio/silk": {
- "source": "apache",
- "extensions": ["sil"]
- },
- "audio/smv": {
- "source": "iana"
- },
- "audio/smv-qcp": {
- "source": "iana"
- },
- "audio/smv0": {
- "source": "iana"
- },
- "audio/sp-midi": {
- "source": "iana"
- },
- "audio/speex": {
- "source": "iana"
- },
- "audio/t140c": {
- "source": "iana"
- },
- "audio/t38": {
- "source": "iana"
- },
- "audio/telephone-event": {
- "source": "iana"
- },
- "audio/tone": {
- "source": "iana"
- },
- "audio/uemclip": {
- "source": "iana"
- },
- "audio/ulpfec": {
- "source": "iana"
- },
- "audio/vdvi": {
- "source": "iana"
- },
- "audio/vmr-wb": {
- "source": "iana"
- },
- "audio/vnd.3gpp.iufp": {
- "source": "iana"
- },
- "audio/vnd.4sb": {
- "source": "iana"
- },
- "audio/vnd.audiokoz": {
- "source": "iana"
- },
- "audio/vnd.celp": {
- "source": "iana"
- },
- "audio/vnd.cisco.nse": {
- "source": "iana"
- },
- "audio/vnd.cmles.radio-events": {
- "source": "iana"
- },
- "audio/vnd.cns.anp1": {
- "source": "iana"
- },
- "audio/vnd.cns.inf1": {
- "source": "iana"
- },
- "audio/vnd.dece.audio": {
- "source": "iana",
- "extensions": ["uva","uvva"]
- },
- "audio/vnd.digital-winds": {
- "source": "iana",
- "extensions": ["eol"]
- },
- "audio/vnd.dlna.adts": {
- "source": "iana"
- },
- "audio/vnd.dolby.heaac.1": {
- "source": "iana"
- },
- "audio/vnd.dolby.heaac.2": {
- "source": "iana"
- },
- "audio/vnd.dolby.mlp": {
- "source": "iana"
- },
- "audio/vnd.dolby.mps": {
- "source": "iana"
- },
- "audio/vnd.dolby.pl2": {
- "source": "iana"
- },
- "audio/vnd.dolby.pl2x": {
- "source": "iana"
- },
- "audio/vnd.dolby.pl2z": {
- "source": "iana"
- },
- "audio/vnd.dolby.pulse.1": {
- "source": "iana"
- },
- "audio/vnd.dra": {
- "source": "iana",
- "extensions": ["dra"]
- },
- "audio/vnd.dts": {
- "source": "iana",
- "extensions": ["dts"]
- },
- "audio/vnd.dts.hd": {
- "source": "iana",
- "extensions": ["dtshd"]
- },
- "audio/vnd.dvb.file": {
- "source": "iana"
- },
- "audio/vnd.everad.plj": {
- "source": "iana"
- },
- "audio/vnd.hns.audio": {
- "source": "iana"
- },
- "audio/vnd.lucent.voice": {
- "source": "iana",
- "extensions": ["lvp"]
- },
- "audio/vnd.ms-playready.media.pya": {
- "source": "iana",
- "extensions": ["pya"]
- },
- "audio/vnd.nokia.mobile-xmf": {
- "source": "iana"
- },
- "audio/vnd.nortel.vbk": {
- "source": "iana"
- },
- "audio/vnd.nuera.ecelp4800": {
- "source": "iana",
- "extensions": ["ecelp4800"]
- },
- "audio/vnd.nuera.ecelp7470": {
- "source": "iana",
- "extensions": ["ecelp7470"]
- },
- "audio/vnd.nuera.ecelp9600": {
- "source": "iana",
- "extensions": ["ecelp9600"]
- },
- "audio/vnd.octel.sbc": {
- "source": "iana"
- },
- "audio/vnd.qcelp": {
- "source": "iana"
- },
- "audio/vnd.rhetorex.32kadpcm": {
- "source": "iana"
- },
- "audio/vnd.rip": {
- "source": "iana",
- "extensions": ["rip"]
- },
- "audio/vnd.rn-realaudio": {
- "compressible": false
- },
- "audio/vnd.sealedmedia.softseal-mpeg": {
- "source": "iana"
- },
- "audio/vnd.sealedmedia.softseal.mpeg": {
- "source": "apache"
- },
- "audio/vnd.vmx.cvsd": {
- "source": "iana"
- },
- "audio/vnd.wave": {
- "compressible": false
- },
- "audio/vorbis": {
- "source": "iana",
- "compressible": false
- },
- "audio/vorbis-config": {
- "source": "iana"
- },
- "audio/webm": {
- "source": "apache",
- "compressible": false,
- "extensions": ["weba"]
- },
- "audio/x-aac": {
- "source": "apache",
- "compressible": false,
- "extensions": ["aac"]
- },
- "audio/x-aiff": {
- "source": "apache",
- "extensions": ["aif","aiff","aifc"]
- },
- "audio/x-caf": {
- "source": "apache",
- "compressible": false,
- "extensions": ["caf"]
- },
- "audio/x-flac": {
- "source": "apache",
- "extensions": ["flac"]
- },
- "audio/x-matroska": {
- "source": "apache",
- "extensions": ["mka"]
- },
- "audio/x-mpegurl": {
- "source": "apache",
- "extensions": ["m3u"]
- },
- "audio/x-ms-wax": {
- "source": "apache",
- "extensions": ["wax"]
- },
- "audio/x-ms-wma": {
- "source": "apache",
- "extensions": ["wma"]
- },
- "audio/x-pn-realaudio": {
- "source": "apache",
- "extensions": ["ram","ra"]
- },
- "audio/x-pn-realaudio-plugin": {
- "source": "apache",
- "extensions": ["rmp"]
- },
- "audio/x-tta": {
- "source": "apache"
- },
- "audio/x-wav": {
- "source": "apache",
- "extensions": ["wav"]
- },
- "audio/xm": {
- "source": "apache",
- "extensions": ["xm"]
- },
- "chemical/x-cdx": {
- "source": "apache",
- "extensions": ["cdx"]
- },
- "chemical/x-cif": {
- "source": "apache",
- "extensions": ["cif"]
- },
- "chemical/x-cmdf": {
- "source": "apache",
- "extensions": ["cmdf"]
- },
- "chemical/x-cml": {
- "source": "apache",
- "extensions": ["cml"]
- },
- "chemical/x-csml": {
- "source": "apache",
- "extensions": ["csml"]
- },
- "chemical/x-pdb": {
- "source": "apache"
- },
- "chemical/x-xyz": {
- "source": "apache",
- "extensions": ["xyz"]
- },
- "font/opentype": {
- "compressible": true,
- "extensions": ["otf"]
- },
- "image/bmp": {
- "source": "apache",
- "compressible": true,
- "extensions": ["bmp"]
- },
- "image/cgm": {
- "source": "iana",
- "extensions": ["cgm"]
- },
- "image/example": {
- "source": "iana"
- },
- "image/fits": {
- "source": "iana"
- },
- "image/g3fax": {
- "source": "iana",
- "extensions": ["g3"]
- },
- "image/gif": {
- "source": "iana",
- "compressible": false,
- "extensions": ["gif"]
- },
- "image/ief": {
- "source": "iana",
- "extensions": ["ief"]
- },
- "image/jp2": {
- "source": "iana"
- },
- "image/jpeg": {
- "source": "iana",
- "compressible": false,
- "extensions": ["jpeg","jpg","jpe"]
- },
- "image/jpm": {
- "source": "iana"
- },
- "image/jpx": {
- "source": "iana"
- },
- "image/ktx": {
- "source": "iana",
- "extensions": ["ktx"]
- },
- "image/naplps": {
- "source": "iana"
- },
- "image/pjpeg": {
- "compressible": false
- },
- "image/png": {
- "source": "iana",
- "compressible": false,
- "extensions": ["png"]
- },
- "image/prs.btif": {
- "source": "iana",
- "extensions": ["btif"]
- },
- "image/prs.pti": {
- "source": "iana"
- },
- "image/pwg-raster": {
- "source": "iana"
- },
- "image/sgi": {
- "source": "apache",
- "extensions": ["sgi"]
- },
- "image/svg+xml": {
- "source": "iana",
- "compressible": true,
- "extensions": ["svg","svgz"]
- },
- "image/t38": {
- "source": "iana"
- },
- "image/tiff": {
- "source": "iana",
- "compressible": false,
- "extensions": ["tiff","tif"]
- },
- "image/tiff-fx": {
- "source": "iana"
- },
- "image/vnd-djvu": {
- "source": "iana"
- },
- "image/vnd-svf": {
- "source": "iana"
- },
- "image/vnd-wap-wbmp": {
- "source": "iana"
- },
- "image/vnd.adobe.photoshop": {
- "source": "iana",
- "compressible": true,
- "extensions": ["psd"]
- },
- "image/vnd.airzip.accelerator.azv": {
- "source": "iana"
- },
- "image/vnd.cns.inf2": {
- "source": "iana"
- },
- "image/vnd.dece.graphic": {
- "source": "iana",
- "extensions": ["uvi","uvvi","uvg","uvvg"]
- },
- "image/vnd.djvu": {
- "source": "apache",
- "extensions": ["djvu","djv"]
- },
- "image/vnd.dvb.subtitle": {
- "source": "iana",
- "extensions": ["sub"]
- },
- "image/vnd.dwg": {
- "source": "iana",
- "extensions": ["dwg"]
- },
- "image/vnd.dxf": {
- "source": "iana",
- "extensions": ["dxf"]
- },
- "image/vnd.fastbidsheet": {
- "source": "iana",
- "extensions": ["fbs"]
- },
- "image/vnd.fpx": {
- "source": "iana",
- "extensions": ["fpx"]
- },
- "image/vnd.fst": {
- "source": "iana",
- "extensions": ["fst"]
- },
- "image/vnd.fujixerox.edmics-mmr": {
- "source": "iana",
- "extensions": ["mmr"]
- },
- "image/vnd.fujixerox.edmics-rlc": {
- "source": "iana",
- "extensions": ["rlc"]
- },
- "image/vnd.globalgraphics.pgb": {
- "source": "iana"
- },
- "image/vnd.microsoft.icon": {
- "source": "iana"
- },
- "image/vnd.mix": {
- "source": "iana"
- },
- "image/vnd.ms-modi": {
- "source": "iana",
- "extensions": ["mdi"]
- },
- "image/vnd.ms-photo": {
- "source": "apache",
- "extensions": ["wdp"]
- },
- "image/vnd.net-fpx": {
- "source": "iana",
- "extensions": ["npx"]
- },
- "image/vnd.radiance": {
- "source": "iana"
- },
- "image/vnd.sealed-png": {
- "source": "iana"
- },
- "image/vnd.sealed.png": {
- "source": "apache"
- },
- "image/vnd.sealedmedia.softseal-gif": {
- "source": "iana"
- },
- "image/vnd.sealedmedia.softseal-jpg": {
- "source": "iana"
- },
- "image/vnd.sealedmedia.softseal.gif": {
- "source": "apache"
- },
- "image/vnd.sealedmedia.softseal.jpg": {
- "source": "apache"
- },
- "image/vnd.svf": {
- "source": "apache"
- },
- "image/vnd.tencent.tap": {
- "source": "iana"
- },
- "image/vnd.valve.source.texture": {
- "source": "iana"
- },
- "image/vnd.wap.wbmp": {
- "source": "apache",
- "extensions": ["wbmp"]
- },
- "image/vnd.xiff": {
- "source": "iana",
- "extensions": ["xif"]
- },
- "image/webp": {
- "source": "apache",
- "extensions": ["webp"]
- },
- "image/x-3ds": {
- "source": "apache",
- "extensions": ["3ds"]
- },
- "image/x-cmu-raster": {
- "source": "apache",
- "extensions": ["ras"]
- },
- "image/x-cmx": {
- "source": "apache",
- "extensions": ["cmx"]
- },
- "image/x-freehand": {
- "source": "apache",
- "extensions": ["fh","fhc","fh4","fh5","fh7"]
- },
- "image/x-icon": {
- "source": "apache",
- "compressible": true,
- "extensions": ["ico"]
- },
- "image/x-mrsid-image": {
- "source": "apache",
- "extensions": ["sid"]
- },
- "image/x-pcx": {
- "source": "apache",
- "extensions": ["pcx"]
- },
- "image/x-pict": {
- "source": "apache",
- "extensions": ["pic","pct"]
- },
- "image/x-portable-anymap": {
- "source": "apache",
- "extensions": ["pnm"]
- },
- "image/x-portable-bitmap": {
- "source": "apache",
- "extensions": ["pbm"]
- },
- "image/x-portable-graymap": {
- "source": "apache",
- "extensions": ["pgm"]
- },
- "image/x-portable-pixmap": {
- "source": "apache",
- "extensions": ["ppm"]
- },
- "image/x-rgb": {
- "source": "apache",
- "extensions": ["rgb"]
- },
- "image/x-tga": {
- "source": "apache",
- "extensions": ["tga"]
- },
- "image/x-xbitmap": {
- "source": "apache",
- "extensions": ["xbm"]
- },
- "image/x-xcf": {
- "compressible": false
- },
- "image/x-xpixmap": {
- "source": "apache",
- "extensions": ["xpm"]
- },
- "image/x-xwindowdump": {
- "source": "apache",
- "extensions": ["xwd"]
- },
- "message/cpim": {
- "source": "iana"
- },
- "message/delivery-status": {
- "source": "iana"
- },
- "message/disposition-notification": {
- "source": "iana"
- },
- "message/example": {
- "source": "iana"
- },
- "message/external-body": {
- "source": "iana"
- },
- "message/feedback-report": {
- "source": "iana"
- },
- "message/global": {
- "source": "iana"
- },
- "message/global-delivery-status": {
- "source": "iana"
- },
- "message/global-disposition-notification": {
- "source": "iana"
- },
- "message/global-headers": {
- "source": "iana"
- },
- "message/http": {
- "source": "iana",
- "compressible": false
- },
- "message/imdn+xml": {
- "source": "iana",
- "compressible": true
- },
- "message/news": {
- "source": "iana"
- },
- "message/partial": {
- "source": "iana",
- "compressible": false
- },
- "message/rfc822": {
- "source": "iana",
- "compressible": true,
- "extensions": ["eml","mime"]
- },
- "message/s-http": {
- "source": "iana"
- },
- "message/sip": {
- "source": "iana"
- },
- "message/sipfrag": {
- "source": "iana"
- },
- "message/tracking-status": {
- "source": "iana"
- },
- "message/vnd.si.simp": {
- "source": "iana"
- },
- "message/vnd.wfa.wsc": {
- "source": "iana"
- },
- "model/example": {
- "source": "iana",
- "compressible": false
- },
- "model/iges": {
- "source": "iana",
- "compressible": false,
- "extensions": ["igs","iges"]
- },
- "model/mesh": {
- "source": "iana",
- "compressible": false,
- "extensions": ["msh","mesh","silo"]
- },
- "model/vnd-dwf": {
- "source": "iana"
- },
- "model/vnd.collada+xml": {
- "source": "iana",
- "extensions": ["dae"]
- },
- "model/vnd.dwf": {
- "source": "apache",
- "extensions": ["dwf"]
- },
- "model/vnd.flatland.3dml": {
- "source": "iana"
- },
- "model/vnd.gdl": {
- "source": "iana",
- "extensions": ["gdl"]
- },
- "model/vnd.gs-gdl": {
- "source": "iana"
- },
- "model/vnd.gs.gdl": {
- "source": "apache"
- },
- "model/vnd.gtw": {
- "source": "iana",
- "extensions": ["gtw"]
- },
- "model/vnd.moml+xml": {
- "source": "iana"
- },
- "model/vnd.mts": {
- "source": "iana",
- "extensions": ["mts"]
- },
- "model/vnd.opengex": {
- "source": "iana"
- },
- "model/vnd.parasolid.transmit-binary": {
- "source": "iana"
- },
- "model/vnd.parasolid.transmit-text": {
- "source": "iana"
- },
- "model/vnd.parasolid.transmit.binary": {
- "source": "apache"
- },
- "model/vnd.parasolid.transmit.text": {
- "source": "apache"
- },
- "model/vnd.valve.source.compiled-map": {
- "source": "iana"
- },
- "model/vnd.vtu": {
- "source": "iana",
- "extensions": ["vtu"]
- },
- "model/vrml": {
- "source": "iana",
- "compressible": false,
- "extensions": ["wrl","vrml"]
- },
- "model/x3d+binary": {
- "source": "apache",
- "compressible": false,
- "extensions": ["x3db","x3dbz"]
- },
- "model/x3d+fastinfoset": {
- "source": "iana"
- },
- "model/x3d+vrml": {
- "source": "apache",
- "compressible": false,
- "extensions": ["x3dv","x3dvz"]
- },
- "model/x3d+xml": {
- "source": "iana",
- "compressible": true,
- "extensions": ["x3d","x3dz"]
- },
- "model/x3d-vrml": {
- "source": "iana"
- },
- "multipart/alternative": {
- "source": "iana",
- "compressible": false
- },
- "multipart/appledouble": {
- "source": "iana"
- },
- "multipart/byteranges": {
- "source": "iana"
- },
- "multipart/digest": {
- "source": "iana"
- },
- "multipart/encrypted": {
- "source": "iana",
- "compressible": false
- },
- "multipart/example": {
- "source": "iana"
- },
- "multipart/form-data": {
- "source": "iana",
- "compressible": false
- },
- "multipart/header-set": {
- "source": "iana"
- },
- "multipart/mixed": {
- "source": "iana",
- "compressible": false
- },
- "multipart/parallel": {
- "source": "iana"
- },
- "multipart/related": {
- "source": "iana",
- "compressible": false
- },
- "multipart/report": {
- "source": "iana"
- },
- "multipart/signed": {
- "source": "iana",
- "compressible": false
- },
- "multipart/voice-message": {
- "source": "iana"
- },
- "multipart/x-mixed-replace": {
- "source": "iana"
- },
- "text/1d-interleaved-parityfec": {
- "source": "iana"
- },
- "text/cache-manifest": {
- "source": "iana",
- "compressible": true,
- "extensions": ["appcache","manifest"]
- },
- "text/calendar": {
- "source": "iana",
- "extensions": ["ics","ifb"]
- },
- "text/calender": {
- "compressible": true
- },
- "text/cmd": {
- "compressible": true
- },
- "text/coffeescript": {
- "extensions": ["coffee"]
- },
- "text/css": {
- "source": "iana",
- "compressible": true,
- "extensions": ["css"]
- },
- "text/csv": {
- "source": "iana",
- "compressible": true,
- "extensions": ["csv"]
- },
- "text/directory": {
- "source": "iana"
- },
- "text/dns": {
- "source": "iana"
- },
- "text/ecmascript": {
- "source": "iana"
- },
- "text/encaprtp": {
- "source": "iana"
- },
- "text/enriched": {
- "source": "iana"
- },
- "text/example": {
- "source": "iana"
- },
- "text/fwdred": {
- "source": "iana"
- },
- "text/grammar-ref-list": {
- "source": "iana"
- },
- "text/html": {
- "source": "iana",
- "compressible": true,
- "extensions": ["html","htm"]
- },
- "text/jade": {
- "extensions": ["jade"]
- },
- "text/javascript": {
- "source": "iana",
- "compressible": true
- },
- "text/jcr-cnd": {
- "source": "iana"
- },
- "text/jsx": {
- "compressible": true,
- "extensions": ["jsx"]
- },
- "text/less": {
- "extensions": ["less"]
- },
- "text/mizar": {
- "source": "iana"
- },
- "text/n3": {
- "source": "iana",
- "compressible": true,
- "extensions": ["n3"]
- },
- "text/parameters": {
- "source": "iana"
- },
- "text/parityfec": {
- "source": "iana"
- },
- "text/plain": {
- "source": "iana",
- "compressible": true,
- "extensions": ["txt","text","conf","def","list","log","in","ini"]
- },
- "text/provenance-notation": {
- "source": "iana"
- },
- "text/prs.fallenstein.rst": {
- "source": "iana"
- },
- "text/prs.lines.tag": {
- "source": "iana",
- "extensions": ["dsc"]
- },
- "text/raptorfec": {
- "source": "iana"
- },
- "text/red": {
- "source": "iana"
- },
- "text/rfc822-headers": {
- "source": "iana"
- },
- "text/richtext": {
- "source": "iana",
- "compressible": true,
- "extensions": ["rtx"]
- },
- "text/rtf": {
- "source": "iana"
- },
- "text/rtp-enc-aescm128": {
- "source": "iana"
- },
- "text/rtploopback": {
- "source": "iana"
- },
- "text/rtx": {
- "source": "iana"
- },
- "text/sgml": {
- "source": "iana",
- "extensions": ["sgml","sgm"]
- },
- "text/stylus": {
- "extensions": ["stylus","styl"]
- },
- "text/t140": {
- "source": "iana"
- },
- "text/tab-separated-values": {
- "source": "iana",
- "compressible": true,
- "extensions": ["tsv"]
- },
- "text/troff": {
- "source": "iana",
- "extensions": ["t","tr","roff","man","me","ms"]
- },
- "text/turtle": {
- "source": "iana",
- "extensions": ["ttl"]
- },
- "text/ulpfec": {
- "source": "iana"
- },
- "text/uri-list": {
- "source": "iana",
- "compressible": true,
- "extensions": ["uri","uris","urls"]
- },
- "text/vcard": {
- "source": "iana",
- "compressible": true,
- "extensions": ["vcard"]
- },
- "text/vnd-a": {
- "source": "iana"
- },
- "text/vnd-curl": {
- "source": "iana"
- },
- "text/vnd.abc": {
- "source": "iana"
- },
- "text/vnd.curl": {
- "source": "apache",
- "extensions": ["curl"]
- },
- "text/vnd.curl.dcurl": {
- "source": "apache",
- "extensions": ["dcurl"]
- },
- "text/vnd.curl.mcurl": {
- "source": "apache",
- "extensions": ["mcurl"]
- },
- "text/vnd.curl.scurl": {
- "source": "apache",
- "extensions": ["scurl"]
- },
- "text/vnd.debian.copyright": {
- "source": "iana"
- },
- "text/vnd.dmclientscript": {
- "source": "iana"
- },
- "text/vnd.dvb.subtitle": {
- "source": "iana",
- "extensions": ["sub"]
- },
- "text/vnd.esmertec.theme-descriptor": {
- "source": "iana"
- },
- "text/vnd.fly": {
- "source": "iana",
- "extensions": ["fly"]
- },
- "text/vnd.fmi.flexstor": {
- "source": "iana",
- "extensions": ["flx"]
- },
- "text/vnd.graphviz": {
- "source": "iana",
- "extensions": ["gv"]
- },
- "text/vnd.in3d.3dml": {
- "source": "iana",
- "extensions": ["3dml"]
- },
- "text/vnd.in3d.spot": {
- "source": "iana",
- "extensions": ["spot"]
- },
- "text/vnd.iptc.newsml": {
- "source": "iana"
- },
- "text/vnd.iptc.nitf": {
- "source": "iana"
- },
- "text/vnd.latex-z": {
- "source": "iana"
- },
- "text/vnd.motorola.reflex": {
- "source": "iana"
- },
- "text/vnd.ms-mediapackage": {
- "source": "iana"
- },
- "text/vnd.net2phone.commcenter.command": {
- "source": "iana"
- },
- "text/vnd.radisys.msml-basic-layout": {
- "source": "iana"
- },
- "text/vnd.si.uricatalogue": {
- "source": "iana"
- },
- "text/vnd.sun.j2me.app-descriptor": {
- "source": "iana",
- "extensions": ["jad"]
- },
- "text/vnd.trolltech.linguist": {
- "source": "iana"
- },
- "text/vnd.wap-wml": {
- "source": "iana"
- },
- "text/vnd.wap.si": {
- "source": "iana"
- },
- "text/vnd.wap.sl": {
- "source": "iana"
- },
- "text/vnd.wap.wml": {
- "source": "apache",
- "extensions": ["wml"]
- },
- "text/vnd.wap.wmlscript": {
- "source": "iana",
- "extensions": ["wmls"]
- },
- "text/vtt": {
- "charset": "UTF-8",
- "compressible": true,
- "extensions": ["vtt"]
- },
- "text/x-asm": {
- "source": "apache",
- "extensions": ["s","asm"]
- },
- "text/x-c": {
- "source": "apache",
- "extensions": ["c","cc","cxx","cpp","h","hh","dic"]
- },
- "text/x-component": {
- "extensions": ["htc"]
- },
- "text/x-fortran": {
- "source": "apache",
- "extensions": ["f","for","f77","f90"]
- },
- "text/x-gwt-rpc": {
- "compressible": true
- },
- "text/x-handlebars-template": {
- "extensions": ["hbs"]
- },
- "text/x-java-source": {
- "source": "apache",
- "extensions": ["java"]
- },
- "text/x-jquery-tmpl": {
- "compressible": true
- },
- "text/x-lua": {
- "extensions": ["lua"]
- },
- "text/x-markdown": {
- "compressible": true,
- "extensions": ["markdown","md","mkd"]
- },
- "text/x-nfo": {
- "source": "apache",
- "extensions": ["nfo"]
- },
- "text/x-opml": {
- "source": "apache",
- "extensions": ["opml"]
- },
- "text/x-pascal": {
- "source": "apache",
- "extensions": ["p","pas"]
- },
- "text/x-sass": {
- "extensions": ["sass"]
- },
- "text/x-scss": {
- "extensions": ["scss"]
- },
- "text/x-setext": {
- "source": "apache",
- "extensions": ["etx"]
- },
- "text/x-sfv": {
- "source": "apache",
- "extensions": ["sfv"]
- },
- "text/x-uuencode": {
- "source": "apache",
- "extensions": ["uu"]
- },
- "text/x-vcalendar": {
- "source": "apache",
- "extensions": ["vcs"]
- },
- "text/x-vcard": {
- "source": "apache",
- "extensions": ["vcf"]
- },
- "text/xml": {
- "source": "iana",
- "compressible": true
- },
- "text/xml-external-parsed-entity": {
- "source": "iana"
- },
- "video/1d-interleaved-parityfec": {
- "source": "apache"
- },
- "video/3gpp": {
- "source": "apache",
- "extensions": ["3gp"]
- },
- "video/3gpp-tt": {
- "source": "apache"
- },
- "video/3gpp2": {
- "source": "apache",
- "extensions": ["3g2"]
- },
- "video/bmpeg": {
- "source": "apache"
- },
- "video/bt656": {
- "source": "apache"
- },
- "video/celb": {
- "source": "apache"
- },
- "video/dv": {
- "source": "apache"
- },
- "video/example": {
- "source": "apache"
- },
- "video/h261": {
- "source": "apache",
- "extensions": ["h261"]
- },
- "video/h263": {
- "source": "apache",
- "extensions": ["h263"]
- },
- "video/h263-1998": {
- "source": "apache"
- },
- "video/h263-2000": {
- "source": "apache"
- },
- "video/h264": {
- "source": "apache",
- "extensions": ["h264"]
- },
- "video/h264-rcdo": {
- "source": "apache"
- },
- "video/h264-svc": {
- "source": "apache"
- },
- "video/jpeg": {
- "source": "apache",
- "extensions": ["jpgv"]
- },
- "video/jpeg2000": {
- "source": "apache"
- },
- "video/jpm": {
- "source": "apache",
- "extensions": ["jpm","jpgm"]
- },
- "video/mj2": {
- "source": "apache",
- "extensions": ["mj2","mjp2"]
- },
- "video/mp1s": {
- "source": "apache"
- },
- "video/mp2p": {
- "source": "apache"
- },
- "video/mp2t": {
- "source": "apache",
- "extensions": ["ts"]
- },
- "video/mp4": {
- "source": "apache",
- "compressible": false,
- "extensions": ["mp4","mp4v","mpg4"]
- },
- "video/mp4v-es": {
- "source": "apache"
- },
- "video/mpeg": {
- "source": "apache",
- "compressible": false,
- "extensions": ["mpeg","mpg","mpe","m1v","m2v"]
- },
- "video/mpeg4-generic": {
- "source": "apache"
- },
- "video/mpv": {
- "source": "apache"
- },
- "video/nv": {
- "source": "apache"
- },
- "video/ogg": {
- "source": "apache",
- "compressible": false,
- "extensions": ["ogv"]
- },
- "video/parityfec": {
- "source": "apache"
- },
- "video/pointer": {
- "source": "apache"
- },
- "video/quicktime": {
- "source": "apache",
- "compressible": false,
- "extensions": ["qt","mov"]
- },
- "video/raw": {
- "source": "apache"
- },
- "video/rtp-enc-aescm128": {
- "source": "apache"
- },
- "video/rtx": {
- "source": "apache"
- },
- "video/smpte292m": {
- "source": "apache"
- },
- "video/ulpfec": {
- "source": "apache"
- },
- "video/vc1": {
- "source": "apache"
- },
- "video/vnd.cctv": {
- "source": "apache"
- },
- "video/vnd.dece.hd": {
- "source": "apache",
- "extensions": ["uvh","uvvh"]
- },
- "video/vnd.dece.mobile": {
- "source": "apache",
- "extensions": ["uvm","uvvm"]
- },
- "video/vnd.dece.mp4": {
- "source": "apache"
- },
- "video/vnd.dece.pd": {
- "source": "apache",
- "extensions": ["uvp","uvvp"]
- },
- "video/vnd.dece.sd": {
- "source": "apache",
- "extensions": ["uvs","uvvs"]
- },
- "video/vnd.dece.video": {
- "source": "apache",
- "extensions": ["uvv","uvvv"]
- },
- "video/vnd.directv.mpeg": {
- "source": "apache"
- },
- "video/vnd.directv.mpeg-tts": {
- "source": "apache"
- },
- "video/vnd.dlna.mpeg-tts": {
- "source": "apache"
- },
- "video/vnd.dvb.file": {
- "source": "apache",
- "extensions": ["dvb"]
- },
- "video/vnd.fvt": {
- "source": "apache",
- "extensions": ["fvt"]
- },
- "video/vnd.hns.video": {
- "source": "apache"
- },
- "video/vnd.iptvforum.1dparityfec-1010": {
- "source": "apache"
- },
- "video/vnd.iptvforum.1dparityfec-2005": {
- "source": "apache"
- },
- "video/vnd.iptvforum.2dparityfec-1010": {
- "source": "apache"
- },
- "video/vnd.iptvforum.2dparityfec-2005": {
- "source": "apache"
- },
- "video/vnd.iptvforum.ttsavc": {
- "source": "apache"
- },
- "video/vnd.iptvforum.ttsmpeg2": {
- "source": "apache"
- },
- "video/vnd.motorola.video": {
- "source": "apache"
- },
- "video/vnd.motorola.videop": {
- "source": "apache"
- },
- "video/vnd.mpegurl": {
- "source": "apache",
- "extensions": ["mxu","m4u"]
- },
- "video/vnd.ms-playready.media.pyv": {
- "source": "apache",
- "extensions": ["pyv"]
- },
- "video/vnd.nokia.interleaved-multimedia": {
- "source": "apache"
- },
- "video/vnd.nokia.videovoip": {
- "source": "apache"
- },
- "video/vnd.objectvideo": {
- "source": "apache"
- },
- "video/vnd.sealed.mpeg1": {
- "source": "apache"
- },
- "video/vnd.sealed.mpeg4": {
- "source": "apache"
- },
- "video/vnd.sealed.swf": {
- "source": "apache"
- },
- "video/vnd.sealedmedia.softseal.mov": {
- "source": "apache"
- },
- "video/vnd.uvvu.mp4": {
- "source": "apache",
- "extensions": ["uvu","uvvu"]
- },
- "video/vnd.vivo": {
- "source": "apache",
- "extensions": ["viv"]
- },
- "video/webm": {
- "source": "apache",
- "compressible": false,
- "extensions": ["webm"]
- },
- "video/x-f4v": {
- "source": "apache",
- "extensions": ["f4v"]
- },
- "video/x-fli": {
- "source": "apache",
- "extensions": ["fli"]
- },
- "video/x-flv": {
- "source": "apache",
- "compressible": false,
- "extensions": ["flv"]
- },
- "video/x-m4v": {
- "source": "apache",
- "extensions": ["m4v"]
- },
- "video/x-matroska": {
- "source": "apache",
- "compressible": false,
- "extensions": ["mkv","mk3d","mks"]
- },
- "video/x-mng": {
- "source": "apache",
- "extensions": ["mng"]
- },
- "video/x-ms-asf": {
- "source": "apache",
- "extensions": ["asf","asx"]
- },
- "video/x-ms-vob": {
- "source": "apache",
- "extensions": ["vob"]
- },
- "video/x-ms-wm": {
- "source": "apache",
- "extensions": ["wm"]
- },
- "video/x-ms-wmv": {
- "source": "apache",
- "compressible": false,
- "extensions": ["wmv"]
- },
- "video/x-ms-wmx": {
- "source": "apache",
- "extensions": ["wmx"]
- },
- "video/x-ms-wvx": {
- "source": "apache",
- "extensions": ["wvx"]
- },
- "video/x-msvideo": {
- "source": "apache",
- "extensions": ["avi"]
- },
- "video/x-sgi-movie": {
- "source": "apache",
- "extensions": ["movie"]
- },
- "video/x-smv": {
- "source": "apache",
- "extensions": ["smv"]
- },
- "x-conference/x-cooltalk": {
- "source": "apache",
- "extensions": ["ice"]
- },
- "x-shader/x-fragment": {
- "compressible": true
- },
- "x-shader/x-vertex": {
- "compressible": true
- }
-}
diff --git a/CoAuthoring/node_modules/express/node_modules/type-is/node_modules/mime-types/node_modules/mime-db/index.js b/CoAuthoring/node_modules/express/node_modules/type-is/node_modules/mime-types/node_modules/mime-db/index.js
deleted file mode 100644
index 551031f690..0000000000
--- a/CoAuthoring/node_modules/express/node_modules/type-is/node_modules/mime-types/node_modules/mime-db/index.js
+++ /dev/null
@@ -1,11 +0,0 @@
-/*!
- * mime-db
- * Copyright(c) 2014 Jonathan Ong
- * MIT Licensed
- */
-
-/**
- * Module exports.
- */
-
-module.exports = require('./db.json')
diff --git a/CoAuthoring/node_modules/express/node_modules/type-is/node_modules/mime-types/node_modules/mime-db/package.json b/CoAuthoring/node_modules/express/node_modules/type-is/node_modules/mime-types/node_modules/mime-db/package.json
deleted file mode 100644
index 1a45988571..0000000000
--- a/CoAuthoring/node_modules/express/node_modules/type-is/node_modules/mime-types/node_modules/mime-db/package.json
+++ /dev/null
@@ -1,56 +0,0 @@
-{
- "name": "mime-db",
- "description": "Media Type Database",
- "version": "1.1.1",
- "author": {
- "name": "Jonathan Ong",
- "email": "me@jongleberry.com",
- "url": "http://jongleberry.com"
- },
- "license": "MIT",
- "repository": {
- "type": "git",
- "url": "git://github.com/jshttp/mime-db"
- },
- "devDependencies": {
- "co": "3",
- "cogent": "1",
- "csv-parse": "0",
- "gnode": "0.1.0",
- "istanbul": "0.3.2",
- "mocha": "~1.21.4",
- "stream-to-array": "2"
- },
- "engines": {
- "node": ">= 0.6"
- },
- "files": [
- "LICENSE",
- "db.json",
- "index.js"
- ],
- "scripts": {
- "update": "gnode scripts/extensions && gnode scripts/types && node scripts/build",
- "clean": "rm src/*",
- "test": "mocha --reporter spec --bail --check-leaks test/",
- "test-cov": "istanbul cover node_modules/mocha/bin/_mocha -- --reporter dot --check-leaks test/",
- "test-travis": "istanbul cover node_modules/mocha/bin/_mocha --report lcovonly -- --reporter spec --check-leaks test/"
- },
- "keywords": [
- "mime",
- "db",
- "type",
- "types",
- "database",
- "charset",
- "charsets"
- ],
- "readme": "# mime-db\n\n[![NPM Version][npm-version-image]][npm-url]\n[![NPM Downloads][npm-downloads-image]][npm-url]\n[![Node.js Version][node-image]][node-url]\n[![Build Status][travis-image]][travis-url]\n[![Coverage Status][coveralls-image]][coveralls-url]\n\nThis is a database of all mime types.\nIt consistents of a single, public JSON file and does not include any logic,\nallowing it to remain as unopinionated as possible with an API.\nIt aggregates data from the following sources:\n\n- http://www.iana.org/assignments/media-types/media-types.xhtml\n- http://svn.apache.org/repos/asf/httpd/httpd/trunk/docs/conf/mime.types\n\n## Usage\n\n```bash\nnpm i mime-db\n```\n\n```js\nvar db = require('mime-db');\n\n// grab data on .js files\nvar data = db['application/javascript'];\n```\n\nIf you're crazy enough to use this in the browser,\nyou can just grab the JSON file:\n\n```\nhttps://cdn.rawgit.com/jshttp/mime-db/master/db.json\n```\n\n## Data Structure\n\nThe JSON file is a map lookup for lowercased mime types.\nEach mime type has the following properties:\n\n- `.source` - where the mime type is defined.\n If not set, it's probably a custom media type.\n - `apache` - [Apache common media types](http://svn.apache.org/repos/asf/httpd/httpd/trunk/docs/conf/mime.types)\n - `iana` - [IANA-defined media types](http://www.iana.org/assignments/media-types/media-types.xhtml)\n- `.extensions[]` - known extensions associated with this mime type.\n- `.compressible` - whether a file of this type is can be gzipped.\n- `.charset` - the default charset associated with this type, if any.\n\nIf unknown, every property could be `undefined`.\n\n## Repository Structure\n\n- `scripts` - these are scripts to run to build the database\n- `src/` - this is a folder of files created from remote sources like Apache and IANA\n- `lib/` - this is a folder of our own custom sources and db, which will be merged into `db.json`\n- `db.json` - the final built JSON file for end-user usage\n\n## Contributing\n\nTo edit the database, only make PRs against files in the `lib/` folder.\nTo update the build, run `npm run update`.\n\n[npm-version-image]: https://img.shields.io/npm/v/mime-db.svg?style=flat\n[npm-downloads-image]: https://img.shields.io/npm/dm/mime-db.svg?style=flat\n[npm-url]: https://npmjs.org/package/mime-db\n[travis-image]: https://img.shields.io/travis/jshttp/mime-db.svg?style=flat\n[travis-url]: https://travis-ci.org/jshttp/mime-db\n[coveralls-image]: https://img.shields.io/coveralls/jshttp/mime-db.svg?style=flat\n[coveralls-url]: https://coveralls.io/r/jshttp/mime-db?branch=master\n[node-image]: https://img.shields.io/node/v/mime-db.svg?style=flat\n[node-url]: http://nodejs.org/download/\n",
- "readmeFilename": "README.md",
- "bugs": {
- "url": "https://github.com/jshttp/mime-db/issues"
- },
- "homepage": "https://github.com/jshttp/mime-db",
- "_id": "mime-db@1.1.1",
- "_from": "mime-db@~1.1.0"
-}
diff --git a/CoAuthoring/node_modules/express/node_modules/type-is/node_modules/mime-types/package.json b/CoAuthoring/node_modules/express/node_modules/type-is/node_modules/mime-types/package.json
deleted file mode 100644
index 45e7d2b8be..0000000000
--- a/CoAuthoring/node_modules/express/node_modules/type-is/node_modules/mime-types/package.json
+++ /dev/null
@@ -1,54 +0,0 @@
-{
- "name": "mime-types",
- "description": "The ultimate javascript content-type utility.",
- "version": "2.0.2",
- "contributors": [
- {
- "name": "Jeremiah Senkpiel",
- "email": "fishrock123@rocketmail.com",
- "url": "https://searchbeam.jit.su"
- },
- {
- "name": "Jonathan Ong",
- "email": "me@jongleberry.com",
- "url": "http://jongleberry.com"
- }
- ],
- "license": "MIT",
- "keywords": [
- "mime",
- "types"
- ],
- "repository": {
- "type": "git",
- "url": "git://github.com/jshttp/mime-types"
- },
- "dependencies": {
- "mime-db": "~1.1.0"
- },
- "devDependencies": {
- "istanbul": "0",
- "mocha": "1"
- },
- "files": [
- "HISTORY.md",
- "LICENSE",
- "index.js"
- ],
- "engines": {
- "node": ">= 0.6"
- },
- "scripts": {
- "test": "mocha --reporter spec test/test.js",
- "test-cov": "istanbul cover node_modules/mocha/bin/_mocha -- --reporter dot test/test.js",
- "test-travis": "istanbul cover node_modules/mocha/bin/_mocha --report lcovonly -- --reporter dot test/test.js"
- },
- "readme": "# mime-types\n\n[![NPM Version][npm-image]][npm-url]\n[![NPM Downloads][downloads-image]][downloads-url]\n[![Node.js Version][node-version-image]][node-version-url]\n[![Build Status][travis-image]][travis-url]\n[![Test Coverage][coveralls-image]][coveralls-url]\n\nThe ultimate javascript content-type utility.\n\nSimilar to [node-mime](https://github.com/broofa/node-mime), except:\n\n- __No fallbacks.__ Instead of naively returning the first available type, `mime-types` simply returns `false`,\n so do `var type = mime.lookup('unrecognized') || 'application/octet-stream'`.\n- No `new Mime()` business, so you could do `var lookup = require('mime-types').lookup`.\n- Additional mime types are added such as jade and stylus via [mime-db](https://github.com/jshttp/mime-db)\n- No `.define()` functionality\n\nOtherwise, the API is compatible.\n\n## Install\n\n```sh\n$ npm install mime-types\n```\n\n## Adding Types\n\nAll mime types are based on [mime-db](https://github.com/jshttp/mime-db),\nso open a PR there if you'd like to add mime types.\n\n## API\n\n```js\nvar mime = require('mime-types')\n```\n\nAll functions return `false` if input is invalid or not found.\n\n### mime.lookup(path)\n\nLookup the content-type associated with a file.\n\n```js\nmime.lookup('json') // 'application/json'\nmime.lookup('.md') // 'text/x-markdown'\nmime.lookup('file.html') // 'text/html'\nmime.lookup('folder/file.js') // 'application/javascript'\n\nmime.lookup('cats') // false\n```\n\n### mime.contentType(type)\n\nCreate a full content-type header given a content-type or extension.\n\n```js\nmime.contentType('markdown') // 'text/x-markdown; charset=utf-8'\nmime.contentType('file.json') // 'application/json; charset=utf-8'\n```\n\n### mime.extension(type)\n\nGet the default extension for a content-type.\n\n```js\nmime.extension('application/octet-stream') // 'bin'\n```\n\n### mime.charset(type)\n\nLookup the implied default charset of a content-type.\n\n```js\nmime.charset('text/x-markdown') // 'UTF-8'\n```\n\n### var type = mime.types[extension]\n\nA map of content-types by extension.\n\n### [extensions...] = mime.extensions[type]\n\nA map of extensions by content-type.\n\n## License\n\n[MIT](LICENSE)\n\n[npm-image]: https://img.shields.io/npm/v/mime-types.svg?style=flat\n[npm-url]: https://npmjs.org/package/mime-types\n[node-version-image]: https://img.shields.io/badge/node.js-%3E%3D_0.6-brightgreen.svg?style=flat\n[node-version-url]: http://nodejs.org/download/\n[travis-image]: https://img.shields.io/travis/jshttp/mime-types.svg?style=flat\n[travis-url]: https://travis-ci.org/jshttp/mime-types\n[coveralls-image]: https://img.shields.io/coveralls/jshttp/mime-types.svg?style=flat\n[coveralls-url]: https://coveralls.io/r/jshttp/mime-types\n[downloads-image]: https://img.shields.io/npm/dm/mime-types.svg?style=flat\n[downloads-url]: https://npmjs.org/package/mime-types\n",
- "readmeFilename": "README.md",
- "bugs": {
- "url": "https://github.com/jshttp/mime-types/issues"
- },
- "homepage": "https://github.com/jshttp/mime-types",
- "_id": "mime-types@2.0.2",
- "_from": "mime-types@~2.0.2"
-}
diff --git a/CoAuthoring/node_modules/express/node_modules/type-is/package.json b/CoAuthoring/node_modules/express/node_modules/type-is/package.json
deleted file mode 100644
index 74512a698e..0000000000
--- a/CoAuthoring/node_modules/express/node_modules/type-is/package.json
+++ /dev/null
@@ -1,55 +0,0 @@
-{
- "name": "type-is",
- "description": "Infer the content-type of a request.",
- "version": "1.5.2",
- "author": {
- "name": "Jonathan Ong",
- "email": "me@jongleberry.com",
- "url": "http://jongleberry.com"
- },
- "contributors": [
- {
- "name": "Douglas Christopher Wilson",
- "email": "doug@somethingdoug.com"
- }
- ],
- "license": "MIT",
- "repository": {
- "type": "git",
- "url": "git://github.com/jshttp/type-is"
- },
- "dependencies": {
- "media-typer": "0.3.0",
- "mime-types": "~2.0.2"
- },
- "devDependencies": {
- "istanbul": "~0.3.0",
- "mocha": "1"
- },
- "engines": {
- "node": ">= 0.6"
- },
- "files": [
- "LICENSE",
- "HISTORY.md",
- "index.js"
- ],
- "scripts": {
- "test": "mocha --reporter spec --check-leaks --bail test/",
- "test-cov": "istanbul cover node_modules/mocha/bin/_mocha -- --reporter dot --check-leaks test/",
- "test-travis": "istanbul cover node_modules/mocha/bin/_mocha --report lcovonly -- --reporter spec --check-leaks test/"
- },
- "keywords": [
- "content",
- "type",
- "checking"
- ],
- "readme": "# type-is\n\n[![NPM Version][npm-image]][npm-url]\n[![NPM Downloads][downloads-image]][downloads-url]\n[![Node.js Version][node-version-image]][node-version-url]\n[![Build Status][travis-image]][travis-url]\n[![Test Coverage][coveralls-image]][coveralls-url]\n\nInfer the content-type of a request.\n\n### Install\n\n```sh\n$ npm install type-is\n```\n\n## API\n\n```js\nvar http = require('http')\nvar is = require('type-is')\n\nhttp.createServer(function (req, res) {\n var istext = is(req, ['text/*'])\n res.end('you ' + (istext ? 'sent' : 'did not send') + ' me text')\n})\n```\n\n### type = is(request, types)\n\n`request` is the node HTTP request. `types` is an array of types.\n\n```js\n// req.headers.content-type = 'application/json'\n\nis(req, ['json']) // 'json'\nis(req, ['html', 'json']) // 'json'\nis(req, ['application/*']) // 'application/json'\nis(req, ['application/json']) // 'application/json'\n\nis(req, ['html']) // false\n```\n\n#### Each type can be:\n\n- An extension name such as `json`. This name will be returned if matched.\n- A mime type such as `application/json`.\n- A mime type with a wildcard such as `*/json` or `application/*`. The full mime type will be returned if matched\n- A suffix such as `+json`. This can be combined with a wildcard such as `*/vnd+json` or `application/*+json`. The full mime type will be returned if matched.\n\n`false` will be returned if no type matches.\n\n## Examples\n\n#### Example body parser\n\n```js\nvar is = require('type-is');\n\nfunction bodyParser(req, res, next) {\n if (!is.hasBody(req)) {\n return next()\n }\n\n switch (is(req, ['urlencoded', 'json', 'multipart'])) {\n case 'urlencoded':\n // parse urlencoded body\n throw new Error('implement urlencoded body parsing')\n break\n case 'json':\n // parse json body\n throw new Error('implement json body parsing')\n break\n case 'multipart':\n // parse multipart body\n throw new Error('implement multipart body parsing')\n break\n default:\n // 415 error code\n res.statusCode = 415\n res.end()\n return\n }\n}\n```\n\n## License\n\n[MIT](LICENSE)\n\n[npm-image]: https://img.shields.io/npm/v/type-is.svg?style=flat\n[npm-url]: https://npmjs.org/package/type-is\n[node-version-image]: https://img.shields.io/node/v/type-is.svg?style=flat\n[node-version-url]: http://nodejs.org/download/\n[travis-image]: https://img.shields.io/travis/jshttp/type-is.svg?style=flat\n[travis-url]: https://travis-ci.org/jshttp/type-is\n[coveralls-image]: https://img.shields.io/coveralls/jshttp/type-is.svg?style=flat\n[coveralls-url]: https://coveralls.io/r/jshttp/type-is?branch=master\n[downloads-image]: https://img.shields.io/npm/dm/type-is.svg?style=flat\n[downloads-url]: https://npmjs.org/package/type-is\n",
- "readmeFilename": "README.md",
- "bugs": {
- "url": "https://github.com/jshttp/type-is/issues"
- },
- "homepage": "https://github.com/jshttp/type-is",
- "_id": "type-is@1.5.2",
- "_from": "type-is@~1.5.2"
-}
diff --git a/CoAuthoring/node_modules/express/node_modules/utils-merge/.travis.yml b/CoAuthoring/node_modules/express/node_modules/utils-merge/.travis.yml
deleted file mode 100644
index af92b021be..0000000000
--- a/CoAuthoring/node_modules/express/node_modules/utils-merge/.travis.yml
+++ /dev/null
@@ -1,6 +0,0 @@
-language: "node_js"
-node_js:
- - "0.4"
- - "0.6"
- - "0.8"
- - "0.10"
diff --git a/CoAuthoring/node_modules/express/node_modules/utils-merge/LICENSE b/CoAuthoring/node_modules/express/node_modules/utils-merge/LICENSE
deleted file mode 100644
index e33bd10bb4..0000000000
--- a/CoAuthoring/node_modules/express/node_modules/utils-merge/LICENSE
+++ /dev/null
@@ -1,20 +0,0 @@
-(The MIT License)
-
-Copyright (c) 2013 Jared Hanson
-
-Permission is hereby granted, free of charge, to any person obtaining a copy of
-this software and associated documentation files (the "Software"), to deal in
-the Software without restriction, including without limitation the rights to
-use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
-the Software, and to permit persons to whom the Software is furnished to do so,
-subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in all
-copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
-FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
-COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
-IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
-CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
diff --git a/CoAuthoring/node_modules/express/node_modules/utils-merge/README.md b/CoAuthoring/node_modules/express/node_modules/utils-merge/README.md
deleted file mode 100644
index 2f94e9bd2e..0000000000
--- a/CoAuthoring/node_modules/express/node_modules/utils-merge/README.md
+++ /dev/null
@@ -1,34 +0,0 @@
-# utils-merge
-
-Merges the properties from a source object into a destination object.
-
-## Install
-
- $ npm install utils-merge
-
-## Usage
-
-```javascript
-var a = { foo: 'bar' }
- , b = { bar: 'baz' };
-
-merge(a, b);
-// => { foo: 'bar', bar: 'baz' }
-```
-
-## Tests
-
- $ npm install
- $ npm test
-
-[](http://travis-ci.org/jaredhanson/utils-merge)
-
-## Credits
-
- - [Jared Hanson](http://github.com/jaredhanson)
-
-## License
-
-[The MIT License](http://opensource.org/licenses/MIT)
-
-Copyright (c) 2013 Jared Hanson <[http://jaredhanson.net/](http://jaredhanson.net/)>
diff --git a/CoAuthoring/node_modules/express/node_modules/utils-merge/index.js b/CoAuthoring/node_modules/express/node_modules/utils-merge/index.js
deleted file mode 100644
index 4265c694fe..0000000000
--- a/CoAuthoring/node_modules/express/node_modules/utils-merge/index.js
+++ /dev/null
@@ -1,23 +0,0 @@
-/**
- * Merge object b with object a.
- *
- * var a = { foo: 'bar' }
- * , b = { bar: 'baz' };
- *
- * merge(a, b);
- * // => { foo: 'bar', bar: 'baz' }
- *
- * @param {Object} a
- * @param {Object} b
- * @return {Object}
- * @api public
- */
-
-exports = module.exports = function(a, b){
- if (a && b) {
- for (var key in b) {
- a[key] = b[key];
- }
- }
- return a;
-};
diff --git a/CoAuthoring/node_modules/express/node_modules/utils-merge/package.json b/CoAuthoring/node_modules/express/node_modules/utils-merge/package.json
deleted file mode 100644
index 967cc31198..0000000000
--- a/CoAuthoring/node_modules/express/node_modules/utils-merge/package.json
+++ /dev/null
@@ -1,43 +0,0 @@
-{
- "name": "utils-merge",
- "version": "1.0.0",
- "description": "merge() utility function",
- "keywords": [
- "util"
- ],
- "repository": {
- "type": "git",
- "url": "git://github.com/jaredhanson/utils-merge.git"
- },
- "bugs": {
- "url": "http://github.com/jaredhanson/utils-merge/issues"
- },
- "author": {
- "name": "Jared Hanson",
- "email": "jaredhanson@gmail.com",
- "url": "http://www.jaredhanson.net/"
- },
- "licenses": [
- {
- "type": "MIT",
- "url": "http://www.opensource.org/licenses/MIT"
- }
- ],
- "main": "./index",
- "dependencies": {},
- "devDependencies": {
- "mocha": "1.x.x",
- "chai": "1.x.x"
- },
- "scripts": {
- "test": "mocha --reporter spec --require test/bootstrap/node test/*.test.js"
- },
- "engines": {
- "node": ">= 0.4.0"
- },
- "readme": "# utils-merge\n\nMerges the properties from a source object into a destination object.\n\n## Install\n\n $ npm install utils-merge\n\n## Usage\n\n```javascript\nvar a = { foo: 'bar' }\n , b = { bar: 'baz' };\n\nmerge(a, b);\n// => { foo: 'bar', bar: 'baz' }\n```\n\n## Tests\n\n $ npm install\n $ npm test\n\n[](http://travis-ci.org/jaredhanson/utils-merge)\n\n## Credits\n\n - [Jared Hanson](http://github.com/jaredhanson)\n\n## License\n\n[The MIT License](http://opensource.org/licenses/MIT)\n\nCopyright (c) 2013 Jared Hanson <[http://jaredhanson.net/](http://jaredhanson.net/)>\n",
- "readmeFilename": "README.md",
- "homepage": "https://github.com/jaredhanson/utils-merge",
- "_id": "utils-merge@1.0.0",
- "_from": "utils-merge@1.0.0"
-}
diff --git a/CoAuthoring/node_modules/express/node_modules/vary/.npmignore b/CoAuthoring/node_modules/express/node_modules/vary/.npmignore
deleted file mode 100644
index cd39b7720a..0000000000
--- a/CoAuthoring/node_modules/express/node_modules/vary/.npmignore
+++ /dev/null
@@ -1,3 +0,0 @@
-coverage/
-test/
-.travis.yml
diff --git a/CoAuthoring/node_modules/express/node_modules/vary/History.md b/CoAuthoring/node_modules/express/node_modules/vary/History.md
deleted file mode 100644
index e5d8e6942c..0000000000
--- a/CoAuthoring/node_modules/express/node_modules/vary/History.md
+++ /dev/null
@@ -1,16 +0,0 @@
-1.0.0 / 2014-08-10
-==================
-
- * Accept valid `Vary` header string as `field`
- * Add `vary.append` for low-level string manipulation
- * Move to `jshttp` orgainzation
-
-0.1.0 / 2014-06-05
-==================
-
- * Support array of fields to set
-
-0.0.0 / 2014-06-04
-==================
-
- * Initial release
diff --git a/CoAuthoring/node_modules/express/node_modules/vary/LICENSE b/CoAuthoring/node_modules/express/node_modules/vary/LICENSE
deleted file mode 100644
index b7dce6cf9a..0000000000
--- a/CoAuthoring/node_modules/express/node_modules/vary/LICENSE
+++ /dev/null
@@ -1,22 +0,0 @@
-(The MIT License)
-
-Copyright (c) 2014 Douglas Christopher Wilson
-
-Permission is hereby granted, free of charge, to any person obtaining
-a copy of this software and associated documentation files (the
-'Software'), to deal in the Software without restriction, including
-without limitation the rights to use, copy, modify, merge, publish,
-distribute, sublicense, and/or sell copies of the Software, and to
-permit persons to whom the Software is furnished to do so, subject to
-the following conditions:
-
-The above copyright notice and this permission notice shall be
-included in all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
-EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
-IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
-CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
-TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
-SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
diff --git a/CoAuthoring/node_modules/express/node_modules/vary/README.md b/CoAuthoring/node_modules/express/node_modules/vary/README.md
deleted file mode 100644
index 82392d0873..0000000000
--- a/CoAuthoring/node_modules/express/node_modules/vary/README.md
+++ /dev/null
@@ -1,59 +0,0 @@
-# vary
-
-[](https://www.npmjs.org/package/vary)
-[](http://nodejs.org/download/)
-[](https://travis-ci.org/jshttp/vary)
-[](https://coveralls.io/r/jshttp/vary)
-[](https://www.gittip.com/dougwilson/)
-
-Manipulate the HTTP Vary header
-
-## Install
-
-```sh
-$ npm install vary
-```
-
-## API
-
-```js
-var vary = require('vary')
-```
-
-### vary(res, field)
-
-Adds the given header `field` to the `Vary` response header of `res`.
-This can be a string of a single field, a string of a valid `Vary`
-header, or an array of multiple fields.
-
-This will append the header if not already listed, otherwise leaves
-it listed in the current location.
-
-```js
-// Append "Origin" to the Vary header of the response
-vary(res, 'Origin')
-```
-
-### vary.append(header, field)
-
-Adds the given header `field` to the `Vary` response header string `header`.
-This can be a string of a single field, a string of a valid `Vary` header,
-or an array of multiple fields.
-
-This will append the header if not already listed, otherwise leaves
-it listed in the current location. The new header string is returned.
-
-```js
-// Get header string appending "Origin" to "Accept, User-Agent"
-vary.append('Accept, User-Agent', 'Origin')
-```
-
-## Testing
-
-```sh
-$ npm test
-```
-
-## License
-
-[MIT](LICENSE)
diff --git a/CoAuthoring/node_modules/express/node_modules/vary/index.js b/CoAuthoring/node_modules/express/node_modules/vary/index.js
deleted file mode 100644
index 1e544e819d..0000000000
--- a/CoAuthoring/node_modules/express/node_modules/vary/index.js
+++ /dev/null
@@ -1,112 +0,0 @@
-/*!
- * vary
- * Copyright(c) 2014 Douglas Christopher Wilson
- * MIT Licensed
- */
-
-/**
- * Module exports.
- */
-
-module.exports = vary;
-module.exports.append = append;
-
-/**
- * Variables.
- */
-
-var separators = /[\(\)<>@,;:\\"\/\[\]\?=\{\}\u0020\u0009]/;
-
-/**
- * Append a field to a vary header.
- *
- * @param {String} header
- * @param {String|Array} field
- * @return {String}
- * @api public
- */
-
-function append(header, field) {
- if (typeof header !== 'string') {
- throw new TypeError('header argument is required');
- }
-
- if (!field) {
- throw new TypeError('field argument is required');
- }
-
- // get fields array
- var fields = !Array.isArray(field)
- ? parse(String(field))
- : field;
-
- // assert on invalid fields
- for (var i = 0; i < fields.length; i++) {
- if (separators.test(fields[i])) {
- throw new TypeError('field argument contains an invalid header');
- }
- }
-
- // existing, unspecified vary
- if (header === '*') {
- return header;
- }
-
- // enumerate current values
- var vals = parse(header.toLowerCase());
-
- // unspecified vary
- if (fields.indexOf('*') !== -1 || vals.indexOf('*') !== -1) {
- return '*';
- }
-
- for (var i = 0; i < fields.length; i++) {
- field = fields[i].toLowerCase();
-
- // append value (case-preserving)
- if (vals.indexOf(field) === -1) {
- vals.push(field);
- header = header
- ? header + ', ' + fields[i]
- : fields[i];
- }
- }
-
- return header;
-}
-
-/**
- * Parse a vary header into an array.
- *
- * @param {String} header
- * @return {Array}
- * @api private
- */
-
-function parse(header) {
- return header.trim().split(/ *, */);
-}
-
-/**
- * Mark that a request is varied on a header field.
- *
- * @param {Object} res
- * @param {String|Array} field
- * @api public
- */
-
-function vary(res, field) {
- if (!res || !res.getHeader || !res.setHeader) {
- // quack quack
- throw new TypeError('res argument is required');
- }
-
- // get existing header
- var val = res.getHeader('Vary') || ''
- var header = Array.isArray(val)
- ? val.join(', ')
- : String(val);
-
- // set new header
- res.setHeader('Vary', append(header, field));
-}
diff --git a/CoAuthoring/node_modules/express/node_modules/vary/package.json b/CoAuthoring/node_modules/express/node_modules/vary/package.json
deleted file mode 100644
index 5968cc1aa5..0000000000
--- a/CoAuthoring/node_modules/express/node_modules/vary/package.json
+++ /dev/null
@@ -1,41 +0,0 @@
-{
- "name": "vary",
- "description": "Manipulate the HTTP Vary header",
- "version": "1.0.0",
- "author": {
- "name": "Douglas Christopher Wilson",
- "email": "doug@somethingdoug.com"
- },
- "license": "MIT",
- "keywords": [
- "http",
- "res",
- "vary"
- ],
- "repository": {
- "type": "git",
- "url": "git://github.com/jshttp/vary"
- },
- "devDependencies": {
- "istanbul": "0.3.0",
- "mocha": "~1.21.4",
- "should": "~4.0.4",
- "supertest": "~0.13.0"
- },
- "engines": {
- "node": ">= 0.8.0"
- },
- "scripts": {
- "test": "mocha --reporter spec --bail --check-leaks test/",
- "test-cov": "istanbul cover node_modules/mocha/bin/_mocha -- --reporter dot --check-leaks test/",
- "test-travis": "istanbul cover node_modules/mocha/bin/_mocha --report lcovonly -- --reporter spec --check-leaks test/"
- },
- "readme": "# vary\n\n[](https://www.npmjs.org/package/vary)\n[](http://nodejs.org/download/)\n[](https://travis-ci.org/jshttp/vary)\n[](https://coveralls.io/r/jshttp/vary)\n[](https://www.gittip.com/dougwilson/)\n\nManipulate the HTTP Vary header\n\n## Install\n\n```sh\n$ npm install vary\n```\n\n## API\n\n```js\nvar vary = require('vary')\n```\n\n### vary(res, field)\n\nAdds the given header `field` to the `Vary` response header of `res`.\nThis can be a string of a single field, a string of a valid `Vary`\nheader, or an array of multiple fields.\n\nThis will append the header if not already listed, otherwise leaves\nit listed in the current location.\n\n```js\n// Append \"Origin\" to the Vary header of the response\nvary(res, 'Origin')\n```\n\n### vary.append(header, field)\n\nAdds the given header `field` to the `Vary` response header string `header`.\nThis can be a string of a single field, a string of a valid `Vary` header,\nor an array of multiple fields.\n\nThis will append the header if not already listed, otherwise leaves\nit listed in the current location. The new header string is returned.\n\n```js\n// Get header string appending \"Origin\" to \"Accept, User-Agent\"\nvary.append('Accept, User-Agent', 'Origin')\n```\n\n## Testing\n\n```sh\n$ npm test\n```\n\n## License\n\n[MIT](LICENSE)\n",
- "readmeFilename": "README.md",
- "bugs": {
- "url": "https://github.com/jshttp/vary/issues"
- },
- "homepage": "https://github.com/jshttp/vary",
- "_id": "vary@1.0.0",
- "_from": "vary@~1.0.0"
-}
diff --git a/CoAuthoring/node_modules/express/package.json b/CoAuthoring/node_modules/express/package.json
deleted file mode 100644
index f4e1b9e747..0000000000
--- a/CoAuthoring/node_modules/express/package.json
+++ /dev/null
@@ -1,117 +0,0 @@
-{
- "name": "express",
- "description": "Fast, unopinionated, minimalist web framework",
- "version": "4.9.8",
- "author": {
- "name": "TJ Holowaychuk",
- "email": "tj@vision-media.ca"
- },
- "contributors": [
- {
- "name": "Aaron Heckmann",
- "email": "aaron.heckmann+github@gmail.com"
- },
- {
- "name": "Ciaran Jessup",
- "email": "ciaranj@gmail.com"
- },
- {
- "name": "Douglas Christopher Wilson",
- "email": "doug@somethingdoug.com"
- },
- {
- "name": "Guillermo Rauch",
- "email": "rauchg@gmail.com"
- },
- {
- "name": "Jonathan Ong",
- "email": "me@jongleberry.com"
- },
- {
- "name": "Roman Shtylman",
- "email": "shtylman+expressjs@gmail.com"
- },
- {
- "name": "Young Jae Sim",
- "email": "hanul@hanul.me"
- }
- ],
- "keywords": [
- "express",
- "framework",
- "sinatra",
- "web",
- "rest",
- "restful",
- "router",
- "app",
- "api"
- ],
- "repository": {
- "type": "git",
- "url": "git://github.com/strongloop/express"
- },
- "license": "MIT",
- "homepage": "http://expressjs.com/",
- "dependencies": {
- "accepts": "~1.1.2",
- "cookie-signature": "1.0.5",
- "debug": "~2.0.0",
- "depd": "0.4.5",
- "escape-html": "1.0.1",
- "etag": "~1.4.0",
- "finalhandler": "0.2.0",
- "fresh": "0.2.4",
- "media-typer": "0.3.0",
- "methods": "1.1.0",
- "on-finished": "~2.1.0",
- "parseurl": "~1.3.0",
- "path-to-regexp": "0.1.3",
- "proxy-addr": "~1.0.3",
- "qs": "2.2.4",
- "range-parser": "~1.0.2",
- "send": "0.9.3",
- "serve-static": "~1.6.4",
- "type-is": "~1.5.2",
- "vary": "~1.0.0",
- "cookie": "0.1.2",
- "merge-descriptors": "0.0.2",
- "utils-merge": "1.0.0"
- },
- "devDependencies": {
- "after": "0.8.1",
- "istanbul": "0.3.2",
- "mocha": "~1.21.5",
- "should": "~4.0.4",
- "supertest": "~0.14.0",
- "ejs": "~1.0.0",
- "marked": "0.3.2",
- "hjs": "~0.0.6",
- "body-parser": "~1.8.2",
- "connect-redis": "~2.1.0",
- "cookie-parser": "~1.3.3",
- "express-session": "~1.8.2",
- "jade": "~1.6.0",
- "method-override": "~2.2.0",
- "morgan": "~1.3.1",
- "multiparty": "~3.3.2",
- "vhost": "~3.0.0"
- },
- "engines": {
- "node": ">= 0.10.0"
- },
- "scripts": {
- "prepublish": "npm prune",
- "test": "mocha --require test/support/env --reporter spec --bail --check-leaks test/ test/acceptance/",
- "test-cov": "istanbul cover node_modules/mocha/bin/_mocha -- --require test/support/env --reporter dot --check-leaks test/ test/acceptance/",
- "test-tap": "mocha --require test/support/env --reporter tap --check-leaks test/ test/acceptance/",
- "test-travis": "istanbul cover node_modules/mocha/bin/_mocha --report lcovonly -- --require test/support/env --reporter spec --check-leaks test/ test/acceptance/"
- },
- "readme": "[](http://expressjs.com/)\n\n Fast, unopinionated, minimalist web framework for [node](http://nodejs.org).\n\n [](https://www.npmjs.org/package/express)\n [](https://travis-ci.org/strongloop/express)\n [](https://coveralls.io/r/strongloop/express)\n [](https://www.gittip.com/dougwilson/)\n\n```js\nvar express = require('express')\nvar app = express()\n\napp.get('/', function (req, res) {\n res.send('Hello World')\n})\n\napp.listen(3000)\n```\n\n **PROTIP** Be sure to read [Migrating from 3.x to 4.x](https://github.com/strongloop/express/wiki/Migrating-from-3.x-to-4.x) as well as [New features in 4.x](https://github.com/strongloop/express/wiki/New-features-in-4.x).\n\n### Installation\n\n```bash\n$ npm install express\n```\n\n## Quick Start\n\n The quickest way to get started with express is to utilize the executable [`express(1)`](https://github.com/expressjs/generator) to generate an application as shown below:\n\n Install the executable. The executable's major version will match Express's:\n\n```bash\n$ npm install -g express-generator@4\n```\n\n Create the app:\n\n```bash\n$ express /tmp/foo && cd /tmp/foo\n```\n\n Install dependencies:\n\n```bash\n$ npm install\n```\n\n Start the server:\n\n```bash\n$ npm start\n```\n\n## Features\n\n * Robust routing\n * HTTP helpers (redirection, caching, etc)\n * View system supporting 14+ template engines\n * Content negotiation\n * Focus on high performance\n * Executable for generating applications quickly\n * High test coverage\n\n## Philosophy\n\n The Express philosophy is to provide small, robust tooling for HTTP servers, making\n it a great solution for single page applications, web sites, hybrids, or public\n HTTP APIs.\n\n Express does not force you to use any specific ORM or template engine. With support for over\n 14 template engines via [Consolidate.js](https://github.com/visionmedia/consolidate.js),\n you can quickly craft your perfect framework.\n\n## More Information\n\n * [Website and Documentation](http://expressjs.com/) - [[website repo](https://github.com/strongloop/expressjs.com)]\n * [Github Organization](https://github.com/expressjs) for Official Middleware & Modules\n * [#express](https://webchat.freenode.net/?channels=express) on freenode IRC\n * Visit the [Wiki](https://github.com/strongloop/express/wiki)\n * [Google Group](https://groups.google.com/group/express-js) for discussion\n * [Русскоязычная документация](http://jsman.ru/express/)\n * [한국어 문서](http://expressjs.kr) - [[website repo](https://github.com/Hanul/expressjs.kr)]\n * Run express examples [online](https://runnable.com/express)\n\n## Viewing Examples\n\n Clone the Express repo, then install the dev dependencies to install all the example / test suite dependencies:\n\n```bash\n$ git clone git://github.com/strongloop/express.git --depth 1\n$ cd express\n$ npm install\n```\n\n Then run whichever example you want:\n\n $ node examples/content-negotiation\n\n You can also view live examples here:\n\n \n\n## Running Tests\n\n To run the test suite, first invoke the following command within the repo, installing the development dependencies:\n\n```bash\n$ npm install\n```\n\n Then run the tests:\n\n```bash\n$ npm test\n```\n\n### Contributors\n\n * Author: [TJ Holowaychuk](https://github.com/visionmedia)\n * Lead Maintainer: [Douglas Christopher Wilson](https://github.com/dougwilson)\n * [All Contributors](https://github.com/strongloop/express/graphs/contributors)\n\n### License\n\n [MIT](LICENSE)\n",
- "readmeFilename": "Readme.md",
- "bugs": {
- "url": "https://github.com/strongloop/express/issues"
- },
- "_id": "express@4.9.8",
- "_from": "express@"
-}
diff --git a/CoAuthoring/node_modules/mongodb/.travis.yml b/CoAuthoring/node_modules/mongodb/.travis.yml
deleted file mode 100644
index 90b208a4d8..0000000000
--- a/CoAuthoring/node_modules/mongodb/.travis.yml
+++ /dev/null
@@ -1,5 +0,0 @@
-language: node_js
-node_js:
- - 0.4
- - 0.6
- - 0.7 # development version of 0.8, may be unstable
\ No newline at end of file
diff --git a/CoAuthoring/node_modules/mongodb/Makefile b/CoAuthoring/node_modules/mongodb/Makefile
deleted file mode 100644
index d5a7677e3a..0000000000
--- a/CoAuthoring/node_modules/mongodb/Makefile
+++ /dev/null
@@ -1,75 +0,0 @@
-NODE = node
-NPM = npm
-NODEUNIT = node_modules/nodeunit/bin/nodeunit
-DOX = node_modules/dox/bin/dox
-name = all
-
-total: build_native
-
-build_native:
- # $(MAKE) -C ./external-libs/bson all
-
-build_native_debug:
- $(MAKE) -C ./external-libs/bson all_debug
-
-build_native_clang:
- $(MAKE) -C ./external-libs/bson clang
-
-build_native_clang_debug:
- $(MAKE) -C ./external-libs/bson clang_debug
-
-clean_native:
- $(MAKE) -C ./external-libs/bson clean
-
-test: build_native
- @echo "\n == Run All tests minus replicaset tests=="
- $(NODE) dev/tools/test_all.js --noreplicaset --boot
-
-test_pure: build_native
- @echo "\n == Run All tests minus replicaset tests=="
- $(NODE) dev/tools/test_all.js --noreplicaset --boot --nonative
-
-test_junit: build_native
- @echo "\n == Run All tests minus replicaset tests=="
- $(NODE) dev/tools/test_all.js --junit --noreplicaset --nokill
-
-jenkins: build_native
- @echo "\n == Run All tests minus replicaset tests=="
- $(NODE) dev/tools/test_all.js --junit --noreplicaset --nokill
-
-test_nodeunit_pure:
- @echo "\n == Execute Test Suite using Pure JS BSON Parser == "
- @$(NODEUNIT) test/ test/gridstore test/bson
-
-test_js:
- @$(NODEUNIT) $(TESTS)
-
-test_nodeunit_replicaset_pure:
- @echo "\n == Execute Test Suite using Pure JS BSON Parser == "
- @$(NODEUNIT) test/replicaset
-
-test_nodeunit_native:
- @echo "\n == Execute Test Suite using Native BSON Parser == "
- @TEST_NATIVE=TRUE $(NODEUNIT) test/ test/gridstore test/bson
-
-test_nodeunit_replicaset_native:
- @echo "\n == Execute Test Suite using Native BSON Parser == "
- @TEST_NATIVE=TRUE $(NODEUNIT) test/replicaset
-
-test_all: build_native
- @echo "\n == Run All tests =="
- $(NODE) dev/tools/test_all.js --boot
-
-test_all_junit: build_native
- @echo "\n == Run All tests =="
- $(NODE) dev/tools/test_all.js --junit --boot
-
-clean:
- rm ./external-libs/bson/bson.node
- rm -r ./external-libs/bson/build
-
-generate_docs:
- $(NODE) dev/tools/build-docs.js
- make --directory=./docs/sphinx-docs --file=Makefile html
-
-.PHONY: total
diff --git a/CoAuthoring/node_modules/mongodb/index.js b/CoAuthoring/node_modules/mongodb/index.js
deleted file mode 100644
index 4f59e9d926..0000000000
--- a/CoAuthoring/node_modules/mongodb/index.js
+++ /dev/null
@@ -1 +0,0 @@
-module.exports = require('./lib/mongodb');
diff --git a/CoAuthoring/node_modules/mongodb/install.js b/CoAuthoring/node_modules/mongodb/install.js
deleted file mode 100644
index f9f2a5778e..0000000000
--- a/CoAuthoring/node_modules/mongodb/install.js
+++ /dev/null
@@ -1,40 +0,0 @@
-var spawn = require('child_process').spawn,
- exec = require('child_process').exec;
-
-process.stdout.write("================================================================================\n");
-process.stdout.write("= =\n");
-process.stdout.write("= To install with C++ bson parser do =\n");
-process.stdout.write("= =\n");
-process.stdout.write("================================================================================\n");
-
-// Check if we want to build the native code
-var build_native = process.env['npm_package_config_native'] != null ? process.env['npm_package_config_native'] : 'false';
-build_native = build_native == 'true' ? true : false;
-// If we are building the native bson extension ensure we use gmake if available
-if(build_native) {
- // Check if we need to use gmake
- exec('which gmake', function(err, stdout, stderr) {
- // Set up spawn command
- var make = null;
- // No gmake build using make
- if(err != null) {
- make = spawn('make', ['total']);
- } else {
- make = spawn('gmake', ['total']);
- }
-
- // Execute spawn
- make.stdout.on('data', function(data) {
- process.stdout.write(data);
- })
-
- make.stderr.on('data', function(data) {
- process.stdout.write(data);
- })
-
- make.on('exit', function(code) {
- process.stdout.write('child process exited with code ' + code + "\n");
- })
- });
-}
-
diff --git a/CoAuthoring/node_modules/mongodb/lib/mongodb/admin.js b/CoAuthoring/node_modules/mongodb/lib/mongodb/admin.js
deleted file mode 100644
index 69575e1528..0000000000
--- a/CoAuthoring/node_modules/mongodb/lib/mongodb/admin.js
+++ /dev/null
@@ -1,340 +0,0 @@
-/*!
- * Module dependencies.
- */
-var Collection = require('./collection').Collection,
- Cursor = require('./cursor').Cursor,
- DbCommand = require('./commands/db_command').DbCommand;
-
-/**
- * Allows the user to access the admin functionality of MongoDB
- *
- * @class Represents the Admin methods of MongoDB.
- * @param {Object} db Current db instance we wish to perform Admin operations on.
- * @return {Function} Constructor for Admin type.
- */
-function Admin(db) {
- if(!(this instanceof Admin)) return new Admin(db);
- this.db = db;
-};
-
-/**
- * Retrieve the server information for the current
- * instance of the db client
- *
- * @param {Function} callback Callback function of format `function(err, result) {}`.
- * @return {null} Returns no result
- * @api public
- */
-Admin.prototype.buildInfo = function(callback) {
- this.serverInfo(callback);
-}
-
-/**
- * Retrieve the server information for the current
- * instance of the db client
- *
- * @param {Function} callback Callback function of format `function(err, result) {}`.
- * @return {null} Returns no result
- * @api private
- */
-Admin.prototype.serverInfo = function(callback) {
- this.db.executeDbAdminCommand({buildinfo:1}, function(err, doc) {
- if(err != null) return callback(err, null);
- return callback(null, doc.documents[0]);
- });
-}
-
-/**
- * Retrieve this db's server status.
- *
- * @param {Function} callback returns the server status.
- * @return {null}
- * @api public
- */
-Admin.prototype.serverStatus = function(callback) {
- var self = this;
-
- this.db.executeDbAdminCommand({serverStatus: 1}, function(err, doc) {
- if(err == null && doc.documents[0].ok === 1) {
- callback(null, doc.documents[0]);
- } else {
- if(err) return callback(err, false);
- return callback(self.wrap(doc.documents[0]), false);
- }
- });
-};
-
-/**
- * Retrieve the current profiling Level for MongoDB
- *
- * @param {Function} callback Callback function of format `function(err, result) {}`.
- * @return {null} Returns no result
- * @api public
- */
-Admin.prototype.profilingLevel = function(callback) {
- var self = this;
-
- this.db.executeDbAdminCommand({profile:-1}, function(err, doc) {
- doc = doc.documents[0];
-
- if(err == null && doc.ok === 1) {
- var was = doc.was;
- if(was == 0) return callback(null, "off");
- if(was == 1) return callback(null, "slow_only");
- if(was == 2) return callback(null, "all");
- return callback(new Error("Error: illegal profiling level value " + was), null);
- } else {
- err != null ? callback(err, null) : callback(new Error("Error with profile command"), null);
- }
- });
-};
-
-/**
- * Ping the MongoDB server and retrieve results
- *
- * @param {Function} callback Callback function of format `function(err, result) {}`.
- * @return {null} Returns no result
- * @api public
- */
-Admin.prototype.ping = function(options, callback) {
- // Unpack calls
- var args = Array.prototype.slice.call(arguments, 0);
- callback = args.pop();
-
- this.db.executeDbAdminCommand({ping: 1}, callback);
-}
-
-/**
- * Authenticate against MongoDB
- *
- * @param {String} username The user name for the authentication.
- * @param {String} password The password for the authentication.
- * @param {Function} callback Callback function of format `function(err, result) {}`.
- * @return {null} Returns no result
- * @api public
- */
-Admin.prototype.authenticate = function(username, password, callback) {
- this.db.authenticate(username, password, {authdb: 'admin'}, function(err, doc) {
- return callback(err, doc);
- })
-}
-
-/**
- * Logout current authenticated user
- *
- * @param {Object} [options] Optional parameters to the command.
- * @param {Function} callback Callback function of format `function(err, result) {}`.
- * @return {null} Returns no result
- * @api public
- */
-Admin.prototype.logout = function(callback) {
- this.db.logout({authdb: 'admin'}, function(err, doc) {
- return callback(err, doc);
- })
-}
-
-/**
- * Add a user to the MongoDB server, if the user exists it will
- * overwrite the current password
- *
- * Options
- * - **safe** {true | {w:n, wtimeout:n} | {fsync:true}, default:false}, executes with a getLastError command returning the results of the command on MongoDB.
- *
- * @param {String} username The user name for the authentication.
- * @param {String} password The password for the authentication.
- * @param {Object} [options] additional options during update.
- * @param {Function} callback Callback function of format `function(err, result) {}`.
- * @return {null} Returns no result
- * @api public
- */
-Admin.prototype.addUser = function(username, password, options, callback) {
- var args = Array.prototype.slice.call(arguments, 2);
- callback = args.pop();
- options = args.length ? args.shift() : {};
-
- options.dbName = 'admin';
- // Add user
- this.db.addUser(username, password, options, function(err, doc) {
- return callback(err, doc);
- })
-}
-
-/**
- * Remove a user from the MongoDB server
- *
- * Options
- * - **safe** {true | {w:n, wtimeout:n} | {fsync:true}, default:false}, executes with a getLastError command returning the results of the command on MongoDB.
- *
- * @param {String} username The user name for the authentication.
- * @param {Object} [options] additional options during update.
- * @param {Function} callback Callback function of format `function(err, result) {}`.
- * @return {null} Returns no result
- * @api public
- */
-Admin.prototype.removeUser = function(username, options, callback) {
- var self = this;
- var args = Array.prototype.slice.call(arguments, 1);
- callback = args.pop();
- options = args.length ? args.shift() : {};
- options.dbName = 'admin';
-
- this.db.removeUser(username, options, function(err, doc) {
- return callback(err, doc);
- })
-}
-
-/**
- * Set the current profiling level of MongoDB
- *
- * @param {String} level The new profiling level (off, slow_only, all)
- * @param {Function} callback Callback function of format `function(err, result) {}`.
- * @return {null} Returns no result
- * @api public
- */
-Admin.prototype.setProfilingLevel = function(level, callback) {
- var self = this;
- var command = {};
- var profile = 0;
-
- if(level == "off") {
- profile = 0;
- } else if(level == "slow_only") {
- profile = 1;
- } else if(level == "all") {
- profile = 2;
- } else {
- return callback(new Error("Error: illegal profiling level value " + level));
- }
-
- // Set up the profile number
- command['profile'] = profile;
-
- this.db.executeDbAdminCommand(command, function(err, doc) {
- doc = doc.documents[0];
-
- if(err == null && doc.ok === 1)
- return callback(null, level);
- return err != null ? callback(err, null) : callback(new Error("Error with profile command"), null);
- });
-};
-
-/**
- * Retrive the current profiling information for MongoDB
- *
- * @param {Function} callback Callback function of format `function(err, result) {}`.
- * @return {null} Returns no result
- * @api public
- */
-Admin.prototype.profilingInfo = function(callback) {
- try {
- new Cursor(this.db, new Collection(this.db, DbCommand.SYSTEM_PROFILE_COLLECTION), {}, null, null, null
- , null, null, null, null, null, null, null, null, null, null
- , null, null, null, null, null, null, null, null, 'admin').toArray(function(err, items) {
- return callback(err, items);
- });
- } catch (err) {
- return callback(err, null);
- }
-};
-
-/**
- * Execute a db command against the Admin database
- *
- * @param {Object} command A command object `{ping:1}`.
- * @param {Object} [options] Optional parameters to the command.
- * @param {Function} callback Callback function of format `function(err, result) {}`.
- * @return {null} Returns no result
- * @api public
- */
-Admin.prototype.command = function(command, options, callback) {
- var self = this;
- var args = Array.prototype.slice.call(arguments, 1);
- callback = args.pop();
- options = args.length ? args.shift() : {};
-
- // Execute a command
- this.db.executeDbAdminCommand(command, options, function(err, doc) {
- // Ensure change before event loop executes
- return callback != null ? callback(err, doc) : null;
- });
-}
-
-/**
- * Validate an existing collection
- *
- * @param {String} collectionName The name of the collection to validate.
- * @param {Object} [options] Optional parameters to the command.
- * @param {Function} callback Callback function of format `function(err, result) {}`.
- * @return {null} Returns no result
- * @api public
- */
-Admin.prototype.validateCollection = function(collectionName, options, callback) {
- var args = Array.prototype.slice.call(arguments, 1);
- callback = args.pop();
- options = args.length ? args.shift() : {};
-
- var self = this;
- var command = {validate: collectionName};
- var keys = Object.keys(options);
-
- // Decorate command with extra options
- for(var i = 0; i < keys.length; i++) {
- if(options.hasOwnProperty(keys[i])) {
- command[keys[i]] = options[keys[i]];
- }
- }
-
- this.db.executeDbCommand(command, function(err, doc) {
- if(err != null) return callback(err, null);
- doc = doc.documents[0];
-
- if(doc.ok === 0)
- return callback(new Error("Error with validate command"), null);
- if(doc.result != null && doc.result.constructor != String)
- return callback(new Error("Error with validation data"), null);
- if(doc.result != null && doc.result.match(/exception|corrupt/) != null)
- return callback(new Error("Error: invalid collection " + collectionName), null);
- if(doc.valid != null && !doc.valid)
- return callback(new Error("Error: invalid collection " + collectionName), null);
-
- return callback(null, doc);
- });
-};
-
-/**
- * List the available databases
- *
- * @param {Function} callback Callback function of format `function(err, result) {}`.
- * @return {null} Returns no result
- * @api public
- */
-Admin.prototype.listDatabases = function(callback) {
- // Execute the listAllDatabases command
- this.db.executeDbAdminCommand({listDatabases:1}, {}, function(err, doc) {
- if(err != null) return callback(err, null);
- return callback(null, doc.documents[0]);
- });
-}
-
-/**
- * Get ReplicaSet status
- *
- * @param {Function} callback returns the replica set status (if available).
- * @return {null}
- * @api public
- */
-Admin.prototype.replSetGetStatus = function(callback) {
- var self = this;
-
- this.db.executeDbAdminCommand({replSetGetStatus:1}, function(err, doc) {
- if(err == null && doc.documents[0].ok === 1)
- return callback(null, doc.documents[0]);
- if(err) return callback(err, false);
- return callback(self.db.wrap(doc.documents[0]), false);
- });
-};
-
-/**
- * @ignore
- */
-exports.Admin = Admin;
diff --git a/CoAuthoring/node_modules/mongodb/lib/mongodb/collection.js b/CoAuthoring/node_modules/mongodb/lib/mongodb/collection.js
deleted file mode 100644
index 98585ae137..0000000000
--- a/CoAuthoring/node_modules/mongodb/lib/mongodb/collection.js
+++ /dev/null
@@ -1,1627 +0,0 @@
-/**
- * Module dependencies.
- * @ignore
- */
-var InsertCommand = require('./commands/insert_command').InsertCommand
- , QueryCommand = require('./commands/query_command').QueryCommand
- , DeleteCommand = require('./commands/delete_command').DeleteCommand
- , UpdateCommand = require('./commands/update_command').UpdateCommand
- , DbCommand = require('./commands/db_command').DbCommand
- , ObjectID = require('bson').ObjectID
- , Code = require('bson').Code
- , Cursor = require('./cursor').Cursor
- , utils = require('./utils');
-
-/**
- * Precompiled regexes
- * @ignore
-**/
-const eErrorMessages = /No matching object found/;
-
-/**
- * toString helper.
- * @ignore
- */
-var toString = Object.prototype.toString;
-
-/**
- * Create a new Collection instance
- *
- * Options
- * - **slaveOk** {Boolean, default:false}, Allow reads from secondaries.
- * - **serializeFunctions** {Boolean, default:false}, serialize functions on the document.
- * - **raw** {Boolean, default:false}, perform all operations using raw bson objects.
- * - **pkFactory** {Object}, object overriding the basic ObjectID primary key generation.
- *
- * @class Represents a Collection
- * @param {Object} db db instance.
- * @param {String} collectionName collection name.
- * @param {Object} [pkFactory] alternative primary key factory.
- * @param {Object} [options] additional options for the collection.
- * @return {Object} a collection instance.
- */
-function Collection (db, collectionName, pkFactory, options) {
- if(!(this instanceof Collection)) return new Collection(db, collectionName, pkFactory, options);
-
- checkCollectionName(collectionName);
-
- this.db = db;
- this.collectionName = collectionName;
- this.internalHint = null;
- this.opts = options != null && ('object' === typeof options) ? options : {};
- this.slaveOk = options == null || options.slaveOk == null ? db.slaveOk : options.slaveOk;
- this.serializeFunctions = options == null || options.serializeFunctions == null ? db.serializeFunctions : options.serializeFunctions;
- this.raw = options == null || options.raw == null ? db.raw : options.raw;
-
- this.readPreference = options == null || options.readPreference == null ? db.serverConfig.readPreference : options.readPreference;
- this.readPreference = this.readPreference == null ? 'primary' : this.readPreference;
-
- this.pkFactory = pkFactory == null
- ? ObjectID
- : pkFactory;
-
- var self = this;
-}
-
-/**
- * Inserts a single document or a an array of documents into MongoDB.
- *
- * Options
- * - **safe** {true | {w:n, wtimeout:n} | {fsync:true}, default:false}, executes with a getLastError command returning the results of the command on MongoDB.
- * - **continueOnError/keepGoing** {Boolean, default:false}, keep inserting documents even if one document has an error, *mongodb 1.9.1 >*.
- * - **serializeFunctions** {Boolean, default:false}, serialize functions on the document.
- *
- * @param {Array|Object} docs
- * @param {Object} [options] optional options for insert command
- * @param {Function} [callback] optional callback for the function, must be provided when using `safe` or `strict` mode
- * @return {null}
- * @api public
- */
-Collection.prototype.insert = function insert (docs, options, callback) {
- if ('function' === typeof options) callback = options, options = {};
- if(options == null) options = {};
- if(!('function' === typeof callback)) callback = null;
- var self = this;
- insertAll(self, Array.isArray(docs) ? docs : [docs], options, callback);
- return this;
-};
-
-/**
- * @ignore
- */
-var checkCollectionName = function checkCollectionName (collectionName) {
- if ('string' !== typeof collectionName) {
- throw Error("collection name must be a String");
- }
-
- if (!collectionName || collectionName.indexOf('..') != -1) {
- throw Error("collection names cannot be empty");
- }
-
- if (collectionName.indexOf('$') != -1 &&
- collectionName.match(/((^\$cmd)|(oplog\.\$main))/) == null) {
- throw Error("collection names must not contain '$'");
- }
-
- if (collectionName.match(/^\.|\.$/) != null) {
- throw Error("collection names must not start or end with '.'");
- }
-};
-
-/**
- * Removes documents specified by `selector` from the db.
- *
- * Options
- * - **safe** {true | {w:n, wtimeout:n} | {fsync:true}, default:false}, executes with a getLastError command returning the results of the command on MongoDB.
- * - **single** {Boolean, default:false}, removes the first document found.
- *
- * @param {Object} [selector] optional select, no selector is equivalent to removing all documents.
- * @param {Object} [options] additional options during remove.
- * @param {Function} [callback] must be provided if you performing a safe remove
- * @return {null}
- * @api public
- */
-Collection.prototype.remove = function remove(selector, options, callback) {
- if ('function' === typeof selector) {
- callback = selector;
- selector = options = {};
- } else if ('function' === typeof options) {
- callback = options;
- options = {};
- }
-
- // Ensure options
- if(options == null) options = {};
- if(!('function' === typeof callback)) callback = null;
- // Ensure we have at least an empty selector
- selector = selector == null ? {} : selector;
- // Set up flags for the command, if we have a single document remove
- var flags = 0 | (options.single ? 1 : 0);
-
- // DbName
- var dbName = options['dbName'];
- // If no dbname defined use the db one
- if(dbName == null) {
- dbName = this.db.databaseName;
- }
-
- // Create a delete command
- var deleteCommand = new DeleteCommand(
- this.db
- , dbName + "." + this.collectionName
- , selector
- , flags);
-
- var self = this;
- var errorOptions = options.safe != null ? options.safe : null;
- errorOptions = errorOptions == null && this.opts.safe != null ? this.opts.safe : errorOptions;
- errorOptions = errorOptions == null && this.db.strict != null ? this.db.strict : errorOptions;
-
- // If we have a write concern set and no callback throw error
- if(errorOptions && errorOptions['safe'] != false && typeof callback !== 'function') throw new Error("safe cannot be used without a callback");
- // Execute the command, do not add a callback as it's async
- if (options && options.safe || this.opts.safe != null || this.db.strict) {
- // Insert options
- var commandOptions = {read:false};
- // If we have safe set set async to false
- if(errorOptions == null) commandOptions['async'] = true;
- // Set safe option
- commandOptions['safe'] = true;
- // If we have an error option
- if(typeof errorOptions == 'object') {
- var keys = Object.keys(errorOptions);
- for(var i = 0; i < keys.length; i++) {
- commandOptions[keys[i]] = errorOptions[keys[i]];
- }
- }
-
- // Execute command with safe options (rolls up both command and safe command into one and executes them on the same connection)
- this.db._executeRemoveCommand(deleteCommand, commandOptions, function (err, error) {
- error = error && error.documents;
- if(!callback) return;
-
- if(err) {
- callback(err);
- } else if(error[0].err || error[0].errmsg) {
- callback(self.db.wrap(error[0]));
- } else {
- callback(null, error[0].n);
- }
- });
- } else {
- var result = this.db._executeRemoveCommand(deleteCommand);
- // If no callback just return
- if (!callback) return;
- // If error return error
- if (result instanceof Error) {
- return callback(result);
- }
- // Otherwise just return
- return callback();
- }
-};
-
-/**
- * Renames the collection.
- *
- * @param {String} newName the new name of the collection.
- * @param {Function} callback the callback accepting the result
- * @return {null}
- * @api public
- */
-Collection.prototype.rename = function rename (newName, callback) {
- var self = this;
- // Ensure the new name is valid
- checkCollectionName(newName);
- // Execute the command, return the new renamed collection if successful
- self.db._executeQueryCommand(DbCommand.createRenameCollectionCommand(self.db, self.collectionName, newName), function(err, result) {
- if(err == null && result.documents[0].ok == 1) {
- if(callback != null) {
- // Set current object to point to the new name
- self.collectionName = newName;
- // Return the current collection
- callback(null, self);
- }
- } else if(result.documents[0].errmsg != null) {
- if(callback != null) {
- err != null ? callback(err, null) : callback(self.db.wrap(result.documents[0]), null);
- }
- }
- });
-};
-
-/**
- * @ignore
- */
-var insertAll = function insertAll (self, docs, options, callback) {
- if('function' === typeof options) callback = options, options = {};
- if(options == null) options = {};
- if(!('function' === typeof callback)) callback = null;
-
- // Insert options (flags for insert)
- var insertFlags = {};
- // If we have a mongodb version >= 1.9.1 support keepGoing attribute
- if(options['keepGoing'] != null) {
- insertFlags['keepGoing'] = options['keepGoing'];
- }
-
- // If we have a mongodb version >= 1.9.1 support keepGoing attribute
- if(options['continueOnError'] != null) {
- insertFlags['continueOnError'] = options['continueOnError'];
- }
-
- // DbName
- var dbName = options['dbName'];
- // If no dbname defined use the db one
- if(dbName == null) {
- dbName = self.db.databaseName;
- }
-
- // Either use override on the function, or go back to default on either the collection
- // level or db
- if(options['serializeFunctions'] != null) {
- insertFlags['serializeFunctions'] = options['serializeFunctions'];
- } else {
- insertFlags['serializeFunctions'] = self.serializeFunctions;
- }
-
- // Pass in options
- var insertCommand = new InsertCommand(
- self.db
- , dbName + "." + self.collectionName, true, insertFlags);
-
- // Add the documents and decorate them with id's if they have none
- for (var index = 0, len = docs.length; index < len; ++index) {
- var doc = docs[index];
-
- // Add id to each document if it's not already defined
- if (!(Buffer.isBuffer(doc)) && doc['_id'] == null && self.db.forceServerObjectId != true) {
- doc['_id'] = self.pkFactory.createPk();
- }
-
- insertCommand.add(doc);
- }
-
- // Collect errorOptions
- var errorOptions = options.safe != null ? options.safe : null;
- errorOptions = errorOptions == null && self.opts.safe != null ? self.opts.safe : errorOptions;
- errorOptions = errorOptions == null && self.db.strict != null ? self.db.strict : errorOptions;
-
- // If we have a write concern set and no callback throw error
- if(errorOptions && errorOptions['safe'] != false && typeof callback !== 'function') throw new Error("safe cannot be used without a callback");
-
- // Default command options
- var commandOptions = {};
- // If safe is defined check for error message
- if(errorOptions && errorOptions != false) {
- // Insert options
- commandOptions['read'] = false;
- // If we have safe set set async to false
- if(errorOptions == null) commandOptions['async'] = true;
-
- // Set safe option
- commandOptions['safe'] = errorOptions;
- // If we have an error option
- if(typeof errorOptions == 'object') {
- var keys = Object.keys(errorOptions);
- for(var i = 0; i < keys.length; i++) {
- commandOptions[keys[i]] = errorOptions[keys[i]];
- }
- }
-
- // Execute command with safe options (rolls up both command and safe command into one and executes them on the same connection)
- self.db._executeInsertCommand(insertCommand, commandOptions, function (err, error) {
- error = error && error.documents;
- if(!callback) return;
-
- if (err) {
- callback(err);
- } else if(error[0].err || error[0].errmsg) {
- callback(self.db.wrap(error[0]));
- } else {
- callback(null, docs);
- }
- });
- } else {
- var result = self.db._executeInsertCommand(insertCommand, commandOptions, callback);
- // If no callback just return
- if(!callback) return;
- // If error return error
- if(result instanceof Error) {
- return callback(result);
- }
- // Otherwise just return
- return callback(null, docs);
- }
-};
-
-/**
- * Save a document. Simple full document replacement function. Not recommended for efficiency, use atomic
- * operators and update instead for more efficient operations.
- *
- * Options
- * - **safe** {true | {w:n, wtimeout:n} | {fsync:true}, default:false}, executes with a getLastError command returning the results of the command on MongoDB.
- *
- * @param {Object} [doc] the document to save
- * @param {Object} [options] additional options during remove.
- * @param {Function} [callback] must be provided if you performing a safe save
- * @return {null}
- * @api public
- */
-Collection.prototype.save = function save(doc, options, callback) {
- if('function' === typeof options) callback = options, options = null;
- if(options == null) options = {};
- if(!('function' === typeof callback)) callback = null;
-
- var errorOptions = options.safe != null ? options.safe : false;
- errorOptions = errorOptions == null && this.opts.safe != null ? this.opts.safe : errorOptions;
- // Extract the id, if we have one we need to do a update command
- var id = doc['_id'];
-
- if(id) {
- this.update({ _id: id }, doc, { upsert: true, safe: errorOptions }, callback);
- } else {
- this.insert(doc, { safe: errorOptions }, callback && function (err, docs) {
- if (err) return callback(err, null);
-
- if (Array.isArray(docs)) {
- callback(err, docs[0]);
- } else {
- callback(err, docs);
- }
- });
- }
-};
-
-/**
- * Updates documents.
- *
- * Options
- * - **safe** {true | {w:n, wtimeout:n} | {fsync:true}, default:false}, executes with a getLastError command returning the results of the command on MongoDB.
- * - **upsert** {Boolean, default:false}, perform an upsert operation.
- * - **multi** {Boolean, default:false}, update all documents matching the selector.
- * - **serializeFunctions** {Boolean, default:false}, serialize functions on the document.
- *
- * @param {Object} selector the query to select the document/documents to be updated
- * @param {Object} document the fields/vals to be updated, or in the case of an upsert operation, inserted.
- * @param {Object} [options] additional options during update.
- * @param {Function} [callback] must be provided if you performing a safe update
- * @return {null}
- * @api public
- */
-Collection.prototype.update = function update(selector, document, options, callback) {
- if('function' === typeof options) callback = options, options = null;
- if(options == null) options = {};
- if(!('function' === typeof callback)) callback = null;
-
- // DbName
- var dbName = options['dbName'];
- // If no dbname defined use the db one
- if(dbName == null) {
- dbName = this.db.databaseName;
- }
-
- // Either use override on the function, or go back to default on either the collection
- // level or db
- if(options['serializeFunctions'] != null) {
- options['serializeFunctions'] = options['serializeFunctions'];
- } else {
- options['serializeFunctions'] = this.serializeFunctions;
- }
-
- var updateCommand = new UpdateCommand(
- this.db
- , dbName + "." + this.collectionName
- , selector
- , document
- , options);
-
- var self = this;
- // Unpack the error options if any
- var errorOptions = (options && options.safe != null) ? options.safe : null;
- errorOptions = errorOptions == null && this.opts.safe != null ? this.opts.safe : errorOptions;
- errorOptions = errorOptions == null && this.db.strict != null ? this.db.strict : errorOptions;
-
- // If we have a write concern set and no callback throw error
- if(errorOptions && errorOptions['safe'] != false && typeof callback !== 'function') throw new Error("safe cannot be used without a callback");
-
- // If we are executing in strict mode or safe both the update and the safe command must happen on the same line
- if(errorOptions && errorOptions != false) {
- // Insert options
- var commandOptions = {read:false};
- // If we have safe set set async to false
- if(errorOptions == null) commandOptions['async'] = true;
- // Set safe option
- commandOptions['safe'] = true;
- // If we have an error option
- if(typeof errorOptions == 'object') {
- var keys = Object.keys(errorOptions);
- for(var i = 0; i < keys.length; i++) {
- commandOptions[keys[i]] = errorOptions[keys[i]];
- }
- }
-
- // Execute command with safe options (rolls up both command and safe command into one and executes them on the same connection)
- this.db._executeUpdateCommand(updateCommand, commandOptions, function (err, error) {
- error = error && error.documents;
- if(!callback) return;
-
- if(err) {
- callback(err);
- } else if(error[0].err || error[0].errmsg) {
- callback(self.db.wrap(error[0]));
- } else {
- // Perform the callback
- callback(null, error[0].n, error[0]);
- }
- });
- } else {
- // Execute update
- var result = this.db._executeUpdateCommand(updateCommand);
- // If no callback just return
- if (!callback) return;
- // If error return error
- if (result instanceof Error) {
- return callback(result);
- }
- // Otherwise just return
- return callback();
- }
-};
-
-/**
- * The distinct command returns returns a list of distinct values for the given key across a collection.
- *
- * Options
- * - **readPreference** {String}, the preferred read preference (Server.PRIMARY, Server.PRIMARY_PREFERRED, Server.SECONDARY, Server.SECONDARY_PREFERRED, Server.NEAREST).
- *
- * @param {String} key key to run distinct against.
- * @param {Object} [query] option query to narrow the returned objects.
- * @param {Object} [options] additional options during update.
- * @param {Function} callback must be provided.
- * @return {null}
- * @api public
- */
-Collection.prototype.distinct = function distinct(key, query, options, callback) {
- var args = Array.prototype.slice.call(arguments, 1);
- callback = args.pop();
- query = args.length ? args.shift() : {};
- options = args.length ? args.shift() : {};
-
- var mapCommandHash = {
- 'distinct': this.collectionName
- , 'query': query
- , 'key': key
- };
-
- // Set read preference if we set one
- var readPreference = options['readPreference'] ? options['readPreference'] : false;
- // Create the command
- var cmd = DbCommand.createDbSlaveOkCommand(this.db, mapCommandHash);
-
- this.db._executeQueryCommand(cmd, {read:readPreference}, function (err, result) {
- if(err)
- return callback(err);
- if(result.documents[0].ok != 1)
- return callback(new Error(result.documents[0].errmsg));
- callback(null, result.documents[0].values);
- });
-};
-
-/**
- * Count number of matching documents in the db to a query.
- *
- * Options
- * - **readPreference** {String}, the preferred read preference (Server.PRIMARY, Server.PRIMARY_PREFERRED, Server.SECONDARY, Server.SECONDARY_PREFERRED, Server.NEAREST).
- *
- * @param {Object} [query] query to filter by before performing count.
- * @param {Object} [options] additional options during count.
- * @param {Function} callback must be provided.
- * @return {null}
- * @api public
- */
-Collection.prototype.count = function count (query, options, callback) {
- var args = Array.prototype.slice.call(arguments, 0);
- callback = args.pop();
- query = args.length ? args.shift() : {};
- options = args.length ? args.shift() : {};
-
- // Final query
- var final_query = {
- 'count': this.collectionName
- , 'query': query
- , 'fields': null
- };
-
- // Set read preference if we set one
- var readPreference = options['readPreference'] ? options['readPreference'] : false;
-
- // Set up query options
- var queryOptions = QueryCommand.OPTS_NO_CURSOR_TIMEOUT;
- if (this.slaveOk || this.db.slaveOk) {
- queryOptions |= QueryCommand.OPTS_SLAVE;
- }
-
- var queryCommand = new QueryCommand(
- this.db
- , this.db.databaseName + ".$cmd"
- , queryOptions
- , 0
- , -1
- , final_query
- , null
- );
-
- var self = this;
- this.db._executeQueryCommand(queryCommand, {read:readPreference}, function (err, result) {
- result = result && result.documents;
- if(!callback) return;
-
- if(err) return callback(err);
- if (result[0].ok != 1 || result[0].errmsg) return callback(self.db.wrap(result[0]));
- callback(null, result[0].n);
- });
-};
-
-
-/**
- * Drop the collection
- *
- * @param {Function} [callback] provide a callback to be notified when command finished executing
- * @return {null}
- * @api public
- */
-Collection.prototype.drop = function drop(callback) {
- this.db.dropCollection(this.collectionName, callback);
-};
-
-/**
- * Find and update a document.
- *
- * Options
- * - **safe** {true | {w:n, wtimeout:n} | {fsync:true}, default:false}, executes with a getLastError command returning the results of the command on MongoDB.
- * - **remove** {Boolean, default:false}, set to true to remove the object before returning.
- * - **upsert** {Boolean, default:false}, perform an upsert operation.
- * - **new** {Boolean, default:false}, set to true if you want to return the modified object rather than the original. Ignored for remove.
- *
- * @param {Object} query query object to locate the object to modify
- * @param {Array} sort - if multiple docs match, choose the first one in the specified sort order as the object to manipulate
- * @param {Object} doc - the fields/vals to be updated
- * @param {Object} [options] additional options during update.
- * @param {Function} [callback] returns results.
- * @return {null}
- * @api public
- */
-Collection.prototype.findAndModify = function findAndModify (query, sort, doc, options, callback) {
- var args = Array.prototype.slice.call(arguments, 1);
- callback = args.pop();
- sort = args.length ? args.shift() : [];
- doc = args.length ? args.shift() : null;
- options = args.length ? args.shift() : {};
- var self = this;
-
- var queryObject = {
- 'findandmodify': this.collectionName
- , 'query': query
- , 'sort': utils.formattedOrderClause(sort)
- };
-
- queryObject.new = options.new ? 1 : 0;
- queryObject.remove = options.remove ? 1 : 0;
- queryObject.upsert = options.upsert ? 1 : 0;
-
- if (options.fields) {
- queryObject.fields = options.fields;
- }
-
- if (doc && !options.remove) {
- queryObject.update = doc;
- }
-
- // Either use override on the function, or go back to default on either the collection
- // level or db
- if(options['serializeFunctions'] != null) {
- options['serializeFunctions'] = options['serializeFunctions'];
- } else {
- options['serializeFunctions'] = this.serializeFunctions;
- }
-
- // Unpack the error options if any
- var errorOptions = (options && options.safe != null) ? options.safe : null;
- errorOptions = errorOptions == null && this.opts.safe != null ? this.opts.safe : errorOptions;
- errorOptions = errorOptions == null && this.db.strict != null ? this.db.strict : errorOptions;
-
- // If we have j, w or something else do the getLast Error path
- if(errorOptions != null && typeof errorOptions == 'object') {
- // Commands to send
- var commands = [];
- // Add the find and modify command
- commands.push(DbCommand.createDbCommand(this.db, queryObject, options));
- // If we have safe defined we need to return both call results
- var chainedCommands = errorOptions != null ? true : false;
- // Add error command if we have one
- if(chainedCommands) {
- commands.push(DbCommand.createGetLastErrorCommand(errorOptions, this.db));
- }
-
- // console.dir(errorOptions)
- // commands = DbCommand.createDbCommand(this.db, queryObject, options)
- // Fire commands and
- this.db._executeQueryCommand(commands, {read:false}, function(err, result) {
- if(err != null) return callback(err);
- result = result && result.documents;
-
- if(result[0].err != null) return callback(self.db.wrap(result[0]), null);
- // Workaround due to 1.8.X returning an error on no matching object
- // while 2.0.X does not not, making 2.0.X behaviour standard
- if(result[0].errmsg != null && !result[0].errmsg.match(eErrorMessages))
- return callback(self.db.wrap(result[0]), null, result[0]);
- return callback(null, result[0].value, result[0]);
- });
- } else {
- // Only run command and rely on getLastError command
- var command = DbCommand.createDbCommand(this.db, queryObject, options)
- // Execute command
- this.db._executeQueryCommand(command, {read:false}, function(err, result) {
- if(err != null) return callback(err);
- result = result && result.documents;
- if(result[0].errmsg != null && !result[0].errmsg.match(eErrorMessages))
- return callback(self.db.wrap(result[0]), null, result[0]);
- // If we have an error return it
- if(result[0].lastErrorObject && result[0].lastErrorObject.err != null) return callback(self.db.wrap(result[0].lastErrorObject), null);
- return callback(null, result[0].value, result[0]);
- });
- }
-}
-
-/**
- * Find and remove a document
- *
- * Options
- * - **safe** {true | {w:n, wtimeout:n} | {fsync:true}, default:false}, executes with a getLastError command returning the results of the command on MongoDB.
- *
- * @param {Object} query query object to locate the object to modify
- * @param {Array} sort - if multiple docs match, choose the first one in the specified sort order as the object to manipulate
- * @param {Object} [options] additional options during update.
- * @param {Function} [callback] returns results.
- * @return {null}
- * @api public
- */
-Collection.prototype.findAndRemove = function(query, sort, options, callback) {
- var args = Array.prototype.slice.call(arguments, 1);
- callback = args.pop();
- sort = args.length ? args.shift() : [];
- options = args.length ? args.shift() : {};
- // Add the remove option
- options['remove'] = true;
- // Execute the callback
- this.findAndModify(query, sort, null, options, callback);
-}
-
-var testForFields = {'limit' : 1, 'sort' : 1, 'fields' : 1, 'skip' : 1, 'hint' : 1, 'explain' : 1, 'snapshot' : 1
- , 'timeout' : 1, 'tailable' : 1, 'batchSize' : 1, 'raw' : 1, 'read' : 1
- , 'returnKey' : 1, 'maxScan' : 1, 'min' : 1, 'max' : 1, 'showDiskLoc' : 1, 'comment' : 1, 'dbName' : 1};
-
-/**
- * Creates a cursor for a query that can be used to iterate over results from MongoDB
- *
- * Various argument possibilities
- * - callback?
- * - selector, callback?,
- * - selector, fields, callback?
- * - selector, options, callback?
- * - selector, fields, options, callback?
- * - selector, fields, skip, limit, callback?
- * - selector, fields, skip, limit, timeout, callback?
- *
- * Options
- * - **limit** {Number, default:0}, sets the limit of documents returned in the query.
- * - **sort** {Array | Object}, set to sort the documents coming back from the query. Array of indexes, [['a', 1]] etc.
- * - **fields** {Object}, the fields to return in the query. Object of fields to include or exclude (not both), {'a':1}
- * - **skip** {Number, default:0}, set to skip N documents ahead in your query (useful for pagination).
- * - **hint** {Object}, tell the query to use specific indexes in the query. Object of indexes to use, {'_id':1}
- * - **explain** {Boolean, default:false}, explain the query instead of returning the data.
- * - **snapshot** {Boolean, default:false}, snapshot query.
- * - **timeout** {Boolean, default:false}, specify if the cursor can timeout.
- * - **tailable** {Boolean, default:false}, specify if the cursor is tailable.
- * - **awaitdata** {Boolean, default:false} allow the cursor to wait for data, only applicable for tailable cursor.
- * - **batchSize** {Number, default:0}, set the batchSize for the getMoreCommand when iterating over the query results.
- * - **returnKey** {Boolean, default:false}, only return the index key.
- * - **maxScan** {Number}, Limit the number of items to scan.
- * - **min** {Number}, Set index bounds.
- * - **max** {Number}, Set index bounds.
- * - **showDiskLoc** {Boolean, default:false}, Show disk location of results.
- * - **comment** {String}, You can put a $comment field on a query to make looking in the profiler logs simpler.
- * - **raw** {Boolean, default:false}, Return all BSON documents as Raw Buffer documents.
- * - **readPreference** {String}, the preferred read preference ((Server.PRIMARY, Server.PRIMARY_PREFERRED, Server.SECONDARY, Server.SECONDARY_PREFERRED, Server.NEAREST).
- * - **numberOfRetries** {Number, default:1}, if using awaidata specifies the number of times to retry on timeout.
- *
- * @param {Object} query query object to locate the object to modify
- * @param {Object} [options] additional options during update.
- * @param {Function} [callback] optional callback for cursor.
- * @return {Cursor} returns a cursor to the query
- * @api public
- */
-Collection.prototype.find = function find () {
- var options
- , args = Array.prototype.slice.call(arguments, 0)
- , has_callback = typeof args[args.length - 1] === 'function'
- , has_weird_callback = typeof args[0] === 'function'
- , callback = has_callback ? args.pop() : (has_weird_callback ? args.shift() : null)
- , len = args.length
- , selector = len >= 1 ? args[0] : {}
- , fields = len >= 2 ? args[1] : undefined;
-
- if(len === 1 && has_weird_callback) {
- // backwards compat for callback?, options case
- selector = {};
- options = args[0];
- }
-
- if(len === 2 && !Array.isArray(fields)) {
- var fieldKeys = Object.getOwnPropertyNames(fields);
- var is_option = false;
-
- for(var i = 0; i < fieldKeys.length; i++) {
- if(testForFields[fieldKeys[i]] != null) {
- is_option = true;
- break;
- }
- }
-
- if(is_option) {
- options = fields;
- fields = undefined;
- } else {
- options = {};
- }
- } else if(len === 2 && Array.isArray(fields) && !Array.isArray(fields[0])) {
- var newFields = {};
- // Rewrite the array
- for(var i = 0; i < fields.length; i++) {
- newFields[fields[i]] = 1;
- }
- // Set the fields
- fields = newFields;
- }
-
- if(3 === len) {
- options = args[2];
- }
-
- // Ensure selector is not null
- selector = selector == null ? {} : selector;
- // Validate correctness off the selector
- var object = selector;
- if(Buffer.isBuffer(object)) {
- var object_size = object[0] | object[1] << 8 | object[2] << 16 | object[3] << 24;
- if(object_size != object.length) {
- var error = new Error("query selector raw message size does not match message header size [" + object.length + "] != [" + object_size + "]");
- error.name = 'MongoError';
- throw error;
- }
- }
-
- // Validate correctness of the field selector
- var object = fields;
- if(Buffer.isBuffer(object)) {
- var object_size = object[0] | object[1] << 8 | object[2] << 16 | object[3] << 24;
- if(object_size != object.length) {
- var error = new Error("query fields raw message size does not match message header size [" + object.length + "] != [" + object_size + "]");
- error.name = 'MongoError';
- throw error;
- }
- }
-
- // Check special case where we are using an objectId
- if(selector instanceof ObjectID) {
- selector = {_id:selector};
- }
-
- // If it's a serialized fields field we need to just let it through
- // user be warned it better be good
- if(options && options.fields && !(Buffer.isBuffer(options.fields))) {
- fields = {};
-
- if(Array.isArray(options.fields)) {
- if(!options.fields.length) {
- fields['_id'] = 1;
- } else {
- for (var i = 0, l = options.fields.length; i < l; i++) {
- fields[options.fields[i]] = 1;
- }
- }
- } else {
- fields = options.fields;
- }
- }
-
- if (!options) options = {};
- options.skip = len > 3 ? args[2] : options.skip ? options.skip : 0;
- options.limit = len > 3 ? args[3] : options.limit ? options.limit : 0;
- options.raw = options.raw != null && typeof options.raw === 'boolean' ? options.raw : this.raw;
- options.hint = options.hint != null ? normalizeHintField(options.hint) : this.internalHint;
- options.timeout = len == 5 ? args[4] : typeof options.timeout === 'undefined' ? undefined : options.timeout;
- // If we have overridden slaveOk otherwise use the default db setting
- options.slaveOk = options.slaveOk != null ? options.slaveOk : this.db.slaveOk;
-
- // Set option
- var o = options;
- // Support read/readPreference
- if(o["read"] != null) o["readPreference"] = o["read"];
- // Set the read preference
- o.read = o["readPreference"] ? o.readPreference : this.readPreference;
- // Adjust slave ok if read preference is secondary or secondary only
- if(o.read == "secondary" || o.read == "secondaryOnly") options.slaveOk = true;
-
- // callback for backward compatibility
- if(callback) {
- // TODO refactor Cursor args
- callback(null, new Cursor(this.db, this, selector, fields, o.skip, o.limit
- , o.sort, o.hint, o.explain, o.snapshot, o.timeout, o.tailable, o.batchSize
- , o.slaveOk, o.raw, o.read, o.returnKey, o.maxScan, o.min, o.max, o.showDiskLoc, o.comment, o.awaitdata
- , o.numberOfRetries, o.dbName));
- } else {
- return new Cursor(this.db, this, selector, fields, o.skip, o.limit
- , o.sort, o.hint, o.explain, o.snapshot, o.timeout, o.tailable, o.batchSize
- , o.slaveOk, o.raw, o.read, o.returnKey, o.maxScan, o.min, o.max, o.showDiskLoc, o.comment, o.awaitdata
- , o.numberOfRetries, o.dbName);
- }
-};
-
-/**
- * Normalizes a `hint` argument.
- *
- * @param {String|Object|Array} hint
- * @return {Object}
- * @api private
- */
-var normalizeHintField = function normalizeHintField(hint) {
- var finalHint = null;
-
- if (null != hint) {
- switch (hint.constructor) {
- case String:
- finalHint = {};
- finalHint[hint] = 1;
- break;
- case Object:
- finalHint = {};
- for (var name in hint) {
- finalHint[name] = hint[name];
- }
- break;
- case Array:
- finalHint = {};
- hint.forEach(function(param) {
- finalHint[param] = 1;
- });
- break;
- }
- }
-
- return finalHint;
-};
-
-/**
- * Finds a single document based on the query
- *
- * Various argument possibilities
- * - callback?
- * - selector, callback?,
- * - selector, fields, callback?
- * - selector, options, callback?
- * - selector, fields, options, callback?
- * - selector, fields, skip, limit, callback?
- * - selector, fields, skip, limit, timeout, callback?
- *
- * Options
- * - **limit** {Number, default:0}, sets the limit of documents returned in the query.
- * - **sort** {Array | Object}, set to sort the documents coming back from the query. Array of indexes, [['a', 1]] etc.
- * - **fields** {Object}, the fields to return in the query. Object of fields to include or exclude (not both), {'a':1}
- * - **skip** {Number, default:0}, set to skip N documents ahead in your query (useful for pagination).
- * - **hint** {Object}, tell the query to use specific indexes in the query. Object of indexes to use, {'_id':1}
- * - **explain** {Boolean, default:false}, explain the query instead of returning the data.
- * - **snapshot** {Boolean, default:false}, snapshot query.
- * - **timeout** {Boolean, default:false}, specify if the cursor can timeout.
- * - **tailable** {Boolean, default:false}, specify if the cursor is tailable.
- * - **batchSize** {Number, default:0}, set the batchSize for the getMoreCommand when iterating over the query results.
- * - **returnKey** {Boolean, default:false}, only return the index key.
- * - **maxScan** {Number}, Limit the number of items to scan.
- * - **min** {Number}, Set index bounds.
- * - **max** {Number}, Set index bounds.
- * - **showDiskLoc** {Boolean, default:false}, Show disk location of results.
- * - **comment** {String}, You can put a $comment field on a query to make looking in the profiler logs simpler.
- * - **raw** {Boolean, default:false}, Return all BSON documents as Raw Buffer documents.
- * - **readPreference** {String}, the preferred read preference (Server.PRIMARY, Server.PRIMARY_PREFERRED, Server.SECONDARY, Server.SECONDARY_PREFERRED, Server.NEAREST).
- *
- * @param {Object} query query object to locate the object to modify
- * @param {Object} [options] additional options during update.
- * @param {Function} [callback] optional callback for cursor.
- * @return {Cursor} returns a cursor to the query
- * @api public
- */
-Collection.prototype.findOne = function findOne () {
- var self = this;
- var args = Array.prototype.slice.call(arguments, 0);
- var callback = args.pop();
- var cursor = this.find.apply(this, args).limit(-1).batchSize(1);
- // Return the item
- cursor.toArray(function(err, items) {
- if(err != null) return callback(err instanceof Error ? err : self.db.wrap(new Error(err)), null);
- if(items.length == 1) return callback(null, items[0]);
- callback(null, null);
- });
-};
-
-/**
- * Creates an index on the collection.
- *
- * Options
- * - **safe** {true | {w:n, wtimeout:n} | {fsync:true}, default:false}, executes with a
- * - **unique** {Boolean, default:false}, creates an unique index.
- * - **sparse** {Boolean, default:false}, creates a sparse index.
- * - **background** {Boolean, default:false}, creates the index in the background, yielding whenever possible.
- * - **dropDups** {Boolean, default:false}, a unique index cannot be created on a key that has pre-existing duplicate values. If you would like to create the index anyway, keeping the first document the database indexes and deleting all subsequent documents that have duplicate value
- * - **min** {Number}, for geospatial indexes set the lower bound for the co-ordinates.
- * - **max** {Number}, for geospatial indexes set the high bound for the co-ordinates.
- *
- * @param {Object} fieldOrSpec fieldOrSpec that defines the index.
- * @param {Object} [options] additional options during update.
- * @param {Function} callback for results.
- * @return {null}
- * @api public
- */
-Collection.prototype.createIndex = function createIndex (fieldOrSpec, options, callback) {
- // Clean up call
- var args = Array.prototype.slice.call(arguments, 1);
- callback = args.pop();
- options = args.length ? args.shift() : {};
- options = typeof callback === 'function' ? options : callback;
- options = options == null ? {} : options;
-
- // Collect errorOptions
- var errorOptions = options.safe != null ? options.safe : null;
- errorOptions = errorOptions == null && this.opts.safe != null ? this.opts.safe : errorOptions;
- errorOptions = errorOptions == null && this.db.strict != null ? this.db.strict : errorOptions;
-
- // If we have a write concern set and no callback throw error
- if(errorOptions != null && errorOptions != false && (typeof callback !== 'function' && typeof options !== 'function')) throw new Error("safe cannot be used without a callback");
-
- // Execute create index
- this.db.createIndex(this.collectionName, fieldOrSpec, options, callback);
-};
-
-/**
- * Ensures that an index exists, if it does not it creates it
- *
- * Options
- * - **safe** {true | {w:n, wtimeout:n} | {fsync:true}, default:false}, executes with a
- * - **unique** {Boolean, default:false}, creates an unique index.
- * - **sparse** {Boolean, default:false}, creates a sparse index.
- * - **background** {Boolean, default:false}, creates the index in the background, yielding whenever possible.
- * - **dropDups** {Boolean, default:false}, a unique index cannot be created on a key that has pre-existing duplicate values. If you would like to create the index anyway, keeping the first document the database indexes and deleting all subsequent documents that have duplicate value
- * - **min** {Number}, for geospatial indexes set the lower bound for the co-ordinates.
- * - **max** {Number}, for geospatial indexes set the high bound for the co-ordinates.
- * - **v** {Number}, specify the format version of the indexes.
- *
- * @param {Object} fieldOrSpec fieldOrSpec that defines the index.
- * @param {Object} [options] additional options during update.
- * @param {Function} callback for results.
- * @return {null}
- * @api public
- */
-Collection.prototype.ensureIndex = function ensureIndex (fieldOrSpec, options, callback) {
- // Clean up call
- if (typeof callback === 'undefined' && typeof options === 'function') {
- callback = options;
- options = {};
- }
-
- if (options == null) {
- options = {};
- }
-
- // Collect errorOptions
- var errorOptions = options.safe != null ? options.safe : null;
- errorOptions = errorOptions == null && this.opts.safe != null ? this.opts.safe : errorOptions;
- errorOptions = errorOptions == null && this.db.strict != null ? this.db.strict : errorOptions;
-
- // If we have a write concern set and no callback throw error
- if(errorOptions != null && errorOptions != false && (typeof callback !== 'function' && typeof options !== 'function')) throw new Error("safe cannot be used without a callback");
-
- // Execute create index
- this.db.ensureIndex(this.collectionName, fieldOrSpec, options, callback);
-};
-
-/**
- * Retrieves this collections index info.
- *
- * Options
- * - **full** {Boolean, default:false}, returns the full raw index information.
- *
- * @param {Object} [options] additional options during update.
- * @param {Function} callback returns the index information.
- * @return {null}
- * @api public
- */
-Collection.prototype.indexInformation = function indexInformation (options, callback) {
- // Unpack calls
- var args = Array.prototype.slice.call(arguments, 0);
- callback = args.pop();
- options = args.length ? args.shift() : {};
- // Call the index information
- this.db.indexInformation(this.collectionName, options, callback);
-};
-
-/**
- * Drops an index from this collection.
- *
- * @param {String} name
- * @param {Function} callback returns the results.
- * @return {null}
- * @api public
- */
-Collection.prototype.dropIndex = function dropIndex (name, callback) {
- this.db.dropIndex(this.collectionName, name, callback);
-};
-
-/**
- * Drops all indexes from this collection.
- *
- * @param {Function} callback returns the results.
- * @return {null}
- * @api public
- */
-Collection.prototype.dropAllIndexes = function dropIndexes (callback) {
- this.db.dropIndex(this.collectionName, '*', function (err, result) {
- if(err != null) {
- callback(err, false);
- } else if(result.documents[0].errmsg == null) {
- callback(null, true);
- } else {
- callback(new Error(result.documents[0].errmsg), false);
- }
- });
-};
-
-/**
- * Drops all indexes from this collection.
- *
- * @deprecated
- * @param {Function} callback returns the results.
- * @return {null}
- * @api private
- */
-Collection.prototype.dropIndexes = Collection.prototype.dropAllIndexes;
-
-/**
- * Reindex all indexes on the collection
- * Warning: reIndex is a blocking operation (indexes are rebuilt in the foreground) and will be slow for large collections.
- *
- * @param {Function} callback returns the results.
- * @return {null}
- * @api public
-**/
-Collection.prototype.reIndex = function(callback) {
- this.db.reIndex(this.collectionName, callback);
-}
-
-/**
- * Run Map Reduce across a collection. Be aware that the inline option for out will return an array of results not a collection.
- *
- * Options
- * - **out** {Object, default:*{inline:1}*}, sets the output target for the map reduce job. *{inline:1} | {replace:'collectionName'} | {merge:'collectionName'} | {reduce:'collectionName'}*
- * - **query** {Object}, query filter object.
- * - **sort** {Object}, sorts the input objects using this key. Useful for optimization, like sorting by the emit key for fewer reduces.
- * - **limit** {Number}, number of objects to return from collection.
- * - **keeptemp** {Boolean, default:false}, keep temporary data.
- * - **finalize** {Function | String}, finalize function.
- * - **scope** {Object}, can pass in variables that can be access from map/reduce/finalize.
- * - **jsMode** {Boolean, default:false}, it is possible to make the execution stay in JS. Provided in MongoDB > 2.0.X.
- * - **verbose** {Boolean, default:false}, provide statistics on job execution time.
- * - **readPreference** {String, only for inline results}, the preferred read preference (Server.PRIMARY, Server.PRIMARY_PREFERRED, Server.SECONDARY, Server.SECONDARY_PREFERRED, Server.NEAREST).
- *
- * @param {Function|String} map the mapping function.
- * @param {Function|String} reduce the reduce function.
- * @param {Objects} [options] options for the map reduce job.
- * @param {Function} callback returns the result of the map reduce job, (error, results, [stats])
- * @return {null}
- * @api public
- */
-Collection.prototype.mapReduce = function mapReduce (map, reduce, options, callback) {
- if ('function' === typeof options) callback = options, options = {};
- // Out must allways be defined (make sure we don't break weirdly on pre 1.8+ servers)
- if(null == options.out) {
- throw new Error("the out option parameter must be defined, see mongodb docs for possible values");
- }
-
- if ('function' === typeof map) {
- map = map.toString();
- }
-
- if ('function' === typeof reduce) {
- reduce = reduce.toString();
- }
-
- if ('function' === typeof options.finalize) {
- options.finalize = options.finalize.toString();
- }
-
- var mapCommandHash = {
- mapreduce: this.collectionName
- , map: map
- , reduce: reduce
- };
-
- // Add any other options passed in
- for (var name in options) {
- mapCommandHash[name] = options[name];
- }
-
- // Set read preference if we set one
- var readPreference = options['readPreference'] ? options['readPreference'] : false;
- // If we have a read preference and inline is not set as output fail hard
- if(readPreference != false && options['out'] != 'inline') {
- throw new Error("a readPreference can only be provided when performing an inline mapReduce");
- }
-
- // self
- var self = this;
- var cmd = DbCommand.createDbCommand(this.db, mapCommandHash);
-
- this.db._executeQueryCommand(cmd, {read:readPreference}, function (err, result) {
- if (err) {
- return callback(err);
- }
-
- //
- if (1 != result.documents[0].ok || result.documents[0].err || result.documents[0].errmsg) {
- return callback(self.db.wrap(result.documents[0]));
- }
-
- // Create statistics value
- var stats = {};
- if(result.documents[0].timeMillis) stats['processtime'] = result.documents[0].timeMillis;
- if(result.documents[0].counts) stats['counts'] = result.documents[0].counts;
- if(result.documents[0].timing) stats['timing'] = result.documents[0].timing;
-
- // invoked with inline?
- if(result.documents[0].results) {
- return callback(null, result.documents[0].results, stats);
- }
-
- // The returned collection
- var collection = null;
-
- // If we have an object it's a different db
- if(result.documents[0].result != null && typeof result.documents[0].result == 'object') {
- var doc = result.documents[0].result;
- collection = self.db.db(doc.db).collection(doc.collection);
- } else {
- // Create a collection object that wraps the result collection
- collection = self.db.collection(result.documents[0].result)
- }
-
- // If we wish for no verbosity
- if(options['verbose'] == null || !options['verbose']) {
- return callback(err, collection);
- }
-
- // Return stats as third set of values
- callback(err, collection, stats);
- });
-};
-
-/**
- * Group function helper
- * @ignore
- */
-var groupFunction = function () {
- var c = db[ns].find(condition);
- var map = new Map();
- var reduce_function = reduce;
-
- while (c.hasNext()) {
- var obj = c.next();
- var key = {};
-
- for (var i = 0, len = keys.length; i < len; ++i) {
- var k = keys[i];
- key[k] = obj[k];
- }
-
- var aggObj = map.get(key);
-
- if (aggObj == null) {
- var newObj = Object.extend({}, key);
- aggObj = Object.extend(newObj, initial);
- map.put(key, aggObj);
- }
-
- reduce_function(obj, aggObj);
- }
-
- return { "result": map.values() };
-}.toString();
-
-/**
- * Run a group command across a collection
- *
- * Options
- * - **readPreference** {String}, the preferred read preference (Server.PRIMARY, Server.PRIMARY_PREFERRED, Server.SECONDARY, Server.SECONDARY_PREFERRED, Server.NEAREST).
- *
- * @param {Object|Array|Function|Code} keys an object, array or function expressing the keys to group by.
- * @param {Object} condition an optional condition that must be true for a row to be considered.
- * @param {Object} initial initial value of the aggregation counter object.
- * @param {Function|Code} reduce the reduce function aggregates (reduces) the objects iterated
- * @param {Function|Code} finalize an optional function to be run on each item in the result set just before the item is returned.
- * @param {Boolean} command specify if you wish to run using the internal group command or using eval, default is true.
- * @param {Object} [options] additional options during update.
- * @param {Function} callback returns the results.
- * @return {null}
- * @api public
- */
-Collection.prototype.group = function group(keys, condition, initial, reduce, finalize, command, options, callback) {
- var args = Array.prototype.slice.call(arguments, 3);
- callback = args.pop();
- // Fetch all commands
- reduce = args.length ? args.shift() : null;
- finalize = args.length ? args.shift() : null;
- command = args.length ? args.shift() : null;
- options = args.length ? args.shift() : {};
-
- // Make sure we are backward compatible
- if(!(typeof finalize == 'function')) {
- command = finalize;
- finalize = null;
- }
-
- if (!Array.isArray(keys) && keys instanceof Object && typeof(keys) !== 'function' && !(keys instanceof Code)) {
- keys = Object.keys(keys);
- }
-
- if(typeof reduce === 'function') {
- reduce = reduce.toString();
- }
-
- if(typeof finalize === 'function') {
- finalize = finalize.toString();
- }
-
- // Set up the command as default
- command = command == null ? true : command;
-
- // Execute using the command
- if(command) {
- var reduceFunction = reduce instanceof Code
- ? reduce
- : new Code(reduce);
-
- var selector = {
- group: {
- 'ns': this.collectionName
- , '$reduce': reduceFunction
- , 'cond': condition
- , 'initial': initial
- , 'out': "inline"
- }
- };
-
- // if finalize is defined
- if(finalize != null) selector.group['finalize'] = finalize;
- // Set up group selector
- if ('function' === typeof keys || keys instanceof Code) {
- selector.group.$keyf = keys instanceof Code
- ? keys
- : new Code(keys);
- } else {
- var hash = {};
- keys.forEach(function (key) {
- hash[key] = 1;
- });
- selector.group.key = hash;
- }
-
- var cmd = DbCommand.createDbSlaveOkCommand(this.db, selector);
- // Set read preference if we set one
- var readPreference = options['readPreference'] ? options['readPreference'] : false;
-
- this.db._executeQueryCommand(cmd, {read:readPreference}, function (err, result) {
- if(err != null) return callback(err);
-
- var document = result.documents[0];
- if (null == document.retval) {
- return callback(new Error("group command failed: " + document.errmsg));
- }
-
- callback(null, document.retval);
- });
-
- } else {
- // Create execution scope
- var scope = reduce != null && reduce instanceof Code
- ? reduce.scope
- : {};
-
- scope.ns = this.collectionName;
- scope.keys = keys;
- scope.condition = condition;
- scope.initial = initial;
-
- // Pass in the function text to execute within mongodb.
- var groupfn = groupFunction.replace(/ reduce;/, reduce.toString() + ';');
-
- this.db.eval(new Code(groupfn, scope), function (err, results) {
- if (err) return callback(err, null);
- callback(null, results.result || results);
- });
- }
-};
-
-/**
- * Returns the options of the collection.
- *
- * @param {Function} callback returns option results.
- * @return {null}
- * @api public
- */
-Collection.prototype.options = function options(callback) {
- this.db.collectionsInfo(this.collectionName, function (err, cursor) {
- if (err) return callback(err);
- cursor.nextObject(function (err, document) {
- callback(err, document && document.options || null);
- });
- });
-};
-
-/**
- * Returns if the collection is a capped collection
- *
- * @param {Function} callback returns if collection is capped.
- * @return {null}
- * @api public
- */
-Collection.prototype.isCapped = function isCapped(callback) {
- this.options(function(err, document) {
- if(err != null) {
- callback(err);
- } else {
- callback(null, document && document.capped);
- }
- });
-};
-
-/**
- * Checks if one or more indexes exist on the collection
- *
- * @param {String|Array} indexNames check if one or more indexes exist on the collection.
- * @param {Function} callback returns if the indexes exist.
- * @return {null}
- * @api public
- */
-Collection.prototype.indexExists = function indexExists(indexes, callback) {
- this.indexInformation(function(err, indexInformation) {
- // If we have an error return
- if(err != null) return callback(err, null);
- // Let's check for the index names
- if(Array.isArray(indexes)) {
- for(var i = 0; i < indexes.length; i++) {
- if(indexInformation[indexes[i]] == null) {
- return callback(null, false);
- }
- }
-
- // All keys found return true
- return callback(null, true);
- } else {
- return callback(null, indexInformation[indexes] != null);
- }
- });
-}
-
-/**
- * Execute the geoNear command to search for items in the collection
- *
- * Options
- * - **num** {Number}, max number of results to return.
- * - **maxDistance** {Number}, include results up to maxDistance from the point.
- * - **distanceMultiplier** {Number}, include a value to multiply the distances with allowing for range conversions.
- * - **query** {Object}, filter the results by a query.
- * - **spherical** {Boolean, default:false}, perform query using a spherical model.
- * - **uniqueDocs** {Boolean, default:false}, the closest location in a document to the center of the search region will always be returned MongoDB > 2.X.
- * - **includeLocs** {Boolean, default:false}, include the location data fields in the top level of the results MongoDB > 2.X.
- * - **readPreference** {String}, the preferred read preference ((Server.PRIMARY, Server.PRIMARY_PREFERRED, Server.SECONDARY, Server.SECONDARY_PREFERRED, Server.NEAREST).
- *
- * @param {Number} x point to search on the x axis, ensure the indexes are ordered in the same order.
- * @param {Number} y point to search on the y axis, ensure the indexes are ordered in the same order.
- * @param {Objects} [options] options for the map reduce job.
- * @param {Function} callback returns matching documents.
- * @return {null}
- * @api public
- */
-Collection.prototype.geoNear = function geoNear(x, y, options, callback) {
- var args = Array.prototype.slice.call(arguments, 2);
- callback = args.pop();
- // Fetch all commands
- options = args.length ? args.shift() : {};
-
- // Build command object
- var commandObject = {
- geoNear:this.collectionName,
- near: [x, y]
- }
-
- // Decorate object if any with known properties
- if(options['num'] != null) commandObject['num'] = options['num'];
- if(options['maxDistance'] != null) commandObject['maxDistance'] = options['maxDistance'];
- if(options['distanceMultiplier'] != null) commandObject['distanceMultiplier'] = options['distanceMultiplier'];
- if(options['query'] != null) commandObject['query'] = options['query'];
- if(options['spherical'] != null) commandObject['spherical'] = options['spherical'];
- if(options['uniqueDocs'] != null) commandObject['uniqueDocs'] = options['uniqueDocs'];
- if(options['includeLocs'] != null) commandObject['includeLocs'] = options['includeLocs'];
-
- // Execute the command
- this.db.command(commandObject, options, callback);
-}
-
-/**
- * Execute a geo search using a geo haystack index on a collection.
- *
- * Options
- * - **maxDistance** {Number}, include results up to maxDistance from the point.
- * - **search** {Object}, filter the results by a query.
- * - **limit** {Number}, max number of results to return.
- * - **readPreference** {String}, the preferred read preference ((Server.PRIMARY, Server.PRIMARY_PREFERRED, Server.SECONDARY, Server.SECONDARY_PREFERRED, Server.NEAREST).
- *
- * @param {Number} x point to search on the x axis, ensure the indexes are ordered in the same order.
- * @param {Number} y point to search on the y axis, ensure the indexes are ordered in the same order.
- * @param {Objects} [options] options for the map reduce job.
- * @param {Function} callback returns matching documents.
- * @return {null}
- * @api public
- */
-Collection.prototype.geoHaystackSearch = function geoHaystackSearch(x, y, options, callback) {
- var args = Array.prototype.slice.call(arguments, 2);
- callback = args.pop();
- // Fetch all commands
- options = args.length ? args.shift() : {};
-
- // Build command object
- var commandObject = {
- geoSearch:this.collectionName,
- near: [x, y]
- }
-
- // Decorate object if any with known properties
- if(options['maxDistance'] != null) commandObject['maxDistance'] = options['maxDistance'];
- if(options['query'] != null) commandObject['search'] = options['query'];
- if(options['search'] != null) commandObject['search'] = options['search'];
- if(options['limit'] != null) commandObject['limit'] = options['limit'];
-
- // Execute the command
- this.db.command(commandObject, options, callback);
-}
-
-/**
- * Retrieve all the indexes on the collection.
- *
- * @param {Function} callback returns index information.
- * @return {null}
- * @api public
- */
-Collection.prototype.indexes = function indexes(callback) {
- // Return all the index information
- this.db.indexInformation(this.collectionName, {full:true}, callback);
-}
-
-/**
- * Execute an aggregation framework pipeline against the collection, needs MongoDB >= 2.1
- *
- * Options
- * - **readPreference** {String}, the preferred read preference ((Server.PRIMARY, Server.PRIMARY_PREFERRED, Server.SECONDARY, Server.SECONDARY_PREFERRED, Server.NEAREST).
- *
- * @param {Array} array containing all the aggregation framework commands for the execution.
- * @param {Object} [options] additional options during update.
- * @param {Function} callback returns matching documents.
- * @return {null}
- * @api public
- */
-Collection.prototype.aggregate = function(pipeline, options, callback) {
- // * - **explain** {Boolean}, return the query plan for the aggregation pipeline instead of the results. 2.3, 2.4
- var args = Array.prototype.slice.call(arguments, 0);
- callback = args.pop();
- var self = this;
- // Get the right options
- options = args[args.length - 1].explain ? args.pop() : {}
-
- // Convert operations to an array
- if(!Array.isArray(args[0])) {
- pipeline = [];
- // Push all the operations to the pipeline
- for(var i = 0; i < args.length; i++) pipeline.push(args[i]);
- }
-
- // Build the command
- var command = { aggregate : this.collectionName, pipeline : pipeline};
- // Add all options
- var keys = Object.keys(options);
- // Add all options
- for(var i = 0; i < keys.length; i++) {
- command[keys[i]] = options[keys[i]];
- }
-
- // Execute the command
- this.db.command(command, options, function(err, result) {
- if(err) {
- callback(err);
- } else if(result['err'] || result['errmsg']) {
- callback(self.db.wrap(result));
- } else if(typeof result == 'object' && result['serverPipeline']) {
- callback(null, result);
- } else {
- callback(null, result.result);
- }
- });
-}
-
-/**
- * Get all the collection statistics.
- *
- * Options
- * - **scale** {Number}, divide the returned sizes by scale value.
- * - **readPreference** {String}, the preferred read preference ((Server.PRIMARY, Server.PRIMARY_PREFERRED, Server.SECONDARY, Server.SECONDARY_PREFERRED, Server.NEAREST).
- *
- * @param {Objects} [options] options for the stats command.
- * @param {Function} callback returns statistical information for the collection.
- * @return {null}
- * @api public
- */
-Collection.prototype.stats = function stats(options, callback) {
- var args = Array.prototype.slice.call(arguments, 0);
- callback = args.pop();
- // Fetch all commands
- options = args.length ? args.shift() : {};
-
- // Build command object
- var commandObject = {
- collStats:this.collectionName,
- }
-
- // Check if we have the scale value
- if(options['scale'] != null) commandObject['scale'] = options['scale'];
-
- // Execute the command
- this.db.command(commandObject, options, callback);
-}
-
-/**
- * @ignore
- */
-Object.defineProperty(Collection.prototype, "hint", {
- enumerable: true
- , get: function () {
- return this.internalHint;
- }
- , set: function (v) {
- this.internalHint = normalizeHintField(v);
- }
-});
-
-/**
- * Expose.
- */
-exports.Collection = Collection;
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/CoAuthoring/node_modules/mongodb/lib/mongodb/commands/base_command.js b/CoAuthoring/node_modules/mongodb/lib/mongodb/commands/base_command.js
deleted file mode 100644
index 955858283c..0000000000
--- a/CoAuthoring/node_modules/mongodb/lib/mongodb/commands/base_command.js
+++ /dev/null
@@ -1,29 +0,0 @@
-/**
- Base object used for common functionality
-**/
-var BaseCommand = exports.BaseCommand = function BaseCommand() {
-};
-
-var id = 1;
-BaseCommand.prototype.getRequestId = function getRequestId() {
- if (!this.requestId) this.requestId = id++;
- return this.requestId;
-};
-
-BaseCommand.prototype.setMongosReadPreference = function setMongosReadPreference(readPreference, tags) {}
-
-BaseCommand.prototype.updateRequestId = function() {
- this.requestId = id++;
- return this.requestId;
-};
-
-// OpCodes
-BaseCommand.OP_REPLY = 1;
-BaseCommand.OP_MSG = 1000;
-BaseCommand.OP_UPDATE = 2001;
-BaseCommand.OP_INSERT = 2002;
-BaseCommand.OP_GET_BY_OID = 2003;
-BaseCommand.OP_QUERY = 2004;
-BaseCommand.OP_GET_MORE = 2005;
-BaseCommand.OP_DELETE = 2006;
-BaseCommand.OP_KILL_CURSORS = 2007;
\ No newline at end of file
diff --git a/CoAuthoring/node_modules/mongodb/lib/mongodb/commands/db_command.js b/CoAuthoring/node_modules/mongodb/lib/mongodb/commands/db_command.js
deleted file mode 100644
index d0a5de1844..0000000000
--- a/CoAuthoring/node_modules/mongodb/lib/mongodb/commands/db_command.js
+++ /dev/null
@@ -1,213 +0,0 @@
-var QueryCommand = require('./query_command').QueryCommand,
- InsertCommand = require('./insert_command').InsertCommand,
- inherits = require('util').inherits,
- crypto = require('crypto');
-
-/**
- Db Command
-**/
-var DbCommand = exports.DbCommand = function(dbInstance, collectionName, queryOptions, numberToSkip, numberToReturn, query, returnFieldSelector, options) {
- QueryCommand.call(this);
- this.collectionName = collectionName;
- this.queryOptions = queryOptions;
- this.numberToSkip = numberToSkip;
- this.numberToReturn = numberToReturn;
- this.query = query;
- this.returnFieldSelector = returnFieldSelector;
- this.db = dbInstance;
-
- // Make sure we don't get a null exception
- options = options == null ? {} : options;
- // Let us defined on a command basis if we want functions to be serialized or not
- if(options['serializeFunctions'] != null && options['serializeFunctions']) {
- this.serializeFunctions = true;
- }
-};
-
-inherits(DbCommand, QueryCommand);
-
-// Constants
-DbCommand.SYSTEM_NAMESPACE_COLLECTION = "system.namespaces";
-DbCommand.SYSTEM_INDEX_COLLECTION = "system.indexes";
-DbCommand.SYSTEM_PROFILE_COLLECTION = "system.profile";
-DbCommand.SYSTEM_USER_COLLECTION = "system.users";
-DbCommand.SYSTEM_COMMAND_COLLECTION = "$cmd";
-
-// New commands
-DbCommand.NcreateIsMasterCommand = function(db, databaseName) {
- return new DbCommand(db, databaseName + "." + DbCommand.SYSTEM_COMMAND_COLLECTION, QueryCommand.OPTS_NO_CURSOR_TIMEOUT, 0, -1, {'ismaster':1}, null);
-};
-
-// Provide constructors for different db commands
-DbCommand.createIsMasterCommand = function(db) {
- return new DbCommand(db, db.databaseName + "." + DbCommand.SYSTEM_COMMAND_COLLECTION, QueryCommand.OPTS_NO_CURSOR_TIMEOUT, 0, -1, {'ismaster':1}, null);
-};
-
-DbCommand.createCollectionInfoCommand = function(db, selector) {
- return new DbCommand(db, db.databaseName + "." + DbCommand.SYSTEM_NAMESPACE_COLLECTION, QueryCommand.OPTS_NO_CURSOR_TIMEOUT, 0, 0, selector, null);
-};
-
-DbCommand.createGetNonceCommand = function(db, options) {
- return new DbCommand(db, db.databaseName + "." + DbCommand.SYSTEM_COMMAND_COLLECTION, QueryCommand.OPTS_NO_CURSOR_TIMEOUT, 0, -1, {'getnonce':1}, null);
-};
-
-DbCommand.createAuthenticationCommand = function(db, username, password, nonce, authdb) {
- // Use node md5 generator
- var md5 = crypto.createHash('md5');
- // Generate keys used for authentication
- md5.update(username + ":mongo:" + password);
- var hash_password = md5.digest('hex');
- // Final key
- md5 = crypto.createHash('md5');
- md5.update(nonce + username + hash_password);
- var key = md5.digest('hex');
- // Creat selector
- var selector = {'authenticate':1, 'user':username, 'nonce':nonce, 'key':key};
- // Create db command
- return new DbCommand(db, authdb + "." + DbCommand.SYSTEM_COMMAND_COLLECTION, QueryCommand.OPTS_NONE, 0, -1, selector, null);
-};
-
-DbCommand.createLogoutCommand = function(db) {
- return new DbCommand(db, db.databaseName + "." + DbCommand.SYSTEM_COMMAND_COLLECTION, QueryCommand.OPTS_NO_CURSOR_TIMEOUT, 0, -1, {'logout':1}, null);
-};
-
-DbCommand.createCreateCollectionCommand = function(db, collectionName, options) {
- var selector = {'create':collectionName};
- // Modify the options to ensure correct behaviour
- for(var name in options) {
- if(options[name] != null && options[name].constructor != Function) selector[name] = options[name];
- }
- // Execute the command
- return new DbCommand(db, db.databaseName + "." + DbCommand.SYSTEM_COMMAND_COLLECTION, QueryCommand.OPTS_NO_CURSOR_TIMEOUT, 0, -1, selector, null);
-};
-
-DbCommand.createDropCollectionCommand = function(db, collectionName) {
- return new DbCommand(db, db.databaseName + "." + DbCommand.SYSTEM_COMMAND_COLLECTION, QueryCommand.OPTS_NO_CURSOR_TIMEOUT, 0, -1, {'drop':collectionName}, null);
-};
-
-DbCommand.createRenameCollectionCommand = function(db, fromCollectionName, toCollectionName) {
- var renameCollection = db.databaseName + "." + fromCollectionName;
- var toCollection = db.databaseName + "." + toCollectionName;
- return new DbCommand(db, "admin." + DbCommand.SYSTEM_COMMAND_COLLECTION, QueryCommand.OPTS_NO_CURSOR_TIMEOUT, 0, -1, {'renameCollection':renameCollection, 'to':toCollection}, null);
-};
-
-DbCommand.createGetLastErrorCommand = function(options, db) {
-
- if (typeof db === 'undefined') {
- db = options;
- options = {};
- }
- // Final command
- var command = {'getlasterror':1};
- // If we have an options Object let's merge in the fields (fsync/wtimeout/w)
- if('object' === typeof options) {
- for(var name in options) {
- command[name] = options[name]
- }
- }
-
- // Execute command
- return new DbCommand(db, db.databaseName + "." + DbCommand.SYSTEM_COMMAND_COLLECTION, QueryCommand.OPTS_NO_CURSOR_TIMEOUT, 0, -1, command, null);
-};
-
-DbCommand.createGetLastStatusCommand = DbCommand.createGetLastErrorCommand;
-
-DbCommand.createGetPreviousErrorsCommand = function(db) {
- return new DbCommand(db, db.databaseName + "." + DbCommand.SYSTEM_COMMAND_COLLECTION, QueryCommand.OPTS_NO_CURSOR_TIMEOUT, 0, -1, {'getpreverror':1}, null);
-};
-
-DbCommand.createResetErrorHistoryCommand = function(db) {
- return new DbCommand(db, db.databaseName + "." + DbCommand.SYSTEM_COMMAND_COLLECTION, QueryCommand.OPTS_NO_CURSOR_TIMEOUT, 0, -1, {'reseterror':1}, null);
-};
-
-DbCommand.createCreateIndexCommand = function(db, collectionName, fieldOrSpec, options) {
- var fieldHash = {};
- var indexes = [];
- var keys;
-
- // Get all the fields accordingly
- if (fieldOrSpec.constructor === String) { // 'type'
- indexes.push(fieldOrSpec + '_' + 1);
- fieldHash[fieldOrSpec] = 1;
- } else if (fieldOrSpec.constructor === Array) { // [{location:'2d'}, ...]
- fieldOrSpec.forEach(function(f) {
- if (f.constructor === String) { // [{location:'2d'}, 'type']
- indexes.push(f + '_' + 1);
- fieldHash[f] = 1;
- } else if (f.constructor === Array) { // [['location', '2d'],['type', 1]]
- indexes.push(f[0] + '_' + (f[1] || 1));
- fieldHash[f[0]] = f[1] || 1;
- } else if (f.constructor === Object) { // [{location:'2d'}, {type:1}]
- keys = Object.keys(f);
- keys.forEach(function(k) {
- indexes.push(k + '_' + f[k]);
- fieldHash[k] = f[k];
- });
- } else {
- // undefined
- }
- });
- } else if (fieldOrSpec.constructor === Object) { // {location:'2d', type:1}
- keys = Object.keys(fieldOrSpec);
- keys.forEach(function(key) {
- indexes.push(key + '_' + fieldOrSpec[key]);
- fieldHash[key] = fieldOrSpec[key];
- });
- }
-
- // Generate the index name
- var indexName = indexes.join("_");
- // Build the selector
- var selector = {'ns':(db.databaseName + "." + collectionName), 'key':fieldHash, 'name':indexName};
-
- // Ensure we have a correct finalUnique
- var finalUnique = options == null || 'object' === typeof options ? false : options;
- // Set up options
- options = options == null || typeof options == 'boolean' ? {} : options;
-
- // Add all the options
- var keys = Object.keys(options);
- // Add all the fields to the selector
- for(var i = 0; i < keys.length; i++) {
- selector[keys[i]] = options[keys[i]];
- }
-
- // If we don't have the unique property set on the selector
- if(selector['unique'] == null) selector['unique'] = finalUnique;
- // Create the insert command for the index and return the document
- return new InsertCommand(db, db.databaseName + "." + DbCommand.SYSTEM_INDEX_COLLECTION, false).add(selector);
-};
-
-DbCommand.logoutCommand = function(db, command_hash, options) {
- var dbName = options != null && options['authdb'] != null ? options['authdb'] : db.databaseName;
- // Create logout command
- return new DbCommand(db, dbName + "." + DbCommand.SYSTEM_COMMAND_COLLECTION, QueryCommand.OPTS_NO_CURSOR_TIMEOUT, 0, -1, command_hash, null);
-}
-
-DbCommand.createDropIndexCommand = function(db, collectionName, indexName) {
- return new DbCommand(db, db.databaseName + "." + DbCommand.SYSTEM_COMMAND_COLLECTION, QueryCommand.OPTS_NO_CURSOR_TIMEOUT, 0, -1, {'deleteIndexes':collectionName, 'index':indexName}, null);
-};
-
-DbCommand.createReIndexCommand = function(db, collectionName) {
- return new DbCommand(db, db.databaseName + "." + DbCommand.SYSTEM_COMMAND_COLLECTION, QueryCommand.OPTS_NO_CURSOR_TIMEOUT, 0, -1, {'reIndex':collectionName}, null);
-};
-
-DbCommand.createDropDatabaseCommand = function(db) {
- return new DbCommand(db, db.databaseName + "." + DbCommand.SYSTEM_COMMAND_COLLECTION, QueryCommand.OPTS_NO_CURSOR_TIMEOUT, 0, -1, {'dropDatabase':1}, null);
-};
-
-DbCommand.createDbCommand = function(db, command_hash, options) {
- return new DbCommand(db, db.databaseName + "." + DbCommand.SYSTEM_COMMAND_COLLECTION, QueryCommand.OPTS_NO_CURSOR_TIMEOUT, 0, -1, command_hash, null, options);
-};
-
-DbCommand.createAdminDbCommand = function(db, command_hash) {
- return new DbCommand(db, "admin." + DbCommand.SYSTEM_COMMAND_COLLECTION, QueryCommand.OPTS_NO_CURSOR_TIMEOUT, 0, -1, command_hash, null);
-};
-
-DbCommand.createAdminDbCommandSlaveOk = function(db, command_hash) {
- return new DbCommand(db, "admin." + DbCommand.SYSTEM_COMMAND_COLLECTION, QueryCommand.OPTS_NO_CURSOR_TIMEOUT | QueryCommand.OPTS_SLAVE, 0, -1, command_hash, null);
-};
-
-DbCommand.createDbSlaveOkCommand = function(db, command_hash, options) {
- return new DbCommand(db, db.databaseName + "." + DbCommand.SYSTEM_COMMAND_COLLECTION, QueryCommand.OPTS_NO_CURSOR_TIMEOUT | QueryCommand.OPTS_SLAVE, 0, -1, command_hash, null, options);
-};
\ No newline at end of file
diff --git a/CoAuthoring/node_modules/mongodb/lib/mongodb/commands/delete_command.js b/CoAuthoring/node_modules/mongodb/lib/mongodb/commands/delete_command.js
deleted file mode 100644
index e6ae20ab6e..0000000000
--- a/CoAuthoring/node_modules/mongodb/lib/mongodb/commands/delete_command.js
+++ /dev/null
@@ -1,114 +0,0 @@
-var BaseCommand = require('./base_command').BaseCommand,
- inherits = require('util').inherits;
-
-/**
- Insert Document Command
-**/
-var DeleteCommand = exports.DeleteCommand = function(db, collectionName, selector, flags) {
- BaseCommand.call(this);
-
- // Validate correctness off the selector
- var object = selector;
- if(Buffer.isBuffer(object)) {
- var object_size = object[0] | object[1] << 8 | object[2] << 16 | object[3] << 24;
- if(object_size != object.length) {
- var error = new Error("delete raw message size does not match message header size [" + object.length + "] != [" + object_size + "]");
- error.name = 'MongoError';
- throw error;
- }
- }
-
- this.flags = flags;
- this.collectionName = collectionName;
- this.selector = selector;
- this.db = db;
-};
-
-inherits(DeleteCommand, BaseCommand);
-
-DeleteCommand.OP_DELETE = 2006;
-
-/*
-struct {
- MsgHeader header; // standard message header
- int32 ZERO; // 0 - reserved for future use
- cstring fullCollectionName; // "dbname.collectionname"
- int32 ZERO; // 0 - reserved for future use
- mongo.BSON selector; // query object. See below for details.
-}
-*/
-DeleteCommand.prototype.toBinary = function() {
- // Calculate total length of the document
- var totalLengthOfCommand = 4 + Buffer.byteLength(this.collectionName) + 1 + 4 + this.db.bson.calculateObjectSize(this.selector, false, true) + (4 * 4);
- // Let's build the single pass buffer command
- var _index = 0;
- var _command = new Buffer(totalLengthOfCommand);
- // Write the header information to the buffer
- _command[_index + 3] = (totalLengthOfCommand >> 24) & 0xff;
- _command[_index + 2] = (totalLengthOfCommand >> 16) & 0xff;
- _command[_index + 1] = (totalLengthOfCommand >> 8) & 0xff;
- _command[_index] = totalLengthOfCommand & 0xff;
- // Adjust index
- _index = _index + 4;
- // Write the request ID
- _command[_index + 3] = (this.requestId >> 24) & 0xff;
- _command[_index + 2] = (this.requestId >> 16) & 0xff;
- _command[_index + 1] = (this.requestId >> 8) & 0xff;
- _command[_index] = this.requestId & 0xff;
- // Adjust index
- _index = _index + 4;
- // Write zero
- _command[_index++] = 0;
- _command[_index++] = 0;
- _command[_index++] = 0;
- _command[_index++] = 0;
- // Write the op_code for the command
- _command[_index + 3] = (DeleteCommand.OP_DELETE >> 24) & 0xff;
- _command[_index + 2] = (DeleteCommand.OP_DELETE >> 16) & 0xff;
- _command[_index + 1] = (DeleteCommand.OP_DELETE >> 8) & 0xff;
- _command[_index] = DeleteCommand.OP_DELETE & 0xff;
- // Adjust index
- _index = _index + 4;
-
- // Write zero
- _command[_index++] = 0;
- _command[_index++] = 0;
- _command[_index++] = 0;
- _command[_index++] = 0;
-
- // Write the collection name to the command
- _index = _index + _command.write(this.collectionName, _index, 'utf8') + 1;
- _command[_index - 1] = 0;
-
- // Write the flags
- _command[_index + 3] = (this.flags >> 24) & 0xff;
- _command[_index + 2] = (this.flags >> 16) & 0xff;
- _command[_index + 1] = (this.flags >> 8) & 0xff;
- _command[_index] = this.flags & 0xff;
- // Adjust index
- _index = _index + 4;
-
- // Document binary length
- var documentLength = 0
-
- // Serialize the selector
- // If we are passing a raw buffer, do minimal validation
- if(Buffer.isBuffer(this.selector)) {
- documentLength = this.selector.length;
- // Copy the data into the current buffer
- this.selector.copy(_command, _index);
- } else {
- documentLength = this.db.bson.serializeWithBufferAndIndex(this.selector, this.checkKeys, _command, _index) - _index + 1;
- }
-
- // Write the length to the document
- _command[_index + 3] = (documentLength >> 24) & 0xff;
- _command[_index + 2] = (documentLength >> 16) & 0xff;
- _command[_index + 1] = (documentLength >> 8) & 0xff;
- _command[_index] = documentLength & 0xff;
- // Update index in buffer
- _index = _index + documentLength;
- // Add terminating 0 for the object
- _command[_index - 1] = 0;
- return _command;
-};
\ No newline at end of file
diff --git a/CoAuthoring/node_modules/mongodb/lib/mongodb/commands/get_more_command.js b/CoAuthoring/node_modules/mongodb/lib/mongodb/commands/get_more_command.js
deleted file mode 100644
index d3aac02ef8..0000000000
--- a/CoAuthoring/node_modules/mongodb/lib/mongodb/commands/get_more_command.js
+++ /dev/null
@@ -1,83 +0,0 @@
-var BaseCommand = require('./base_command').BaseCommand,
- inherits = require('util').inherits,
- binaryutils = require('../utils');
-
-/**
- Get More Document Command
-**/
-var GetMoreCommand = exports.GetMoreCommand = function(db, collectionName, numberToReturn, cursorId) {
- BaseCommand.call(this);
-
- this.collectionName = collectionName;
- this.numberToReturn = numberToReturn;
- this.cursorId = cursorId;
- this.db = db;
-};
-
-inherits(GetMoreCommand, BaseCommand);
-
-GetMoreCommand.OP_GET_MORE = 2005;
-
-GetMoreCommand.prototype.toBinary = function() {
- // Calculate total length of the document
- var totalLengthOfCommand = 4 + Buffer.byteLength(this.collectionName) + 1 + 4 + 8 + (4 * 4);
- // Let's build the single pass buffer command
- var _index = 0;
- var _command = new Buffer(totalLengthOfCommand);
- // Write the header information to the buffer
- _command[_index++] = totalLengthOfCommand & 0xff;
- _command[_index++] = (totalLengthOfCommand >> 8) & 0xff;
- _command[_index++] = (totalLengthOfCommand >> 16) & 0xff;
- _command[_index++] = (totalLengthOfCommand >> 24) & 0xff;
-
- // Write the request ID
- _command[_index++] = this.requestId & 0xff;
- _command[_index++] = (this.requestId >> 8) & 0xff;
- _command[_index++] = (this.requestId >> 16) & 0xff;
- _command[_index++] = (this.requestId >> 24) & 0xff;
-
- // Write zero
- _command[_index++] = 0;
- _command[_index++] = 0;
- _command[_index++] = 0;
- _command[_index++] = 0;
-
- // Write the op_code for the command
- _command[_index++] = GetMoreCommand.OP_GET_MORE & 0xff;
- _command[_index++] = (GetMoreCommand.OP_GET_MORE >> 8) & 0xff;
- _command[_index++] = (GetMoreCommand.OP_GET_MORE >> 16) & 0xff;
- _command[_index++] = (GetMoreCommand.OP_GET_MORE >> 24) & 0xff;
-
- // Write zero
- _command[_index++] = 0;
- _command[_index++] = 0;
- _command[_index++] = 0;
- _command[_index++] = 0;
-
- // Write the collection name to the command
- _index = _index + _command.write(this.collectionName, _index, 'utf8') + 1;
- _command[_index - 1] = 0;
-
- // Number of documents to return
- _command[_index++] = this.numberToReturn & 0xff;
- _command[_index++] = (this.numberToReturn >> 8) & 0xff;
- _command[_index++] = (this.numberToReturn >> 16) & 0xff;
- _command[_index++] = (this.numberToReturn >> 24) & 0xff;
-
- // Encode the cursor id
- var low_bits = this.cursorId.getLowBits();
- // Encode low bits
- _command[_index++] = low_bits & 0xff;
- _command[_index++] = (low_bits >> 8) & 0xff;
- _command[_index++] = (low_bits >> 16) & 0xff;
- _command[_index++] = (low_bits >> 24) & 0xff;
-
- var high_bits = this.cursorId.getHighBits();
- // Encode high bits
- _command[_index++] = high_bits & 0xff;
- _command[_index++] = (high_bits >> 8) & 0xff;
- _command[_index++] = (high_bits >> 16) & 0xff;
- _command[_index++] = (high_bits >> 24) & 0xff;
- // Return command
- return _command;
-};
\ No newline at end of file
diff --git a/CoAuthoring/node_modules/mongodb/lib/mongodb/commands/insert_command.js b/CoAuthoring/node_modules/mongodb/lib/mongodb/commands/insert_command.js
deleted file mode 100644
index d6a210017a..0000000000
--- a/CoAuthoring/node_modules/mongodb/lib/mongodb/commands/insert_command.js
+++ /dev/null
@@ -1,147 +0,0 @@
-var BaseCommand = require('./base_command').BaseCommand,
- inherits = require('util').inherits;
-
-/**
- Insert Document Command
-**/
-var InsertCommand = exports.InsertCommand = function(db, collectionName, checkKeys, options) {
- BaseCommand.call(this);
-
- this.collectionName = collectionName;
- this.documents = [];
- this.checkKeys = checkKeys == null ? true : checkKeys;
- this.db = db;
- this.flags = 0;
- this.serializeFunctions = false;
-
- // Ensure valid options hash
- options = options == null ? {} : options;
-
- // Check if we have keepGoing set -> set flag if it's the case
- if(options['keepGoing'] != null && options['keepGoing']) {
- // This will finish inserting all non-index violating documents even if it returns an error
- this.flags = 1;
- }
-
- // Check if we have keepGoing set -> set flag if it's the case
- if(options['continueOnError'] != null && options['continueOnError']) {
- // This will finish inserting all non-index violating documents even if it returns an error
- this.flags = 1;
- }
-
- // Let us defined on a command basis if we want functions to be serialized or not
- if(options['serializeFunctions'] != null && options['serializeFunctions']) {
- this.serializeFunctions = true;
- }
-};
-
-inherits(InsertCommand, BaseCommand);
-
-// OpCodes
-InsertCommand.OP_INSERT = 2002;
-
-InsertCommand.prototype.add = function(document) {
- if(Buffer.isBuffer(document)) {
- var object_size = document[0] | document[1] << 8 | document[2] << 16 | document[3] << 24;
- if(object_size != document.length) {
- var error = new Error("insert raw message size does not match message header size [" + document.length + "] != [" + object_size + "]");
- error.name = 'MongoError';
- throw error;
- }
- }
-
- this.documents.push(document);
- return this;
-};
-
-/*
-struct {
- MsgHeader header; // standard message header
- int32 ZERO; // 0 - reserved for future use
- cstring fullCollectionName; // "dbname.collectionname"
- BSON[] documents; // one or more documents to insert into the collection
-}
-*/
-InsertCommand.prototype.toBinary = function() {
- // Calculate total length of the document
- var totalLengthOfCommand = 4 + Buffer.byteLength(this.collectionName) + 1 + (4 * 4);
- // var docLength = 0
- for(var i = 0; i < this.documents.length; i++) {
- if(Buffer.isBuffer(this.documents[i])) {
- totalLengthOfCommand += this.documents[i].length;
- } else {
- // Calculate size of document
- totalLengthOfCommand += this.db.bson.calculateObjectSize(this.documents[i], this.serializeFunctions, true);
- }
- }
-
- // Let's build the single pass buffer command
- var _index = 0;
- var _command = new Buffer(totalLengthOfCommand);
- // Write the header information to the buffer
- _command[_index + 3] = (totalLengthOfCommand >> 24) & 0xff;
- _command[_index + 2] = (totalLengthOfCommand >> 16) & 0xff;
- _command[_index + 1] = (totalLengthOfCommand >> 8) & 0xff;
- _command[_index] = totalLengthOfCommand & 0xff;
- // Adjust index
- _index = _index + 4;
- // Write the request ID
- _command[_index + 3] = (this.requestId >> 24) & 0xff;
- _command[_index + 2] = (this.requestId >> 16) & 0xff;
- _command[_index + 1] = (this.requestId >> 8) & 0xff;
- _command[_index] = this.requestId & 0xff;
- // Adjust index
- _index = _index + 4;
- // Write zero
- _command[_index++] = 0;
- _command[_index++] = 0;
- _command[_index++] = 0;
- _command[_index++] = 0;
- // Write the op_code for the command
- _command[_index + 3] = (InsertCommand.OP_INSERT >> 24) & 0xff;
- _command[_index + 2] = (InsertCommand.OP_INSERT >> 16) & 0xff;
- _command[_index + 1] = (InsertCommand.OP_INSERT >> 8) & 0xff;
- _command[_index] = InsertCommand.OP_INSERT & 0xff;
- // Adjust index
- _index = _index + 4;
- // Write flags if any
- _command[_index + 3] = (this.flags >> 24) & 0xff;
- _command[_index + 2] = (this.flags >> 16) & 0xff;
- _command[_index + 1] = (this.flags >> 8) & 0xff;
- _command[_index] = this.flags & 0xff;
- // Adjust index
- _index = _index + 4;
- // Write the collection name to the command
- _index = _index + _command.write(this.collectionName, _index, 'utf8') + 1;
- _command[_index - 1] = 0;
-
- // Write all the bson documents to the buffer at the index offset
- for(var i = 0; i < this.documents.length; i++) {
- // Document binary length
- var documentLength = 0
- var object = this.documents[i];
-
- // Serialize the selector
- // If we are passing a raw buffer, do minimal validation
- if(Buffer.isBuffer(object)) {
- documentLength = object.length;
- // Copy the data into the current buffer
- object.copy(_command, _index);
- } else {
- // Serialize the document straight to the buffer
- documentLength = this.db.bson.serializeWithBufferAndIndex(object, this.checkKeys, _command, _index, this.serializeFunctions) - _index + 1;
- }
-
- // Write the length to the document
- _command[_index + 3] = (documentLength >> 24) & 0xff;
- _command[_index + 2] = (documentLength >> 16) & 0xff;
- _command[_index + 1] = (documentLength >> 8) & 0xff;
- _command[_index] = documentLength & 0xff;
- // Update index in buffer
- _index = _index + documentLength;
- // Add terminating 0 for the object
- _command[_index - 1] = 0;
- }
-
- return _command;
-};
diff --git a/CoAuthoring/node_modules/mongodb/lib/mongodb/commands/kill_cursor_command.js b/CoAuthoring/node_modules/mongodb/lib/mongodb/commands/kill_cursor_command.js
deleted file mode 100644
index d8ccb0c3a6..0000000000
--- a/CoAuthoring/node_modules/mongodb/lib/mongodb/commands/kill_cursor_command.js
+++ /dev/null
@@ -1,98 +0,0 @@
-var BaseCommand = require('./base_command').BaseCommand,
- inherits = require('util').inherits,
- binaryutils = require('../utils');
-
-/**
- Insert Document Command
-**/
-var KillCursorCommand = exports.KillCursorCommand = function(db, cursorIds) {
- BaseCommand.call(this);
-
- this.cursorIds = cursorIds;
- this.db = db;
-};
-
-inherits(KillCursorCommand, BaseCommand);
-
-KillCursorCommand.OP_KILL_CURSORS = 2007;
-
-/*
-struct {
- MsgHeader header; // standard message header
- int32 ZERO; // 0 - reserved for future use
- int32 numberOfCursorIDs; // number of cursorIDs in message
- int64[] cursorIDs; // array of cursorIDs to close
-}
-*/
-KillCursorCommand.prototype.toBinary = function() {
- // Calculate total length of the document
- var totalLengthOfCommand = 4 + 4 + (4 * 4) + (this.cursorIds.length * 8);
- // Let's build the single pass buffer command
- var _index = 0;
- var _command = new Buffer(totalLengthOfCommand);
- // Write the header information to the buffer
- _command[_index + 3] = (totalLengthOfCommand >> 24) & 0xff;
- _command[_index + 2] = (totalLengthOfCommand >> 16) & 0xff;
- _command[_index + 1] = (totalLengthOfCommand >> 8) & 0xff;
- _command[_index] = totalLengthOfCommand & 0xff;
- // Adjust index
- _index = _index + 4;
- // Write the request ID
- _command[_index + 3] = (this.requestId >> 24) & 0xff;
- _command[_index + 2] = (this.requestId >> 16) & 0xff;
- _command[_index + 1] = (this.requestId >> 8) & 0xff;
- _command[_index] = this.requestId & 0xff;
- // Adjust index
- _index = _index + 4;
- // Write zero
- _command[_index++] = 0;
- _command[_index++] = 0;
- _command[_index++] = 0;
- _command[_index++] = 0;
- // Write the op_code for the command
- _command[_index + 3] = (KillCursorCommand.OP_KILL_CURSORS >> 24) & 0xff;
- _command[_index + 2] = (KillCursorCommand.OP_KILL_CURSORS >> 16) & 0xff;
- _command[_index + 1] = (KillCursorCommand.OP_KILL_CURSORS >> 8) & 0xff;
- _command[_index] = KillCursorCommand.OP_KILL_CURSORS & 0xff;
- // Adjust index
- _index = _index + 4;
-
- // Write zero
- _command[_index++] = 0;
- _command[_index++] = 0;
- _command[_index++] = 0;
- _command[_index++] = 0;
-
- // Number of cursors to kill
- var numberOfCursors = this.cursorIds.length;
- _command[_index + 3] = (numberOfCursors >> 24) & 0xff;
- _command[_index + 2] = (numberOfCursors >> 16) & 0xff;
- _command[_index + 1] = (numberOfCursors >> 8) & 0xff;
- _command[_index] = numberOfCursors & 0xff;
- // Adjust index
- _index = _index + 4;
-
- // Encode all the cursors
- for(var i = 0; i < this.cursorIds.length; i++) {
- // Encode the cursor id
- var low_bits = this.cursorIds[i].getLowBits();
- // Encode low bits
- _command[_index + 3] = (low_bits >> 24) & 0xff;
- _command[_index + 2] = (low_bits >> 16) & 0xff;
- _command[_index + 1] = (low_bits >> 8) & 0xff;
- _command[_index] = low_bits & 0xff;
- // Adjust index
- _index = _index + 4;
-
- var high_bits = this.cursorIds[i].getHighBits();
- // Encode high bits
- _command[_index + 3] = (high_bits >> 24) & 0xff;
- _command[_index + 2] = (high_bits >> 16) & 0xff;
- _command[_index + 1] = (high_bits >> 8) & 0xff;
- _command[_index] = high_bits & 0xff;
- // Adjust index
- _index = _index + 4;
- }
-
- return _command;
-};
\ No newline at end of file
diff --git a/CoAuthoring/node_modules/mongodb/lib/mongodb/commands/query_command.js b/CoAuthoring/node_modules/mongodb/lib/mongodb/commands/query_command.js
deleted file mode 100644
index bb5cb14a5a..0000000000
--- a/CoAuthoring/node_modules/mongodb/lib/mongodb/commands/query_command.js
+++ /dev/null
@@ -1,253 +0,0 @@
-var BaseCommand = require('./base_command').BaseCommand,
- inherits = require('util').inherits;
-
-/**
- Insert Document Command
-**/
-var QueryCommand = exports.QueryCommand = function(db, collectionName, queryOptions, numberToSkip, numberToReturn, query, returnFieldSelector, options) {
- BaseCommand.call(this);
-
- // Validate correctness off the selector
- var object = query,
- object_size;
- if(Buffer.isBuffer(object)) {
- object_size = object[0] | object[1] << 8 | object[2] << 16 | object[3] << 24;
- if(object_size != object.length) {
- var error = new Error("query selector raw message size does not match message header size [" + object.length + "] != [" + object_size + "]");
- error.name = 'MongoError';
- throw error;
- }
- }
-
- object = returnFieldSelector;
- if(Buffer.isBuffer(object)) {
- object_size = object[0] | object[1] << 8 | object[2] << 16 | object[3] << 24;
- if(object_size != object.length) {
- var error = new Error("query fields raw message size does not match message header size [" + object.length + "] != [" + object_size + "]");
- error.name = 'MongoError';
- throw error;
- }
- }
-
- // Make sure we don't get a null exception
- options = options == null ? {} : options;
- // Set up options
- this.collectionName = collectionName;
- this.queryOptions = queryOptions;
- this.numberToSkip = numberToSkip;
- this.numberToReturn = numberToReturn;
-
- // Ensure we have no null query
- query = query == null ? {} : query;
- // Wrap query in the $query parameter so we can add read preferences for mongos
- this.query = query;
- this.returnFieldSelector = returnFieldSelector;
- this.db = db;
-
- // Let us defined on a command basis if we want functions to be serialized or not
- if(options['serializeFunctions'] != null && options['serializeFunctions']) {
- this.serializeFunctions = true;
- }
-};
-
-inherits(QueryCommand, BaseCommand);
-
-QueryCommand.OP_QUERY = 2004;
-
-/*
- * Adds the read prefrence to the current command
- */
-QueryCommand.prototype.setMongosReadPreference = function(readPreference, tags) {
- // Force the slave ok flag to be set if we are not using primary read preference
- if(readPreference != false && readPreference != 'primary') {
- this.queryOptions |= QueryCommand.OPTS_SLAVE;
- }
-
- // Backward compatibility, ensure $query only set on read preference so 1.8.X works
- if((readPreference != null || tags != null) && this.query['$query'] == null) {
- this.query = {'$query': this.query};
- }
-
- // If we have no readPreference set and no tags, check if the slaveOk bit is set
- if(readPreference == null && tags == null) {
- // If we have a slaveOk bit set the read preference for MongoS
- if(this.queryOptions & QueryCommand.OPTS_SLAVE) {
- this.query['$readPreference'] = {mode: 'secondary'}
- } else {
- this.query['$readPreference'] = {mode: 'primary'}
- }
- }
-
- // Build read preference object
- if(typeof readPreference == 'object' && readPreference['_type'] == 'ReadPreference') {
- this.query['$readPreference'] = readPreference.toObject();
- } else if(readPreference != null) {
- // Add the read preference
- this.query['$readPreference'] = {mode: readPreference};
-
- // If we have tags let's add them
- if(tags != null) {
- this.query['$readPreference']['tags'] = tags;
- }
- }
-}
-
-/*
-struct {
- MsgHeader header; // standard message header
- int32 opts; // query options. See below for details.
- cstring fullCollectionName; // "dbname.collectionname"
- int32 numberToSkip; // number of documents to skip when returning results
- int32 numberToReturn; // number of documents to return in the first OP_REPLY
- BSON query ; // query object. See below for details.
- [ BSON returnFieldSelector; ] // OPTIONAL : selector indicating the fields to return. See below for details.
-}
-*/
-QueryCommand.prototype.toBinary = function() {
- // Total length of the command
- var totalLengthOfCommand = 0;
- // Calculate total length of the document
- if(Buffer.isBuffer(this.query)) {
- totalLengthOfCommand = 4 + Buffer.byteLength(this.collectionName) + 1 + 4 + 4 + this.query.length + (4 * 4);
- } else {
- totalLengthOfCommand = 4 + Buffer.byteLength(this.collectionName) + 1 + 4 + 4 + this.db.bson.calculateObjectSize(this.query, this.serializeFunctions, true) + (4 * 4);
- }
-
- // Calculate extra fields size
- if(this.returnFieldSelector != null && !(Buffer.isBuffer(this.returnFieldSelector))) {
- if(Object.keys(this.returnFieldSelector).length > 0) {
- totalLengthOfCommand += this.db.bson.calculateObjectSize(this.returnFieldSelector, this.serializeFunctions, true);
- }
- } else if(Buffer.isBuffer(this.returnFieldSelector)) {
- totalLengthOfCommand += this.returnFieldSelector.length;
- }
-
- // Let's build the single pass buffer command
- var _index = 0;
- var _command = new Buffer(totalLengthOfCommand);
- // Write the header information to the buffer
- _command[_index + 3] = (totalLengthOfCommand >> 24) & 0xff;
- _command[_index + 2] = (totalLengthOfCommand >> 16) & 0xff;
- _command[_index + 1] = (totalLengthOfCommand >> 8) & 0xff;
- _command[_index] = totalLengthOfCommand & 0xff;
- // Adjust index
- _index = _index + 4;
- // Write the request ID
- _command[_index + 3] = (this.requestId >> 24) & 0xff;
- _command[_index + 2] = (this.requestId >> 16) & 0xff;
- _command[_index + 1] = (this.requestId >> 8) & 0xff;
- _command[_index] = this.requestId & 0xff;
- // Adjust index
- _index = _index + 4;
- // Write zero
- _command[_index++] = 0;
- _command[_index++] = 0;
- _command[_index++] = 0;
- _command[_index++] = 0;
- // Write the op_code for the command
- _command[_index + 3] = (QueryCommand.OP_QUERY >> 24) & 0xff;
- _command[_index + 2] = (QueryCommand.OP_QUERY >> 16) & 0xff;
- _command[_index + 1] = (QueryCommand.OP_QUERY >> 8) & 0xff;
- _command[_index] = QueryCommand.OP_QUERY & 0xff;
- // Adjust index
- _index = _index + 4;
-
- // Write the query options
- _command[_index + 3] = (this.queryOptions >> 24) & 0xff;
- _command[_index + 2] = (this.queryOptions >> 16) & 0xff;
- _command[_index + 1] = (this.queryOptions >> 8) & 0xff;
- _command[_index] = this.queryOptions & 0xff;
- // Adjust index
- _index = _index + 4;
-
- // Write the collection name to the command
- _index = _index + _command.write(this.collectionName, _index, 'utf8') + 1;
- _command[_index - 1] = 0;
-
- // Write the number of documents to skip
- _command[_index + 3] = (this.numberToSkip >> 24) & 0xff;
- _command[_index + 2] = (this.numberToSkip >> 16) & 0xff;
- _command[_index + 1] = (this.numberToSkip >> 8) & 0xff;
- _command[_index] = this.numberToSkip & 0xff;
- // Adjust index
- _index = _index + 4;
-
- // Write the number of documents to return
- _command[_index + 3] = (this.numberToReturn >> 24) & 0xff;
- _command[_index + 2] = (this.numberToReturn >> 16) & 0xff;
- _command[_index + 1] = (this.numberToReturn >> 8) & 0xff;
- _command[_index] = this.numberToReturn & 0xff;
- // Adjust index
- _index = _index + 4;
-
- // Document binary length
- var documentLength = 0
- var object = this.query;
-
- // Serialize the selector
- if(Buffer.isBuffer(object)) {
- documentLength = object.length;
- // Copy the data into the current buffer
- object.copy(_command, _index);
- } else {
- // Serialize the document straight to the buffer
- documentLength = this.db.bson.serializeWithBufferAndIndex(object, this.checkKeys, _command, _index, this.serializeFunctions) - _index + 1;
- }
-
- // Write the length to the document
- _command[_index + 3] = (documentLength >> 24) & 0xff;
- _command[_index + 2] = (documentLength >> 16) & 0xff;
- _command[_index + 1] = (documentLength >> 8) & 0xff;
- _command[_index] = documentLength & 0xff;
- // Update index in buffer
- _index = _index + documentLength;
- // Add terminating 0 for the object
- _command[_index - 1] = 0;
-
- // Push field selector if available
- if(this.returnFieldSelector != null && !(Buffer.isBuffer(this.returnFieldSelector))) {
- if(Object.keys(this.returnFieldSelector).length > 0) {
- var documentLength = this.db.bson.serializeWithBufferAndIndex(this.returnFieldSelector, this.checkKeys, _command, _index, this.serializeFunctions) - _index + 1;
- // Write the length to the document
- _command[_index + 3] = (documentLength >> 24) & 0xff;
- _command[_index + 2] = (documentLength >> 16) & 0xff;
- _command[_index + 1] = (documentLength >> 8) & 0xff;
- _command[_index] = documentLength & 0xff;
- // Update index in buffer
- _index = _index + documentLength;
- // Add terminating 0 for the object
- _command[_index - 1] = 0;
- }
- } if(this.returnFieldSelector != null && Buffer.isBuffer(this.returnFieldSelector)) {
- // Document binary length
- var documentLength = 0
- var object = this.returnFieldSelector;
-
- // Serialize the selector
- documentLength = object.length;
- // Copy the data into the current buffer
- object.copy(_command, _index);
-
- // Write the length to the document
- _command[_index + 3] = (documentLength >> 24) & 0xff;
- _command[_index + 2] = (documentLength >> 16) & 0xff;
- _command[_index + 1] = (documentLength >> 8) & 0xff;
- _command[_index] = documentLength & 0xff;
- // Update index in buffer
- _index = _index + documentLength;
- // Add terminating 0 for the object
- _command[_index - 1] = 0;
- }
-
- // Return finished command
- return _command;
-};
-
-// Constants
-QueryCommand.OPTS_NONE = 0;
-QueryCommand.OPTS_TAILABLE_CURSOR = 2;
-QueryCommand.OPTS_SLAVE = 4;
-QueryCommand.OPTS_OPLOG_REPLY = 8;
-QueryCommand.OPTS_NO_CURSOR_TIMEOUT = 16;
-QueryCommand.OPTS_AWAIT_DATA = 32;
-QueryCommand.OPTS_EXHAUST = 64;
\ No newline at end of file
diff --git a/CoAuthoring/node_modules/mongodb/lib/mongodb/commands/update_command.js b/CoAuthoring/node_modules/mongodb/lib/mongodb/commands/update_command.js
deleted file mode 100644
index 9829dea453..0000000000
--- a/CoAuthoring/node_modules/mongodb/lib/mongodb/commands/update_command.js
+++ /dev/null
@@ -1,174 +0,0 @@
-var BaseCommand = require('./base_command').BaseCommand,
- inherits = require('util').inherits;
-
-/**
- Update Document Command
-**/
-var UpdateCommand = exports.UpdateCommand = function(db, collectionName, spec, document, options) {
- BaseCommand.call(this);
-
- var object = spec;
- if(Buffer.isBuffer(object)) {
- var object_size = object[0] | object[1] << 8 | object[2] << 16 | object[3] << 24;
- if(object_size != object.length) {
- var error = new Error("update spec raw message size does not match message header size [" + object.length + "] != [" + object_size + "]");
- error.name = 'MongoError';
- throw error;
- }
- }
-
- var object = document;
- if(Buffer.isBuffer(object)) {
- var object_size = object[0] | object[1] << 8 | object[2] << 16 | object[3] << 24;
- if(object_size != object.length) {
- var error = new Error("update document raw message size does not match message header size [" + object.length + "] != [" + object_size + "]");
- error.name = 'MongoError';
- throw error;
- }
- }
-
- this.collectionName = collectionName;
- this.spec = spec;
- this.document = document;
- this.db = db;
- this.serializeFunctions = false;
-
- // Generate correct flags
- var db_upsert = 0;
- var db_multi_update = 0;
- db_upsert = options != null && options['upsert'] != null ? (options['upsert'] == true ? 1 : 0) : db_upsert;
- db_multi_update = options != null && options['multi'] != null ? (options['multi'] == true ? 1 : 0) : db_multi_update;
-
- // Flags
- this.flags = parseInt(db_multi_update.toString() + db_upsert.toString(), 2);
- // Let us defined on a command basis if we want functions to be serialized or not
- if(options['serializeFunctions'] != null && options['serializeFunctions']) {
- this.serializeFunctions = true;
- }
-};
-
-inherits(UpdateCommand, BaseCommand);
-
-UpdateCommand.OP_UPDATE = 2001;
-
-/*
-struct {
- MsgHeader header; // standard message header
- int32 ZERO; // 0 - reserved for future use
- cstring fullCollectionName; // "dbname.collectionname"
- int32 flags; // bit vector. see below
- BSON spec; // the query to select the document
- BSON document; // the document data to update with or insert
-}
-*/
-UpdateCommand.prototype.toBinary = function() {
- // Calculate total length of the document
- var totalLengthOfCommand = 4 + Buffer.byteLength(this.collectionName) + 1 + 4 + this.db.bson.calculateObjectSize(this.spec, false, true) +
- this.db.bson.calculateObjectSize(this.document, this.serializeFunctions, true) + (4 * 4);
-
- // Let's build the single pass buffer command
- var _index = 0;
- var _command = new Buffer(totalLengthOfCommand);
- // Write the header information to the buffer
- _command[_index + 3] = (totalLengthOfCommand >> 24) & 0xff;
- _command[_index + 2] = (totalLengthOfCommand >> 16) & 0xff;
- _command[_index + 1] = (totalLengthOfCommand >> 8) & 0xff;
- _command[_index] = totalLengthOfCommand & 0xff;
- // Adjust index
- _index = _index + 4;
- // Write the request ID
- _command[_index + 3] = (this.requestId >> 24) & 0xff;
- _command[_index + 2] = (this.requestId >> 16) & 0xff;
- _command[_index + 1] = (this.requestId >> 8) & 0xff;
- _command[_index] = this.requestId & 0xff;
- // Adjust index
- _index = _index + 4;
- // Write zero
- _command[_index++] = 0;
- _command[_index++] = 0;
- _command[_index++] = 0;
- _command[_index++] = 0;
- // Write the op_code for the command
- _command[_index + 3] = (UpdateCommand.OP_UPDATE >> 24) & 0xff;
- _command[_index + 2] = (UpdateCommand.OP_UPDATE >> 16) & 0xff;
- _command[_index + 1] = (UpdateCommand.OP_UPDATE >> 8) & 0xff;
- _command[_index] = UpdateCommand.OP_UPDATE & 0xff;
- // Adjust index
- _index = _index + 4;
-
- // Write zero
- _command[_index++] = 0;
- _command[_index++] = 0;
- _command[_index++] = 0;
- _command[_index++] = 0;
-
- // Write the collection name to the command
- _index = _index + _command.write(this.collectionName, _index, 'utf8') + 1;
- _command[_index - 1] = 0;
-
- // Write the update flags
- _command[_index + 3] = (this.flags >> 24) & 0xff;
- _command[_index + 2] = (this.flags >> 16) & 0xff;
- _command[_index + 1] = (this.flags >> 8) & 0xff;
- _command[_index] = this.flags & 0xff;
- // Adjust index
- _index = _index + 4;
-
- // Document binary length
- var documentLength = 0
- var object = this.spec;
-
- // Serialize the selector
- // If we are passing a raw buffer, do minimal validation
- if(Buffer.isBuffer(object)) {
- var object_size = object[0] | object[1] << 8 | object[2] << 16 | object[3] << 24;
- if(object_size != object.length) throw new Error("raw message size does not match message header size [" + object.length + "] != [" + object_size + "]");
- documentLength = object.length;
- // Copy the data into the current buffer
- object.copy(_command, _index);
- } else {
- documentLength = this.db.bson.serializeWithBufferAndIndex(object, this.checkKeys, _command, _index, false) - _index + 1;
- }
-
- // Write the length to the document
- _command[_index + 3] = (documentLength >> 24) & 0xff;
- _command[_index + 2] = (documentLength >> 16) & 0xff;
- _command[_index + 1] = (documentLength >> 8) & 0xff;
- _command[_index] = documentLength & 0xff;
- // Update index in buffer
- _index = _index + documentLength;
- // Add terminating 0 for the object
- _command[_index - 1] = 0;
-
- // Document binary length
- var documentLength = 0
- var object = this.document;
-
- // Serialize the document
- // If we are passing a raw buffer, do minimal validation
- if(Buffer.isBuffer(object)) {
- var object_size = object[0] | object[1] << 8 | object[2] << 16 | object[3] << 24;
- if(object_size != object.length) throw new Error("raw message size does not match message header size [" + object.length + "] != [" + object_size + "]");
- documentLength = object.length;
- // Copy the data into the current buffer
- object.copy(_command, _index);
- } else {
- documentLength = this.db.bson.serializeWithBufferAndIndex(object, this.checkKeys, _command, _index, this.serializeFunctions) - _index + 1;
- }
-
- // Write the length to the document
- _command[_index + 3] = (documentLength >> 24) & 0xff;
- _command[_index + 2] = (documentLength >> 16) & 0xff;
- _command[_index + 1] = (documentLength >> 8) & 0xff;
- _command[_index] = documentLength & 0xff;
- // Update index in buffer
- _index = _index + documentLength;
- // Add terminating 0 for the object
- _command[_index - 1] = 0;
-
- return _command;
-};
-
-// Constants
-UpdateCommand.DB_UPSERT = 0;
-UpdateCommand.DB_MULTI_UPDATE = 1;
\ No newline at end of file
diff --git a/CoAuthoring/node_modules/mongodb/lib/mongodb/connection/connection.js b/CoAuthoring/node_modules/mongodb/lib/mongodb/connection/connection.js
deleted file mode 100644
index 3ed7feaa5d..0000000000
--- a/CoAuthoring/node_modules/mongodb/lib/mongodb/connection/connection.js
+++ /dev/null
@@ -1,416 +0,0 @@
-var utils = require('./connection_utils'),
- inherits = require('util').inherits,
- net = require('net'),
- EventEmitter = require('events').EventEmitter,
- inherits = require('util').inherits,
- binaryutils = require('../utils'),
- tls = require('tls');
-
-var Connection = exports.Connection = function(id, socketOptions) {
- // Set up event emitter
- EventEmitter.call(this);
- // Store all socket options
- this.socketOptions = socketOptions ? socketOptions : {host:'localhost', port:27017};
- // Id for the connection
- this.id = id;
- // State of the connection
- this.connected = false;
-
- //
- // Connection parsing state
- //
- this.maxBsonSize = socketOptions.maxBsonSize ? socketOptions.maxBsonSize : Connection.DEFAULT_MAX_BSON_SIZE;
- // Contains the current message bytes
- this.buffer = null;
- // Contains the current message size
- this.sizeOfMessage = 0;
- // Contains the readIndex for the messaage
- this.bytesRead = 0;
- // Contains spill over bytes from additional messages
- this.stubBuffer = 0;
-
- // Just keeps list of events we allow
- this.eventHandlers = {error:[], parseError:[], poolReady:[], message:[], close:[], timeout:[], end:[]};
-
- // Just keeps list of events we allow
- resetHandlers(this, false);
-}
-
-// Set max bson size
-Connection.DEFAULT_MAX_BSON_SIZE = 1024 * 1024 * 4;
-
-// Inherit event emitter so we can emit stuff wohoo
-inherits(Connection, EventEmitter);
-
-Connection.prototype.start = function() {
- // If we have a normal connection
- if(this.socketOptions.ssl) {
- // Create a new stream
- this.connection = new net.Socket();
- // Set timeout allowing backward compatibility to timeout if no connectTimeoutMS is set
- this.connection.setTimeout(this.socketOptions.connectTimeoutMS != null ? this.socketOptions.connectTimeoutMS : this.socketOptions.timeout);
- // Work around for 0.4.X
- if(process.version.indexOf("v0.4") == -1) this.connection.setNoDelay(this.socketOptions.noDelay);
- // Set keep alive if defined
- if(process.version.indexOf("v0.4") == -1) {
- if(this.socketOptions.keepAlive > 0) {
- this.connection.setKeepAlive(true, this.socketOptions.keepAlive);
- } else {
- this.connection.setKeepAlive(false);
- }
- }
-
- // Set up pair for tls with server, accept self-signed certificates as well
- var pair = this.pair = tls.createSecurePair(false);
- // Set up encrypted streams
- this.pair.encrypted.pipe(this.connection);
- this.connection.pipe(this.pair.encrypted);
-
- // Setup clearText stream
- this.writeSteam = this.pair.cleartext;
- // Add all handlers to the socket to manage it
- this.pair.on("secure", connectHandler(this));
- this.pair.cleartext.on("data", createDataHandler(this));
- // Add handlers
- this.connection.on("error", errorHandler(this));
- // this.connection.on("connect", connectHandler(this));
- this.connection.on("end", endHandler(this));
- this.connection.on("timeout", timeoutHandler(this));
- this.connection.on("drain", drainHandler(this));
- this.writeSteam.on("close", closeHandler(this));
- // Start socket
- this.connection.connect(this.socketOptions.port, this.socketOptions.host);
- } else {
- // Create new connection instance
- this.connection = net.createConnection(this.socketOptions.port, this.socketOptions.host);
- // Set options on the socket
- this.connection.setTimeout(this.socketOptions.connectTimeoutMS != null ? this.socketOptions.connectTimeoutMS : this.socketOptions.timeout);
- // Work around for 0.4.X
- if(process.version.indexOf("v0.4") == -1) this.connection.setNoDelay(this.socketOptions.noDelay);
- // Set keep alive if defined
- if(process.version.indexOf("v0.4") == -1) {
- if(this.socketOptions.keepAlive > 0) {
- this.connection.setKeepAlive(true, this.socketOptions.keepAlive);
- } else {
- this.connection.setKeepAlive(false);
- }
- }
-
- // Set up write stream
- this.writeSteam = this.connection;
- // Add handlers
- this.connection.on("error", errorHandler(this));
- // Add all handlers to the socket to manage it
- this.connection.on("connect", connectHandler(this));
- // this.connection.on("end", endHandler(this));
- this.connection.on("data", createDataHandler(this));
- this.connection.on("timeout", timeoutHandler(this));
- this.connection.on("drain", drainHandler(this));
- this.connection.on("close", closeHandler(this));
- }
-}
-
-// Check if the sockets are live
-Connection.prototype.isConnected = function() {
- return this.connected && !this.connection.destroyed && this.connection.writable && this.connection.readable;
-}
-
-// Write the data out to the socket
-Connection.prototype.write = function(command, callback) {
- try {
- // If we have a list off commands to be executed on the same socket
- if(Array.isArray(command)) {
- for(var i = 0; i < command.length; i++) {
- var binaryCommand = command[i].toBinary()
- if(!this.socketOptions['disableDriverBSONSizeCheck'] && binaryCommand.length > this.maxBsonSize) return callback(new Error("Document exceeds maximal allowed bson size of " + this.maxBsonSize + " bytes"));
- if(this.logger != null && this.logger.doDebug) this.logger.debug("writing command to mongodb", binaryCommand);
- var r = this.writeSteam.write(binaryCommand);
- }
- } else {
- var binaryCommand = command.toBinary()
- if(!this.socketOptions['disableDriverBSONSizeCheck'] && binaryCommand.length > this.maxBsonSize) return callback(new Error("Document exceeds maximal allowed bson size of " + this.maxBsonSize + " bytes"));
- if(this.logger != null && this.logger.doDebug) this.logger.debug("writing command to mongodb", binaryCommand);
- var r = this.writeSteam.write(binaryCommand);
- }
- } catch (err) {
- if(typeof callback === 'function') callback(err);
- }
-}
-
-// Force the closure of the connection
-Connection.prototype.close = function() {
- // clear out all the listeners
- resetHandlers(this, true);
- // Add a dummy error listener to catch any weird last moment errors (and ignore them)
- this.connection.on("error", function() {})
- // destroy connection
- this.connection.destroy();
-}
-
-// Reset all handlers
-var resetHandlers = function(self, clearListeners) {
- self.eventHandlers = {error:[], connect:[], close:[], end:[], timeout:[], parseError:[], message:[]};
-
- // If we want to clear all the listeners
- if(clearListeners && self.connection != null) {
- var keys = Object.keys(self.eventHandlers);
- // Remove all listeners
- for(var i = 0; i < keys.length; i++) {
- self.connection.removeAllListeners(keys[i]);
- }
- }
-}
-
-//
-// Handlers
-//
-
-// Connect handler
-var connectHandler = function(self) {
- return function() {
- // Set connected
- self.connected = true;
- // Now that we are connected set the socket timeout
- self.connection.setTimeout(self.socketOptions.socketTimeoutMS != null ? self.socketOptions.socketTimeoutMS : self.socketOptions.timeout);
- // Emit the connect event with no error
- self.emit("connect", null, self);
- }
-}
-
-var createDataHandler = exports.Connection.createDataHandler = function(self) {
- // We need to handle the parsing of the data
- // and emit the messages when there is a complete one
- return function(data) {
- // Parse until we are done with the data
- while(data.length > 0) {
- // If we still have bytes to read on the current message
- if(self.bytesRead > 0 && self.sizeOfMessage > 0) {
- // Calculate the amount of remaining bytes
- var remainingBytesToRead = self.sizeOfMessage - self.bytesRead;
- // Check if the current chunk contains the rest of the message
- if(remainingBytesToRead > data.length) {
- // Copy the new data into the exiting buffer (should have been allocated when we know the message size)
- data.copy(self.buffer, self.bytesRead);
- // Adjust the number of bytes read so it point to the correct index in the buffer
- self.bytesRead = self.bytesRead + data.length;
-
- // Reset state of buffer
- data = new Buffer(0);
- } else {
- // Copy the missing part of the data into our current buffer
- data.copy(self.buffer, self.bytesRead, 0, remainingBytesToRead);
- // Slice the overflow into a new buffer that we will then re-parse
- data = data.slice(remainingBytesToRead);
-
- // Emit current complete message
- try {
- var emitBuffer = self.buffer;
- // Reset state of buffer
- self.buffer = null;
- self.sizeOfMessage = 0;
- self.bytesRead = 0;
- self.stubBuffer = null;
- // Emit the buffer
- self.emit("message", emitBuffer, self);
- } catch(err) {
- var errorObject = {err:"socketHandler", trace:err, bin:buffer, parseState:{
- sizeOfMessage:self.sizeOfMessage,
- bytesRead:self.bytesRead,
- stubBuffer:self.stubBuffer}};
- if(self.logger != null && self.logger.doError) self.logger.error("parseError", errorObject);
- // We got a parse Error fire it off then keep going
- self.emit("parseError", errorObject, self);
- }
- }
- } else {
- // Stub buffer is kept in case we don't get enough bytes to determine the
- // size of the message (< 4 bytes)
- if(self.stubBuffer != null && self.stubBuffer.length > 0) {
-
- // If we have enough bytes to determine the message size let's do it
- if(self.stubBuffer.length + data.length > 4) {
- // Prepad the data
- var newData = new Buffer(self.stubBuffer.length + data.length);
- self.stubBuffer.copy(newData, 0);
- data.copy(newData, self.stubBuffer.length);
- // Reassign for parsing
- data = newData;
-
- // Reset state of buffer
- self.buffer = null;
- self.sizeOfMessage = 0;
- self.bytesRead = 0;
- self.stubBuffer = null;
-
- } else {
-
- // Add the the bytes to the stub buffer
- var newStubBuffer = new Buffer(self.stubBuffer.length + data.length);
- // Copy existing stub buffer
- self.stubBuffer.copy(newStubBuffer, 0);
- // Copy missing part of the data
- data.copy(newStubBuffer, self.stubBuffer.length);
- // Exit parsing loop
- data = new Buffer(0);
- }
- } else {
- if(data.length > 4) {
- // Retrieve the message size
- var sizeOfMessage = binaryutils.decodeUInt32(data, 0);
- // If we have a negative sizeOfMessage emit error and return
- if(sizeOfMessage < 0 || sizeOfMessage > self.maxBsonSize) {
- var errorObject = {err:"socketHandler", trace:'', bin:self.buffer, parseState:{
- sizeOfMessage: sizeOfMessage,
- bytesRead: self.bytesRead,
- stubBuffer: self.stubBuffer}};
- if(self.logger != null && self.logger.doError) self.logger.error("parseError", errorObject);
- // We got a parse Error fire it off then keep going
- self.emit("parseError", errorObject, self);
- return;
- }
-
- // Ensure that the size of message is larger than 0 and less than the max allowed
- if(sizeOfMessage > 4 && sizeOfMessage < self.maxBsonSize && sizeOfMessage > data.length) {
- self.buffer = new Buffer(sizeOfMessage);
- // Copy all the data into the buffer
- data.copy(self.buffer, 0);
- // Update bytes read
- self.bytesRead = data.length;
- // Update sizeOfMessage
- self.sizeOfMessage = sizeOfMessage;
- // Ensure stub buffer is null
- self.stubBuffer = null;
- // Exit parsing loop
- data = new Buffer(0);
-
- } else if(sizeOfMessage > 4 && sizeOfMessage < self.maxBsonSize && sizeOfMessage == data.length) {
- try {
- var emitBuffer = data;
- // Reset state of buffer
- self.buffer = null;
- self.sizeOfMessage = 0;
- self.bytesRead = 0;
- self.stubBuffer = null;
- // Exit parsing loop
- data = new Buffer(0);
- // Emit the message
- self.emit("message", emitBuffer, self);
- } catch (err) {
- var errorObject = {err:"socketHandler", trace:err, bin:self.buffer, parseState:{
- sizeOfMessage:self.sizeOfMessage,
- bytesRead:self.bytesRead,
- stubBuffer:self.stubBuffer}};
- if(self.logger != null && self.logger.doError) self.logger.error("parseError", errorObject);
- // We got a parse Error fire it off then keep going
- self.emit("parseError", errorObject, self);
- }
- } else if(sizeOfMessage <= 4 || sizeOfMessage > self.maxBsonSize) {
- var errorObject = {err:"socketHandler", trace:null, bin:data, parseState:{
- sizeOfMessage:sizeOfMessage,
- bytesRead:0,
- buffer:null,
- stubBuffer:null}};
- if(self.logger != null && self.logger.doError) self.logger.error("parseError", errorObject);
- // We got a parse Error fire it off then keep going
- self.emit("parseError", errorObject, self);
-
- // Clear out the state of the parser
- self.buffer = null;
- self.sizeOfMessage = 0;
- self.bytesRead = 0;
- self.stubBuffer = null;
- // Exit parsing loop
- data = new Buffer(0);
-
- } else {
- try {
- var emitBuffer = data.slice(0, sizeOfMessage);
- // Reset state of buffer
- self.buffer = null;
- self.sizeOfMessage = 0;
- self.bytesRead = 0;
- self.stubBuffer = null;
- // Copy rest of message
- data = data.slice(sizeOfMessage);
- // Emit the message
- self.emit("message", emitBuffer, self);
- } catch (err) {
- var errorObject = {err:"socketHandler", trace:err, bin:self.buffer, parseState:{
- sizeOfMessage:sizeOfMessage,
- bytesRead:self.bytesRead,
- stubBuffer:self.stubBuffer}};
- if(self.logger != null && self.logger.doError) self.logger.error("parseError", errorObject);
- // We got a parse Error fire it off then keep going
- self.emit("parseError", errorObject, self);
- }
-
- }
- } else {
- // Create a buffer that contains the space for the non-complete message
- self.stubBuffer = new Buffer(data.length)
- // Copy the data to the stub buffer
- data.copy(self.stubBuffer, 0);
- // Exit parsing loop
- data = new Buffer(0);
- }
- }
- }
- }
- }
-}
-
-var endHandler = function(self) {
- return function() {
- // Set connected to false
- self.connected = false;
- // Emit end event
- self.emit("end", {err: 'connection received Fin packet from [' + self.socketOptions.host + ':' + self.socketOptions.port + ']'}, self);
- }
-}
-
-var timeoutHandler = function(self) {
- return function() {
- self.emit("timeout", {err: 'connection to [' + self.socketOptions.host + ':' + self.socketOptions.port + '] timed out'}, self);
- }
-}
-
-var drainHandler = function(self) {
- return function() {
- }
-}
-
-var errorHandler = function(self) {
- return function(err) {
- // Set connected to false
- self.connected = false;
- // Emit error
- self.emit("error", {err: 'failed to connect to [' + self.socketOptions.host + ':' + self.socketOptions.port + ']'}, self);
- }
-}
-
-var closeHandler = function(self) {
- return function(hadError) {
- // If we have an error during the connection phase
- if(hadError && !self.connected) {
- // Set disconnected
- self.connected = false;
- // Emit error
- self.emit("error", {err: 'failed to connect to [' + self.socketOptions.host + ':' + self.socketOptions.port + ']'}, self);
- } else {
- // Set disconnected
- self.connected = false;
- // Emit close
- self.emit("close", {err: 'connection closed to [' + self.socketOptions.host + ':' + self.socketOptions.port + ']'}, self);
- }
- }
-}
-
-// Some basic defaults
-Connection.DEFAULT_PORT = 27017;
-
-
-
-
-
-
-
diff --git a/CoAuthoring/node_modules/mongodb/lib/mongodb/connection/connection_pool.js b/CoAuthoring/node_modules/mongodb/lib/mongodb/connection/connection_pool.js
deleted file mode 100644
index 61f53d7860..0000000000
--- a/CoAuthoring/node_modules/mongodb/lib/mongodb/connection/connection_pool.js
+++ /dev/null
@@ -1,239 +0,0 @@
-var utils = require('./connection_utils'),
- inherits = require('util').inherits,
- net = require('net'),
- EventEmitter = require('events').EventEmitter,
- inherits = require('util').inherits,
- MongoReply = require("../responses/mongo_reply").MongoReply,
- Connection = require("./connection").Connection;
-
-var ConnectionPool = exports.ConnectionPool = function(host, port, poolSize, bson, socketOptions) {
- if(typeof host !== 'string' || typeof port !== 'number') throw "host and port must be specified [" + host + ":" + port + "]";
- // Set up event emitter
- EventEmitter.call(this);
- // Keep all options for the socket in a specific collection allowing the user to specify the
- // Wished upon socket connection parameters
- this.socketOptions = typeof socketOptions === 'object' ? socketOptions : {};
- this.socketOptions.host = host;
- this.socketOptions.port = port;
- this.bson = bson;
- // PoolSize is always + 1 for special reserved "measurment" socket (like ping, stats etc)
- this.poolSize = poolSize;
- this.minPoolSize = Math.floor(this.poolSize / 2) + 1;
-
- // Set default settings for the socket options
- utils.setIntegerParameter(this.socketOptions, 'timeout', 0);
- // Delay before writing out the data to the server
- utils.setBooleanParameter(this.socketOptions, 'noDelay', true);
- // Delay before writing out the data to the server
- utils.setIntegerParameter(this.socketOptions, 'keepAlive', 0);
- // Set the encoding of the data read, default is binary == null
- utils.setStringParameter(this.socketOptions, 'encoding', null);
- // Allows you to set a throttling bufferSize if you need to stop overflows
- utils.setIntegerParameter(this.socketOptions, 'bufferSize', 0);
-
- // Internal structures
- this.openConnections = [];
- // Assign connection id's
- this.connectionId = 0;
-
- // Current index for selection of pool connection
- this.currentConnectionIndex = 0;
- // The pool state
- this._poolState = 'disconnected';
- // timeout control
- this._timeout = false;
-}
-
-inherits(ConnectionPool, EventEmitter);
-
-ConnectionPool.prototype.setMaxBsonSize = function(maxBsonSize) {
- if(maxBsonSize == null){
- maxBsonSize = Connection.DEFAULT_MAX_BSON_SIZE;
- }
-
- for(var i = 0; i < this.openConnections.length; i++) {
- this.openConnections[i].maxBsonSize = maxBsonSize;
- }
-}
-
-// Start a function
-var _connect = function(_self) {
- return new function() {
- // Create a new connection instance
- var connection = new Connection(_self.connectionId++, _self.socketOptions);
- // Set logger on pool
- connection.logger = _self.logger;
- // Connect handler
- connection.on("connect", function(err, connection) {
- // Add connection to list of open connections
- _self.openConnections.push(connection);
- // If the number of open connections is equal to the poolSize signal ready pool
- if(_self.openConnections.length === _self.poolSize && _self._poolState !== 'disconnected') {
- // Set connected
- _self._poolState = 'connected';
- // Emit pool ready
- _self.emit("poolReady");
- } else if(_self.openConnections.length < _self.poolSize) {
- // We need to open another connection, make sure it's in the next
- // tick so we don't get a cascade of errors
- process.nextTick(function() {
- _connect(_self);
- });
- }
- });
-
- var numberOfErrors = 0
-
- // Error handler
- connection.on("error", function(err, connection) {
- numberOfErrors++;
- // If we are already disconnected ignore the event
- if(_self._poolState != 'disconnected' && _self.listeners("error").length > 0) {
- _self.emit("error", err);
- }
-
- // Set disconnected
- _self._poolState = 'disconnected';
- // Stop
- _self.stop();
- });
-
- // Close handler
- connection.on("close", function() {
- // If we are already disconnected ignore the event
- if(_self._poolState !== 'disconnected' && _self.listeners("close").length > 0) {
- _self.emit("close");
- }
- // Set disconnected
- _self._poolState = 'disconnected';
- // Stop
- _self.stop();
- });
-
- // Timeout handler
- connection.on("timeout", function(err, connection) {
- // If we are already disconnected ignore the event
- if(_self._poolState !== 'disconnected' && _self.listeners("timeout").length > 0) {
- _self.emit("timeout", err);
- }
- // Set disconnected
- _self._poolState = 'disconnected';
- // Stop
- _self.stop();
- });
-
- // Parse error, needs a complete shutdown of the pool
- connection.on("parseError", function() {
- // If we are already disconnected ignore the event
- if(_self._poolState !== 'disconnected' && _self.listeners("parseError").length > 0) {
- _self.emit("parseError", new Error("parseError occured"));
- }
-
- _self.stop();
- });
-
- connection.on("message", function(message) {
- _self.emit("message", message);
- });
-
- // Start connection in the next tick
- connection.start();
- }();
-}
-
-
-// Start method, will throw error if no listeners are available
-// Pass in an instance of the listener that contains the api for
-// finding callbacks for a given message etc.
-ConnectionPool.prototype.start = function() {
- var markerDate = new Date().getTime();
- var self = this;
-
- if(this.listeners("poolReady").length == 0) {
- throw "pool must have at least one listener ready that responds to the [poolReady] event";
- }
-
- // Set pool state to connecting
- this._poolState = 'connecting';
- this._timeout = false;
-
- _connect(self);
-}
-
-// Restart a connection pool (on a close the pool might be in a wrong state)
-ConnectionPool.prototype.restart = function() {
- // Close all connections
- this.stop(false);
- // Now restart the pool
- this.start();
-}
-
-// Stop the connections in the pool
-ConnectionPool.prototype.stop = function(removeListeners) {
- removeListeners = removeListeners == null ? true : removeListeners;
- // Set disconnected
- this._poolState = 'disconnected';
-
- // Clear all listeners if specified
- if(removeListeners) {
- this.removeAllEventListeners();
- }
-
- // Close all connections
- for(var i = 0; i < this.openConnections.length; i++) {
- this.openConnections[i].close();
- }
-
- // Clean up
- this.openConnections = [];
-}
-
-// Check the status of the connection
-ConnectionPool.prototype.isConnected = function() {
- return this._poolState === 'connected';
-}
-
-// Checkout a connection from the pool for usage, or grab a specific pool instance
-ConnectionPool.prototype.checkoutConnection = function(id) {
- var index = (this.currentConnectionIndex++ % (this.openConnections.length));
- var connection = this.openConnections[index];
- return connection;
-}
-
-ConnectionPool.prototype.getAllConnections = function() {
- return this.openConnections;
-}
-
-// Remove all non-needed event listeners
-ConnectionPool.prototype.removeAllEventListeners = function() {
- this.removeAllListeners("close");
- this.removeAllListeners("error");
- this.removeAllListeners("timeout");
- this.removeAllListeners("connect");
- this.removeAllListeners("end");
- this.removeAllListeners("parseError");
- this.removeAllListeners("message");
- this.removeAllListeners("poolReady");
-}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/CoAuthoring/node_modules/mongodb/lib/mongodb/connection/connection_utils.js b/CoAuthoring/node_modules/mongodb/lib/mongodb/connection/connection_utils.js
deleted file mode 100644
index 591092495a..0000000000
--- a/CoAuthoring/node_modules/mongodb/lib/mongodb/connection/connection_utils.js
+++ /dev/null
@@ -1,23 +0,0 @@
-exports.setIntegerParameter = function(object, field, defaultValue) {
- if(object[field] == null) {
- object[field] = defaultValue;
- } else if(typeof object[field] !== "number" && object[field] !== parseInt(object[field], 10)) {
- throw "object field [" + field + "] must be a numeric integer value, attempted to set to [" + object[field] + "] type of [" + typeof object[field] + "]";
- }
-}
-
-exports.setBooleanParameter = function(object, field, defaultValue) {
- if(object[field] == null) {
- object[field] = defaultValue;
- } else if(typeof object[field] !== "boolean") {
- throw "object field [" + field + "] must be a boolean value, attempted to set to [" + object[field] + "] type of [" + typeof object[field] + "]";
- }
-}
-
-exports.setStringParameter = function(object, field, defaultValue) {
- if(object[field] == null) {
- object[field] = defaultValue;
- } else if(typeof object[field] !== "string") {
- throw "object field [" + field + "] must be a string value, attempted to set to [" + object[field] + "] type of [" + typeof object[field] + "]";
- }
-}
\ No newline at end of file
diff --git a/CoAuthoring/node_modules/mongodb/lib/mongodb/connection/mongos.js b/CoAuthoring/node_modules/mongodb/lib/mongodb/connection/mongos.js
deleted file mode 100644
index 9d0b49c9cf..0000000000
--- a/CoAuthoring/node_modules/mongodb/lib/mongodb/connection/mongos.js
+++ /dev/null
@@ -1,316 +0,0 @@
-var ReadPreference = require('./read_preference').ReadPreference;
-
-/**
- * Mongos constructor provides a connection to a mongos proxy including failover to additional servers
- *
- * Options
- * - **socketOptions** {Object, default:null}, an object containing socket options to use (noDelay:(boolean), keepAlive:(number), connectTimeoutMS:(number), socketTimeoutMS:(number))
- * - **ha** {Boolean, default:true}, turn on high availability, attempts to reconnect to down proxies
- * - **haInterval** {Number, default:2000}, time between each replicaset status check.
- *
- * @class Represents a Mongos connection with failover to backup proxies
- * @param {Array} list of mongos server objects
- * @param {Object} [options] additional options for the mongos connection
- */
-var Mongos = function Mongos(servers, options) {
- // Set up basic
- if(!(this instanceof Mongos))
- return new Mongos(servers, options);
-
- // Throw error on wrong setup
- if(servers == null || !Array.isArray(servers) || servers.length == 0)
- throw new Error("At least one mongos proxy must be in the array");
-
- // Ensure we have at least an empty options object
- this.options = options == null ? {} : options;
- // Set default connection pool options
- this.socketOptions = this.options.socketOptions != null ? this.options.socketOptions : {};
- // Enabled ha
- this.haEnabled = this.options['ha'] == null ? true : this.options['ha'];
- // How often are we checking for new servers in the replicaset
- this.mongosStatusCheckInterval = this.options['haInterval'] == null ? 2000 : this.options['haInterval'];
- // Save all the server connections
- this.servers = servers;
- // Servers we need to attempt reconnect with
- this.downServers = [];
- // Just contains the current lowest ping time and server
- this.lowestPingTimeServer = null;
- this.lowestPingTime = 0;
-
- // Add options to servers
- for(var i = 0; i < this.servers.length; i++) {
- var server = this.servers[i];
- // Default empty socket options object
- var socketOptions = {host: server.host, port: server.port};
- // If a socket option object exists clone it
- if(this.socketOptions != null) {
- var keys = Object.keys(this.socketOptions);
- for(var k = 0; k < keys.length;k++) socketOptions[keys[i]] = this.socketOptions[keys[i]];
- }
- // Set socket options
- server.socketOptions = socketOptions;
- }
-}
-
-/**
- * @ignore
- */
-Mongos.prototype.isMongos = function() {
- return true;
-}
-
-/**
- * @ignore
- */
-Mongos.prototype.connect = function(db, options, callback) {
- if('function' === typeof options) callback = options, options = {};
- if(options == null) options = {};
- if(!('function' === typeof callback)) callback = null;
- var self = this;
-
- // Keep reference to parent
- this.db = db;
- // Set server state to connecting
- this._serverState = 'connecting';
- // Number of total servers that need to initialized (known servers)
- this._numberOfServersLeftToInitialize = this.servers.length;
- // Default to the first proxy server as the first one to use
- this._currentMongos = this.servers[0];
-
- // Connect handler
- var connectHandler = function(_server) {
- return function(err, result) {
- self._numberOfServersLeftToInitialize = self._numberOfServersLeftToInitialize - 1;
-
- if(self._numberOfServersLeftToInitialize == 0) {
- // Start ha function if it exists
- if(self.haEnabled) {
- // Setup the ha process
- self._replicasetTimeoutId = setTimeout(self.mongosCheckFunction, self.mongosStatusCheckInterval);
- }
-
- // Set the mongos to connected
- self._serverState = "connected";
- // Emit the open event
- self.db.emit("open", null, self.db);
- // Callback
- callback(null, self.db);
- }
- }
- };
-
- // Error handler
- var errorOrCloseHandler = function(_server) {
- return function(err, result) {
- // Create current mongos comparision
- var currentUrl = self._currentMongos.host + ":" + self._currentMongos.port;
- var serverUrl = this.host + ":" + this.port;
- // We need to check if the server that closed is the actual current proxy we are using, otherwise
- // just ignore
- if(currentUrl == serverUrl) {
- // Remove the server from the list
- if(self.servers.indexOf(_server) != -1) {
- self.servers.splice(self.servers.indexOf(_server), 1);
- }
-
- // Pick the next one on the list if there is one
- for(var i = 0; i < self.servers.length; i++) {
- // Grab the server out of the array (making sure there is no servers in the list if none available)
- var server = self.servers[i];
- // Generate url for comparision
- var serverUrl = server.host + ":" + server.port;
- // It's not the current one and connected set it as the current db
- if(currentUrl != serverUrl && server.isConnected()) {
- self._currentMongos = server;
- break;
- }
- }
- }
-
- // Ensure we don't store the _server twice
- if(self.downServers.indexOf(_server) == -1) {
- // Add the server instances
- self.downServers.push(_server);
- }
- }
- }
-
- // Mongo function
- this.mongosCheckFunction = function() {
- // If we have down servers let's attempt a reconnect
- if(self.downServers.length > 0) {
- var numberOfServersLeft = self.downServers.length;
- // Attempt to reconnect
- for(var i = 0; i < self.downServers.length; i++) {
- var downServer = self.downServers.pop();
- // Attemp to reconnect
- downServer.connect(self.db, {returnIsMasterResults: true}, function(_server) {
- // Return a function to check for the values
- return function(err, result) {
- // Adjust the number of servers left
- numberOfServersLeft = numberOfServersLeft - 1;
-
- if(err != null) {
- self.downServers.push(_server);
- } else {
- // Add server event handlers
- _server.on("close", errorOrCloseHandler(_server));
- _server.on("error", errorOrCloseHandler(_server));
- // Add to list of servers
- self.servers.push(_server);
- }
-
- if(numberOfServersLeft <= 0) {
- // Perfom another ha
- self._replicasetTimeoutId = setTimeout(self.mongosCheckFunction, self.mongosStatusCheckInterval);
- }
- }
- }(downServer));
- }
- } else if(self.servers.length > 0) {
- var numberOfServersLeft = self.servers.length;
- var _s = new Date().getTime()
-
- // Else let's perform a ping command
- for(var i = 0; i < self.servers.length; i++) {
- var executePing = function(_server) {
- // Get a read connection
- var _connection = _server.checkoutReader();
- // Execute ping command
- self.db.command({ping:1}, {connection:_connection}, function(err, result) {
- var pingTime = new Date().getTime() - _s;
- // If no server set set the first one, otherwise check
- // the lowest ping time and assign the server if it's got a lower ping time
- if(self.lowestPingTimeServer == null) {
- self.lowestPingTimeServer = _server;
- self.lowestPingTime = pingTime;
- self._currentMongos = _server;
- } else if(self.lowestPingTime > pingTime
- && (_server.host != self.lowestPingTimeServer.host || _server.port != self.lowestPingTimeServer.port)) {
- self.lowestPingTimeServer = _server;
- self.lowestPingTime = pingTime;
- self._currentMongos = _server;
- }
-
- // Number of servers left
- numberOfServersLeft = numberOfServersLeft - 1;
- // All active mongos's pinged
- if(numberOfServersLeft == 0) {
- // Perfom another ha
- self._replicasetTimeoutId = setTimeout(self.mongosCheckFunction, self.mongosStatusCheckInterval);
- }
- })
- }
- // Execute the function
- executePing(self.servers[i]);
- }
- } else {
- self._replicasetTimeoutId = setTimeout(self.mongosCheckFunction, self.mongosStatusCheckInterval);
- }
- }
-
- // Connect all the server instances
- for(var i = 0; i < this.servers.length; i++) {
- // Get the connection
- var server = this.servers[i];
- server.mongosInstance = this;
- // Add server event handlers
- server.on("close", errorOrCloseHandler(server));
- server.on("error", errorOrCloseHandler(server));
- // Connect the instance
- server.connect(self.db, {returnIsMasterResults: true}, connectHandler(server));
- }
-}
-
-/**
- * @ignore
- * Just return the currently picked active connection
- */
-Mongos.prototype.allServerInstances = function() {
- return this.servers;
-}
-
-/**
- * @ignore
- */
-Mongos.prototype.allRawConnections = function() {
- // Neeed to build a complete list of all raw connections, start with master server
- var allConnections = [];
- // Add all connections
- for(var i = 0; i < this.servers.length; i++) {
- allConnections = allConnections.concat(this.servers[i].allRawConnections)
- }
-
- // Return all the conections
- return allConnections;
-}
-
-/**
- * @ignore
- */
-Mongos.prototype.isConnected = function() {
- return this._serverState == "connected";
-}
-
-/**
- * @ignore
- */
-Mongos.prototype.checkoutWriter = function() {
- // No current mongo, just pick first server
- if(this._currentMongos == null && this.servers.length > 0) {
- return this.servers[0].checkoutWriter();
- }
- return this._currentMongos.checkoutWriter();
-}
-
-/**
- * @ignore
- */
-Mongos.prototype.checkoutReader = function(read) {
- // If we have a read preference object unpack it
- if(typeof read == 'object' && read['_type'] == 'ReadPreference') {
- // Validate if the object is using a valid mode
- if(!read.isValid()) throw new Error("Illegal readPreference mode specified, " + read.mode);
- } else if(!ReadPreference.isValid(read)) {
- throw new Error("Illegal readPreference mode specified, " + read);
- }
-
- // No current mongo, just pick first server
- if(this._currentMongos == null && this.servers.length > 0) {
- return this.servers[0].checkoutReader();
- }
- return this._currentMongos.checkoutReader();
-}
-
-/**
- * @ignore
- */
-Mongos.prototype.close = function(callback) {
- var self = this;
- // Set server status as disconnected
- this._serverState = 'disconnected';
- // Number of connections to close
- var numberOfConnectionsToClose = self.servers.length;
- // If we have a ha process running kill it
- if(self._replicasetTimeoutId != null) clearTimeout(self._replicasetTimeoutId);
- // Close all proxy connections
- for(var i = 0; i < self.servers.length; i++) {
- self.servers[i].close(function(err, result) {
- numberOfConnectionsToClose = numberOfConnectionsToClose - 1;
- // Callback if we have one defined
- if(numberOfConnectionsToClose == 0 && typeof callback == 'function') {
- callback(null);
- }
- });
- }
-}
-
-/**
- * @ignore
- * Return the used state
- */
-Mongos.prototype._isUsed = function() {
- return this._used;
-}
-
-exports.Mongos = Mongos;
\ No newline at end of file
diff --git a/CoAuthoring/node_modules/mongodb/lib/mongodb/connection/read_preference.js b/CoAuthoring/node_modules/mongodb/lib/mongodb/connection/read_preference.js
deleted file mode 100644
index 4cba58792b..0000000000
--- a/CoAuthoring/node_modules/mongodb/lib/mongodb/connection/read_preference.js
+++ /dev/null
@@ -1,66 +0,0 @@
-/**
- * A class representation of the Read Preference.
- *
- * Read Preferences
- * - **ReadPreference.PRIMARY**, Read from primary only. All operations produce an error (throw an exception where applicable) if primary is unavailable. Cannot be combined with tags (This is the default.).
- * - **ReadPreference.PRIMARY_PREFERRED**, Read from primary if available, otherwise a secondary.
- * - **ReadPreference.SECONDARY**, Read from secondary if available, otherwise error.
- * - **ReadPreference.SECONDARY_PREFERRED**, Read from a secondary if available, otherwise read from the primary.
- * - **ReadPreference.NEAREST**, All modes read from among the nearest candidates, but unlike other modes, NEAREST will include both the primary and all secondaries in the random selection.
- *
- * @class Represents a Read Preference.
- * @param {String} the read preference type
- * @param {Object} tags
- * @return {ReadPreference}
- */
-var ReadPreference = function(mode, tags) {
- if(!(this instanceof ReadPreference))
- return new ReadPreference(mode, tags);
- this._type = 'ReadPreference';
- this.mode = mode;
- this.tags = tags;
-}
-
-/**
- * @ignore
- */
-ReadPreference.isValid = function(_mode) {
- return (_mode == ReadPreference.PRIMARY || _mode == ReadPreference.PRIMARY_PREFERRED
- || _mode == ReadPreference.SECONDARY || _mode == ReadPreference.SECONDARY_PREFERRED
- || _mode == ReadPreference.NEAREST);
-}
-
-/**
- * @ignore
- */
-ReadPreference.prototype.isValid = function(mode) {
- var _mode = typeof mode == 'string' ? mode : this.mode;
- return ReadPreference.isValid(_mode);
-}
-
-/**
- * @ignore
- */
-ReadPreference.prototype.toObject = function() {
- var object = {mode:this.mode};
-
- if(this.tags != null) {
- object['tags'] = this.tags;
- }
-
- return object;
-}
-
-/**
- * @ignore
- */
-ReadPreference.PRIMARY = 'primary';
-ReadPreference.PRIMARY_PREFERRED = 'primaryPreferred';
-ReadPreference.SECONDARY = 'secondary';
-ReadPreference.SECONDARY_PREFERRED = 'secondaryPreferred';
-ReadPreference.NEAREST = 'nearest'
-
-/**
- * @ignore
- */
-exports.ReadPreference = ReadPreference;
\ No newline at end of file
diff --git a/CoAuthoring/node_modules/mongodb/lib/mongodb/connection/repl_set.js b/CoAuthoring/node_modules/mongodb/lib/mongodb/connection/repl_set.js
deleted file mode 100644
index d44d9fe84a..0000000000
--- a/CoAuthoring/node_modules/mongodb/lib/mongodb/connection/repl_set.js
+++ /dev/null
@@ -1,1092 +0,0 @@
-var Connection = require('./connection').Connection,
- ReadPreference = require('./read_preference').ReadPreference,
- DbCommand = require('../commands/db_command').DbCommand,
- MongoReply = require('../responses/mongo_reply').MongoReply,
- debug = require('util').debug,
- EventEmitter = require('events').EventEmitter,
- inherits = require('util').inherits,
- inspect = require('util').inspect,
- Server = require('./server').Server,
- PingStrategy = require('./strategies/ping_strategy').PingStrategy,
- StatisticsStrategy = require('./strategies/statistics_strategy').StatisticsStrategy;
-
-const STATE_STARTING_PHASE_1 = 0;
-const STATE_PRIMARY = 1;
-const STATE_SECONDARY = 2;
-const STATE_RECOVERING = 3;
-const STATE_FATAL_ERROR = 4;
-const STATE_STARTING_PHASE_2 = 5;
-const STATE_UNKNOWN = 6;
-const STATE_ARBITER = 7;
-const STATE_DOWN = 8;
-const STATE_ROLLBACK = 9;
-
-/**
- * ReplSet constructor provides replicaset functionality
- *
- * Options
- * - **ha** {Boolean, default:true}, turn on high availability.
- * - **haInterval** {Number, default:2000}, time between each replicaset status check.
- * - **reconnectWait** {Number, default:1000}, time to wait in miliseconds before attempting reconnect.
- * - **retries** {Number, default:30}, number of times to attempt a replicaset reconnect.
- * - **rs_name** {String}, the name of the replicaset to connect to.
- * - **socketOptions** {Object, default:null}, an object containing socket options to use (noDelay:(boolean), keepAlive:(number), connectTimeoutMS:(number), socketTimeoutMS:(number))
- * - **readPreference** {String}, the prefered read preference (ReadPreference.PRIMARY, ReadPreference.PRIMARY_PREFERRED, ReadPreference.SECONDARY, ReadPreference.SECONDARY_PREFERRED, ReadPreference.NEAREST).
- * - **strategy** {String, default:null}, selection strategy for reads choose between (ping and statistical, default is round-robin)
- * - **secondaryAcceptableLatencyMS** {Number, default:15}, sets the range of servers to pick when using NEAREST (lowest ping ms + the latency fence, ex: range of 1 to (1 + 15) ms)
- * - **connectArbiter** {Boolean, default:false}, sets if the driver should connect to arbiters or not.
- *
- * @class Represents a Replicaset Configuration
- * @param {Array} list of server objects participating in the replicaset.
- * @param {Object} [options] additional options for the replicaset connection.
- */
-var ReplSet = exports.ReplSet = function(servers, options) {
- this.count = 0;
-
- // Set up basic
- if(!(this instanceof ReplSet))
- return new ReplSet(servers, options);
-
- // Set up event emitter
- EventEmitter.call(this);
-
- // Ensure no Mongos's
- for(var i = 0; i < servers.length; i++) {
- if(!(servers[i] instanceof Server)) throw new Error("list of servers must be of type Server");
- }
-
- // Just reference for simplicity
- var self = this;
- // Contains the master server entry
- this.options = options == null ? {} : options;
- this.reconnectWait = this.options["reconnectWait"] != null ? this.options["reconnectWait"] : 1000;
- this.retries = this.options["retries"] != null ? this.options["retries"] : 30;
- this.replicaSet = this.options["rs_name"];
-
- // Are we allowing reads from secondaries ?
- this.readSecondary = this.options["read_secondary"];
- this.slaveOk = true;
- this.closedConnectionCount = 0;
- this._used = false;
-
- // Connect arbiters ?
- this.connectArbiter = this.options.connectArbiter == null ? false : this.options.connectArbiter;
-
- // Default poolSize for new server instances
- this.poolSize = this.options.poolSize == null ? 5 : this.options.poolSize;
- this._currentServerChoice = 0;
-
- // Set up ssl connections
- this.ssl = this.options.ssl == null ? false : this.options.ssl;
-
- // Just keeps list of events we allow
- this.eventHandlers = {error:[], parseError:[], poolReady:[], message:[], close:[], timeout:[]};
- // Internal state of server connection
- this._serverState = 'disconnected';
- // Read preference
- this._readPreference = null;
- // Number of initalized severs
- this._numberOfServersLeftToInitialize = 0;
- // Do we record server stats or not
- this.recordQueryStats = false;
-
- // Get the readPreference
- var readPreference = this.options['readPreference'];
-
- // Validate correctness of Read preferences
- if(readPreference != null) {
- if(readPreference != ReadPreference.PRIMARY && readPreference != ReadPreference.PRIMARY_PREFERRED
- && readPreference != ReadPreference.SECONDARY && readPreference != ReadPreference.SECONDARY_PREFERRED
- && readPreference != ReadPreference.NEAREST && typeof readPreference != 'object' && readPreference['_type'] != 'ReadPreference') {
- throw new Error("Illegal readPreference mode specified, " + readPreference);
- }
-
- this._readPreference = readPreference;
- } else {
- this._readPreference = null;
- }
-
- // Strategy for picking a secondary
- this.secondaryAcceptableLatencyMS = this.options['secondaryAcceptableLatencyMS'] == null ? 15 : this.options['secondaryAcceptableLatencyMS'];
- this.strategy = this.options['strategy'];
- // Make sure strategy is one of the two allowed
- if(this.strategy != null && (this.strategy != 'ping' && this.strategy != 'statistical')) throw new Error("Only ping or statistical strategies allowed");
- // Let's set up our strategy object for picking secodaries
- if(this.strategy == 'ping') {
- // Create a new instance
- this.strategyInstance = new PingStrategy(this, this.secondaryAcceptableLatencyMS);
- } else if(this.strategy == 'statistical') {
- // Set strategy as statistical
- this.strategyInstance = new StatisticsStrategy(this);
- // Add enable query information
- this.enableRecordQueryStats(true);
- }
-
- // Set default connection pool options
- this.socketOptions = this.options.socketOptions != null ? this.options.socketOptions : {};
-
- // Set up logger if any set
- this.logger = this.options.logger != null
- && (typeof this.options.logger.debug == 'function')
- && (typeof this.options.logger.error == 'function')
- && (typeof this.options.logger.debug == 'function')
- ? this.options.logger : {error:function(message, object) {}, log:function(message, object) {}, debug:function(message, object) {}};
-
- // Ensure all the instances are of type server and auto_reconnect is false
- if(!Array.isArray(servers) || servers.length == 0) {
- throw Error("The parameter must be an array of servers and contain at least one server");
- } else if(Array.isArray(servers) || servers.length > 0) {
- var count = 0;
- servers.forEach(function(server) {
- if(server instanceof Server) count = count + 1;
- // Ensure no server has reconnect on
- server.options.auto_reconnect = false;
- });
-
- if(count < servers.length) {
- throw Error("All server entries must be of type Server");
- } else {
- this.servers = servers;
- }
- }
-
- // var deduplicate list
- var uniqueServers = {};
- // De-duplicate any servers in the seed list
- for(var i = 0; i < this.servers.length; i++) {
- var server = this.servers[i];
- // If server does not exist set it
- if(uniqueServers[server.host + ":" + server.port] == null) {
- uniqueServers[server.host + ":" + server.port] = server;
- }
- }
-
- // Let's set the deduplicated list of servers
- this.servers = [];
- // Add the servers
- for(var key in uniqueServers) {
- this.servers.push(uniqueServers[key]);
- }
-
- // Enabled ha
- this.haEnabled = this.options['ha'] == null ? true : this.options['ha'];
- // How often are we checking for new servers in the replicaset
- this.replicasetStatusCheckInterval = this.options['haInterval'] == null ? 1000 : this.options['haInterval'];
- this._replicasetTimeoutId = null;
- // Connection timeout
- this._connectTimeoutMS = 1000;
- // Current list of servers to test
- this.pingCandidateServers = [];
-
- // Last replicaset check time
- this.lastReplicaSetTime = new Date().getTime();
-};
-
-/**
- * @ignore
- */
-inherits(ReplSet, EventEmitter);
-
-/**
- * @ignore
- */
-// Allow setting the read preference at the replicaset level
-ReplSet.prototype.setReadPreference = function(preference) {
- // Set read preference
- this._readPreference = preference;
- // Ensure slaveOk is correct for secodnaries read preference and tags
- if((this._readPreference == ReadPreference.SECONDARY_PREFERRED || this._readPreference == ReadPreference.SECONDARY)
- || (this._readPreference != null && typeof this._readPreference == 'object')) {
- this.slaveOk = true;
- }
-}
-
-/**
- * @ignore
- */
-ReplSet.prototype._isUsed = function() {
- return this._used;
-}
-
-/**
- * @ignore
- */
-ReplSet.prototype.isMongos = function() {
- return false;
-}
-
-/**
- * @ignore
- */
-ReplSet.prototype.isConnected = function() {
- return this.primary != null && this._state.master != null && this._state.master.isConnected();
-}
-
-/**
- * @ignore
- */
-ReplSet.prototype.isSetMember = function() {
- return false;
-}
-
-/**
- * @ignore
- */
-ReplSet.prototype.isPrimary = function(config) {
- return this.readSecondary && Object.keys(this._state.secondaries).length > 0 ? false : true;
-}
-
-/**
- * @ignore
- */
-ReplSet.prototype.isReadPrimary = ReplSet.prototype.isPrimary;
-
-/**
- * @ignore
- **/
-ReplSet.prototype._checkReplicaSet = function() {
- if(!this.haEnabled) return false;
- var currentTime = new Date().getTime();
- if((currentTime - this.lastReplicaSetTime) >= this.replicasetStatusCheckInterval) {
- this.lastReplicaSetTime = currentTime;
- return true;
- } else {
- return false;
- }
-}
-
-/**
- * @ignore
- */
-ReplSet.prototype.allServerInstances = function() {
- var self = this;
- // Close all the servers (concatenate entire list of servers first for ease)
- var allServers = self._state.master != null ? [self._state.master] : [];
-
- // Secondary keys
- var keys = Object.keys(self._state.secondaries);
- // Add all secondaries
- for(var i = 0; i < keys.length; i++) {
- allServers.push(self._state.secondaries[keys[i]]);
- }
-
- // Arbiter keys
- var keys = Object.keys(self._state.arbiters);
- // Add all arbiters
- for(var i = 0; i < keys.length; i++) {
- allServers.push(self._state.arbiters[keys[i]]);
- }
-
- // Passive keys
- var keys = Object.keys(self._state.passives);
- // Add all arbiters
- for(var i = 0; i < keys.length; i++) {
- allServers.push(self._state.passives[keys[i]]);
- }
-
- // Return complete list of all servers
- return allServers;
-}
-
-/**
- * @ignore
- */
-var __executeAllCallbacksWithError = function(dbInstance, error) {
- var keys = Object.keys(dbInstance._callBackStore._notReplied);
- // Iterate over all callbacks
- for(var i = 0; i < keys.length; i++) {
- // Delete info object
- delete dbInstance._callBackStore._notReplied[keys[i]];
- // Emit the error
- dbInstance._callBackStore.emit(keys[i], error);
- }
-}
-
-/**
- * @ignore
- */
-ReplSet.prototype._validateReplicaset = function(result, auths) {
- var self = this;
- // For each member we need to check if we have a new connection that needs to be established
- var members = result['documents'][0]['members'];
- // Get members
- var members = Array.isArray(result['documents'][0]['members']) ? result['documents'][0]['members'] : [];
- // The total members we check
- var serversToConnectList = {};
-
- // Iterate over all the members and see if we need to reconnect
- for(var i = 0, jlen = members.length; i < jlen; i++) {
- var member = members[i];
-
- if(member['health'] != 0
- && null == self._state['addresses'][member['name']]
- && null == serversToConnectList[member['name']]) {
- if (member['stateStr'] == 'ARBITER' && self.connectArbiter != true) {
- continue;
- }
- // Split the server string
- var parts = member.name.split(/:/);
- if(parts.length == 1) {
- parts = [parts[0], Connection.DEFAULT_PORT];
- }
-
- // Default empty socket options object
- var socketOptions = {host:parts[0], port:parseInt(parts[1], 10)};
- // If a socket option object exists clone it
- if(self.socketOptions != null) {
- var keys = Object.keys(self.socketOptions);
- for(var k = 0; k < keys.length;k++) socketOptions[keys[i]] = self.socketOptions[keys[i]];
- }
-
- // Create a new server instance
- var newServer = new Server(parts[0], parseInt(parts[1], 10), {auto_reconnect:false, 'socketOptions':socketOptions
- , logger:self.logger, ssl:self.ssl, poolSize:self.poolSize});
- // Set the replicaset instance
- newServer.replicasetInstance = self;
-
- // Add handlers
- newServer.on("close", _handler("close", self));
- newServer.on("error", _handler("error", self));
- newServer.on("timeout", _handler("timeout", self));
- // Add to list of server connection target
- serversToConnectList[member['name']] = newServer;
- } else if(member['stateStr'] == 'PRIMARY' && self._state.master['name'] != member['name']) {
- // Delete master record so we can rediscover it
- delete self._state['addresses'][self._state.master['name']];
- // Update inormation on new primary
- var newMaster = self._state.addresses[member['name']];
- newMaster.isMasterDoc.ismaster = true;
- newMaster.isMasterDoc.secondary = false;
- self._state.master = newMaster;
- // Remove from secondaries
- delete self._state.secondaries[member['name']];
- newMaster = null;
- }
- }
-
- // All servers we want to connect to
- var serverKeys = Object.keys(serversToConnectList);
- // For all remaining servers on the list connect
- while(serverKeys.length > 0) {
- var _serverKey = serverKeys.pop();
- // Fetch the server
- var _server = serversToConnectList[_serverKey];
- // Add a new server to the total number of servers that need to initialized before we are done
- //var newServerCallback = self.connectionHandler(_server);
- var newServerCallback = _connectHandler(self, null, _server)
- // Connect To the new server
- _server.connect(self.db, {returnIsMasterResults: true, eventReceiver:newServer}, function(err, result, _server) {
- if(err == null && result != null) {
- // Fetch the myState
- var document = result.documents[0];
- // Remove from list until
- if(document.ismaster || document.secondary || document.arbiterOnly) {
- process.nextTick(function() {
- // Apply any auths
- if(Array.isArray(auths) && auths.length > 0) {
- // Get number of auths we need to execute
- var numberOfAuths = auths.length;
- // Apply all auths
- for(var i = 0; i < auths.length; i++) {
- self.db.authenticate(auths[i].username, auths[i].password, {'authdb':auths[i].authdb}, function(err, authenticated) {
- numberOfAuths = numberOfAuths - 1;
- // If we have no more authentications to replay
- if(numberOfAuths == 0) {
- newServerCallback(err, result, _server);
- }
- });
- }
- } else {
- newServerCallback(err, result, _server);
- }
- });
- } else {
- _server.close();
- }
- } else {
- _server.close();
- }
- });
- }
-}
-
-var _handler = function(event, self) {
- return function(err, server) {
- // Check if we have a secondary server
- if(self._state.master && self._state.master.name == server.name) {
- // Force close
- self.close();
- // Error out all callbacks
- __executeAllCallbacksWithError(self.db, err);
- } else if(self._state.master
- && (self._state.secondaries[server.name] != null
- || self._state.arbiters[server.name] != null
- || self._state.passives[server.name] != null)) {
-
- delete self._state.secondaries[server.name];
- delete self._state.arbiters[server.name];
- delete self._state.passives[server.name];
- delete self._state.addresses[server.name];
- }
-
- // If it's a primary we need to close the set to reconnect
- if(self._state.master && self._state.master.host == server.host && self._state.master.port == server.port) {
- // If we have app listeners on close event
- if(self.db.listeners(event).length > 0) {
- self.db.emit(event, err);
- }
- }
- }
-}
-
-var _connectHandler = function(self, candidateServers, instanceServer) {
- return function(err, result) {
- // We are disconnected stop attempting reconnect or connect
- if(self._serverState == 'disconnected') return instanceServer.close();
- // If no error handle isMaster
- if(err == null && result.documents[0].hosts != null) {
- // Fetch the isMaster command result
- var document = result.documents[0];
- // Break out the results
- var setName = document.setName;
- var isMaster = document.ismaster;
- var secondary = document.secondary;
- var passive = document.passive;
- var arbiterOnly = document.arbiterOnly;
- var hosts = Array.isArray(document.hosts) ? document.hosts : [];
- var arbiters = Array.isArray(document.arbiters) ? document.arbiters : [];
- var passives = Array.isArray(document.passives) ? document.passives : [];
- var tags = document.tags ? document.tags : {};
- var primary = document.primary;
- // Find the current server name and fallback if none
- var userProvidedServerString = instanceServer.host + ":" + instanceServer.port;
- var me = document.me || userProvidedServerString;
-
- // Verify if the set name is the same otherwise shut down and return an error
- if(self.replicaSet == null) {
- self.replicaSet = setName;
- } else if(self.replicaSet != setName) {
- // Stop the set
- self.close();
- // Emit a connection error
- return self.emit("connectionError",
- new Error("configured mongodb replicaset does not match provided replicaset [" + setName + "] != [" + self.replicaSet + "]"))
- }
-
- // Make sure we have the right reference
- delete self._state.addresses[instanceServer.host + ":" + instanceServer.port];
- self._state.addresses[me] = instanceServer;
-
- // Let's add the server to our list of server types
- if(secondary == true && (passive == false || passive == null)) {
- self._state.secondaries[me] = instanceServer;
- } else if(arbiterOnly == true) {
- self._state.arbiters[me] = instanceServer;
- } else if(secondary == true && passive == true) {
- self._state.passives[me] = instanceServer;
- } else if(isMaster == true) {
- self._state.master = instanceServer;
- } else if(isMaster == false && primary != null && self._state.addresses[primary]) {
- self._state.master = self._state.addresses[primary];
- }
-
- // Set the name
- instanceServer.name = me;
- // Add tag info
- instanceServer.tags = tags;
- // Add the handlers to the instance
- instanceServer.on("close", _handler("close", self));
- instanceServer.on("error", _handler("error", self));
- instanceServer.on("timeout", _handler("timeout", self));
-
- // Possible hosts
- var possibleHosts = Array.isArray(hosts) ? hosts.slice() : [];
- possibleHosts = Array.isArray(passives) ? possibleHosts.concat(passives) : possibleHosts;
-
- if(self.connectArbiter == true) {
- possibleHosts = Array.isArray(arbiters) ? possibleHosts.concat(arbiters) : possibleHosts;
- }
-
- if(Array.isArray(candidateServers)) {
- // Add any new candidate servers for connection
- for(var j = 0; j < possibleHosts.length; j++) {
- if(self._state.addresses[possibleHosts[j]] == null && possibleHosts[j] != null) {
- var parts = possibleHosts[j].split(/:/);
- if(parts.length == 1) {
- parts = [parts[0], Connection.DEFAULT_PORT];
- }
-
- // New candidate server
- var candidateServer = new Server(parts[0], parseInt(parts[1]));
- candidateServer.name = possibleHosts[j];
- self._state.addresses[possibleHosts[j]] = candidateServer;
- // Add the new server to the list of candidate servers
- candidateServers.push(candidateServer);
- }
- }
- }
- } else if(err != null || self._serverState == 'disconnected'){
- delete self._state.addresses[instanceServer.host + ":" + instanceServer.port];
- // Remove it from the set
- instanceServer.close();
- }
-
- // Attempt to connect to the next server
- if(Array.isArray(candidateServers) && candidateServers.length > 0) {
- var server = candidateServers.pop();
- // Get server addresses
- var addresses = self._state.addresses;
- // Default empty socket options object
- var socketOptions = {};
- // If a socket option object exists clone it
- if(self.socketOptions != null && typeof self.socketOptions === 'object') {
- var keys = Object.keys(self.socketOptions);
- for(var j = 0; j < keys.length;j++) socketOptions[keys[j]] = self.socketOptions[keys[j]];
- }
- // If ssl is specified
- if(self.ssl) serverConnections[i].ssl = true;
- // Set fast connect timeout
- socketOptions['connectTimeoutMS'] = self._connectTimeoutMS
- // Add host information to socket options
- socketOptions['host'] = server.host;
- socketOptions['port'] = server.port;
- server.socketOptions = socketOptions;
- server.replicasetInstance = self;
- server.enableRecordQueryStats(self.recordQueryStats);
-
- // Set the server
- addresses[server.host + ":" + server.port] = server;
- // Connect
- server.connect(self.db, {returnIsMasterResults: true, eventReceiver:server}, _connectHandler(self, candidateServers, server));
- } else if(Array.isArray(candidateServers)) {
- // If we have no primary emit error
- if(self._state.master == null) {
- // Stop the set
- self.close();
- // Emit a connection error
- return self.emit("connectionError",
- new Error("no primary server found in set"))
- } else{
- self.emit("fullsetup", null, self.db, self);
- self.emit("open", null, self.db, self);
- }
- }
- }
-}
-
-/**
- * @ignore
- */
-ReplSet.prototype.connect = function(parent, options, callback) {
- var self = this;
- if('function' === typeof options) callback = options, options = {};
- if(options == null) options = {};
- if(!('function' === typeof callback)) callback = null;
-
- // Ensure it's all closed
- self.close();
- // Set connecting status
- this.db = parent;
- this._serverState = 'connecting';
- this._callbackList = [];
- this._state = {'master':null, 'secondaries':{}, 'arbiters':{}, 'passives':{}
- , 'errors':{}, 'addresses':{}, 'setName':null, 'errorMessages':[], 'members':[]};
- // Ensure parent can do a slave query if it's set
- parent.slaveOk = this.slaveOk ? this.slaveOk : parent.slaveOk;
-
- // Remove any listeners
- this.removeAllListeners("fullsetup");
- this.removeAllListeners("connectionError");
-
- // Add primary found event handler
- this.once("fullsetup", function() {
- // Set state connected
- self._serverState = 'connected';
- // Emit the fullsetup and open event
- parent.emit("open", null, self.db, self);
- parent.emit("fullsetup", null, self.db, self);
- // Callback
- if(typeof callback == 'function') {
- var internalCallback = callback;
- callback = null;
- internalCallback(null, parent, self);
- }
- });
-
- this.once("connectionError", function(err) {
- self._serverState = 'disconnected';
- // Ensure it's all closed
- self.close();
- // Perform the callback
- if(typeof callback == 'function') {
- var internalCallback = callback;
- callback = null;
- internalCallback(err, parent, self);
- }
- });
-
- // Get server addresses
- var addresses = this._state.addresses;
-
- // Default empty socket options object
- var socketOptions = {};
- // If a socket option object exists clone it
- if(this.socketOptions != null && typeof this.socketOptions === 'object') {
- var keys = Object.keys(this.socketOptions);
- for(var j = 0; j < keys.length;j++) socketOptions[keys[j]] = this.socketOptions[keys[j]];
- }
- // If ssl is specified
- if(this.ssl) serverConnections[i].ssl = true;
- // Set fast connect timeout
- socketOptions['connectTimeoutMS'] = this._connectTimeoutMS
-
- // De-duplicate any servers
- var server;
- for(var i = 0; i < this.servers.length; i++) {
- server = this.servers[i];
- // Add host information to socket options
- socketOptions['host'] = server.host;
- socketOptions['port'] = server.port;
- server.socketOptions = socketOptions;
- server.replicasetInstance = this;
- server.enableRecordQueryStats(this.recordQueryStats);
- // If server does not exist set it
- if(addresses[server.host + ":" + server.port] == null) {
- addresses[server.host + ":" + server.port] = server;
- }
- }
-
- // Get the list of servers that is deduplicated and start connecting
- var candidateServers = [];
- for(var key in addresses) {
- candidateServers.push(addresses[key]);
- }
- // Let's connect to the first one on the list
- server = candidateServers.pop();
- server.connect(parent, {returnIsMasterResults: true, eventReceiver:server}, _connectHandler(this, candidateServers, server));
-}
-
-/**
- * @ignore
- */
-ReplSet.prototype.checkoutWriter = function() {
- // Establish connection
- var connection = this._state.master != null ? this._state.master.checkoutWriter() : null;
- // Return the connection
- return connection;
-}
-
-/**
- * @ignore
- */
-var pickFirstConnectedSecondary = function pickFirstConnectedSecondary(self, tags) {
- var keys = Object.keys(self._state.secondaries);
- var connection = null;
-
- // Find first available reader if any
- for(var i = 0; i < keys.length; i++) {
- connection = self._state.secondaries[keys[i]].checkoutReader();
- if(connection != null) break;
- }
-
- // If we still have a null, read from primary if it's not secondary only
- if(self._readPreference == ReadPreference.SECONDARY_PREFERRED) {
- connection = self._state.master.checkoutReader();
- }
-
- if(connection == null) {
- var preferenceName = self._readPreference == ReadPreference.SECONDARY_PREFERRED ? 'secondary' : self._readPreference;
- return new Error("No replica set member available for query with ReadPreference " + preferenceName + " and tags " + JSON.stringify(tags));
- }
-
- // Return the connection
- return connection;
-}
-
-/**
- * @ignore
- */
-var _pickFromTags = function(self, tags) {
- // If we have an array or single tag selection
- var tagObjects = Array.isArray(tags) ? tags : [tags];
- // Iterate over all tags until we find a candidate server
- for(var _i = 0; _i < tagObjects.length; _i++) {
- // Grab a tag object
- var tagObject = tagObjects[_i];
- // Matching keys
- var matchingKeys = Object.keys(tagObject);
- // Match all the servers that match the provdided tags
- var keys = Object.keys(self._state.secondaries);
- var candidateServers = [];
-
- for(var i = 0; i < keys.length; i++) {
- var server = self._state.secondaries[keys[i]];
- // If we have tags match
- if(server.tags != null) {
- var matching = true;
- // Ensure we have all the values
- for(var j = 0; j < matchingKeys.length; j++) {
- if(server.tags[matchingKeys[j]] != tagObject[matchingKeys[j]]) {
- matching = false;
- break;
- }
- }
-
- // If we have a match add it to the list of matching servers
- if(matching) {
- candidateServers.push(server);
- }
- }
- }
-
- // If we have a candidate server return
- if(candidateServers.length > 0) {
- if(this.strategyInstance) return this.strategyInstance.checkoutSecondary(tags, candidateServers);
- // Set instance to return
- return candidateServers[Math.floor(Math.random() * candidateServers.length)].checkoutReader();
- }
- }
-
- // No connection found
- return null;
-}
-
-/**
- * @ignore
- */
-ReplSet.prototype.checkoutReader = function(readPreference, tags) {
- var connection = null;
- // If we have a read preference object unpack it
- if(typeof readPreference == 'object' && readPreference['_type'] == 'ReadPreference') {
- // Validate if the object is using a valid mode
- if(!readPreference.isValid()) throw new Error("Illegal readPreference mode specified, " + readPreference.mode);
- // Set the tag
- tags = readPreference.tags;
- readPreference = readPreference.mode;
- } else if(typeof readPreference == 'object' && readPreference['_type'] != 'ReadPreference') {
- throw new Error("read preferences must be either a string or an instance of ReadPreference");
- }
-
- // Set up our read Preference, allowing us to override the readPreference
- var finalReadPreference = readPreference != null ? readPreference : this._readPreference;
- finalReadPreference = finalReadPreference == true ? ReadPreference.SECONDARY_PREFERRED : finalReadPreference;
-
- // If we are reading from a primary
- if(finalReadPreference == 'primary') {
- // If we provide a tags set send an error
- if(typeof tags == 'object' && tags != null) {
- return new Error("PRIMARY cannot be combined with tags");
- }
-
- // If we provide a tags set send an error
- if(this._state.master == null) {
- return new Error("No replica set primary available for query with ReadPreference PRIMARY");
- }
-
- // Checkout a writer
- return this.checkoutWriter();
- }
-
- // If we have specified to read from a secondary server grab a random one and read
- // from it, otherwise just pass the primary connection
- if((this.readSecondary || finalReadPreference == ReadPreference.SECONDARY_PREFERRED || finalReadPreference == ReadPreference.SECONDARY) && Object.keys(this._state.secondaries).length > 0) {
- // If we have tags, look for servers matching the specific tag
- if(tags != null && typeof tags == 'object') {
- // Get connection
- connection = _pickFromTags(this, tags);// = function(self, readPreference, tags) {
- // No candidate servers that match the tags, error
- if(connection == null) {
- return new Error("No replica set members available for query");
- }
- } else {
- // Pick a secondary using round robin
- var keys = Object.keys(this._state.secondaries);
- this._currentServerChoice = this._currentServerChoice % keys.length;
- var key = keys[this._currentServerChoice++];
- // Fetch a connectio
- connection = this._state.secondaries[key] != null ? this._state.secondaries[key].checkoutReader() : null;
- // If connection is null fallback to first available secondary
- connection = connection == null ? pickFirstConnectedSecondary(this, tags) : connection;
- }
- } else if(finalReadPreference == ReadPreference.PRIMARY_PREFERRED) {
- // Check if there is a primary available and return that if possible
- connection = this.checkoutWriter();
- // If no connection available checkout a secondary
- if(connection == null) {
- // If we have tags, look for servers matching the specific tag
- if(tags != null && typeof tags == 'object') {
- // Get connection
- connection = _pickFromTags(this, tags);// = function(self, readPreference, tags) {
- // No candidate servers that match the tags, error
- if(connection == null) {
- return new Error("No replica set members available for query");
- }
- } else {
- // Pick a secondary using round robin
- var keys = Object.keys(this._state.secondaries);
- this._currentServerChoice = this._currentServerChoice % keys.length;
- var key = keys[this._currentServerChoice++];
- // Fetch a connectio
- connection = this._state.secondaries[key] != null ? this._state.secondaries[key].checkoutReader() : null;
- // If connection is null fallback to first available secondary
- connection = connection == null ? pickFirstConnectedSecondary(this, tags) : connection;
- }
- }
- } else if(finalReadPreference == ReadPreference.SECONDARY_PREFERRED && tags == null && Object.keys(this._state.secondaries).length == 0) {
- connection = this.checkoutWriter();
- // If no connection return an error
- if(connection == null) {
- var preferenceName = finalReadPreference == ReadPreference.SECONDARY ? 'secondary' : finalReadPreference;
- connection = new Error("No replica set member available for query with ReadPreference " + preferenceName + " and tags " + JSON.stringify(tags));
- }
- } else if(finalReadPreference == ReadPreference.SECONDARY_PREFERRED) {
- // If we have tags, look for servers matching the specific tag
- if(tags != null && typeof tags == 'object') {
- // Get connection
- connection = _pickFromTags(this, tags);// = function(self, readPreference, tags) {
- // No candidate servers that match the tags, error
- if(connection == null) {
- // No secondary server avilable, attemp to checkout a primary server
- connection = this.checkoutWriter();
- // If no connection return an error
- if(connection == null) {
- return new Error("No replica set members available for query");
- }
- }
- } else if(this.strategyInstance != null) {
- connection = this.strategyInstance.checkoutReader(tags);
- }
- } else if(finalReadPreference == ReadPreference.NEAREST && this.strategyInstance != null) {
- connection = this.strategyInstance.checkoutSecondary(tags);
- } else if(finalReadPreference == ReadPreference.NEAREST && this.strategyInstance == null) {
- return new Error("A strategy for calculating nearness must be enabled such as ping or statistical");
- } else if(finalReadPreference == ReadPreference.SECONDARY && Object.keys(this._state.secondaries).length == 0) {
- if(tags != null && typeof tags == 'object') {
- var preferenceName = finalReadPreference == ReadPreference.SECONDARY ? 'secondary' : finalReadPreference;
- connection = new Error("No replica set member available for query with ReadPreference " + preferenceName + " and tags " + JSON.stringify(tags));
- } else {
- connection = new Error("No replica set secondary available for query with ReadPreference SECONDARY");
- }
- } else {
- connection = this.checkoutWriter();
- }
-
- // Return the connection
- return connection;
-}
-
-/**
- * @ignore
- */
-ReplSet.prototype.allRawConnections = function() {
- // Neeed to build a complete list of all raw connections, start with master server
- var allConnections = [];
- if(this._state.master == null) return [];
- // Get connection object
- var allMasterConnections = this._state.master.connectionPool.getAllConnections();
- // Add all connections to list
- allConnections = allConnections.concat(allMasterConnections);
-
- // If we have read secondary let's add all secondary servers
- if(this.readSecondary && Object.keys(this._state.secondaries).length > 0) {
- // Get all the keys
- var keys = Object.keys(this._state.secondaries);
- // For each of the secondaries grab the connections
- for(var i = 0; i < keys.length; i++) {
- // Get connection object
- var secondaryPoolConnections = this._state.secondaries[keys[i]].connectionPool.getAllConnections();
- // Add all connections to list
- allConnections = allConnections.concat(secondaryPoolConnections);
- }
- }
-
- // Return all the conections
- return allConnections;
-}
-
-/**
- * @ignore
- */
-ReplSet.prototype.enableRecordQueryStats = function(enable) {
- // Set the global enable record query stats
- this.recordQueryStats = enable;
- // Ensure all existing servers already have the flag set, even if the
- // connections are up already or we have not connected yet
- if(this._state != null && this._state.addresses != null) {
- var keys = Object.keys(this._state.addresses);
- // Iterate over all server instances and set the enableRecordQueryStats flag
- for(var i = 0; i < keys.length; i++) {
- this._state.addresses[keys[i]].enableRecordQueryStats(enable);
- }
- } else if(Array.isArray(this.servers)) {
- for(var i = 0; i < this.servers.length; i++) {
- this.servers[i].enableRecordQueryStats(enable);
- }
- }
-}
-
-/**
- * @ignore
- */
-ReplSet.prototype.disconnect = function(callback) {
- this.close(callback);
-}
-
-/**
- * @ignore
- */
-ReplSet.prototype.close = function(callback) {
- var self = this;
- // Disconnect
- this._serverState = 'disconnected';
- // Close all servers
- if(this._state && this._state.addresses) {
- for(var key in this._state.addresses) {
- this._state.addresses[key].close();
- }
- }
-
- // If it's a callback
- if(typeof callback == 'function') callback(null, null);
-}
-
-/**
- * Auto Reconnect property
- * @ignore
- */
-Object.defineProperty(ReplSet.prototype, "autoReconnect", { enumerable: true
- , get: function () {
- return true;
- }
-});
-
-/**
- * Get Read Preference method
- * @ignore
- */
-Object.defineProperty(ReplSet.prototype, "readPreference", { enumerable: true
- , get: function () {
- if(this._readPreference == null && this.readSecondary) {
- return ReadPreference.SECONDARY_PREFERRED;
- } else if(this._readPreference == null && !this.readSecondary) {
- return ReadPreference.PRIMARY;
- } else {
- return this._readPreference;
- }
- }
-});
-
-/**
- * Db Instances
- * @ignore
- */
-Object.defineProperty(ReplSet.prototype, "dbInstances", {enumerable:true
- , get: function() {
- var servers = this.allServerInstances();
- return servers.length > 0 ? servers[0].dbInstances : [];
- }
-})
-
-/**
- * Just make compatible with server.js
- * @ignore
- */
-Object.defineProperty(ReplSet.prototype, "host", { enumerable: true
- , get: function () {
- if (this.primary != null) return this.primary.host;
- }
-});
-
-/**
- * Just make compatible with server.js
- * @ignore
- */
-Object.defineProperty(ReplSet.prototype, "port", { enumerable: true
- , get: function () {
- if (this.primary != null) return this.primary.port;
- }
-});
-
-/**
- * Get status of read
- * @ignore
- */
-Object.defineProperty(ReplSet.prototype, "read", { enumerable: true
- , get: function () {
- return this.secondaries.length > 0 ? this.secondaries[0] : null;
- }
-});
-
-/**
- * Get list of secondaries
- * @ignore
- */
-Object.defineProperty(ReplSet.prototype, "secondaries", {enumerable: true
- , get: function() {
- var keys = Object.keys(this._state.secondaries);
- var array = new Array(keys.length);
- // Convert secondaries to array
- for(var i = 0; i < keys.length; i++) {
- array[i] = this._state.secondaries[keys[i]];
- }
- return array;
- }
-});
-
-/**
- * Get list of all secondaries including passives
- * @ignore
- */
-Object.defineProperty(ReplSet.prototype, "allSecondaries", {enumerable: true
- , get: function() {
- return this.secondaries.concat(this.passives);
- }
-});
-
-/**
- * Get list of arbiters
- * @ignore
- */
-Object.defineProperty(ReplSet.prototype, "arbiters", {enumerable: true
- , get: function() {
- var keys = Object.keys(this._state.arbiters);
- var array = new Array(keys.length);
- // Convert arbiters to array
- for(var i = 0; i < keys.length; i++) {
- array[i] = this._state.arbiters[keys[i]];
- }
- return array;
- }
-});
-
-/**
- * Get list of passives
- * @ignore
- */
-Object.defineProperty(ReplSet.prototype, "passives", {enumerable: true
- , get: function() {
- var keys = Object.keys(this._state.passives);
- var array = new Array(keys.length);
- // Convert arbiters to array
- for(var i = 0; i < keys.length; i++) {
- array[i] = this._state.passives[keys[i]];
- }
- return array;
- }
-});
-
-/**
- * Master connection property
- * @ignore
- */
-Object.defineProperty(ReplSet.prototype, "primary", { enumerable: true
- , get: function () {
- return this._state != null ? this._state.master : null;
- }
-});
-
-/**
- * @ignore
- */
-// Backward compatibility
-exports.ReplSetServers = ReplSet;
diff --git a/CoAuthoring/node_modules/mongodb/lib/mongodb/connection/server.js b/CoAuthoring/node_modules/mongodb/lib/mongodb/connection/server.js
deleted file mode 100644
index 6ede413436..0000000000
--- a/CoAuthoring/node_modules/mongodb/lib/mongodb/connection/server.js
+++ /dev/null
@@ -1,839 +0,0 @@
-var Connection = require('./connection').Connection,
- ReadPreference = require('./read_preference').ReadPreference,
- DbCommand = require('../commands/db_command').DbCommand,
- MongoReply = require('../responses/mongo_reply').MongoReply,
- ConnectionPool = require('./connection_pool').ConnectionPool,
- EventEmitter = require('events').EventEmitter,
- inherits = require('util').inherits;
-
-/**
- * Class representing a single MongoDB Server connection
- *
- * Options
- * - **readPreference** {String, default:null}, set's the read preference (ReadPreference.PRIMARY, ReadPreference.PRIMARY_PREFERRED, ReadPreference.SECONDARY, ReadPreference.SECONDARY_PREFERRED, ReadPreference.NEAREST)
- * - **ssl** {Boolean, default:false}, use ssl connection (needs to have a mongod server with ssl support)
- * - **slaveOk** {Boolean, default:false}, legacy option allowing reads from secondary, use **readPrefrence** instead.
- * - **poolSize** {Number, default:1}, number of connections in the connection pool, set to 1 as default for legacy reasons.
- * - **socketOptions** {Object, default:null}, an object containing socket options to use (noDelay:(boolean), keepAlive:(number), connectTimeoutMS:(number), socketTimeoutMS:(number))
- * - **logger** {Object, default:null}, an object representing a logger that you want to use, needs to support functions debug, log, error **({error:function(message, object) {}, log:function(message, object) {}, debug:function(message, object) {}})**.
- * - **auto_reconnect** {Boolean, default:false}, reconnect on error.
- * - **disableDriverBSONSizeCheck** {Boolean, default:false}, force the server to error if the BSON message is to big
- *
- * @class Represents a Server connection.
- * @param {String} host the server host
- * @param {Number} port the server port
- * @param {Object} [options] optional options for insert command
- */
-function Server(host, port, options) {
- // Set up event emitter
- EventEmitter.call(this);
- // Set up Server instance
- if(!(this instanceof Server)) return new Server(host, port, options);
-
- var self = this;
- this.host = host;
- this.port = port;
- this.options = options == null ? {} : options;
- this.internalConnection;
- this.internalMaster = false;
- this.connected = false;
- this.poolSize = this.options.poolSize == null ? 5 : this.options.poolSize;
- this.disableDriverBSONSizeCheck = this.options.disableDriverBSONSizeCheck != null ? this.options.disableDriverBSONSizeCheck : false;
- this.ssl = this.options.ssl == null ? false : this.options.ssl;
- this.slaveOk = this.options["slave_ok"];
- this._used = false;
-
- // Get the readPreference
- var readPreference = this.options['readPreference'];
- // Read preference setting
- if(readPreference != null) {
- if(readPreference != ReadPreference.PRIMARY && readPreference != ReadPreference.SECONDARY
- && readPreference != ReadPreference.SECONDARY_PREFERRED) {
- throw new Error("Illegal readPreference mode specified, " + readPreference);
- }
-
- // Set read Preference
- this._readPreference = readPreference;
- } else {
- this._readPreference = null;
- }
-
- // Contains the isMaster information returned from the server
- this.isMasterDoc;
-
- // Set default connection pool options
- this.socketOptions = this.options.socketOptions != null ? this.options.socketOptions : {};
- if(this.disableDriverBSONSizeCheck) this.socketOptions.disableDriverBSONSizeCheck = this.disableDriverBSONSizeCheck;
- // Set ssl up if it's defined
- if(this.ssl) {
- this.socketOptions.ssl = true;
- }
-
- // Set up logger if any set
- this.logger = this.options.logger != null
- && (typeof this.options.logger.debug == 'function')
- && (typeof this.options.logger.error == 'function')
- && (typeof this.options.logger.log == 'function')
- ? this.options.logger : {error:function(message, object) {}, log:function(message, object) {}, debug:function(message, object) {}};
-
- // Just keeps list of events we allow
- this.eventHandlers = {error:[], parseError:[], poolReady:[], message:[], close:[], timeout:[]};
- // Internal state of server connection
- this._serverState = 'disconnected';
- // this._timeout = false;
- // Contains state information about server connection
- this._state = {'runtimeStats': {'queryStats':new RunningStats()}};
- // Do we record server stats or not
- this.recordQueryStats = false;
-};
-
-/**
- * @ignore
- */
-// Inherit simple event emitter
-inherits(Server, EventEmitter);
-
-//
-// Deprecated, USE ReadPreferences class
-//
-Server.READ_PRIMARY = ReadPreference.PRIMARY;
-Server.READ_SECONDARY = ReadPreference.SECONDARY_PREFERRED;
-Server.READ_SECONDARY_ONLY = ReadPreference.SECONDARY;
-
-/**
- * Always ourselves
- * @ignore
- */
-Server.prototype.setReadPreference = function() {}
-
-/**
- * @ignore
- */
-Server.prototype.isMongos = function() {
- return this.isMasterDoc != null && this.isMasterDoc['msg'] == "isdbgrid" ? true : false;
-}
-
-/**
- * @ignore
- */
-Server.prototype._isUsed = function() {
- return this._used;
-}
-
-/**
- * @ignore
- */
-Server.prototype.close = function(callback) {
- // Remove all local listeners
- this.removeAllListeners();
-
- if(this.connectionPool != null) {
- // Remove all the listeners on the pool so it does not fire messages all over the place
- this.connectionPool.removeAllEventListeners();
- // Close the connection if it's open
- this.connectionPool.stop(true);
- }
-
- // Set server status as disconnected
- this._serverState = 'disconnected';
- // Peform callback if present
- if(typeof callback === 'function') callback();
-};
-
-/**
- * @ignore
- */
-Server.prototype.isConnected = function() {
- return this._serverState == 'connected';
-}
-
-/**
- * @ignore
- */
-Server.prototype.allServerInstances = function() {
- return [this];
-}
-
-/**
- * @ignore
- */
-Server.prototype.isSetMember = function() {
- return this['replicasetInstance'] != null || this['mongosInstance'] != null;
-}
-
-/**
- * @ignore
- */
-Server.prototype.connect = function(dbInstance, options, callback) {
- if('function' === typeof options) callback = options, options = {};
- if(options == null) options = {};
- if(!('function' === typeof callback)) callback = null;
-
- // Currently needed to work around problems with multiple connections in a pool with ssl
- // TODO fix if possible
- if(this.ssl == true) {
- // Set up socket options for ssl
- this.socketOptions.ssl = true;
- }
-
- // Let's connect
- var server = this;
- // Let's us override the main receiver of events
- var eventReceiver = options.eventReceiver != null ? options.eventReceiver : this;
- // Creating dbInstance
- this.dbInstance = dbInstance;
- // Save reference to dbInstance
- this.dbInstances = [dbInstance];
-
- // Force connection pool if there is one
- if(server.connectionPool) server.connectionPool.stop();
-
- // Set server state to connecting
- this._serverState = 'connecting';
- // Ensure dbInstance can do a slave query if it's set
- dbInstance.slaveOk = this.slaveOk ? this.slaveOk : dbInstance.slaveOk;
- // Create connection Pool instance with the current BSON serializer
- var connectionPool = new ConnectionPool(this.host, this.port, this.poolSize, dbInstance.bson, this.socketOptions);
- // Set logger on pool
- connectionPool.logger = this.logger;
-
- // Set up a new pool using default settings
- server.connectionPool = connectionPool;
-
- // Set basic parameters passed in
- var returnIsMasterResults = options.returnIsMasterResults == null ? false : options.returnIsMasterResults;
-
- // Create a default connect handler, overriden when using replicasets
- var connectCallback = function(err, reply) {
- // ensure no callbacks get called twice
- var internalCallback = callback;
- callback = null;
- // If something close down the connection and removed the callback before
- // proxy killed connection etc, ignore the erorr as close event was isssued
- if(err != null && internalCallback == null) return;
- // Internal callback
- if(err != null) return internalCallback(err, null);
- server.master = reply.documents[0].ismaster == 1 ? true : false;
- server.connectionPool.setMaxBsonSize(reply.documents[0].maxBsonObjectSize);
- // Set server as connected
- server.connected = true;
- // Save document returned so we can query it
- server.isMasterDoc = reply.documents[0];
-
- // Emit open event
- _emitAcrossAllDbInstances(server, eventReceiver, "open", null, returnIsMasterResults ? reply : dbInstance, null);
-
- // If we have it set to returnIsMasterResults
- if(returnIsMasterResults) {
- internalCallback(null, reply, server);
- } else {
- internalCallback(null, dbInstance, server);
- }
- };
-
- // Let's us override the main connect callback
- var connectHandler = options.connectHandler == null ? connectCallback : options.connectHandler;
-
- // Set up on connect method
- connectionPool.on("poolReady", function() {
- // Create db command and Add the callback to the list of callbacks by the request id (mapping outgoing messages to correct callbacks)
- var db_command = DbCommand.NcreateIsMasterCommand(dbInstance, dbInstance.databaseName);
- // Check out a reader from the pool
- var connection = connectionPool.checkoutConnection();
- // Set server state to connEcted
- server._serverState = 'connected';
-
- // Register handler for messages
- dbInstance._registerHandler(db_command, false, connection, connectHandler);
-
- // Write the command out
- connection.write(db_command);
- })
-
- // Set up item connection
- connectionPool.on("message", function(message) {
- // Attempt to parse the message
- try {
- // Create a new mongo reply
- var mongoReply = new MongoReply()
- // Parse the header
- mongoReply.parseHeader(message, connectionPool.bson)
- // If message size is not the same as the buffer size
- // something went terribly wrong somewhere
- if(mongoReply.messageLength != message.length) {
- // Emit the error
- if(eventReceiver.listeners("error") && eventReceiver.listeners("error").length > 0) eventReceiver.emit("error", new Error("bson length is different from message length"), server);
- // Remove all listeners
- server.removeAllListeners();
- } else {
- var startDate = new Date().getTime();
-
- // Callback instance
- var callbackInfo = null;
- var dbInstanceObject = null;
-
- // Locate a callback instance and remove any additional ones
- for(var i = 0; i < server.dbInstances.length; i++) {
- var dbInstanceObjectTemp = server.dbInstances[i];
- var hasHandler = dbInstanceObjectTemp._hasHandler(mongoReply.responseTo.toString());
- // Assign the first one we find and remove any duplicate ones
- if(hasHandler && callbackInfo == null) {
- callbackInfo = dbInstanceObjectTemp._findHandler(mongoReply.responseTo.toString());
- dbInstanceObject = dbInstanceObjectTemp;
- } else if(hasHandler) {
- dbInstanceObjectTemp._removeHandler(mongoReply.responseTo.toString());
- }
- }
-
- // Only execute callback if we have a caller
- // chained is for findAndModify as it does not respect write concerns
- if(callbackInfo.callback && Array.isArray(callbackInfo.info.chained)) {
- // Check if callback has already been fired (missing chain command)
- var chained = callbackInfo.info.chained;
- var numberOfFoundCallbacks = 0;
- for(var i = 0; i < chained.length; i++) {
- if(dbInstanceObject._hasHandler(chained[i])) numberOfFoundCallbacks++;
- }
-
- // If we have already fired then clean up rest of chain and move on
- if(numberOfFoundCallbacks != chained.length) {
- for(var i = 0; i < chained.length; i++) {
- dbInstanceObject._removeHandler(chained[i]);
- }
-
- // Just return from function
- return;
- }
-
- // Parse the body
- mongoReply.parseBody(message, connectionPool.bson, callbackInfo.info.raw, function(err) {
- if(err != null) {
- // If pool connection is already closed
- if(server._serverState === 'disconnected') return;
- // Set server state to disconnected
- server._serverState = 'disconnected';
- // Remove all listeners and close the connection pool
- server.removeAllListeners();
- connectionPool.stop(true);
-
- // If we have a callback return the error
- if(typeof callback === 'function') {
- // ensure no callbacks get called twice
- var internalCallback = callback;
- callback = null;
- // Perform callback
- internalCallback(new Error("connection closed due to parseError"), null, server);
- } else if(server.isSetMember()) {
- if(server.listeners("parseError") && server.listeners("parseError").length > 0) server.emit("parseError", new Error("connection closed due to parseError"), server);
- } else {
- if(eventReceiver.listeners("parseError") && eventReceiver.listeners("parseError").length > 0) eventReceiver.emit("parseError", new Error("connection closed due to parseError"), server);
- }
-
- // If we are a single server connection fire errors correctly
- if(!server.isSetMember()) {
- // Fire all callback errors
- _fireCallbackErrors(server, new Error("connection closed due to parseError"));
- // Emit error
- _emitAcrossAllDbInstances(server, eventReceiver, "parseError", server, null, true);
- }
- // Short cut
- return;
- }
-
- // Fetch the callback
- var callbackInfo = dbInstanceObject._findHandler(mongoReply.responseTo.toString());
- // If we have an error let's execute the callback and clean up all other
- // chained commands
- var firstResult = mongoReply && mongoReply.documents;
- // Check for an error, if we have one let's trigger the callback and clean up
- // The chained callbacks
- if(firstResult[0].err != null || firstResult[0].errmsg != null) {
- // Trigger the callback for the error
- dbInstanceObject._callHandler(mongoReply.responseTo, mongoReply, null);
- } else {
- var chainedIds = callbackInfo.info.chained;
-
- if(chainedIds.length > 0 && chainedIds[chainedIds.length - 1] == mongoReply.responseTo) {
- // Cleanup all other chained calls
- chainedIds.pop();
- // Remove listeners
- for(var i = 0; i < chainedIds.length; i++) dbInstanceObject._removeHandler(chainedIds[i]);
- // Call the handler
- dbInstanceObject._callHandler(mongoReply.responseTo, callbackInfo.info.results.shift(), null);
- } else{
- // Add the results to all the results
- for(var i = 0; i < chainedIds.length; i++) {
- var handler = dbInstanceObject._findHandler(chainedIds[i]);
- // Check if we have an object, if it's the case take the current object commands and
- // and add this one
- if(handler.info != null) {
- handler.info.results = Array.isArray(callbackInfo.info.results) ? callbackInfo.info.results : [];
- handler.info.results.push(mongoReply);
- }
- }
- }
- }
- });
- } else if(callbackInfo.callback) {
- // Parse the body
- mongoReply.parseBody(message, connectionPool.bson, callbackInfo.info.raw, function(err) {
- if(err != null) {
- // If pool connection is already closed
- if(server._serverState === 'disconnected') return;
- // Set server state to disconnected
- server._serverState = 'disconnected';
- // Remove all listeners and close the connection pool
- server.removeAllListeners();
- connectionPool.stop(true);
-
- // If we have a callback return the error
- if(typeof callback === 'function') {
- // ensure no callbacks get called twice
- var internalCallback = callback;
- callback = null;
- // Perform callback
- internalCallback(new Error("connection closed due to parseError"), null, server);
- } else if(server.isSetMember()) {
- if(server.listeners("parseError") && server.listeners("parseError").length > 0) server.emit("parseError", new Error("connection closed due to parseError"), server);
- } else {
- if(eventReceiver.listeners("parseError") && eventReceiver.listeners("parseError").length > 0) eventReceiver.emit("parseError", new Error("connection closed due to parseError"), server);
- }
-
- // If we are a single server connection fire errors correctly
- if(!server.isSetMember()) {
- // Fire all callback errors
- _fireCallbackErrors(server, new Error("connection closed due to parseError"));
- // Emit error
- _emitAcrossAllDbInstances(server, eventReceiver, "parseError", server, null, true);
- }
- // Short cut
- return;
- }
-
- // Let's record the stats info if it's enabled
- if(server.recordQueryStats == true && server._state['runtimeStats'] != null
- && server._state.runtimeStats['queryStats'] instanceof RunningStats) {
- // Add data point to the running statistics object
- server._state.runtimeStats.queryStats.push(new Date().getTime() - callbackInfo.info.start);
- }
-
- // Trigger the callback
- dbInstanceObject._callHandler(mongoReply.responseTo, mongoReply, null);
- });
- }
- }
- } catch (err) {
- // Throw error in next tick
- process.nextTick(function() {
- throw err;
- })
- }
- });
-
- // Handle timeout
- connectionPool.on("timeout", function(err) {
- // If pool connection is already closed
- if(server._serverState === 'disconnected') return;
- // Set server state to disconnected
- server._serverState = 'disconnected';
- // If we have a callback return the error
- if(typeof callback === 'function') {
- // ensure no callbacks get called twice
- var internalCallback = callback;
- callback = null;
- // Perform callback
- internalCallback(err, null, server);
- } else if(server.isSetMember()) {
- if(server.listeners("timeout") && server.listeners("timeout").length > 0) server.emit("timeout", err, server);
- } else {
- if(eventReceiver.listeners("timeout") && eventReceiver.listeners("timeout").length > 0) eventReceiver.emit("timeout", err, server);
- }
-
- // If we are a single server connection fire errors correctly
- if(!server.isSetMember()) {
- // Fire all callback errors
- _fireCallbackErrors(server, err);
- // Emit error
- _emitAcrossAllDbInstances(server, eventReceiver, "timeout", err, server, true);
- }
- });
-
- // Handle errors
- connectionPool.on("error", function(message) {
- // If pool connection is already closed
- if(server._serverState === 'disconnected') return;
- // Set server state to disconnected
- server._serverState = 'disconnected';
- // If we have a callback return the error
- if(typeof callback === 'function') {
- // ensure no callbacks get called twice
- var internalCallback = callback;
- callback = null;
- // Perform callback
- internalCallback(new Error(message && message.err ? message.err : message), null, server);
- } else if(server.isSetMember()) {
- if(server.listeners("error") && server.listeners("error").length > 0) server.emit("error", new Error(message && message.err ? message.err : message), server);
- } else {
- if(eventReceiver.listeners("error") && eventReceiver.listeners("error").length > 0) eventReceiver.emit("error", new Error(message && message.err ? message.err : message), server);
- }
-
- // If we are a single server connection fire errors correctly
- if(!server.isSetMember()) {
- // Fire all callback errors
- _fireCallbackErrors(server, new Error(message && message.err ? message.err : message));
- // Emit error
- _emitAcrossAllDbInstances(server, eventReceiver, "error", new Error(message && message.err ? message.err : message), server, true);
- }
- });
-
- // Handle close events
- connectionPool.on("close", function() {
- // If pool connection is already closed
- if(server._serverState === 'disconnected') return;
- // Set server state to disconnected
- server._serverState = 'disconnected';
- // If we have a callback return the error
- if(typeof callback == 'function') {
- // ensure no callbacks get called twice
- var internalCallback = callback;
- callback = null;
- // Perform callback
- internalCallback(new Error("connection closed"), null, server);
- } else if(server.isSetMember()) {
- if(server.listeners("close") && server.listeners("close").length > 0) server.emit("close", new Error("connection closed"), server);
- } else {
- if(eventReceiver.listeners("close") && eventReceiver.listeners("close").length > 0) eventReceiver.emit("close", new Error("connection closed"), server);
- }
-
- // If we are a single server connection fire errors correctly
- if(!server.isSetMember()) {
- // Fire all callback errors
- _fireCallbackErrors(server, new Error("connection closed"));
- // Emit error
- _emitAcrossAllDbInstances(server, eventReceiver, "close", server, null, true);
- }
- });
-
- // If we have a parser error we are in an unknown state, close everything and emit
- // error
- connectionPool.on("parseError", function(message) {
- // If pool connection is already closed
- if(server._serverState === 'disconnected') return;
- // Set server state to disconnected
- server._serverState = 'disconnected';
- // If we have a callback return the error
- if(typeof callback === 'function') {
- // ensure no callbacks get called twice
- var internalCallback = callback;
- callback = null;
- // Perform callback
- internalCallback(new Error("connection closed due to parseError"), null, server);
- } else if(server.isSetMember()) {
- if(server.listeners("parseError") && server.listeners("parseError").length > 0) server.emit("parseError", new Error("connection closed due to parseError"), server);
- } else {
- if(eventReceiver.listeners("parseError") && eventReceiver.listeners("parseError").length > 0) eventReceiver.emit("parseError", new Error("connection closed due to parseError"), server);
- }
-
- // If we are a single server connection fire errors correctly
- if(!server.isSetMember()) {
- // Fire all callback errors
- _fireCallbackErrors(server, new Error("connection closed due to parseError"));
- // Emit error
- _emitAcrossAllDbInstances(server, eventReceiver, "parseError", server, null, true);
- }
- });
-
- // Boot up connection poole, pass in a locator of callbacks
- connectionPool.start();
-}
-
-/**
- * Fire all the errors
- * @ignore
- */
-var _fireCallbackErrors = function(server, err) {
- // Locate all the possible callbacks that need to return
- for(var i = 0; i < server.dbInstances.length; i++) {
- // Fetch the db Instance
- var dbInstance = server.dbInstances[i];
- // Check all callbacks
- var keys = Object.keys(dbInstance._callBackStore._notReplied);
- // For each key check if it's a callback that needs to be returned
- for(var j = 0; j < keys.length; j++) {
- var info = dbInstance._callBackStore._notReplied[keys[j]];
- // Check if we have a chained command (findAndModify)
- if(info && info['chained'] && Array.isArray(info['chained']) && info['chained'].length > 0) {
- var chained = info['chained'];
- // Only callback once and the last one is the right one
- var finalCallback = chained.pop();
- if(info.connection.socketOptions.host === server.host && info.connection.socketOptions.port === server.port) {
- dbInstance._callBackStore.emit(finalCallback, err, null);
- }
-
- // Put back the final callback to ensure we don't call all commands in the chain
- chained.push(finalCallback);
-
- // Remove all chained callbacks
- for(var i = 0; i < chained.length; i++) {
- delete dbInstance._callBackStore._notReplied[chained[i]];
- }
- } else {
- if(info && info.connection.socketOptions.host === server.host && info.connection.socketOptions.port === server.port) {
- dbInstance._callBackStore.emit(keys[j], err, null);
- }
- }
- }
- }
-}
-
-/**
- * @ignore
- */
-var _emitAcrossAllDbInstances = function(server, filterDb, event, message, object, resetConnection) {
- // Emit close event across all db instances sharing the sockets
- var allServerInstances = server.allServerInstances();
- // Fetch the first server instance
- var serverInstance = allServerInstances[0];
- // For all db instances signal all db instances
- if(Array.isArray(serverInstance.dbInstances) && serverInstance.dbInstances.length >= 1) {
- for(var i = 0; i < serverInstance.dbInstances.length; i++) {
- var dbInstance = serverInstance.dbInstances[i];
- // Set the parent
- if(resetConnection && typeof dbInstance.openCalled != 'undefined')
- dbInstance.openCalled = false;
- // Check if it's our current db instance and skip if it is
- if(filterDb == null || filterDb.databaseName !== dbInstance.databaseName || filterDb.tag !== dbInstance.tag) {
- // Only emit if there is a listener
- if(dbInstance.listeners(event).length > 0)
- dbInstance.emit(event, message, object);
- }
- }
- }
-}
-
-/**
- * @ignore
- */
-Server.prototype.allRawConnections = function() {
- return this.connectionPool.getAllConnections();
-}
-
-/**
- * Check if a writer can be provided
- * @ignore
- */
-var canCheckoutWriter = function(self, read) {
- // We cannot write to an arbiter or secondary server
- if(self.isMasterDoc['arbiterOnly'] == true) {
- return new Error("Cannot write to an arbiter");
- } if(self.isMasterDoc['secondary'] == true) {
- return new Error("Cannot write to a secondary");
- } else if(read == true && self._readPreference == ReadPreference.SECONDARY && self.isMasterDoc['ismaster'] == true) {
- return new Error("Cannot read from primary when secondary only specified");
- }
-
- // Return no error
- return null;
-}
-
-/**
- * @ignore
- */
-Server.prototype.checkoutWriter = function(read) {
- if(read == true) return this.connectionPool.checkoutConnection();
- // Check if are allowed to do a checkout (if we try to use an arbiter f.ex)
- var result = canCheckoutWriter(this, read);
- // If the result is null check out a writer
- if(result == null && this.connectionPool != null) {
- return this.connectionPool.checkoutConnection();
- } else if(result == null) {
- return null;
- } else {
- return result;
- }
-}
-
-/**
- * Check if a reader can be provided
- * @ignore
- */
-var canCheckoutReader = function(self) {
- // We cannot write to an arbiter or secondary server
- if(self.isMasterDoc && self.isMasterDoc['arbiterOnly'] == true) {
- return new Error("Cannot write to an arbiter");
- } else if(self._readPreference != null) {
- // If the read preference is Primary and the instance is not a master return an error
- if((self._readPreference == ReadPreference.PRIMARY) && self.isMasterDoc['ismaster'] != true) {
- return new Error("Read preference is Server.PRIMARY and server is not master");
- } else if(self._readPreference == ReadPreference.SECONDARY && self.isMasterDoc['ismaster'] == true) {
- return new Error("Cannot read from primary when secondary only specified");
- }
- }
-
- // Return no error
- return null;
-}
-
-/**
- * @ignore
- */
-Server.prototype.checkoutReader = function() {
- // Check if are allowed to do a checkout (if we try to use an arbiter f.ex)
- var result = canCheckoutReader(this);
- // If the result is null check out a writer
- if(result == null && this.connectionPool != null) {
- return this.connectionPool.checkoutConnection();
- } else if(result == null) {
- return null;
- } else {
- return result;
- }
-}
-
-/**
- * @ignore
- */
-Server.prototype.enableRecordQueryStats = function(enable) {
- this.recordQueryStats = enable;
-}
-
-/**
- * Internal statistics object used for calculating average and standard devitation on
- * running queries
- * @ignore
- */
-var RunningStats = function() {
- var self = this;
- this.m_n = 0;
- this.m_oldM = 0.0;
- this.m_oldS = 0.0;
- this.m_newM = 0.0;
- this.m_newS = 0.0;
-
- // Define getters
- Object.defineProperty(this, "numDataValues", { enumerable: true
- , get: function () { return this.m_n; }
- });
-
- Object.defineProperty(this, "mean", { enumerable: true
- , get: function () { return (this.m_n > 0) ? this.m_newM : 0.0; }
- });
-
- Object.defineProperty(this, "variance", { enumerable: true
- , get: function () { return ((this.m_n > 1) ? this.m_newS/(this.m_n - 1) : 0.0); }
- });
-
- Object.defineProperty(this, "standardDeviation", { enumerable: true
- , get: function () { return Math.sqrt(this.variance); }
- });
-
- Object.defineProperty(this, "sScore", { enumerable: true
- , get: function () {
- var bottom = this.mean + this.standardDeviation;
- if(bottom == 0) return 0;
- return ((2 * this.mean * this.standardDeviation)/(bottom));
- }
- });
-}
-
-/**
- * @ignore
- */
-RunningStats.prototype.push = function(x) {
- // Update the number of samples
- this.m_n = this.m_n + 1;
- // See Knuth TAOCP vol 2, 3rd edition, page 232
- if(this.m_n == 1) {
- this.m_oldM = this.m_newM = x;
- this.m_oldS = 0.0;
- } else {
- this.m_newM = this.m_oldM + (x - this.m_oldM) / this.m_n;
- this.m_newS = this.m_oldS + (x - this.m_oldM) * (x - this.m_newM);
-
- // set up for next iteration
- this.m_oldM = this.m_newM;
- this.m_oldS = this.m_newS;
- }
-}
-
-/**
- * @ignore
- */
-Object.defineProperty(Server.prototype, "autoReconnect", { enumerable: true
- , get: function () {
- return this.options['auto_reconnect'] == null ? false : this.options['auto_reconnect'];
- }
-});
-
-/**
- * @ignore
- */
-Object.defineProperty(Server.prototype, "connection", { enumerable: true
- , get: function () {
- return this.internalConnection;
- }
- , set: function(connection) {
- this.internalConnection = connection;
- }
-});
-
-/**
- * @ignore
- */
-Object.defineProperty(Server.prototype, "master", { enumerable: true
- , get: function () {
- return this.internalMaster;
- }
- , set: function(value) {
- this.internalMaster = value;
- }
-});
-
-/**
- * @ignore
- */
-Object.defineProperty(Server.prototype, "primary", { enumerable: true
- , get: function () {
- return this;
- }
-});
-
-/**
- * Getter for query Stats
- * @ignore
- */
-Object.defineProperty(Server.prototype, "queryStats", { enumerable: true
- , get: function () {
- return this._state.runtimeStats.queryStats;
- }
-});
-
-/**
- * @ignore
- */
-Object.defineProperty(Server.prototype, "runtimeStats", { enumerable: true
- , get: function () {
- return this._state.runtimeStats;
- }
-});
-
-/**
- * Get Read Preference method
- * @ignore
- */
-Object.defineProperty(Server.prototype, "readPreference", { enumerable: true
- , get: function () {
- if(this._readPreference == null && this.readSecondary) {
- return Server.READ_SECONDARY;
- } else if(this._readPreference == null && !this.readSecondary) {
- return Server.READ_PRIMARY;
- } else {
- return this._readPreference;
- }
- }
-});
-
-/**
- * @ignore
- */
-exports.Server = Server;
diff --git a/CoAuthoring/node_modules/mongodb/lib/mongodb/connection/strategies/ping_strategy.js b/CoAuthoring/node_modules/mongodb/lib/mongodb/connection/strategies/ping_strategy.js
deleted file mode 100644
index aaf75690e5..0000000000
--- a/CoAuthoring/node_modules/mongodb/lib/mongodb/connection/strategies/ping_strategy.js
+++ /dev/null
@@ -1,173 +0,0 @@
-var Server = require("../server").Server;
-
-// The ping strategy uses pings each server and records the
-// elapsed time for the server so it can pick a server based on lowest
-// return time for the db command {ping:true}
-var PingStrategy = exports.PingStrategy = function(replicaset, secondaryAcceptableLatencyMS) {
- this.replicaset = replicaset;
- this.secondaryAcceptableLatencyMS = secondaryAcceptableLatencyMS;
- this.state = 'disconnected';
- // Class instance
- this.Db = require("../../db").Db;
-}
-
-// Starts any needed code
-PingStrategy.prototype.start = function(callback) {
- this.state = 'connected';
- // Start ping server
- this._pingServer(callback);
-}
-
-// Stops and kills any processes running
-PingStrategy.prototype.stop = function(callback) {
- // Stop the ping process
- this.state = 'disconnected';
- // Call the callback
- callback(null, null);
-}
-
-PingStrategy.prototype.checkoutSecondary = function(tags, secondaryCandidates) {
- // Servers are picked based on the lowest ping time and then servers that lower than that + secondaryAcceptableLatencyMS
- // Create a list of candidat servers, containing the primary if available
- var candidateServers = [];
-
- // If we have not provided a list of candidate servers use the default setup
- if(!Array.isArray(secondaryCandidates)) {
- candidateServers = this.replicaset._state.master != null ? [this.replicaset._state.master] : [];
- // Add all the secondaries
- var keys = Object.keys(this.replicaset._state.secondaries);
- for(var i = 0; i < keys.length; i++) {
- candidateServers.push(this.replicaset._state.secondaries[keys[i]])
- }
- } else {
- candidateServers = secondaryCandidates;
- }
-
- // Final list of eligable server
- var finalCandidates = [];
-
- // If we have tags filter by tags
- if(tags != null && typeof tags == 'object') {
- // If we have an array or single tag selection
- var tagObjects = Array.isArray(tags) ? tags : [tags];
- // Iterate over all tags until we find a candidate server
- for(var _i = 0; _i < tagObjects.length; _i++) {
- // Grab a tag object
- var tagObject = tagObjects[_i];
- // Matching keys
- var matchingKeys = Object.keys(tagObject);
- // Remove any that are not tagged correctly
- for(var i = 0; i < candidateServers.length; i++) {
- var server = candidateServers[i];
- // If we have tags match
- if(server.tags != null) {
- var matching = true;
-
- // Ensure we have all the values
- for(var j = 0; j < matchingKeys.length; j++) {
- if(server.tags[matchingKeys[j]] != tagObject[matchingKeys[j]]) {
- matching = false;
- break;
- }
- }
-
- // If we have a match add it to the list of matching servers
- if(matching) {
- finalCandidates.push(server);
- }
- }
- }
- }
- } else {
- // Final array candidates
- var finalCandidates = candidateServers;
- }
-
- // Sort by ping time
- finalCandidates.sort(function(a, b) {
- return a.runtimeStats['pingMs'] > b.runtimeStats['pingMs'];
- });
-
- // Cut off the array of anything slower than the [0].pingMs + secondaryAcceptableLatencyMS
- for(var i = 0; i < finalCandidates.length; i++) {
- if(finalCandidates[i].runtimeStats['pingMs'] > finalCandidates[0].runtimeStats['pingMs'] + this.secondaryAcceptableLatencyMS) {
- // Slice out the array and break
- finalCandidates = finalCandidates.slice(i);
- break;
- }
- }
-
- // If no candidates available return an error
- if(finalCandidates.length == 0) return new Error("No replica set members available for query");
- // Pick a random server
- return finalCandidates[Math.round(Math.random(1000000) * (finalCandidates.length - 1))].checkoutReader();
-}
-
-PingStrategy.prototype._pingServer = function(callback) {
- var self = this;
-
- // Ping server function
- var pingFunction = function() {
- if(self.state == 'disconnected') return;
- var addresses = self.replicaset._state != null && self.replicaset._state.addresses != null ? self.replicaset._state.addresses : null;
- // Grab all servers
- var serverKeys = Object.keys(addresses);
- // Number of server entries
- var numberOfEntries = serverKeys.length;
- // We got keys
- for(var i = 0; i < serverKeys.length; i++) {
- // We got a server instance
- var server = addresses[serverKeys[i]];
- // Create a new server object, avoid using internal connections as they might
- // be in an illegal state
- new function(serverInstance) {
- var server = new Server(serverInstance.host, serverInstance.port, {poolSize:1, timeout:500});
- var db = new self.Db(self.replicaset.db.databaseName, server);
- // Add error listener
- db.on("error", function(err) {
- // Adjust the number of checks
- numberOfEntries = numberOfEntries - 1;
- // Close connection
- db.close();
- // If we are done with all results coming back trigger ping again
- if(numberOfEntries == 0 && self.state == 'connected') {
- setTimeout(pingFunction, 1000);
- }
- })
-
- // Open the db instance
- db.open(function(err, p_db) {
- if(err != null) {
- db.close();
- } else {
- // Startup time of the command
- var startTime = new Date().getTime();
- // Execute ping on this connection
- p_db.executeDbCommand({ping:1}, function(err, result) {
- // Adjust the number of checks
- numberOfEntries = numberOfEntries - 1;
- // Get end time of the command
- var endTime = new Date().getTime();
- // Store the ping time in the server instance state variable, if there is one
- if(serverInstance != null && serverInstance.runtimeStats != null && serverInstance.isConnected()) {
- serverInstance.runtimeStats['pingMs'] = (endTime - startTime);
- }
-
- // Close server
- p_db.close();
- // If we are done with all results coming back trigger ping again
- if(numberOfEntries == 0 && self.state == 'connected') {
- setTimeout(pingFunction, 1000);
- }
- })
- }
- })
- }(server);
- }
- }
-
- // Start pingFunction
- setTimeout(pingFunction, 1000);
- // Do the callback
- callback(null);
-}
diff --git a/CoAuthoring/node_modules/mongodb/lib/mongodb/connection/strategies/statistics_strategy.js b/CoAuthoring/node_modules/mongodb/lib/mongodb/connection/strategies/statistics_strategy.js
deleted file mode 100644
index dac6bb780a..0000000000
--- a/CoAuthoring/node_modules/mongodb/lib/mongodb/connection/strategies/statistics_strategy.js
+++ /dev/null
@@ -1,81 +0,0 @@
-// The Statistics strategy uses the measure of each end-start time for each
-// query executed against the db to calculate the mean, variance and standard deviation
-// and pick the server which the lowest mean and deviation
-var StatisticsStrategy = exports.StatisticsStrategy = function(replicaset) {
- this.replicaset = replicaset;
-}
-
-// Starts any needed code
-StatisticsStrategy.prototype.start = function(callback) {
- callback(null, null);
-}
-
-StatisticsStrategy.prototype.stop = function(callback) {
- // Remove reference to replicaset
- this.replicaset = null;
- // Perform callback
- callback(null, null);
-}
-
-StatisticsStrategy.prototype.checkoutSecondary = function(tags, secondaryCandidates) {
- // Servers are picked based on the lowest ping time and then servers that lower than that + secondaryAcceptableLatencyMS
- // Create a list of candidat servers, containing the primary if available
- var candidateServers = [];
-
- // If we have not provided a list of candidate servers use the default setup
- if(!Array.isArray(secondaryCandidates)) {
- candidateServers = this.replicaset._state.master != null ? [this.replicaset._state.master] : [];
- // Add all the secondaries
- var keys = Object.keys(this.replicaset._state.secondaries);
- for(var i = 0; i < keys.length; i++) {
- candidateServers.push(this.replicaset._state.secondaries[keys[i]])
- }
- } else {
- candidateServers = secondaryCandidates;
- }
-
- // Final list of eligable server
- var finalCandidates = [];
-
- // If we have tags filter by tags
- if(tags != null && typeof tags == 'object') {
- // If we have an array or single tag selection
- var tagObjects = Array.isArray(tags) ? tags : [tags];
- // Iterate over all tags until we find a candidate server
- for(var _i = 0; _i < tagObjects.length; _i++) {
- // Grab a tag object
- var tagObject = tagObjects[_i];
- // Matching keys
- var matchingKeys = Object.keys(tagObject);
- // Remove any that are not tagged correctly
- for(var i = 0; i < candidateServers.length; i++) {
- var server = candidateServers[i];
- // If we have tags match
- if(server.tags != null) {
- var matching = true;
-
- // Ensure we have all the values
- for(var j = 0; j < matchingKeys.length; j++) {
- if(server.tags[matchingKeys[j]] != tagObject[matchingKeys[j]]) {
- matching = false;
- break;
- }
- }
-
- // If we have a match add it to the list of matching servers
- if(matching) {
- finalCandidates.push(server);
- }
- }
- }
- }
- } else {
- // Final array candidates
- var finalCandidates = candidateServers;
- }
-
- // If no candidates available return an error
- if(finalCandidates.length == 0) return new Error("No replica set members available for query");
- // Pick a random server
- return finalCandidates[Math.round(Math.random(1000000) * (finalCandidates.length - 1))].checkoutReader();
-}
diff --git a/CoAuthoring/node_modules/mongodb/lib/mongodb/cursor.js b/CoAuthoring/node_modules/mongodb/lib/mongodb/cursor.js
deleted file mode 100644
index 3a0a47240b..0000000000
--- a/CoAuthoring/node_modules/mongodb/lib/mongodb/cursor.js
+++ /dev/null
@@ -1,805 +0,0 @@
-var QueryCommand = require('./commands/query_command').QueryCommand,
- GetMoreCommand = require('./commands/get_more_command').GetMoreCommand,
- KillCursorCommand = require('./commands/kill_cursor_command').KillCursorCommand,
- Long = require('bson').Long,
- CursorStream = require('./cursorstream'),
- utils = require('./utils');
-
-/**
- * Constructor for a cursor object that handles all the operations on query result
- * using find. This cursor object is unidirectional and cannot traverse backwards. Clients should not be creating a cursor directly,
- * but use find to acquire a cursor.
- *
- * @class Represents a Cursor.
- * @param {Db} db the database object to work with.
- * @param {Collection} collection the collection to query.
- * @param {Object} selector the query selector.
- * @param {Object} fields an object containing what fields to include or exclude from objects returned.
- * @param {Number} skip number of documents to skip.
- * @param {Number} limit the number of results to return. -1 has a special meaning and is used by Db.eval. A value of 1 will also be treated as if it were -1.
- * @param {String|Array|Object} sort the required sorting for the query.
- * @param {Object} hint force the query to use a specific index.
- * @param {Boolean} explain return the explaination of the query.
- * @param {Boolean} snapshot Snapshot mode assures no duplicates are returned.
- * @param {Boolean} timeout allow the query to timeout.
- * @param {Boolean} tailable allow the cursor to be tailable.
- * @param {Boolean} awaitdata allow the cursor to wait for data, only applicable for tailable cursor.
- * @param {Number} batchSize the number of the subset of results to request the database to return for every request. This should initially be greater than 1 otherwise the database will automatically close the cursor. The batch size can be set to 1 with cursorInstance.batchSize after performing the initial query to the database.
- * @param {Boolean} raw return all query documents as raw buffers (default false).
- * @param {Boolean} read specify override of read from source (primary/secondary).
- * @param {Boolean} returnKey only return the index key.
- * @param {Number} maxScan limit the number of items to scan.
- * @param {Number} min set index bounds.
- * @param {Number} max set index bounds.
- * @param {Boolean} showDiskLoc show disk location of results.
- * @param {String} comment you can put a $comment field on a query to make looking in the profiler logs simpler.
- * @param {Boolean} awaitdata allow the cursor to wait for data, only applicable for tailable cursor.
- * @param {Number} numberOfRetries if using awaidata specifies the number of times to retry on timeout.
- * @param {String} dbName override the default dbName.
- */
-function Cursor(db, collection, selector, fields, skip, limit
- , sort, hint, explain, snapshot, timeout, tailable, batchSize, slaveOk, raw, read
- , returnKey, maxScan, min, max, showDiskLoc, comment, awaitdata, numberOfRetries, dbName) {
- this.db = db;
- this.collection = collection;
- this.selector = selector;
- this.fields = fields;
- this.skipValue = skip == null ? 0 : skip;
- this.limitValue = limit == null ? 0 : limit;
- this.sortValue = sort;
- this.hint = hint;
- this.explainValue = explain;
- this.snapshot = snapshot;
- this.timeout = timeout == null ? true : timeout;
- this.tailable = tailable;
- this.awaitdata = awaitdata;
- this.numberOfRetries = numberOfRetries == null ? 1 : numberOfRetries;
- this.batchSizeValue = batchSize == null ? 0 : batchSize;
- this.slaveOk = slaveOk == null ? collection.slaveOk : slaveOk;
- this.raw = raw == null ? false : raw;
- this.read = read == null ? true : read;
- this.returnKey = returnKey;
- this.maxScan = maxScan;
- this.min = min;
- this.max = max;
- this.showDiskLoc = showDiskLoc;
- this.comment = comment;
-
- this.totalNumberOfRecords = 0;
- this.items = [];
- this.cursorId = Long.fromInt(0);
-
- // This name
- this.dbName = dbName;
-
- // State variables for the cursor
- this.state = Cursor.INIT;
- // Keep track of the current query run
- this.queryRun = false;
- this.getMoreTimer = false;
-
- // If we are using a specific db execute against it
- if(this.dbName != null) {
- this.collectionName = this.dbName + "." + this.collection.collectionName;
- } else {
- this.collectionName = (this.db.databaseName ? this.db.databaseName + "." : '') + this.collection.collectionName;
- }
-};
-
-/**
- * Resets this cursor to its initial state. All settings like the query string,
- * tailable, batchSizeValue, skipValue and limits are preserved.
- *
- * @return {Cursor} returns itself with rewind applied.
- * @api public
- */
-Cursor.prototype.rewind = function() {
- var self = this;
-
- if (self.state != Cursor.INIT) {
- if (self.state != Cursor.CLOSED) {
- self.close(function() {});
- }
-
- self.numberOfReturned = 0;
- self.totalNumberOfRecords = 0;
- self.items = [];
- self.cursorId = Long.fromInt(0);
- self.state = Cursor.INIT;
- self.queryRun = false;
- }
-
- return self;
-};
-
-
-/**
- * Returns an array of documents. The caller is responsible for making sure that there
- * is enough memory to store the results. Note that the array only contain partial
- * results when this cursor had been previouly accessed. In that case,
- * cursor.rewind() can be used to reset the cursor.
- *
- * @param {Function} callback This will be called after executing this method successfully. The first paramter will contain the Error object if an error occured, or null otherwise. The second paramter will contain an array of BSON deserialized objects as a result of the query.
- * @return {null}
- * @api public
- */
-Cursor.prototype.toArray = function(callback) {
- var self = this;
-
- if(!callback) {
- throw new Error('callback is mandatory');
- }
-
- if(this.tailable) {
- callback(new Error("Tailable cursor cannot be converted to array"), null);
- } else if(this.state != Cursor.CLOSED) {
- var items = [];
-
- this.each(function(err, item) {
- if(err != null) return callback(err, null);
-
- if (item != null) {
- items.push(item);
- } else {
- var resultItems = items;
- items = null;
- self.items = [];
- // Returns items
- callback(err, resultItems);
- }
- });
- } else {
- callback(new Error("Cursor is closed"), null);
- }
-};
-
-/**
- * Iterates over all the documents for this cursor. As with **{cursor.toArray}**,
- * not all of the elements will be iterated if this cursor had been previouly accessed.
- * In that case, **{cursor.rewind}** can be used to reset the cursor. However, unlike
- * **{cursor.toArray}**, the cursor will only hold a maximum of batch size elements
- * at any given time if batch size is specified. Otherwise, the caller is responsible
- * for making sure that the entire result can fit the memory.
- *
- * @param {Function} callback this will be called for while iterating every document of the query result. The first paramter will contain the Error object if an error occured, or null otherwise. While the second paramter will contain the document.
- * @return {null}
- * @api public
- */
-Cursor.prototype.each = function(callback) {
- var self = this;
-
- if (!callback) {
- throw new Error('callback is mandatory');
- }
-
- if(this.state != Cursor.CLOSED) {
- //FIX: stack overflow (on deep callback) (cred: https://github.com/limp/node-mongodb-native/commit/27da7e4b2af02035847f262b29837a94bbbf6ce2)
- process.nextTick(function(){
- var s = new Date()
- // Fetch the next object until there is no more objects
- self.nextObject(function(err, item) {
- if(err != null) return callback(err, null);
- if(item != null) {
- callback(null, item);
- self.each(callback);
- } else {
- // Close the cursor if done
- self.state = Cursor.CLOSED;
- callback(err, null);
- }
- });
- });
- } else {
- callback(new Error("Cursor is closed"), null);
- }
-};
-
-/**
- * Determines how many result the query for this cursor will return
- *
- * @param {Function} callback this will be after executing this method. The first paramter will contain the Error object if an error occured, or null otherwise. While the second paramter will contain the number of results or null if an error occured.
- * @return {null}
- * @api public
- */
-Cursor.prototype.count = function(callback) {
- this.collection.count(this.selector, callback);
-};
-
-/**
- * Sets the sort parameter of this cursor to the given value.
- *
- * This method has the following method signatures:
- * (keyOrList, callback)
- * (keyOrList, direction, callback)
- *
- * @param {String|Array|Object} keyOrList This can be a string or an array. If passed as a string, the string will be the field to sort. If passed an array, each element will represent a field to be sorted and should be an array that contains the format [string, direction].
- * @param {String|Number} direction this determines how the results are sorted. "asc", "ascending" or 1 for asceding order while "desc", "desceding or -1 for descending order. Note that the strings are case insensitive.
- * @param {Function} callback this will be called after executing this method. The first parameter will contain an error object when the cursor is already closed while the second parameter will contain a reference to this object upon successful execution.
- * @return {Cursor} an instance of this object.
- * @api public
- */
-Cursor.prototype.sort = function(keyOrList, direction, callback) {
- callback = callback || function(){};
- if(typeof direction === "function") { callback = direction; direction = null; }
-
- if(this.tailable) {
- callback(new Error("Tailable cursor doesn't support sorting"), null);
- } else if(this.queryRun == true || this.state == Cursor.CLOSED) {
- callback(new Error("Cursor is closed"), null);
- } else {
- var order = keyOrList;
-
- if(direction != null) {
- order = [[keyOrList, direction]];
- }
-
- this.sortValue = order;
- callback(null, this);
- }
- return this;
-};
-
-/**
- * Sets the limit parameter of this cursor to the given value.
- *
- * @param {Number} limit the new limit.
- * @param {Function} [callback] this optional callback will be called after executing this method. The first parameter will contain an error object when the limit given is not a valid number or when the cursor is already closed while the second parameter will contain a reference to this object upon successful execution.
- * @return {Cursor} an instance of this object.
- * @api public
- */
-Cursor.prototype.limit = function(limit, callback) {
- if(this.tailable) {
- if(callback) {
- callback(new Error("Tailable cursor doesn't support limit"), null);
- } else {
- throw new Error("Tailable cursor doesn't support limit");
- }
- } else if(this.queryRun == true || this.state == Cursor.CLOSED) {
- if(callback) {
- callback(new Error("Cursor is closed"), null);
- } else {
- throw new Error("Cursor is closed");
- }
- } else {
- if(limit != null && limit.constructor != Number) {
- if(callback) {
- callback(new Error("limit requires an integer"), null);
- } else {
- throw new Error("limit requires an integer");
- }
- } else {
- this.limitValue = limit;
- if(callback) return callback(null, this);
- }
- }
-
- return this;
-};
-
-/**
- * Sets the read preference for the cursor
- *
- * @param {String} the read preference for the cursor, one of Server.READ_PRIMARY, Server.READ_SECONDARY, Server.READ_SECONDARY_ONLY
- * @param {Function} [callback] this optional callback will be called after executing this method. The first parameter will contain an error object when the read preference given is not a valid number or when the cursor is already closed while the second parameter will contain a reference to this object upon successful execution.
- * @return {Cursor} an instance of this object.
- * @api public
- */
-Cursor.prototype.setReadPreference = function(readPreference, tags, callback) {
- if(typeof tags == 'function') callback = tags;
- callback = callback || function() {};
-
- if(this.queryRun == true || this.state == Cursor.CLOSED) {
- callback(new Error("Cannot change read preference on executed query or closed cursor"));
- } else if(readPreference == null && readPreference != 'primary'
- && readPreference != 'secondaryOnly' && readPreference != 'secondary') {
- callback(new Error("only readPreference of primary, secondary or secondaryOnly supported"));
- } else {
- this.read = readPreference;
- }
-
- return this;
-}
-
-/**
- * Sets the skip parameter of this cursor to the given value.
- *
- * @param {Number} skip the new skip value.
- * @param {Function} [callback] this optional callback will be called after executing this method. The first parameter will contain an error object when the skip value given is not a valid number or when the cursor is already closed while the second parameter will contain a reference to this object upon successful execution.
- * @return {Cursor} an instance of this object.
- * @api public
- */
-Cursor.prototype.skip = function(skip, callback) {
- callback = callback || function(){};
-
- if(this.tailable) {
- callback(new Error("Tailable cursor doesn't support skip"), null);
- } else if(this.queryRun == true || this.state == Cursor.CLOSED) {
- callback(new Error("Cursor is closed"), null);
- } else {
- if(skip != null && skip.constructor != Number) {
- callback(new Error("skip requires an integer"), null);
- } else {
- this.skipValue = skip;
- callback(null, this);
- }
- }
-
- return this;
-};
-
-/**
- * Sets the batch size parameter of this cursor to the given value.
- *
- * @param {Number} batchSize the new batch size.
- * @param {Function} [callback] this optional callback will be called after executing this method. The first parameter will contain an error object when the batchSize given is not a valid number or when the cursor is already closed while the second parameter will contain a reference to this object upon successful execution.
- * @return {Cursor} an instance of this object.
- * @api public
- */
-Cursor.prototype.batchSize = function(batchSize, callback) {
- if(this.state == Cursor.CLOSED) {
- if(callback != null) {
- return callback(new Error("Cursor is closed"), null);
- } else {
- throw new Error("Cursor is closed");
- }
- } else if(batchSize != null && batchSize.constructor != Number) {
- if(callback != null) {
- return callback(new Error("batchSize requires an integer"), null);
- } else {
- throw new Error("batchSize requires an integer");
- }
- } else {
- this.batchSizeValue = batchSize;
- if(callback != null) return callback(null, this);
- }
-
- return this;
-};
-
-/**
- * The limit used for the getMore command
- *
- * @return {Number} The number of records to request per batch.
- * @ignore
- * @api private
- */
-var limitRequest = function(self) {
- var requestedLimit = self.limitValue;
- var absLimitValue = Math.abs(self.limitValue);
- var absBatchValue = Math.abs(self.batchSizeValue);
-
- if(absLimitValue > 0) {
- if (absBatchValue > 0) {
- requestedLimit = Math.min(absLimitValue, absBatchValue);
- }
- } else {
- requestedLimit = self.batchSizeValue;
- }
-
- return requestedLimit;
-};
-
-
-/**
- * Generates a QueryCommand object using the parameters of this cursor.
- *
- * @return {QueryCommand} The command object
- * @ignore
- * @api private
- */
-var generateQueryCommand = function(self) {
- // Unpack the options
- var queryOptions = QueryCommand.OPTS_NONE;
- if(!self.timeout) {
- queryOptions |= QueryCommand.OPTS_NO_CURSOR_TIMEOUT;
- }
-
- if(self.tailable != null) {
- queryOptions |= QueryCommand.OPTS_TAILABLE_CURSOR;
- self.skipValue = self.limitValue = 0;
-
- // if awaitdata is set
- if(self.awaitdata != null) {
- queryOptions |= QueryCommand.OPTS_AWAIT_DATA;
- }
- }
-
- if(self.slaveOk) {
- queryOptions |= QueryCommand.OPTS_SLAVE;
- }
-
- // limitValue of -1 is a special case used by Db#eval
- var numberToReturn = self.limitValue == -1 ? -1 : limitRequest(self);
-
- // Check if we need a special selector
- if(self.sortValue != null || self.explainValue != null || self.hint != null || self.snapshot != null
- || self.returnKey != null || self.maxScan != null || self.min != null || self.max != null
- || self.showDiskLoc != null || self.comment != null) {
-
- // Build special selector
- var specialSelector = {'$query':self.selector};
- if(self.sortValue != null) specialSelector['orderby'] = utils.formattedOrderClause(self.sortValue);
- if(self.hint != null && self.hint.constructor == Object) specialSelector['$hint'] = self.hint;
- if(self.snapshot != null) specialSelector['$snapshot'] = true;
- if(self.returnKey != null) specialSelector['$returnKey'] = self.returnKey;
- if(self.maxScan != null) specialSelector['$maxScan'] = self.maxScan;
- if(self.min != null) specialSelector['$min'] = self.min;
- if(self.max != null) specialSelector['$max'] = self.max;
- if(self.showDiskLoc != null) specialSelector['$showDiskLoc'] = self.showDiskLoc;
- if(self.comment != null) specialSelector['$comment'] = self.comment;
- // If we have explain set only return a single document with automatic cursor close
- if(self.explainValue != null) {
- numberToReturn = (-1)*Math.abs(numberToReturn);
- specialSelector['$explain'] = true;
- }
-
- // Return the query
- return new QueryCommand(self.db, self.collectionName, queryOptions, self.skipValue, numberToReturn, specialSelector, self.fields);
- } else {
- return new QueryCommand(self.db, self.collectionName, queryOptions, self.skipValue, numberToReturn, self.selector, self.fields);
- }
-};
-
-/**
- * @return {Object} Returns an object containing the sort value of this cursor with
- * the proper formatting that can be used internally in this cursor.
- * @ignore
- * @api private
- */
-Cursor.prototype.formattedOrderClause = function() {
- return utils.formattedOrderClause(this.sortValue);
-};
-
-/**
- * Converts the value of the sort direction into its equivalent numerical value.
- *
- * @param sortDirection {String|number} Range of acceptable values:
- * 'ascending', 'descending', 'asc', 'desc', 1, -1
- *
- * @return {number} The equivalent numerical value
- * @throws Error if the given sortDirection is invalid
- * @ignore
- * @api private
- */
-Cursor.prototype.formatSortValue = function(sortDirection) {
- return utils.formatSortValue(sortDirection);
-};
-
-/**
- * Gets the next document from the cursor.
- *
- * @param {Function} callback this will be called after executing this method. The first parameter will contain an error object on error while the second parameter will contain a document from the returned result or null if there are no more results.
- * @api public
- */
-Cursor.prototype.nextObject = function(callback) {
- var self = this;
-
- if(self.state == Cursor.INIT) {
- var cmd;
- try {
- cmd = generateQueryCommand(self);
- } catch (err) {
- return callback(err, null);
- }
-
- var commandHandler = function(err, result) {
- if(err != null && result == null) return callback(err, null);
-
- if(!err && result.documents[0] && result.documents[0]['$err']) {
- return self.close(function() {callback(result.documents[0]['$err'], null);});
- }
-
- self.queryRun = true;
- self.state = Cursor.OPEN; // Adjust the state of the cursor
- self.cursorId = result.cursorId;
- self.totalNumberOfRecords = result.numberReturned;
-
- // Add the new documents to the list of items, using forloop to avoid
- // new array allocations and copying
- for(var i = 0; i < result.documents.length; i++) {
- self.items.push(result.documents[i]);
- }
-
- result = null;
- self.nextObject(callback);
- };
-
- // If we have no connection set on this cursor check one out
- if(self.connection == null) {
- try {
- self.connection = this.read == null ? self.db.serverConfig.checkoutWriter() : self.db.serverConfig.checkoutReader(this.read);
- } catch(err) {
- return callback(err, null);
- }
- }
-
- // Execute the command
- self.db._executeQueryCommand(cmd, {raw:self.raw, read:this.read, connection:self.connection}, commandHandler);
- // Set the command handler to null
- commandHandler = null;
- } else if(self.items.length) {
- callback(null, self.items.shift());
- } else if(self.cursorId.greaterThan(Long.fromInt(0))) {
- getMore(self, callback);
- } else {
- // Force cursor to stay open
- return self.close(function() {callback(null, null);});
- }
-}
-
-/**
- * Gets more results from the database if any.
- *
- * @param {Function} callback this will be called after executing this method. The first parameter will contain an error object on error while the second parameter will contain a document from the returned result or null if there are no more results.
- * @ignore
- * @api private
- */
-var getMore = function(self, callback) {
- var limit = 0;
-
- if (!self.tailable && self.limitValue > 0) {
- limit = self.limitValue - self.totalNumberOfRecords;
- if (limit < 1) {
- self.close(function() {callback(null, null);});
- return;
- }
- }
- try {
- var getMoreCommand = new GetMoreCommand(
- self.db
- , self.collectionName
- , limitRequest(self)
- , self.cursorId
- );
-
- // Set up options
- var options = { read: self.read, raw: self.raw, connection:self.connection };
-
- // Execute the command
- self.db._executeQueryCommand(getMoreCommand, options, function(err, result) {
- try {
- if(err != null) {
- return callback(err, null);
- }
-
- var isDead = 1 === result.responseFlag && result.cursorId.isZero();
-
- self.cursorId = result.cursorId;
- self.totalNumberOfRecords += result.numberReturned;
-
- // Determine if there's more documents to fetch
- if(result.numberReturned > 0) {
- if (self.limitValue > 0) {
- var excessResult = self.totalNumberOfRecords - self.limitValue;
-
- if (excessResult > 0) {
- result.documents.splice(-1 * excessResult, excessResult);
- }
- }
-
- self.items = self.items.concat(result.documents);
- // result = null;
- callback(null, self.items.shift());
- } else if(self.tailable && !isDead && self.awaitdata) {
- // Excute the tailable cursor once more, will timeout after ~4 sec if awaitdata used
- self.numberOfRetries = self.numberOfRetries - 1;
- if(self.numberOfRetries == 0) {
- self.close(function() {
- callback(new Error("tailable cursor timed out"), null);
- });
- } else {
- process.nextTick(function() {getMore(self, callback);});
- }
- } else if(self.tailable && !isDead) {
- self.getMoreTimer = setTimeout(function() {getMore(self, callback);}, 100);
- } else {
- self.close(function() {callback(null, null);});
- }
-
- result = null;
- } catch(err) {
- callback(err, null);
- }
- });
-
- getMoreCommand = null;
- } catch(err) {
- var handleClose = function() {
- callback(err, null);
- };
-
- self.close(handleClose);
- handleClose = null;
- }
-}
-
-/**
- * Gets a detailed information about how the query is performed on this cursor and how
- * long it took the database to process it.
- *
- * @param {Function} callback this will be called after executing this method. The first parameter will always be null while the second parameter will be an object containing the details.
- * @api public
- */
-Cursor.prototype.explain = function(callback) {
- var limit = (-1)*Math.abs(this.limitValue);
- // Create a new cursor and fetch the plan
- var cursor = new Cursor(this.db, this.collection, this.selector, this.fields, this.skipValue, limit
- , this.sortValue, this.hint, true, this.snapshot, this.timeout, this.tailable, this.batchSizeValue
- , this.slaveOk, this.raw, this.read, this.returnKey, this.maxScan, this.min, this.max, this.showDiskLoc
- , this.comment, this.awaitdata, this.numberOfRetries, this.dbName);
- // Fetch the explaination document
- cursor.nextObject(function(err, item) {
- if(err != null) return callback(err, null);
- // close the cursor
- cursor.close(function(err, result) {
- if(err != null) return callback(err, null);
- callback(null, item);
- });
- });
-};
-
-/**
- * Returns a stream object that can be used to listen to and stream records
- * (**Use the CursorStream object instead as this is deprected**)
- *
- * Options
- * - **fetchSize** {Number} the number of records to fetch in each batch (steam specific batchSize).
- *
- * Events
- * - **data** {function(item) {}} the data event triggers when a document is ready.
- * - **error** {function(err) {}} the error event triggers if an error happens.
- * - **end** {function() {}} the end event triggers when there is no more documents available.
- *
- * @param {Object} [options] additional options for streamRecords.
- * @return {EventEmitter} returns a stream object.
- * @api public
- */
-Cursor.prototype.streamRecords = function(options) {
- var args = Array.prototype.slice.call(arguments, 0);
- options = args.length ? args.shift() : {};
-
- var
- self = this,
- stream = new process.EventEmitter(),
- recordLimitValue = this.limitValue || 0,
- emittedRecordCount = 0,
- queryCommand = generateQueryCommand(self);
-
- // see http://www.mongodb.org/display/DOCS/Mongo+Wire+Protocol
- queryCommand.numberToReturn = options.fetchSize ? options.fetchSize : 500;
- // Execute the query
- execute(queryCommand);
-
- function execute(command) {
- self.db._executeQueryCommand(command, {read:self.read, raw:self.raw, connection:self.connection}, function(err,result) {
- if(err) {
- stream.emit('error', err);
- self.close(function(){});
- return;
- }
-
- if (!self.queryRun && result) {
- self.queryRun = true;
- self.cursorId = result.cursorId;
- self.state = Cursor.OPEN;
- self.getMoreCommand = new GetMoreCommand(self.db, self.collectionName, queryCommand.numberToReturn, result.cursorId);
- }
-
- var resflagsMap = {
- CursorNotFound:1<<0,
- QueryFailure:1<<1,
- ShardConfigStale:1<<2,
- AwaitCapable:1<<3
- };
-
- if(result.documents && result.documents.length && !(result.responseFlag & resflagsMap.QueryFailure)) {
- try {
- result.documents.forEach(function(doc){
- if(recordLimitValue && emittedRecordCount>=recordLimitValue) {
- throw("done");
- }
- emittedRecordCount++;
- stream.emit('data', doc);
- });
- } catch(err) {
- if (err != "done") { throw err; }
- else {
- self.close(function(){
- stream.emit('end', recordLimitValue);
- });
- self.close(function(){});
- return;
- }
- }
- // rinse & repeat
- execute(self.getMoreCommand);
- } else {
- self.close(function(){
- stream.emit('end', recordLimitValue);
- });
- }
- });
- }
-
- return stream;
-};
-
-/**
- * Returns a Node ReadStream interface for this cursor.
- *
- * @return {CursorStream} returns a stream object.
- * @api public
- */
-Cursor.prototype.stream = function stream () {
- return new CursorStream(this);
-}
-
-/**
- * Close the cursor.
- *
- * @param {Function} callback this will be called after executing this method. The first parameter will always contain null while the second parameter will contain a reference to this cursor.
- * @return {null}
- * @api public
- */
-Cursor.prototype.close = function(callback) {
- var self = this
- this.getMoreTimer && clearTimeout(this.getMoreTimer);
- // Close the cursor if not needed
- if(this.cursorId instanceof Long && this.cursorId.greaterThan(Long.fromInt(0))) {
- try {
- var command = new KillCursorCommand(this.db, [this.cursorId]);
- this.db._executeQueryCommand(command, {read:self.read, raw:self.raw, connection:self.connection}, null);
- } catch(err) {}
- }
-
- // Null out the connection
- self.connection = null;
- // Reset cursor id
- this.cursorId = Long.fromInt(0);
- // Set to closed status
- this.state = Cursor.CLOSED;
-
- if(callback) {
- callback(null, self);
- self.items = [];
- }
-
- return this;
-};
-
-/**
- * Check if the cursor is closed or open.
- *
- * @return {Boolean} returns the state of the cursor.
- * @api public
- */
-Cursor.prototype.isClosed = function() {
- return this.state == Cursor.CLOSED ? true : false;
-};
-
-/**
- * Init state
- *
- * @classconstant INIT
- **/
-Cursor.INIT = 0;
-
-/**
- * Cursor open
- *
- * @classconstant OPEN
- **/
-Cursor.OPEN = 1;
-
-/**
- * Cursor closed
- *
- * @classconstant CLOSED
- **/
-Cursor.CLOSED = 2;
-
-/**
- * @ignore
- * @api private
- */
-exports.Cursor = Cursor;
diff --git a/CoAuthoring/node_modules/mongodb/lib/mongodb/cursorstream.js b/CoAuthoring/node_modules/mongodb/lib/mongodb/cursorstream.js
deleted file mode 100644
index 3839fc69db..0000000000
--- a/CoAuthoring/node_modules/mongodb/lib/mongodb/cursorstream.js
+++ /dev/null
@@ -1,141 +0,0 @@
-/**
- * Module dependecies.
- */
-var Stream = require('stream').Stream;
-
-/**
- * CursorStream
- *
- * Returns a stream interface for the **cursor**.
- *
- * Events
- * - **data** {function(item) {}} the data event triggers when a document is ready.
- * - **error** {function(err) {}} the error event triggers if an error happens.
- * - **close** {function() {}} the end event triggers when there is no more documents available.
- *
- * @class Represents a CursorStream.
- * @param {Cursor} cursor a cursor object that the stream wraps.
- * @return {Stream}
- */
-function CursorStream(cursor) {
- if(!(this instanceof CursorStream)) return new CursorStream(cursor);
-
- Stream.call(this);
-
- this.readable = true;
- this.paused = false;
- this._cursor = cursor;
- this._destroyed = null;
-
- // give time to hook up events
- var self = this;
- process.nextTick(function () {
- self._init();
- });
-}
-
-/**
- * Inherit from Stream
- * @ignore
- * @api private
- */
-CursorStream.prototype.__proto__ = Stream.prototype;
-
-/**
- * Flag stating whether or not this stream is readable.
- */
-CursorStream.prototype.readable;
-
-/**
- * Flag stating whether or not this stream is paused.
- */
-CursorStream.prototype.paused;
-
-/**
- * Initialize the cursor.
- * @ignore
- * @api private
- */
-CursorStream.prototype._init = function () {
- if (this._destroyed) return;
- this._next();
-}
-
-/**
- * Pull the next document from the cursor.
- * @ignore
- * @api private
- */
-CursorStream.prototype._next = function () {
- if (this.paused || this._destroyed) return;
-
- var self = this;
-
- // nextTick is necessary to avoid stack overflows when
- // dealing with large result sets.
- process.nextTick(function () {
- self._cursor.nextObject(function (err, doc) {
- self._onNextObject(err, doc);
- });
- });
-}
-
-/**
- * Handle each document as its returned from the cursor.
- * @ignore
- * @api private
- */
-CursorStream.prototype._onNextObject = function (err, doc) {
- if (err) return this.destroy(err);
-
- // when doc is null we hit the end of the cursor
- if (!doc) return this.destroy();
-
- this.emit('data', doc);
- this._next();
-}
-
-/**
- * Pauses the stream.
- *
- * @api public
- */
-CursorStream.prototype.pause = function () {
- this.paused = true;
-}
-
-/**
- * Resumes the stream.
- *
- * @api public
- */
-CursorStream.prototype.resume = function () {
- this.paused = false;
- this._next();
-}
-
-/**
- * Destroys the stream, closing the underlying
- * cursor. No more events will be emitted.
- *
- * @api public
- */
-CursorStream.prototype.destroy = function (err) {
- if (this._destroyed) return;
- this._destroyed = true;
- this.readable = false;
-
- this._cursor.close();
-
- if (err) {
- this.emit('error', err);
- }
-
- this.emit('close');
-}
-
-// TODO - maybe implement the raw option to pass binary?
-//CursorStream.prototype.setEncoding = function () {
-//}
-
-module.exports = exports = CursorStream;
diff --git a/CoAuthoring/node_modules/mongodb/lib/mongodb/db.js b/CoAuthoring/node_modules/mongodb/lib/mongodb/db.js
deleted file mode 100644
index f7a3e6388d..0000000000
--- a/CoAuthoring/node_modules/mongodb/lib/mongodb/db.js
+++ /dev/null
@@ -1,2066 +0,0 @@
-/**
- * Module dependencies.
- * @ignore
- */
-var QueryCommand = require('./commands/query_command').QueryCommand,
- DbCommand = require('./commands/db_command').DbCommand,
- MongoReply = require('./responses/mongo_reply').MongoReply,
- Admin = require('./admin').Admin,
- Collection = require('./collection').Collection,
- Server = require('./connection/server').Server,
- ReplSet = require('./connection/repl_set').ReplSet,
- ReadPreference = require('./connection/read_preference').ReadPreference,
- Mongos = require('./connection/mongos').Mongos,
- Cursor = require('./cursor').Cursor,
- EventEmitter = require('events').EventEmitter,
- inherits = require('util').inherits,
- crypto = require('crypto');
-
-/**
- * Internal class for callback storage
- * @ignore
- */
-var CallbackStore = function() {
- // Make class an event emitter
- EventEmitter.call(this);
- // Add a info about call variable
- this._notReplied = {};
-}
-
-/**
- * @ignore
- */
-inherits(CallbackStore, EventEmitter);
-
-/**
- * Create a new Db instance.
- *
- * Options
- * - **strict** {true | {w:n, wtimeout:n} | {fsync:true}, default:false}, execute insert with a getLastError command returning the result of the insert command.
- * - **readPreference** {String}, the prefered read preference (ReadPreference.PRIMARY, ReadPreference.PRIMARY_PREFERRED, ReadPreference.SECONDARY, ReadPreference.SECONDARY_PREFERRED, ReadPreference.NEAREST).
- * - **native_parser** {Boolean, default:false}, use c++ bson parser.
- * - **forceServerObjectId** {Boolean, default:false}, force server to create _id fields instead of client.
- * - **pkFactory** {Object}, object overriding the basic ObjectID primary key generation.
- * - **serializeFunctions** {Boolean, default:false}, serialize functions.
- * - **raw** {Boolean, default:false}, peform operations using raw bson buffers.
- * - **recordQueryStats** {Boolean, default:false}, record query statistics during execution.
- * - **reaper** {Boolean, default:false}, enables the reaper, timing out calls that never return.
- * - **reaperInterval** {Number, default:10000}, number of miliseconds between reaper wakups.
- * - **reaperTimeout** {Number, default:30000}, the amount of time before a callback times out.
- * - **retryMiliSeconds** {Number, default:5000}, number of miliseconds between retries.
- * - **numberOfRetries** {Number, default:5}, number of retries off connection.
- *
- * @class Represents a Collection
- * @param {String} databaseName name of the database.
- * @param {Object} serverConfig server config object.
- * @param {Object} [options] additional options for the collection.
- */
-function Db(databaseName, serverConfig, options) {
-
- if(!(this instanceof Db)) return new Db(databaseName, serverConfig, options);
-
- EventEmitter.call(this);
- this.databaseName = databaseName;
- this.serverConfig = serverConfig;
- this.options = options == null ? {} : options;
- // State to check against if the user force closed db
- this._applicationClosed = false;
- // Fetch the override flag if any
- var overrideUsedFlag = this.options['override_used_flag'] == null ? false : this.options['override_used_flag'];
- // Verify that nobody is using this config
- if(!overrideUsedFlag && typeof this.serverConfig == 'object' && this.serverConfig._isUsed()) {
- throw new Error("A Server or ReplSet instance cannot be shared across multiple Db instances");
- } else if(!overrideUsedFlag && typeof this.serverConfig == 'object'){
- // Set being used
- this.serverConfig._used = true;
- }
-
- // Ensure we have a valid db name
- validateDatabaseName(databaseName);
-
- // Contains all the connections for the db
- try {
- this.native_parser = this.options.native_parser;
- // The bson lib
- var bsonLib = this.bsonLib = this.options.native_parser ? require('bson').BSONNative : new require('bson').BSONPure;
- // Fetch the serializer object
- var BSON = bsonLib.BSON;
- // Create a new instance
- this.bson = new BSON([bsonLib.Long, bsonLib.ObjectID, bsonLib.Binary, bsonLib.Code, bsonLib.DBRef, bsonLib.Symbol, bsonLib.Double, bsonLib.Timestamp, bsonLib.MaxKey, bsonLib.MinKey]);
- // Backward compatibility to access types
- this.bson_deserializer = bsonLib;
- this.bson_serializer = bsonLib;
- } catch (err) {
- // If we tried to instantiate the native driver
- var msg = "Native bson parser not compiled, please compile "
- + "or avoid using native_parser=true";
- throw Error(msg);
- }
-
- // Internal state of the server
- this._state = 'disconnected';
-
- this.pkFactory = this.options.pk == null ? bsonLib.ObjectID : this.options.pk;
- this.forceServerObjectId = this.options.forceServerObjectId != null ? this.options.forceServerObjectId : false;
- // Added strict
- this.strict = this.options.strict == null ? false : this.options.strict;
- this.notReplied ={};
- this.isInitializing = true;
- this.auths = [];
- this.openCalled = false;
-
- // Command queue, keeps a list of incoming commands that need to be executed once the connection is up
- this.commands = [];
-
- // Contains all the callbacks
- this._callBackStore = new CallbackStore();
-
- // Set up logger
- this.logger = this.options.logger != null
- && (typeof this.options.logger.debug == 'function')
- && (typeof this.options.logger.error == 'function')
- && (typeof this.options.logger.log == 'function')
- ? this.options.logger : {error:function(message, object) {}, log:function(message, object) {}, debug:function(message, object) {}};
- // Allow slaveOk
- this.slaveOk = this.options["slave_ok"] == null ? false : this.options["slave_ok"];
-
- var self = this;
- // Associate the logger with the server config
- this.serverConfig.logger = this.logger;
- this.tag = new Date().getTime();
- // Just keeps list of events we allow
- this.eventHandlers = {error:[], parseError:[], poolReady:[], message:[], close:[]};
-
- // Controls serialization options
- this.serializeFunctions = this.options.serializeFunctions != null ? this.options.serializeFunctions : false;
-
- // Raw mode
- this.raw = this.options.raw != null ? this.options.raw : false;
-
- // Record query stats
- this.recordQueryStats = this.options.recordQueryStats != null ? this.options.recordQueryStats : false;
-
- // If we have server stats let's make sure the driver objects have it enabled
- if(this.recordQueryStats == true) {
- this.serverConfig.enableRecordQueryStats(true);
- }
-
- // Reaper enable setting
- this.reaperEnabled = this.options.reaper != null ? this.options.reaper : false;
- this._lastReaperTimestamp = new Date().getTime();
-
- // Retry information
- this.retryMiliSeconds = this.options.retryMiliSeconds != null ? this.options.retryMiliSeconds : 1000;
- this.numberOfRetries = this.options.numberOfRetries != null ? this.options.numberOfRetries : 60;
-
- // Reaper information
- this.reaperInterval = this.options.reaperInterval != null ? this.options.reaperInterval : 10000;
- this.reaperTimeout = this.options.reaperTimeout != null ? this.options.reaperTimeout : 30000;
-
- // Set default read preference if any
- this.readPreference = this.options.readPreference;
-};
-
-/**
- * The reaper cleans up any callbacks that have not returned inside the space set by
- * the parameter reaperTimeout, it will only attempt to reap if the time since last reap
- * is bigger or equal to the reaperInterval value
- * @ignore
- */
-var reaper = function(dbInstance, reaperInterval, reaperTimeout) {
- // Get current time, compare to reaper interval
- var currentTime = new Date().getTime();
- // Now calculate current time difference to check if it's time to reap
- if((currentTime - dbInstance._lastReaperTimestamp) >= reaperInterval) {
- // Save current timestamp for next reaper iteration
- dbInstance._lastReaperTimestamp = currentTime;
- // Get all non-replied to messages
- var keys = Object.keys(dbInstance._callBackStore._notReplied);
- // Iterate over all callbacks
- for(var i = 0; i < keys.length; i++) {
- // Fetch the current key
- var key = keys[i];
- // Get info element
- var info = dbInstance._callBackStore._notReplied[key];
- // If it's timed out let's remove the callback and return an error
- if((currentTime - info.start) > reaperTimeout) {
- // Cleanup
- delete dbInstance._callBackStore._notReplied[key];
- // Perform callback in next Tick
- process.nextTick(function() {
- dbInstance._callBackStore.emit(key, new Error("operation timed out"), null);
- });
- }
- }
- // Return reaping was done
- return true;
- } else {
- // No reaping done
- return false;
- }
-}
-
-/**
- * @ignore
- */
-function validateDatabaseName(databaseName) {
- if(typeof databaseName !== 'string') throw new Error("database name must be a string");
- if(databaseName.length === 0) throw new Error("database name cannot be the empty string");
-
- var invalidChars = [" ", ".", "$", "/", "\\"];
- for(var i = 0; i < invalidChars.length; i++) {
- if(databaseName.indexOf(invalidChars[i]) != -1) throw new Error("database names cannot contain the character '" + invalidChars[i] + "'");
- }
-}
-
-/**
- * @ignore
- */
-inherits(Db, EventEmitter);
-
-/**
- * Initialize the database connection.
- *
- * @param {Function} callback returns index information.
- * @return {null}
- * @api public
- */
-Db.prototype.open = function(callback) {
- var self = this;
-
- // Check that the user has not called this twice
- if(this.openCalled) {
- // Close db
- this.close();
- // Throw error
- throw new Error("db object already connecting, open cannot be called multiple times");
- }
-
- // If we have a specified read preference
- if(this.readPreference != null) this.serverConfig.setReadPreference(this.readPreference);
-
- // Set that db has been opened
- this.openCalled = true;
- // Set the status of the server
- self._state = 'connecting';
- // Set up connections
- if(self.serverConfig instanceof Server || self.serverConfig instanceof ReplSet || self.serverConfig instanceof Mongos) {
- self.serverConfig.connect(self, {firstCall: true}, function(err, result) {
- if(err != null) {
- // Set that db has been closed
- self.openCalled = false;
- // Return error from connection
- return callback(err, null);
- }
- // Set the status of the server
- self._state = 'connected';
- // Callback
- return callback(null, self);
- });
- } else {
- return callback(Error("Server parameter must be of type Server, ReplSet or Mongos"), null);
- }
-};
-
-/**
- * Create a new Db instance sharing the current socket connections.
- *
- * @param {String} dbName the name of the database we want to use.
- * @return {Db} a db instance using the new database.
- * @api public
- */
-Db.prototype.db = function(dbName) {
- // Copy the options and add out internal override of the not shared flag
- var options = {};
- for(var key in this.options) {
- options[key] = this.options[key];
- }
- // Add override flag
- options['override_used_flag'] = true;
- // Create a new db instance
- var newDbInstance = new Db(dbName, this.serverConfig, options);
- //copy over any auths, we may need them for reconnecting
- if (this.serverConfig.db) {
- newDbInstance.auths = this.serverConfig.db.auths;
- }
- // Add the instance to the list of approved db instances
- var allServerInstances = this.serverConfig.allServerInstances();
- // Add ourselves to all server callback instances
- for(var i = 0; i < allServerInstances.length; i++) {
- var server = allServerInstances[i];
- server.dbInstances.push(newDbInstance);
- }
- // Return new db object
- return newDbInstance;
-}
-
-/**
- * Close the current db connection, including all the child db instances. Emits close event if no callback is provided.
- *
- * @param {Boolean} [forceClose] connection can never be reused.
- * @param {Function} [callback] returns the results.
- * @return {null}
- * @api public
- */
-Db.prototype.close = function(forceClose, callback) {
- var self = this;
- // Ensure we force close all connections
- this._applicationClosed = false;
-
- if(typeof forceClose == 'function') {
- callback = forceClose;
- } else if(typeof forceClose == 'boolean') {
- this._applicationClosed = forceClose;
- }
-
- // Remove all listeners and close the connection
- this.serverConfig.close(function(err, result) {
- // Emit the close event
- if(typeof callback !== 'function') self.emit("close");
-
- // Emit close event across all db instances sharing the sockets
- var allServerInstances = self.serverConfig.allServerInstances();
- // Fetch the first server instance
- if(Array.isArray(allServerInstances) && allServerInstances.length > 0) {
- var server = allServerInstances[0];
- // For all db instances signal all db instances
- if(Array.isArray(server.dbInstances) && server.dbInstances.length > 1) {
- for(var i = 0; i < server.dbInstances.length; i++) {
- var dbInstance = server.dbInstances[i];
- // Check if it's our current db instance and skip if it is
- if(dbInstance.databaseName !== self.databaseName && dbInstance.tag !== self.tag) {
- server.dbInstances[i].emit("close");
- }
- }
- }
- }
-
- // Remove all listeners
- self.removeAllEventListeners();
- // You can reuse the db as everything is shut down
- self.openCalled = false;
- // If we have a callback call it
- if(callback) callback(err, result);
- });
-};
-
-/**
- * Access the Admin database
- *
- * @param {Function} [callback] returns the results.
- * @return {Admin} the admin db object.
- * @api public
- */
-Db.prototype.admin = function(callback) {
- if(callback == null) return new Admin(this);
- callback(null, new Admin(this));
-};
-
-/**
- * Returns a cursor to all the collection information.
- *
- * @param {String} [collectionName] the collection name we wish to retrieve the information from.
- * @param {Function} callback returns option results.
- * @return {null}
- * @api public
- */
-Db.prototype.collectionsInfo = function(collectionName, callback) {
- if(callback == null && typeof collectionName == 'function') { callback = collectionName; collectionName = null; }
- // Create selector
- var selector = {};
- // If we are limiting the access to a specific collection name
- if(collectionName != null) selector.name = this.databaseName + "." + collectionName;
-
- // Return Cursor
- // callback for backward compatibility
- if(callback) {
- callback(null, new Cursor(this, new Collection(this, DbCommand.SYSTEM_NAMESPACE_COLLECTION), selector));
- } else {
- return new Cursor(this, new Collection(this, DbCommand.SYSTEM_NAMESPACE_COLLECTION), selector);
- }
-};
-
-/**
- * Get the list of all collection names for the specified db
- *
- * Options
- * - **namesOnly** {String, default:false}, Return only the full collection namespace.
- *
- * @param {String} [collectionName] the collection name we wish to filter by.
- * @param {Object} [options] additional options during update.
- * @param {Function} callback returns option results.
- * @return {null}
- * @api public
- */
-Db.prototype.collectionNames = function(collectionName, options, callback) {
- var self = this;
- var args = Array.prototype.slice.call(arguments, 0);
- callback = args.pop();
- collectionName = args.length ? args.shift() : null;
- options = args.length ? args.shift() : {};
-
- // Ensure no breaking behavior
- if(collectionName != null && typeof collectionName == 'object') {
- options = collectionName;
- collectionName = null;
- }
-
- // Let's make our own callback to reuse the existing collections info method
- self.collectionsInfo(collectionName, function(err, cursor) {
- if(err != null) return callback(err, null);
-
- cursor.toArray(function(err, documents) {
- if(err != null) return callback(err, null);
-
- // List of result documents that have been filtered
- var filtered_documents = documents.filter(function(document) {
- return !(document.name.indexOf(self.databaseName) == -1 || document.name.indexOf('$') != -1);
- });
-
- // If we are returning only the names
- if(options.namesOnly) {
- filtered_documents = filtered_documents.map(function(document) { return document.name });
- }
-
- // Return filtered items
- callback(null, filtered_documents);
- });
- });
-};
-
-/**
- * Fetch a specific collection (containing the actual collection information)
- *
- * Options
- * - **safe** {true | {w:n, wtimeout:n} | {fsync:true}, default:false}, executes with a getLastError command returning the results of the command on MongoDB.
- * - **serializeFunctions** {Boolean, default:false}, serialize functions on the document.
- * - **raw** {Boolean, default:false}, perform all operations using raw bson objects.
- * - **pkFactory** {Object}, object overriding the basic ObjectID primary key generation.
- * - **readPreference** {String}, the prefered read preference (ReadPreference.PRIMARY, ReadPreference.PRIMARY_PREFERRED, ReadPreference.SECONDARY, ReadPreference.SECONDARY_PREFERRED, ReadPreference.NEAREST).
- *
- * @param {String} collectionName the collection name we wish to access.
- * @param {Object} [options] returns option results.
- * @param {Function} [callback] returns the results.
- * @return {null}
- * @api public
- */
-Db.prototype.collection = function(collectionName, options, callback) {
- var self = this;
- if(typeof options === "function") { callback = options; options = {}; }
- // Execute safe
- if(options && options.safe || this.strict) {
- self.collectionNames(collectionName, function(err, collections) {
- if(err != null) return callback(err, null);
-
- if(collections.length == 0) {
- return callback(new Error("Collection " + collectionName + " does not exist. Currently in strict mode."), null);
- } else {
- try {
- var collection = new Collection(self, collectionName, self.pkFactory, options);
- } catch(err) {
- return callback(err, null);
- }
- return callback(null, collection);
- }
- });
- } else {
- try {
- var collection = new Collection(self, collectionName, self.pkFactory, options);
- } catch(err) {
- if(callback == null) {
- throw err;
- } else {
- return callback(err, null);
- }
- }
-
- // If we have no callback return collection object
- return callback == null ? collection : callback(null, collection);
- }
-};
-
-/**
- * Fetch all collections for the current db.
- *
- * @param {Function} callback returns the results.
- * @return {null}
- * @api public
- */
-Db.prototype.collections = function(callback) {
- var self = this;
- // Let's get the collection names
- self.collectionNames(function(err, documents) {
- if(err != null) return callback(err, null);
- var collections = [];
- documents.forEach(function(document) {
- collections.push(new Collection(self, document.name.replace(self.databaseName + ".", ''), self.pkFactory));
- });
- // Return the collection objects
- callback(null, collections);
- });
-};
-
-/**
- * Evaluate javascript on the server
- *
- * Options
- * - **nolock** {Boolean, default:false}, Tell MongoDB not to block on the evaulation of the javascript.
- *
- * @param {Code} code javascript to execute on server.
- * @param {Object|Array} [parameters] the parameters for the call.
- * @param {Object} [options] the options
- * @param {Function} callback returns the results.
- * @return {null}
- * @api public
- */
-Db.prototype.eval = function(code, parameters, options, callback) {
- // Unpack calls
- var args = Array.prototype.slice.call(arguments, 1);
- callback = args.pop();
- parameters = args.length ? args.shift() : parameters;
- options = args.length ? args.shift() : {};
-
- var finalCode = code;
- var finalParameters = [];
- // If not a code object translate to one
- if(!(finalCode instanceof this.bsonLib.Code)) {
- finalCode = new this.bsonLib.Code(finalCode);
- }
-
- // Ensure the parameters are correct
- if(parameters != null && parameters.constructor != Array && typeof parameters !== 'function') {
- finalParameters = [parameters];
- } else if(parameters != null && parameters.constructor == Array && typeof parameters !== 'function') {
- finalParameters = parameters;
- }
- // Create execution selector
- var selector = {'$eval':finalCode, 'args':finalParameters};
- // Check if the nolock parameter is passed in
- if(options['nolock']) {
- selector['nolock'] = options['nolock'];
- }
-
- // Iterate through all the fields of the index
- new Cursor(this, new Collection(this, DbCommand.SYSTEM_COMMAND_COLLECTION), selector, options, 0, -1)
- .setReadPreference(ReadPreference.PRIMARY)
- .nextObject(function(err, result) {
- if(err != null) return callback(err, null);
-
- if(result.ok == 1) {
- callback(null, result.retval);
- } else {
- callback(new Error("eval failed: " + result.errmsg), null); return;
- }
- });
-};
-
-/**
- * Dereference a dbref, against a db
- *
- * @param {DBRef} dbRef db reference object we wish to resolve.
- * @param {Function} callback returns the results.
- * @return {null}
- * @api public
- */
-Db.prototype.dereference = function(dbRef, callback) {
- var db = this;
- // If we have a db reference then let's get the db first
- if(dbRef.db != null) db = this.db(dbRef.db);
- // Fetch the collection and find the reference
- var collection = db.collection(dbRef.namespace);
- collection.findOne({'_id':dbRef.oid}, function(err, result) {
- callback(err, result);
- });
-};
-
-/**
- * Logout user from server, fire off on all connections and remove all auth info
- *
- * @param {Function} callback returns the results.
- * @return {null}
- * @api public
- */
-Db.prototype.logout = function(options, callback) {
- var self = this;
- // Unpack calls
- var args = Array.prototype.slice.call(arguments, 0);
- callback = args.pop();
- options = args.length ? args.shift() : {};
-
- // Number of connections we need to logout from
- var numberOfConnections = this.serverConfig.allRawConnections().length;
-
- // Let's generate the logout command object
- var logoutCommand = DbCommand.logoutCommand(self, {logout:1}, options);
- self._executeQueryCommand(logoutCommand, {onAll:true}, function(err, result) {
- // Count down
- numberOfConnections = numberOfConnections - 1;
- // Work around the case where the number of connections are 0
- if(numberOfConnections <= 0 && typeof callback == 'function') {
- var internalCallback = callback;
- callback = null;
- // Reset auth
- self.auths = [];
- // Handle any errors
- if(err == null && result.documents[0].ok == 1) {
- internalCallback(null, true);
- } else {
- err != null ? internalCallback(err, false) : internalCallback(new Error(result.documents[0].errmsg), false);
- }
- }
- });
-}
-
-/**
- * Authenticate a user against the server.
- *
- * Options
- * - **authdb** {String}, The database that the credentials are for,
- * different from the name of the current DB, for example admin
- * @param {String} username username.
- * @param {String} password password.
- * @param {Object} [options] the options
- * @param {Function} callback returns the results.
- * @return {null}
- * @api public
- */
-Db.prototype.authenticate = function(username, password, options, callback) {
- var self = this;
-
- if (typeof callback === 'undefined') {
- callback = options;
- options = {};
- }
- // the default db to authenticate against is 'this'
- // if authententicate is called from a retry context, it may be another one, like admin
- var authdb = options.authdb ? options.authdb : self.databaseName;
-
- // Push the new auth if we have no previous record
- // Get the amount of connections in the pool to ensure we have authenticated all comments
- var numberOfConnections = this.serverConfig.allRawConnections().length;
- var errorObject = null;
-
- // Execute all four
- this._executeQueryCommand(DbCommand.createGetNonceCommand(self), {onAll:true}, function(err, result, connection) {
- // Execute on all the connections
- if(err == null) {
- // Nonce used to make authentication request with md5 hash
- var nonce = result.documents[0].nonce;
- // Execute command
- self._executeQueryCommand(DbCommand.createAuthenticationCommand(self, username, password, nonce, authdb), {connection:connection}, function(err, result) {
- // Count down
- numberOfConnections = numberOfConnections - 1;
- // Ensure we save any error
- if(err) {
- errorObject = err;
- } else if(result.documents[0].err != null || result.documents[0].errmsg != null){
- errorObject = self.wrap(result.documents[0]);
- }
-
- // Work around the case where the number of connections are 0
- if(numberOfConnections <= 0 && typeof callback == 'function') {
- var internalCallback = callback;
- callback = null;
-
- if(errorObject == null && result.documents[0].ok == 1) {
- // We authenticated correctly save the credentials
- self.auths = [{'username':username, 'password':password, 'authdb': authdb}];
- // Return callback
- internalCallback(errorObject, true);
- } else {
- internalCallback(errorObject, false);
- }
- }
- });
- }
- });
-};
-
-/**
- * Add a user to the database.
- *
- * Options
- * - **safe** {true | {w:n, wtimeout:n} | {fsync:true}, default:false}, executes with a getLastError command returning the results of the command on MongoDB.
- *
- * @param {String} username username.
- * @param {String} password password.
- * @param {Object} [options] additional options during update.
- * @param {Function} callback returns the results.
- * @return {null}
- * @api public
- */
-Db.prototype.addUser = function(username, password, options, callback) {
- var self = this;
- var args = Array.prototype.slice.call(arguments, 2);
- callback = args.pop();
- options = args.length ? args.shift() : {};
-
- // Figure out the safe mode settings
- var safe = self.strict != null && self.strict == false ? true : self.strict;
- // Override with options passed in if applicable
- safe = options != null && options['safe'] != null ? options['safe'] : safe;
- // Ensure it's at least set to safe
- safe = safe == null ? true : safe;
-
- // Use node md5 generator
- var md5 = crypto.createHash('md5');
- // Generate keys used for authentication
- md5.update(username + ":mongo:" + password);
- var userPassword = md5.digest('hex');
- // Fetch a user collection
- var collection = this.collection(DbCommand.SYSTEM_USER_COLLECTION);
- // Check if we are inserting the first user
- collection.count({}, function(err, count) {
- // We got an error (f.ex not authorized)
- if(err != null) return callback(err, null);
- // Check if the user exists and update i
- collection.find({user: username}, {dbName: options['dbName']}).toArray(function(err, documents) {
- // We got an error (f.ex not authorized)
- if(err != null) return callback(err, null);
- // We have a user, let's update the password or upsert if not
- collection.update({user: username},{$set: {user: username, pwd: userPassword}}, {safe:safe, dbName: options['dbName'], upsert:true}, function(err, results) {
- if(count == 0 && err) {
- callback(null, [{user:username, pwd:userPassword}]);
- } else if(err) {
- callback(err, null)
- } else {
- callback(null, [{user:username, pwd:userPassword}]);
- }
- });
- });
- });
-};
-
-/**
- * Remove a user from a database
- *
- * Options
- * - **safe** {true | {w:n, wtimeout:n} | {fsync:true}, default:false}, executes with a getLastError command returning the results of the command on MongoDB.
- *
- * @param {String} username username.
- * @param {Object} [options] additional options during update.
- * @param {Function} callback returns the results.
- * @return {null}
- * @api public
- */
-Db.prototype.removeUser = function(username, options, callback) {
- var self = this;
- var args = Array.prototype.slice.call(arguments, 1);
- callback = args.pop();
- options = args.length ? args.shift() : {};
-
- // Figure out the safe mode settings
- var safe = self.strict != null && self.strict == false ? true : self.strict;
- // Override with options passed in if applicable
- safe = options != null && options['safe'] != null ? options['safe'] : safe;
- // Ensure it's at least set to safe
- safe = safe == null ? true : safe;
-
- // Fetch a user collection
- var collection = this.collection(DbCommand.SYSTEM_USER_COLLECTION);
- collection.findOne({user: username}, {dbName: options['dbName']}, function(err, user) {
- if(user != null) {
- collection.remove({user: username}, {safe:safe, dbName: options['dbName']}, function(err, result) {
- callback(err, true);
- });
- } else {
- callback(err, false);
- }
- });
-};
-
-/**
- * Creates a collection on a server pre-allocating space, need to create f.ex capped collections.
- *
- * Options
- * - **safe** {true | {w:n, wtimeout:n} | {fsync:true}, default:false}, executes with a getLastError command returning the results of the command on MongoDB.
- * - **serializeFunctions** {Boolean, default:false}, serialize functions on the document.
- * - **raw** {Boolean, default:false}, perform all operations using raw bson objects.
- * - **pkFactory** {Object}, object overriding the basic ObjectID primary key generation.
- * - **capped** {Boolean, default:false}, create a capped collection.
- * - **size** {Number}, the size of the capped collection in bytes.
- * - **max** {Number}, the maximum number of documents in the capped collection.
- * - **autoIndexId** {Boolean, default:false}, create an index on the _id field of the document, not created automatically on capped collections.
- * - **readPreference** {String}, the prefered read preference (ReadPreference.PRIMARY, ReadPreference.PRIMARY_PREFERRED, ReadPreference.SECONDARY, ReadPreference.SECONDARY_PREFERRED, ReadPreference.NEAREST).
- *
- * @param {String} collectionName the collection name we wish to access.
- * @param {Object} [options] returns option results.
- * @param {Function} callback returns the results.
- * @return {null}
- * @api public
- */
-Db.prototype.createCollection = function(collectionName, options, callback) {
- var args = Array.prototype.slice.call(arguments, 1);
- callback = args.pop();
- options = args.length ? args.shift() : null;
- var self = this;
-
- // Figure out the safe mode settings
- var safe = self.strict != null && self.strict == false ? true : self.strict;
- // Override with options passed in if applicable
- safe = options != null && options['safe'] != null ? options['safe'] : safe;
- // Ensure it's at least set to safe
- safe = safe == null ? true : safe;
-
- // Check if we have the name
- this.collectionNames(collectionName, function(err, collections) {
- if(err != null) return callback(err, null);
-
- var found = false;
- collections.forEach(function(collection) {
- if(collection.name == self.databaseName + "." + collectionName) found = true;
- });
-
- // If the collection exists either throw an exception (if db in strict mode) or return the existing collection
- if(found && ((options && options.safe) || self.strict)) {
- return callback(new Error("Collection " + collectionName + " already exists. Currently in strict mode."), null);
- } else if(found){
- try {
- var collection = new Collection(self, collectionName, self.pkFactory, options);
- } catch(err) {
- return callback(err, null);
- }
- return callback(null, collection);
- }
-
- // Create a new collection and return it
- self._executeQueryCommand(DbCommand.createCreateCollectionCommand(self, collectionName, options), {read:false, safe:safe}, function(err, result) {
- var document = result.documents[0];
- // If we have no error let's return the collection
- if(err == null && document.ok == 1) {
- try {
- var collection = new Collection(self, collectionName, self.pkFactory, options);
- } catch(err) {
- return callback(err, null);
- }
- return callback(null, collection);
- } else {
- err != null ? callback(err, null) : callback(self.wrap(document), null);
- }
- });
- });
-};
-
-/**
- * Execute a command hash against MongoDB. This lets you acess any commands not available through the api on the server.
- *
- * @param {Object} selector the command hash to send to the server, ex: {ping:1}.
- * @param {Function} callback returns the results.
- * @return {null}
- * @api public
- */
-Db.prototype.command = function(selector, options, callback) {
- var args = Array.prototype.slice.call(arguments, 1);
- callback = args.pop();
- options = args.length ? args.shift() : {};
-
- // Set up the options
- var cursor = new Cursor(this
- , new Collection(this, DbCommand.SYSTEM_COMMAND_COLLECTION), selector, {}, 0, -1, null, null, null, null, QueryCommand.OPTS_NO_CURSOR_TIMEOUT
- , null, null, null, null, null, null, null, null, null, null, null, null, null, options['dbName']);
- // Set read preference if we set one
- var readPreference = options['readPreference'] ? options['readPreference'] : false;
- // Ensure only commands who support read Prefrences are exeuted otherwise override and use Primary
- if(readPreference != false) {
- if(selector['group'] || selector['aggregate'] || selector['collStats'] || selector['dbStats']
- || selector['count'] || selector['distinct'] || selector['geoNear'] || selector['geoSearch'] || selector['geoWalk']
- || (selector['mapreduce'] && selector.out = 'inline')) {
- // Set the read preference
- cursor.setReadPreference(readPreference);
- } else {
- cursor.setReadPreference(ReadPreference.PRIMARY);
- }
- }
- // Return the next object
- cursor.nextObject(callback);
-};
-
-/**
- * Drop a collection from the database, removing it permanently. New accesses will create a new collection.
- *
- * @param {String} collectionName the name of the collection we wish to drop.
- * @param {Function} callback returns the results.
- * @return {null}
- * @api public
- */
-Db.prototype.dropCollection = function(collectionName, callback) {
- var self = this;
-
- // Drop the collection
- this._executeQueryCommand(DbCommand.createDropCollectionCommand(this, collectionName), function(err, result) {
- if(err == null && result.documents[0].ok == 1) {
- if(callback != null) return callback(null, true);
- } else {
- if(callback != null) err != null ? callback(err, null) : callback(self.wrap(result.documents[0]), null);
- }
- });
-};
-
-/**
- * Rename a collection.
- *
- * @param {String} fromCollection the name of the current collection we wish to rename.
- * @param {String} toCollection the new name of the collection.
- * @param {Function} callback returns the results.
- * @return {null}
- * @api public
- */
-Db.prototype.renameCollection = function(fromCollection, toCollection, callback) {
- var self = this;
-
- // Execute the command, return the new renamed collection if successful
- this._executeQueryCommand(DbCommand.createRenameCollectionCommand(this, fromCollection, toCollection), function(err, result) {
- if(err == null && result.documents[0].ok == 1) {
- if(callback != null) return callback(null, new Collection(self, toCollection, self.pkFactory));
- } else {
- if(callback != null) err != null ? callback(err, null) : callback(self.wrap(result.documents[0]), null);
- }
- });
-};
-
-/**
- * Return last error message for the given connection, note options can be combined.
- *
- * Options
- * - **fsync** {Boolean, default:false}, option forces the database to fsync all files before returning.
- * - **j** {Boolean, default:false}, awaits the journal commit before returning, > MongoDB 2.0.
- * - **w** {Number}, until a write operation has been replicated to N servers.
- * - **wtimeout** {Number}, number of miliseconds to wait before timing out.
- *
- * Connection Options
- * - **connection** {Connection}, fire the getLastError down a specific connection.
- *
- * @param {Object} [options] returns option results.
- * @param {Object} [connectionOptions] returns option results.
- * @param {Function} callback returns the results.
- * @return {null}
- * @api public
- */
-Db.prototype.lastError = function(options, connectionOptions, callback) {
- // Unpack calls
- var args = Array.prototype.slice.call(arguments, 0);
- callback = args.pop();
- options = args.length ? args.shift() : {};
- connectionOptions = args.length ? args.shift() : {};
-
- this._executeQueryCommand(DbCommand.createGetLastErrorCommand(options, this), connectionOptions, function(err, error) {
- callback(err, error && error.documents);
- });
-};
-
-/**
- * Legacy method calls.
- *
- * @ignore
- * @api private
- */
-Db.prototype.error = Db.prototype.lastError;
-Db.prototype.lastStatus = Db.prototype.lastError;
-
-/**
- * Return all errors up to the last time db reset_error_history was called.
- *
- * Options
- * - **connection** {Connection}, fire the getLastError down a specific connection.
- *
- * @param {Object} [options] returns option results.
- * @param {Function} callback returns the results.
- * @return {null}
- * @api public
- */
-Db.prototype.previousErrors = function(options, callback) {
- // Unpack calls
- var args = Array.prototype.slice.call(arguments, 0);
- callback = args.pop();
- options = args.length ? args.shift() : {};
-
- this._executeQueryCommand(DbCommand.createGetPreviousErrorsCommand(this), options, function(err, error) {
- callback(err, error.documents);
- });
-};
-
-/**
- * Runs a command on the database.
- * @ignore
- * @api private
- */
-Db.prototype.executeDbCommand = function(command_hash, options, callback) {
- if(callback == null) { callback = options; options = {}; }
- this._executeQueryCommand(DbCommand.createDbSlaveOkCommand(this, command_hash, options), options, callback);
-};
-
-/**
- * Runs a command on the database as admin.
- * @ignore
- * @api private
- */
-Db.prototype.executeDbAdminCommand = function(command_hash, options, callback) {
- if(callback == null) { callback = options; options = {}; }
- this._executeQueryCommand(DbCommand.createAdminDbCommand(this, command_hash), options, callback);
-};
-
-/**
- * Resets the error history of the mongo instance.
- *
- * Options
- * - **connection** {Connection}, fire the getLastError down a specific connection.
- *
- * @param {Object} [options] returns option results.
- * @param {Function} callback returns the results.
- * @return {null}
- * @api public
- */
-Db.prototype.resetErrorHistory = function(options, callback) {
- // Unpack calls
- var args = Array.prototype.slice.call(arguments, 0);
- callback = args.pop();
- options = args.length ? args.shift() : {};
-
- this._executeQueryCommand(DbCommand.createResetErrorHistoryCommand(this), options, function(err, error) {
- callback(err, error.documents);
- });
-};
-
-/**
- * Creates an index on the collection.
- *
- * Options
- * - **safe** {true | {w:n, wtimeout:n} | {fsync:true}, default:false}, executes with a getLastError command returning the results of the command on MongoDB.
- * - **unique** {Boolean, default:false}, creates an unique index.
- * - **sparse** {Boolean, default:false}, creates a sparse index.
- * - **background** {Boolean, default:false}, creates the index in the background, yielding whenever possible.
- * - **dropDups** {Boolean, default:false}, a unique index cannot be created on a key that has pre-existing duplicate values. If you would like to create the index anyway, keeping the first document the database indexes and deleting all subsequent documents that have duplicate value
- * - **min** {Number}, for geospatial indexes set the lower bound for the co-ordinates.
- * - **max** {Number}, for geospatial indexes set the high bound for the co-ordinates.
- *
- * @param {String} collectionName name of the collection to create the index on.
- * @param {Object} fieldOrSpec fieldOrSpec that defines the index.
- * @param {Object} [options] additional options during update.
- * @param {Function} callback for results.
- * @return {null}
- * @api public
- */
-Db.prototype.createIndex = function(collectionName, fieldOrSpec, options, callback) {
- var self = this;
- var args = Array.prototype.slice.call(arguments, 2);
- callback = args.pop();
- options = args.length ? args.shift() : {};
- options = typeof callback === 'function' ? options : callback;
- options = options == null ? {} : options;
-
- // Collect errorOptions
- var errorOptions = options.safe != null ? options.safe : null;
- errorOptions = errorOptions == null && self.strict != null ? self.strict : errorOptions;
-
- // If we have a write concern set and no callback throw error
- if(errorOptions != null && errorOptions != false && (typeof callback !== 'function' && typeof options !== 'function')) throw new Error("safe cannot be used without a callback");
-
- // Create command
- var command = DbCommand.createCreateIndexCommand(this, collectionName, fieldOrSpec, options);
- // Default command options
- var commandOptions = {};
-
- // If we have error conditions set handle them
- if(errorOptions && errorOptions != false) {
- // Insert options
- commandOptions['read'] = false;
- // If we have safe set set async to false
- if(errorOptions == null) commandOptions['async'] = true;
-
- // Set safe option
- commandOptions['safe'] = errorOptions;
- // If we have an error option
- if(typeof errorOptions == 'object') {
- var keys = Object.keys(errorOptions);
- for(var i = 0; i < keys.length; i++) {
- commandOptions[keys[i]] = errorOptions[keys[i]];
- }
- }
-
- // Execute insert command
- this._executeInsertCommand(command, commandOptions, function(err, result) {
- if(err != null) return callback(err, null);
-
- result = result && result.documents;
- if (result[0].err) {
- callback(self.wrap(result[0]));
- } else {
- callback(null, command.documents[0].name);
- }
- });
- } else {
- // Execute insert command
- var result = this._executeInsertCommand(command, commandOptions);
- // If no callback just return
- if(!callback) return;
- // If error return error
- if(result instanceof Error) {
- return callback(result);
- }
- // Otherwise just return
- return callback(null, null);
- }
-};
-
-/**
- * Ensures that an index exists, if it does not it creates it
- *
- * Options
- * - **safe** {true | {w:n, wtimeout:n} | {fsync:true}, default:false}, executes with a
- * - **unique** {Boolean, default:false}, creates an unique index.
- * - **sparse** {Boolean, default:false}, creates a sparse index.
- * - **background** {Boolean, default:false}, creates the index in the background, yielding whenever possible.
- * - **dropDups** {Boolean, default:false}, a unique index cannot be created on a key that has pre-existing duplicate values. If you would like to create the index anyway, keeping the first document the database indexes and deleting all subsequent documents that have duplicate value
- * - **min** {Number}, for geospatial indexes set the lower bound for the co-ordinates.
- * - **max** {Number}, for geospatial indexes set the high bound for the co-ordinates.
- * - **v** {Number}, specify the format version of the indexes.
- * - **expireAfterSeconds** {Number}, specify the number of seconds before a document expires (requires Mongo DB 2.2 or higher)
- *
- * @param {String} collectionName name of the collection to create the index on.
- * @param {Object} fieldOrSpec fieldOrSpec that defines the index.
- * @param {Object} [options] additional options during update.
- * @param {Function} callback for results.
- * @return {null}
- * @api public
- */
-Db.prototype.ensureIndex = function(collectionName, fieldOrSpec, options, callback) {
- var self = this;
-
- if (typeof callback === 'undefined' && typeof options === 'function') {
- callback = options;
- options = {};
- }
-
- if (options == null) {
- options = {};
- }
-
- // Collect errorOptions
- var errorOptions = options.safe != null ? options.safe : null;
- errorOptions = errorOptions == null && self.strict != null ? self.strict : errorOptions;
-
- // If we have a write concern set and no callback throw error
- if(errorOptions != null && errorOptions != false && (typeof callback !== 'function' && typeof options !== 'function')) throw new Error("safe cannot be used without a callback");
-
- // Create command
- var command = DbCommand.createCreateIndexCommand(this, collectionName, fieldOrSpec, options);
- var index_name = command.documents[0].name;
-
- // Default command options
- var commandOptions = {};
- // Check if the index allready exists
- this.indexInformation(collectionName, function(err, collectionInfo) {
- if(err != null) return callback(err, null);
-
- if(!collectionInfo[index_name]) {
- // If we have error conditions set handle them
- if(errorOptions && errorOptions != false) {
- // Insert options
- commandOptions['read'] = false;
- // If we have safe set set async to false
- if(errorOptions == null) commandOptions['async'] = true;
-
- // Set safe option
- commandOptions['safe'] = errorOptions;
- // If we have an error option
- if(typeof errorOptions == 'object') {
- var keys = Object.keys(errorOptions);
- for(var i = 0; i < keys.length; i++) {
- commandOptions[keys[i]] = errorOptions[keys[i]];
- }
- }
-
- self._executeInsertCommand(command, commandOptions, function(err, result) {
- // Only callback if we have one specified
- if(typeof callback === 'function') {
- if(err != null) return callback(err, null);
-
- result = result && result.documents;
- if (result[0].err) {
- callback(self.wrap(result[0]));
- } else {
- callback(null, command.documents[0].name);
- }
- }
- });
- } else {
- // Execute insert command
- var result = self._executeInsertCommand(command, commandOptions);
- // If no callback just return
- if(!callback) return;
- // If error return error
- if(result instanceof Error) {
- return callback(result);
- }
- // Otherwise just return
- return callback(null, index_name);
- }
- } else {
- if(typeof callback === 'function') return callback(null, index_name);
- }
- });
-};
-
-/**
- * Returns the information available on allocated cursors.
- *
- * Options
- * - **readPreference** {String}, the prefered read preference (ReadPreference.PRIMARY, ReadPreference.PRIMARY_PREFERRED, ReadPreference.SECONDARY, ReadPreference.SECONDARY_PREFERRED, ReadPreference.NEAREST).
- *
- * @param {Object} [options] additional options during update.
- * @param {Function} callback for results.
- * @return {null}
- * @api public
- */
-Db.prototype.cursorInfo = function(options, callback) {
- var args = Array.prototype.slice.call(arguments, 0);
- callback = args.pop();
- options = args.length ? args.shift() : {};
-
- this._executeQueryCommand(DbCommand.createDbSlaveOkCommand(this, {'cursorInfo':1}), options, function(err, result) {
- callback(err, result.documents[0]);
- });
-};
-
-/**
- * Drop an index on a collection.
- *
- * @param {String} collectionName the name of the collection where the command will drop an index.
- * @param {String} indexName name of the index to drop.
- * @param {Function} callback for results.
- * @return {null}
- * @api public
- */
-Db.prototype.dropIndex = function(collectionName, indexName, callback) {
- this._executeQueryCommand(DbCommand.createDropIndexCommand(this, collectionName, indexName), callback);
-};
-
-/**
- * Reindex all indexes on the collection
- * Warning: reIndex is a blocking operation (indexes are rebuilt in the foreground) and will be slow for large collections.
- *
- * @param {String} collectionName the name of the collection.
- * @param {Function} callback returns the results.
- * @api public
-**/
-Db.prototype.reIndex = function(collectionName, callback) {
- this._executeQueryCommand(DbCommand.createReIndexCommand(this, collectionName), function(err, result) {
- if(err != null) {
- callback(err, false);
- } else if(result.documents[0].errmsg == null) {
- callback(null, true);
- } else {
- callback(new Error(result.documents[0].errmsg), false);
- }
- });
-};
-
-/**
- * Retrieves this collections index info.
- *
- * Options
- * - **full** {Boolean, default:false}, returns the full raw index information.
- * - **readPreference** {String}, the preferred read preference ((Server.PRIMARY, Server.PRIMARY_PREFERRED, Server.SECONDARY, Server.SECONDARY_PREFERRED, Server.NEAREST).
- *
- * @param {String} collectionName the name of the collection.
- * @param {Object} [options] additional options during update.
- * @param {Function} callback returns the index information.
- * @return {null}
- * @api public
- */
-Db.prototype.indexInformation = function(collectionName, options, callback) {
- if(typeof callback === 'undefined') {
- if(typeof options === 'undefined') {
- callback = collectionName;
- collectionName = null;
- } else {
- callback = options;
- }
- options = {};
- }
-
- // If we specified full information
- var full = options['full'] == null ? false : options['full'];
- // Build selector for the indexes
- var selector = collectionName != null ? {ns: (this.databaseName + "." + collectionName)} : {};
-
- // Set read preference if we set one
- var readPreference = options['readPreference'] ? options['readPreference'] : ReadPreference.PRIMARY;
-
- // Iterate through all the fields of the index
- this.collection(DbCommand.SYSTEM_INDEX_COLLECTION, function(err, collection) {
- // Perform the find for the collection
- collection.find(selector).setReadPreference(readPreference).toArray(function(err, indexes) {
- if(err != null) return callback(err, null);
- // Contains all the information
- var info = {};
-
- // if full defined just return all the indexes directly
- if(full) return callback(null, indexes);
-
- // Process all the indexes
- for(var i = 0; i < indexes.length; i++) {
- var index = indexes[i];
- // Let's unpack the object
- info[index.name] = [];
- for(var name in index.key) {
- info[index.name].push([name, index.key[name]]);
- }
- }
-
- // Return all the indexes
- callback(null, info);
- });
- });
-};
-
-/**
- * Drop a database.
- *
- * @param {Function} callback returns the index information.
- * @return {null}
- * @api public
- */
-Db.prototype.dropDatabase = function(callback) {
- var self = this;
-
- this._executeQueryCommand(DbCommand.createDropDatabaseCommand(this), function(err, result) {
- if (err == null && result.documents[0].ok == 1) {
- callback(null, true);
- } else {
- if (err) {
- callback(err, false);
- } else {
- callback(self.wrap(result.documents[0]), false);
- }
- }
- });
-};
-
-/**
- * Get all the db statistics.
- *
- * Options
- * - **scale** {Number}, divide the returned sizes by scale value.
- * - **readPreference** {String}, the preferred read preference ((Server.PRIMARY, Server.PRIMARY_PREFERRED, Server.SECONDARY, Server.SECONDARY_PREFERRED, Server.NEAREST).
- *
- * @param {Objects} [options] options for the stats command
- * @param {Function} callback returns statistical information for the db.
- * @return {null}
- * @api public
- */
-Db.prototype.stats = function stats(options, callback) {
- var args = Array.prototype.slice.call(arguments, 0);
- callback = args.pop();
- // Fetch all commands
- options = args.length ? args.shift() : {};
-
- // Build command object
- var commandObject = {
- dbStats:this.collectionName,
- }
-
- // Check if we have the scale value
- if(options['scale'] != null) commandObject['scale'] = options['scale'];
-
- // Execute the command
- this.command(commandObject, options, callback);
-}
-
-/**
- * Register a handler
- * @ignore
- * @api private
- */
-Db.prototype._registerHandler = function(db_command, raw, connection, callback) {
- // If we have an array of commands, chain them
- var chained = Array.isArray(db_command);
-
- // If they are chained we need to add a special handler situation
- if(chained) {
- // List off chained id's
- var chainedIds = [];
- // Add all id's
- for(var i = 0; i < db_command.length; i++) chainedIds.push(db_command[i].getRequestId().toString());
-
- // Register all the commands together
- for(var i = 0; i < db_command.length; i++) {
- var command = db_command[i];
- // Add the callback to the store
- this._callBackStore.once(command.getRequestId(), callback);
- // Add the information about the reply
- this._callBackStore._notReplied[command.getRequestId().toString()] = {start: new Date().getTime(), 'raw': raw, chained:chainedIds, connection:connection};
- }
- } else {
- // Add the callback to the list of handlers
- this._callBackStore.once(db_command.getRequestId(), callback);
- // Add the information about the reply
- this._callBackStore._notReplied[db_command.getRequestId().toString()] = {start: new Date().getTime(), 'raw': raw, connection:connection};
- }
-}
-
-/**
- *
- * @ignore
- * @api private
- */
-Db.prototype._callHandler = function(id, document, err) {
- // If there is a callback peform it
- if(this._callBackStore.listeners(id).length >= 1) {
- // Get info object
- var info = this._callBackStore._notReplied[id];
- // Delete the current object
- delete this._callBackStore._notReplied[id];
- // Emit to the callback of the object
- this._callBackStore.emit(id, err, document, info.connection);
- }
-}
-
-/**
- *
- * @ignore
- * @api private
- */
-Db.prototype._hasHandler = function(id) {
- // If there is a callback peform it
- return this._callBackStore.listeners(id).length >= 1;
-}
-
-/**
- *
- * @ignore
- * @api private
- */
-Db.prototype._removeHandler = function(id) {
- // Remove the information
- if(this._callBackStore._notReplied[id] != null) delete this._callBackStore._notReplied[id];
- // Remove the callback if it's registered
- this._callBackStore.removeAllListeners(id);
- // Force cleanup _events, node.js seems to set it as a null value
- if(this._callBackStore._events != null) delete this._callBackStore._events[id];
-}
-
-/**
- *
- * @ignore
- * @api private
- */
-Db.prototype._findHandler = function(id) {
- var info = this._callBackStore._notReplied[id];
- // Return the callback
- return {info:info, callback:(this._callBackStore.listeners(id).length >= 1)}
-}
-
-/**
- * @ignore
- */
-var __executeQueryCommand = function(self, db_command, options, callback) {
- // Options unpacking
- var read = options['read'] != null ? options['read'] : false;
- var raw = options['raw'] != null ? options['raw'] : self.raw;
- var onAll = options['onAll'] != null ? options['onAll'] : false;
- var specifiedConnection = options['connection'] != null ? options['connection'] : null;
-
- // Correct read preference to default primary if set to false, null or primary
- if(!(typeof read == 'object') && read._type == 'ReadPreference') {
- read = (read == null || read == 'primary' || read == false) ? ReadPreference.PRIMARY : read;
- if(!ReadPreference.isValid(read)) return callback(new Error("Illegal readPreference mode specified, " + read));
- } else if(typeof read == 'object' && read._type == 'ReadPreference') {
- if(!read.isValid()) return callback(new Error("Illegal readPreference mode specified, " + read.mode));
- }
-
- // If we have a read preference set and we are a mongos pass the read preference on to the mongos instance,
- if(self.serverConfig.isMongos() && read != null && read != false) {
- db_command.setMongosReadPreference(read);
- }
-
- // If we got a callback object
- if(typeof callback === 'function' && !onAll) {
- // Override connection if we passed in a specific connection
- var connection = specifiedConnection != null ? specifiedConnection : null;
- // Fetch either a reader or writer dependent on the specified read option if no connection
- // was passed in
- if(connection == null) {
- connection = read == null || read == 'primary' || read == false ? self.serverConfig.checkoutWriter(true) : self.serverConfig.checkoutReader(read);
- }
-
- // Ensure we have a valid connection
- if(connection == null) {
- return callback(new Error("no open connections"));
- } else if(connection instanceof Error || connection['message'] != null) {
- return callback(connection);
- }
-
- // Perform reaping of any dead connection
- if(self.reaperEnabled) reaper(self, self.reaperInterval, self.reaperTimeout);
-
- // Register the handler in the data structure
- self._registerHandler(db_command, raw, connection, callback);
-
- // Write the message out and handle any errors if there are any
- connection.write(db_command, function(err) {
- if(err != null) {
- // Call the handler with an error
- self._callHandler(db_command.getRequestId(), null, err);
- }
- });
- } else if(typeof callback === 'function' && onAll) {
- var connections = self.serverConfig.allRawConnections();
- var numberOfEntries = connections.length;
- // Go through all the connections
- for(var i = 0; i < connections.length; i++) {
- // Fetch a connection
- var connection = connections[i];
- // Override connection if needed
- connection = specifiedConnection != null ? specifiedConnection : connection;
- // Ensure we have a valid connection
- if(connection == null) {
- return callback(new Error("no open connections"));
- } else if(connection instanceof Error) {
- return callback(connection);
- }
-
- // Register the handler in the data structure
- self._registerHandler(db_command, raw, connection, callback);
-
- // Write the message out
- connection.write(db_command, function(err) {
- // Adjust the number of entries we need to process
- numberOfEntries = numberOfEntries - 1;
- // Remove listener
- if(err != null) {
- // Clean up listener and return error
- self._removeHandler(db_command.getRequestId());
- }
-
- // No more entries to process callback with the error
- if(numberOfEntries <= 0) {
- callback(err);
- }
- });
-
- // Update the db_command request id
- db_command.updateRequestId();
- }
- } else {
- // Fetch either a reader or writer dependent on the specified read option
- var connection = read == null || read == 'primary' || read == false ? self.serverConfig.checkoutWriter(true) : self.serverConfig.checkoutReader(read);
- // Override connection if needed
- connection = specifiedConnection != null ? specifiedConnection : connection;
- // Ensure we have a valid connection
- if(connection == null || connection instanceof Error || connection['message'] != null) return null;
- // Write the message out
- connection.write(db_command, function(err) {
- if(err != null) {
- // Emit the error
- self.emit("error", err);
- }
- });
- }
-}
-
-/**
- * @ignore
- */
-var __retryCommandOnFailure = function(self, retryInMilliseconds, numberOfTimes, command, db_command, options, callback) {
- if(this._state == 'connected' || this._state == 'disconnected') this._state = 'connecting';
- // Number of retries done
- var numberOfRetriesDone = numberOfTimes;
- // Retry function, execute once
- var retryFunction = function(_self, _numberOfRetriesDone, _retryInMilliseconds, _numberOfTimes, _command, _db_command, _options, _callback) {
- _self.serverConfig.connect(_self, {}, function(err, result, _serverConfig) {
- // Adjust the number of retries left
- _numberOfRetriesDone = _numberOfRetriesDone - 1;
- // Definitively restart
- if(err != null && _numberOfRetriesDone > 0) {
- _self._state = 'connecting';
- // Close the server config
- _serverConfig.close(function(err) {
- // Retry the connect
- setTimeout(function() {
- retryFunction(_self, _numberOfRetriesDone, _retryInMilliseconds, _numberOfTimes, _command, _db_command, _options, _callback);
- }, _retryInMilliseconds);
- });
- } else if(err != null && _numberOfRetriesDone <= 0) {
- _self._state = 'disconnected';
- // Force close the current connections
- _serverConfig.close(function(_err) {
- // Force close the current connections
- if(typeof _callback == 'function') _callback(err, null);
- });
- } else if(err == null && _self.serverConfig.isConnected() == true && Array.isArray(_self.auths) && _self.auths.length > 0) {
- _self._state = 'connected';
- // Get number of auths we need to execute
- var numberOfAuths = _self.auths.length;
- // Apply all auths
- for(var i = 0; i < _self.auths.length; i++) {
- _self.authenticate(_self.auths[i].username, _self.auths[i].password, {'authdb':_self.auths[i].authdb}, function(err, authenticated) {
- numberOfAuths = numberOfAuths - 1;
-
- // If we have no more authentications to replay
- if(numberOfAuths == 0) {
- if(err != null || !authenticated) {
- if(typeof _callback == 'function') _callback(err, null);
- return;
- } else {
- // Execute command
- command(_self, _db_command, _options, _callback);
-
- // Execute any backed up commands
- process.nextTick(function() {
- // Execute any backed up commands
- while(_self.commands.length > 0) {
- // Fetch the command
- var command = _self.commands.shift();
- // Execute based on type
- if(command['type'] == 'query') {
- __executeQueryCommand(_self, command['db_command'], command['options'], command['callback']);
- } else if(command['type'] == 'insert') {
- __executeInsertCommand(_self, command['db_command'], command['options'], command['callback']);
- }
- }
- });
- }
- }
- });
- }
- } else if(err == null && _self.serverConfig.isConnected() == true) {
- _self._state = 'connected';
- // Execute command
- command(_self, _db_command, _options, _callback);
-
- process.nextTick(function() {
- // Execute any backed up commands
- while(_self.commands.length > 0) {
- // Fetch the command
- var command = _self.commands.shift();
- // Execute based on type
- if(command['type'] == 'query') {
- __executeQueryCommand(_self, command['db_command'], command['options'], command['callback']);
- } else if(command['type'] == 'insert') {
- __executeInsertCommand(_self, command['db_command'], command['options'], command['callback']);
- }
- }
- });
- } else {
- _self._state = 'connecting';
- // Force close the current connections
- _serverConfig.close(function(err) {
- // _self.serverConfig.close(function(err) {
- // Retry the connect
- setTimeout(function() {
- retryFunction(_self, _numberOfRetriesDone, _retryInMilliseconds, _numberOfTimes, _command, _db_command, _options, _callback);
- }, _retryInMilliseconds);
- });
- }
- });
- };
-
- // Execute function first time
- retryFunction(self, numberOfRetriesDone, retryInMilliseconds, numberOfTimes, command, db_command, options, callback);
-}
-
-/**
- * Execute db query command (not safe)
- * @ignore
- * @api private
- */
-Db.prototype._executeQueryCommand = function(db_command, options, callback) {
- var self = this;
-
- // Unpack the parameters
- if (typeof callback === 'undefined') {
- callback = options;
- options = {};
- }
-
- // fast fail option used for HA, no retry
- var failFast = options['failFast'] != null ? options['failFast'] : false;
- // Check if the user force closed the command
- if(this._applicationClosed) {
- if(typeof callback == 'function') {
- return callback(new Error("db closed by application"), null);
- } else {
- throw new Error("db closed by application");
- }
- }
-
- // If the pool is not connected, attemp to reconnect to send the message
- if(this._state == 'connecting' && this.serverConfig.autoReconnect && !failFast) {
- process.nextTick(function() {
- self.commands.push({type:'query', 'db_command':db_command, 'options':options, 'callback':callback});
- })
- } else if(!this.serverConfig.isConnected() && this.serverConfig.autoReconnect && !failFast) {
- this._state = 'connecting';
- // Retry command
- __retryCommandOnFailure(this, this.retryMiliSeconds, this.numberOfRetries, __executeQueryCommand, db_command, options, callback);
- } else if(!this.serverConfig.isConnected() && !this.serverConfig.autoReconnect && callback) {
- // Fire an error to the callback if we are not connected and don't do reconnect
- callback(new Error("no open connections"), null);
- } else {
- // If we have a
- if(this.serverConfig instanceof ReplSet && this.serverConfig._checkReplicaSet()) {
- // Execute the command in waiting
- __executeQueryCommand(self, db_command, options, function(err, result, connection) {
- if(!err) {
- process.nextTick(function() {
- // Force close if we are disconnected
- if(self._state == 'disconnected') {
- self.close();
- return;
- }
-
- var replSetGetStatusCommand = DbCommand.createAdminDbCommandSlaveOk(self, {replSetGetStatus:1}, {});
- // Do a freaking ping
- __executeQueryCommand(self, replSetGetStatusCommand, {readPreference:ReadPreference.SECONDARY_PREFERRED}, function(_replerr, _replresult) {
- // Force close if we are disconnected
- if(self._state == 'disconnected') {
- self.close(true);
- return;
- }
-
- // Handle the HA
- if(_replerr == null) {
- self.serverConfig._validateReplicaset(_replresult, self.auths);
- }
- })
- })
- }
- // Call the original method
- callback(err, result, connection)
- })
- } else {
- __executeQueryCommand(self, db_command, options, callback)
- }
- }
-};
-
-/**
- * @ignore
- */
-var __executeInsertCommand = function(self, db_command, options, callback) {
- // Always checkout a writer for this kind of operations
- var connection = self.serverConfig.checkoutWriter();
- // Get strict mode
- var safe = options['safe'] != null ? options['safe'] : false;
- var raw = options['raw'] != null ? options['raw'] : self.raw;
- var specifiedConnection = options['connection'] != null ? options['connection'] : null;
- // Override connection if needed
- connection = specifiedConnection != null ? specifiedConnection : connection;
-
- // Ensure we have a valid connection
- if(typeof callback === 'function') {
- // Ensure we have a valid connection
- if(connection == null) {
- return callback(new Error("no open connections"));
- } else if(connection instanceof Error) {
- return callback(connection);
- }
-
- // We are expecting a check right after the actual operation
- if(safe != null && safe != false) {
- // db command is now an array of commands (original command + lastError)
- db_command = [db_command, DbCommand.createGetLastErrorCommand(safe, self)];
-
- // Register the handler in the data structure
- self._registerHandler(db_command[1], raw, connection, callback);
- }
- }
-
- // If we have no callback and there is no connection
- if(connection == null) return null;
- if(connection instanceof Error && typeof callback == 'function') return callback(connection, null);
- if(connection instanceof Error) return null;
- if(connection == null && typeof callback == 'function') return callback(new Error("no primary server found"), null);
-
- // Write the message out
- connection.write(db_command, function(err) {
- // Return the callback if it's not a safe operation and the callback is defined
- if(typeof callback === 'function' && (safe == null || safe == false)) {
- // Perform reaping
- if(self.reaperEnabled) reaper(self, self.reaperInterval, self.reaperTimeout);
- // Perform the callback
- callback(err, null);
- } else if(typeof callback === 'function'){
- // Call the handler with an error
- self._callHandler(db_command[1].getRequestId(), null, err);
- } else {
- self.emit("error", err);
- }
- });
-}
-
-/**
- * Execute an insert Command
- * @ignore
- * @api private
- */
-Db.prototype._executeInsertCommand = function(db_command, options, callback) {
- var self = this;
-
- // Unpack the parameters
- if(callback == null && typeof options === 'function') {
- callback = options;
- options = {};
- }
-
- // Ensure options are not null
- options = options == null ? {} : options;
-
- // Check if the user force closed the command
- if(this._applicationClosed) {
- if(typeof callback == 'function') {
- return callback(new Error("db closed by application"), null);
- } else {
- throw new Error("db closed by application");
- }
- }
-
- // If the pool is not connected, attemp to reconnect to send the message
- if(self._state == 'connecting' && this.serverConfig.autoReconnect) {
- process.nextTick(function() {
- self.commands.push({type:'insert', 'db_command':db_command, 'options':options, 'callback':callback});
- })
- } else if(!this.serverConfig.isConnected() && this.serverConfig.autoReconnect) {
- this._state = 'connecting';
- // Retry command
- __retryCommandOnFailure(this, this.retryMiliSeconds, this.numberOfRetries, __executeInsertCommand, db_command, options, callback);
- } else if(!this.serverConfig.isConnected() && !this.serverConfig.autoReconnect && callback) {
- // Fire an error to the callback if we are not connected and don't do reconnect
- if(callback) callback(new Error("no open connections"), null);
- } else {
- // If we have a
- if(this.serverConfig instanceof ReplSet && this.serverConfig._checkReplicaSet()) {
- // Execute insert command
- __executeInsertCommand(self, db_command, options, callback)
-
- var replSetGetStatusCommand = DbCommand.createAdminDbCommandSlaveOk(self, {replSetGetStatus:1}, {});
- // Do a freaking ping
- __executeQueryCommand(self, replSetGetStatusCommand, {readPreference:ReadPreference.SECONDARY_PREFERRED}, function(_replerr, _replresult) {
- // Force close if we are disconnected
- if(self._state == 'disconnected') {
- self.close(true);
- return;
- }
-
- // Handle the HA
- if(_replerr == null) {
- self.serverConfig._validateReplicaset(_replresult, self.auths);
- }
- })
- } else {
- __executeInsertCommand(self, db_command, options, callback)
- }
- }
-}
-
-/**
- * Update command is the same
- * @ignore
- * @api private
- */
-Db.prototype._executeUpdateCommand = Db.prototype._executeInsertCommand;
-/**
- * Remove command is the same
- * @ignore
- * @api private
- */
-Db.prototype._executeRemoveCommand = Db.prototype._executeInsertCommand;
-
-/**
- * Wrap a Mongo error document into an Error instance
- * @ignore
- * @api private
- */
-Db.prototype.wrap = function(error) {
- var msg = error.err || error.errmsg || error;
- var e = new Error(msg);
- e.name = 'MongoError';
-
- // Get all object keys
- var keys = Object.keys(error);
- // Populate error object with properties
- for(var i = 0; i < keys.length; i++) {
- e[keys[i]] = error[keys[i]];
- }
-
- return e;
-}
-
-/**
- * Default URL
- *
- * @classconstant DEFAULT_URL
- **/
-Db.DEFAULT_URL = 'mongodb://localhost:27017/default';
-
-/**
- * Connect to MongoDB using a url as documented at
- *
- * www.mongodb.org/display/DOCS/Connections
- *
- * Options
- * - **uri_decode_auth** {Boolean, default:false} uri decode the user name and password for authentication
- *
- * @param {String} url connection url for MongoDB.
- * @param {Object} [options] optional options for insert command
- * @param {Function} callback callback returns the initialized db.
- * @return {null}
- * @api public
- */
-Db.connect = function(url, options, callback) {
- var args = Array.prototype.slice.call(arguments, 1);
- callback = typeof args[args.length - 1] == 'function' ? args.pop() : null;
- options = args.length ? args.shift() : null;
- options = options || {};
- var serverOptions = options.server || {};
- var replSetServersOptions = options.replSet || options.replSetServers || {};
- var dbOptions = options.db || {};
-
- // Ensure empty socket option field
- serverOptions.socketOptions = serverOptions.socketOptions || {};
- replSetServersOptions.socketOptions = serverOptions.socketOptions || {};
-
- // Match the url format
- var urlRE = new RegExp('^mongo(?:db)?://(?:|([^@/]*)@)([^@/]*)(?:|/([^?]*)(?:|\\?([^?]*)))$');
- var match = (url || Db.DEFAULT_URL).match(urlRE);
- if (!match)
- throw Error("URL must be in the format mongodb://user:pass@host:port/dbname");
-
- var authPart = match[1] || '';
- var auth = authPart.split(':', 2);
- if(options['uri_decode_auth']){
- auth[0] = decodeURIComponent(auth[0]);
- if(auth[1]){
- auth[1] = decodeURIComponent(auth[1]);
- }
- }
-
- var hostPart = match[2];
- var dbname = match[3] || 'default';
- var urlOptions = (match[4] || '').split(/[&;]/);
-
- // Ugh, we have to figure out which options go to which constructor manually.
- urlOptions.forEach(function(opt) {
- if(!opt) return;
- var splitOpt = opt.split('='), name = splitOpt[0], value = splitOpt[1];
-
- // Options implementations
- switch(name) {
- case 'slaveOk':
- case 'slave_ok':
- serverOptions.slave_ok = (value == 'true');
- break;
- case 'poolSize':
- serverOptions.poolSize = Number(value);
- break;
- case 'autoReconnect':
- case 'auto_reconnect':
- serverOptions.auto_reconnect = (value == 'true');
- break;
- case 'ssl':
- serverOptions.ssl = (value == 'true');
- break;
- case 'replicaSet':
- case 'rs_name':
- replSetServersOptions.rs_name = value;
- break;
- case 'reconnectWait':
- replSetServersOptions.reconnectWait = Number(value);
- break;
- case 'retries':
- replSetServersOptions.retries = Number(value);
- break;
- case 'readSecondary':
- case 'read_secondary':
- replSetServersOptions.retries = Number(value);
- break;
- case 'safe':
- dbOptions.safe = (value == 'true');
- break;
- case 'nativeParser':
- case 'native_parser':
- dbOptions.native_parser = (value == 'true');
- break;
- case 'strict':
- dbOptions.strict = (value == 'true');
- break;
- case 'connectTimeoutMS':
- serverOptions.socketOptions.connectTimeoutMS = Number(value);
- replSetServersOptions.socketOptions.connectTimeoutMS = Number(value);
- break;
- case 'socketTimeoutMS':
- serverOptions.socketOptions.socketTimeoutMS = Number(value);
- replSetServersOptions.socketOptions.socketTimeoutMS = Number(value);
- break;
- default:
- break;
- }
- });
-
- var servers = hostPart.split(',').map(function(h) {
- var hostPort = h.split(':', 2);
- return new Server(hostPort[0] || 'localhost', hostPort[1] != null ? parseInt(hostPort[1]) : 27017, serverOptions);
- });
-
- var server;
- if (servers.length == 1) {
- server = servers[0];
- } else {
- server = new ReplSet(servers, replSetServersOptions);
- }
-
- var db = new Db(dbname, server, dbOptions);
- if(options.noOpen)
- return db;
-
- // If callback is null throw an exception
- if(callback == null) throw new Error("no callback function provided");
-
- db.open(function(err, db){
- if(err == null && authPart){
- db.authenticate(auth[0], auth[1], function(err, success){
- if(success){
- callback(null, db);
- } else {
- callback(err ? err : new Error('Could not authenticate user ' + auth[0]), db);
- }
- });
- } else {
- callback(err, db);
- }
- });
-}
-
-/**
- * State of the db connection
- * @ignore
- */
-Object.defineProperty(Db.prototype, "state", { enumerable: true
- , get: function () {
- return this.serverConfig._serverState;
- }
-});
-
-/**
- * Legacy support
- *
- * @ignore
- * @api private
- */
-exports.connect = Db.connect;
-exports.Db = Db;
-
-/**
- * Remove all listeners to the db instance.
- * @ignore
- * @api private
- */
-Db.prototype.removeAllEventListeners = function() {
- this.removeAllListeners("close");
- this.removeAllListeners("error");
- this.removeAllListeners("timeout");
- this.removeAllListeners("parseError");
- this.removeAllListeners("poolReady");
- this.removeAllListeners("message");
-}
diff --git a/CoAuthoring/node_modules/mongodb/lib/mongodb/gridfs/chunk.js b/CoAuthoring/node_modules/mongodb/lib/mongodb/gridfs/chunk.js
deleted file mode 100644
index 572d144653..0000000000
--- a/CoAuthoring/node_modules/mongodb/lib/mongodb/gridfs/chunk.js
+++ /dev/null
@@ -1,213 +0,0 @@
-var Binary = require('bson').Binary,
- ObjectID = require('bson').ObjectID;
-
-/**
- * Class for representing a single chunk in GridFS.
- *
- * @class
- *
- * @param file {GridStore} The {@link GridStore} object holding this chunk.
- * @param mongoObject {object} The mongo object representation of this chunk.
- *
- * @throws Error when the type of data field for {@link mongoObject} is not
- * supported. Currently supported types for data field are instances of
- * {@link String}, {@link Array}, {@link Binary} and {@link Binary}
- * from the bson module
- *
- * @see Chunk#buildMongoObject
- */
-var Chunk = exports.Chunk = function(file, mongoObject) {
- if(!(this instanceof Chunk)) return new Chunk(file, mongoObject);
-
- this.file = file;
- var self = this;
- var mongoObjectFinal = mongoObject == null ? {} : mongoObject;
-
- this.objectId = mongoObjectFinal._id == null ? new ObjectID() : mongoObjectFinal._id;
- this.chunkNumber = mongoObjectFinal.n == null ? 0 : mongoObjectFinal.n;
- this.data = new Binary();
-
- if(mongoObjectFinal.data == null) {
- } else if(typeof mongoObjectFinal.data == "string") {
- var buffer = new Buffer(mongoObjectFinal.data.length);
- buffer.write(mongoObjectFinal.data, 'binary', 0);
- this.data = new Binary(buffer);
- } else if(Array.isArray(mongoObjectFinal.data)) {
- var buffer = new Buffer(mongoObjectFinal.data.length);
- buffer.write(mongoObjectFinal.data.join(''), 'binary', 0);
- this.data = new Binary(buffer);
- } else if(mongoObjectFinal.data instanceof Binary || Object.prototype.toString.call(mongoObjectFinal.data) == "[object Binary]") {
- this.data = mongoObjectFinal.data;
- } else if(Buffer.isBuffer(mongoObjectFinal.data)) {
- } else {
- throw Error("Illegal chunk format");
- }
- // Update position
- this.internalPosition = 0;
-};
-
-/**
- * Writes a data to this object and advance the read/write head.
- *
- * @param data {string} the data to write
- * @param callback {function(*, GridStore)} This will be called after executing
- * this method. The first parameter will contain null and the second one
- * will contain a reference to this object.
- */
-Chunk.prototype.write = function(data, callback) {
- this.data.write(data, this.internalPosition);
- this.internalPosition = this.data.length();
- if(callback != null) return callback(null, this);
- return this;
-};
-
-/**
- * Reads data and advances the read/write head.
- *
- * @param length {number} The length of data to read.
- *
- * @return {string} The data read if the given length will not exceed the end of
- * the chunk. Returns an empty String otherwise.
- */
-Chunk.prototype.read = function(length) {
- // Default to full read if no index defined
- length = length == null || length == 0 ? this.length() : length;
-
- if(this.length() - this.internalPosition + 1 >= length) {
- var data = this.data.read(this.internalPosition, length);
- this.internalPosition = this.internalPosition + length;
- return data;
- } else {
- return '';
- }
-};
-
-Chunk.prototype.readSlice = function(length) {
- if ((this.length() - this.internalPosition) >= length) {
- var data = null;
- if (this.data.buffer != null) { //Pure BSON
- data = this.data.buffer.slice(this.internalPosition, this.internalPosition + length);
- } else { //Native BSON
- data = new Buffer(length);
- length = this.data.readInto(data, this.internalPosition);
- }
- this.internalPosition = this.internalPosition + length;
- return data;
- } else {
- return null;
- }
-};
-
-/**
- * Checks if the read/write head is at the end.
- *
- * @return {boolean} Whether the read/write head has reached the end of this
- * chunk.
- */
-Chunk.prototype.eof = function() {
- return this.internalPosition == this.length() ? true : false;
-};
-
-/**
- * Reads one character from the data of this chunk and advances the read/write
- * head.
- *
- * @return {string} a single character data read if the the read/write head is
- * not at the end of the chunk. Returns an empty String otherwise.
- */
-Chunk.prototype.getc = function() {
- return this.read(1);
-};
-
-/**
- * Clears the contents of the data in this chunk and resets the read/write head
- * to the initial position.
- */
-Chunk.prototype.rewind = function() {
- this.internalPosition = 0;
- this.data = new Binary();
-};
-
-/**
- * Saves this chunk to the database. Also overwrites existing entries having the
- * same id as this chunk.
- *
- * @param callback {function(*, GridStore)} This will be called after executing
- * this method. The first parameter will contain null and the second one
- * will contain a reference to this object.
- */
-Chunk.prototype.save = function(callback) {
- var self = this;
-
- self.file.chunkCollection(function(err, collection) {
- if(err) return callback(err);
-
- collection.remove({'_id':self.objectId}, {safe:true}, function(err, result) {
- if(err) return callback(err);
-
- if(self.data.length() > 0) {
- self.buildMongoObject(function(mongoObject) {
- collection.insert(mongoObject, {safe:true}, function(err, collection) {
- callback(err, self);
- });
- });
- } else {
- callback(null, self);
- }
- });
- });
-};
-
-/**
- * Creates a mongoDB object representation of this chunk.
- *
- * @param callback {function(Object)} This will be called after executing this
- * method. The object will be passed to the first parameter and will have
- * the structure:
- *
- *
- * {
- * '_id' : , // {number} id for this chunk
- * 'files_id' : , // {number} foreign key to the file collection
- * 'n' : , // {number} chunk number
- * 'data' : , // {bson#Binary} the chunk data itself
- * }
- *
- *
- * @see MongoDB GridFS Chunk Object Structure
- */
-Chunk.prototype.buildMongoObject = function(callback) {
- var mongoObject = {'_id': this.objectId,
- 'files_id': this.file.fileId,
- 'n': this.chunkNumber,
- 'data': this.data};
- callback(mongoObject);
-};
-
-/**
- * @return {number} the length of the data
- */
-Chunk.prototype.length = function() {
- return this.data.length();
-};
-
-/**
- * The position of the read/write head
- * @name position
- * @lends Chunk#
- * @field
- */
-Object.defineProperty(Chunk.prototype, "position", { enumerable: true
- , get: function () {
- return this.internalPosition;
- }
- , set: function(value) {
- this.internalPosition = value;
- }
-});
-
-/**
- * The default chunk size
- * @constant
- */
-Chunk.DEFAULT_CHUNK_SIZE = 1024 * 256;
diff --git a/CoAuthoring/node_modules/mongodb/lib/mongodb/gridfs/grid.js b/CoAuthoring/node_modules/mongodb/lib/mongodb/gridfs/grid.js
deleted file mode 100644
index d42c3d60a6..0000000000
--- a/CoAuthoring/node_modules/mongodb/lib/mongodb/gridfs/grid.js
+++ /dev/null
@@ -1,98 +0,0 @@
-var GridStore = require('./gridstore').GridStore,
- ObjectID = require('bson').ObjectID;
-
-/**
- * A class representation of a simple Grid interface.
- *
- * @class Represents the Grid.
- * @param {Db} db A database instance to interact with.
- * @param {String} [fsName] optional different root collection for GridFS.
- * @return {Grid}
- */
-function Grid(db, fsName) {
-
- if(!(this instanceof Grid)) return new Grid(db, fsName);
-
- this.db = db;
- this.fsName = fsName == null ? GridStore.DEFAULT_ROOT_COLLECTION : fsName;
-}
-
-/**
- * Puts binary data to the grid
- *
- * @param {Buffer} data buffer with Binary Data.
- * @param {Object} [options] the options for the files.
- * @callback {Function} this will be called after this method is executed. The first parameter will contain an Error object if an error occured or null otherwise. The second parameter will contain a reference to this object.
- * @return {null}
- * @api public
- */
-Grid.prototype.put = function(data, options, callback) {
- var self = this;
- var args = Array.prototype.slice.call(arguments, 1);
- callback = args.pop();
- options = args.length ? args.shift() : {};
- // If root is not defined add our default one
- options['root'] = options['root'] == null ? this.fsName : options['root'];
-
- // Return if we don't have a buffer object as data
- if(!(Buffer.isBuffer(data))) return callback(new Error("Data object must be a buffer object"), null);
- // Get filename if we are using it
- var filename = options['filename'];
- // Create gridstore
- var gridStore = new GridStore(this.db, filename, "w", options);
- gridStore.open(function(err, gridStore) {
- if(err) return callback(err, null);
-
- gridStore.write(data, function(err, result) {
- if(err) return callback(err, null);
-
- gridStore.close(function(err, result) {
- if(err) return callback(err, null);
- callback(null, result);
- })
- })
- })
-}
-
-/**
- * Get binary data to the grid
- *
- * @param {ObjectID} id ObjectID for file.
- * @callback {Function} this will be called after this method is executed. The first parameter will contain an Error object if an error occured or null otherwise. The second parameter will contain a reference to this object.
- * @return {null}
- * @api public
- */
-Grid.prototype.get = function(id, callback) {
- // Validate that we have a valid ObjectId
- if(!(id instanceof ObjectID)) return callback(new Error("Not a valid ObjectID", null));
- // Create gridstore
- var gridStore = new GridStore(this.db, id, "r", {root:this.fsName});
- gridStore.open(function(err, gridStore) {
- if(err) return callback(err, null);
-
- // Return the data
- gridStore.read(function(err, data) {
- return callback(err, data)
- });
- })
-}
-
-/**
- * Delete file from grid
- *
- * @param {ObjectID} id ObjectID for file.
- * @callback {Function} this will be called after this method is executed. The first parameter will contain an Error object if an error occured or null otherwise. The second parameter will contain a reference to this object.
- * @return {null}
- * @api public
- */
-Grid.prototype.delete = function(id, callback) {
- // Validate that we have a valid ObjectId
- if(!(id instanceof ObjectID)) return callback(new Error("Not a valid ObjectID", null));
- // Create gridstore
- GridStore.unlink(this.db, id, {root:this.fsName}, function(err, result) {
- if(err) return callback(err, false);
- return callback(null, true);
- });
-}
-
-exports.Grid = Grid;
diff --git a/CoAuthoring/node_modules/mongodb/lib/mongodb/gridfs/gridstore.js b/CoAuthoring/node_modules/mongodb/lib/mongodb/gridfs/gridstore.js
deleted file mode 100644
index 0c54f62f35..0000000000
--- a/CoAuthoring/node_modules/mongodb/lib/mongodb/gridfs/gridstore.js
+++ /dev/null
@@ -1,1464 +0,0 @@
-/**
- * @fileOverview GridFS is a tool for MongoDB to store files to the database.
- * Because of the restrictions of the object size the database can hold, a
- * facility to split a file into several chunks is needed. The {@link GridStore}
- * class offers a simplified api to interact with files while managing the
- * chunks of split files behind the scenes. More information about GridFS can be
- * found here .
- */
-var Chunk = require('./chunk').Chunk,
- DbCommand = require('../commands/db_command').DbCommand,
- ObjectID = require('bson').ObjectID,
- Buffer = require('buffer').Buffer,
- fs = require('fs'),
- util = require('util'),
- inherits = util.inherits,
- ReadStream = require('./readstream').ReadStream,
- Stream = require('stream');
-
-var REFERENCE_BY_FILENAME = 0,
- REFERENCE_BY_ID = 1;
-
-/**
- * A class representation of a file stored in GridFS.
- *
- * Modes
- * - **"r"** - read only. This is the default mode.
- * - **"w"** - write in truncate mode. Existing data will be overwriten.
- * - **w+"** - write in edit mode.
- *
- * Options
- * - **root** {String}, root collection to use. Defaults to **{GridStore.DEFAULT_ROOT_COLLECTION}**.
- * - **content_type** {String}, mime type of the file. Defaults to **{GridStore.DEFAULT_CONTENT_TYPE}**.
- * - **chunk_size** {Number}, size for the chunk. Defaults to **{Chunk.DEFAULT_CHUNK_SIZE}**.
- * - **metadata** {Object}, arbitrary data the user wants to store.
- *
- * @class Represents the GridStore.
- * @param {Db} db A database instance to interact with.
- * @param {ObjectID} id an unique ObjectID for this file
- * @param {String} [filename] optional a filename for this file, no unique constrain on the field
- * @param {String} mode set the mode for this file.
- * @param {Object} options optional properties to specify. Recognized keys:
- * @return {GridStore}
- */
-var GridStore = function GridStore(db, id, filename, mode, options) {
- if(!(this instanceof GridStore)) return new GridStore(db, id, filename, mode, options);
-
- var self = this;
- this.db = db;
-
- // Call stream constructor
- if(typeof Stream == 'function') {
- Stream.call(this);
- } else {
- // 0.4.X backward compatibility fix
- Stream.Stream.call(this);
- }
-
- // Handle options
- if(options == null) options = {};
- // Handle mode
- if(mode == null) {
- mode = filename;
- filename = null;
- } else if(typeof mode == 'object') {
- options = mode;
- mode = filename;
- filename = null;
- }
-
- // Handle id
- if(id instanceof ObjectID && (typeof filename == 'string' || filename == null)) {
- this.referenceBy = 1;
- this.fileId = id;
- this.filename = filename;
- } else if(!(id instanceof ObjectID) && typeof id == 'string' && mode.indexOf("w") != null) {
- this.referenceBy = 0;
- this.fileId = new ObjectID();
- this.filename = id;
- } else if(!(id instanceof ObjectID) && typeof id == 'string' && mode.indexOf("r") != null) {
- this.referenceBy = 0;
- this.filename = filename;
- } else {
- this.referenceBy = 1;
- this.fileId = id;
- this.filename = filename;
- }
-
- // Set up the rest
- this.mode = mode == null ? "r" : mode;
- this.options = options == null ? {} : options;
- this.root = this.options['root'] == null ? exports.GridStore.DEFAULT_ROOT_COLLECTION : this.options['root'];
- this.position = 0;
- // Set default chunk size
- this.internalChunkSize = this.options['chunkSize'] == null ? Chunk.DEFAULT_CHUNK_SIZE : this.options['chunkSize'];
- // Previous chunk size
- this.previousChunkSize = 0;
-}
-
-/**
- * Code for the streaming capabilities of the gridstore object
- * Most code from Aaron heckmanns project https://github.com/aheckmann/gridfs-stream
- * Modified to work on the gridstore object itself
- * @ignore
- */
-if(typeof Stream == 'function') {
- GridStore.prototype = { __proto__: Stream.prototype }
-} else {
- // Node 0.4.X compatibility code
- GridStore.prototype = { __proto__: Stream.Stream.prototype }
-}
-
-// Move pipe to _pipe
-GridStore.prototype._pipe = GridStore.prototype.pipe;
-
-/**
- * Opens the file from the database and initialize this object. Also creates a
- * new one if file does not exist.
- *
- * @param {Function} callback this will be called after executing this method. The first parameter will contain an **{Error}** object and the second parameter will be null if an error occured. Otherwise, the first parameter will be null and the second will contain the reference to this object.
- * @return {null}
- * @api public
- */
-GridStore.prototype.open = function(callback) {
- if( this.mode != "w" && this.mode != "w+" && this.mode != "r"){
- callback(new Error("Illegal mode " + this.mode), null);
- return;
- }
-
- var self = this;
-
- if((self.mode == "w" || self.mode == "w+") && self.db.serverConfig.primary != null) {
- // Get files collection
- self.collection(function(err, collection) {
- if(err) return callback(err);
-
- // Put index on filename
- collection.ensureIndex([['filename', 1]], function(err, index) {
- if(err) return callback(err);
-
- // Get chunk collection
- self.chunkCollection(function(err, chunkCollection) {
- if(err) return callback(err);
-
- // Ensure index on chunk collection
- chunkCollection.ensureIndex([['files_id', 1], ['n', 1]], function(err, index) {
- if(err) return callback(err);
- _open(self, callback);
- });
- });
- });
- });
- } else {
- // Open the gridstore
- _open(self, callback);
- }
-};
-
-/**
- * Hidding the _open function
- * @ignore
- * @api private
- */
-var _open = function(self, callback) {
- self.collection(function(err, collection) {
- if(err!==null) {
- callback(new Error("at collection: "+err), null);
- return;
- }
-
- // Create the query
- var query = self.referenceBy == REFERENCE_BY_ID ? {_id:self.fileId} : {filename:self.filename};
- query = null == self.fileId && this.filename == null ? null : query;
-
- // Fetch the chunks
- if(query != null) {
- collection.find(query, function(err, cursor) {
- if(err) return error(err);
-
- // Fetch the file
- cursor.nextObject(function(err, doc) {
- if(err) return error(err);
-
- // Check if the collection for the files exists otherwise prepare the new one
- if(doc != null) {
- self.fileId = doc._id;
- self.filename = doc.filename;
- self.contentType = doc.contentType;
- self.internalChunkSize = doc.chunkSize;
- self.uploadDate = doc.uploadDate;
- self.aliases = doc.aliases;
- self.length = doc.length;
- self.metadata = doc.metadata;
- self.internalMd5 = doc.md5;
- } else {
- self.fileId = self.fileId == null ? new ObjectID() : self.fileId;
- self.contentType = exports.GridStore.DEFAULT_CONTENT_TYPE;
- self.internalChunkSize = self.internalChunkSize == null ? Chunk.DEFAULT_CHUNK_SIZE : self.internalChunkSize;
- self.length = 0;
- }
-
- // Process the mode of the object
- if(self.mode == "r") {
- nthChunk(self, 0, function(err, chunk) {
- if(err) return error(err);
- self.currentChunk = chunk;
- self.position = 0;
- callback(null, self);
- });
- } else if(self.mode == "w") {
- // Delete any existing chunks
- deleteChunks(self, function(err, result) {
- if(err) return error(err);
- self.currentChunk = new Chunk(self, {'n':0});
- self.contentType = self.options['content_type'] == null ? self.contentType : self.options['content_type'];
- self.internalChunkSize = self.options['chunk_size'] == null ? self.internalChunkSize : self.options['chunk_size'];
- self.metadata = self.options['metadata'] == null ? self.metadata : self.options['metadata'];
- self.position = 0;
- callback(null, self);
- });
- } else if(self.mode == "w+") {
- nthChunk(self, lastChunkNumber(self), function(err, chunk) {
- if(err) return error(err);
- // Set the current chunk
- self.currentChunk = chunk == null ? new Chunk(self, {'n':0}) : chunk;
- self.currentChunk.position = self.currentChunk.data.length();
- self.metadata = self.options['metadata'] == null ? self.metadata : self.options['metadata'];
- self.position = self.length;
- callback(null, self);
- });
- }
- });
- });
- } else {
- // Write only mode
- self.fileId = null == self.fileId ? new ObjectID() : self.fileId;
- self.contentType = exports.GridStore.DEFAULT_CONTENT_TYPE;
- self.internalChunkSize = self.internalChunkSize == null ? Chunk.DEFAULT_CHUNK_SIZE : self.internalChunkSize;
- self.length = 0;
-
- self.chunkCollection(function(err, collection2) {
- if(err) return error(err);
-
- // No file exists set up write mode
- if(self.mode == "w") {
- // Delete any existing chunks
- deleteChunks(self, function(err, result) {
- if(err) return error(err);
- self.currentChunk = new Chunk(self, {'n':0});
- self.contentType = self.options['content_type'] == null ? self.contentType : self.options['content_type'];
- self.internalChunkSize = self.options['chunk_size'] == null ? self.internalChunkSize : self.options['chunk_size'];
- self.metadata = self.options['metadata'] == null ? self.metadata : self.options['metadata'];
- self.position = 0;
- callback(null, self);
- });
- } else if(self.mode == "w+") {
- nthChunk(self, lastChunkNumber(self), function(err, chunk) {
- if(err) return error(err);
- // Set the current chunk
- self.currentChunk = chunk == null ? new Chunk(self, {'n':0}) : chunk;
- self.currentChunk.position = self.currentChunk.data.length();
- self.metadata = self.options['metadata'] == null ? self.metadata : self.options['metadata'];
- self.position = self.length;
- callback(null, self);
- });
- }
- });
- }
- });
-
- // only pass error to callback once
- function error (err) {
- if(error.err) return;
- callback(error.err = err);
- }
-};
-
-/**
- * Stores a file from the file system to the GridFS database.
- *
- * @param {String|Buffer|FileHandle} file the file to store.
- * @param {Function} callback this will be called after this method is executed. The first parameter will be null and the the second will contain the reference to this object.
- * @return {null}
- * @api public
- */
-GridStore.prototype.writeFile = function (file, callback) {
- var self = this;
- if (typeof file === 'string') {
- fs.open(file, 'r', 0666, function (err, fd) {
- if(err) return callback(err);
- self.writeFile(fd, callback);
- });
- return;
- }
-
- self.open(function (err, self) {
- if(err) return callback(err);
-
- fs.fstat(file, function (err, stats) {
- if(err) return callback(err);
-
- var offset = 0;
- var index = 0;
- var numberOfChunksLeft = Math.min(stats.size / self.chunkSize);
-
- // Write a chunk
- var writeChunk = function() {
- fs.read(file, self.chunkSize, offset, 'binary', function(err, data, bytesRead) {
- if(err) return callback(err);
-
- offset = offset + bytesRead;
-
- // Create a new chunk for the data
- var chunk = new Chunk(self, {n:index++});
- chunk.write(data, function(err, chunk) {
- if(err) return callback(err);
-
- chunk.save(function(err, result) {
- if(err) return callback(err);
-
- self.position = self.position + data.length;
-
- // Point to current chunk
- self.currentChunk = chunk;
-
- if(offset >= stats.size) {
- fs.close(file);
- self.close(callback);
- } else {
- return process.nextTick(writeChunk);
- }
- });
- });
- });
- }
-
- // Process the first write
- process.nextTick(writeChunk);
- });
- });
-};
-
-/**
- * Writes some data. This method will work properly only if initialized with mode
- * "w" or "w+".
- *
- * @param string {string} The data to write.
- * @param close {boolean=false} opt_argument Closes this file after writing if
- * true.
- * @param callback {function(*, GridStore)} This will be called after executing
- * this method. The first parameter will contain null and the second one
- * will contain a reference to this object.
- *
- * @ignore
- * @api private
- */
-var writeBuffer = function(self, buffer, close, callback) {
- if(typeof close === "function") { callback = close; close = null; }
- var finalClose = (close == null) ? false : close;
-
- if(self.mode[0] != "w") {
- callback(new Error((self.referenceBy == REFERENCE_BY_ID ? self.toHexString() : self.filename) + " not opened for writing"), null);
- } else {
- if(self.currentChunk.position + buffer.length >= self.chunkSize) {
- // Write out the current Chunk and then keep writing until we have less data left than a chunkSize left
- // to a new chunk (recursively)
- var previousChunkNumber = self.currentChunk.chunkNumber;
- var leftOverDataSize = self.chunkSize - self.currentChunk.position;
- var firstChunkData = buffer.slice(0, leftOverDataSize);
- var leftOverData = buffer.slice(leftOverDataSize);
- // A list of chunks to write out
- var chunksToWrite = [self.currentChunk.write(firstChunkData)];
- // If we have more data left than the chunk size let's keep writing new chunks
- while(leftOverData.length >= self.chunkSize) {
- // Create a new chunk and write to it
- var newChunk = new Chunk(self, {'n': (previousChunkNumber + 1)});
- var firstChunkData = leftOverData.slice(0, self.chunkSize);
- leftOverData = leftOverData.slice(self.chunkSize);
- // Update chunk number
- previousChunkNumber = previousChunkNumber + 1;
- // Write data
- newChunk.write(firstChunkData);
- // Push chunk to save list
- chunksToWrite.push(newChunk);
- }
-
- // Set current chunk with remaining data
- self.currentChunk = new Chunk(self, {'n': (previousChunkNumber + 1)});
- // If we have left over data write it
- if(leftOverData.length > 0) self.currentChunk.write(leftOverData);
-
- // Update the position for the gridstore
- self.position = self.position + buffer.length;
- // Total number of chunks to write
- var numberOfChunksToWrite = chunksToWrite.length;
- // Write out all the chunks and then return
- for(var i = 0; i < chunksToWrite.length; i++) {
- var chunk = chunksToWrite[i];
- chunk.save(function(err, result) {
- if(err) return callback(err);
-
- numberOfChunksToWrite = numberOfChunksToWrite - 1;
-
- if(numberOfChunksToWrite <= 0) {
- return callback(null, self);
- }
- })
- }
- } else {
- // Update the position for the gridstore
- self.position = self.position + buffer.length;
- // We have less data than the chunk size just write it and callback
- self.currentChunk.write(buffer);
- callback(null, self);
- }
- }
-};
-
-/**
- * Creates a mongoDB object representation of this object.
- *
- * @param callback {function(object)} This will be called after executing this
- * method. The object will be passed to the first parameter and will have
- * the structure:
- *
- *
- * {
- * '_id' : , // {number} id for this file
- * 'filename' : , // {string} name for this file
- * 'contentType' : , // {string} mime type for this file
- * 'length' : , // {number} size of this file?
- * 'chunksize' : , // {number} chunk size used by this file
- * 'uploadDate' : , // {Date}
- * 'aliases' : , // {array of string}
- * 'metadata' : , // {string}
- * }
- *
- *
- * @ignore
- * @api private
- */
-var buildMongoObject = function(self, callback) {
- // Keeps the final chunk number
- var chunkNumber = 0;
- var previousChunkSize = self.previousChunkSize;
- // Get the correct chunk Number, if we have an empty chunk return the previous chunk number
- if(null != self.currentChunk && self.currentChunk.chunkNumber > 0 && self.currentChunk.position == 0) {
- chunkNumber = self.currentChunk.chunkNumber - 1;
- } else {
- chunkNumber = self.currentChunk.chunkNumber;
- previousChunkSize = self.currentChunk.position;
- }
-
- // Calcuate the length
- var length = self.currentChunk != null ? (chunkNumber * self.chunkSize + previousChunkSize) : 0;
- var mongoObject = {
- '_id': self.fileId,
- 'filename': self.filename,
- 'contentType': self.contentType,
- 'length': self.position ? self.position : 0,
- 'chunkSize': self.chunkSize,
- 'uploadDate': self.uploadDate,
- 'aliases': self.aliases,
- 'metadata': self.metadata
- };
-
- var md5Command = {filemd5:self.fileId, root:self.root};
- self.db.command(md5Command, function(err, results) {
- mongoObject.md5 = results.md5;
- callback(mongoObject);
- });
-};
-
-/**
- * Saves this file to the database. This will overwrite the old entry if it
- * already exists. This will work properly only if mode was initialized to
- * "w" or "w+".
- *
- * @param {Function} callback this will be called after executing this method. Passes an **{Error}** object to the first parameter and null to the second if an error occured. Otherwise, passes null to the first and a reference to this object to the second.
- * @return {null}
- * @api public
- */
-GridStore.prototype.close = function(callback) {
- var self = this;
-
- if(self.mode[0] == "w") {
- if(self.currentChunk != null && self.currentChunk.position > 0) {
- self.currentChunk.save(function(err, chunk) {
- if(err) return callback(err);
-
- self.collection(function(err, files) {
- if(err) return callback(err);
-
- // Build the mongo object
- if(self.uploadDate != null) {
- files.remove({'_id':self.fileId}, {safe:true}, function(err, collection) {
- if(err) return callback(err);
-
- buildMongoObject(self, function(mongoObject) {
- files.save(mongoObject, {safe:true}, function(err) {
- callback(err, mongoObject);
- });
- });
- });
- } else {
- self.uploadDate = new Date();
- buildMongoObject(self, function(mongoObject) {
- files.save(mongoObject, {safe:true}, function(err) {
- callback(err, mongoObject);
- });
- });
- }
- });
- });
- } else {
- self.collection(function(err, files) {
- if(err) return callback(err);
-
- self.uploadDate = new Date();
- buildMongoObject(self, function(mongoObject) {
- files.save(mongoObject, {safe:true}, function(err) {
- callback(err, mongoObject);
- });
- });
- });
- }
- } else if(self.mode[0] == "r") {
- callback(null, null);
- } else {
- callback(new Error("Illegal mode " + self.mode), null);
- }
-};
-
-/**
- * Gets the nth chunk of this file.
- *
- * @param chunkNumber {number} The nth chunk to retrieve.
- * @param callback {function(*, Chunk|object)} This will be called after
- * executing this method. null will be passed to the first parameter while
- * a new {@link Chunk} instance will be passed to the second parameter if
- * the chunk was found or an empty object {} if not.
- *
- * @ignore
- * @api private
- */
-var nthChunk = function(self, chunkNumber, callback) {
- self.chunkCollection(function(err, collection) {
- if(err) return callback(err);
-
- collection.find({'files_id':self.fileId, 'n':chunkNumber}, function(err, cursor) {
- if(err) return callback(err);
-
- cursor.nextObject(function(err, chunk) {
- if(err) return callback(err);
-
- var finalChunk = chunk == null ? {} : chunk;
- callback(null, new Chunk(self, finalChunk));
- });
- });
- });
-};
-
-/**
- *
- * @ignore
- * @api private
- */
-GridStore.prototype._nthChunk = function(chunkNumber, callback) {
- nthChunk(this, chunkNumber, callback);
-}
-
-/**
- * @return {Number} The last chunk number of this file.
- *
- * @ignore
- * @api private
- */
-var lastChunkNumber = function(self) {
- return Math.floor(self.length/self.chunkSize);
-};
-
-/**
- * Retrieve this file's chunks collection.
- *
- * @param {Function} callback this will be called after executing this method. An exception object will be passed to the first parameter when an error occured or null otherwise. A new **{Collection}** object will be passed to the second parameter if no error occured.
- * @return {null}
- * @api public
- */
-GridStore.prototype.chunkCollection = function(callback) {
- this.db.collection((this.root + ".chunks"), callback);
-};
-
-/**
- * Deletes all the chunks of this file in the database.
- *
- * @param callback {function(*, boolean)} This will be called after this method
- * executes. Passes null to the first and true to the second argument.
- *
- * @ignore
- * @api private
- */
-var deleteChunks = function(self, callback) {
- if(self.fileId != null) {
- self.chunkCollection(function(err, collection) {
- if(err) return callback(err, false);
- collection.remove({'files_id':self.fileId}, {safe:true}, function(err, result) {
- if(err) return callback(err, false);
- callback(null, true);
- });
- });
- } else {
- callback(null, true);
- }
-};
-
-/**
- * Deletes all the chunks of this file in the database.
- *
- * @param {Function} callback this will be called after this method executes. Passes null to the first and true to the second argument.
- * @return {null}
- * @api public
- */
-GridStore.prototype.unlink = function(callback) {
- var self = this;
- deleteChunks(this, function(err) {
- if(err!==null) {
- err.message = "at deleteChunks: " + err.message;
- return callback(err);
- }
-
- self.collection(function(err, collection) {
- if(err!==null) {
- err.message = "at collection: " + err.message;
- return callback(err);
- }
-
- collection.remove({'_id':self.fileId}, {safe:true}, function(err) {
- callback(err, self);
- });
- });
- });
-};
-
-/**
- * Retrieves the file collection associated with this object.
- *
- * @param {Function} callback this will be called after executing this method. An exception object will be passed to the first parameter when an error occured or null otherwise. A new **{Collection}** object will be passed to the second parameter if no error occured.
- * @return {null}
- * @api public
- */
-GridStore.prototype.collection = function(callback) {
- this.db.collection(this.root + ".files", callback);
-};
-
-/**
- * Reads the data of this file.
- *
- * @param {String} [separator] the character to be recognized as the newline separator.
- * @param {Function} callback This will be called after this method is executed. The first parameter will be null and the second parameter will contain an array of strings representing the entire data, each element representing a line including the separator character.
- * @return {null}
- * @api public
- */
-GridStore.prototype.readlines = function(separator, callback) {
- var args = Array.prototype.slice.call(arguments, 0);
- callback = args.pop();
- separator = args.length ? args.shift() : "\n";
-
- this.read(function(err, data) {
- if(err) return callback(err);
-
- var items = data.toString().split(separator);
- items = items.length > 0 ? items.splice(0, items.length - 1) : [];
- for(var i = 0; i < items.length; i++) {
- items[i] = items[i] + separator;
- }
-
- callback(null, items);
- });
-};
-
-/**
- * Deletes all the chunks of this file in the database if mode was set to "w" or
- * "w+" and resets the read/write head to the initial position.
- *
- * @param {Function} callback this will be called after executing this method. The first parameter will contain null and the second one will contain a reference to this object.
- * @return {null}
- * @api public
- */
-GridStore.prototype.rewind = function(callback) {
- var self = this;
-
- if(this.currentChunk.chunkNumber != 0) {
- if(this.mode[0] == "w") {
- deleteChunks(self, function(err, gridStore) {
- if(err) return callback(err);
- self.currentChunk = new Chunk(self, {'n': 0});
- self.position = 0;
- callback(null, self);
- });
- } else {
- self.currentChunk(0, function(err, chunk) {
- if(err) return callback(err);
- self.currentChunk = chunk;
- self.currentChunk.rewind();
- self.position = 0;
- callback(null, self);
- });
- }
- } else {
- self.currentChunk.rewind();
- self.position = 0;
- callback(null, self);
- }
-};
-
-/**
- * Retrieves the contents of this file and advances the read/write head. Works with Buffers only.
- *
- * There are 3 signatures for this method:
- *
- * (callback)
- * (length, callback)
- * (length, buffer, callback)
- *
- * @param {Number} [length] the number of characters to read. Reads all the characters from the read/write head to the EOF if not specified.
- * @param {String|Buffer} [buffer] a string to hold temporary data. This is used for storing the string data read so far when recursively calling this method.
- * @param {Function} callback this will be called after this method is executed. null will be passed to the first parameter and a string containing the contents of the buffer concatenated with the contents read from this file will be passed to the second.
- * @return {null}
- * @api public
- */
-GridStore.prototype.read = function(length, buffer, callback) {
- var self = this;
-
- var args = Array.prototype.slice.call(arguments, 0);
- callback = args.pop();
- length = args.length ? args.shift() : null;
- buffer = args.length ? args.shift() : null;
-
- // The data is a c-terminated string and thus the length - 1
- var finalLength = length == null ? self.length - self.position : length;
- var finalBuffer = buffer == null ? new Buffer(finalLength) : buffer;
- // Add a index to buffer to keep track of writing position or apply current index
- finalBuffer._index = buffer != null && buffer._index != null ? buffer._index : 0;
-
- if((self.currentChunk.length() - self.currentChunk.position + finalBuffer._index) >= finalLength) {
- var slice = self.currentChunk.readSlice(finalLength - finalBuffer._index);
- // Copy content to final buffer
- slice.copy(finalBuffer, finalBuffer._index);
- // Update internal position
- self.position = finalBuffer.length;
- // Check if we don't have a file at all
- if(finalLength == 0 && finalBuffer.length == 0) return callback(new Error("File does not exist"), null);
- // Else return data
- callback(null, finalBuffer);
- } else {
- var slice = self.currentChunk.readSlice(self.currentChunk.length() - self.currentChunk.position);
- // Copy content to final buffer
- slice.copy(finalBuffer, finalBuffer._index);
- // Update index position
- finalBuffer._index += slice.length;
-
- // Load next chunk and read more
- nthChunk(self, self.currentChunk.chunkNumber + 1, function(err, chunk) {
- if(err) return callback(err);
-
- if(chunk.length() > 0) {
- self.currentChunk = chunk;
- self.read(length, finalBuffer, callback);
- } else {
- if (finalBuffer._index > 0) {
- callback(null, finalBuffer)
- } else {
- callback(new Error("no chunks found for file, possibly corrupt"), null);
- }
- }
- });
- }
-}
-
-/**
- * Retrieves the position of the read/write head of this file.
- *
- * @param {Function} callback This gets called after this method terminates. null is passed to the first parameter and the position is passed to the second.
- * @return {null}
- * @api public
- */
-GridStore.prototype.tell = function(callback) {
- callback(null, this.position);
-};
-
-/**
- * Moves the read/write head to a new location.
- *
- * There are 3 signatures for this method
- *
- * Seek Location Modes
- * - **GridStore.IO_SEEK_SET**, **(default)** set the position from the start of the file.
- * - **GridStore.IO_SEEK_CUR**, set the position from the current position in the file.
- * - **GridStore.IO_SEEK_END**, set the position from the end of the file.
- *
- * @param {Number} [position] the position to seek to
- * @param {Number} [seekLocation] seek mode. Use one of the Seek Location modes.
- * @param {Function} callback this will be called after executing this method. The first parameter will contain null and the second one will contain a reference to this object.
- * @return {null}
- * @api public
- */
-GridStore.prototype.seek = function(position, seekLocation, callback) {
- var self = this;
-
- var args = Array.prototype.slice.call(arguments, 1);
- callback = args.pop();
- seekLocation = args.length ? args.shift() : null;
-
- var seekLocationFinal = seekLocation == null ? exports.GridStore.IO_SEEK_SET : seekLocation;
- var finalPosition = position;
- var targetPosition = 0;
- if(seekLocationFinal == exports.GridStore.IO_SEEK_CUR) {
- targetPosition = self.position + finalPosition;
- } else if(seekLocationFinal == exports.GridStore.IO_SEEK_END) {
- targetPosition = self.length + finalPosition;
- } else {
- targetPosition = finalPosition;
- }
-
- var newChunkNumber = Math.floor(targetPosition/self.chunkSize);
- if(newChunkNumber != self.currentChunk.chunkNumber) {
- var seekChunk = function() {
- nthChunk(self, newChunkNumber, function(err, chunk) {
- self.currentChunk = chunk;
- self.position = targetPosition;
- self.currentChunk.position = (self.position % self.chunkSize);
- callback(err, self);
- });
- };
-
- if(self.mode[0] == 'w') {
- self.currentChunk.save(function(err) {
- if(err) return callback(err);
- seekChunk();
- });
- } else {
- seekChunk();
- }
- } else {
- self.position = targetPosition;
- self.currentChunk.position = (self.position % self.chunkSize);
- callback(null, self);
- }
-};
-
-/**
- * Verify if the file is at EOF.
- *
- * @return {Boolean} true if the read/write head is at the end of this file.
- * @api public
- */
-GridStore.prototype.eof = function() {
- return this.position == this.length ? true : false;
-};
-
-/**
- * Retrieves a single character from this file.
- *
- * @param {Function} callback this gets called after this method is executed. Passes null to the first parameter and the character read to the second or null to the second if the read/write head is at the end of the file.
- * @return {null}
- * @api public
- */
-GridStore.prototype.getc = function(callback) {
- var self = this;
-
- if(self.eof()) {
- callback(null, null);
- } else if(self.currentChunk.eof()) {
- nthChunk(self, self.currentChunk.chunkNumber + 1, function(err, chunk) {
- self.currentChunk = chunk;
- self.position = self.position + 1;
- callback(err, self.currentChunk.getc());
- });
- } else {
- self.position = self.position + 1;
- callback(null, self.currentChunk.getc());
- }
-};
-
-/**
- * Writes a string to the file with a newline character appended at the end if
- * the given string does not have one.
- *
- * @param {String} string the string to write.
- * @param {Function} callback this will be called after executing this method. The first parameter will contain null and the second one will contain a reference to this object.
- * @return {null}
- * @api public
- */
-GridStore.prototype.puts = function(string, callback) {
- var finalString = string.match(/\n$/) == null ? string + "\n" : string;
- this.write(finalString, callback);
-};
-
-/**
- * Returns read stream based on this GridStore file
- *
- * Events
- * - **data** {function(item) {}} the data event triggers when a document is ready.
- * - **end** {function() {}} the end event triggers when there is no more documents available.
- * - **close** {function() {}} the close event triggers when the stream is closed.
- * - **error** {function(err) {}} the error event triggers if an error happens.
- *
- * @param {Boolean} autoclose if true current GridStore will be closed when EOF and 'close' event will be fired
- * @return {null}
- * @api public
- */
-GridStore.prototype.stream = function(autoclose) {
- return new ReadStream(autoclose, this);
-};
-
-/**
-* The collection to be used for holding the files and chunks collection.
-*
-* @classconstant DEFAULT_ROOT_COLLECTION
-**/
-GridStore.DEFAULT_ROOT_COLLECTION = 'fs';
-
-/**
-* Default file mime type
-*
-* @classconstant DEFAULT_CONTENT_TYPE
-**/
-GridStore.DEFAULT_CONTENT_TYPE = 'binary/octet-stream';
-
-/**
-* Seek mode where the given length is absolute.
-*
-* @classconstant IO_SEEK_SET
-**/
-GridStore.IO_SEEK_SET = 0;
-
-/**
-* Seek mode where the given length is an offset to the current read/write head.
-*
-* @classconstant IO_SEEK_CUR
-**/
-GridStore.IO_SEEK_CUR = 1;
-
-/**
-* Seek mode where the given length is an offset to the end of the file.
-*
-* @classconstant IO_SEEK_END
-**/
-GridStore.IO_SEEK_END = 2;
-
-/**
- * Checks if a file exists in the database.
- *
- * @param {Db} db the database to query.
- * @param {String} name the name of the file to look for.
- * @param {String} [rootCollection] the root collection that holds the files and chunks collection. Defaults to **{GridStore.DEFAULT_ROOT_COLLECTION}**.
- * @param {Function} callback this will be called after this method executes. Passes null to the first and passes true to the second if the file exists and false otherwise.
- * @return {null}
- * @api public
- */
-GridStore.exist = function(db, fileIdObject, rootCollection, callback) {
- var args = Array.prototype.slice.call(arguments, 2);
- callback = args.pop();
- rootCollection = args.length ? args.shift() : null;
-
- // Fetch collection
- var rootCollectionFinal = rootCollection != null ? rootCollection : GridStore.DEFAULT_ROOT_COLLECTION;
- db.collection(rootCollectionFinal + ".files", function(err, collection) {
- if(err) return callback(err);
-
- // Build query
- var query = (typeof fileIdObject == 'string' || Object.prototype.toString.call(fileIdObject) == '[object RegExp]' )
- ? {'filename':fileIdObject}
- : {'_id':fileIdObject}; // Attempt to locate file
-
- collection.find(query, function(err, cursor) {
- if(err) return callback(err);
-
- cursor.nextObject(function(err, item) {
- if(err) return callback(err);
- callback(null, item == null ? false : true);
- });
- });
- });
-};
-
-/**
- * Gets the list of files stored in the GridFS.
- *
- * @param {Db} db the database to query.
- * @param {String} [rootCollection] the root collection that holds the files and chunks collection. Defaults to **{GridStore.DEFAULT_ROOT_COLLECTION}**.
- * @param {Function} callback this will be called after this method executes. Passes null to the first and passes an array of strings containing the names of the files.
- * @return {null}
- * @api public
- */
-GridStore.list = function(db, rootCollection, options, callback) {
- var args = Array.prototype.slice.call(arguments, 1);
- callback = args.pop();
- rootCollection = args.length ? args.shift() : null;
- options = args.length ? args.shift() : {};
-
- // Ensure we have correct values
- if(rootCollection != null && typeof rootCollection == 'object') {
- options = rootCollection;
- rootCollection = null;
- }
-
- // Check if we are returning by id not filename
- var byId = options['id'] != null ? options['id'] : false;
- // Fetch item
- var rootCollectionFinal = rootCollection != null ? rootCollection : GridStore.DEFAULT_ROOT_COLLECTION;
- var items = [];
- db.collection((rootCollectionFinal + ".files"), function(err, collection) {
- if(err) return callback(err);
-
- collection.find(function(err, cursor) {
- if(err) return callback(err);
-
- cursor.each(function(err, item) {
- if(item != null) {
- items.push(byId ? item._id : item.filename);
- } else {
- callback(err, items);
- }
- });
- });
- });
-};
-
-/**
- * Reads the contents of a file.
- *
- * This method has the following signatures
- *
- * (db, name, callback)
- * (db, name, length, callback)
- * (db, name, length, offset, callback)
- * (db, name, length, offset, options, callback)
- *
- * @param {Db} db the database to query.
- * @param {String} name the name of the file.
- * @param {Number} [length] the size of data to read.
- * @param {Number} [offset] the offset from the head of the file of which to start reading from.
- * @param {Object} [options] the options for the file.
- * @param {Function} callback this will be called after this method executes. A string with an error message will be passed to the first parameter when the length and offset combination exceeds the length of the file while an Error object will be passed if other forms of error occured, otherwise, a string is passed. The second parameter will contain the data read if successful or null if an error occured.
- * @return {null}
- * @api public
- */
-GridStore.read = function(db, name, length, offset, options, callback) {
- var args = Array.prototype.slice.call(arguments, 2);
- callback = args.pop();
- length = args.length ? args.shift() : null;
- offset = args.length ? args.shift() : null;
- options = args.length ? args.shift() : null;
-
- new GridStore(db, name, "r", options).open(function(err, gridStore) {
- if(err) return callback(err);
- // Make sure we are not reading out of bounds
- if(offset && offset >= gridStore.length) return callback("offset larger than size of file", null);
- if(length && length > gridStore.length) return callback("length is larger than the size of the file", null);
- if(offset && length && (offset + length) > gridStore.length) return callback("offset and length is larger than the size of the file", null);
-
- if(offset != null) {
- gridStore.seek(offset, function(err, gridStore) {
- if(err) return callback(err);
- gridStore.read(length, callback);
- });
- } else {
- gridStore.read(length, callback);
- }
- });
-};
-
-/**
- * Reads the data of this file.
- *
- * @param {Db} db the database to query.
- * @param {String} name the name of the file.
- * @param {String} [separator] the character to be recognized as the newline separator.
- * @param {Object} [options] file options.
- * @param {Function} callback this will be called after this method is executed. The first parameter will be null and the second parameter will contain an array of strings representing the entire data, each element representing a line including the separator character.
- * @return {null}
- * @api public
- */
-GridStore.readlines = function(db, name, separator, options, callback) {
- var args = Array.prototype.slice.call(arguments, 2);
- callback = args.pop();
- separator = args.length ? args.shift() : null;
- options = args.length ? args.shift() : null;
-
- var finalSeperator = separator == null ? "\n" : separator;
- new GridStore(db, name, "r", options).open(function(err, gridStore) {
- if(err) return callback(err);
- gridStore.readlines(finalSeperator, callback);
- });
-};
-
-/**
- * Deletes the chunks and metadata information of a file from GridFS.
- *
- * @param {Db} db the database to interact with.
- * @param {String|Array} names the name/names of the files to delete.
- * @param {Object} [options] the options for the files.
- * @callback {Function} this will be called after this method is executed. The first parameter will contain an Error object if an error occured or null otherwise. The second parameter will contain a reference to this object.
- * @return {null}
- * @api public
- */
-GridStore.unlink = function(db, names, options, callback) {
- var self = this;
- var args = Array.prototype.slice.call(arguments, 2);
- callback = args.pop();
- options = args.length ? args.shift() : null;
-
- if(names.constructor == Array) {
- var tc = 0;
- for(var i = 0; i < names.length; i++) {
- ++tc;
- self.unlink(db, names[i], function(result) {
- if(--tc == 0) {
- callback(null, self);
- }
- });
- }
- } else {
- new GridStore(db, names, "w", options).open(function(err, gridStore) {
- if(err) return callback(err);
- deleteChunks(gridStore, function(err, result) {
- if(err) return callback(err);
- gridStore.collection(function(err, collection) {
- if(err) return callback(err);
- collection.remove({'_id':gridStore.fileId}, {safe:true}, function(err, collection) {
- callback(err, self);
- });
- });
- });
- });
- }
-};
-
-/**
- * Returns the current chunksize of the file.
- *
- * @field chunkSize
- * @type {Number}
- * @getter
- * @setter
- * @property return number of bytes in the current chunkSize.
- */
-Object.defineProperty(GridStore.prototype, "chunkSize", { enumerable: true
- , get: function () {
- return this.internalChunkSize;
- }
- , set: function(value) {
- if(!(this.mode[0] == "w" && this.position == 0 && this.uploadDate == null)) {
- this.internalChunkSize = this.internalChunkSize;
- } else {
- this.internalChunkSize = value;
- }
- }
-});
-
-/**
- * The md5 checksum for this file.
- *
- * @field md5
- * @type {Number}
- * @getter
- * @setter
- * @property return this files md5 checksum.
- */
-Object.defineProperty(GridStore.prototype, "md5", { enumerable: true
- , get: function () {
- return this.internalMd5;
- }
-});
-
-/**
- * GridStore Streaming methods
- * Handles the correct return of the writeable stream status
- * @ignore
- */
-Object.defineProperty(GridStore.prototype, "writable", { enumerable: true
- , get: function () {
- if(this._writeable == null) {
- this._writeable = this.mode != null && this.mode.indexOf("w") != -1;
- }
- // Return the _writeable
- return this._writeable;
- }
- , set: function(value) {
- this._writeable = value;
- }
-});
-
-/**
- * Handles the correct return of the readable stream status
- * @ignore
- */
-Object.defineProperty(GridStore.prototype, "readable", { enumerable: true
- , get: function () {
- if(this._readable == null) {
- this._readable = this.mode != null && this.mode.indexOf("r") != -1;
- }
- return this._readable;
- }
- , set: function(value) {
- this._readable = value;
- }
-});
-
-GridStore.prototype.paused;
-
-/**
- * Handles the correct setting of encoding for the stream
- * @ignore
- */
-GridStore.prototype.setEncoding = fs.ReadStream.prototype.setEncoding;
-
-/**
- * Handles the end events
- * @ignore
- */
-GridStore.prototype.end = function end(data) {
- var self = this;
- // allow queued data to write before closing
- if(!this.writable) return;
- this.writable = false;
-
- if(data) {
- this._q.push(data);
- }
-
- this.on('drain', function () {
- self.close(function (err) {
- if (err) return _error(self, err);
- self.emit('close');
- });
- });
-
- _flush(self);
-}
-
-/**
- * Handles the normal writes to gridstore
- * @ignore
- */
-var _writeNormal = function(self, data, close, callback) {
- // If we have a buffer write it using the writeBuffer method
- if(Buffer.isBuffer(data)) {
- return writeBuffer(self, data, close, callback);
- } else {
- // Wrap the string in a buffer and write
- return writeBuffer(self, new Buffer(data, 'binary'), close, callback);
- }
-}
-
-/**
- * Writes some data. This method will work properly only if initialized with mode "w" or "w+".
- *
- * @param {String|Buffer} data the data to write.
- * @param {Boolean} [close] closes this file after writing if set to true.
- * @param {Function} callback this will be called after executing this method. The first parameter will contain null and the second one will contain a reference to this object.
- * @return {null}
- * @api public
- */
-GridStore.prototype.write = function write(data, close, callback) {
- // If it's a normal write delegate the call
- if(typeof close == 'function' || typeof callback == 'function') {
- return _writeNormal(this, data, close, callback);
- }
-
- // Otherwise it's a stream write
- var self = this;
- if (!this.writable) {
- throw new Error('GridWriteStream is not writable');
- }
-
- // queue data until we open.
- if (!this._opened) {
- // Set up a queue to save data until gridstore object is ready
- this._q = [];
- _openStream(self);
- this._q.push(data);
- return false;
- }
-
- // Push data to queue
- this._q.push(data);
- _flush(this);
- // Return write successful
- return true;
-}
-
-/**
- * Handles the destroy part of a stream
- * @ignore
- */
-GridStore.prototype.destroy = function destroy() {
- // close and do not emit any more events. queued data is not sent.
- if(!this.writable) return;
- this.readable = false;
- if(this.writable) {
- this.writable = false;
- this._q.length = 0;
- this.emit('close');
- }
-}
-
-/**
- * Handles the destroySoon part of a stream
- * @ignore
- */
-GridStore.prototype.destroySoon = function destroySoon() {
- // as soon as write queue is drained, destroy.
- // may call destroy immediately if no data is queued.
- if(!this._q.length) {
- return this.destroy();
- }
- this._destroying = true;
-}
-
-/**
- * Handles the pipe part of the stream
- * @ignore
- */
-GridStore.prototype.pipe = function(destination, options) {
- var self = this;
- // Open the gridstore
- this.open(function(err, result) {
- if(err) _errorRead(self, err);
- if(!self.readable) return;
- // Set up the pipe
- self._pipe(destination, options);
- // Emit the stream is open
- self.emit('open');
- // Read from the stream
- _read(self);
- })
-}
-
-/**
- * Internal module methods
- * @ignore
- */
-var _read = function _read(self) {
- if (!self.readable || self.paused || self.reading) {
- return;
- }
-
- self.reading = true;
- var stream = self._stream = self.stream();
- stream.paused = self.paused;
-
- stream.on('data', function (data) {
- if (self._decoder) {
- var str = self._decoder.write(data);
- if (str.length) self.emit('data', str);
- } else {
- self.emit('data', data);
- }
- });
-
- stream.on('end', function (data) {
- self.emit('end', data);
- });
-
- stream.on('error', function (data) {
- _errorRead(self, data);
- });
-
- stream.on('close', function (data) {
- self.emit('close', data);
- });
-
- self.pause = function () {
- // native doesn't always pause.
- // bypass its pause() method to hack it
- self.paused = stream.paused = true;
- }
-
- self.resume = function () {
- self.paused = false;
- stream.resume();
- self.readable = stream.readable;
- }
-
- self.destroy = function () {
- self.readable = false;
- stream.destroy();
- }
-}
-
-/**
- * pause
- * @ignore
- */
-GridStore.prototype.pause = function pause () {
- // Overridden when the GridStore opens.
- this.paused = true;
-}
-
-/**
- * resume
- * @ignore
- */
-GridStore.prototype.resume = function resume () {
- // Overridden when the GridStore opens.
- this.paused = false;
-}
-
-/**
- * Internal module methods
- * @ignore
- */
-var _flush = function _flush(self, _force) {
- if (!self._opened) return;
- if (!_force && self._flushing) return;
- self._flushing = true;
-
- // write the entire q to gridfs
- if (!self._q.length) {
- self._flushing = false;
- self.emit('drain');
-
- if(self._destroying) {
- self.destroy();
- }
- return;
- }
-
- self.write(self._q.shift(), function (err, store) {
- if (err) return _error(self, err);
- self.emit('progress', store.position);
- _flush(self, true);
- });
-}
-
-var _openStream = function _openStream (self) {
- if(self._opening == true) return;
- self._opening = true;
-
- // Open the store
- self.open(function (err, gridstore) {
- if (err) return _error(self, err);
- self._opened = true;
- self.emit('open');
- _flush(self);
- });
-}
-
-var _error = function _error(self, err) {
- self.destroy();
- self.emit('error', err);
-}
-
-var _errorRead = function _errorRead (self, err) {
- self.readable = false;
- self.emit('error', err);
-}
-
-/**
- * @ignore
- * @api private
- */
-exports.GridStore = GridStore;
diff --git a/CoAuthoring/node_modules/mongodb/lib/mongodb/gridfs/readstream.js b/CoAuthoring/node_modules/mongodb/lib/mongodb/gridfs/readstream.js
deleted file mode 100644
index 239b483996..0000000000
--- a/CoAuthoring/node_modules/mongodb/lib/mongodb/gridfs/readstream.js
+++ /dev/null
@@ -1,174 +0,0 @@
-var Stream = require('stream').Stream,
- util = require('util');
-
-/**
- * ReadStream
- *
- * Returns a stream interface for the **file**.
- *
- * Events
- * - **data** {function(item) {}} the data event triggers when a document is ready.
- * - **end** {function() {}} the end event triggers when there is no more documents available.
- * - **close** {function() {}} the close event triggers when the stream is closed.
- * - **error** {function(err) {}} the error event triggers if an error happens.
- *
- * @class Represents a GridFS File Stream.
- * @param {Boolean} autoclose automatically close file when the stream reaches the end.
- * @param {GridStore} cursor a cursor object that the stream wraps.
- * @return {ReadStream}
- */
-function ReadStream(autoclose, gstore) {
- if (!(this instanceof ReadStream)) return new ReadStream(autoclose, gstore);
- Stream.call(this);
-
- this.autoclose = !!autoclose;
- this.gstore = gstore;
-
- this.finalLength = gstore.length - gstore.position;
- this.completedLength = 0;
- this.currentChunkNumber = 0;
-
- this.paused = false;
- this.readable = true;
- this.pendingChunk = null;
- this.executing = false;
-
- // Calculate the number of chunks
- this.numberOfChunks = Math.ceil(gstore.length/gstore.chunkSize);
-
- var self = this;
- process.nextTick(function() {
- self._execute();
- });
-};
-
-/**
- * Inherit from Stream
- * @ignore
- * @api private
- */
-ReadStream.prototype.__proto__ = Stream.prototype;
-
-/**
- * Flag stating whether or not this stream is readable.
- */
-ReadStream.prototype.readable;
-
-/**
- * Flag stating whether or not this stream is paused.
- */
-ReadStream.prototype.paused;
-
-/**
- * @ignore
- * @api private
- */
-ReadStream.prototype._execute = function() {
- if(this.paused === true || this.readable === false) {
- return;
- }
-
- var gstore = this.gstore;
- var self = this;
- // Set that we are executing
- this.executing = true;
-
- var last = false;
- var toRead = 0;
-
- if(gstore.currentChunk.chunkNumber >= (this.numberOfChunks - 1)) {
- self.executing = false;
- last = true;
- }
-
- var data = gstore.currentChunk.readSlice(gstore.currentChunk.length());
- if(data != null && gstore.currentChunk.chunkNumber == self.currentChunkNumber) {
- self.currentChunkNumber = self.currentChunkNumber + 1;
- self.completedLength += data.length;
- self.pendingChunk = null;
- self.emit("data", data);
- }
-
- if(last === true) {
- self.readable = false;
- self.emit("end");
-
- if(self.autoclose === true) {
- if(gstore.mode[0] == "w") {
- gstore.close(function(err, doc) {
- if (err) {
- self.emit("error", err);
- return;
- }
- self.readable = false;
- self.emit("close", doc);
- });
- } else {
- self.readable = false;
- self.emit("close");
- }
- }
- } else {
- gstore._nthChunk(gstore.currentChunk.chunkNumber + 1, function(err, chunk) {
- if(err) {
- self.readable = false;
- self.emit("error", err);
- self.executing = false;
- return;
- }
-
- self.pendingChunk = chunk;
- if(self.paused === true) {
- self.executing = false;
- return;
- }
-
- gstore.currentChunk = self.pendingChunk;
- self._execute();
- });
- }
-};
-
-/**
- * Pauses this stream, then no farther events will be fired.
- *
- * @ignore
- * @api public
- */
-ReadStream.prototype.pause = function() {
- if(!this.executing) {
- this.paused = true;
- }
-};
-
-/**
- * Destroys the stream, then no farther events will be fired.
- *
- * @ignore
- * @api public
- */
-ReadStream.prototype.destroy = function() {
- this.readable = false;
- // Emit close event
- this.emit("close");
-};
-
-/**
- * Resumes this stream.
- *
- * @ignore
- * @api public
- */
-ReadStream.prototype.resume = function() {
- if(this.paused === false || !this.readable) {
- return;
- }
-
- this.paused = false;
- var self = this;
- process.nextTick(function() {
- self._execute();
- });
-};
-
-exports.ReadStream = ReadStream;
diff --git a/CoAuthoring/node_modules/mongodb/lib/mongodb/index.js b/CoAuthoring/node_modules/mongodb/lib/mongodb/index.js
deleted file mode 100644
index 014f3d2e0b..0000000000
--- a/CoAuthoring/node_modules/mongodb/lib/mongodb/index.js
+++ /dev/null
@@ -1,157 +0,0 @@
-try {
- exports.BSONPure = require('bson').BSONPure;
- exports.BSONNative = require('bson').BSONNative;
-} catch(err) {
- // do nothing
-}
-
-[ 'commands/base_command'
- , 'commands/db_command'
- , 'commands/delete_command'
- , 'commands/get_more_command'
- , 'commands/insert_command'
- , 'commands/kill_cursor_command'
- , 'commands/query_command'
- , 'commands/update_command'
- , 'responses/mongo_reply'
- , 'admin'
- , 'collection'
- , 'connection/read_preference'
- , 'connection/connection'
- , 'connection/server'
- , 'connection/mongos'
- , 'connection/repl_set'
- , 'cursor'
- , 'db'
- , 'gridfs/grid'
- , 'gridfs/chunk'
- , 'gridfs/gridstore'].forEach(function (path) {
- var module = require('./' + path);
- for (var i in module) {
- exports[i] = module[i];
- }
-
- // backwards compat
- exports.ReplSetServers = exports.ReplSet;
-
- // Add BSON Classes
- exports.Binary = require('bson').Binary;
- exports.Code = require('bson').Code;
- exports.DBRef = require('bson').DBRef;
- exports.Double = require('bson').Double;
- exports.Long = require('bson').Long;
- exports.MinKey = require('bson').MinKey;
- exports.MaxKey = require('bson').MaxKey;
- exports.ObjectID = require('bson').ObjectID;
- exports.Symbol = require('bson').Symbol;
- exports.Timestamp = require('bson').Timestamp;
-
- // Add BSON Parser
- exports.BSON = require('bson').BSONPure.BSON;
-});
-
-// Exports all the classes for the PURE JS BSON Parser
-exports.pure = function() {
- var classes = {};
- // Map all the classes
- [ 'commands/base_command'
- , 'commands/db_command'
- , 'commands/delete_command'
- , 'commands/get_more_command'
- , 'commands/insert_command'
- , 'commands/kill_cursor_command'
- , 'commands/query_command'
- , 'commands/update_command'
- , 'responses/mongo_reply'
- , 'admin'
- , 'collection'
- , 'connection/read_preference'
- , 'connection/connection'
- , 'connection/server'
- , 'connection/mongos'
- , 'connection/repl_set'
- , 'cursor'
- , 'db'
- , 'gridfs/grid'
- , 'gridfs/chunk'
- , 'gridfs/gridstore'].forEach(function (path) {
- var module = require('./' + path);
- for (var i in module) {
- classes[i] = module[i];
- }
- });
-
- // backwards compat
- classes.ReplSetServers = exports.ReplSet;
-
- // Add BSON Classes
- classes.Binary = require('bson').Binary;
- classes.Code = require('bson').Code;
- classes.DBRef = require('bson').DBRef;
- classes.Double = require('bson').Double;
- classes.Long = require('bson').Long;
- classes.MinKey = require('bson').MinKey;
- classes.MaxKey = require('bson').MaxKey;
- classes.ObjectID = require('bson').ObjectID;
- classes.Symbol = require('bson').Symbol;
- classes.Timestamp = require('bson').Timestamp;
-
- // Add BSON Parser
- classes.BSON = require('bson').BSONPure.BSON;
-
- // Return classes list
- return classes;
-}
-
-// Exports all the classes for the PURE JS BSON Parser
-exports.native = function() {
- var classes = {};
- // Map all the classes
- [ 'commands/base_command'
- , 'commands/db_command'
- , 'commands/delete_command'
- , 'commands/get_more_command'
- , 'commands/insert_command'
- , 'commands/kill_cursor_command'
- , 'commands/query_command'
- , 'commands/update_command'
- , 'responses/mongo_reply'
- , 'admin'
- , 'collection'
- , 'connection/read_preference'
- , 'connection/connection'
- , 'connection/server'
- , 'connection/mongos'
- , 'connection/repl_set'
- , 'cursor'
- , 'db'
- , 'gridfs/grid'
- , 'gridfs/chunk'
- , 'gridfs/gridstore'].forEach(function (path) {
- var module = require('./' + path);
- for (var i in module) {
- classes[i] = module[i];
- }
- });
-
- // Add BSON Classes
- classes.Binary = require('bson').Binary;
- classes.Code = require('bson').Code;
- classes.DBRef = require('bson').DBRef;
- classes.Double = require('bson').Double;
- classes.Long = require('bson').Long;
- classes.MinKey = require('bson').MinKey;
- classes.MaxKey = require('bson').MaxKey;
- classes.ObjectID = require('bson').ObjectID;
- classes.Symbol = require('bson').Symbol;
- classes.Timestamp = require('bson').Timestamp;
-
- // backwards compat
- classes.ReplSetServers = exports.ReplSet;
-
- // Add BSON Parser
- classes.BSON = require('bson').BSONNative.BSON;
-
- // Return classes list
- return classes;
-}
diff --git a/CoAuthoring/node_modules/mongodb/lib/mongodb/responses/mongo_reply.js b/CoAuthoring/node_modules/mongodb/lib/mongodb/responses/mongo_reply.js
deleted file mode 100644
index 4f72a0f2e3..0000000000
--- a/CoAuthoring/node_modules/mongodb/lib/mongodb/responses/mongo_reply.js
+++ /dev/null
@@ -1,140 +0,0 @@
-var Long = require('bson').Long;
-
-/**
- Reply message from mongo db
-**/
-var MongoReply = exports.MongoReply = function() {
- this.documents = [];
- this.index = 0;
-};
-
-MongoReply.prototype.parseHeader = function(binary_reply, bson) {
- // Unpack the standard header first
- this.messageLength = binary_reply[this.index] | binary_reply[this.index + 1] << 8 | binary_reply[this.index + 2] << 16 | binary_reply[this.index + 3] << 24;
- this.index = this.index + 4;
- // Fetch the request id for this reply
- this.requestId = binary_reply[this.index] | binary_reply[this.index + 1] << 8 | binary_reply[this.index + 2] << 16 | binary_reply[this.index + 3] << 24;
- this.index = this.index + 4;
- // Fetch the id of the request that triggered the response
- this.responseTo = binary_reply[this.index] | binary_reply[this.index + 1] << 8 | binary_reply[this.index + 2] << 16 | binary_reply[this.index + 3] << 24;
- // Skip op-code field
- this.index = this.index + 4 + 4;
- // Unpack the reply message
- this.responseFlag = binary_reply[this.index] | binary_reply[this.index + 1] << 8 | binary_reply[this.index + 2] << 16 | binary_reply[this.index + 3] << 24;
- this.index = this.index + 4;
- // Unpack the cursor id (a 64 bit long integer)
- var low_bits = binary_reply[this.index] | binary_reply[this.index + 1] << 8 | binary_reply[this.index + 2] << 16 | binary_reply[this.index + 3] << 24;
- this.index = this.index + 4;
- var high_bits = binary_reply[this.index] | binary_reply[this.index + 1] << 8 | binary_reply[this.index + 2] << 16 | binary_reply[this.index + 3] << 24;
- this.index = this.index + 4;
- this.cursorId = new Long(low_bits, high_bits);
- // Unpack the starting from
- this.startingFrom = binary_reply[this.index] | binary_reply[this.index + 1] << 8 | binary_reply[this.index + 2] << 16 | binary_reply[this.index + 3] << 24;
- this.index = this.index + 4;
- // Unpack the number of objects returned
- this.numberReturned = binary_reply[this.index] | binary_reply[this.index + 1] << 8 | binary_reply[this.index + 2] << 16 | binary_reply[this.index + 3] << 24;
- this.index = this.index + 4;
-}
-
-MongoReply.prototype.parseBody = function(binary_reply, bson, raw, callback) {
- raw = raw == null ? false : raw;
- // Just set a doc limit for deserializing
- var docLimitSize = 1024*20;
-
- // If our message length is very long, let's switch to process.nextTick for messages
- if(this.messageLength > docLimitSize) {
- var batchSize = this.numberReturned;
- this.documents = new Array(this.numberReturned);
-
- // Just walk down until we get a positive number >= 1
- for(var i = 50; i > 0; i--) {
- if((this.numberReturned/i) >= 1) {
- batchSize = i;
- break;
- }
- }
-
- // Actual main creator of the processFunction setting internal state to control the flow
- var parseFunction = function(_self, _binary_reply, _batchSize, _numberReturned) {
- var object_index = 0;
- // Internal loop process that will use nextTick to ensure we yield some time
- var processFunction = function() {
- // Adjust batchSize if we have less results left than batchsize
- if((_numberReturned - object_index) < _batchSize) {
- _batchSize = _numberReturned - object_index;
- }
-
- // If raw just process the entries
- if(raw) {
- // Iterate over the batch
- for(var i = 0; i < _batchSize; i++) {
- // Are we done ?
- if(object_index <= _numberReturned) {
- // Read the size of the bson object
- var bsonObjectSize = _binary_reply[_self.index] | _binary_reply[_self.index + 1] << 8 | _binary_reply[_self.index + 2] << 16 | _binary_reply[_self.index + 3] << 24;
- // If we are storing the raw responses to pipe straight through
- _self.documents[object_index] = binary_reply.slice(_self.index, _self.index + bsonObjectSize);
- // Adjust binary index to point to next block of binary bson data
- _self.index = _self.index + bsonObjectSize;
- // Update number of docs parsed
- object_index = object_index + 1;
- }
- }
- } else {
- try {
- // Parse documents
- _self.index = bson.deserializeStream(binary_reply, _self.index, _batchSize, _self.documents, object_index);
- // Adjust index
- object_index = object_index + _batchSize;
- } catch (err) {
- return callback(err);
- }
- }
-
- // If we hav more documents process NextTick
- if(object_index < _numberReturned) {
- process.nextTick(processFunction);
- } else {
- callback(null);
- }
- }
-
- // Return the process function
- return processFunction;
- }(this, binary_reply, batchSize, this.numberReturned)();
- } else {
- try {
- // Let's unpack all the bson documents, deserialize them and store them
- for(var object_index = 0; object_index < this.numberReturned; object_index++) {
- // Read the size of the bson object
- var bsonObjectSize = binary_reply[this.index] | binary_reply[this.index + 1] << 8 | binary_reply[this.index + 2] << 16 | binary_reply[this.index + 3] << 24;
- // If we are storing the raw responses to pipe straight through
- if(raw) {
- // Deserialize the object and add to the documents array
- this.documents.push(binary_reply.slice(this.index, this.index + bsonObjectSize));
- } else {
- // Deserialize the object and add to the documents array
- this.documents.push(bson.deserialize(binary_reply.slice(this.index, this.index + bsonObjectSize)));
- }
- // Adjust binary index to point to next block of binary bson data
- this.index = this.index + bsonObjectSize;
- }
- } catch(err) {
- return callback(err);
- }
-
- // No error return
- callback(null);
- }
-}
-
-MongoReply.prototype.is_error = function(){
- if(this.documents.length == 1) {
- return this.documents[0].ok == 1 ? false : true;
- }
- return false;
-};
-
-MongoReply.prototype.error_message = function() {
- return this.documents.length == 1 && this.documents[0].ok == 1 ? '' : this.documents[0].errmsg;
-};
\ No newline at end of file
diff --git a/CoAuthoring/node_modules/mongodb/lib/mongodb/utils.js b/CoAuthoring/node_modules/mongodb/lib/mongodb/utils.js
deleted file mode 100644
index 07a0ab04e2..0000000000
--- a/CoAuthoring/node_modules/mongodb/lib/mongodb/utils.js
+++ /dev/null
@@ -1,74 +0,0 @@
-/**
- * Sort functions, Normalize and prepare sort parameters
- */
-var formatSortValue = exports.formatSortValue = function(sortDirection) {
- var value = ("" + sortDirection).toLowerCase();
-
- switch (value) {
- case 'ascending':
- case 'asc':
- case '1':
- return 1;
- case 'descending':
- case 'desc':
- case '-1':
- return -1;
- default:
- throw new Error("Illegal sort clause, must be of the form "
- + "[['field1', '(ascending|descending)'], "
- + "['field2', '(ascending|descending)']]");
- }
-};
-
-var formattedOrderClause = exports.formattedOrderClause = function(sortValue) {
- var orderBy = {};
-
- if (Array.isArray(sortValue)) {
- for(var i = 0; i < sortValue.length; i++) {
- if(sortValue[i].constructor == String) {
- orderBy[sortValue[i]] = 1;
- } else {
- orderBy[sortValue[i][0]] = formatSortValue(sortValue[i][1]);
- }
- }
- } else if(Object.prototype.toString.call(sortValue) === '[object Object]') {
- orderBy = sortValue;
- } else if (sortValue.constructor == String) {
- orderBy[sortValue] = 1;
- } else {
- throw new Error("Illegal sort clause, must be of the form " +
- "[['field1', '(ascending|descending)'], ['field2', '(ascending|descending)']]");
- }
-
- return orderBy;
-};
-
-exports.encodeInt = function(value) {
- var buffer = new Buffer(4);
- buffer[3] = (value >> 24) & 0xff;
- buffer[2] = (value >> 16) & 0xff;
- buffer[1] = (value >> 8) & 0xff;
- buffer[0] = value & 0xff;
- return buffer;
-}
-
-exports.encodeIntInPlace = function(value, buffer, index) {
- buffer[index + 3] = (value >> 24) & 0xff;
- buffer[index + 2] = (value >> 16) & 0xff;
- buffer[index + 1] = (value >> 8) & 0xff;
- buffer[index] = value & 0xff;
-}
-
-exports.encodeCString = function(string) {
- var buf = new Buffer(string, 'utf8');
- return [buf, new Buffer([0])];
-}
-
-exports.decodeUInt32 = function(array, index) {
- return array[index] | array[index + 1] << 8 | array[index + 2] << 16 | array[index + 3] << 24;
-}
-
-// Decode the int
-exports.decodeUInt8 = function(array, index) {
- return array[index];
-}
diff --git a/CoAuthoring/node_modules/mongodb/node_modules/bson/.travis.yml b/CoAuthoring/node_modules/mongodb/node_modules/bson/.travis.yml
deleted file mode 100644
index 90b208a4d8..0000000000
--- a/CoAuthoring/node_modules/mongodb/node_modules/bson/.travis.yml
+++ /dev/null
@@ -1,5 +0,0 @@
-language: node_js
-node_js:
- - 0.4
- - 0.6
- - 0.7 # development version of 0.8, may be unstable
\ No newline at end of file
diff --git a/CoAuthoring/node_modules/mongodb/node_modules/bson/Makefile b/CoAuthoring/node_modules/mongodb/node_modules/bson/Makefile
deleted file mode 100644
index 88b1ddc802..0000000000
--- a/CoAuthoring/node_modules/mongodb/node_modules/bson/Makefile
+++ /dev/null
@@ -1,31 +0,0 @@
-NODE = node
-NPM = npm
-NODEUNIT = node_modules/nodeunit/bin/nodeunit
-name = all
-
-total: build_native
-
-test: build_native
- $(NODEUNIT) ./test/node
- TEST_NATIVE=TRUE $(NODEUNIT) ./test/node
-
-build_native:
- $(MAKE) -C ./ext all
-
-build_native_debug:
- $(MAKE) -C ./ext all_debug
-
-build_native_clang:
- $(MAKE) -C ./ext clang
-
-build_native_clang_debug:
- $(MAKE) -C ./ext clang_debug
-
-clean_native:
- $(MAKE) -C ./ext clean
-
-clean:
- rm ./ext/bson.node
- rm -r ./ext/build
-
-.PHONY: total
diff --git a/CoAuthoring/node_modules/mongodb/node_modules/bson/README b/CoAuthoring/node_modules/mongodb/node_modules/bson/README
deleted file mode 100644
index e69de29bb2..0000000000
diff --git a/CoAuthoring/node_modules/mongodb/node_modules/bson/benchmarks/benchmarks.js b/CoAuthoring/node_modules/mongodb/node_modules/bson/benchmarks/benchmarks.js
deleted file mode 100644
index 45a1111548..0000000000
--- a/CoAuthoring/node_modules/mongodb/node_modules/bson/benchmarks/benchmarks.js
+++ /dev/null
@@ -1,130 +0,0 @@
-// var BSON = require('../../lib/mongodb').BSONNative.BSON,
-// ObjectID = require('../../lib/mongodb').BSONNative.ObjectID,
-// Code = require('../../lib/mongodb').BSONNative.Code,
-// Long = require('../../lib/mongodb').BSONNative.Long,
-// Binary = require('../../lib/mongodb').BSONNative.Binary,
-// debug = require('util').debug,
-// inspect = require('util').inspect,
-//
-// Long = require('../../lib/mongodb').Long,
-// ObjectID = require('../../lib/mongodb').ObjectID,
-// Binary = require('../../lib/mongodb').Binary,
-// Code = require('../../lib/mongodb').Code,
-// DBRef = require('../../lib/mongodb').DBRef,
-// Symbol = require('../../lib/mongodb').Symbol,
-// Double = require('../../lib/mongodb').Double,
-// MaxKey = require('../../lib/mongodb').MaxKey,
-// MinKey = require('../../lib/mongodb').MinKey,
-// Timestamp = require('../../lib/mongodb').Timestamp;
-
-
-// var BSON = require('../../lib/mongodb').BSONPure.BSON,
-// ObjectID = require('../../lib/mongodb').BSONPure.ObjectID,
-// Code = require('../../lib/mongodb').BSONPure.Code,
-// Long = require('../../lib/mongodb').BSONPure.Long,
-// Binary = require('../../lib/mongodb').BSONPure.Binary;
-
-var BSON = require('../lib/bson').BSONNative.BSON,
- Long = require('../lib/bson').Long,
- ObjectID = require('../lib/bson').ObjectID,
- Binary = require('../lib/bson').Binary,
- Code = require('../lib/bson').Code,
- DBRef = require('../lib/bson').DBRef,
- Symbol = require('../lib/bson').Symbol,
- Double = require('../lib/bson').Double,
- MaxKey = require('../lib/bson').MaxKey,
- MinKey = require('../lib/bson').MinKey,
- Timestamp = require('../lib/bson').Timestamp;
-
- // console.dir(require('../lib/bson'))
-
-var COUNT = 1000;
-var COUNT = 100;
-
-var object = {
- string: "Strings are great",
- decimal: 3.14159265,
- bool: true,
- integer: 5,
- date: new Date(),
- double: new Double(1.4),
- id: new ObjectID(),
- min: new MinKey(),
- max: new MaxKey(),
- symbol: new Symbol('hello'),
- long: Long.fromNumber(100),
- bin: new Binary(new Buffer(100)),
-
- subObject: {
- moreText: "Bacon ipsum dolor sit amet cow pork belly rump ribeye pastrami andouille. Tail hamburger pork belly, drumstick flank salami t-bone sirloin pork chop ribeye ham chuck pork loin shankle. Ham fatback pork swine, sirloin shankle short loin andouille shank sausage meatloaf drumstick. Pig chicken cow bresaola, pork loin jerky meatball tenderloin brisket strip steak jowl spare ribs. Biltong sirloin pork belly boudin, bacon pastrami rump chicken. Jowl rump fatback, biltong bacon t-bone turkey. Turkey pork loin boudin, tenderloin jerky beef ribs pastrami spare ribs biltong pork chop beef.",
- longKeylongKeylongKeylongKeylongKeylongKey: "Pork belly boudin shoulder ribeye pork chop brisket biltong short ribs. Salami beef pork belly, t-bone sirloin meatloaf tail jowl spare ribs. Sirloin biltong bresaola cow turkey. Biltong fatback meatball, bresaola tail shankle turkey pancetta ham ribeye flank bacon jerky pork chop. Boudin sirloin shoulder, salami swine flank jerky t-bone pork chop pork beef tongue. Bresaola ribeye jerky andouille. Ribeye ground round sausage biltong beef ribs chuck, shank hamburger chicken short ribs spare ribs tenderloin meatloaf pork loin."
- },
-
- subArray: [1,2,3,4,5,6,7,8,9,10],
- anotherString: "another string",
- code: new Code("function() {}", {i:1})
-}
-
-// Number of objects
-var numberOfObjects = 10000;
-var bson = new BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]);
-console.log("---------------------- 1")
-var s = new Date()
-// Object serialized
-for(var i = 0; i < numberOfObjects; i++) {
- objectBSON = bson.serialize(object, null, true)
-}
-console.log("====================== " + (new Date().getTime() - s.getTime()) + " :: " + ((new Date().getTime() - s.getTime()))/numberOfObjects)
-
-console.log("---------------------- 2")
-var s = new Date()
-// Object serialized
-for(var i = 0; i < numberOfObjects; i++) {
- bson.deserialize(objectBSON);
-}
-console.log("====================== " + (new Date().getTime() - s.getTime()) + " :: " + ((new Date().getTime() - s.getTime()))/numberOfObjects)
-
-// // Buffer With copies of the objectBSON
-// var data = new Buffer(objectBSON.length * numberOfObjects);
-// var index = 0;
-//
-// // Copy the buffer 1000 times to create a strea m of objects
-// for(var i = 0; i < numberOfObjects; i++) {
-// // Copy data
-// objectBSON.copy(data, index);
-// // Adjust index
-// index = index + objectBSON.length;
-// }
-//
-// // console.log("-----------------------------------------------------------------------------------")
-// // console.dir(objectBSON)
-//
-// var x, start, end, j
-// var objectBSON, objectJSON
-//
-// // Allocate the return array (avoid concatinating everything)
-// var results = new Array(numberOfObjects);
-//
-// console.log(COUNT + "x (objectBSON = BSON.serialize(object))")
-// start = new Date
-//
-// // var objects = BSON.deserializeStream(data, 0, numberOfObjects);
-// // console.log("----------------------------------------------------------------------------------- 0")
-// // var objects = BSON.deserialize(data);
-// // console.log("----------------------------------------------------------------------------------- 1")
-// // console.dir(objects)
-//
-// for (j=COUNT; --j>=0; ) {
-// var nextIndex = BSON.deserializeStream(data, 0, numberOfObjects, results, 0);
-// }
-//
-// end = new Date
-// var opsprsecond = COUNT / ((end - start)/1000);
-// console.log("bson size (bytes): ", objectBSON.length);
-// console.log("time = ", end - start, "ms -", COUNT / ((end - start)/1000), " ops/sec");
-// console.log("MB/s = " + ((opsprsecond*objectBSON.length)/1024));
-//
-// // console.dir(nextIndex)
-// // console.dir(results)
-
-
diff --git a/CoAuthoring/node_modules/mongodb/node_modules/bson/ext/.npmignore b/CoAuthoring/node_modules/mongodb/node_modules/bson/ext/.npmignore
deleted file mode 100644
index 92bdc57773..0000000000
--- a/CoAuthoring/node_modules/mongodb/node_modules/bson/ext/.npmignore
+++ /dev/null
@@ -1,3 +0,0 @@
-build/
-bson.node
-.lock-wscript
\ No newline at end of file
diff --git a/CoAuthoring/node_modules/mongodb/node_modules/bson/ext/Makefile b/CoAuthoring/node_modules/mongodb/node_modules/bson/ext/Makefile
deleted file mode 100644
index 435999ee96..0000000000
--- a/CoAuthoring/node_modules/mongodb/node_modules/bson/ext/Makefile
+++ /dev/null
@@ -1,28 +0,0 @@
-NODE = node
-name = all
-JOBS = 1
-
-all:
- rm -rf build .lock-wscript bson.node
- node-waf configure build
- cp -R ./build/Release/bson.node . || true
-
-all_debug:
- rm -rf build .lock-wscript bson.node
- node-waf --debug configure build
- cp -R ./build/Release/bson.node . || true
-
-clang:
- rm -rf build .lock-wscript bson.node
- CXX=clang node-waf configure build
- cp -R ./build/Release/bson.node . || true
-
-clang_debug:
- rm -rf build .lock-wscript bson.node
- CXX=clang node-waf --debug configure build
- cp -R ./build/Release/bson.node . || true
-
-clean:
- rm -rf build .lock-wscript bson.node
-
-.PHONY: all
\ No newline at end of file
diff --git a/CoAuthoring/node_modules/mongodb/node_modules/bson/ext/bson.cc b/CoAuthoring/node_modules/mongodb/node_modules/bson/ext/bson.cc
deleted file mode 100644
index 4b83f38597..0000000000
--- a/CoAuthoring/node_modules/mongodb/node_modules/bson/ext/bson.cc
+++ /dev/null
@@ -1,997 +0,0 @@
-//===========================================================================
-
-#include
-#include
-#include
-
-#ifdef __clang__
-#pragma clang diagnostic push
-#pragma clang diagnostic ignored "-Wunused-parameter"
-#endif
-
-#include
-
-#ifdef __clang__
-#pragma clang diagnostic pop
-#endif
-
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-
-#include "bson.h"
-
-using namespace v8;
-using namespace node;
-
-//===========================================================================
-
-void DataStream::WriteObjectId(const Handle& object, const Handle& key)
-{
- uint16_t buffer[12];
- object->Get(key)->ToString()->Write(buffer, 0, 12);
- for(uint32_t i = 0; i < 12; ++i)
- {
- *p++ = (char) buffer[i];
- }
-}
-
-void ThrowAllocatedStringException(size_t allocationSize, const char* format, ...)
-{
- va_list args;
- va_start(args, format);
- char* string = (char*) malloc(allocationSize);
- vsprintf(string, format, args);
- va_end(args);
-
- throw string;
-}
-
-void DataStream::CheckKey(const Local& keyName)
-{
- size_t keyLength = keyName->Utf8Length();
- if(keyLength == 0) return;
-
- char* keyStringBuffer = (char*) alloca(keyLength+1);
- keyName->WriteUtf8(keyStringBuffer);
-
- if(keyStringBuffer[0] == '$')
- {
- ThrowAllocatedStringException(64+keyLength, "key %s must not start with '$'", keyStringBuffer);
- }
-
- if(strchr(keyStringBuffer, '.') != NULL)
- {
- ThrowAllocatedStringException(64+keyLength, "key %s must not contain '.'", keyStringBuffer);
- }
-}
-
-template void BSONSerializer::SerializeDocument(const Handle& value)
-{
- void* documentSize = this->BeginWriteSize();
- Local object = bson->GetSerializeObject(value);
-
- // Get the object property names
- #if NODE_MAJOR_VERSION == 0 && NODE_MINOR_VERSION < 6
- Local propertyNames = object->GetPropertyNames();
- #else
- Local propertyNames = object->GetOwnPropertyNames();
- #endif
-
- // Length of the property
- int propertyLength = propertyNames->Length();
- for(int i = 0; i < propertyLength; ++i)
- {
- const Local& propertyName = propertyNames->Get(i)->ToString();
- if(checkKeys) this->CheckKey(propertyName);
-
- const Local& propertyValue = object->Get(propertyName);
-
- if(serializeFunctions || !propertyValue->IsFunction())
- {
- void* typeLocation = this->BeginWriteType();
- this->WriteString(propertyName);
- SerializeValue(typeLocation, propertyValue);
- }
- }
-
- this->WriteByte(0);
- this->CommitSize(documentSize);
-}
-
-template void BSONSerializer::SerializeArray(const Handle& value)
-{
- void* documentSize = this->BeginWriteSize();
-
- Local array = Local::Cast(value->ToObject());
- uint32_t arrayLength = array->Length();
-
- for(uint32_t i = 0; i < arrayLength; ++i)
- {
- void* typeLocation = this->BeginWriteType();
- this->WriteUInt32String(i);
- SerializeValue(typeLocation, array->Get(i));
- }
-
- this->WriteByte(0);
- this->CommitSize(documentSize);
-}
-
-// This is templated so that we can use this function to both count the number of bytes, and to serialize those bytes.
-// The template approach eliminates almost all of the inspection of values unless they're required (eg. string lengths)
-// and ensures that there is always consistency between bytes counted and bytes written by design.
-template void BSONSerializer::SerializeValue(void* typeLocation, const Handle& value)
-{
- if(value->IsNumber())
- {
- double doubleValue = value->NumberValue();
- int intValue = (int) doubleValue;
- if(intValue == doubleValue)
- {
- this->CommitType(typeLocation, BSON_TYPE_INT);
- this->WriteInt32(intValue);
- }
- else
- {
- this->CommitType(typeLocation, BSON_TYPE_NUMBER);
- this->WriteDouble(doubleValue);
- }
- }
- else if(value->IsString())
- {
- this->CommitType(typeLocation, BSON_TYPE_STRING);
- this->WriteLengthPrefixedString(value->ToString());
- }
- else if(value->IsBoolean())
- {
- this->CommitType(typeLocation, BSON_TYPE_BOOLEAN);
- this->WriteBool(value);
- }
- else if(value->IsArray())
- {
- this->CommitType(typeLocation, BSON_TYPE_ARRAY);
- SerializeArray(value);
- }
- else if(value->IsDate())
- {
- this->CommitType(typeLocation, BSON_TYPE_DATE);
- this->WriteInt64(value);
- }
- else if(value->IsRegExp())
- {
- this->CommitType(typeLocation, BSON_TYPE_REGEXP);
- const Handle& regExp = Handle::Cast(value);
-
- this->WriteString(regExp->GetSource());
-
- int flags = regExp->GetFlags();
- if(flags & RegExp::kGlobal) this->WriteByte('s');
- if(flags & RegExp::kIgnoreCase) this->WriteByte('i');
- if(flags & RegExp::kMultiline) this->WriteByte('m');
- this->WriteByte(0);
- }
- else if(value->IsFunction())
- {
- this->CommitType(typeLocation, BSON_TYPE_CODE);
- this->WriteLengthPrefixedString(value->ToString());
- }
- else if(value->IsObject())
- {
- const Local& object = value->ToObject();
- if(object->Has(bson->_bsontypeString))
- {
- const Local& constructorString = object->GetConstructorName();
- if(bson->longString->StrictEquals(constructorString))
- {
- this->CommitType(typeLocation, BSON_TYPE_LONG);
- this->WriteInt32(object, bson->_longLowString);
- this->WriteInt32(object, bson->_longHighString);
- }
- else if(bson->timestampString->StrictEquals(constructorString))
- {
- this->CommitType(typeLocation, BSON_TYPE_TIMESTAMP);
- this->WriteInt32(object, bson->_longLowString);
- this->WriteInt32(object, bson->_longHighString);
- }
- else if(bson->objectIDString->StrictEquals(constructorString))
- {
- this->CommitType(typeLocation, BSON_TYPE_OID);
- this->WriteObjectId(object, bson->_objectIDidString);
- }
- else if(bson->binaryString->StrictEquals(constructorString))
- {
- this->CommitType(typeLocation, BSON_TYPE_BINARY);
-
- uint32_t length = object->Get(bson->_binaryPositionString)->Uint32Value();
- Local bufferObj = object->Get(bson->_binaryBufferString)->ToObject();
-
- this->WriteInt32(length);
- this->WriteByte(object, bson->_binarySubTypeString); // write subtype
- this->WriteData(Buffer::Data(bufferObj), length);
- }
- else if(bson->doubleString->StrictEquals(constructorString))
- {
- this->CommitType(typeLocation, BSON_TYPE_NUMBER);
- this->WriteDouble(object, bson->_doubleValueString);
- }
- else if(bson->symbolString->StrictEquals(constructorString))
- {
- this->CommitType(typeLocation, BSON_TYPE_SYMBOL);
- this->WriteLengthPrefixedString(object->Get(bson->_symbolValueString)->ToString());
- }
- else if(bson->codeString->StrictEquals(constructorString))
- {
- const Local& function = object->Get(bson->_codeCodeString)->ToString();
- const Local& scope = object->Get(bson->_codeScopeString)->ToObject();
-
- // For Node < 0.6.X use the GetPropertyNames
- #if NODE_MAJOR_VERSION == 0 && NODE_MINOR_VERSION < 6
- uint32_t propertyNameLength = scope->GetPropertyNames()->Length();
- #else
- uint32_t propertyNameLength = scope->GetOwnPropertyNames()->Length();
- #endif
-
- if(propertyNameLength > 0)
- {
- this->CommitType(typeLocation, BSON_TYPE_CODE_W_SCOPE);
- void* codeWidthScopeSize = this->BeginWriteSize();
- this->WriteLengthPrefixedString(function->ToString());
- SerializeDocument(scope);
- this->CommitSize(codeWidthScopeSize);
- }
- else
- {
- this->CommitType(typeLocation, BSON_TYPE_CODE);
- this->WriteLengthPrefixedString(function->ToString());
- }
- }
- else if(bson->dbrefString->StrictEquals(constructorString))
- {
- this->CommitType(typeLocation, BSON_TYPE_OBJECT);
-
- void* dbRefSize = this->BeginWriteSize();
-
- void* refType = this->BeginWriteType();
- this->WriteData("$ref", 5);
- SerializeValue(refType, object->Get(bson->_dbRefNamespaceString));
-
- void* idType = this->BeginWriteType();
- this->WriteData("$id", 4);
- SerializeValue(idType, object->Get(bson->_dbRefOidString));
-
- const Local& refDbValue = object->Get(bson->_dbRefDbString);
- if(!refDbValue->IsUndefined())
- {
- void* dbType = this->BeginWriteType();
- this->WriteData("$db", 4);
- SerializeValue(dbType, refDbValue);
- }
-
- this->WriteByte(0);
- this->CommitSize(dbRefSize);
- }
- else if(bson->minKeyString->StrictEquals(constructorString))
- {
- this->CommitType(typeLocation, BSON_TYPE_MIN_KEY);
- }
- else if(bson->maxKeyString->StrictEquals(constructorString))
- {
- this->CommitType(typeLocation, BSON_TYPE_MAX_KEY);
- }
- }
- else
- {
- this->CommitType(typeLocation, BSON_TYPE_OBJECT);
- SerializeDocument(value);
- }
- }
- else if(value->IsNull() || value->IsUndefined())
- {
- this->CommitType(typeLocation, BSON_TYPE_NULL);
- }
-}
-
-// Data points to start of element list, length is length of entire document including '\0' but excluding initial size
-BSONDeserializer::BSONDeserializer(BSON* aBson, char* data, size_t length)
-: bson(aBson),
- pStart(data),
- p(data),
- pEnd(data + length - 1)
-{
- if(*pEnd != '\0') ThrowAllocatedStringException(64, "Missing end of document marker '\\0'");
-}
-
-BSONDeserializer::BSONDeserializer(BSONDeserializer& parentSerializer, size_t length)
-: bson(parentSerializer.bson),
- pStart(parentSerializer.p),
- p(parentSerializer.p),
- pEnd(parentSerializer.p + length - 1)
-{
- parentSerializer.p += length;
- if(pEnd > parentSerializer.pEnd) ThrowAllocatedStringException(64, "Child document exceeds parent's bounds");
- if(*pEnd != '\0') ThrowAllocatedStringException(64, "Missing end of document marker '\\0'");
-}
-
-Local BSONDeserializer::ReadCString()
-{
- char* start = p;
- while(*p++) { }
- return String::New(start, (int32_t) (p-start-1) );
-}
-
-int32_t BSONDeserializer::ReadRegexOptions()
-{
- int32_t options = 0;
- for(;;)
- {
- switch(*p++)
- {
- case '\0': return options;
- case 's': options |= RegExp::kGlobal; break;
- case 'i': options |= RegExp::kIgnoreCase; break;
- case 'm': options |= RegExp::kMultiline; break;
- }
- }
-}
-
-uint32_t BSONDeserializer::ReadIntegerString()
-{
- uint32_t value = 0;
- while(*p)
- {
- if(*p < '0' || *p > '9') ThrowAllocatedStringException(64, "Invalid key for array");
- value = value * 10 + *p++ - '0';
- }
- ++p;
- return value;
-}
-
-Local BSONDeserializer::ReadString()
-{
- uint32_t length = ReadUInt32();
- char* start = p;
- p += length;
- return String::New(start, length-1);
-}
-
-Local BSONDeserializer::ReadObjectId()
-{
- uint16_t objectId[12];
- for(size_t i = 0; i < 12; ++i)
- {
- objectId[i] = *reinterpret_cast(p++);
- }
- return String::New(objectId, 12);
-}
-
-Handle BSONDeserializer::DeserializeDocument()
-{
- uint32_t length = ReadUInt32();
- if(length < 5) ThrowAllocatedStringException(64, "Bad BSON: Document is less than 5 bytes");
-
- BSONDeserializer documentDeserializer(*this, length-4);
- return documentDeserializer.DeserializeDocumentInternal();
-}
-
-Handle BSONDeserializer::DeserializeDocumentInternal()
-{
- Local returnObject = Object::New();
-
- while(HasMoreData())
- {
- BsonType type = (BsonType) ReadByte();
- const Local& name = ReadCString();
- const Handle& value = DeserializeValue(type);
- returnObject->ForceSet(name, value);
- }
- if(p != pEnd) ThrowAllocatedStringException(64, "Bad BSON Document: Serialize consumed unexpected number of bytes");
-
- // From JavaScript:
- // if(object['$id'] != null) object = new DBRef(object['$ref'], object['$id'], object['$db']);
- if(returnObject->Has(bson->_dbRefIdRefString))
- {
- Local argv[] = { returnObject->Get(bson->_dbRefRefString), returnObject->Get(bson->_dbRefIdRefString), returnObject->Get(bson->_dbRefDbRefString) };
- return bson->dbrefConstructor->NewInstance(3, argv);
- }
- else
- {
- return returnObject;
- }
-}
-
-Handle BSONDeserializer::DeserializeArray()
-{
- uint32_t length = ReadUInt32();
- if(length < 5) ThrowAllocatedStringException(64, "Bad BSON: Array Document is less than 5 bytes");
-
- BSONDeserializer documentDeserializer(*this, length-4);
- return documentDeserializer.DeserializeArrayInternal();
-}
-
-Handle BSONDeserializer::DeserializeArrayInternal()
-{
- Local returnArray = Array::New();
-
- while(HasMoreData())
- {
- BsonType type = (BsonType) ReadByte();
- uint32_t index = ReadIntegerString();
- const Handle& value = DeserializeValue(type);
- returnArray->Set(index, value);
- }
- if(p != pEnd) ThrowAllocatedStringException(64, "Bad BSON Array: Serialize consumed unexpected number of bytes");
-
- return returnArray;
-}
-
-Handle BSONDeserializer::DeserializeValue(BsonType type)
-{
- switch(type)
- {
- case BSON_TYPE_STRING:
- return ReadString();
-
- case BSON_TYPE_INT:
- return Integer::New(ReadInt32());
-
- case BSON_TYPE_NUMBER:
- return Number::New(ReadDouble());
-
- case BSON_TYPE_NULL:
- return Null();
-
- case BSON_TYPE_UNDEFINED:
- return Undefined();
-
- case BSON_TYPE_TIMESTAMP:
- {
- int32_t lowBits = ReadInt32();
- int32_t highBits = ReadInt32();
- Local argv[] = { Int32::New(lowBits), Int32::New(highBits) };
- return bson->timestampConstructor->NewInstance(2, argv);
- }
-
- case BSON_TYPE_BOOLEAN:
- return (ReadByte() != 0) ? True() : False();
-
- case BSON_TYPE_REGEXP:
- {
- const Local& regex = ReadCString();
- int32_t options = ReadRegexOptions();
- return RegExp::New(regex, (RegExp::Flags) options);
- }
-
- case BSON_TYPE_CODE:
- {
- const Local& code = ReadString();
- const Local& scope = Object::New();
- Local argv[] = { code, scope };
- return bson->codeConstructor->NewInstance(2, argv);
- }
-
- case BSON_TYPE_CODE_W_SCOPE:
- {
- uint32_t length = ReadUInt32();
- const Local& code = ReadString();
- const Handle& scope = DeserializeDocument();
- Local argv[] = { code, scope->ToObject() };
- return bson->codeConstructor->NewInstance(2, argv);
- }
-
- case BSON_TYPE_OID:
- {
- Local argv[] = { ReadObjectId() };
- return bson->objectIDConstructor->NewInstance(1, argv);
- }
-
- case BSON_TYPE_BINARY:
- {
- uint32_t length = ReadUInt32();
- uint32_t subType = ReadByte();
- Buffer* buffer = Buffer::New(p, length);
- p += length;
-
- Handle argv[] = { buffer->handle_, Uint32::New(subType) };
- return bson->binaryConstructor->NewInstance(2, argv);
- }
-
- case BSON_TYPE_LONG:
- {
- // Read 32 bit integers
- int32_t lowBits = (int32_t) ReadInt32();
- int32_t highBits = (int32_t) ReadInt32();
-
- // If value is < 2^53 and >-2^53
- if((highBits < 0x200000 || (highBits == 0x200000 && lowBits == 0)) && highBits >= -0x200000) {
- // Adjust the pointer and read as 64 bit value
- p -= 8;
- // Read the 64 bit value
- int64_t finalValue = (int64_t) ReadInt64();
- return Number::New(finalValue);
- }
-
- Local argv[] = { Int32::New(lowBits), Int32::New(highBits) };
- return bson->longConstructor->NewInstance(2, argv);
- }
-
- case BSON_TYPE_DATE:
- return Date::New((double) ReadInt64());
-
- case BSON_TYPE_ARRAY:
- return DeserializeArray();
-
- case BSON_TYPE_OBJECT:
- return DeserializeDocument();
-
- case BSON_TYPE_SYMBOL:
- {
- const Local& string = ReadString();
- Local argv[] = { string };
- return bson->symbolConstructor->NewInstance(1, argv);
- }
-
- case BSON_TYPE_MIN_KEY:
- return bson->minKeyConstructor->NewInstance();
-
- case BSON_TYPE_MAX_KEY:
- return bson->maxKeyConstructor->NewInstance();
-
- default:
- ThrowAllocatedStringException(64, "Unhandled BSON Type: %d", type);
- }
-}
-
-
-static Handle VException(const char *msg)
-{
- HandleScope scope;
- return ThrowException(Exception::Error(String::New(msg)));
-}
-
-Persistent BSON::constructor_template;
-
-BSON::BSON() : ObjectWrap()
-{
- // Setup pre-allocated comparision objects
- _bsontypeString = Persistent::New(String::New("_bsontype"));
- _longLowString = Persistent::New(String::New("low_"));
- _longHighString = Persistent::New(String::New("high_"));
- _objectIDidString = Persistent::New(String::New("id"));
- _binaryPositionString = Persistent::New(String::New("position"));
- _binarySubTypeString = Persistent::New(String::New("sub_type"));
- _binaryBufferString = Persistent::New(String::New("buffer"));
- _doubleValueString = Persistent::New(String::New("value"));
- _symbolValueString = Persistent::New(String::New("value"));
- _dbRefRefString = Persistent::New(String::New("$ref"));
- _dbRefIdRefString = Persistent::New(String::New("$id"));
- _dbRefDbRefString = Persistent::New(String::New("$db"));
- _dbRefNamespaceString = Persistent::New(String::New("namespace"));
- _dbRefDbString = Persistent::New(String::New("db"));
- _dbRefOidString = Persistent::New(String::New("oid"));
- _codeCodeString = Persistent::New(String::New("code"));
- _codeScopeString = Persistent::New(String::New("scope"));
- _toBSONString = Persistent