From 31d10761480e903e6b646724aaf62da9ef6a4d6d Mon Sep 17 00:00:00 2001 From: cory robinson Date: Sat, 1 Oct 2016 19:31:39 -0700 Subject: [PATCH] fix(build): fix rollup --- dist/bundle.js | 27071 ++++++++++++++++++++++++++++++++++++++++++++- package.json | 15 +- rollup.config.js | 7 +- src/index.js | 6 +- 4 files changed, 27082 insertions(+), 17 deletions(-) diff --git a/dist/bundle.js b/dist/bundle.js index a7efacd..f22a810 100644 --- a/dist/bundle.js +++ b/dist/bundle.js @@ -1,13 +1,27078 @@ 'use strict'; +function _interopDefault (ex) { return (ex && (typeof ex === 'object') && 'default' in ex) ? ex['default'] : ex; } + +var events = _interopDefault(require('events')); +var tty = _interopDefault(require('tty')); +var util = _interopDefault(require('util')); +var fs = _interopDefault(require('fs')); +var net = _interopDefault(require('net')); +var http = _interopDefault(require('http')); +var buffer = _interopDefault(require('buffer')); +var path = _interopDefault(require('path')); +var url = _interopDefault(require('url')); +var stream = _interopDefault(require('stream')); +var crypto = _interopDefault(require('crypto')); +var querystring = _interopDefault(require('querystring')); +var string_decoder = _interopDefault(require('string_decoder')); +var zlib = _interopDefault(require('zlib')); + +var commonjsGlobal = typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {}; + +function createCommonjsModule(fn, module) { + return module = { exports: {} }, fn(module, module.exports), module.exports; +} + +var _typeof$1 = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { + return typeof obj; +} : function (obj) { + return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; +}; + +var asyncGenerator = function () { + function AwaitValue(value) { + this.value = value; + } + + function AsyncGenerator(gen) { + var front, back; + + function send(key, arg) { + return new Promise(function (resolve, reject) { + var request = { + key: key, + arg: arg, + resolve: resolve, + reject: reject, + next: null + }; + + if (back) { + back = back.next = request; + } else { + front = back = request; + resume(key, arg); + } + }); + } + + function resume(key, arg) { + try { + var result = gen[key](arg); + var value = result.value; + + if (value instanceof AwaitValue) { + Promise.resolve(value.value).then(function (arg) { + resume("next", arg); + }, function (arg) { + resume("throw", arg); + }); + } else { + settle(result.done ? "return" : "normal", result.value); + } + } catch (err) { + settle("throw", err); + } + } + + function settle(type, value) { + switch (type) { + case "return": + front.resolve({ + value: value, + done: true + }); + break; + + case "throw": + front.reject(value); + break; + + default: + front.resolve({ + value: value, + done: false + }); + break; + } + + front = front.next; + + if (front) { + resume(front.key, front.arg); + } else { + back = null; + } + } + + this._invoke = send; + + if (typeof gen.return !== "function") { + this.return = undefined; + } + } + + if (typeof Symbol === "function" && Symbol.asyncIterator) { + AsyncGenerator.prototype[Symbol.asyncIterator] = function () { + return this; + }; + } + + AsyncGenerator.prototype.next = function (arg) { + return this._invoke("next", arg); + }; + + AsyncGenerator.prototype.throw = function (arg) { + return this._invoke("throw", arg); + }; + + AsyncGenerator.prototype.return = function (arg) { + return this._invoke("return", arg); + }; + + return { + wrap: function (fn) { + return function () { + return new AsyncGenerator(fn.apply(this, arguments)); + }; + }, + await: function (value) { + return new AwaitValue(value); + } + }; +}(); + var classCallCheck = function (instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }; -var MODULE = function MODULE() { - classCallCheck(this, MODULE); +var createClass = function () { + function defineProperties(target, props) { + for (var i = 0; i < props.length; i++) { + var descriptor = props[i]; + descriptor.enumerable = descriptor.enumerable || false; + descriptor.configurable = true; + if ("value" in descriptor) descriptor.writable = true; + Object.defineProperty(target, descriptor.key, descriptor); + } + } + + return function (Constructor, protoProps, staticProps) { + if (protoProps) defineProperties(Constructor.prototype, protoProps); + if (staticProps) defineProperties(Constructor, staticProps); + return Constructor; + }; +}(); + +/*! +* js-data +* @version 3.0.0-rc.5 - Homepage +* @author js-data project authors +* @copyright (c) 2014-2016 js-data project authors +* @license MIT +* +* @overview js-data is a framework-agnostic, datastore-agnostic ORM/ODM for Node.js and the Browser. +*/var _typeof=typeof Symbol==="function"&&_typeof$1(Symbol.iterator)==="symbol"?function(obj){return typeof obj==="undefined"?"undefined":_typeof$1(obj);}:function(obj){return obj&&typeof Symbol==="function"&&obj.constructor===Symbol?"symbol":typeof obj==="undefined"?"undefined":_typeof$1(obj);};var defineProperty=function defineProperty(obj,key,value){if(key in obj){Object.defineProperty(obj,key,{value:value,enumerable:true,configurable:true,writable:true});}else{obj[key]=value;}return obj;};var toConsumableArray=function toConsumableArray(arr){if(Array.isArray(arr)){for(var i=0,arr2=Array(arr.length);iMake JSData use a different `Promise` constructor + * import Promise from 'bluebird' + * import {utils} from 'js-data' + * utils.Promise = Promise + * + * @name utils.Promise + * @since 3.0.0 + * @type {Function} + */Promise:Promise,/** + * Shallow copy properties that meet the following criteria from `src` to + * `dest`: + * + * - own enumerable + * - not a function + * - does not start with "_" + * + * @method utils._ + * @param {Object} dest Destination object. + * @param {Object} src Source object. + * @private + * @since 3.0.0 + */_:function _(dest,src){utils.forOwn(src,function(value,key){if(key&&dest[key]===undefined&&!utils.isFunction(value)&&key.indexOf('_')!==0){dest[key]=value;}});},/** + * Recursively iterates over relations found in `opts.with`. + * + * @method utils._forRelation + * @param {Object} opts Configuration options. + * @param {Relation} def Relation definition. + * @param {Function} fn Callback function. + * @param {*} [thisArg] Execution context for the callback function. + * @private + * @since 3.0.0 + */_forRelation:function _forRelation(opts,def,fn,thisArg){var relationName=def.relation;var containedName=null;var index=void 0;opts||(opts={});opts.with||(opts.with=[]);if((index=utils._getIndex(opts.with,relationName))>=0){containedName=relationName;}else if((index=utils._getIndex(opts.with,def.localField))>=0){containedName=def.localField;}if(opts.withAll){fn.call(thisArg,def,{});return;}else if(!containedName){return;}var optsCopy={};utils.fillIn(optsCopy,def.getRelation());utils.fillIn(optsCopy,opts);optsCopy.with=opts.with.slice();optsCopy._activeWith=optsCopy.with.splice(index,1)[0];optsCopy.with.forEach(function(relation,i){if(relation&&relation.indexOf(containedName)===0&&relation.length>=containedName.length&&relation[containedName.length]==='.'){optsCopy.with[i]=relation.substr(containedName.length+1);}else{optsCopy.with[i]='';}});fn.call(thisArg,def,optsCopy);},/** + * Find the index of a relation in the given list + * + * @method utils._getIndex + * @param {string[]} list List to search. + * @param {string} relation Relation to find. + * @private + * @returns {number} + */_getIndex:function _getIndex(list,relation){var index=-1;list.forEach(function(_relation,i){if(_relation===relation){index=i;return false;}else if(utils.isObject(_relation)){if(_relation.relation===relation){index=i;return false;}}});return index;},/** + * Define hidden (non-enumerable), writable properties on `target` from the + * provided `props`. + * + * @example + * import {utils} from 'js-data' + * function Cat () {} + * utils.addHiddenPropsToTarget(Cat.prototype, { + * say () { + * console.log('meow') + * } + * }) + * const cat = new Cat() + * cat.say() // "meow" + * + * @method utils.addHiddenPropsToTarget + * @param {Object} target That to which `props` should be added. + * @param {Object} props Properties to be added to `target`. + * @since 3.0.0 + */addHiddenPropsToTarget:function addHiddenPropsToTarget(target,props){var map={};Object.keys(props).forEach(function(propName){var descriptor=Object.getOwnPropertyDescriptor(props,propName);descriptor.enumerable=false;map[propName]=descriptor;});Object.defineProperties(target,map);},/** + * Return whether the two objects are deeply different. + * + * @example + * import {utils} from 'js-data' + * utils.areDifferent({}, {}) // false + * utils.areDifferent({ a: 1 }, { a: 1 }) // false + * utils.areDifferent({ foo: 'bar' }, {}) // true + * + * @method utils.areDifferent + * @param {Object} a Base object. + * @param {Object} b Comparison object. + * @param {Object} [opts] Configuration options. + * @param {Function} [opts.equalsFn={@link utils.deepEqual}] Equality function. + * @param {Array} [opts.ignore=[]] Array of strings or RegExp of fields to ignore. + * @returns {boolean} Whether the two objects are deeply different. + * @see utils.diffObjects + * @since 3.0.0 + */areDifferent:function areDifferent(newObject,oldObject,opts){opts||(opts={});var diff=utils.diffObjects(newObject,oldObject,opts);var diffCount=Object.keys(diff.added).length+Object.keys(diff.removed).length+Object.keys(diff.changed).length;return diffCount>0;},/** + * Verified that the given constructor is being invoked via `new`, as opposed + * to just being called like a normal function. + * + * @example + * import {utils} from 'js-data' + * function Cat () { + * utils.classCallCheck(this, Cat) + * } + * const cat = new Cat() // this is ok + * Cat() // this throws an error + * + * @method utils.classCallCheck + * @param {*} instance Instance that is being constructed. + * @param {Constructor} ctor Constructor function used to construct the + * instance. + * @since 3.0.0 + * @throws {Error} Throws an error if the constructor is being improperly + * invoked. + */classCallCheck:function classCallCheck(instance,ctor){if(!(instance instanceof ctor)){throw utils.err(''+ctor.name)(500,'Cannot call a class as a function');}},/** + * Deep copy a value. + * + * @example + * import {utils} from 'js-data' + * const a = { foo: { bar: 'baz' } } + * const b = utils.copy(a) + * a === b // false + * utils.areDifferent(a, b) // false + * + * @param {*} from Value to deep copy. + * @param {*} [to] Destination object for the copy operation. + * @param {*} [stackFrom] For internal use. + * @param {*} [stackTo] For internal use. + * @param {string[]|RegExp[]} [blacklist] List of strings or RegExp of + * properties to skip. + * @param {boolean} [plain] Whether to make a plain copy (don't try to use + * original prototype). + * @returns {*} Deep copy of `from`. + * @since 3.0.0 + */copy:function copy(from,to,stackFrom,stackTo,blacklist,plain){if(!to){to=from;if(from){if(utils.isArray(from)){to=utils.copy(from,[],stackFrom,stackTo,blacklist,plain);}else if(utils.isDate(from)){to=new Date(from.getTime());}else if(utils.isRegExp(from)){to=new RegExp(from.source,from.toString().match(/[^\/]*$/)[0]);to.lastIndex=from.lastIndex;}else if(utils.isObject(from)){if(plain){to=utils.copy(from,{},stackFrom,stackTo,blacklist,plain);}else{to=utils.copy(from,Object.create(Object.getPrototypeOf(from)),stackFrom,stackTo,blacklist,plain);}}}}else{if(from===to){throw utils.err(DOMAIN+'.copy')(500,'Cannot copy! Source and destination are identical.');}stackFrom=stackFrom||[];stackTo=stackTo||[];if(utils.isObject(from)){var index=stackFrom.indexOf(from);if(index!==-1){return stackTo[index];}stackFrom.push(from);stackTo.push(to);}var result=void 0;if(utils.isArray(from)){var i=void 0;to.length=0;for(i=0;i console.log(arguments)) + * user.emit('foo', 1, 'bar') // should log to console values (1, "bar") + * + * @method utils.eventify + * @param {Object} target Target object. + * @param {Function} [getter] Custom getter for retrieving the object's event + * listeners. + * @param {Function} [setter] Custom setter for setting the object's event + * listeners. + * @since 3.0.0 + */eventify:function eventify(target,getter,setter){target=target||this;var _events={};if(!getter&&!setter){getter=function getter(){return _events;};setter=function setter(value){_events=value;};}Object.defineProperties(target,{emit:{value:function value(){var events=getter.call(this)||{};for(var _len=arguments.length,args=Array(_len),_key=0;_key<_len;_key++){args[_key]=arguments[_key];}var type=args.shift();var listeners=events[type]||[];var i=void 0;for(i=0;i user.age === 25)) // 1 + * console.log(utils.findIndex(users, (user) => user.age > 19)) // 2 + * console.log(utils.findIndex(users, (user) => user.name === 'John')) // 0 + * console.log(utils.findIndex(users, (user) => user.name === 'Jimmy')) // -1 + * + * @method utils.findIndex + * @param {Array} array The array to search. + * @param {Function} fn Checker function. + * @returns {number} Index if found or -1 if not found. + * @since 3.0.0 + */findIndex:function findIndex(array,fn){var index=-1;if(!array){return index;}array.forEach(function(record,i){if(fn(record)){index=i;return false;}});return index;},/** + * Recursively iterate over a {@link Mapper}'s relations according to + * `opts.with`. + * + * @method utils.forEachRelation + * @param {Mapper} mapper Mapper. + * @param {Object} opts Configuration options. + * @param {Function} fn Callback function. + * @param {*} thisArg Execution context for the callback function. + * @since 3.0.0 + */forEachRelation:function forEachRelation(mapper,opts,fn,thisArg){var relationList=mapper.relationList||[];if(!relationList.length){return;}relationList.forEach(function(def){utils._forRelation(opts,def,fn,thisArg);});},/** + * Iterate over an object's own enumerable properties. + * + * @example + * import {utils} from 'js-data' + * const a = { b: 1, c: 4 } + * let sum = 0 + * utils.forOwn(a, function (value, key) { + * sum += value + * }) + * console.log(sum) // 5 + * + * @method utils.forOwn + * @param {Object} object The object whose properties are to be enumerated. + * @param {Function} fn Iteration function. + * @param {Object} [thisArg] Content to which to bind `fn`. + * @since 3.0.0 + */forOwn:function forOwn(obj,fn,thisArg){var keys=Object.keys(obj);var len=keys.length;var i=void 0;for(i=0;i1?_len4-1:0),_key4=1;_key4<_len4;_key4++){args[_key4-1]=arguments[_key4];}if(level&&!args.length){args.push(level);level='debug';}if(level==='debug'&&!this.debug){return;}var prefix=level.toUpperCase()+': ('+(this.name||this.constructor.name)+')';if(utils.isFunction(console[level])){var _console;(_console=console)[level].apply(_console,[prefix].concat(args));}else{var _console2;(_console2=console).log.apply(_console2,[prefix].concat(args));}}});},/** + * Adds the given record to the provided array only if it's not already in the + * array. + * + * @example + * import {utils} from 'js-data' + * const colors = ['red', 'green', 'yellow'] + * + * console.log(colors.length) // 3 + * utils.noDupeAdd(colors, 'red') + * console.log(colors.length) // 3, red already exists + * + * utils.noDupeAdd(colors, 'blue') + * console.log(colors.length) // 4, blue was added + * + * @method utils.noDupeAdd + * @param {Array} array The array. + * @param {*} record The value to add. + * @param {Function} fn Callback function passed to {@link utils.findIndex}. + * @since 3.0.0 + */noDupeAdd:function noDupeAdd(array,record,fn){if(!array){return;}var index=this.findIndex(array,fn);if(index<0){array.push(record);}},/** + * Return a shallow copy of the provided object, minus the properties + * specified in `keys`. + * + * @example + * import {utils} from 'js-data' + * const a = { name: 'John', $hashKey: 1214910 } + * + * let b = utils.omit(a, ['$hashKey']) + * console.log(b) // { name: 'John' } + * + * @method utils.omit + * @param {Object} props The object to copy. + * @param {string[]} keys Array of strings, representing properties to skip. + * @returns {Object} Shallow copy of `props`, minus `keys`. + * @since 3.0.0 + */omit:function omit(props,keys){var _props={};utils.forOwn(props,function(value,key){if(keys.indexOf(key)===-1){_props[key]=value;}});return _props;},/** + * Return a shallow copy of the provided object, but only include the + * properties specified in `keys`. + * + * @example + * import {utils} from 'js-data' + * const a = { name: 'John', $hashKey: 1214910 } + * + * let b = utils.pick(a, ['$hashKey']) + * console.log(b) // { $hashKey: 1214910 } + * + * @method utils.pick + * @param {Object} props The object to copy. + * @param {string[]} keys Array of strings, representing properties to keep. + * @returns {Object} Shallow copy of `props`, but only including `keys`. + * @since 3.0.0 + */pick:function pick(props,keys){var _props={};utils.forOwn(props,function(value,key){if(keys.indexOf(key)!==-1){_props[key]=value;}});return _props;},/** + * Return a plain copy of the given value. + * + * @example + * import {utils} from 'js-data' + * const a = { name: 'John' } + * let b = utils.plainCopy(a) + * console.log(a === b) // false + * + * @method utils.plainCopy + * @param {*} value The value to copy. + * @returns {*} Plain copy of `value`. + * @see utils.copy + * @since 3.0.0 + */plainCopy:function plainCopy(value){return utils.copy(value,undefined,undefined,undefined,undefined,true);},/** + * Shortcut for `utils.Promise.reject(value)`. + * + * @example + * import {utils} from 'js-data' + * + * utils.reject("Testing static reject").then(function(data) { + * // not called + * }).catch(function(reason) { + * console.log(reason); // "Testing static reject" + * }) + * + * @method utils.reject + * @param {*} [value] Value with which to reject the Promise. + * @returns {Promise} Promise reject with `value`. + * @see utils.Promise + * @since 3.0.0 + */reject:function reject(value){return utils.Promise.reject(value);},/** + * Remove the last item found in array according to the given checker function. + * + * @example + * import {utils} from 'js-data' + * + * const colors = ['red', 'green', 'yellow', 'red'] + * utils.remove(colors, (color) => color === 'red') + * console.log(colors) // ['red', 'green', 'yellow'] + * + * @method utils.remove + * @param {Array} array The array to search. + * @param {Function} fn Checker function. + */remove:function remove(array,fn){if(!array||!array.length){return;}var index=this.findIndex(array,fn);if(index>=0){array.splice(index,1);// todo should this be recursive? +}},/** + * Shortcut for `utils.Promise.resolve(value)`. + * + * @example + * import {utils} from 'js-data' + * + * utils.resolve("Testing static resolve").then(function(data) { + * console.log(data); // "Testing static resolve" + * }).catch(function(reason) { + * // not called + * }) + * + * @param {*} [value] Value with which to resolve the Promise. + * @returns {Promise} Promise resolved with `value`. + * @see utils.Promise + * @since 3.0.0 + */resolve:function resolve(value){return utils.Promise.resolve(value);},/** + * Set the value at the provided key or path. + * + * @example + * import {utils} from 'js-data' + * + * const john = { + * name: 'John', + * age: 25, + * parent: { + * name: 'John's Mom', + * age: 50 + * } + * } + * // set value by key + * utils.set(john, 'id', 98) + * console.log(john.id) // 98 + * + * // set value by path + * utils.set(john, 'parent.id', 20) + * console.log(john.parent.id) // 20 + * + * // set value by path/value map + * utils.set(john, { + * 'id': 1098, + * 'parent': { id: 1020 }, + * 'parent.age': '55' + * }) + * console.log(john.id) // 1098 + * console.log(john.parent.id) // 1020 + * console.log(john.parent.age) // 55 + * + * @method utils.set + * @param {Object} object The object on which to set a property. + * @param {(string|Object)} path The key or path to the property. Can also + * pass in an object of path/value pairs, which will all be set on the target + * object. + * @param {*} [value] The value to set. + */set:function set(object,path,value){if(utils.isObject(path)){utils.forOwn(path,function(value,_path){utils.set(object,_path,value);});}else{var parts=PATH.exec(path);if(parts){mkdirP(object,parts[1])[parts[2]]=value;}else{object[path]=value;}}},/** + * Check whether the two provided objects are deeply equal. + * + * @example + * import {utils} from 'js-data' + * + * const objA = { + * name: 'John', + * id: 27, + * nested: { + * item: 'item 1', + * colors: ['red', 'green', 'blue'] + * } + * } + * + * const objB = { + * name: 'John', + * id: 27, + * nested: { + * item: 'item 1', + * colors: ['red', 'green', 'blue'] + * } + * } + * + * console.log(utils.deepEqual(a,b)) // true + * objB.nested.colors.add('yellow') // make a change to a nested object's array + * console.log(utils.deepEqual(a,b)) // false + * + * @method utils.deepEqual + * @param {Object} a First object in the comparison. + * @param {Object} b Second object in the comparison. + * @returns {boolean} Whether the two provided objects are deeply equal. + * @see utils.equal + * @since 3.0.0 + */deepEqual:function deepEqual(a,b){if(a===b){return true;}var _equal=true;if(utils.isObject(a)&&utils.isObject(b)){utils.forOwn(a,function(value,key){_equal=_equal&&utils.deepEqual(value,b[key]);});if(!_equal){return _equal;}utils.forOwn(b,function(value,key){_equal=_equal&&utils.deepEqual(value,a[key]);});}else if(utils.isArray(a)&&utils.isArray(b)){a.forEach(function(value,i){_equal=_equal&&utils.deepEqual(value,b[i]);if(!_equal){return false;}});}else{return false;}return _equal;},/** + * Proxy for `JSON.stringify`. + * + * @example + * import {utils} from 'js-data' + * + * const a = { name: 'John' } + * let jsonVal = utils.toJson(a) + * console.log(jsonVal) // '{"name" : "John"}' + * + * @method utils.toJson + * @param {*} value Value to serialize to JSON. + * @returns {string} JSON string. + * @see utils.fromJson + * @since 3.0.0 + */toJson:JSON.stringify,/** + * Unset the value at the provided key or path. + * + * @example + * import {utils} from 'js-data' + * + * const john = { + * name: 'John', + * age: 25, + * parent: { + * name: 'John's Mom', + * age: 50 + * } + * } + * + * utils.unset(john, age) + * utils.unset(john, parent.age) + * + * console.log(john.age) // null + * console.log(john.parent.age) // null + * + * @method utils.unset + * @param {Object} object The object from which to delete the property. + * @param {string} path The key or path to the property. + * @see utils.set + * @since 3.0.0 + */unset:function unset(object,path){var parts=path.split('.');var last=parts.pop();while(path=parts.shift()){// eslint-disable-line +object=object[path];if(object==null){// eslint-disable-line +return;}}object[last]=undefined;}};var safeSetProp=function safeSetProp(record,field,value){if(record&&record._set){record._set('props.'+field,value);}else{utils.set(record,field,value);}};var safeSetLink=function safeSetLink(record,field,value){if(record&&record._set){record._set('links.'+field,value);}else{utils.set(record,field,value);}};/** + * A base class which gives instances private properties. + * + * Typically you won't instantiate this class directly, but you may find it + * useful as an abstract class for your own components. + * + * See {@link Settable.extend} for an example of using {@link Settable} as a + * base class. + * + *```javascript + * import {Settable} from 'js-data' + * ``` + * + * @class Settable + * @returns {Settable} A new {@link Settable} instance. + * @since 3.0.0 + */function Settable(){var _props={};Object.defineProperties(this,{/** + * Get a private property of this instance. + * + * __Don't use the method unless you know what you're doing.__ + * + * @method Settable#_get + * @param {string} key The property to retrieve. + * @returns {*} The value of the property. + * @since 3.0.0 + */_get:{value:function value(key){return utils.get(_props,key);}},/** + * Set a private property of this instance. + * + * __Don't use the method unless you know what you're doing.__ + * + * @method __Don't use the method unless you know what you're doing.__#_set + * @param {(string|Object)} key The key or path to the property. Can also + * pass in an object of key/value pairs, which will all be set on the instance. + * @param {*} [value] The value to set. + * @since 3.0.0 + */_set:{value:function value(key,_value){return utils.set(_props,key,_value);}},/** + * Unset a private property of this instance. + * + * __Don't use the method unless you know what you're doing.__ + * + * @method __Don't use the method unless you know what you're doing.__#_unset + * @param {string} key The property to unset. + * @since 3.0.0 + */_unset:{value:function value(key){return utils.unset(_props,key);}}});}/** + * Create a subclass of this Settable: + * + * @example Settable.extend + * // Normally you would do: import {Settable} from 'js-data' + * const JSData = require('js-data@3.0.0-rc.4') + * const {Settable} = JSData + * console.log('Using JSData v' + JSData.version.full) + * + * // Extend the class using ES2015 class syntax. + * class CustomSettableClass extends Settable { + * foo () { return 'bar' } + * static beep () { return 'boop' } + * } + * const customSettable = new CustomSettableClass() + * console.log(customSettable.foo()) + * console.log(CustomSettableClass.beep()) + * + * // Extend the class using alternate method. + * const OtherSettableClass = Settable.extend({ + * foo () { return 'bar' } + * }, { + * beep () { return 'boop' } + * }) + * const otherSettable = new OtherSettableClass() + * console.log(otherSettable.foo()) + * console.log(OtherSettableClass.beep()) + * + * // Extend the class, providing a custom constructor. + * function AnotherSettableClass () { + * Settable.call(this) + * this.created_at = new Date().getTime() + * } + * Settable.extend({ + * constructor: AnotherSettableClass, + * foo () { return 'bar' } + * }, { + * beep () { return 'boop' } + * }) + * const anotherSettable = new AnotherSettableClass() + * console.log(anotherSettable.created_at) + * console.log(anotherSettable.foo()) + * console.log(AnotherSettableClass.beep()) + * + * @method Settable.extend + * @param {Object} [props={}] Properties to add to the prototype of the + * subclass. + * @param {Object} [props.constructor] Provide a custom constructor function + * to be used as the subclass itself. + * @param {Object} [classProps={}] Static properties to add to the subclass. + * @returns {Constructor} Subclass of this Settable class. + * @since 3.0.0 + */Settable.extend=utils.extend;/** + * The base class from which all JSData components inherit some basic + * functionality. + * + * Typically you won't instantiate this class directly, but you may find it + * useful as an abstract class for your own components. + * + * See {@link Component.extend} for an example of using {@link Component} as a + * base class. + * + *```javascript + * import {Component} from 'js-data' + * ``` + * + * @class Component + * @param {Object} [opts] Configuration options. + * @param {boolean} [opts.debug=false] See {@link Component#debug}. + * @returns {Component} A new {@link Component} instance. + * @since 3.0.0 + */function Component(opts){Settable.call(this);opts||(opts={});/** + * Whether to enable debug-level logs for this component. Anything that + * extends `Component` inherits this option and the corresponding logging + * functionality. + * + * @example Component#debug + * // Normally you would do: import {Component} from 'js-data' + * const JSData = require('js-data@3.0.0-rc.4') + * const {Component} = JSData + * console.log('Using JSData v' + JSData.version.full) + * + * const component = new Component() + * component.log('debug', 'some message') // nothing gets logged + * // Display debug logs: + * component.debug = true + * component.log('debug', 'other message') // this DOES get logged + * + * @default false + * @name Component#debug + * @since 3.0.0 + * @type {boolean} + */this.debug=opts.hasOwnProperty('debug')?!!opts.debug:false;/** + * Event listeners attached to this Component. __Do not modify.__ Use + * {@link Component#on} and {@link Component#off} instead. + * + * @name Component#_listeners + * @instance + * @since 3.0.0 + * @type {Object} + */Object.defineProperty(this,'_listeners',{value:{},writable:true});}var Component$1=Settable.extend({constructor:Component});/** + * Create a subclass of this Component: + * + * @example Component.extend + * // Normally you would do: import {Component} from 'js-data' + * const JSData = require('js-data@3.0.0-rc.4') + * const {Component} = JSData + * console.log('Using JSData v' + JSData.version.full) + * + * // Extend the class using ES2015 class syntax. + * class CustomComponentClass extends Component { + * foo () { return 'bar' } + * static beep () { return 'boop' } + * } + * const customComponent = new CustomComponentClass() + * console.log(customComponent.foo()) + * console.log(CustomComponentClass.beep()) + * + * // Extend the class using alternate method. + * const OtherComponentClass = Component.extend({ + * foo () { return 'bar' } + * }, { + * beep () { return 'boop' } + * }) + * const otherComponent = new OtherComponentClass() + * console.log(otherComponent.foo()) + * console.log(OtherComponentClass.beep()) + * + * // Extend the class, providing a custom constructor. + * function AnotherComponentClass () { + * Component.call(this) + * this.created_at = new Date().getTime() + * } + * Component.extend({ + * constructor: AnotherComponentClass, + * foo () { return 'bar' } + * }, { + * beep () { return 'boop' } + * }) + * const anotherComponent = new AnotherComponentClass() + * console.log(anotherComponent.created_at) + * console.log(anotherComponent.foo()) + * console.log(AnotherComponentClass.beep()) + * + * @method Component.extend + * @param {Object} [props={}] Properties to add to the prototype of the + * subclass. + * @param {Object} [props.constructor] Provide a custom constructor function + * to be used as the subclass itself. + * @param {Object} [classProps={}] Static properties to add to the subclass. + * @returns {Constructor} Subclass of this Component class. + * @since 3.0.0 + */Component.extend=utils.extend;/** + * Log the provided values at the "debug" level. Debug-level logs are only + * logged if {@link Component#debug} is `true`. + * + * `.dbg(...)` is shorthand for `.log('debug', ...)`. + * + * @method Component#dbg + * @param {...*} [args] Values to log. + * @since 3.0.0 + *//** + * Log the provided values. By default sends values to `console[level]`. + * Debug-level logs are only logged if {@link Component#debug} is `true`. + * + * Will attempt to use appropriate `console` methods if they are available. + * + * @method Component#log + * @param {string} level Log level. + * @param {...*} [args] Values to log. + * @since 3.0.0 + */utils.logify(Component.prototype);/** + * Register a new event listener on this Component. + * + * @example + * // Listen for all "afterCreate" events in a DataStore + * store.on('afterCreate', (mapperName, props, opts, result) => { + * console.log(mapperName) // "post" + * console.log(props.id) // undefined + * console.log(result.id) // 1234 + * }) + * store.create('post', { title: 'Modeling your data' }).then((post) => { + * console.log(post.id) // 1234 + * }) + * + * @example + * // Listen for the "add" event on a collection + * collection.on('add', (records) => { + * console.log(records) // [...] + * }) + * + * @example + * // Listen for "change" events on a record + * post.on('change', (record, changes) => { + * console.log(changes) // { changed: { title: 'Modeling your data' } } + * }) + * post.title = 'Modeling your data' + * + * @method Component#on + * @param {string} event Name of event to subsribe to. + * @param {Function} listener Listener function to handle the event. + * @param {*} [ctx] Optional content in which to invoke the listener. + * @since 3.0.0 + *//** + * Remove an event listener from this Component. If no listener is provided, + * then all listeners for the specified event will be removed. If no event is + * specified then all listeners for all events will be removed. + * + * @example + * // Remove a particular listener for a particular event + * collection.off('add', handler) + * + * @example + * // Remove all listeners for a particular event + * record.off('change') + * + * @example + * // Remove all listeners to all events + * store.off() + * + * @method Component#off + * @param {string} [event] Name of event to unsubsribe to. + * @param {Function} [listener] Listener to remove. + * @since 3.0.0 + *//** + * Trigger an event on this Component. + * + * @example Component#emit + * // import {Collection, DataStore} from 'js-data' + * const JSData = require('js-data@3.0.0-rc.4') + * const {Collection, DataStore} = JSData + * + * const collection = new Collection() + * collection.on('foo', function (msg) { + * console.log(msg) + * }) + * collection.emit('foo', 'bar') + * + * const store = new DataStore() + * store.on('beep', function (msg) { + * console.log(msg) + * }) + * store.emit('beep', 'boop') + * + * @method Component#emit + * @param {string} event Name of event to emit. + * @param {...*} [args] Arguments to pass to any listeners. + * @since 3.0.0 + */utils.eventify(Component.prototype,function(){return this._listeners;},function(value){this._listeners=value;});var DOMAIN$2='Query';var INDEX_ERR='Index inaccessible after first operation';// Reserved words used by JSData's Query Syntax +var reserved={limit:'',offset:'',orderBy:'',skip:'',sort:'',where:''};// Used by our JavaScript implementation of the LIKE operator +var escapeRegExp=/([.*+?^=!:${}()|[\]\/\\])/g;var percentRegExp=/%/g;var underscoreRegExp=/_/g;var escape=function escape(pattern){return pattern.replace(escapeRegExp,'\\$1');};/** + * A class used by the {@link Collection} class to build queries to be executed + * against the collection's data. An instance of `Query` is returned by + * {@link Collection#query}. Query instances are typically short-lived, and you + * shouldn't have to create them yourself. Just use {@link Collection#query}. + * + * ```javascript + * import {Query} from 'js-data' + * ``` + * + * @example + * const store = new JSData.DataStore() + * store.defineMapper('post') + * const posts = [ + * { author: 'John', age: 30, status: 'published', id: 1 }, + * { author: 'Sally', age: 31, status: 'draft', id: 2 }, + * { author: 'Mike', age: 32, status: 'draft', id: 3 }, + * { author: 'Adam', age: 33, status: 'deleted', id: 4 }, + * { author: 'Adam', age: 33, status: 'draft', id: 5 } + * ] + * store.add('post', posts) + * const drafts = store.query('post').filter({ status: 'draft' }).limit(2).run() + * console.log(drafts) + * + * @class Query + * @extends Component + * @param {Collection} collection The collection on which this query operates. + * @since 3.0.0 + */function Query(collection){utils.classCallCheck(this,Query);/** + * The {@link Collection} on which this query operates. + * + * @name Query#collection + * @since 3.0.0 + * @type {Collection} + */this.collection=collection;/** + * The current data result of this query. + * + * @name Query#data + * @since 3.0.0 + * @type {Array} + */this.data=null;}var Query$1=Component$1.extend({constructor:Query,_applyWhereFromObject:function _applyWhereFromObject(where){var fields=[];var ops=[];var predicates=[];utils.forOwn(where,function(clause,field){if(!utils.isObject(clause)){clause={'==':clause};}utils.forOwn(clause,function(expr,op){fields.push(field);ops.push(op);predicates.push(expr);});});return{fields:fields,ops:ops,predicates:predicates};},_applyWhereFromArray:function _applyWhereFromArray(where){var _this=this;var groups=[];where.forEach(function(_where,i){if(utils.isString(_where)){return;}var prev=where[i-1];var parser=utils.isArray(_where)?_this._applyWhereFromArray:_this._applyWhereFromObject;var group=parser.call(_this,_where);if(prev==='or'){group.isOr=true;}groups.push(group);});groups.isArray=true;return groups;},_testObjectGroup:function _testObjectGroup(keep,first,group,item){var i=void 0;var fields=group.fields;var ops=group.ops;var predicates=group.predicates;var len=ops.length;for(i=0;iGet the users ages 18 to 30. + * const store = new JSData.DataStore() + * store.defineMapper('user') + * const users = [ + * { name: 'Peter', age: 25, id: 1 }, + * { name: 'Jim', age: 19, id: 2 }, + * { name: 'Mike', age: 17, id: 3 }, + * { name: 'Alan', age: 29, id: 4 }, + * { name: 'Katie', age: 33, id: 5 } + * ] + * store.add('post', posts) + * const filteredUsers = store.query('user').between(18, 30, { index: 'age' }).run() + * console.log(filteredUsers) + * + * @example Same as above. + * const store = new JSData.DataStore() + * store.defineMapper('user') + * const users = [ + * { name: 'Peter', age: 25, id: 1 }, + * { name: 'Jim', age: 19, id: 2 }, + * { name: 'Mike', age: 17, id: 3 }, + * { name: 'Alan', age: 29, id: 4 }, + * { name: 'Katie', age: 33, id: 5 } + * ] + * store.add('post', posts) + * const filteredUsers = store.query('user').between([18], [30], { index: 'age' }).run() + * console.log(filteredUsers) + * + * @method Query#between + * @param {Array} leftKeys Keys defining the left boundary. + * @param {Array} rightKeys Keys defining the right boundary. + * @param {Object} [opts] Configuration options. + * @param {string} [opts.index] Name of the secondary index to use in the + * query. If no index is specified, the main index is used. + * @param {boolean} [opts.leftInclusive=true] Whether to include entities + * on the left boundary. + * @param {boolean} [opts.rightInclusive=false] Whether to include entities + * on the left boundary. + * @param {boolean} [opts.limit] Limit the result to a certain number. + * @param {boolean} [opts.offset] The number of resulting entities to skip. + * @returns {Query} A reference to itself for chaining. + * @since 3.0.0 + */between:function between(leftKeys,rightKeys,opts){opts||(opts={});if(this.data){throw utils.err(DOMAIN$2+'#between')(500,'Cannot access index');}this.data=this.collection.getIndex(opts.index).between(leftKeys,rightKeys,opts);return this;},/** + * The comparison function used by the {@link Query} class. + * + * @method Query#compare + * @param {Array} orderBy An orderBy clause used for sorting and sub-sorting. + * @param {number} index The index of the current orderBy clause being used. + * @param {*} a The first item in the comparison. + * @param {*} b The second item in the comparison. + * @returns {number} -1 if `b` should preceed `a`. 0 if `a` and `b` are equal. + * 1 if `a` should preceed `b`. + * @since 3.0.0 + */compare:function compare(orderBy,index,a,b){var def=orderBy[index];var cA=utils.get(a,def[0]);var cB=utils.get(b,def[0]);if(cA&&utils.isString(cA)){cA=cA.toUpperCase();}if(cB&&utils.isString(cB)){cB=cB.toUpperCase();}if(a===undefined){a=null;}if(b===undefined){b=null;}if(def[1].toUpperCase()==='DESC'){var temp=cB;cB=cA;cA=temp;}if(cAcB){return 1;}else{if(indexGet the draft posts by authors younger than 30 + * const store = new JSData.DataStore() + * store.defineMapper('post') + * const posts = [ + * { author: 'John', age: 30, status: 'published', id: 1 }, + * { author: 'Sally', age: 31, status: 'published', id: 2 }, + * { author: 'Mike', age: 32, status: 'draft', id: 3 }, + * { author: 'Adam', age: 33, status: 'deleted', id: 4 }, + * { author: 'Adam', age: 33, status: 'published', id: 5 } + * { author: 'Peter', age: 25, status: 'deleted', id: 6 }, + * { author: 'Sally', age: 21, status: 'draft', id: 7 }, + * { author: 'Jim', age: 27, status: 'draft', id: 8 }, + * { author: 'Jim', age: 27, status: 'published', id: 9 }, + * { author: 'Jason', age: 55, status: 'published', id: 10 } + * ] + * store.add('post', posts) + * let results = store.query('post').filter({ + * where: { + * status: { + * '==': 'draft' + * }, + * age: { + * '<': 30 + * } + * } + * }).run() + * console.log(results) + * + * @example Use a custom filter function + * const posts = query.filter(function (post) { + * return post.isReady() + * }).run() + * + * @method Query#filter + * @param {(Object|Function)} [queryOrFn={}] Selection query or filter + * function. + * @param {Function} [thisArg] Context to which to bind `queryOrFn` if + * `queryOrFn` is a function. + * @returns {Query} A reference to itself for chaining. + * @since 3.0.0 + */filter:function filter(query,thisArg){var _this2=this;/** + * Selection query as defined by JSData's [Query Syntax][querysyntax]. + * + * [querysyntax]: http://www.js-data.io/v3.0/docs/query-syntax + * + * @example Empty "findAll" query + * const store = new JSData.DataStore() + * store.defineMapper('post') + * store.findAll('post').then((posts) => { + * console.log(posts) // [...] + * }) + * + * @example Empty "filter" query + * const store = new JSData.DataStore() + * store.defineMapper('post') + * const posts = store.filter('post') + * console.log(posts) // [...] + * + * @example Complex "filter" query + * const PAGE_SIZE = 2 + * let currentPage = 3 + * + * const store = new JSData.DataStore() + * store.defineMapper('post') + * const posts = [ + * { author: 'John', age: 30, status: 'published', id: 1 }, + * { author: 'Sally', age: 31, status: 'published', id: 2 }, + * { author: 'Mike', age: 32, status: 'draft', id: 3 }, + * { author: 'Adam', age: 33, status: 'deleted', id: 4 }, + * { author: 'Adam', age: 33, status: 'published', id: 5 } + * { author: 'Peter', age: 25, status: 'deleted', id: 6 }, + * { author: 'Sally', age: 21, status: 'draft', id: 7 }, + * { author: 'Jim', age: 27, status: 'draft', id: 8 }, + * { author: 'Jim', age: 27, status: 'published', id: 9 }, + * { author: 'Jason', age: 55, status: 'published', id: 10 } + * ] + * store.add('post', posts) + * // Retrieve a filtered page of blog posts + * // Would typically replace filter with findAll + * store.filter('post', { + * where: { + * status: { + * // WHERE status = 'published' + * '==': 'published' + * }, + * author: { + * // AND author IN ('bob', 'alice') + * 'in': ['bob', 'alice'], + * // OR author IN ('karen') + * '|in': ['karen'] + * } + * }, + * orderBy: [ + * // ORDER BY date_published DESC, + * ['date_published', 'DESC'], + * // ORDER BY title ASC + * ['title', 'ASC'] + * ], + * // LIMIT 2 + * limit: PAGE_SIZE, + * // SKIP 4 + * offset: PAGE_SIZE * (currentPage - 1) + * }) + * + * @namespace query + * @property {number} [limit] See {@link query.limit}. + * @property {number} [offset] See {@link query.offset}. + * @property {string|Array[]} [orderBy] See {@link query.orderBy}. + * @property {number} [skip] Alias for {@link query.offset}. + * @property {string|Array[]} [sort] Alias for {@link query.orderBy}. + * @property {Object} [where] See {@link query.where}. + * @since 3.0.0 + * @tutorial ["http://www.js-data.io/v3.0/docs/query-syntax","JSData's Query Syntax"] + */query||(query={});this.getData();if(utils.isObject(query)){(function(){var where={};/** + * Filtering criteria. Records that do not meet this criteria will be exluded + * from the result. + * + * @example Return posts where author is at least 32 years old + * const store = new JSData.DataStore() + * store.defineMapper('post') + * const posts = [ + * { author: 'John', age: 30, id: 5 }, + * { author: 'Sally', age: 31, id: 6 }, + * { author: 'Mike', age: 32, id: 7 }, + * { author: 'Adam', age: 33, id: 8 }, + * { author: 'Adam', age: 33, id: 9 } + * ] + * store.add('post', posts) + * store.filter('post', { + * where: { + * age: { + * '>=': 30 + * } + * } + * }) + * console.log(results) + * + * @name query.where + * @type {Object} + * @see http://www.js-data.io/v3.0/docs/query-syntax + * @since 3.0.0 + */if(utils.isObject(query.where)||utils.isArray(query.where)){where=query.where;}utils.forOwn(query,function(value,key){if(!(key in reserved)&&!(key in where)){where[key]={'==':value};}});var groups=void 0;// Apply filter for each field +if(utils.isObject(where)&&Object.keys(where).length!==0){groups=_this2._applyWhereFromArray([where]);}else if(utils.isArray(where)){groups=_this2._applyWhereFromArray(where);}if(groups){_this2.data=_this2.data.filter(function(item,i){return _this2._testArrayGroup(true,true,groups,item).keep;});}// Sort +var orderBy=query.orderBy||query.sort;if(utils.isString(orderBy)){orderBy=[[orderBy,'ASC']];}if(!utils.isArray(orderBy)){orderBy=null;}/** + * Determines how records should be ordered in the result. + * + * @example Order posts by `author` then by `id` descending + * const store = new JSData.DataStore() + * store.defineMapper('post') + * const posts = [ + * { author: 'John', age: 30, id: 5 }, + * { author: 'Sally', age: 31, id: 6 }, + * { author: 'Mike', age: 32, id: 7 }, + * { author: 'Adam', age: 33, id: 8 }, + * { author: 'Adam', age: 33, id: 9 } + * ] + * store.add('post', posts) + * store.filter('post', { + * orderBy:[['author','ASC'],['id','DESC']] + * }) + * console.log(results) + * + * @name query.orderBy + * @type {string|Array[]} + * @see http://www.js-data.io/v3.0/docs/query-syntax + * @since 3.0.0 + */if(orderBy){(function(){var index=0;orderBy.forEach(function(def,i){if(utils.isString(def)){orderBy[i]=[def,'ASC'];}});_this2.data.sort(function(a,b){return _this2.compare(orderBy,index,a,b);});})();}/** + * Number of records to skip. + * + * @example Retrieve the first "page" of blog posts using findAll + * const PAGE_SIZE = 10 + * let currentPage = 1 + * PostMapper.findAll({ + * offset: PAGE_SIZE * (currentPage 1) + * limit: PAGE_SIZE + * }) + * + * @example Retrieve the last "page" of blog posts using filter + * const PAGE_SIZE = 5 + * let currentPage = 2 + * const store = new JSData.DataStore() + * store.defineMapper('post') + * const posts = [ + * { author: 'John', age: 30, id: 1 }, + * { author: 'Sally', age: 31, id: 2 }, + * { author: 'Mike', age: 32, id: 3 }, + * { author: 'Adam', age: 33, id: 4 }, + * { author: 'Adam', age: 33, id: 5 }, + * { author: 'Peter', age: 25, id: 6 }, + * { author: 'Sally', age: 21, id: 7 }, + * { author: 'Jim', age: 27, id: 8 }, + * { author: 'Jim', age: 27, id: 9 }, + * { author: 'Jason', age: 55, id: 10 } + * ] + * store.add('post', posts) + * store.filter('post', { + * offset: PAGE_SIZE * (currentPage 1) + * limit: PAGE_SIZE + * }) + * + * console.log(results) + * + * @name query.offset + * @type {number} + * @see http://www.js-data.io/v3.0/docs/query-syntax + * @since 3.0.0 + */if(utils.isNumber(query.skip)){_this2.skip(query.skip);}else if(utils.isNumber(query.offset)){_this2.skip(query.offset);}/** + * Maximum number of records to retrieve. + * + * @example Retrieve the first "page" of blog posts using findAll + * const PAGE_SIZE = 10 + * let currentPage = 1 + * PostMapper.findAll({ + * offset: PAGE_SIZE * (currentPage 1) + * limit: PAGE_SIZE + * }) + * + * @example Retrieve the last "page" of blog posts using filter + * const PAGE_SIZE = 5 + * let currentPage = 2 + * const store = new JSData.DataStore() + * store.defineMapper('post') + * const posts = [ + * { author: 'John', age: 30, id: 1 }, + * { author: 'Sally', age: 31, id: 2 }, + * { author: 'Mike', age: 32, id: 3 }, + * { author: 'Adam', age: 33, id: 4 }, + * { author: 'Adam', age: 33, id: 5 }, + * { author: 'Peter', age: 25, id: 6 }, + * { author: 'Sally', age: 21, id: 7 }, + * { author: 'Jim', age: 27, id: 8 }, + * { author: 'Jim', age: 27, id: 9 }, + * { author: 'Jason', age: 55, id: 10 } + * ] + * store.add('post', posts) + * store.filter('post', { + * offset: PAGE_SIZE * (currentPage 1) + * limit: PAGE_SIZE + * }) + * + * console.log(results) + * @name query.limit + * @type {number} + * @see http://www.js-data.io/v3.0/docs/query-syntax + * @since 3.0.0 + */if(utils.isNumber(query.limit)){_this2.limit(query.limit);}})();}else if(utils.isFunction(query)){this.data=this.data.filter(query,thisArg);}return this;},/** + * Iterate over all entities. + * + * @method Query#forEach + * @param {Function} forEachFn Iteration function. + * @param {*} [thisArg] Context to which to bind `forEachFn`. + * @returns {Query} A reference to itself for chaining. + * @since 3.0.0 + */forEach:function forEach(forEachFn,thisArg){this.getData().forEach(forEachFn,thisArg);return this;},/** + * Find the entity or entities that match the provided key. + * + * @example Get the entity whose primary key is 25. + * const entities = query.get(25).run() + * + * @example Same as above. + * const entities = query.get([25]).run() + * + * @example Get all users who are active and have the "admin" role. + * const activeAdmins = query.get(['active', 'admin'], { + * index: 'activityAndRoles' + * }).run() + * + * @example Get all entities that match a certain weather condition. + * const niceDays = query.get(['sunny', 'humid', 'calm'], { + * index: 'weatherConditions' + * }).run() + * + * @method Query#get + * @param {Array} keyList Key(s) defining the entity to retrieve. If + * `keyList` is not an array (i.e. for a single-value key), it will be + * wrapped in an array. + * @param {Object} [opts] Configuration options. + * @param {string} [opts.string] Name of the secondary index to use in the + * query. If no index is specified, the main index is used. + * @returns {Query} A reference to itself for chaining. + * @since 3.0.0 + */get:function get(keyList,opts){keyList||(keyList=[]);opts||(opts={});if(this.data){throw utils.err(DOMAIN$2+'#get')(500,INDEX_ERR);}if(keyList&&!utils.isArray(keyList)){keyList=[keyList];}if(!keyList.length){this.getData();return this;}this.data=this.collection.getIndex(opts.index).get(keyList);return this;},/** + * Find the entity or entities that match the provided keyLists. + * + * @example Get the posts where "status" is "draft" or "inReview". + * const posts = query.getAll('draft', 'inReview', { index: 'status' }).run() + * + * @example Same as above. + * const posts = query.getAll(['draft'], ['inReview'], { index: 'status' }).run() + * + * @method Query#getAll + * @param {...Array} [keyList] Provide one or more keyLists, and all + * entities matching each keyList will be retrieved. If no keyLists are + * provided, all entities will be returned. + * @param {Object} [opts] Configuration options. + * @param {string} [opts.index] Name of the secondary index to use in the + * query. If no index is specified, the main index is used. + * @returns {Query} A reference to itself for chaining. + * @since 3.0.0 + */getAll:function getAll(){var _this3=this;var opts={};if(this.data){throw utils.err(DOMAIN$2+'#getAll')(500,INDEX_ERR);}for(var _len=arguments.length,args=Array(_len),_key=0;_key<_len;_key++){args[_key]=arguments[_key];}if(!args.length||args.length===1&&utils.isObject(args[0])){this.getData();return this;}else if(args.length&&utils.isObject(args[args.length-1])){opts=args[args.length-1];args.pop();}var collection=this.collection;var index=collection.getIndex(opts.index);this.data=[];args.forEach(function(keyList){_this3.data=_this3.data.concat(index.get(keyList));});return this;},/** + * Return the current data result of this query. + * + * @method Query#getData + * @returns {Array} The data in this query. + * @since 3.0.0 + */getData:function getData(){if(!this.data){this.data=this.collection.index.getAll();}return this.data;},/** + * Implementation used by the `like` operator. Takes a pattern and flags and + * returns a `RegExp` instance that can test strings. + * + * @method Query#like + * @param {string} pattern Testing pattern. + * @param {string} flags Flags for the regular expression. + * @returns {RegExp} Regular expression for testing strings. + * @since 3.0.0 + */like:function like(pattern,flags){return new RegExp('^'+escape(pattern).replace(percentRegExp,'.*').replace(underscoreRegExp,'.')+'$',flags);},/** + * Limit the result. + * + * @example Get only the first 2 posts. + * const store = new JSData.DataStore() + * store.defineMapper('post') + * const posts = [ + * { author: 'John', age: 30, status: 'published', id: 1 }, + * { author: 'Sally', age: 31, status: 'draft', id: 2 }, + * { author: 'Mike', age: 32, status: 'draft', id: 3 }, + * { author: 'Adam', age: 33, status: 'deleted', id: 4 }, + * { author: 'Adam', age: 33, status: 'draft', id: 5 } + * ] + * store.add('post', posts) + * const results = store.query('post').limit(2).run() + * console.log(results) + * + * @method Query#limit + * @param {number} num The maximum number of entities to keep in the result. + * @returns {Query} A reference to itself for chaining. + * @since 3.0.0 + */limit:function limit(num){if(!utils.isNumber(num)){throw utils.err(DOMAIN$2+'#limit','num')(400,'number',num);}var data=this.getData();this.data=data.slice(0,Math.min(data.length,num));return this;},/** + * Apply a mapping function to the result data. + * + * @example + * // Return the age of all users + * const store = new JSData.DataStore() + * store.defineMapper('user') + * const users = [ + * { name: 'Peter', age: 25, id: 1 }, + * { name: 'Jim', age: 19, id: 2 }, + * { name: 'Mike', age: 17, id: 3 }, + * { name: 'Alan', age: 29, id: 4 }, + * { name: 'Katie', age: 33, id: 5 } + * ] + * store.add('post', posts) + * const ages = store.query('user').map((user) => { + * return user.age + * }).run() + * console.log(ages) + * + * @method Query#map + * @param {Function} mapFn Mapping function. + * @param {*} [thisArg] Context to which to bind `mapFn`. + * @returns {Query} A reference to itself for chaining. + * @since 3.0.0 + */map:function map(mapFn,thisArg){this.data=this.getData().map(mapFn,thisArg);return this;},/** + * Return the result of calling the specified function on each item in this + * collection's main index. + * + * @example + * const stringAges = UserCollection.query().mapCall('toString').run() + * + * @method Query#mapCall + * @param {string} funcName Name of function to call + * @parama {...*} [args] Remaining arguments to be passed to the function. + * @returns {Query} A reference to itself for chaining. + * @since 3.0.0 + */mapCall:function mapCall(funcName){for(var _len2=arguments.length,args=Array(_len2>1?_len2-1:0),_key2=1;_key2<_len2;_key2++){args[_key2-1]=arguments[_key2];}this.data=this.getData().map(function(item){return item[funcName].apply(item,args);});return this;},/** + * Complete the execution of the query and return the resulting data. + * + * @method Query#run + * @returns {Array} The result of executing this query. + * @since 3.0.0 + */run:function run(){var data=this.data;this.data=null;return data;},/** + * Skip a number of results. + * + * @example Get all but the first 2 posts. + * const store = new JSData.DataStore() + * store.defineMapper('post') + * const posts = [ + * { author: 'John', age: 30, status: 'published', id: 1 }, + * { author: 'Sally', age: 31, status: 'draft', id: 2 }, + * { author: 'Mike', age: 32, status: 'draft', id: 3 }, + * { author: 'Adam', age: 33, status: 'deleted', id: 4 }, + * { author: 'Adam', age: 33, status: 'draft', id: 5 } + * ] + * store.add('post', posts) + * const results = store.query('post').skip(2).run() + * console.log(results) + * + * @method Query#skip + * @param {number} num The number of entities to skip. + * @returns {Query} A reference to itself for chaining. + * @since 3.0.0 + */skip:function skip(num){if(!utils.isNumber(num)){throw utils.err(DOMAIN$2+'#skip','num')(400,'number',num);}var data=this.getData();if(numVariant 1 + * + * const store = new JSData.DataStore() + * store.defineMapper('post') + * const posts = [ + * { author: 'John', age: 30, status: 'published', id: 1 }, + * { author: 'Sally', age: 31, status: 'published', id: 2 }, + * { author: 'Mike', age: 32, status: 'published', id: 3 }, + * { author: 'Adam', age: 33, status: 'deleted', id: 4 }, + * { author: 'Adam', age: 33, status: 'published', id: 5 } + * ] + * store.add('post', posts) + * + * const publishedPosts = store.filter('post', { + * status: 'published', + * limit: 2 + * }) + * + * console.log(publishedPosts) + * + * + * @example Variant 2 + * + * const store = new JSData.DataStore() + * store.defineMapper('post') + * const posts = [ + * { author: 'John', age: 30, status: 'published', id: 1 }, + * { author: 'Sally', age: 31, status: 'published', id: 2 }, + * { author: 'Mike', age: 32, status: 'published', id: 3 }, + * { author: 'Adam', age: 33, status: 'deleted', id: 4 }, + * { author: 'Adam', age: 33, status: 'published', id: 5 } + * ] + * store.add('post', posts) + * + * const publishedPosts = store.filter('post', { + * where: { + * status: { + * '==': 'published' + * } + * }, + * limit: 2 + * }) + * + * console.log(publishedPosts) + * + * @example Variant 3 + * + * const store = new JSData.DataStore() + * store.defineMapper('post') + * const posts = [ + * { author: 'John', age: 30, status: 'published', id: 1 }, + * { author: 'Sally', age: 31, status: 'published', id: 2 }, + * { author: 'Mike', age: 32, status: 'published', id: 3 }, + * { author: 'Adam', age: 33, status: 'deleted', id: 4 }, + * { author: 'Adam', age: 33, status: 'published', id: 5 } + * ] + * store.add('post', posts) + * + * const publishedPosts = store.query('post').filter({ + * status: 'published' + * }).limit(2).run() + * + * console.log(publishedPosts) + * + * @example Variant 4 + * + * const store = new JSData.DataStore() + * store.defineMapper('post') + * const posts = [ + * { author: 'John', age: 30, status: 'published', id: 1 }, + * { author: 'Sally', age: 31, status: 'published', id: 2 }, + * { author: 'Mike', age: 32, status: 'published', id: 3 }, + * { author: 'Adam', age: 33, status: 'deleted', id: 4 }, + * { author: 'Adam', age: 33, status: 'published', id: 5 } + * ] + * store.add('post', posts) + * + * const publishedPosts = store.query('post').filter({ + * where: { + * status: { + * '==': 'published' + * } + * } + * }).limit(2).run() + * + * console.log(publishedPosts) + * + * @example Multiple operators + * + * const store = new JSData.DataStore() + * store.defineMapper('post') + * const posts = [ + * { author: 'John', age: 30, status: 'published', id: 1 }, + * { author: 'Sally', age: 31, status: 'published', id: 2 }, + * { author: 'Mike', age: 32, status: 'published', id: 3 }, + * { author: 'Adam', age: 33, status: 'deleted', id: 4 }, + * { author: 'Adam', age: 33, status: 'published', id: 5 } + * ] + * store.add('post', posts) + * + * const myPublishedPosts = store.filter('post', { + * where: { + * status: { + * '==': 'published' + * }, + * user_id: { + * '==': currentUser.id + * } + * } + * }) + * + * console.log(myPublishedPosts) + * + * @name Query.ops + * @property {Function} == Equality operator. + * @property {Function} != Inequality operator. + * @property {Function} > Greater than operator. + * @property {Function} >= Greater than (inclusive) operator. + * @property {Function} < Less than operator. + * @property {Function} <= Less than (inclusive) operator. + * @property {Function} isectEmpty Operator that asserts that the intersection + * between two arrays is empty. + * @property {Function} isectNotEmpty Operator that asserts that the + * intersection between two arrays is __not__ empty. + * @property {Function} in Operator that asserts whether a value is in an + * array. + * @property {Function} notIn Operator that asserts whether a value is __not__ + * in an array. + * @property {Function} contains Operator that asserts whether an array + * contains a value. + * @property {Function} notContains Operator that asserts whether an array + * does __not__ contain a value. + * @since 3.0.0 + * @type {Object} + */ops:{'=':function _(value,predicate){return value==predicate;// eslint-disable-line +},'==':function _(value,predicate){return value==predicate;// eslint-disable-line +},'===':function _(value,predicate){return value===predicate;},'!=':function _(value,predicate){return value!=predicate;// eslint-disable-line +},'!==':function _(value,predicate){return value!==predicate;},'>':function _(value,predicate){return value>predicate;},'>=':function _(value,predicate){return value>=predicate;},'<':function _(value,predicate){return valueQuery.extend + * // Normally you would do: import {Query} from 'js-data' + * const JSData = require('js-data@3.0.0-rc.4') + * const {Query} = JSData + * console.log('Using JSData v' + JSData.version.full) + * + * // Extend the class using ES2015 class syntax. + * class CustomQueryClass extends Query { + * foo () { return 'bar' } + * static beep () { return 'boop' } + * } + * const customQuery = new CustomQueryClass() + * console.log(customQuery.foo()) + * console.log(CustomQueryClass.beep()) + * + * // Extend the class using alternate method. + * const OtherQueryClass = Query.extend({ + * foo () { return 'bar' } + * }, { + * beep () { return 'boop' } + * }) + * const otherQuery = new OtherQueryClass() + * console.log(otherQuery.foo()) + * console.log(OtherQueryClass.beep()) + * + * // Extend the class, providing a custom constructor. + * function AnotherQueryClass (collection) { + * Query.call(this, collection) + * this.created_at = new Date().getTime() + * } + * Query.extend({ + * constructor: AnotherQueryClass, + * foo () { return 'bar' } + * }, { + * beep () { return 'boop' } + * }) + * const anotherQuery = new AnotherQueryClass() + * console.log(anotherQuery.created_at) + * console.log(anotherQuery.foo()) + * console.log(AnotherQueryClass.beep()) + * + * @method Query.extend + * @param {Object} [props={}] Properties to add to the prototype of the + * subclass. + * @param {Object} [props.constructor] Provide a custom constructor function + * to be used as the subclass itself. + * @param {Object} [classProps={}] Static properties to add to the subclass. + * @returns {Constructor} Subclass of this Query class. + * @since 3.0.0 + */function sort(a,b,hashCode){// Short-circuit comparison if a and b are strictly equal +// This is absolutely necessary for indexed objects that +// don't have the idAttribute field +if(a===b){return 0;}if(hashCode){a=hashCode(a);b=hashCode(b);}if(a===null&&b===null||a===undefined&&b===undefined){return-1;}if(a===null||a===undefined){return-1;}if(b===null||b===undefined){return 1;}if(ab){return 1;}return 0;}function insertAt(array,index,value){array.splice(index,0,value);return array;}function removeAt(array,index){array.splice(index,1);return array;}function binarySearch(array,value,field){var lo=0;var hi=array.length;var compared=void 0;var mid=void 0;while(lo=0;i--){var value=values[i];if(value.isIndex){results=results.concat(value.getAll(opts));}else{results=results.concat(value);}}}else{for(var _i=0;_irightKey){break;}}else{if(this.keys[i]>=rightKey){break;}}}if(this.values[i].isIndex){results=results.concat(this.values[i].getAll());}else{results=results.concat(this.values[i]);}if(opts.limit){if(results.length>=opts.limit+opts.offset){break;}}}}else{for(var _i2=pos.index;_i2rightKey){break;}if(this.values[_i2].isIndex){if(currKey===leftKey){results=results.concat(this.values[_i2]._between(utils.copy(leftKeys),rightKeys.map(function(){return undefined;}),opts));}else if(currKey===rightKey){results=results.concat(this.values[_i2]._between(leftKeys.map(function(){return undefined;}),utils.copy(rightKeys),opts));}else{results=results.concat(this.values[_i2].getAll());}}else{results=results.concat(this.values[_i2]);}if(opts.limit){if(results.length>=opts.limit+opts.offset){break;}}}}if(opts.limit){return results.slice(0,opts.limit+opts.offset);}else{return results;}},peek:function peek(){if(this.values.length){if(this.values[0].isIndex){return this.values[0].peek();}else{return this.values[0];}}return[];},clear:function clear(){this.keys=[];this.values=[];},insertRecord:function insertRecord(data){var keyList=this.fieldList.map(function(field){if(utils.isFunction(field)){return field(data)||undefined;}else{return data[field]||undefined;}});this.set(keyList,data);},removeRecord:function removeRecord(data){var _this=this;var removed=void 0;var isUnique=this.hashCode(data)!==undefined;this.values.forEach(function(value,i){if(value.isIndex){if(value.removeRecord(data)){if(value.keys.length===0){removeAt(_this.keys,i);removeAt(_this.values,i);}removed=true;return false;}}else{var dataLocation={};if(_this.keys[i]===undefined||!isUnique){for(var j=value.length-1;j>=0;j--){if(value[j]===data){dataLocation={found:true,index:j};break;}}}else if(isUnique){dataLocation=binarySearch(value,data,_this.hashCode);}if(dataLocation.found){removeAt(value,dataLocation.index);if(value.length===0){removeAt(_this.keys,i);removeAt(_this.values,i);}removed=true;return false;}}});return removed?data:undefined;},updateRecord:function updateRecord(data){var removed=this.removeRecord(data);if(removed!==undefined){this.insertRecord(data);}}});var DOMAIN$1='Collection';var COLLECTION_DEFAULTS={/** + * Whether to call {@link Record#commit} on records that are added to the + * collection and already exist in the collection. + * + * @name Collection#commitOnMerge + * @type {boolean} + * @default true + */commitOnMerge:true,/** + * Field to be used as the unique identifier for records in this collection. + * Defaults to `"id"` unless {@link Collection#mapper} is set, in which case + * this will default to {@link Mapper#idAttribute}. + * + * @name Collection#idAttribute + * @type {string} + * @default "id" + */idAttribute:'id',/** + * What to do when inserting a record into this Collection that shares a + * primary key with a record already in this Collection. + * + * Possible values: + * merge + * replace + * + * Merge: + * + * Recursively shallow copy properties from the new record onto the existing + * record. + * + * Replace: + * + * Shallow copy top-level properties from the new record onto the existing + * record. Any top-level own properties of the existing record that are _not_ + * on the new record will be removed. + * + * @name Collection#onConflict + * @type {string} + * @default "merge" + */onConflict:'merge'};/** + * An ordered set of {@link Record} instances. + * + * @example Collection#constructor + * // import {Collection, Record} from 'js-data' + * const JSData = require('js-data@3.0.0-rc.4') + * const {Collection, Record} = JSData + * console.log('Using JSData v' + JSData.version.full) + * + * const user1 = new Record({ id: 1 }) + * const user2 = new Record({ id: 2 }) + * const UserCollection = new Collection([user1, user2]) + * console.log(UserCollection.get(1) === user1) + * + * @class Collection + * @extends Component + * @param {Array} [records] Initial set of records to insert into the + * collection. + * @param {Object} [opts] Configuration options. + * @param {string} [opts.commitOnMerge] See {@link Collection#commitOnMerge}. + * @param {string} [opts.idAttribute] See {@link Collection#idAttribute}. + * @param {string} [opts.onConflict="merge"] See {@link Collection#onConflict}. + * @param {string} [opts.mapper] See {@link Collection#mapper}. + * @since 3.0.0 + */function Collection(records,opts){utils.classCallCheck(this,Collection);Component$1.call(this,opts);if(records&&!utils.isArray(records)){opts=records;records=[];}if(utils.isString(opts)){opts={idAttribute:opts};}// Default values for arguments +records||(records=[]);opts||(opts={});Object.defineProperties(this,{/** + * Default Mapper for this collection. Optional. If a Mapper is provided, then + * the collection will use the {@link Mapper#idAttribute} setting, and will + * wrap records in {@link Mapper#recordClass}. + * + * @example Collection#mapper + * // Normally you would do: import {Collection, Mapper} from 'js-data' + * const JSData = require('js-data@3.0.0-rc.4') + * const {Collection, Mapper} = JSData + * console.log('Using JSData v' + JSData.version.full) + * + * class MyMapperClass extends Mapper { + * foo () { return 'bar' } + * } + * const myMapper = new MyMapperClass({ name: 'myMapper' }) + * const collection = new Collection(null, { mapper: myMapper }) + * + * @name Collection#mapper + * @type {Mapper} + * @default null + * @since 3.0.0 + */mapper:{value:undefined,writable:true},// Query class used by this collection +queryClass:{value:undefined,writable:true}});// Apply user-provided configuration +utils.fillIn(this,opts);// Fill in any missing options with the defaults +utils.fillIn(this,utils.copy(COLLECTION_DEFAULTS));if(!this.queryClass){this.queryClass=Query$1;}var idAttribute=this.recordId();Object.defineProperties(this,{/** + * The main index, which uses @{link Collection#recordId} as the key. + * + * @name Collection#index + * @type {Index} + */index:{value:new Index([idAttribute],{hashCode:function hashCode(obj){return utils.get(obj,idAttribute);}})},/** + * Object that holds the secondary indexes of this collection. + * + * @name Collection#indexes + * @type {Object.} + */indexes:{value:{}}});// Insert initial data into the collection +if(utils.isObject(records)||utils.isArray(records)&&records.length){this.add(records);}}var Collection$1=Component$1.extend({constructor:Collection,/** + * Used to bind to events emitted by records in this Collection. + * + * @method Collection#_onRecordEvent + * @since 3.0.0 + * @private + * @param {...*} [arg] Args passed to {@link Collection#emit}. + */_onRecordEvent:function _onRecordEvent(){this.emit.apply(this,arguments);},/** + * Insert the provided record or records. + * + * If a record is already in the collection then the provided record will + * either merge with or replace the existing record based on the value of the + * `onConflict` option. + * + * The collection's secondary indexes will be updated as each record is + * visited. + * + * @method Collection#add + * @since 3.0.0 + * @param {(Object|Object[]|Record|Record[])} data The record or records to insert. + * @param {Object} [opts] Configuration options. + * @param {boolean} [opts.commitOnMerge=true] See {@link Collection#commitOnMerge}. + * @param {string} [opts.onConflict] See {@link Collection#onConflict}. + * @returns {(Object|Object[]|Record|Record[])} The added record or records. + */add:function add(records,opts){var _this=this;// Default values for arguments +opts||(opts={});// Fill in "opts" with the Collection's configuration +utils._(opts,this);records=this.beforeAdd(records,opts)||records;// Track whether just one record or an array of records is being inserted +var singular=false;var idAttribute=this.recordId();if(!utils.isArray(records)){if(utils.isObject(records)){records=[records];singular=true;}else{throw utils.err(DOMAIN$1+'#add','records')(400,'object or array',records);}}// Map the provided records to existing records. +// New records will be inserted. If any records map to existing records, +// they will be merged into the existing records according to the onConflict +// option. +records=records.map(function(record){var id=_this.recordId(record);// Grab existing record if there is one +var existing=id===undefined?id:_this.get(id);// If the currently visited record is just a reference to an existing +// record, then there is nothing to be done. Exit early. +if(record===existing){return existing;}if(existing){// Here, the currently visited record corresponds to a record already +// in the collection, so we need to merge them +var onConflict=opts.onConflict||_this.onConflict;if(onConflict==='merge'){utils.deepMixIn(existing,record);}else if(onConflict==='replace'){utils.forOwn(existing,function(value,key){if(key!==idAttribute&&record[key]===undefined){existing[key]=undefined;}});existing.set(record);}else{throw utils.err(DOMAIN$1+'#add','opts.onConflict')(400,'one of (merge, replace)',onConflict,true);}record=existing;if(opts.commitOnMerge&&utils.isFunction(record.commit)){record.commit();}// Update all indexes in the collection +_this.updateIndexes(record);}else{// Here, the currently visted record does not correspond to any record +// in the collection, so (optionally) instantiate this record and insert +// it into the collection +record=_this.mapper?_this.mapper.createRecord(record,opts):record;_this.index.insertRecord(record);utils.forOwn(_this.indexes,function(index,name){index.insertRecord(record);});if(record&&utils.isFunction(record.on)){record.on('all',_this._onRecordEvent,_this);}}return record;});// Finally, return the inserted data +var result=singular?records[0]:records;this.emit('add',result);return this.afterAdd(records,opts,result)||result;},/** + * Lifecycle hook called by {@link Collection#add}. If this method returns a + * value then {@link Collection#add} will return that same value. + * + * @method Collection#method + * @since 3.0.0 + * @param {(Object|Object[]|Record|Record[])} result The record or records + * that were added to this Collection by {@link Collection#add}. + * @param {Object} opts The `opts` argument passed to {@link Collection#add}. + */afterAdd:function afterAdd(){},/** + * Lifecycle hook called by {@link Collection#remove}. If this method returns + * a value then {@link Collection#remove} will return that same value. + * + * @method Collection#afterRemove + * @since 3.0.0 + * @param {(string|number)} id The `id` argument passed to {@link Collection#remove}. + * @param {Object} opts The `opts` argument passed to {@link Collection#remove}. + * @param {Object} record The result that will be returned by {@link Collection#remove}. + */afterRemove:function afterRemove(){},/** + * Lifecycle hook called by {@link Collection#removeAll}. If this method + * returns a value then {@link Collection#removeAll} will return that same + * value. + * + * @method Collection#afterRemoveAll + * @since 3.0.0 + * @param {Object} query The `query` argument passed to {@link Collection#removeAll}. + * @param {Object} opts The `opts` argument passed to {@link Collection#removeAll}. + * @param {Object} records The result that will be returned by {@link Collection#removeAll}. + */afterRemoveAll:function afterRemoveAll(){},/** + * Lifecycle hook called by {@link Collection#add}. If this method returns a + * value then the `records` argument in {@link Collection#add} will be + * re-assigned to the returned value. + * + * @method Collection#beforeAdd + * @since 3.0.0 + * @param {(Object|Object[]|Record|Record[])} records The `records` argument passed to {@link Collection#add}. + * @param {Object} opts The `opts` argument passed to {@link Collection#add}. + */beforeAdd:function beforeAdd(){},/** + * Lifecycle hook called by {@link Collection#remove}. + * + * @method Collection#beforeRemove + * @since 3.0.0 + * @param {(string|number)} id The `id` argument passed to {@link Collection#remove}. + * @param {Object} opts The `opts` argument passed to {@link Collection#remove}. + */beforeRemove:function beforeRemove(){},/** + * Lifecycle hook called by {@link Collection#removeAll}. + * + * @method Collection#beforeRemoveAll + * @since 3.0.0 + * @param {Object} query The `query` argument passed to {@link Collection#removeAll}. + * @param {Object} opts The `opts` argument passed to {@link Collection#removeAll}. + */beforeRemoveAll:function beforeRemoveAll(){},/** + * Find all records between two boundaries. + * + * Shortcut for `collection.query().between(18, 30, { index: 'age' }).run()` + * + * @example + * // Get all users ages 18 to 30 + * const users = collection.between(18, 30, { index: 'age' }) + * + * @example + * // Same as above + * const users = collection.between([18], [30], { index: 'age' }) + * + * @method Collection#between + * @since 3.0.0 + * @param {Array} leftKeys Keys defining the left boundary. + * @param {Array} rightKeys Keys defining the right boundary. + * @param {Object} [opts] Configuration options. + * @param {string} [opts.index] Name of the secondary index to use in the + * query. If no index is specified, the main index is used. + * @param {boolean} [opts.leftInclusive=true] Whether to include records + * on the left boundary. + * @param {boolean} [opts.rightInclusive=false] Whether to include records + * on the left boundary. + * @param {boolean} [opts.limit] Limit the result to a certain number. + * @param {boolean} [opts.offset] The number of resulting records to skip. + * @returns {Object[]|Record[]} The result. + */between:function between(leftKeys,rightKeys,opts){return this.query().between(leftKeys,rightKeys,opts).run();},/** + * Create a new secondary index on the contents of the collection. + * + * @example + * // Index users by age + * collection.createIndex('age') + * + * @example + * // Index users by status and role + * collection.createIndex('statusAndRole', ['status', 'role']) + * + * @method Collection#createIndex + * @since 3.0.0 + * @param {string} name The name of the new secondary index. + * @param {string[]} [fieldList] Array of field names to use as the key or + * compound key of the new secondary index. If no fieldList is provided, then + * the name will also be the field that is used to index the collection. + */createIndex:function createIndex(name,fieldList,opts){var _this2=this;if(utils.isString(name)&&fieldList===undefined){fieldList=[name];}opts||(opts={});opts.hashCode||(opts.hashCode=function(obj){return _this2.recordId(obj);});var index=this.indexes[name]=new Index(fieldList,opts);this.index.visitAll(index.insertRecord,index);},/** + * Find the record or records that match the provided query or pass the + * provided filter function. + * + * Shortcut for `collection.query().filter(queryOrFn[, thisArg]).run()` + * + * @example Collection#filter + * // Normally you would do: import {Collection} from 'js-data' + * const JSData = require('js-data@3.0.0-rc.4') + * const {Collection} = JSData + * console.log('Using JSData v' + JSData.version.full) + * + * const collection = new Collection([ + * { id: 1, status: 'draft', created_at_timestamp: new Date().getTime() } + * ]) + * + * // Get the draft posts created less than three months ago + * let posts = collection.filter({ + * where: { + * status: { + * '==': 'draft' + * }, + * created_at_timestamp: { + * '>=': (new Date().getTime() - (1000 \* 60 \* 60 \* 24 \* 30 \* 3)) // 3 months ago + * } + * } + * }) + * console.log(posts) + * + * // Use a custom filter function + * posts = collection.filter(function (post) { + * return post.id % 2 === 0 + * }) + * + * @method Collection#filter + * @param {(Object|Function)} [queryOrFn={}] Selection query or filter + * function. + * @param {Object} [thisArg] Context to which to bind `queryOrFn` if + * `queryOrFn` is a function. + * @returns {Array} The result. + * @see query + * @since 3.0.0 + */filter:function filter(query,thisArg){return this.query().filter(query,thisArg).run();},/** + * Iterate over all records. + * + * @example + * collection.forEach(function (record) { + * // do something + * }) + * + * @method Collection#forEach + * @since 3.0.0 + * @param {Function} forEachFn Iteration function. + * @param {*} [thisArg] Context to which to bind `forEachFn`. + * @returns {Array} The result. + */forEach:function forEach(cb,thisArg){this.index.visitAll(cb,thisArg);},/** + * Get the record with the given id. + * + * @method Collection#get + * @since 3.0.0 + * @param {(string|number)} id The primary key of the record to get. + * @returns {(Object|Record)} The record with the given id. + */get:function get(id){var instances=this.query().get(id).run();return instances.length?instances[0]:undefined;},/** + * Find the record or records that match the provided keyLists. + * + * Shortcut for `collection.query().getAll(keyList1, keyList2, ...).run()` + * + * @example + * // Get the posts where "status" is "draft" or "inReview" + * const posts = collection.getAll('draft', 'inReview', { index: 'status' }) + * + * @example + * // Same as above + * const posts = collection.getAll(['draft'], ['inReview'], { index: 'status' }) + * + * @method Collection#getAll + * @since 3.0.0 + * @param {...Array} [keyList] Provide one or more keyLists, and all + * records matching each keyList will be retrieved. If no keyLists are + * provided, all records will be returned. + * @param {Object} [opts] Configuration options. + * @param {string} [opts.index] Name of the secondary index to use in the + * query. If no index is specified, the main index is used. + * @returns {Array} The result. + */getAll:function getAll(){var _query;return(_query=this.query()).getAll.apply(_query,arguments).run();},/** + * Return the index with the given name. If no name is provided, return the + * main index. Throws an error if the specified index does not exist. + * + * @method Collection#getIndex + * @since 3.0.0 + * @param {string} [name] The name of the index to retrieve. + */getIndex:function getIndex(name){var index=name?this.indexes[name]:this.index;if(!index){throw utils.err(DOMAIN$1+'#getIndex',name)(404,'index');}return index;},/** + * Limit the result. + * + * Shortcut for `collection.query().limit(maximumNumber).run()` + * + * @example + * const posts = collection.limit(10) + * + * @method Collection#limit + * @since 3.0.0 + * @param {number} num The maximum number of records to keep in the result. + * @returns {Array} The result. + */limit:function limit(num){return this.query().limit(num).run();},/** + * Apply a mapping function to all records. + * + * @example + * const names = collection.map(function (user) { + * return user.name + * }) + * + * @method Collection#map + * @since 3.0.0 + * @param {Function} mapFn Mapping function. + * @param {*} [thisArg] Context to which to bind `mapFn`. + * @returns {Array} The result of the mapping. + */map:function map(cb,thisArg){var data=[];this.index.visitAll(function(value){data.push(cb.call(thisArg,value));});return data;},/** + * Return the result of calling the specified function on each record in this + * collection's main index. + * + * @method Collection#mapCall + * @since 3.0.0 + * @param {string} funcName Name of function to call + * @parama {...*} [args] Remaining arguments to be passed to the function. + * @returns {Array} The result. + */mapCall:function mapCall(funcName){for(var _len=arguments.length,args=Array(_len>1?_len-1:0),_key=1;_key<_len;_key++){args[_key-1]=arguments[_key];}var data=[];this.index.visitAll(function(record){data.push(record[funcName].apply(record,args));});return data;},/** + * Return all "unsaved" (not uniquely identifiable) records in this colleciton. + * + * @method Collection#prune + * @param {Object} [opts] Configuration options, passed to {@link Collection#removeAll}. + * @since 3.0.0 + * @returns {Array} The removed records, if any. + */prune:function prune(opts){return this.removeAll(this.unsaved(),opts);},/** + * Create a new query to be executed against the contents of the collection. + * The result will be all or a subset of the contents of the collection. + * + * @example + * // Grab page 2 of users between ages 18 and 30 + * collection.query() + * .between(18, 30, { index: 'age' }) // between ages 18 and 30 + * .skip(10) // second page + * .limit(10) // page size + * .run() + * + * @method Collection#query + * @since 3.0.0 + * @returns {Query} New query object. + */query:function query(){var Ctor=this.queryClass;return new Ctor(this);},/** + * Return the primary key of the given, or if no record is provided, return the + * name of the field that holds the primary key of records in this Collection. + * + * @method Collection#recordId + * @since 3.0.0 + * @param {(Object|Record)} [record] The record whose primary key is to be + * returned. + * @returns {(string|number)} Primary key or name of field that holds primary + * key. + */recordId:function recordId(record){if(record){return utils.get(record,this.recordId());}return this.mapper?this.mapper.idAttribute:this.idAttribute;},/** + * Reduce the data in the collection to a single value and return the result. + * + * @example + * const totalVotes = collection.reduce(function (prev, record) { + * return prev + record.upVotes + record.downVotes + * }, 0) + * + * @method Collection#reduce + * @since 3.0.0 + * @param {Function} cb Reduction callback. + * @param {*} initialValue Initial value of the reduction. + * @returns {*} The result. + */reduce:function reduce(cb,initialValue){var data=this.getAll();return data.reduce(cb,initialValue);},/** + * Remove the record with the given id from this Collection. + * + * @method Collection#remove + * @since 3.0.0 + * @param {(string|number|object|Record)} idOrRecord The primary key of the + * record to be removed, or a reference to the record that is to be removed. + * @param {Object} [opts] Configuration options. + * @returns {Object|Record} The removed record, if any. + */remove:function remove(idOrRecord,opts){// Default values for arguments +opts||(opts={});this.beforeRemove(idOrRecord,opts);var record=utils.isSorN(idOrRecord)?this.get(idOrRecord):idOrRecord;// The record is in the collection, remove it +if(utils.isObject(record)){record=this.index.removeRecord(record);if(record){utils.forOwn(this.indexes,function(index,name){index.removeRecord(record);});if(utils.isFunction(record.off)){record.off('all',this._onRecordEvent,this);if(!opts.silent){this.emit('remove',record);}}}}return this.afterRemove(idOrRecord,opts,record)||record;},/** + * Remove from this collection the given records or the records selected by + * the given "query". + * + * @method Collection#removeAll + * @since 3.0.0 + * @param {Object|Object[]|Record[]} [queryOrRecords={}] Records to be removed or selection query. See {@link query}. + * @param {Object} [queryOrRecords.where] See {@link query.where}. + * @param {number} [queryOrRecords.offset] See {@link query.offset}. + * @param {number} [queryOrRecords.limit] See {@link query.limit}. + * @param {string|Array[]} [queryOrRecords.orderBy] See {@link query.orderBy}. + * @param {Object} [opts] Configuration options. + * @returns {(Object[]|Record[])} The removed records, if any. + */removeAll:function removeAll(queryOrRecords,opts){var _this3=this;// Default values for arguments +opts||(opts={});this.beforeRemoveAll(queryOrRecords,opts);var records=utils.isArray(queryOrRecords)?queryOrRecords.slice():this.filter(queryOrRecords);// Remove each selected record from the collection +var optsCopy=utils.plainCopy(opts);optsCopy.silent=true;records=records.map(function(record){return _this3.remove(record,optsCopy);}).filter(function(record){return record;});if(!opts.silent){this.emit('remove',records);}return this.afterRemoveAll(queryOrRecords,opts,records)||records;},/** + * Skip a number of results. + * + * Shortcut for `collection.query().skip(numberToSkip).run()` + * + * @example + * const posts = collection.skip(10) + * + * @method Collection#skip + * @since 3.0.0 + * @param {number} num The number of records to skip. + * @returns {Array} The result. + */skip:function skip(num){return this.query().skip(num).run();},/** + * Return the plain JSON representation of all items in this collection. + * Assumes records in this collection have a toJSON method. + * + * @method Collection#toJSON + * @since 3.0.0 + * @param {Object} [opts] Configuration options. + * @param {string[]} [opts.with] Array of relation names or relation fields + * to include in the representation. + * @returns {Array} The records. + */toJSON:function toJSON(opts){return this.mapCall('toJSON',opts);},/** + * Return all "unsaved" (not uniquely identifiable) records in this colleciton. + * + * @method Collection#unsaved + * @since 3.0.0 + * @returns {Array} The unsaved records, if any. + */unsaved:function unsaved(opts){return this.index.get();},/** + * Update a record's position in a single index of this collection. See + * {@link Collection#updateIndexes} to update a record's position in all + * indexes at once. + * + * @method Collection#updateIndex + * @since 3.0.0 + * @param {Object} record The record to update. + * @param {Object} [opts] Configuration options. + * @param {string} [opts.index] The index in which to update the record's + * position. If you don't specify an index then the record will be updated + * in the main index. + */updateIndex:function updateIndex(record,opts){opts||(opts={});this.getIndex(opts.index).updateRecord(record);},/** + * Updates all indexes in this collection for the provided record. Has no + * effect if the record is not in the collection. + * + * @method Collection#updateIndexes + * @since 3.0.0 + * @param {Object} record TODO + */updateIndexes:function updateIndexes(record){this.index.updateRecord(record);utils.forOwn(this.indexes,function(index,name){index.updateRecord(record);});}});/** + * Fired when a record changes. Only works for records that have tracked changes. + * See {@link Collection~changeListener} on how to listen for this event. + * + * @event Collection#change + * @see Collection~changeListener + *//** + * Callback signature for the {@link Collection#event:change} event. + * + * @example + * function onChange (record, changes) { + * // do something + * } + * collection.on('change', onChange) + * + * @callback Collection~changeListener + * @param {Record} The Record that changed. + * @param {Object} The changes. + * @see Collection#event:change + * @since 3.0.0 + *//** + * Fired when one or more records are added to the Collection. See + * {@link Collection~addListener} on how to listen for this event. + * + * @event Collection#add + * @see Collection~addListener + * @see Collection#event:add + * @see Collection#add + *//** + * Callback signature for the {@link Collection#event:add} event. + * + * @example + * function onAdd (recordOrRecords) { + * // do something + * } + * collection.on('add', onAdd) + * + * @callback Collection~addListener + * @param {Record|Record[]} The Record or Records that were added. + * @see Collection#event:add + * @see Collection#add + * @since 3.0.0 + *//** + * Fired when one or more records are removed from the Collection. See + * {@link Collection~removeListener} for how to listen for this event. + * + * @event Collection#remove + * @see Collection~removeListener + * @see Collection#event:remove + * @see Collection#remove + * @see Collection#removeAll + *//** + * Callback signature for the {@link Collection#event:remove} event. + * + * @example + * function onRemove (recordsOrRecords) { + * // do something + * } + * collection.on('remove', onRemove) + * + * @callback Collection~removeListener + * @param {Record|Record[]} Record or Records that were removed. + * @see Collection#event:remove + * @see Collection#remove + * @see Collection#removeAll + * @since 3.0.0 + *//** + * Create a subclass of this Collection: + * @example Collection.extend + * // Normally you would do: import {Collection} from 'js-data' + * const JSData = require('js-data@3.0.0-rc.4') + * const {Collection} = JSData + * console.log('Using JSData v' + JSData.version.full) + * + * // Extend the class using ES2015 class syntax. + * class CustomCollectionClass extends Collection { + * foo () { return 'bar' } + * static beep () { return 'boop' } + * } + * const customCollection = new CustomCollectionClass() + * console.log(customCollection.foo()) + * console.log(CustomCollectionClass.beep()) + * + * // Extend the class using alternate method. + * const OtherCollectionClass = Collection.extend({ + * foo () { return 'bar' } + * }, { + * beep () { return 'boop' } + * }) + * const otherCollection = new OtherCollectionClass() + * console.log(otherCollection.foo()) + * console.log(OtherCollectionClass.beep()) + * + * // Extend the class, providing a custom constructor. + * function AnotherCollectionClass () { + * Collection.call(this) + * this.created_at = new Date().getTime() + * } + * Collection.extend({ + * constructor: AnotherCollectionClass, + * foo () { return 'bar' } + * }, { + * beep () { return 'boop' } + * }) + * const anotherCollection = new AnotherCollectionClass() + * console.log(anotherCollection.created_at) + * console.log(anotherCollection.foo()) + * console.log(AnotherCollectionClass.beep()) + * + * @method Collection.extend + * @param {Object} [props={}] Properties to add to the prototype of the + * subclass. + * @param {Object} [props.constructor] Provide a custom constructor function + * to be used as the subclass itself. + * @param {Object} [classProps={}] Static properties to add to the subclass. + * @returns {Constructor} Subclass of this Collection class. + * @since 3.0.0 + */// TODO: remove this when the rest of the project is cleaned +var belongsToType='belongsTo';var hasManyType='hasMany';var hasOneType='hasOne';var DOMAIN$6='Relation';function Relation(relatedMapper){var options=arguments.length<=1||arguments[1]===undefined?{}:arguments[1];utils.classCallCheck(this,Relation);options.type=this.constructor.TYPE_NAME;this.validateOptions(relatedMapper,options);if((typeof relatedMapper==='undefined'?'undefined':_typeof(relatedMapper))==='object'){Object.defineProperty(this,'relatedMapper',{value:relatedMapper});}Object.defineProperty(this,'inverse',{writable:true});utils.fillIn(this,options);}Relation.extend=utils.extend;utils.addHiddenPropsToTarget(Relation.prototype,{get canAutoAddLinks(){return this.add===undefined||!!this.add;},get relatedCollection(){return this.mapper.datastore.getCollection(this.relation);},validateOptions:function validateOptions(related,opts){var DOMAIN_ERR='new '+DOMAIN$6;var localField=opts.localField;if(!localField){throw utils.err(DOMAIN_ERR,'opts.localField')(400,'string',localField);}var foreignKey=opts.foreignKey=opts.foreignKey||opts.localKey;if(!foreignKey&&(opts.type===belongsToType||opts.type===hasOneType)){throw utils.err(DOMAIN_ERR,'opts.foreignKey')(400,'string',foreignKey);}if(utils.isString(related)){opts.relation=related;if(!utils.isFunction(opts.getRelation)){throw utils.err(DOMAIN_ERR,'opts.getRelation')(400,'function',opts.getRelation);}}else if(related){opts.relation=related.name;}else{throw utils.err(DOMAIN_ERR,'related')(400,'Mapper or string',related);}},assignTo:function assignTo(mapper){this.name=mapper.name;Object.defineProperty(this,'mapper',{value:mapper});mapper.relationList||Object.defineProperty(mapper,'relationList',{value:[]});mapper.relationFields||Object.defineProperty(mapper,'relationFields',{value:[]});mapper.relationList.push(this);mapper.relationFields.push(this.localField);},canFindLinkFor:function canFindLinkFor(){return!!(this.foreignKey||this.localKey);},getRelation:function getRelation(){return this.relatedMapper;},getForeignKey:function getForeignKey(record){return utils.get(record,this.mapper.idAttribute);},setForeignKey:function setForeignKey(record,relatedRecord){if(!record||!relatedRecord){return;}this._setForeignKey(record,relatedRecord);},_setForeignKey:function _setForeignKey(record,relatedRecords){var _this=this;var idAttribute=this.mapper.idAttribute;if(!utils.isArray(relatedRecords)){relatedRecords=[relatedRecords];}relatedRecords.forEach(function(relatedRecord){utils.set(relatedRecord,_this.foreignKey,utils.get(record,idAttribute));});},getLocalField:function getLocalField(record){return utils.get(record,this.localField);},setLocalField:function setLocalField(record,relatedData){return utils.set(record,this.localField,relatedData);},getInverse:function getInverse(mapper){if(!this.inverse){this.findInverseRelation(mapper);}return this.inverse;},findInverseRelation:function findInverseRelation(mapper){var _this2=this;this.getRelation().relationList.forEach(function(def){if(def.getRelation()===mapper&&_this2.isInversedTo(def)){_this2.inverse=def;return true;}});},isInversedTo:function isInversedTo(def){return!def.foreignKey||def.foreignKey===this.foreignKey;},addLinkedRecords:function addLinkedRecords(records){var _this3=this;var datastore=this.mapper.datastore;records.forEach(function(record){var relatedData=_this3.getLocalField(record);if(utils.isFunction(_this3.add)){relatedData=_this3.add(datastore,_this3,record);}else if(relatedData){relatedData=_this3.linkRecord(record,relatedData);}var isEmptyLinks=!relatedData||utils.isArray(relatedData)&&!relatedData.length;if(isEmptyLinks&&_this3.canFindLinkFor(record)){relatedData=_this3.findExistingLinksFor(record);}if(relatedData){_this3.setLocalField(record,relatedData);}});},removeLinkedRecords:function removeLinkedRecords(relatedMapper,records){var localField=this.localField;records.forEach(function(record){utils.set(record,localField,undefined);});},linkRecord:function linkRecord(record,relatedRecord){var relatedId=utils.get(relatedRecord,this.mapper.idAttribute);if(relatedId===undefined){var unsaved=this.relatedCollection.unsaved();if(unsaved.indexOf(relatedRecord)===-1){if(this.canAutoAddLinks){relatedRecord=this.relatedCollection.add(relatedRecord);}}}else{if(relatedRecord!==this.relatedCollection.get(relatedId)){this.setForeignKey(record,relatedRecord);if(this.canAutoAddLinks){relatedRecord=this.relatedCollection.add(relatedRecord);}}}return relatedRecord;},// e.g. user hasMany post via "foreignKey", so find all posts of user +findExistingLinksByForeignKey:function findExistingLinksByForeignKey(id){if(id===undefined||id===null){return;}return this.relatedCollection.filter(defineProperty({},this.foreignKey,id));}});var BelongsToRelation=Relation.extend({getForeignKey:function getForeignKey(record){return utils.get(record,this.foreignKey);},_setForeignKey:function _setForeignKey(record,relatedRecord){utils.set(record,this.foreignKey,utils.get(relatedRecord,this.getRelation().idAttribute));},findExistingLinksFor:function findExistingLinksFor(record){// console.log('\tBelongsTo#findExistingLinksFor', record) +if(!record){return;}var relatedId=utils.get(record,this.foreignKey);if(relatedId!==undefined&&relatedId!==null){return this.relatedCollection.get(relatedId);}}},{TYPE_NAME:'belongsTo'});var HasManyRelation=Relation.extend({validateOptions:function validateOptions(related,opts){Relation.prototype.validateOptions.call(this,related,opts);var localKeys=opts.localKeys;var foreignKeys=opts.foreignKeys;var foreignKey=opts.foreignKey;if(!foreignKey&&!localKeys&&!foreignKeys){throw utils.err('new Relation','opts.')(400,'string',foreignKey);}},canFindLinkFor:function canFindLinkFor(record){var hasForeignKeys=this.foreignKey||this.foreignKeys;return!!(hasForeignKeys||this.localKeys&&utils.get(record,this.localKeys));},linkRecord:function linkRecord(record,relatedRecords){var _this=this;var relatedCollection=this.relatedCollection;var canAutoAddLinks=this.canAutoAddLinks;var foreignKey=this.foreignKey;var unsaved=this.relatedCollection.unsaved();return relatedRecords.map(function(relatedRecord){var relatedId=relatedCollection.recordId(relatedRecord);if(relatedId===undefined&&unsaved.indexOf(relatedRecord)===-1||relatedRecord!==relatedCollection.get(relatedId)){if(foreignKey){// TODO: slow, could be optimized? But user loses hook +_this.setForeignKey(record,relatedRecord);}if(canAutoAddLinks){relatedRecord=relatedCollection.add(relatedRecord);}}return relatedRecord;});},findExistingLinksFor:function findExistingLinksFor(record){var id=utils.get(record,this.mapper.idAttribute);var ids=this.localKeys?utils.get(record,this.localKeys):null;var records=void 0;if(id!==undefined&&this.foreignKey){records=this.findExistingLinksByForeignKey(id);}else if(this.localKeys&&ids){records=this.findExistingLinksByLocalKeys(ids);}else if(id!==undefined&&this.foreignKeys){records=this.findExistingLinksByForeignKeys(id);}if(records&&records.length){return records;}},// e.g. user hasMany group via "foreignKeys", so find all users of a group +findExistingLinksByLocalKeys:function findExistingLinksByLocalKeys(ids){return this.relatedCollection.filter({where:defineProperty({},this.mapper.idAttribute,{'in':ids})});},// e.g. group hasMany user via "localKeys", so find all groups that own a user +findExistingLinksByForeignKeys:function findExistingLinksByForeignKeys(id){return this.relatedCollection.filter({where:defineProperty({},this.foreignKeys,{'contains':id})});}},{TYPE_NAME:'hasMany'});var HasOneRelation=Relation.extend({findExistingLinksFor:function findExistingLinksFor(relatedMapper,record){var recordId=utils.get(record,relatedMapper.idAttribute);var records=this.findExistingLinksByForeignKey(recordId);if(records&&records.length){return records[0];}}},{TYPE_NAME:'hasOne'});[BelongsToRelation,HasManyRelation,HasOneRelation].forEach(function(RelationType){Relation[RelationType.TYPE_NAME]=function(related,options){return new RelationType(related,options);};});/** + * BelongsTo relation decorator. You probably won't use this directly. + * + * @name module:js-data.belongsTo + * @method + * @param {Mapper} related The relation the target belongs to. + * @param {Object} opts Configuration options. + * @param {string} opts.foreignKey The field that holds the primary key of the + * related record. + * @param {string} opts.localField The field that holds a reference to the + * related record object. + * @returns {Function} Invocation function, which accepts the target as the only + * parameter. + */var belongsTo=function belongsTo$1(related,opts){return function(mapper){Relation.belongsTo(related,opts).assignTo(mapper);};};/** + * HasMany relation decorator. You probably won't use this directly. + * + * @name module:js-data.hasMany + * @method + * @param {Mapper} related The relation of which the target has many. + * @param {Object} opts Configuration options. + * @param {string} [opts.foreignKey] The field that holds the primary key of the + * related record. + * @param {string} opts.localField The field that holds a reference to the + * related record object. + * @returns {Function} Invocation function, which accepts the target as the only + * parameter. + */var hasMany=function hasMany$1(related,opts){return function(mapper){Relation.hasMany(related,opts).assignTo(mapper);};};/** + * HasOne relation decorator. You probably won't use this directly. + * + * @name module:js-data.hasOne + * @method + * @param {Mapper} related The relation of which the target has one. + * @param {Object} opts Configuration options. + * @param {string} [opts.foreignKey] The field that holds the primary key of the + * related record. + * @param {string} opts.localField The field that holds a reference to the + * related record object. + * @returns {Function} Invocation function, which accepts the target as the only + * parameter. + */var hasOne=function hasOne$1(related,opts){return function(mapper){Relation.hasOne(related,opts).assignTo(mapper);};};var DOMAIN$5='Record';var superMethod=function superMethod(mapper,name){var store=mapper.datastore;if(store&&store[name]){return function(){for(var _len=arguments.length,args=Array(_len),_key=0;_key<_len;_key++){args[_key]=arguments[_key];}return store[name].apply(store,[mapper.name].concat(args));};}return mapper[name].bind(mapper);};// Cache these strings +var creatingPath='creating';var noValidatePath='noValidate';var keepChangeHistoryPath='keepChangeHistory';var previousPath='previous';/** + * js-data's Record class. An instance of `Record` corresponds to an in-memory + * representation of a single row or document in a database, Firebase, + * localstorage, etc. Basically, a `Record` instance represents whatever kind of + * entity in your persistence layer that has a primary key. + * + * ```javascript + * import {Record} from 'js-data' + * ``` + * + * @example Record#constructor + * // Normally you would do: import {Record} from 'js-data' + * const JSData = require('js-data@3.0.0-rc.4') + * const {Record} = JSData + * console.log('Using JSData v' + JSData.version.full) + * + * // Instantiate a plain record + * let record = new Record() + * console.log('record: ' + JSON.stringify(record)) + * + * // You can supply properties on instantiation + * record = new Record({ name: 'John' }) + * console.log('record: ' + JSON.stringify(record)) + * + * @example Record#constructor2 + * // Normally you would do: import {Mapper} from 'js-data' + * const JSData = require('js-data@3.0.0-rc.4') + * const {Mapper} = JSData + * console.log('Using JSData v' + JSData.version.full) + * + * // Instantiate a record that's associated with a Mapper: + * const UserMapper = new Mapper({ name: 'user' }) + * const User = UserMapper.recordClass + * const user = UserMapper.createRecord({ name: 'John' }) + * const user2 = new User({ name: 'Sally' }) + * console.log('user: ' + JSON.stringify(user)) + * console.log('user2: ' + JSON.stringify(user2)) + * + * @example Record#constructor3 + * // Normally you would do: import {Container} from 'js-data' + * const JSData = require('js-data@3.0.0-rc.4') + * const {Container} = JSData + * console.log('Using JSData v' + JSData.version.full) + * + * const store = new Container() + * store.defineMapper('user') + * + * // Instantiate a record that's associated with a store's Mapper + * const user = store.createRecord('user', { name: 'John' }) + * console.log('user: ' + JSON.stringify(user)) + * + * @example Record#constructor4 + * // Normally you would do: import {Container} from 'js-data' + * const JSData = require('js-data@3.0.0-rc.4') + * const {Container} = JSData + * console.log('Using JSData v' + JSData.version.full) + * + * const store = new Container() + * store.defineMapper('user', { + * schema: { + * properties: { + * name: { type: 'string' } + * } + * } + * }) + * + * // Validate on instantiation + * const user = store.createRecord('user', { name: 1234 }) + * console.log('user: ' + JSON.stringify(user)) + * + * @example Record#constructor5 + * // Normally you would do: import {Container} from 'js-data' + * const JSData = require('js-data@3.0.0-rc.4') + * const {Container} = JSData + * console.log('Using JSData v' + JSData.version.full) + * + * const store = new Container() + * store.defineMapper('user', { + * schema: { + * properties: { + * name: { type: 'string' } + * } + * } + * }) + * + * // Skip validation on instantiation + * const user = store.createRecord('user', { name: 1234 }, { noValidate: true }) + * console.log('user: ' + JSON.stringify(user)) + * console.log('user.isValid(): ' + user.isValid()) + * + * @class Record + * @extends Component + * @param {Object} [props] The initial properties of the new Record instance. + * @param {Object} [opts] Configuration options. + * @param {boolean} [opts.noValidate=false] Whether to skip validation on the + * initial properties. + * @since 3.0.0 + */function Record(props,opts){utils.classCallCheck(this,Record);Settable.call(this);props||(props={});opts||(opts={});var _set=this._set;_set(creatingPath,true);if(opts.noValidate){_set(noValidatePath,opts.noValidate===undefined?true:opts.noValidate);}_set(keepChangeHistoryPath,opts.keepChangeHistory===undefined?mapper?mapper.keepChangeHistory:true:opts.keepChangeHistory);// Set the idAttribute value first, if it exists. +var mapper=this.constructor.mapper;var id=mapper?utils.get(props,mapper.idAttribute):undefined;if(id!==undefined){utils.set(this,mapper.idAttribute,id);}utils.fillIn(this,props);_set(creatingPath,false);var validateOnSet=opts.validateOnSet===undefined?mapper?mapper.validateOnSet:true:opts.validateOnSet;_set(noValidatePath,!validateOnSet);_set(previousPath,mapper?mapper.toJSON(props):utils.plainCopy(props));}var Record$1=Component$1.extend({constructor:Record,/** + * Returns the {@link Mapper} paired with this record's class, if any. + * + * @method Record#_mapper + * @returns {Mapper} The {@link Mapper} paired with this record's class, if any. + * @since 3.0.0 + */_mapper:function _mapper(){var mapper=this.constructor.mapper;if(!mapper){throw utils.err(DOMAIN$5+'#_mapper','')(404,'mapper');}return mapper;},/** + * Lifecycle hook. + * + * @method Record#afterLoadRelations + * @param {string[]} relations The `relations` argument passed to {@link Record#loadRelations}. + * @param {Object} opts The `opts` argument passed to {@link Record#loadRelations}. + * @since 3.0.0 + */afterLoadRelations:function afterLoadRelations(){},/** + * Lifecycle hook. + * + * @method Record#beforeLoadRelations + * @param {string[]} relations The `relations` argument passed to {@link Record#loadRelations}. + * @param {Object} opts The `opts` argument passed to {@link Record#loadRelations}. + * @since 3.0.0 + */beforeLoadRelations:function beforeLoadRelations(){},/** + * Return the change history of this record since it was instantiated or + * {@link Record#commit} was called. + * + * @method Record#changeHistory + * @since 3.0.0 + */changeHistory:function changeHistory(){return(this._get('history')||[]).slice();},/** + * Return changes to this record since it was instantiated or + * {@link Record#commit} was called. + * + * @example Record#changes + * // Normally you would do: import {Container} from 'js-data' + * const JSData = require('js-data@3.0.0-rc.4') + * const {Container} = JSData + * console.log('Using JSData v' + JSData.version.full) + * + * const store = new Container() + * store.defineMapper('user') + * const user = store.createRecord('user') + * console.log('user changes: ' + JSON.stringify(user.changes())) + * user.name = 'John' + * console.log('user changes: ' + JSON.stringify(user.changes())) + * + * @method Record#changes + * @param [opts] Configuration options. + * @param {Function} [opts.equalsFn={@link utils.deepEqual}] Equality function. + * @param {Array} [opts.ignore=[]] Array of strings or RegExp of fields to ignore. + * @returns {Object} Object describing the changes to this record since it was + * instantiated or its {@link Record#commit} method was last called. + * @since 3.0.0 + */changes:function changes(opts){opts||(opts={});return utils.diffObjects(typeof this.toJSON==='function'?this.toJSON(opts):this,this._get('previous'),opts);},/** + * Make the record's current in-memory state it's only state, with any + * previous property values being set to current values. + * + * @example Record#commit + * // Normally you would do: import {Container} from 'js-data' + * const JSData = require('js-data@3.0.0-rc.4') + * const {Container} = JSData + * console.log('Using JSData v' + JSData.version.full) + * + * const store = new Container() + * store.defineMapper('user') + * const user = store.createRecord('user') + * console.log('user hasChanges: ' + user.hasChanges()) + * user.name = 'John' + * console.log('user hasChanges: ' + user.hasChanges()) + * user.commit() + * console.log('user hasChanges: ' + user.hasChanges()) + * + * @method Record#commit + * @param {Object} [opts] Configuration options. Passed to {@link Record#toJSON}. + * @since 3.0.0 + */commit:function commit(opts){this._set('changed');// unset +this._set('history',[]);// clear history +this._set('previous',this.toJSON(opts));},/** + * Call {@link Mapper#destroy} using this record's primary key. + * + * @example + * import {Container} from 'js-data' + * import {RethinkDBAdapter} from 'js-data-rethinkdb' + * + * const store = new Container() + * store.registerAdapter('rethink', new RethinkDBAdapter(), { default: true }) + * store.defineMapper('user') + * store.find('user', 1234).then((user) => { + * console.log(user.id) // 1234 + * + * // Destroy this user from the database + * return user.destroy() + * }) + * + * @method Record#destroy + * @param {Object} [opts] Configuration options passed to {@link Mapper#destroy}. + * @returns {Promise} The result of calling {@link Mapper#destroy} with the + * primary key of this record. + * @since 3.0.0 + */destroy:function destroy(opts){opts||(opts={});var mapper=this._mapper();return superMethod(mapper,'destroy')(utils.get(this,mapper.idAttribute),opts);},/** + * Return the value at the given path for this instance. + * + * @example Record#get + * // Normally you would do: import {Container} from 'js-data' + * const JSData = require('js-data@3.0.0-rc.4') + * const {Container} = JSData + * console.log('Using JSData v' + JSData.version.full) + * const store = new Container() + * store.defineMapper('user') + * + * const user = store.createRecord('user', { name: 'Bob' }) + * console.log('user.get("name"): ' + user.get('name')) + * + * @method Record#get + * @param {string} key Path of value to retrieve. + * @returns {*} Value at path. + * @since 3.0.0 + */'get':function get(key){return utils.get(this,key);},/** + * Return whether this record has changed since it was instantiated or + * {@link Record#commit} was called. + * + * @example Record#hasChanges + * // Normally you would do: import {Container} from 'js-data' + * const JSData = require('js-data@3.0.0-rc.4') + * const {Container} = JSData + * console.log('Using JSData v' + JSData.version.full) + * const store = new Container() + * store.defineMapper('user') + * const user = store.createRecord('user') + * console.log('user hasChanges: ' + user.hasChanges()) + * user.name = 'John' + * console.log('user hasChanges: ' + user.hasChanges()) + * user.commit() + * console.log('user hasChanges: ' + user.hasChanges()) + * + * @method Record#hasChanges + * @param [opts] Configuration options. + * @param {Function} [opts.equalsFn={@link utils.deepEqual}] Equality function. + * @param {Array} [opts.ignore=[]] Array of strings or RegExp of fields to ignore. + * @returns {boolean} Return whether the record has changed since it was + * instantiated or since its {@link Record#commit} method was called. + * @since 3.0.0 + */hasChanges:function hasChanges(opts){var quickHasChanges=!!(this._get('changed')||[]).length;return quickHasChanges||utils.areDifferent(typeof this.toJSON==='function'?this.toJSON(opts):this,this._get('previous'),opts);},/** + * Return whether the record is unsaved. Records that have primary keys are + * considered "saved". Records without primary keys are considered "unsaved". + * + * @example Record#isNew + * // Normally you would do: import {Container} from 'js-data' + * const JSData = require('js-data@3.0.0-rc.4') + * const {Container} = JSData + * console.log('Using JSData v' + JSData.version.full) + * const store = new Container() + * store.defineMapper('user') + * const user = store.createRecord('user', { + * id: 1234 + * }) + * const user2 = store.createRecord('user') + * console.log('user isNew: ' + user.isNew()) // false + * console.log('user2 isNew: ' + user2.isNew()) // true + * + * @method Record#isNew + * @returns {boolean} Whether the record is unsaved. + * @since 3.0.0 + */isNew:function isNew(opts){return utils.get(this,this._mapper().idAttribute)===undefined;},/** + * Return whether the record in its current state passes validation. + * + * @example Record#isValid + * // Normally you would do: import {Container} from 'js-data' + * const JSData = require('js-data@3.0.0-rc.4') + * const {Container} = JSData + * console.log('Using JSData v' + JSData.version.full) + * const store = new Container() + * store.defineMapper('user', { + * schema: { + * properties: { + * name: { type: 'string' } + * } + * } + * }) + * const user = store.createRecord('user', { + * name: 1234 + * }, { + * noValidate: true // this allows us to put the record into an invalid state + * }) + * console.log('user isValid: ' + user.isValid()) + * user.name = 'John' + * console.log('user isValid: ' + user.isValid()) + * + * @method Record#isValid + * @param {Object} [opts] Configuration options. Passed to {@link Mapper#validate}. + * @returns {boolean} Whether the record in its current state passes + * validation. + * @since 3.0.0 + */isValid:function isValid(opts){return!this._mapper().validate(this,opts);},removeInverseRelation:function removeInverseRelation(currentParent,id,inverseDef,idAttribute){var _this=this;if(inverseDef.type===hasOneType){safeSetLink(currentParent,inverseDef.localField,undefined);}else if(inverseDef.type===hasManyType){// e.g. remove comment from otherPost.comments +var children=utils.get(currentParent,inverseDef.localField);if(id===undefined){utils.remove(children,function(child){return child===_this;});}else{utils.remove(children,function(child){return child===_this||id===utils.get(child,idAttribute);});}}},setupInverseRelation:function setupInverseRelation(record,id,inverseDef,idAttribute){var _this2=this;// Update (set) inverse relation +if(inverseDef.type===hasOneType){// e.g. someUser.profile = profile +safeSetLink(record,inverseDef.localField,this);}else if(inverseDef.type===hasManyType){// e.g. add comment to somePost.comments +var children=utils.get(record,inverseDef.localField);if(id===undefined){utils.noDupeAdd(children,this,function(child){return child===_this2;});}else{utils.noDupeAdd(children,this,function(child){return child===_this2||id===utils.get(child,idAttribute);});}}},/** + * Lazy load relations of this record, to be attached to the record once their + * loaded. + * + * @example + * import {Container} from 'js-data' + * import {RethinkDBAdapter} from 'js-data-rethinkdb' + * + * const store = new Container() + * store.registerAdapter('rethink', new RethinkDBAdapter(), { default: true }) + * store.defineMapper('user', { + * relations: { + * hasMany: { + * post: { + * localField: 'posts', + * foreignKey: 'user_id' + * } + * } + * } + * }) + * store.defineMapper('post', { + * relations: { + * belongsTo: { + * user: { + * localField: 'user', + * foreignKey: 'user_id' + * } + * } + * } + * }) + * store.find('user', 1234).then((user) => { + * console.log(user.id) // 1234 + * + * // Load the user's post relations + * return user.loadRelations(['post']) + * }).then((user) => { + * console.log(user.posts) // [{...}, {...}, ...] + * }) + * + * @method Record#loadRelations + * @param {string[]} [relations] List of relations to load. Can use localField + * names or Mapper names to pick relations. + * @param {Object} [opts] Configuration options. + * @returns {Promise} Resolves with the record, with the loaded relations now + * attached. + * @since 3.0.0 + */loadRelations:function loadRelations(relations,opts){var _this3=this;var op=void 0;var mapper=this._mapper();// Default values for arguments +relations||(relations=[]);if(utils.isString(relations)){relations=[relations];}opts||(opts={});opts.with=relations;// Fill in "opts" with the Model's configuration +utils._(opts,mapper);opts.adapter=mapper.getAdapterName(opts);// beforeLoadRelations lifecycle hook +op=opts.op='beforeLoadRelations';return utils.resolve(this[op](relations,opts)).then(function(){// Now delegate to the adapter +op=opts.op='loadRelations';mapper.dbg(op,_this3,relations,opts);var tasks=[];var task=void 0;utils.forEachRelation(mapper,opts,function(def,optsCopy){var relatedMapper=def.getRelation();optsCopy.raw=false;if(utils.isFunction(def.load)){task=def.load(mapper,def,_this3,opts);}else if(def.type==='hasMany'||def.type==='hasOne'){if(def.foreignKey){task=superMethod(relatedMapper,'findAll')(defineProperty({},def.foreignKey,utils.get(_this3,mapper.idAttribute)),optsCopy).then(function(relatedData){if(def.type==='hasOne'){return relatedData.length?relatedData[0]:undefined;}return relatedData;});}else if(def.localKeys){task=superMethod(relatedMapper,'findAll')({where:defineProperty({},relatedMapper.idAttribute,{'in':utils.get(_this3,def.localKeys)})});}else if(def.foreignKeys){task=superMethod(relatedMapper,'findAll')({where:defineProperty({},def.foreignKeys,{'contains':utils.get(_this3,mapper.idAttribute)})},opts);}}else if(def.type==='belongsTo'){var key=utils.get(_this3,def.foreignKey);if(utils.isSorN(key)){task=superMethod(relatedMapper,'find')(key,optsCopy);}}if(task){task=task.then(function(relatedData){def.setLocalField(_this3,relatedData);});tasks.push(task);}});return Promise.all(tasks);}).then(function(){// afterLoadRelations lifecycle hook +op=opts.op='afterLoadRelations';return utils.resolve(_this3[op](relations,opts)).then(function(){return _this3;});});},/** + * Return the properties with which this record was instantiated. + * + * @example Record#previous + * // import {Container} from 'js-data' + * const JSData = require('js-data@3.0.0-rc.4') + * const {Container} = JSData + * console.log('Using JSData v' + JSData.version.full) + * const store = new Container() + * store.defineMapper('user') + * const user = store.createRecord('user', { + * name: 'William' + * }) + * console.log('user previous: ' + JSON.stringify(user.previous())) + * user.name = 'Bob' + * console.log('user previous: ' + JSON.stringify(user.previous())) + * user.commit() + * console.log('user previous: ' + JSON.stringify(user.previous())) + * + * @method Record#previous + * @param {string} [key] If specified, return just the initial value of the + * given key. + * @returns {Object} The initial properties of this record. + * @since 3.0.0 + */previous:function previous(key){if(key){return this._get('previous.'+key);}return this._get('previous');},/** + * Revert changes to this record back to the properties it had when it was + * instantiated. + * + * @example Record#revert + * // import {Container} from 'js-data' + * const JSData = require('js-data@3.0.0-rc.4') + * const {Container} = JSData + * console.log('Using JSData v' + JSData.version.full) + * const store = new Container() + * store.defineMapper('user') + * const user = store.createRecord('user', { + * name: 'William' + * }) + * console.log('user: ' + JSON.stringify(user)) + * user.name = 'Bob' + * console.log('user: ' + JSON.stringify(user)) + * user.revert() + * console.log('user: ' + JSON.stringify(user)) + * + * @method Record#revert + * @param {Object} [opts] Configuration options. + * @param {string[]} [opts.preserve] Array of strings or Regular Expressions + * denoting properties that should not be reverted. + * @since 3.0.0 + */revert:function revert(opts){var _this4=this;var previous=this._get('previous');opts||(opts={});opts.preserve||(opts.preserve=[]);utils.forOwn(this,function(value,key){if(key!==_this4._mapper().idAttribute&&!previous.hasOwnProperty(key)&&_this4.hasOwnProperty(key)&&opts.preserve.indexOf(key)===-1){delete _this4[key];}});utils.forOwn(previous,function(value,key){if(opts.preserve.indexOf(key)===-1){_this4[key]=value;}});this.commit();},/** + * Delegates to {@link Mapper#create} or {@link Mapper#update}. + * + * @example + * import {Container} from 'js-data' + * import {RethinkDBAdapter} from 'js-data-rethinkdb' + * + * const store = new Container() + * store.registerAdapter('rethink', new RethinkDBAdapter(), { default: true }) + * store.defineMapper('session') + * const session = store.createRecord('session', { topic: 'Node.js' }) + * + * // Create a new record in the database + * session.save().then(() => { + * console.log(session.id) // 1234 + * + * session.skill_level = 'beginner' + * + * // Update the record in the database + * return user.save() + * }) + * + * @method Record#save + * @param {Object} [opts] Configuration options. See {@link Mapper#create} and + * {@link Mapper#update}. + * @param {boolean} [opts.changesOnly] Equality function. Default uses `===`. + * @param {Function} [opts.equalsFn] Passed to {@link Record#changes} when + * `opts.changesOnly` is `true`. + * @param {Array} [opts.ignore] Passed to {@link Record#changes} when + * `opts.changesOnly` is `true`. + * @returns {Promise} The result of calling {@link Mapper#create} or + * {@link Mapper#update}. + * @since 3.0.0 + */save:function save(opts){var _this5=this;opts||(opts={});var mapper=this._mapper();var id=utils.get(this,mapper.idAttribute);var props=this;var postProcess=function postProcess(result){var record=opts.raw?result.data:result;if(record){utils.deepMixIn(_this5,record);_this5.commit();}return result;};if(id===undefined){return superMethod(mapper,'create')(props,opts).then(postProcess);}if(opts.changesOnly){var changes=this.changes(opts);props={};utils.fillIn(props,changes.added);utils.fillIn(props,changes.changed);}return superMethod(mapper,'update')(id,props,opts).then(postProcess);},/** + * Set the value for a given key, or the values for the given keys if "key" is + * an object. Triggers change events on those properties that have `track: true` + * in {@link Mapper#schema}. + * + * @example Record#set + * // Normally you would do: import {Container} from 'js-data' + * const JSData = require('js-data@3.0.0-rc.4') + * const {Container} = JSData + * console.log('Using JSData v' + JSData.version.full) + * const store = new Container() + * store.defineMapper('user') + * + * const user = store.createRecord('user') + * console.log('user: ' + JSON.stringify(user)) + * + * user.set('name', 'Bob') + * console.log('user: ' + JSON.stringify(user)) + * + * user.set({ age: 30, role: 'admin' }) + * console.log('user: ' + JSON.stringify(user)) + * + * @fires Record#change + * @method Record#set + * @param {(string|Object)} key Key to set or hash of key-value pairs to set. + * @param {*} [value] Value to set for the given key. + * @param {Object} [opts] Configuration options. + * @param {boolean} [opts.silent=false] Whether to trigger change events. + * @since 3.0.0 + */'set':function set(key,value,opts){if(utils.isObject(key)){opts=value;}opts||(opts={});if(opts.silent){this._set('silent',true);}utils.set(this,key,value);if(!this._get('eventId')){this._set('silent');// unset +}},/** + * Return a plain object representation of this record. If the class from + * which this record was created has a Mapper, then {@link Mapper#toJSON} will + * be called with this record instead. + * + * @example Record#toJSON + * // Normally you would do: import {Container} from 'js-data' + * const JSData = require('js-data@3.0.0-rc.4') + * const {Container} = JSData + * console.log('Using JSData v' + JSData.version.full) + * const store = new Container() + * store.defineMapper('user', { + * schema: { + * properties: { + * name: { type: 'string' } + * } + * } + * }) + * + * const user = store.createRecord('user', { + * name: 'John', + * $$hashKey: '1234' + * }) + * console.log('user: ' + JSON.stringify(user.toJSON())) + * console.log('user: ' + JSON.stringify(user.toJSON({ strict: true }))) + * + * @method Record#toJSON + * @param {Object} [opts] Configuration options. + * @param {boolean} [opts.strict] Whether to exclude properties that are not + * defined in {@link Mapper#schema}. + * @param {string[]} [opts.with] Array of relation names or relation fields + * to include in the representation. Only available as an option if the class + * from which this record was created has a Mapper and this record resides in + * an instance of {@link DataStore}. + * @returns {Object} Plain object representation of this record. + * @since 3.0.0 + */toJSON:function toJSON(opts){var _this6=this;var mapper=this.constructor.mapper;if(mapper){return mapper.toJSON(this,opts);}else{var _ret=function(){var json={};utils.forOwn(_this6,function(prop,key){json[key]=utils.plainCopy(prop);});return{v:json};}();if((typeof _ret==='undefined'?'undefined':_typeof(_ret))==="object")return _ret.v;}},/** + * Unset the value for a given key. Triggers change events on those properties + * that have `track: true` in {@link Mapper#schema}. + * + * @example Record#unset + * // Normally you would do: import {Container} from 'js-data' + * const JSData = require('js-data@3.0.0-rc.4') + * const {Container} = JSData + * console.log('Using JSData v' + JSData.version.full) + * const store = new Container() + * store.defineMapper('user') + * + * const user = store.createRecord('user', { + * name: 'John' + * }) + * console.log('user: ' + JSON.stringify(user)) + * + * user.unset('name') + * console.log('user: ' + JSON.stringify(user)) + * + * @method Record#unset + * @param {string} key Key to unset. + * @param {Object} [opts] Configuration options. + * @param {boolean} [opts.silent=false] Whether to trigger change events. + * @since 3.0.0 + */unset:function unset(key,opts){this.set(key,undefined,opts);},/** + * Validate this record based on its current properties. + * + * @example Record#validate + * // Normally you would do: import {Container} from 'js-data' + * const JSData = require('js-data@3.0.0-rc.4') + * const {Container} = JSData + * console.log('Using JSData v' + JSData.version.full) + * const store = new Container() + * store.defineMapper('user', { + * schema: { + * properties: { + * name: { type: 'string' } + * } + * } + * }) + * const user = store.createRecord('user', { + * name: 1234 + * }, { + * noValidate: true // this allows us to put the record into an invalid state + * }) + * console.log('user validation: ' + JSON.stringify(user.validate())) + * user.name = 'John' + * console.log('user validation: ' + user.validate()) + * + * @method Record#validate + * @param {Object} [opts] Configuration options. Passed to {@link Mapper#validate}. + * @returns {*} Array of errors or `undefined` if no errors. + * @since 3.0.0 + */validate:function validate(opts){return this._mapper().validate(this,opts);}});/** + * Allow records to emit events. + * + * An record's registered listeners are stored in the record's private data. + */utils.eventify(Record.prototype,function(){return this._get('events');},function(value){this._set('events',value);});/** + * Fired when a record changes. Only works for records that have tracked fields. + * See {@link Record~changeListener} on how to listen for this event. + * + * @event Record#change + * @see Record~changeListener + *//** + * Callback signature for the {@link Record#event:change} event. + * + * @example + * function onChange (record, changes) { + * // do something + * } + * record.on('change', onChange) + * + * @callback Record~changeListener + * @param {Record} The Record that changed. + * @param {Object} The changes. + * @see Record#event:change + * @since 3.0.0 + *//** + * Create a subclass of this Record: + * @example Record.extend + * // Normally you would do: import {Record} from 'js-data' + * const JSData = require('js-data@3.0.0-rc.4') + * const {Record} = JSData + * console.log('Using JSData v' + JSData.version.full) + * + * // Extend the class using ES2015 class syntax. + * class CustomRecordClass extends Record { + * foo () { return 'bar' } + * static beep () { return 'boop' } + * } + * const customRecord = new CustomRecordClass() + * console.log(customRecord.foo()) + * console.log(CustomRecordClass.beep()) + * + * // Extend the class using alternate method. + * const OtherRecordClass = Record.extend({ + * foo () { return 'bar' } + * }, { + * beep () { return 'boop' } + * }) + * const otherRecord = new OtherRecordClass() + * console.log(otherRecord.foo()) + * console.log(OtherRecordClass.beep()) + * + * // Extend the class, providing a custom constructor. + * function AnotherRecordClass () { + * Record.call(this) + * this.created_at = new Date().getTime() + * } + * Record.extend({ + * constructor: AnotherRecordClass, + * foo () { return 'bar' } + * }, { + * beep () { return 'boop' } + * }) + * const anotherRecord = new AnotherRecordClass() + * console.log(anotherRecord.created_at) + * console.log(anotherRecord.foo()) + * console.log(AnotherRecordClass.beep()) + * + * @method Record.extend + * @param {Object} [props={}] Properties to add to the prototype of the + * subclass. + * @param {Object} [props.constructor] Provide a custom constructor function + * to be used as the subclass itself. + * @param {Object} [classProps={}] Static properties to add to the subclass. + * @returns {Constructor} Subclass of this Record class. + * @since 3.0.0 + */var DOMAIN$7='Schema';/** + * A function map for each of the seven primitive JSON types defined by the core specification. + * Each function will check a given value and return true or false if the value is an instance of that type. + * ``` + * types.integer(1) // returns true + * types.string({}) // returns false + * ``` + * http://json-schema.org/latest/json-schema-core.html#anchor8 + * @name Schema.types + * @type {Object} + */var types={array:utils.isArray,boolean:utils.isBoolean,integer:utils.isInteger,'null':utils.isNull,number:utils.isNumber,object:utils.isObject,string:utils.isString};/** + * @ignore + */var segmentToString=function segmentToString(segment,prev){var str='';if(segment){if(utils.isNumber(segment)){str+='['+segment+']';}else if(prev){str+='.'+segment;}else{str+=''+segment;}}return str;};/** + * @ignore + */var makePath=function makePath(opts){opts||(opts={});var path='';var segments=opts.path||[];segments.forEach(function(segment){path+=segmentToString(segment,path);});path+=segmentToString(opts.prop,path);return path;};/** + * @ignore + */var makeError=function makeError(actual,expected,opts){return{expected:expected,actual:''+actual,path:makePath(opts)};};/** + * @ignore + */var addError=function addError(actual,expected,opts,errors){errors.push(makeError(actual,expected,opts));};/** + * @ignore + */var maxLengthCommon=function maxLengthCommon(keyword,value,schema,opts){var max=schema[keyword];if(value.length>max){return makeError(value.length,'length no more than '+max,opts);}};/** + * @ignore + */var minLengthCommon=function minLengthCommon(keyword,value,schema,opts){var min=schema[keyword];if(value.lengthvalue:maximum>=value)){return exclusiveMaximum?makeError(value,'no more than nor equal to '+maximum,opts):makeError(value,'no more than '+maximum,opts);}},/** + * Validates the length of the provided array against a maximum value defined by the Schema's `maxItems` keyword. + * Validation succeeds if the length of the array is less than, or equal to the value of this keyword. + * see http://json-schema.org/latest/json-schema-validation.html#anchor42 + * + * @name Schema.validationKeywords.maxItems + * @method + * @param {*} value Array to be validated. + * @param {Object} schema Schema containing the `maxItems` keyword. + * @param {Object} [opts] Configuration options. + * @returns {(array|undefined)} Array of errors or `undefined` if valid. + */maxItems:function maxItems(value,schema,opts){if(utils.isArray(value)){return maxLengthCommon('maxItems',value,schema,opts);}},/** + * Validates the length of the provided string against a maximum value defined in the Schema's `maxLength` keyword. + * Validation succeeds if the length of the string is less than, or equal to the value of this keyword. + * see http://json-schema.org/latest/json-schema-validation.html#anchor26 + * + * @name Schema.validationKeywords.maxLength + * @method + * @param {*} value String to be validated. + * @param {Object} schema Schema containing the `maxLength` keyword. + * @param {Object} [opts] Configuration options. + * @returns {(array|undefined)} Array of errors or `undefined` if valid. + */maxLength:function maxLength(value,schema,opts){return maxLengthCommon('maxLength',value,schema,opts);},/** + * Validates the count of the provided object's properties against a maximum value defined in the Schema's `maxProperties` keyword. + * Validation succeeds if the object's property count is less than, or equal to the value of this keyword. + * see http://json-schema.org/latest/json-schema-validation.html#anchor54 + * + * @name Schema.validationKeywords.maxProperties + * @method + * @param {*} value Object to be validated. + * @param {Object} schema Schema containing the `maxProperties` keyword. + * @param {Object} [opts] Configuration options. + * @returns {(array|undefined)} Array of errors or `undefined` if valid. + */maxProperties:function maxProperties(value,schema,opts){// validate only objects +if(!utils.isObject(value))return;var maxProperties=schema.maxProperties;var length=Object.keys(value).length;if(length>maxProperties){return makeError(length,'no more than '+maxProperties+' properties',opts);}},/** + * Validates the provided value against a minimum value defined by the Schema's `minimum` keyword + * Validation succeeds if the value is a number and is greater than, or equal to, the value of this keyword. + * http://json-schema.org/latest/json-schema-validation.html#anchor21 + * + * @name Schema.validationKeywords.minimum + * @method + * @param {*} value Number to validate against the keyword. + * @param {Object} schema Schema containing the `minimum` keyword. + * @param {Object} [opts] Configuration options. + * @returns {(array|undefined)} Array of errors or `undefined` if valid. + */minimum:function minimum(value,schema,opts){// Must be a number +var minimum=schema.minimum;// Must be a boolean +// Depends on minimum +// default: false +var exclusiveMinimum=schema.exclusiveMinimum;if((typeof value==='undefined'?'undefined':_typeof(value))===(typeof minimum==='undefined'?'undefined':_typeof(minimum))&&!(exclusiveMinimum?value>minimum:value>=minimum)){return exclusiveMinimum?makeError(value,'no less than nor equal to '+minimum,opts):makeError(value,'no less than '+minimum,opts);}},/** + * Validates the length of the provided array against a minimum value defined by the Schema's `minItems` keyword. + * Validation succeeds if the length of the array is greater than, or equal to the value of this keyword. + * see http://json-schema.org/latest/json-schema-validation.html#anchor45 + * + * @name Schema.validationKeywords.minItems + * @method + * @param {*} value Array to be validated. + * @param {Object} schema Schema containing the `minItems` keyword. + * @param {Object} [opts] Configuration options. + * @returns {(array|undefined)} Array of errors or `undefined` if valid. + */minItems:function minItems(value,schema,opts){if(utils.isArray(value)){return minLengthCommon('minItems',value,schema,opts);}},/** + * Validates the length of the provided string against a minimum value defined in the Schema's `minLength` keyword. + * Validation succeeds if the length of the string is greater than, or equal to the value of this keyword. + * see http://json-schema.org/latest/json-schema-validation.html#anchor29 + * + * @name Schema.validationKeywords.minLength + * @method + * @param {*} value String to be validated. + * @param {Object} schema Schema containing the `minLength` keyword. + * @param {Object} [opts] Configuration options. + * @returns {(array|undefined)} Array of errors or `undefined` if valid. + */minLength:function minLength(value,schema,opts){return minLengthCommon('minLength',value,schema,opts);},/** + * Validates the count of the provided object's properties against a minimum value defined in the Schema's `minProperties` keyword. + * Validation succeeds if the object's property count is greater than, or equal to the value of this keyword. + * see http://json-schema.org/latest/json-schema-validation.html#anchor57 + * + * @name Schema.validationKeywords.minProperties + * @method + * @param {*} value Object to be validated. + * @param {Object} schema Schema containing the `minProperties` keyword. + * @param {Object} [opts] Configuration options. + * @returns {(array|undefined)} Array of errors or `undefined` if valid. + */minProperties:function minProperties(value,schema,opts){// validate only objects +if(!utils.isObject(value))return;var minProperties=schema.minProperties;var length=Object.keys(value).length;if(length0;i--){item=value[i];// Only compare against unchecked items +for(j=i-1;j>=0;j--){// Found a duplicate +if(utils.deepEqual(item,value[j])){return makeError(item,'no duplicates',opts);}}}}}};/** + * @ignore + */var runOps=function runOps(ops,value,schema,opts){var errors=[];ops.forEach(function(op){if(schema[op]!==undefined){errors=errors.concat(validationKeywords[op](value,schema,opts)||[]);}});return errors.length?errors:undefined;};var ANY_OPS=['enum','type','allOf','anyOf','oneOf','not'];var ARRAY_OPS=['items','maxItems','minItems','uniqueItems'];var NUMERIC_OPS=['multipleOf','maximum','minimum'];var OBJECT_OPS=['maxProperties','minProperties','required','properties','dependencies'];var STRING_OPS=['maxLength','minLength','pattern'];/** + * http://json-schema.org/latest/json-schema-validation.html#anchor75 + * @ignore + */var validateAny=function validateAny(value,schema,opts){return runOps(ANY_OPS,value,schema,opts);};/** + * Validates the provided value against a given Schema according to the http://json-schema.org/ v4 specification. + * + * @name Schema.validate + * @method + * @param {*} value Value to be validated. + * @param {Object} schema Valid Schema according to the http://json-schema.org/ v4 specification. + * @param {Object} [opts] Configuration options. + * @returns {(array|undefined)} Array of errors or `undefined` if valid. + */var _validate=function _validate(value,schema,opts){var errors=[];opts||(opts={});opts.ctx||(opts.ctx={value:value,schema:schema});var shouldPop=void 0;var prevProp=opts.prop;if(schema===undefined){return;}if(!utils.isObject(schema)){throw utils.err(DOMAIN$7+'#validate')(500,'Invalid schema at path: "'+opts.path+'"');}if(opts.path===undefined){opts.path=[];}// Track our location as we recurse +if(opts.prop!==undefined){shouldPop=true;opts.path.push(opts.prop);opts.prop=undefined;}// Validate against parent schema +if(schema['extends']){// opts.path = path +// opts.prop = prop +if(utils.isFunction(schema['extends'].validate)){errors=errors.concat(schema['extends'].validate(value,opts)||[]);}else{errors=errors.concat(_validate(value,schema['extends'],opts)||[]);}}if(value===undefined){// Check if property is required +if(schema.required===true&&!opts.existingOnly){addError(value,'a value',opts,errors);}if(shouldPop){opts.path.pop();opts.prop=prevProp;}return errors.length?errors:undefined;}errors=errors.concat(validateAny(value,schema,opts)||[]);if(shouldPop){opts.path.pop();opts.prop=prevProp;}return errors.length?errors:undefined;};// These strings are cached for optimal performance of the change detection +// boolean - Whether a Record is changing in the current execution frame +var changingPath='changing';// string[] - Properties that have changed in the current execution frame +var changedPath='changed';// Object[] - History of change records +var changeHistoryPath='history';// boolean - Whether a Record is currently being instantiated +var creatingPath$1='creating';// number - The setTimeout change event id of a Record, if any +var eventIdPath='eventId';// boolean - Whether to skip validation for a Record's currently changing property +var noValidatePath$1='noValidate';// boolean - Whether to preserve Change History for a Record +var keepChangeHistoryPath$1='keepChangeHistory';// boolean - Whether to skip change notification for a Record's currently +// changing property +var silentPath='silent';var validationFailureMsg='validation failed';/** + * Assemble a property descriptor which will be added to the prototype of + * {@link Mapper#recordClass}. This method is called when + * {@link Mapper#applySchema} is set to `true`. + * + * @ignore + */var makeDescriptor=function makeDescriptor(prop,schema,opts){var descriptor={// Better to allow configurability, but at the user's own risk +configurable:true,// These properties are enumerable by default, but regardless of their +// enumerability, they won't be "own" properties of individual records +enumerable:schema.enumerable===undefined?true:!!schema.enumerable};// Cache a few strings for optimal performance +var keyPath='props.'+prop;var previousPath='previous.'+prop;var getter=opts.getter;var setter=opts.setter;var unsetter=opts.unsetter;var track=utils.isBoolean(opts.track)?opts.track:schema.track;descriptor.get=function(){return this._get(keyPath);};if(utils.isFunction(schema.get)){(function(){var originalGet=descriptor.get;descriptor.get=function(){return schema.get.call(this,originalGet);};})();}descriptor.set=function(value){var _this=this;// These are accessed a lot +var _get=this[getter];var _set=this[setter];var _unset=this[unsetter];// Optionally check that the new value passes validation +if(!_get(noValidatePath$1)){var errors=schema.validate(value,{path:[prop]});if(errors){// Immediately throw an error, preventing the record from getting into +// an invalid state +var error=new Error(validationFailureMsg);error.errors=errors;throw error;}}// TODO: Make it so tracking can be turned on for all properties instead of +// only per-property +if(track&&!_get(creatingPath$1)){(function(){// previous is versioned on database commit +// props are versioned on set() +var previous=_get(previousPath);var current=_get(keyPath);var changing=_get(changingPath);var changed=_get(changedPath);if(!changing){// Track properties that are changing in the current event loop +changed=[];}// Add changing properties to this array once at most +var index=changed.indexOf(prop);if(current!==value&&index===-1){changed.push(prop);}if(previous===value){if(index>=0){changed.splice(index,1);}}// No changes in current event loop +if(!changed.length){changing=false;_unset(changingPath);_unset(changedPath);// Cancel pending change event +if(_get(eventIdPath)){clearTimeout(_get(eventIdPath));_unset(eventIdPath);}}// Changes detected in current event loop +if(!changing&&changed.length){_set(changedPath,changed);_set(changingPath,true);// Saving the timeout id allows us to batch all changes in the same +// event loop into a single "change" +// TODO: Optimize +_set(eventIdPath,setTimeout(function(){// Previous event loop where changes were gathered has ended, so +// notify any listeners of those changes and prepare for any new +// changes +_unset(changedPath);_unset(eventIdPath);_unset(changingPath);// TODO: Optimize +if(!_get(silentPath)){var i=void 0;for(i=0;iSchema#constructor + * // Normally you would do: import {Schema} from 'js-data' + * const JSData = require('js-data@3.0.0-rc.4') + * const {Schema} = JSData + * console.log('Using JSData v' + JSData.version.full) + * + * const PostSchema = new Schema({ + * type: 'object', + * properties: { + * title: { type: 'string' } + * } + * }) + * PostSchema.validate({ title: 1234 }) + * + * @class Schema + * @extends Component + * @param {Object} definition Schema definition according to json-schema.org + */function Schema(definition){var _this2=this;definition||(definition={});// TODO: schema validation +utils.fillIn(this,definition);if(this.type==='object'&&this.properties){utils.forOwn(this.properties,function(_definition,prop){if(!(_definition instanceof Schema)){_this2.properties[prop]=new Schema(_definition);}});}else if(this.type==='array'&&this.items&&!(this.items instanceof Schema)){this.items=new Schema(this.items);}if(this.extends&&!(this.extends instanceof Schema)){this.extends=new Schema(this.extends);}['allOf','anyOf','oneOf'].forEach(function(validationKeyword){if(_this2[validationKeyword]){_this2[validationKeyword].forEach(function(_definition,i){if(!(_definition instanceof Schema)){_this2[validationKeyword][i]=new Schema(_definition);}});}});}var Schema$1=Component$1.extend({constructor:Schema,/** + * This adds ES5 getters/setters to the target based on the "properties" in + * this Schema, which makes possible change tracking and validation on + * property assignment. + * + * @name Schema#validate + * @method + * @param {Object} target The prototype to which to apply this schema. + */apply:function apply(target,opts){opts||(opts={});opts.getter||(opts.getter='_get');opts.setter||(opts.setter='_set');opts.unsetter||(opts.unsetter='_unset');opts.track||(opts.track=this.track);var properties=this.properties||{};utils.forOwn(properties,function(schema,prop){Object.defineProperty(target,prop,makeDescriptor(prop,schema,opts));});},/** + * Apply default values to the target object for missing values. + * + * @name Schema#applyDefaults + * @method + * @param {Object} target The target to which to apply values for missing values. + */applyDefaults:function applyDefaults(target){if(!target){return;}var properties=this.properties||{};var hasSet=utils.isFunction(target.set)||utils.isFunction(target._set);utils.forOwn(properties,function(schema,prop){if(schema.hasOwnProperty('default')&&utils.get(target,prop)===undefined){if(hasSet){target.set(prop,utils.plainCopy(schema['default']),{silent:true});}else{utils.set(target,prop,utils.plainCopy(schema['default']));}}if(schema.type==='object'&&schema.properties){if(hasSet){var orig=target._get('noValidate');target._set('noValidate',true);utils.set(target,prop,utils.get(target,prop)||{},{silent:true});target._set('noValidate',orig);}else{utils.set(target,prop,utils.get(target,prop)||{});}schema.applyDefaults(utils.get(target,prop));}});},/** + * Create a copy of the given value that contains only the properties defined + * in this schema. + * + * @name Schema#pick + * @method + * @param {*} value The value to copy. + * @returns {*} The copy. + */pick:function pick(value){var _this3=this;if(this.type==='object'){var _ret4=function(){value||(value={});var copy={};if(_this3.properties){utils.forOwn(_this3.properties,function(_definition,prop){copy[prop]=_definition.pick(value[prop]);});}if(_this3.extends){utils.fillIn(copy,_this3.extends.pick(value));}return{v:copy};}();if((typeof _ret4==='undefined'?'undefined':_typeof(_ret4))==="object")return _ret4.v;}else if(this.type==='array'){value||(value=[]);return value.map(function(item){var _copy=_this3.items?_this3.items.pick(item):{};if(_this3.extends){utils.fillIn(_copy,_this3.extends.pick(item));}return _copy;});}return utils.plainCopy(value);},/** + * Validate the provided value against this schema. + * + * @name Schema#validate + * @method + * @param {*} value Value to validate. + * @param {Object} [opts] Configuration options. + * @returns {(array|undefined)} Array of errors or `undefined` if valid. + */validate:function validate(value,opts){return _validate(value,this,opts);}},{ANY_OPS:ANY_OPS,ARRAY_OPS:ARRAY_OPS,NUMERIC_OPS:NUMERIC_OPS,OBJECT_OPS:OBJECT_OPS,STRING_OPS:STRING_OPS,typeGroupValidators:typeGroupValidators,types:types,validate:_validate,validationKeywords:validationKeywords});/** + * Create a subclass of this Schema: + * @example Schema.extend + * // Normally you would do: import {Schema} from 'js-data' + * const JSData = require('js-data@3.0.0-rc.4') + * const {Schema} = JSData + * console.log('Using JSData v' + JSData.version.full) + * + * // Extend the class using ES2015 class syntax. + * class CustomSchemaClass extends Schema { + * foo () { return 'bar' } + * static beep () { return 'boop' } + * } + * const customSchema = new CustomSchemaClass() + * console.log(customSchema.foo()) + * console.log(CustomSchemaClass.beep()) + * + * // Extend the class using alternate method. + * const OtherSchemaClass = Schema.extend({ + * foo () { return 'bar' } + * }, { + * beep () { return 'boop' } + * }) + * const otherSchema = new OtherSchemaClass() + * console.log(otherSchema.foo()) + * console.log(OtherSchemaClass.beep()) + * + * // Extend the class, providing a custom constructor. + * function AnotherSchemaClass () { + * Schema.call(this) + * this.created_at = new Date().getTime() + * } + * Schema.extend({ + * constructor: AnotherSchemaClass, + * foo () { return 'bar' } + * }, { + * beep () { return 'boop' } + * }) + * const anotherSchema = new AnotherSchemaClass() + * console.log(anotherSchema.created_at) + * console.log(anotherSchema.foo()) + * console.log(AnotherSchemaClass.beep()) + * + * @method Schema.extend + * @param {Object} [props={}] Properties to add to the prototype of the + * subclass. + * @param {Object} [props.constructor] Provide a custom constructor function + * to be used as the subclass itself. + * @param {Object} [classProps={}] Static properties to add to the subclass. + * @returns {Constructor} Subclass of this Schema class. + * @since 3.0.0 + */var DOMAIN$4='Mapper';var applyDefaultsHooks=['beforeCreate','beforeCreateMany'];var validatingHooks=['beforeCreate','beforeCreateMany','beforeUpdate','beforeUpdateAll','beforeUpdateMany'];var makeNotify=function makeNotify(num){return function(){var _this=this;for(var _len=arguments.length,args=Array(_len),_key=0;_key<_len;_key++){args[_key]=arguments[_key];}var opts=args[args.length-num];var op=opts.op;this.dbg.apply(this,[op].concat(args));if(applyDefaultsHooks.indexOf(op)!==-1&&opts.applyDefaults!==false){(function(){var schema=_this.getSchema();if(schema&&schema.applyDefaults){var toProcess=args[0];if(!utils.isArray(toProcess)){toProcess=[toProcess];}toProcess.forEach(function(record){schema.applyDefaults(record);});}})();}// Automatic validation +if(validatingHooks.indexOf(op)!==-1&&!opts.noValidate){// Save current value of option +var originalExistingOnly=opts.existingOnly;// For updates, ignore required fields if they aren't present +if(op.indexOf('beforeUpdate')===0&&opts.existingOnly===undefined){opts.existingOnly=true;}var errors=this.validate(args[op==='beforeUpdate'?1:0],utils.pick(opts,['existingOnly']));// Restore option +opts.existingOnly=originalExistingOnly;// Abort lifecycle due to validation errors +if(errors){return utils.reject(errors);}}// Emit lifecycle event +if(opts.notify||opts.notify===undefined&&this.notify){setTimeout(function(){_this.emit.apply(_this,[op].concat(args));});}};};// These are the default implementations of all of the lifecycle hooks +var notify=makeNotify(1);var notify2=makeNotify(2);// This object provides meta information used by Mapper#crud to actually +// execute each lifecycle method +var LIFECYCLE_METHODS={count:{defaults:[{},{}],skip:true,types:[]},destroy:{defaults:[{},{}],skip:true,types:[]},destroyAll:{defaults:[{},{}],skip:true,types:[]},find:{defaults:[undefined,{}],types:[]},findAll:{defaults:[{},{}],types:[]},sum:{defaults:[undefined,{},{}],skip:true,types:[]},update:{adapterArgs:function adapterArgs(mapper,id,props,opts){return[id,mapper.toJSON(props,opts),opts];},beforeAssign:1,defaults:[undefined,{},{}],types:[]},updateAll:{adapterArgs:function adapterArgs(mapper,props,query,opts){return[mapper.toJSON(props,opts),query,opts];},beforeAssign:0,defaults:[{},{},{}],types:[]},updateMany:{adapterArgs:function adapterArgs(mapper,records,opts){return[records.map(function(record){return mapper.toJSON(record,opts);}),opts];},beforeAssign:0,defaults:[[],{}],types:[]}};var MAPPER_DEFAULTS={/** + * Hash of registered adapters. Don't modify directly. Use + * {@link Mapper#registerAdapter} instead. + * + * @default {} + * @name Mapper#_adapters + * @since 3.0.0 + * @tutorial ["http://www.js-data.io/v3.0/docs/connecting-to-a-data-source","Connecting to a data source"] + */_adapters:{},/** + * Whether {@link Mapper#beforeCreate} and {@link Mapper#beforeCreateMany} + * should automatically receive default values according to the Mapper's schema. + * + * @default true + * @name Mapper#applyDefaults + * @since 3.0.0 + * @type {boolean} + */applyDefaults:true,/** + * Whether to augment {@link Mapper#recordClass} with ES5 getters and setters + * according to the properties defined in {@link Mapper#schema}. This makes + * possible validation and change tracking on individual properties + * when using the dot (e.g. `user.name = "Bob"`) operator to modify a + * property, and is `true` by default. + * + * @default true + * @name Mapper#applySchema + * @since 3.0.0 + * @type {boolean} + */applySchema:true,/** + * The name of the registered adapter that this Mapper should used by default. + * + * @default "http" + * @name Mapper#defaultAdapter + * @since 3.0.0 + * @tutorial ["http://www.js-data.io/v3.0/docs/connecting-to-a-data-source","Connecting to a data source"] + * @type {string} + */defaultAdapter:'http',/** + * The field used as the unique identifier on records handled by this Mapper. + * + * @default id + * @name Mapper#idAttribute + * @since 3.0.0 + * @type {string} + */idAttribute:'id',/** + * Whether records created from this mapper keep changeHistory on property changes. + * + * @default true + * @name Mapper#keepChangeHistory + * @since 3.0.0 + * @type {boolean} + */keepChangeHistory:true,/** + * Whether this Mapper should emit operational events. + * + * @default true + * @name Mapper#notify + * @since 3.0.0 + * @type {boolean} + */notify:true,/** + * Whether to skip validation when the Record instances are created. + * + * @default false + * @name Mapper#noValidate + * @since 3.0.0 + * @type {boolean} + */noValidate:false,/** + * Whether {@link Mapper#create}, {@link Mapper#createMany}, + * {@link Mapper#update}, {@link Mapper#updateAll}, {@link Mapper#updateMany}, + * {@link Mapper#find}, {@link Mapper#findAll}, {@link Mapper#destroy}, + * {@link Mapper#destroyAll}, {@link Mapper#count}, and {@link Mapper#sum} + * should return a raw result object that contains both the instance data + * returned by the adapter _and_ metadata about the operation. + * + * The default is to NOT return the result object, and instead return just the + * instance data. + * + * @default false + * @name Mapper#raw + * @since 3.0.0 + * @type {boolean} + */raw:false,/** + * Whether records created from this mapper automatically validate their properties + * when their properties are modified. + * + * @default true + * @name Mapper#validateOnSet + * @since 3.0.0 + * @type {boolean} + */validateOnSet:true};/** + * The core of JSData's [ORM/ODM][orm] implementation. Given a minimum amout of + * meta information about a resource, a Mapper can perform generic CRUD + * operations against that resource. Apart from its configuration, a Mapper is + * stateless. The particulars of various persistence layers have been abstracted + * into adapters, which a Mapper uses to perform its operations. + * + * The term "Mapper" comes from the [Data Mapper Pattern][pattern] described in + * Martin Fowler's [Patterns of Enterprise Application Architecture][book]. A + * Data Mapper moves data between [in-memory object instances][record] and a + * relational or document-based database. JSData's Mapper can work with any + * persistence layer you can write an adapter for. + * + * _("Model" is a heavily overloaded term and is avoided in this documentation + * to prevent confusion.)_ + * + * [orm]: https://en.wikipedia.org/wiki/Object-relational_mapping + * [pattern]: https://en.wikipedia.org/wiki/Data_mapper_pattern + * [book]: http://martinfowler.com/books/eaa.html + * [record]: Record.html + * + * @example + * // Import and instantiate + * import {Mapper} from 'js-data' + * const UserMapper = new Mapper({ name: 'user' }) + * + * @example + * // Define a Mapper using the Container component + * import {Container} from 'js-data' + * const store = new Container() + * store.defineMapper('user') + * + * @class Mapper + * @extends Component + * @param {Object} opts Configuration options. + * @param {boolean} [opts.applySchema=true] See {@link Mapper#applySchema}. + * @param {boolean} [opts.debug=false] See {@link Component#debug}. + * @param {string} [opts.defaultAdapter=http] See {@link Mapper#defaultAdapter}. + * @param {string} [opts.idAttribute=id] See {@link Mapper#idAttribute}. + * @param {Object} [opts.methods] See {@link Mapper#methods}. + * @param {string} opts.name See {@link Mapper#name}. + * @param {boolean} [opts.notify] See {@link Mapper#notify}. + * @param {boolean} [opts.raw=false] See {@link Mapper#raw}. + * @param {Function|boolean} [opts.recordClass] See {@link Mapper#recordClass}. + * @param {Object|Schema} [opts.schema] See {@link Mapper#schema}. + * @returns {Mapper} A new {@link Mapper} instance. + * @see http://www.js-data.io/v3.0/docs/components-of-jsdata#mapper + * @since 3.0.0 + * @tutorial ["http://www.js-data.io/v3.0/docs/components-of-jsdata#mapper","Components of JSData: Mapper"] + * @tutorial ["http://www.js-data.io/v3.0/docs/modeling-your-data","Modeling your data"] + */function Mapper(opts){var _this2=this;utils.classCallCheck(this,Mapper);Component$1.call(this);opts||(opts={});// Prepare certain properties to be non-enumerable +Object.defineProperties(this,{_adapters:{value:undefined,writable:true},/** + * The {@link Container} that holds this Mapper. __Do not modify.__ + * + * @name Mapper#lifecycleMethods + * @since 3.0.0 + * @type {Object} + */datastore:{value:undefined,writable:true},/** + * The meta information describing this Mapper's available lifecycle + * methods. __Do not modify.__ + * + * @name Mapper#lifecycleMethods + * @since 3.0.0 + * @type {Object} + */lifecycleMethods:{value:LIFECYCLE_METHODS},/** + * Set to `false` to force the Mapper to work with POJO objects only. + * + * @example + * // Use POJOs only. + * import {Mapper, Record} from 'js-data' + * const UserMapper = new Mapper({ recordClass: false }) + * UserMapper.recordClass // false + * const user = UserMapper#createRecord() + * user instanceof Record // false + * + * @example + * // Set to a custom class to have records wrapped in your custom class. + * import {Mapper, Record} from 'js-data' + * // Custom class + * class User { + * constructor (props = {}) { + * for (var key in props) { + * if (props.hasOwnProperty(key)) { + * this[key] = props[key] + * } + * } + * } + * } + * const UserMapper = new Mapper({ recordClass: User }) + * UserMapper.recordClass // function User() {} + * const user = UserMapper#createRecord() + * user instanceof Record // false + * user instanceof User // true + * + * + * @example + * // Extend the {@link Record} class. + * import {Mapper, Record} from 'js-data' + * // Custom class + * class User extends Record { + * constructor () { + * super(props) + * } + * } + * const UserMapper = new Mapper({ recordClass: User }) + * UserMapper.recordClass // function User() {} + * const user = UserMapper#createRecord() + * user instanceof Record // true + * user instanceof User // true + * + * @name Mapper#recordClass + * @default {@link Record} + * @see Record + * @since 3.0.0 + */recordClass:{value:undefined,writable:true},/** + * This Mapper's {@link Schema}. + * + * @example Mapper#schema + * // Normally you would do: import {Mapper} from 'js-data' + * const JSData = require('js-data@3.0.0-rc.4') + * const {Mapper} = JSData + * console.log('Using JSData v' + JSData.version.full) + * + * const UserMapper = new Mapper({ + * name: 'user', + * schema: { + * properties: { + * id: { type: 'number' }, + * first: { type: 'string', track: true }, + * last: { type: 'string', track: true }, + * role: { type: 'string', track: true, required: true }, + * age: { type: 'integer', track: true }, + * is_active: { type: 'number' } + * } + * } + * }) + * const user = UserMapper.createRecord({ + * id: 1, + * name: 'John', + * role: 'admin' + * }) + * user.on('change', function (user, changes) { + * console.log(changes) + * }) + * user.on('change:role', function (user, value) { + * console.log('change:role - ' + value) + * }) + * user.role = 'owner' + * + * @name Mapper#schema + * @see Schema + * @since 3.0.0 + * @type {Schema} + */schema:{value:undefined,writable:true}});// Apply user-provided configuration +utils.fillIn(this,opts);// Fill in any missing options with the defaults +utils.fillIn(this,utils.copy(MAPPER_DEFAULTS));/** + * The name for this Mapper. This is the minimum amount of meta information + * required for a Mapper to be able to execute CRUD operations for a + * Resource. + * + * @name Mapper#name + * @since 3.0.0 + * @type {string} + */if(!this.name){throw utils.err('new '+DOMAIN$4,'opts.name')(400,'string',this.name);}// Setup schema, with an empty default schema if necessary +if(this.schema){this.schema.type||(this.schema.type='object');}if(!(this.schema instanceof Schema$1)){this.schema=new Schema$1(this.schema||{type:'object'});}// Create a subclass of Record that's tied to this Mapper +if(this.recordClass===undefined){(function(){var superClass=Record$1;_this2.recordClass=superClass.extend({constructor:function Record$1(){var subClass=function Record$1(props,opts){utils.classCallCheck(this,subClass);superClass.call(this,props,opts);};return subClass;}()});})();}if(this.recordClass){this.recordClass.mapper=this;/** + * Functions that should be added to the prototype of {@link Mapper#recordClass}. + * + * @name Mapper#methods + * @since 3.0.0 + * @type {Object} + */if(utils.isObject(this.methods)){utils.addHiddenPropsToTarget(this.recordClass.prototype,this.methods);}// We can only apply the schema to the prototype of this.recordClass if the +// class extends Record +if(Record$1.prototype.isPrototypeOf(Object.create(this.recordClass.prototype))&&this.schema&&this.schema.apply&&this.applySchema){this.schema.apply(this.recordClass.prototype);}}}var Mapper$1=Component$1.extend({constructor:Mapper,/** + * Mapper lifecycle hook called by {@link Mapper#count}. If this method + * returns a promise then {@link Mapper#count} will wait for the promise + * to resolve before continuing. + * + * @method Mapper#afterCount + * @param {Object} query The `query` argument passed to {@link Mapper#count}. + * @param {Object} opts The `opts` argument passed to {@link Mapper#count}. + * @param {*} result The result, if any. + * @since 3.0.0 + */afterCount:notify2,/** + * Mapper lifecycle hook called by {@link Mapper#create}. If this method + * returns a promise then {@link Mapper#create} will wait for the promise + * to resolve before continuing. + * + * @method Mapper#afterCreate + * @param {Object} props The `props` argument passed to {@link Mapper#create}. + * @param {Object} opts The `opts` argument passed to {@link Mapper#create}. + * @param {*} result The result, if any. + * @since 3.0.0 + */afterCreate:notify2,/** + * Mapper lifecycle hook called by {@link Mapper#createMany}. If this method + * returns a promise then {@link Mapper#createMany} will wait for the promise + * to resolve before continuing. + * + * @method Mapper#afterCreateMany + * @param {Array} records The `records` argument passed to {@link Mapper#createMany}. + * @param {Object} opts The `opts` argument passed to {@link Mapper#createMany}. + * @param {*} result The result, if any. + * @since 3.0.0 + */afterCreateMany:notify2,/** + * Mapper lifecycle hook called by {@link Mapper#destroy}. If this method + * returns a promise then {@link Mapper#destroy} will wait for the promise + * to resolve before continuing. + * + * @method Mapper#afterDestroy + * @param {(string|number)} id The `id` argument passed to {@link Mapper#destroy}. + * @param {Object} opts The `opts` argument passed to {@link Mapper#destroy}. + * @param {*} result The result, if any. + * @since 3.0.0 + */afterDestroy:notify2,/** + * Mapper lifecycle hook called by {@link Mapper#destroyAll}. If this method + * returns a promise then {@link Mapper#destroyAll} will wait for the promise + * to resolve before continuing. + * + * @method Mapper#afterDestroyAll + * @param {*} data The `data` returned by the adapter. + * @param {query} query The `query` argument passed to {@link Mapper#destroyAll}. + * @param {Object} opts The `opts` argument passed to {@link Mapper#destroyAll}. + * @param {*} result The result, if any. + * @since 3.0.0 + */afterDestroyAll:notify2,/** + * Mapper lifecycle hook called by {@link Mapper#find}. If this method + * returns a promise then {@link Mapper#find} will wait for the promise + * to resolve before continuing. + * + * @method Mapper#afterFind + * @param {(string|number)} id The `id` argument passed to {@link Mapper#find}. + * @param {Object} opts The `opts` argument passed to {@link Mapper#find}. + * @param {*} result The result, if any. + * @since 3.0.0 + */afterFind:notify2,/** + * Mapper lifecycle hook called by {@link Mapper#findAll}. If this method + * returns a promise then {@link Mapper#findAll} will wait for the promise + * to resolve before continuing. + * + * @method Mapper#afterFindAll + * @param {Object} query The `query` argument passed to {@link Mapper#findAll}. + * @param {Object} opts The `opts` argument passed to {@link Mapper#findAll}. + * @param {*} result The result, if any. + * @since 3.0.0 + */afterFindAll:notify2,/** + * Mapper lifecycle hook called by {@link Mapper#sum}. If this method + * returns a promise then {@link Mapper#sum} will wait for the promise + * to resolve before continuing. + * + * @method Mapper#afterSum + * @param {Object} query The `query` argument passed to {@link Mapper#sum}. + * @param {Object} opts The `opts` argument passed to {@link Mapper#sum}. + * @param {*} result The result, if any. + * @since 3.0.0 + */afterSum:notify2,/** + * Mapper lifecycle hook called by {@link Mapper#update}. If this method + * returns a promise then {@link Mapper#update} will wait for the promise + * to resolve before continuing. + * + * @method Mapper#afterUpdate + * @param {(string|number)} id The `id` argument passed to {@link Mapper#update}. + * @param {props} props The `props` argument passed to {@link Mapper#update}. + * @param {Object} opts The `opts` argument passed to {@link Mapper#update}. + * @param {*} result The result, if any. + * @since 3.0.0 + */afterUpdate:notify2,/** + * Mapper lifecycle hook called by {@link Mapper#updateAll}. If this method + * returns a promise then {@link Mapper#updateAll} will wait for the promise + * to resolve before continuing. + * + * @method Mapper#afterUpdateAll + * @param {Object} props The `props` argument passed to {@link Mapper#updateAll}. + * @param {Object} query The `query` argument passed to {@link Mapper#updateAll}. + * @param {Object} opts The `opts` argument passed to {@link Mapper#updateAll}. + * @param {*} result The result, if any. + * @since 3.0.0 + */afterUpdateAll:notify2,/** + * Mapper lifecycle hook called by {@link Mapper#updateMany}. If this method + * returns a promise then {@link Mapper#updateMany} will wait for the promise + * to resolve before continuing. + * + * @method Mapper#afterUpdateMany + * @param {Array} records The `records` argument passed to {@link Mapper#updateMany}. + * @param {Object} opts The `opts` argument passed to {@link Mapper#updateMany}. + * @param {*} result The result, if any. + * @since 3.0.0 + */afterUpdateMany:notify2,/** + * Mapper lifecycle hook called by {@link Mapper#create}. If this method + * returns a promise then {@link Mapper#create} will wait for the promise + * to resolve before continuing. + * + * @method Mapper#beforeCreate + * @param {Object} props The `props` argument passed to {@link Mapper#create}. + * @param {Object} opts The `opts` argument passed to {@link Mapper#create}. + * @since 3.0.0 + */beforeCreate:notify,/** + * Mapper lifecycle hook called by {@link Mapper#createMany}. If this method + * returns a promise then {@link Mapper#createMany} will wait for the promise + * to resolve before continuing. + * + * @method Mapper#beforeCreateMany + * @param {Array} records The `records` argument passed to {@link Mapper#createMany}. + * @param {Object} opts The `opts` argument passed to {@link Mapper#createMany}. + * @since 3.0.0 + */beforeCreateMany:notify,/** + * Mapper lifecycle hook called by {@link Mapper#count}. If this method + * returns a promise then {@link Mapper#count} will wait for the promise + * to resolve before continuing. + * + * @method Mapper#beforeCount + * @param {Object} query The `query` argument passed to {@link Mapper#count}. + * @param {Object} opts The `opts` argument passed to {@link Mapper#count}. + * @since 3.0.0 + */beforeCount:notify,/** + * Mapper lifecycle hook called by {@link Mapper#destroy}. If this method + * returns a promise then {@link Mapper#destroy} will wait for the promise + * to resolve before continuing. + * + * @method Mapper#beforeDestroy + * @param {(string|number)} id The `id` argument passed to {@link Mapper#destroy}. + * @param {Object} opts The `opts` argument passed to {@link Mapper#destroy}. + * @since 3.0.0 + */beforeDestroy:notify,/** + * Mapper lifecycle hook called by {@link Mapper#destroyAll}. If this method + * returns a promise then {@link Mapper#destroyAll} will wait for the promise + * to resolve before continuing. + * + * @method Mapper#beforeDestroyAll + * @param {query} query The `query` argument passed to {@link Mapper#destroyAll}. + * @param {Object} opts The `opts` argument passed to {@link Mapper#destroyAll}. + * @since 3.0.0 + */beforeDestroyAll:notify,/** + * Mappers lifecycle hook called by {@link Mapper#find}. If this method + * returns a promise then {@link Mapper#find} will wait for the promise + * to resolve before continuing. + * + * @method Mapper#beforeFind + * @param {(string|number)} id The `id` argument passed to {@link Mapper#find}. + * @param {Object} opts The `opts` argument passed to {@link Mapper#find}. + * @since 3.0.0 + */beforeFind:notify,/** + * Mapper lifecycle hook called by {@link Mapper#findAll}. If this method + * returns a promise then {@link Mapper#findAll} will wait for the promise + * to resolve before continuing. + * + * @method Mapper#beforeFindAll + * @param {Object} query The `query` argument passed to {@link Mapper#findAll}. + * @param {Object} opts The `opts` argument passed to {@link Mapper#findAll}. + * @since 3.0.0 + */beforeFindAll:notify,/** + * Mapper lifecycle hook called by {@link Mapper#sum}. If this method + * returns a promise then {@link Mapper#sum} will wait for the promise + * to resolve before continuing. + * + * @method Mapper#beforeSum + * @param {string} field The `field` argument passed to {@link Mapper#sum}. + * @param {Object} query The `query` argument passed to {@link Mapper#sum}. + * @param {Object} opts The `opts` argument passed to {@link Mapper#sum}. + * @since 3.0.0 + */beforeSum:notify,/** + * Mapper lifecycle hook called by {@link Mapper#update}. If this method + * returns a promise then {@link Mapper#update} will wait for the promise + * to resolve before continuing. + * + * @method Mapper#beforeUpdate + * @param {(string|number)} id The `id` argument passed to {@link Mapper#update}. + * @param {props} props The `props` argument passed to {@link Mapper#update}. + * @param {Object} opts The `opts` argument passed to {@link Mapper#update}. + * @since 3.0.0 + */beforeUpdate:notify,/** + * Mapper lifecycle hook called by {@link Mapper#updateAll}. If this method + * returns a promise then {@link Mapper#updateAll} will wait for the promise + * to resolve before continuing. + * + * @method Mapper#beforeUpdateAll + * @param {Object} props The `props` argument passed to {@link Mapper#updateAll}. + * @param {Object} query The `query` argument passed to {@link Mapper#updateAll}. + * @param {Object} opts The `opts` argument passed to {@link Mapper#updateAll}. + * @since 3.0.0 + */beforeUpdateAll:notify,/** + * Mapper lifecycle hook called by {@link Mapper#updateMany}. If this method + * returns a promise then {@link Mapper#updateMany} will wait for the promise + * to resolve before continuing. + * + * @method Mapper#beforeUpdateMany + * @param {Array} records The `records` argument passed to {@link Mapper#updateMany}. + * @param {Object} opts The `opts` argument passed to {@link Mapper#updateMany}. + * @since 3.0.0 + */beforeUpdateMany:notify,/** + * This method is called at the end of most lifecycle methods. It does the + * following: + * + * 1. If `opts.raw` is `true`, add this Mapper's configuration to the `opts` + * argument as metadata for the operation. + * 2. Wrap the result data appropriately using {@link Mapper#wrap}, which + * calls {@link Mapper#createRecord}. + * + * @method Mapper#_end + * @private + * @since 3.0.0 + */_end:function _end(result,opts,skip){if(opts.raw){utils._(result,opts);}if(skip){return result;}var _data=opts.raw?result.data:result;if(_data&&utils.isFunction(this.wrap)){_data=this.wrap(_data,opts);if(opts.raw){result.data=_data;}else{result=_data;}}return result;},/** + * Define a belongsTo relationship. Only useful if you're managing your + * Mappers manually and not using a Container or DataStore component. + * + * @example + * PostMapper.belongsTo(UserMapper, { + * // post.user_id points to user.id + * foreignKey: 'user_id' + * // user records will be attached to post records at "post.user" + * localField: 'user' + * }) + * + * CommentMapper.belongsTo(UserMapper, { + * // comment.user_id points to user.id + * foreignKey: 'user_id' + * // user records will be attached to comment records at "comment.user" + * localField: 'user' + * }) + * CommentMapper.belongsTo(PostMapper, { + * // comment.post_id points to post.id + * foreignKey: 'post_id' + * // post records will be attached to comment records at "comment.post" + * localField: 'post' + * }) + * + * @method Mapper#belongsTo + * @see http://www.js-data.io/v3.0/docs/relations + * @since 3.0.0 + */belongsTo:function belongsTo$$(relatedMapper,opts){return belongsTo(relatedMapper,opts)(this);},/** + * Select records according to the `query` argument and return the count. + * + * {@link Mapper#beforeCount} will be called before calling the adapter. + * {@link Mapper#afterCount} will be called after calling the adapter. + * + * @example + * // Get the number of published blog posts + * PostMapper.count({ status: 'published' }).then((numPublished) => { + * console.log(numPublished) // e.g. 45 + * }) + * + * @method Mapper#count + * @param {Object} [query={}] Selection query. See {@link query}. + * @param {Object} [query.where] See {@link query.where}. + * @param {number} [query.offset] See {@link query.offset}. + * @param {number} [query.limit] See {@link query.limit}. + * @param {string|Array[]} [query.orderBy] See {@link query.orderBy}. + * @param {Object} [opts] Configuration options. Refer to the `count` method + * of whatever adapter you're using for more configuration options. + * @param {boolean} [opts.adapter={@link Mapper#defaultAdapter}] Name of the + * adapter to use. + * @param {boolean} [opts.notify={@link Mapper#notify}] See {@link Mapper#notify}. + * @param {boolean} [opts.raw={@link Mapper#raw}] See {@link Mapper#raw}. + * @returns {Promise} Resolves with the count of the selected records. + * @since 3.0.0 + */count:function count(query,opts){return this.crud('count',query,opts);},/** + * Fired during {@link Mapper#create}. See + * {@link Mapper~beforeCreateListener} for how to listen for this event. + * + * @event Mapper#beforeCreate + * @see Mapper~beforeCreateListener + * @see Mapper#create + *//** + * Callback signature for the {@link Mapper#event:beforeCreate} event. + * + * @example + * function onBeforeCreate (props, opts) { + * // do something + * } + * store.on('beforeCreate', onBeforeCreate) + * + * @callback Mapper~beforeCreateListener + * @param {Object} props The `props` argument passed to {@link Mapper#beforeCreate}. + * @param {Object} opts The `opts` argument passed to {@link Mapper#beforeCreate}. + * @see Mapper#event:beforeCreate + * @see Mapper#create + * @since 3.0.0 + *//** + * Fired during {@link Mapper#create}. See + * {@link Mapper~afterCreateListener} for how to listen for this event. + * + * @event Mapper#afterCreate + * @see Mapper~afterCreateListener + * @see Mapper#create + *//** + * Callback signature for the {@link Mapper#event:afterCreate} event. + * + * @example + * function onAfterCreate (props, opts, result) { + * // do something + * } + * store.on('afterCreate', onAfterCreate) + * + * @callback Mapper~afterCreateListener + * @param {Object} props The `props` argument passed to {@link Mapper#afterCreate}. + * @param {Object} opts The `opts` argument passed to {@link Mapper#afterCreate}. + * @param {Object} result The `result` argument passed to {@link Mapper#afterCreate}. + * @see Mapper#event:afterCreate + * @see Mapper#create + * @since 3.0.0 + *//** + * Create and save a new the record using the provided `props`. + * + * {@link Mapper#beforeCreate} will be called before calling the adapter. + * {@link Mapper#afterCreate} will be called after calling the adapter. + * + * @example + * // Create and save a new blog post + * PostMapper.create({ + * title: 'Modeling your data', + * status: 'draft' + * }).then((post) => { + * console.log(post) // { id: 1234, status: 'draft', ... } + * }) + * + * @fires Mapper#beforeCreate + * @fires Mapper#afterCreate + * @method Mapper#create + * @param {Object} props The properties for the new record. + * @param {Object} [opts] Configuration options. Refer to the `create` method + * of whatever adapter you're using for more configuration options. + * @param {boolean} [opts.adapter={@link Mapper#defaultAdapter}] Name of the + * adapter to use. + * @param {boolean} [opts.noValidate={@link Mapper#noValidate}] See {@link Mapper#noValidate}. + * @param {boolean} [opts.notify={@link Mapper#notify}] See {@link Mapper#notify}. + * @param {boolean} [opts.raw={@link Mapper#raw}] See {@link Mapper#raw}. + * @param {string[]} [opts.with=[]] Relations to create in a cascading + * create if `props` contains nested relations. NOT performed in a + * transaction. Each nested create will result in another {@link Mapper#create} + * or {@link Mapper#createMany} call. + * @param {string[]} [opts.pass=[]] Relations to send to the adapter as part + * of the payload. Normally relations are not sent. + * @returns {Promise} Resolves with the created record. + * @since 3.0.0 + */create:function create(props,opts){var _this3=this;var op=void 0,adapter=void 0;// Default values for arguments +props||(props={});opts||(opts={});var originalRecord=props;// Fill in "opts" with the Mapper's configuration +utils._(opts,this);adapter=opts.adapter=this.getAdapterName(opts);// beforeCreate lifecycle hook +op=opts.op='beforeCreate';return utils.resolve(this[op](props,opts)).then(function(_props){// Allow for re-assignment from lifecycle hook +props=_props===undefined?props:_props;// Deep pre-create belongsTo relations +var belongsToRelationData={};opts.with||(opts.with=[]);var tasks=[];utils.forEachRelation(_this3,opts,function(def,optsCopy){var relationData=def.getLocalField(props);var relatedMapper=def.getRelation();var relatedIdAttribute=relatedMapper.idAttribute;optsCopy.raw=false;if(!relationData){return;}if(def.type===belongsToType){// Create belongsTo relation first because we need a generated id to +// attach to the child +tasks.push(relatedMapper.create(relationData,optsCopy).then(function(data){def.setLocalField(belongsToRelationData,data);def.setForeignKey(props,data);}));}else if(def.type===hasManyType&&def.localKeys){// Create his hasMany relation first because it uses localKeys +tasks.push(relatedMapper.createMany(relationData,optsCopy).then(function(data){def.setLocalField(belongsToRelationData,data);utils.set(props,def.localKeys,data.map(function(record){return utils.get(record,relatedIdAttribute);}));}));}});return utils.Promise.all(tasks).then(function(){// Now delegate to the adapter for the main create +op=opts.op='create';_this3.dbg(op,props,opts);return utils.resolve(_this3.getAdapter(adapter)[op](_this3,_this3.toJSON(props,{with:opts.pass||[]}),opts));}).then(function(result){var createdRecordData=opts.raw?result.data:result;// Deep post-create hasMany and hasOne relations +tasks=[];utils.forEachRelation(_this3,opts,function(def,optsCopy){var relationData=def.getLocalField(props);if(!relationData){return;}optsCopy.raw=false;var task=void 0;// Create hasMany and hasOne after the main create because we needed +// a generated id to attach to these items +if(def.type===hasManyType&&def.foreignKey){def.setForeignKey(createdRecordData,relationData);task=def.getRelation().createMany(relationData,optsCopy).then(function(result){def.setLocalField(createdRecordData,result);});}else if(def.type===hasOneType){def.setForeignKey(createdRecordData,relationData);task=def.getRelation().create(relationData,optsCopy).then(function(result){def.setLocalField(createdRecordData,result);});}else if(def.type===belongsToType&&def.getLocalField(belongsToRelationData)){def.setLocalField(createdRecordData,def.getLocalField(belongsToRelationData));}else if(def.type===hasManyType&&def.localKeys&&def.getLocalField(belongsToRelationData)){def.setLocalField(createdRecordData,def.getLocalField(belongsToRelationData));}if(task){tasks.push(task);}});return utils.Promise.all(tasks).then(function(){utils.set(originalRecord,createdRecordData,{silent:true});if(utils.isFunction(originalRecord.commit)){originalRecord.commit();}if(opts.raw){result.data=originalRecord;}else{result=originalRecord;}return result;});});}).then(function(result){result=_this3._end(result,opts);// afterCreate lifecycle hook +op=opts.op='afterCreate';return utils.resolve(_this3[op](props,opts,result)).then(function(_result){// Allow for re-assignment from lifecycle hook +return _result===undefined?result:_result;});});},/** + * Use {@link Mapper#createRecord} instead. + * @deprecated + * @method Mapper#createInstance + * @param {Object|Array} props See {@link Mapper#createRecord}. + * @param {Object} [opts] See {@link Mapper#createRecord}. + * @returns {Object|Array} See {@link Mapper#createRecord}. + * @see Mapper#createRecord + * @since 3.0.0 + */createInstance:function createInstance(props,opts){return this.createRecord(props,opts);},/** + * Fired during {@link Mapper#createMany}. See + * {@link Mapper~beforeCreateManyListener} for how to listen for this event. + * + * @event Mapper#beforeCreateMany + * @see Mapper~beforeCreateManyListener + * @see Mapper#createMany + *//** + * Callback signature for the {@link Mapper#event:beforeCreateMany} event. + * + * @example + * function onBeforeCreateMany (records, opts) { + * // do something + * } + * store.on('beforeCreateMany', onBeforeCreateMany) + * + * @callback Mapper~beforeCreateManyListener + * @param {Object} records The `records` argument received by {@link Mapper#beforeCreateMany}. + * @param {Object} opts The `opts` argument received by {@link Mapper#beforeCreateMany}. + * @see Mapper#event:beforeCreateMany + * @see Mapper#createMany + * @since 3.0.0 + *//** + * Fired during {@link Mapper#createMany}. See + * {@link Mapper~afterCreateManyListener} for how to listen for this event. + * + * @event Mapper#afterCreateMany + * @see Mapper~afterCreateManyListener + * @see Mapper#createMany + *//** + * Callback signature for the {@link Mapper#event:afterCreateMany} event. + * + * @example + * function onAfterCreateMany (records, opts, result) { + * // do something + * } + * store.on('afterCreateMany', onAfterCreateMany) + * + * @callback Mapper~afterCreateManyListener + * @param {Object} records The `records` argument received by {@link Mapper#afterCreateMany}. + * @param {Object} opts The `opts` argument received by {@link Mapper#afterCreateMany}. + * @param {Object} result The `result` argument received by {@link Mapper#afterCreateMany}. + * @see Mapper#event:afterCreateMany + * @see Mapper#createMany + * @since 3.0.0 + *//** + * Given an array of records, batch create them via an adapter. + * + * {@link Mapper#beforeCreateMany} will be called before calling the adapter. + * {@link Mapper#afterCreateMany} will be called after calling the adapter. + * + * @example + * // Create and save several new blog posts + * PostMapper.createMany([{ + * title: 'Modeling your data', + * status: 'draft' + * }, { + * title: 'Reading data', + * status: 'draft' + * }]).then((posts) => { + * console.log(posts[0]) // { id: 1234, status: 'draft', ... } + * console.log(posts[1]) // { id: 1235, status: 'draft', ... } + * }) + * + * @fires Mapper#beforeCreate + * @fires Mapper#afterCreate + * @method Mapper#createMany + * @param {Record[]} records Array of records to be created in one batch. + * @param {Object} [opts] Configuration options. Refer to the `createMany` + * method of whatever adapter you're using for more configuration options. + * @param {boolean} [opts.adapter={@link Mapper#defaultAdapter}] Name of the + * adapter to use. + * @param {boolean} [opts.noValidate={@link Mapper#noValidate}] See {@link Mapper#noValidate}. + * @param {boolean} [opts.notify={@link Mapper#notify}] See {@link Mapper#notify}. + * @param {boolean} [opts.raw={@link Mapper#raw}] See {@link Mapper#raw}. + * @param {string[]} [opts.with=[]] Relations to create in a cascading + * create if `records` contains nested relations. NOT performed in a + * transaction. Each nested create will result in another {@link Mapper#createMany} + * call. + * @param {string[]} [opts.pass=[]] Relations to send to the adapter as part + * of the payload. Normally relations are not sent. + * @returns {Promise} Resolves with the created records. + * @since 3.0.0 + * @tutorial ["http://www.js-data.io/v3.0/docs/saving-data","Saving data"] + */createMany:function createMany(records,opts){var _this4=this;var op=void 0,adapter=void 0;// Default values for arguments +records||(records=[]);opts||(opts={});var originalRecords=records;// Fill in "opts" with the Mapper's configuration +utils._(opts,this);adapter=opts.adapter=this.getAdapterName(opts);// beforeCreateMany lifecycle hook +op=opts.op='beforeCreateMany';return utils.resolve(this[op](records,opts)).then(function(_records){// Allow for re-assignment from lifecycle hook +records=_records===undefined?records:_records;// Deep pre-create belongsTo relations +var belongsToRelationData={};opts.with||(opts.with=[]);var tasks=[];utils.forEachRelation(_this4,opts,function(def,optsCopy){var relationData=records.map(function(record){return def.getLocalField(record);}).filter(function(relatedRecord){return relatedRecord;});if(def.type===belongsToType&&relationData.length===records.length){// Create belongsTo relation first because we need a generated id to +// attach to the child +tasks.push(def.getRelation().createMany(relationData,optsCopy).then(function(data){var relatedRecords=optsCopy.raw?data.data:data;def.setLocalField(belongsToRelationData,relatedRecords);records.forEach(function(record,i){def.setForeignKey(record,relatedRecords[i]);});}));}});return utils.Promise.all(tasks).then(function(){// Now delegate to the adapter +op=opts.op='createMany';var json=records.map(function(record){return _this4.toJSON(record,{with:opts.pass||[]});});_this4.dbg(op,records,opts);return utils.resolve(_this4.getAdapter(adapter)[op](_this4,json,opts));}).then(function(result){var createdRecordsData=opts.raw?result.data:result;// Deep post-create hasOne relations +tasks=[];utils.forEachRelation(_this4,opts,function(def,optsCopy){var relationData=records.map(function(record){return def.getLocalField(record);}).filter(function(relatedRecord){return relatedRecord;});if(relationData.length!==records.length){return;}var belongsToData=def.getLocalField(belongsToRelationData);var task=void 0;// Create hasMany and hasOne after the main create because we needed +// a generated id to attach to these items +if(def.type===hasManyType){// Not supported +_this4.log('warn','deep createMany of hasMany type not supported!');}else if(def.type===hasOneType){createdRecordsData.forEach(function(createdRecordData,i){def.setForeignKey(createdRecordData,relationData[i]);});task=def.getRelation().createMany(relationData,optsCopy).then(function(result){var relatedData=opts.raw?result.data:result;createdRecordsData.forEach(function(createdRecordData,i){def.setLocalField(createdRecordData,relatedData[i]);});});}else if(def.type===belongsToType&&belongsToData&&belongsToData.length===createdRecordsData.length){createdRecordsData.forEach(function(createdRecordData,i){def.setLocalField(createdRecordData,belongsToData[i]);});}if(task){tasks.push(task);}});return utils.Promise.all(tasks).then(function(){createdRecordsData.forEach(function(createdRecordData,i){var originalRecord=originalRecords[i];utils.set(originalRecord,createdRecordData,{silent:true});if(utils.isFunction(originalRecord.commit)){originalRecord.commit();}});if(opts.raw){result.data=originalRecords;}else{result=originalRecords;}return result;});});}).then(function(result){result=_this4._end(result,opts);// afterCreateMany lifecycle hook +op=opts.op='afterCreateMany';return utils.resolve(_this4[op](records,opts,result)).then(function(_result){// Allow for re-assignment from lifecycle hook +return _result===undefined?result:_result;});});},/** + * Create an unsaved, uncached instance of this Mapper's + * {@link Mapper#recordClass}. + * + * Returns `props` if `props` is already an instance of + * {@link Mapper#recordClass}. + * + * __Note:__ This method does __not__ interact with any adapter, and does + * __not__ save any data. It only creates new objects in memory. + * + * @example + * // Create empty unsaved record instance + * const post = PostMapper.createRecord() + * + * @example + * // Create an unsaved record instance with inital properties + * const post = PostMapper.createRecord({ + * title: 'Modeling your data', + * status: 'draft' + * }) + * + * @example + * // Create a record instance that corresponds to a saved record + * const post = PostMapper.createRecord({ + * // JSData thinks this record has been saved if it has a primary key + * id: 1234, + * title: 'Modeling your data', + * status: 'draft' + * }) + * + * @example + * // Create record instances from an array + * const posts = PostMapper.createRecord([{ + * title: 'Modeling your data', + * status: 'draft' + * }, { + * title: 'Reading data', + * status: 'draft' + * }]) + * + * @example + * // Records are validated by default + * import {Mapper} from 'js-data' + * const PostMapper = new Mapper({ + * name: 'post', + * schema: { properties: { title: { type: 'string' } } } + * }) + * try { + * const post = PostMapper.createRecord({ + * title: 1234, + * }) + * } catch (err) { + * console.log(err.errors) // [{ expected: 'one of (string)', actual: 'number', path: 'title' }] + * } + * + * @example + * // Skip validation + * import {Mapper} from 'js-data' + * const PostMapper = new Mapper({ + * name: 'post', + * schema: { properties: { title: { type: 'string' } } } + * }) + * const post = PostMapper.createRecord({ + * title: 1234, + * }, { noValidate: true }) + * console.log(post.isValid()) // false + * + * @method Mapper#createRecord + * @param {Object|Object[]} props The properties for the Record instance or an + * array of property objects for the Record instances. + * @param {Object} [opts] Configuration options. + * @param {boolean} [opts.noValidate={@link Mapper#noValidate}] See {@link Mapper#noValidate}. + * @returns {Record|Record[]} The Record instance or Record instances. + * @since 3.0.0 + */createRecord:function createRecord(props,opts){var _this5=this;props||(props={});if(utils.isArray(props)){return props.map(function(_props){return _this5.createRecord(_props,opts);});}if(!utils.isObject(props)){throw utils.err(DOMAIN$4+'#createRecord','props')(400,'array or object',props);}var RecordCtor=this.recordClass;var relationList=this.relationList||[];relationList.forEach(function(def){var relatedMapper=def.getRelation();var relationData=def.getLocalField(props);if(relationData&&!relatedMapper.is(relationData)){if(utils.isArray(relationData)&&(!relationData.length||relatedMapper.is(relationData[0]))){return;}utils.set(props,def.localField,relatedMapper.createRecord(relationData,opts));}});// Check to make sure "props" is not already an instance of this Mapper. +if(RecordCtor&&!(props instanceof RecordCtor)){return new RecordCtor(props,opts);}return props;},/** + * Lifecycle invocation method. You probably won't call this method directly. + * + * @method Mapper#crud + * @param {string} method Name of the lifecycle method to invoke. + * @param {...*} args Arguments to pass to the lifecycle method. + * @returns {Promise} + * @since 3.0.0 + */crud:function crud(method){var _this6=this;for(var _len2=arguments.length,args=Array(_len2>1?_len2-1:0),_key2=1;_key2<_len2;_key2++){args[_key2-1]=arguments[_key2];}var config=this.lifecycleMethods[method];if(!config){throw utils.err(DOMAIN$4+'#crud',method)(404,'method');}var upper=''+method.charAt(0).toUpperCase()+method.substr(1);var before='before'+upper;var after='after'+upper;var op=void 0,adapter=void 0;// Default values for arguments +config.defaults.forEach(function(value,i){if(args[i]===undefined){args[i]=utils.copy(value);}});var opts=args[args.length-1];// Fill in "opts" with the Mapper's configuration +utils._(opts,this);adapter=opts.adapter=this.getAdapterName(opts);// before lifecycle hook +op=opts.op=before;return utils.resolve(this[op].apply(this,toConsumableArray(args))).then(function(_value){var _getAdapter;if(args[config.beforeAssign]!==undefined){// Allow for re-assignment from lifecycle hook +args[config.beforeAssign]=_value===undefined?args[config.beforeAssign]:_value;}// Now delegate to the adapter +op=opts.op=method;args=config.adapterArgs?config.adapterArgs.apply(config,[_this6].concat(toConsumableArray(args))):args;_this6.dbg.apply(_this6,[op].concat(toConsumableArray(args)));return utils.resolve((_getAdapter=_this6.getAdapter(adapter))[op].apply(_getAdapter,[_this6].concat(toConsumableArray(args))));}).then(function(result){result=_this6._end(result,opts,!!config.skip);args.push(result);// after lifecycle hook +op=opts.op=after;return utils.resolve(_this6[op].apply(_this6,toConsumableArray(args))).then(function(_result){// Allow for re-assignment from lifecycle hook +return _result===undefined?result:_result;});});},/** + * Fired during {@link Mapper#destroy}. See + * {@link Mapper~beforeDestroyListener} for how to listen for this event. + * + * @event Mapper#beforeDestroy + * @see Mapper~beforeDestroyListener + * @see Mapper#destroy + *//** + * Callback signature for the {@link Mapper#event:beforeDestroy} event. + * + * @example + * function onBeforeDestroy (id, opts) { + * // do something + * } + * store.on('beforeDestroy', onBeforeDestroy) + * + * @callback Mapper~beforeDestroyListener + * @param {string|number} id The `id` argument passed to {@link Mapper#beforeDestroy}. + * @param {Object} opts The `opts` argument passed to {@link Mapper#beforeDestroy}. + * @see Mapper#event:beforeDestroy + * @see Mapper#destroy + * @since 3.0.0 + *//** + * Fired during {@link Mapper#destroy}. See + * {@link Mapper~afterDestroyListener} for how to listen for this event. + * + * @event Mapper#afterDestroy + * @see Mapper~afterDestroyListener + * @see Mapper#destroy + *//** + * Callback signature for the {@link Mapper#event:afterDestroy} event. + * + * @example + * function onAfterDestroy (id, opts, result) { + * // do something + * } + * store.on('afterDestroy', onAfterDestroy) + * + * @callback Mapper~afterDestroyListener + * @param {string|number} id The `id` argument passed to {@link Mapper#afterDestroy}. + * @param {Object} opts The `opts` argument passed to {@link Mapper#afterDestroy}. + * @param {Object} result The `result` argument passed to {@link Mapper#afterDestroy}. + * @see Mapper#event:afterDestroy + * @see Mapper#destroy + * @since 3.0.0 + *//** + * Using an adapter, destroy the record with the given primary key. + * + * {@link Mapper#beforeDestroy} will be called before destroying the record. + * {@link Mapper#afterDestroy} will be called after destroying the record. + * + * @example + * // Destroy a specific blog post + * PostMapper.destroy(1234).then(() => { + * // Blog post #1234 has been destroyed + * }) + * + * @example + * // Get full response + * PostMapper.destroy(1234, { raw: true }).then((result) => { + * console.log(result.deleted) e.g. 1 + * console.log(...) // etc., more metadata can be found on the result + * }) + * + * @fires Mapper#beforeDestroy + * @fires Mapper#afterDestroy + * @method Mapper#destroy + * @param {(string|number)} id The primary key of the record to destroy. + * @param {Object} [opts] Configuration options. Refer to the `destroy` method + * of whatever adapter you're using for more configuration options. + * @param {boolean} [opts.adapter={@link Mapper#defaultAdapter}] Name of the + * adapter to use. + * @param {boolean} [opts.notify={@link Mapper#notify}] See {@link Mapper#notify}. + * @param {boolean} [opts.raw={@link Mapper#raw}] See {@link Mapper#raw}. + * @returns {Promise} Resolves when the record has been destroyed. Resolves + * even if no record was found to be destroyed. + * @since 3.0.0 + * @tutorial ["http://www.js-data.io/v3.0/docs/saving-data","Saving data"] + */destroy:function destroy(id,opts){return this.crud('destroy',id,opts);},/** + * Fired during {@link Mapper#destroyAll}. See + * {@link Mapper~beforeDestroyAllListener} for how to listen for this event. + * + * @event Mapper#beforeDestroyAll + * @see Mapper~beforeDestroyAllListener + * @see Mapper#destroyAll + *//** + * Callback signature for the {@link Mapper#event:beforeDestroyAll} event. + * + * @example + * function onBeforeDestroyAll (query, opts) { + * // do something + * } + * store.on('beforeDestroyAll', onBeforeDestroyAll) + * + * @callback Mapper~beforeDestroyAllListener + * @param {Object} query The `query` argument passed to {@link Mapper#beforeDestroyAll}. + * @param {Object} opts The `opts` argument passed to {@link Mapper#beforeDestroyAll}. + * @see Mapper#event:beforeDestroyAll + * @see Mapper#destroyAll + * @since 3.0.0 + *//** + * Fired during {@link Mapper#destroyAll}. See + * {@link Mapper~afterDestroyAllListener} for how to listen for this event. + * + * @event Mapper#afterDestroyAll + * @see Mapper~afterDestroyAllListener + * @see Mapper#destroyAll + *//** + * Callback signature for the {@link Mapper#event:afterDestroyAll} event. + * + * @example + * function onAfterDestroyAll (query, opts, result) { + * // do something + * } + * store.on('afterDestroyAll', onAfterDestroyAll) + * + * @callback Mapper~afterDestroyAllListener + * @param {Object} query The `query` argument passed to {@link Mapper#afterDestroyAll}. + * @param {Object} opts The `opts` argument passed to {@link Mapper#afterDestroyAll}. + * @param {Object} result The `result` argument passed to {@link Mapper#afterDestroyAll}. + * @see Mapper#event:afterDestroyAll + * @see Mapper#destroyAll + * @since 3.0.0 + *//** + * Destroy the records selected by `query` via an adapter. If no `query` is + * provided then all records will be destroyed. + * + * {@link Mapper#beforeDestroyAll} will be called before destroying the records. + * {@link Mapper#afterDestroyAll} will be called after destroying the records. + * + * @example + * // Destroy all blog posts + * PostMapper.destroyAll().then(() => { + * // All blog posts have been destroyed + * }) + * + * @example + * // Destroy all "draft" blog posts + * PostMapper.destroyAll({ status: 'draft' }).then(() => { + * // All "draft" blog posts have been destroyed + * }) + * + * @example + * // Get full response + * const query = null + * const options = { raw: true } + * PostMapper.destroyAll(query, options).then((result) => { + * console.log(result.deleted) e.g. 14 + * console.log(...) // etc., more metadata can be found on the result + * }) + * + * @fires Mapper#beforeDestroyAll + * @fires Mapper#afterDestroyAll + * @method Mapper#destroyAll + * @param {Object} [query={}] Selection query. See {@link query}. + * @param {Object} [query.where] See {@link query.where}. + * @param {number} [query.offset] See {@link query.offset}. + * @param {number} [query.limit] See {@link query.limit}. + * @param {string|Array[]} [query.orderBy] See {@link query.orderBy}. + * @param {Object} [opts] Configuration options. Refer to the `destroyAll` + * method of whatever adapter you're using for more configuration options. + * @param {boolean} [opts.adapter={@link Mapper#defaultAdapter}] Name of the + * adapter to use. + * @param {boolean} [opts.notify={@link Mapper#notify}] See {@link Mapper#notify}. + * @param {boolean} [opts.raw={@link Mapper#raw}] See {@link Mapper#raw}. + * @returns {Promise} Resolves when the records have been destroyed. Resolves + * even if no records were found to be destroyed. + * @see query + * @since 3.0.0 + * @tutorial ["http://www.js-data.io/v3.0/docs/saving-data","Saving data"] + */destroyAll:function destroyAll(query,opts){return this.crud('destroyAll',query,opts);},/** + * Fired during {@link Mapper#find}. See + * {@link Mapper~beforeFindListener} for how to listen for this event. + * + * @event Mapper#beforeFind + * @see Mapper~beforeFindListener + * @see Mapper#find + *//** + * Callback signature for the {@link Mapper#event:beforeFind} event. + * + * @example + * function onBeforeFind (id, opts) { + * // do something + * } + * store.on('beforeFind', onBeforeFind) + * + * @callback Mapper~beforeFindListener + * @param {string|number} id The `id` argument passed to {@link Mapper#beforeFind}. + * @param {Object} opts The `opts` argument passed to {@link Mapper#beforeFind}. + * @see Mapper#event:beforeFind + * @see Mapper#find + * @since 3.0.0 + *//** + * Fired during {@link Mapper#find}. See + * {@link Mapper~afterFindListener} for how to listen for this event. + * + * @event Mapper#afterFind + * @see Mapper~afterFindListener + * @see Mapper#find + *//** + * Callback signature for the {@link Mapper#event:afterFind} event. + * + * @example + * function onAfterFind (id, opts, result) { + * // do something + * } + * store.on('afterFind', onAfterFind) + * + * @callback Mapper~afterFindListener + * @param {string|number} id The `id` argument passed to {@link Mapper#afterFind}. + * @param {Object} opts The `opts` argument passed to {@link Mapper#afterFind}. + * @param {Object} result The `result` argument passed to {@link Mapper#afterFind}. + * @see Mapper#event:afterFind + * @see Mapper#find + * @since 3.0.0 + *//** + * Retrieve via an adapter the record with the given primary key. + * + * {@link Mapper#beforeFind} will be called before calling the adapter. + * {@link Mapper#afterFind} will be called after calling the adapter. + * + * @example + * PostMapper.find(1).then((post) => { + * console.log(post) // { id: 1, ...} + * }) + * + * @example + * // Get full response + * PostMapper.find(1, { raw: true }).then((result) => { + * console.log(result.data) // { id: 1, ...} + * console.log(result.found) // 1 + * console.log(...) // etc., more metadata can be found on the result + * }) + * + * @fires Mapper#beforeFind + * @fires Mapper#afterFind + * @method Mapper#find + * @param {(string|number)} id The primary key of the record to retrieve. + * @param {Object} [opts] Configuration options. Refer to the `find` method + * of whatever adapter you're using for more configuration options. + * @param {boolean} [opts.adapter={@link Mapper#defaultAdapter}] Name of the + * adapter to use. + * @param {boolean} [opts.notify={@link Mapper#notify}] See {@link Mapper#notify}. + * @param {boolean} [opts.raw={@link Mapper#raw}] See {@link Mapper#raw}. + * @param {string[]} [opts.with=[]] Relations to eager load in the request. + * @returns {Promise} Resolves with the found record. Resolves with + * `undefined` if no record was found. + * @see http://www.js-data.io/v3.0/docs/reading-data + * @since 3.0.0 + * @tutorial ["http://www.js-data.io/v3.0/docs/reading-data","Reading data"] + */find:function find(id,opts){return this.crud('find',id,opts);},/** + * Fired during {@link Mapper#findAll}. See + * {@link Mapper~beforeFindAllListener} for how to listen for this event. + * + * @event Mapper#beforeFindAll + * @see Mapper~beforeFindAllListener + * @see Mapper#findAll + *//** + * Callback signature for the {@link Mapper#event:beforeFindAll} event. + * + * @example + * function onBeforeFindAll (query, opts) { + * // do something + * } + * store.on('beforeFindAll', onBeforeFindAll) + * + * @callback Mapper~beforeFindAllListener + * @param {Object} query The `query` argument passed to {@link Mapper#beforeFindAll}. + * @param {Object} opts The `opts` argument passed to {@link Mapper#beforeFindAll}. + * @see Mapper#event:beforeFindAll + * @see Mapper#findAll + * @since 3.0.0 + *//** + * Fired during {@link Mapper#findAll}. See + * {@link Mapper~afterFindAllListener} for how to listen for this event. + * + * @event Mapper#afterFindAll + * @see Mapper~afterFindAllListener + * @see Mapper#findAll + *//** + * Callback signature for the {@link Mapper#event:afterFindAll} event. + * + * @example + * function onAfterFindAll (query, opts, result) { + * // do something + * } + * store.on('afterFindAll', onAfterFindAll) + * + * @callback Mapper~afterFindAllListener + * @param {Object} query The `query` argument passed to {@link Mapper#afterFindAll}. + * @param {Object} opts The `opts` argument passed to {@link Mapper#afterFindAll}. + * @param {Object} result The `result` argument passed to {@link Mapper#afterFindAll}. + * @see Mapper#event:afterFindAll + * @see Mapper#findAll + * @since 3.0.0 + *//** + * Using the `query` argument, select records to retrieve via an adapter. + * + * {@link Mapper#beforeFindAll} will be called before calling the adapter. + * {@link Mapper#afterFindAll} will be called after calling the adapter. + * + * @example + * // Find all "published" blog posts + * PostMapper.findAll({ status: 'published' }).then((posts) => { + * console.log(posts) // [{ id: 1, status: 'published', ...}, ...] + * }) + * + * @example + * // Get full response + * PostMapper.findAll({ status: 'published' }, { raw: true }).then((result) => { + * console.log(result.data) // [{ id: 1, status: 'published', ...}, ...] + * console.log(result.found) // e.g. 13 + * console.log(...) // etc., more metadata can be found on the result + * }) + * + * @fires Mapper#beforeFindAll + * @fires Mapper#afterFindAll + * @method Mapper#findAll + * @param {Object} [query={}] Selection query. See {@link query}. + * @param {Object} [query.where] See {@link query.where}. + * @param {number} [query.offset] See {@link query.offset}. + * @param {number} [query.limit] See {@link query.limit}. + * @param {string|Array[]} [query.orderBy] See {@link query.orderBy}. + * @param {Object} [opts] Configuration options. Refer to the `findAll` method + * of whatever adapter you're using for more configuration options. + * @param {boolean} [opts.adapter={@link Mapper#defaultAdapter}] Name of the + * adapter to use. + * @param {boolean} [opts.notify={@link Mapper#notify}] See {@link Mapper#notify}. + * @param {boolean} [opts.raw={@link Mapper#raw}] See {@link Mapper#raw}. + * @param {string[]} [opts.with=[]] Relations to eager load in the request. + * @returns {Promise} Resolves with the found records, if any. + * @see query + * @since 3.0.0 + * @tutorial ["http://www.js-data.io/v3.0/docs/reading-data","Reading data"] + */findAll:function findAll(query,opts){return this.crud('findAll',query,opts);},/** + * Return the registered adapter with the given name or the default adapter if + * no name is provided. + * + * @method Mapper#getAdapter + * @param {string} [name] The name of the adapter to retrieve. + * @returns {Adapter} The adapter. + * @since 3.0.0 + * @tutorial ["http://www.js-data.io/v3.0/docs/connecting-to-a-data-source","Connecting to a data source"] + */getAdapter:function getAdapter(name){this.dbg('getAdapter','name:',name);var adapter=this.getAdapterName(name);if(!adapter){throw utils.err(DOMAIN$4+'#getAdapter','name')(400,'string',name);}return this.getAdapters()[adapter];},/** + * Return the name of a registered adapter based on the given name or options, + * or the name of the default adapter if no name provided. + * + * @method Mapper#getAdapterName + * @param {(Object|string)} [opts] The name of an adapter or options, if any. + * @returns {string} The name of the adapter. + * @since 3.0.0 + * @tutorial ["http://www.js-data.io/v3.0/docs/connecting-to-a-data-source","Connecting to a data source"] + */getAdapterName:function getAdapterName(opts){opts||(opts={});if(utils.isString(opts)){opts={adapter:opts};}return opts.adapter||opts.defaultAdapter;},/** + * Get the object of registered adapters for this Mapper. + * + * @method Mapper#getAdapters + * @returns {Object} {@link Mapper#_adapters} + * @since 3.0.0 + * @tutorial ["http://www.js-data.io/v3.0/docs/connecting-to-a-data-source","Connecting to a data source"] + */getAdapters:function getAdapters(){return this._adapters;},/** + * Returns this Mapper's {@link Schema}. + * + * @method Mapper#getSchema + * @returns {Schema} This Mapper's {@link Schema}. + * @see Mapper#schema + * @since 3.0.0 + */getSchema:function getSchema(){return this.schema;},/** + * Defines a hasMany relationship. Only useful if you're managing your + * Mappers manually and not using a Container or DataStore component. + * + * @example + * UserMapper.hasMany(PostMapper, { + * // post.user_id points to user.id + * foreignKey: 'user_id' + * // post records will be attached to user records at "user.posts" + * localField: 'posts' + * }) + * + * @method Mapper#hasMany + * @see http://www.js-data.io/v3.0/docs/relations + * @since 3.0.0 + */hasMany:function hasMany$$(relatedMapper,opts){return hasMany(relatedMapper,opts)(this);},/** + * Defines a hasOne relationship. Only useful if you're managing your Mappers + * manually and not using a {@link Container} or {@link DataStore} component. + * + * @example + * UserMapper.hasOne(ProfileMapper, { + * // profile.user_id points to user.id + * foreignKey: 'user_id' + * // profile records will be attached to user records at "user.profile" + * localField: 'profile' + * }) + * + * @method Mapper#hasOne + * @see http://www.js-data.io/v3.0/docs/relations + * @since 3.0.0 + */hasOne:function hasOne$$(relatedMapper,opts){return hasOne(relatedMapper,opts)(this);},/** + * Return whether `record` is an instance of this Mapper's recordClass. + * + * @example + * const post = PostMapper.createRecord() + * + * console.log(PostMapper.is(post)) // true + * // Equivalent to what's above + * console.log(post instanceof PostMapper.recordClass) // true + * + * @method Mapper#is + * @param {Object|Record} record The record to check. + * @returns {boolean} Whether `record` is an instance of this Mapper's + * {@link Mapper#recordClass}. + * @since 3.0.0 + */is:function is(record){var recordClass=this.recordClass;return recordClass?record instanceof recordClass:false;},/** + * Register an adapter on this Mapper under the given name. + * + * @method Mapper#registerAdapter + * @param {string} name The name of the adapter to register. + * @param {Adapter} adapter The adapter to register. + * @param {Object} [opts] Configuration options. + * @param {boolean} [opts.default=false] Whether to make the adapter the + * default adapter for this Mapper. + * @since 3.0.0 + * @tutorial ["http://www.js-data.io/v3.0/docs/connecting-to-a-data-source","Connecting to a data source"] + */registerAdapter:function registerAdapter(name,adapter,opts){opts||(opts={});this.getAdapters()[name]=adapter;// Optionally make it the default adapter for the target. +if(opts===true||opts.default){this.defaultAdapter=name;}},/** + * Select records according to the `query` argument, and aggregate the sum + * value of the property specified by `field`. + * + * {@link Mapper#beforeSum} will be called before calling the adapter. + * {@link Mapper#afterSum} will be called after calling the adapter. + * + * @example + * PurchaseOrderMapper.sum('amount', { status: 'paid' }).then((amountPaid) => { + * console.log(amountPaid) // e.g. 451125.34 + * }) + * + * @method Mapper#sum + * @param {string} field The field to sum. + * @param {Object} [query={}] Selection query. See {@link query}. + * @param {Object} [query.where] See {@link query.where}. + * @param {number} [query.offset] See {@link query.offset}. + * @param {number} [query.limit] See {@link query.limit}. + * @param {string|Array[]} [query.orderBy] See {@link query.orderBy}. + * @param {Object} [opts] Configuration options. Refer to the `sum` method + * of whatever adapter you're using for more configuration options. + * @param {boolean} [opts.adapter={@link Mapper#defaultAdapter}] Name of the + * adapter to use. + * @param {boolean} [opts.notify={@link Mapper#notify}] See {@link Mapper#notify}. + * @param {boolean} [opts.raw={@link Mapper#raw}] See {@link Mapper#raw}. + * @returns {Promise} Resolves with the aggregated sum. + * @since 3.0.0 + */sum:function sum(field,query,opts){return this.crud('sum',field,query,opts);},/** + * Return a plain object representation of the given record. Relations can + * be optionally be included. Non-schema properties can be excluded. + * + * @example + * import {Mapper, Schema} from 'js-data' + * const PersonMapper = new Mapper({ + * name: 'person', + * schema: { + * properties: { + * name: { type: 'string' }, + * id: { type: 'string' } + * } + * } + * }) + * const person = PersonMapper.createRecord({ id: 1, name: 'John', foo: 'bar' }) + * console.log(PersonMapper.toJSON(person)) // {"id":1,"name":"John","foo":"bar"} + * console.log(PersonMapper.toJSON(person), { strict: true }) // {"id":1,"name":"John"} + * + * @method Mapper#toJSON + * @param {Record|Record[]} records Record or records from which to create a + * POJO representation. + * @param {Object} [opts] Configuration options. + * @param {boolean} [opts.strict] Whether to exclude properties that are not + * defined in {@link Mapper#schema}. + * @param {string[]} [opts.with] Array of relation names or relation fields + * to include in the POJO representation. + * @param {boolean} [opts.withAll] Whether to simply include all relations in + * the representation. Overrides `opts.with`. + * @returns {Object|Object[]} POJO representation of the record or records. + * @since 3.0.0 + */toJSON:function toJSON(records,opts){var _this7=this;var record=void 0;opts||(opts={});if(utils.isArray(records)){return records.map(function(record){return _this7.toJSON(record,opts);});}else{record=records;}var relationFields=(this?this.relationFields:[])||[];var json={};var properties=void 0;// Copy properties defined in the schema +if(this&&this.schema){json=this.schema.pick(record);properties=this.schema.properties;}properties||(properties={});// Optionally copy properties not defined in the schema +if(!opts.strict){for(var key in record){if(!properties[key]&&relationFields.indexOf(key)===-1){json[key]=utils.plainCopy(record[key]);}}}// The user wants to include relations in the resulting plain object representation +if(this&&opts.withAll){opts.with=relationFields.slice();}if(this&&opts.with){if(utils.isString(opts.with)){opts.with=[opts.with];}utils.forEachRelation(this,opts,function(def,optsCopy){var relationData=def.getLocalField(record);if(relationData){// The actual recursion +if(utils.isArray(relationData)){def.setLocalField(json,relationData.map(function(item){return def.getRelation().toJSON(item,optsCopy);}));}else{def.setLocalField(json,def.getRelation().toJSON(relationData,optsCopy));}}});}return json;},/** + * Fired during {@link Mapper#update}. See + * {@link Mapper~beforeUpdateListener} for how to listen for this event. + * + * @event Mapper#beforeUpdate + * @see Mapper~beforeUpdateListener + * @see Mapper#update + *//** + * Callback signature for the {@link Mapper#event:beforeUpdate} event. + * + * @example + * function onBeforeUpdate (id, props, opts) { + * // do something + * } + * store.on('beforeUpdate', onBeforeUpdate) + * + * @callback Mapper~beforeUpdateListener + * @param {string|number} id The `id` argument passed to {@link Mapper#beforeUpdate}. + * @param {Object} props The `props` argument passed to {@link Mapper#beforeUpdate}. + * @param {Object} opts The `opts` argument passed to {@link Mapper#beforeUpdate}. + * @see Mapper#event:beforeUpdate + * @see Mapper#update + * @since 3.0.0 + *//** + * Fired during {@link Mapper#update}. See + * {@link Mapper~afterUpdateListener} for how to listen for this event. + * + * @event Mapper#afterUpdate + * @see Mapper~afterUpdateListener + * @see Mapper#update + *//** + * Callback signature for the {@link Mapper#event:afterUpdate} event. + * + * @example + * function onAfterUpdate (id, props, opts, result) { + * // do something + * } + * store.on('afterUpdate', onAfterUpdate) + * + * @callback Mapper~afterUpdateListener + * @param {string|number} id The `id` argument passed to {@link Mapper#afterUpdate}. + * @param {Object} props The `props` argument passed to {@link Mapper#afterUpdate}. + * @param {Object} opts The `opts` argument passed to {@link Mapper#afterUpdate}. + * @param {Object} result The `result` argument passed to {@link Mapper#afterUpdate}. + * @see Mapper#event:afterUpdate + * @see Mapper#update + * @since 3.0.0 + *//** + * Using an adapter, update the record with the primary key specified by the + * `id` argument. + * + * {@link Mapper#beforeUpdate} will be called before updating the record. + * {@link Mapper#afterUpdate} will be called after updating the record. + * + * @example + * // Update a specific post + * PostMapper.update(1234, { + * status: 'published', + * published_at: new Date() + * }).then((post) => { + * console.log(post) // { id: 1234, status: 'published', ... } + * }) + * + * @fires Mapper#beforeUpdate + * @fires Mapper#afterUpdate + * @method Mapper#update + * @param {(string|number)} id The primary key of the record to update. + * @param {Object} props The update to apply to the record. + * @param {Object} [opts] Configuration options. Refer to the `update` method + * of whatever adapter you're using for more configuration options. + * @param {boolean} [opts.adapter={@link Mapper#defaultAdapter}] Name of the + * adapter to use. + * @param {boolean} [opts.notify={@link Mapper#notify}] See {@link Mapper#notify}. + * @param {boolean} [opts.noValidate={@link Mapper#noValidate}] See {@link Mapper#noValidate}. + * @param {boolean} [opts.raw={@link Mapper#raw}] See {@link Mapper#raw}. + * transaction. + * @returns {Promise} Resolves with the updated record. Rejects if the record + * could not be found. + * @since 3.0.0 + * @tutorial ["http://www.js-data.io/v3.0/docs/saving-data","Saving data"] + */update:function update(id,props,opts){return this.crud('update',id,props,opts);},/** + * Fired during {@link Mapper#updateAll}. See + * {@link Mapper~beforeUpdateAllListener} for how to listen for this event. + * + * @event Mapper#beforeUpdateAll + * @see Mapper~beforeUpdateAllListener + * @see Mapper#updateAll + *//** + * Callback signature for the {@link Mapper#event:beforeUpdateAll} event. + * + * @example + * function onBeforeUpdateAll (props, query, opts) { + * // do something + * } + * store.on('beforeUpdateAll', onBeforeUpdateAll) + * + * @callback Mapper~beforeUpdateAllListener + * @param {Object} props The `props` argument received by {@link Mapper#beforeUpdateAll}. + * @param {Object} query The `query` argument received by {@link Mapper#beforeUpdateAll}. + * @param {Object} opts The `opts` argument received by {@link Mapper#beforeUpdateAll}. + * @see Mapper#event:beforeUpdateAll + * @see Mapper#updateAll + * @since 3.0.0 + *//** + * Fired during {@link Mapper#updateAll}. See + * {@link Mapper~afterUpdateAllListener} for how to listen for this event. + * + * @event Mapper#afterUpdateAll + * @see Mapper~afterUpdateAllListener + * @see Mapper#updateAll + *//** + * Callback signature for the {@link Mapper#event:afterUpdateAll} event. + * + * @example + * function onAfterUpdateAll (props, query, opts, result) { + * // do something + * } + * store.on('afterUpdateAll', onAfterUpdateAll) + * + * @callback Mapper~afterUpdateAllListener + * @param {Object} props The `props` argument received by {@link Mapper#afterUpdateAll}. + * @param {Object} query The `query` argument received by {@link Mapper#afterUpdateAll}. + * @param {Object} opts The `opts` argument received by {@link Mapper#afterUpdateAll}. + * @param {Object} result The `result` argument received by {@link Mapper#afterUpdateAll}. + * @see Mapper#event:afterUpdateAll + * @see Mapper#updateAll + * @since 3.0.0 + *//** + * Using the `query` argument, perform the a single updated to the selected + * records. + * + * {@link Mapper#beforeUpdateAll} will be called before making the update. + * {@link Mapper#afterUpdateAll} will be called after making the update. + * + * @example + * // Turn all of John's blog posts into drafts. + * const update = { status: draft: published_at: null } + * const query = { userId: 1234 } + * PostMapper.updateAll(update, query).then((posts) => { + * console.log(posts) // [...] + * }) + * + * @fires Mapper#beforeUpdateAll + * @fires Mapper#afterUpdateAll + * @method Mapper#updateAll + * @param {Object} props Update to apply to selected records. + * @param {Object} [query={}] Selection query. See {@link query}. + * @param {Object} [query.where] See {@link query.where}. + * @param {number} [query.offset] See {@link query.offset}. + * @param {number} [query.limit] See {@link query.limit}. + * @param {string|Array[]} [query.orderBy] See {@link query.orderBy}. + * @param {Object} [opts] Configuration options. Refer to the `updateAll` + * method of whatever adapter you're using for more configuration options. + * @param {boolean} [opts.adapter={@link Mapper#defaultAdapter}] Name of the + * adapter to use. + * @param {boolean} [opts.notify={@link Mapper#notify}] See {@link Mapper#notify}. + * @param {boolean} [opts.noValidate={@link Mapper#noValidate}] See {@link Mapper#noValidate}. + * @param {boolean} [opts.raw={@link Mapper#raw}] See {@link Mapper#raw}. + * @returns {Promise} Resolves with the update records, if any. + * @see query + * @since 3.0.0 + * @tutorial ["http://www.js-data.io/v3.0/docs/saving-data","Saving data"] + */updateAll:function updateAll(props,query,opts){return this.crud('updateAll',props,query,opts);},/** + * Fired during {@link Mapper#updateMany}. See + * {@link Mapper~beforeUpdateManyListener} for how to listen for this event. + * + * @event Mapper#beforeUpdateMany + * @see Mapper~beforeUpdateManyListener + * @see Mapper#updateMany + *//** + * Callback signature for the {@link Mapper#event:beforeUpdateMany} event. + * + * @example + * function onBeforeUpdateMany (records, opts) { + * // do something + * } + * store.on('beforeUpdateMany', onBeforeUpdateMany) + * + * @callback Mapper~beforeUpdateManyListener + * @param {Object} records The `records` argument received by {@link Mapper#beforeUpdateMany}. + * @param {Object} opts The `opts` argument received by {@link Mapper#beforeUpdateMany}. + * @see Mapper#event:beforeUpdateMany + * @see Mapper#updateMany + * @since 3.0.0 + *//** + * Fired during {@link Mapper#updateMany}. See + * {@link Mapper~afterUpdateManyListener} for how to listen for this event. + * + * @event Mapper#afterUpdateMany + * @see Mapper~afterUpdateManyListener + * @see Mapper#updateMany + *//** + * Callback signature for the {@link Mapper#event:afterUpdateMany} event. + * + * @example + * function onAfterUpdateMany (records, opts, result) { + * // do something + * } + * store.on('afterUpdateMany', onAfterUpdateMany) + * + * @callback Mapper~afterUpdateManyListener + * @param {Object} records The `records` argument received by {@link Mapper#afterUpdateMany}. + * @param {Object} opts The `opts` argument received by {@link Mapper#afterUpdateMany}. + * @param {Object} result The `result` argument received by {@link Mapper#afterUpdateMany}. + * @see Mapper#event:afterUpdateMany + * @see Mapper#updateMany + * @since 3.0.0 + *//** + * Given an array of updates, perform each of the updates via an adapter. Each + * "update" is a hash of properties with which to update an record. Each + * update must contain the primary key of the record to be updated. + * + * {@link Mapper#beforeUpdateMany} will be called before making the update. + * {@link Mapper#afterUpdateMany} will be called after making the update. + * + * @example + * PostMapper.updateMany([ + * { id: 1234, status: 'draft' }, + * { id: 2468, status: 'published', published_at: new Date() } + * ]).then((posts) => { + * console.log(posts) // [...] + * }) + * + * @fires Mapper#beforeUpdateMany + * @fires Mapper#afterUpdateMany + * @method Mapper#updateMany + * @param {Record[]} records Array up record updates. + * @param {Object} [opts] Configuration options. Refer to the `updateMany` + * method of whatever adapter you're using for more configuration options. + * @param {boolean} [opts.adapter={@link Mapper#defaultAdapter}] Name of the + * adapter to use. + * @param {boolean} [opts.notify={@link Mapper#notify}] See {@link Mapper#notify}. + * @param {boolean} [opts.noValidate={@link Mapper#noValidate}] See {@link Mapper#noValidate}. + * @param {boolean} [opts.raw={@link Mapper#raw}] See {@link Mapper#raw}. + * @returns {Promise} Resolves with the updated records. Rejects if any of the + * records could be found. + * @since 3.0.0 + * @tutorial ["http://www.js-data.io/v3.0/docs/saving-data","Saving data"] + */updateMany:function updateMany(records,opts){return this.crud('updateMany',records,opts);},/** + * Validate the given record or records according to this Mapper's + * {@link Schema}. If there are no validation errors then the return value + * will be `undefined`. + * + * @example + * import {Mapper, Schema} from 'js-data' + * const PersonSchema = new Schema({ + * properties: { + * name: { type: 'string' }, + * id: { type: 'string' } + * } + * }) + * const PersonMapper = new Mapper({ + * name: 'person', + * schema: PersonSchema + * }) + * let errors = PersonMapper.validate({ name: 'John' }) + * console.log(errors) // undefined + * errors = PersonMapper.validate({ name: 123 }) + * console.log(errors) // [{ expected: 'one of (string)', actual: 'number', path: 'name' }] + * + * @method Mapper#validate + * @param {Object|Object[]} record The record or records to validate. + * @param {Object} [opts] Configuration options. Passed to + * {@link Schema#validate}. + * @returns {Object[]} Array of errors or `undefined` if no errors. + * @since 3.0.0 + */validate:function validate(record,opts){opts||(opts={});var schema=this.getSchema();var _opts=utils.pick(opts,['existingOnly']);if(utils.isArray(record)){var errors=record.map(function(_record){return schema.validate(_record,utils.pick(_opts,['existingOnly']));});var hasErrors=false;errors.forEach(function(err){if(err){hasErrors=true;}});if(hasErrors){return errors;}return undefined;}return schema.validate(record,_opts);},/** + * Method used to wrap data returned by an adapter with this Mapper's + * {@link Mapper#recordClass}. This method is used by all of a Mapper's CRUD + * methods. The provided implementation of this method assumes that the `data` + * passed to it is a record or records that need to be wrapped with + * {@link Mapper#createRecord}. Override with care. + * + * Provided implementation of {@link Mapper#wrap}: + * + * ``` + * function (data, opts) { + * return this.createRecord(data, opts) + * } + * ``` + * + * @example + * const PostMapper = new Mapper({ + * name: 'post', + * // Override to customize behavior + * wrap (data, opts) { + * const originalWrap = this.constructor.prototype.wrap + * // Let's say "GET /post" doesn't return JSON quite like JSData expects, + * // but the actual post records are nested under a "posts" field. So, + * // we override Mapper#wrap to handle this special case. + * if (opts.op === 'findAll') { + * return originalWrap.call(this, data.posts, opts) + * } + * // Otherwise perform original behavior + * return originalWrap.call(this, data, opts) + * } + * }) + * + * @method Mapper#wrap + * @param {Object|Object[]} data The record or records to be wrapped. + * @param {Object} [opts] Configuration options. Passed to {@link Mapper#createRecord}. + * @returns {Record|Record[]} The wrapped record or records. + * @since 3.0.0 + */wrap:function wrap(data,opts){return this.createRecord(data,opts);},/** + * @ignore + */defineRelations:function defineRelations(){var _this8=this;// Setup the mapper's relations, including generating Mapper#relationList +// and Mapper#relationFields +utils.forOwn(this.relations,function(group,type){utils.forOwn(group,function(relations,_name){if(utils.isObject(relations)){relations=[relations];}relations.forEach(function(def){var relatedMapper=_this8.datastore.getMapperByName(_name)||_name;def.getRelation=function(){return _this8.datastore.getMapper(_name);};if(typeof Relation[type]!=='function'){throw utils.err(DOMAIN$4,'defineRelations')(400,'relation type (hasOne, hasMany, etc)',type,true);}_this8[type](relatedMapper,def);});});});}});/** + * Create a subclass of this Mapper: + * + * @example Mapper.extend + * // Normally you would do: import {Mapper} from 'js-data' + * const JSData = require('js-data@3.0.0-rc.4') + * const {Mapper} = JSData + * console.log('Using JSData v' + JSData.version.full) + * + * // Extend the class using ES2015 class syntax. + * class CustomMapperClass extends Mapper { + * foo () { return 'bar' } + * static beep () { return 'boop' } + * } + * const customMapper = new CustomMapperClass() + * console.log(customMapper.foo()) + * console.log(CustomMapperClass.beep()) + * + * // Extend the class using alternate method. + * const OtherMapperClass = Mapper.extend({ + * foo () { return 'bar' } + * }, { + * beep () { return 'boop' } + * }) + * const otherMapper = new OtherMapperClass() + * console.log(otherMapper.foo()) + * console.log(OtherMapperClass.beep()) + * + * // Extend the class, providing a custom constructor. + * function AnotherMapperClass () { + * Mapper.call(this) + * this.created_at = new Date().getTime() + * } + * Mapper.extend({ + * constructor: AnotherMapperClass, + * foo () { return 'bar' } + * }, { + * beep () { return 'boop' } + * }) + * const anotherMapper = new AnotherMapperClass() + * console.log(anotherMapper.created_at) + * console.log(anotherMapper.foo()) + * console.log(AnotherMapperClass.beep()) + * + * @method Mapper.extend + * @param {Object} [props={}] Properties to add to the prototype of the + * subclass. + * @param {Object} [props.constructor] Provide a custom constructor function + * to be used as the subclass itself. + * @param {Object} [classProps={}] Static properties to add to the subclass. + * @returns {Constructor} Subclass of this Mapper class. + * @since 3.0.0 + */var DOMAIN$3='Container';var proxiedMapperMethods=[/** + * Wrapper for {@link Mapper#count}. + * + * @example + * // Get the number of published blog posts + * import {Container} from 'js-data' + * import RethinkDBAdapter from 'js-data-rethinkdb' + * const store = new Container() + * store.registerAdapter('rethinkdb', new RethinkDBAdapter(), { default: true }) + * store.defineMapper('post') + * + * store.count('post', { status: 'published' }).then((numPublished) => { + * console.log(numPublished) // e.g. 45 + * }) + * + * @method Container#count + * @param {string} name Name of the {@link Mapper} to target. + * @param {Object} [query] See {@link Mapper#count}. + * @param {Object} [opts] See {@link Mapper#count}. + * @returns {Promise} See {@link Mapper#count}. + * @see Mapper#count + * @since 3.0.0 + */'count',/** + * Fired during {@link Container#create}. See + * {@link Container~beforeCreateListener} for how to listen for this event. + * + * @event Container#beforeCreate + * @see Container~beforeCreateListener + * @see Container#create + *//** + * Callback signature for the {@link Container#event:beforeCreate} event. + * + * @example + * function onBeforeCreate (mapperName, props, opts) { + * // do something + * } + * store.on('beforeCreate', onBeforeCreate) + * + * @callback Container~beforeCreateListener + * @param {string} name The `name` argument received by {@link Mapper#beforeCreate}. + * @param {Object} props The `props` argument received by {@link Mapper#beforeCreate}. + * @param {Object} opts The `opts` argument received by {@link Mapper#beforeCreate}. + * @see Container#event:beforeCreate + * @see Container#create + * @since 3.0.0 + *//** + * Fired during {@link Container#create}. See + * {@link Container~afterCreateListener} for how to listen for this event. + * + * @event Container#afterCreate + * @see Container~afterCreateListener + * @see Container#create + *//** + * Callback signature for the {@link Container#event:afterCreate} event. + * + * @example + * function onAfterCreate (mapperName, props, opts, result) { + * // do something + * } + * store.on('afterCreate', onAfterCreate) + * + * @callback Container~afterCreateListener + * @param {string} name The `name` argument received by {@link Mapper#afterCreate}. + * @param {Object} props The `props` argument received by {@link Mapper#afterCreate}. + * @param {Object} opts The `opts` argument received by {@link Mapper#afterCreate}. + * @param {Object} result The `result` argument received by {@link Mapper#afterCreate}. + * @see Container#event:afterCreate + * @see Container#create + * @since 3.0.0 + *//** + * Wrapper for {@link Mapper#create}. + * + * @example + * // Create and save a new blog post + * import {Container} from 'js-data' + * import RethinkDBAdapter from 'js-data-rethinkdb' + * const store = new Container() + * store.registerAdapter('rethinkdb', new RethinkDBAdapter(), { default: true }) + * store.defineMapper('post') + * + * store.create('post', { + * title: 'Modeling your data', + * status: 'draft' + * }).then((post) => { + * console.log(post) // { id: 1234, status: 'draft', ... } + * }) + * + * @fires Container#beforeCreate + * @fires Container#afterCreate + * @method Container#create + * @param {string} name Name of the {@link Mapper} to target. + * @param {Object} props See {@link Mapper#create}. + * @param {Object} [opts] See {@link Mapper#create}. + * @returns {Promise} See {@link Mapper#create}. + * @see Mapper#create + * @since 3.0.0 + */'create',/** + * Fired during {@link Container#createMany}. See + * {@link Container~beforeCreateManyListener} for how to listen for this event. + * + * @event Container#beforeCreateMany + * @see Container~beforeCreateManyListener + * @see Container#createMany + *//** + * Callback signature for the {@link Container#event:beforeCreateMany} event. + * + * @example + * function onBeforeCreateMany (mapperName, records, opts) { + * // do something + * } + * store.on('beforeCreateMany', onBeforeCreateMany) + * + * @callback Container~beforeCreateManyListener + * @param {string} name The `name` argument received by {@link Mapper#beforeCreateMany}. + * @param {Object} records The `records` argument received by {@link Mapper#beforeCreateMany}. + * @param {Object} opts The `opts` argument received by {@link Mapper#beforeCreateMany}. + * @see Container#event:beforeCreateMany + * @see Container#createMany + * @since 3.0.0 + *//** + * Fired during {@link Container#createMany}. See + * {@link Container~afterCreateManyListener} for how to listen for this event. + * + * @event Container#afterCreateMany + * @see Container~afterCreateManyListener + * @see Container#createMany + *//** + * Callback signature for the {@link Container#event:afterCreateMany} event. + * + * @example + * function onAfterCreateMany (mapperName, records, opts, result) { + * // do something + * } + * store.on('afterCreateMany', onAfterCreateMany) + * + * @callback Container~afterCreateManyListener + * @param {string} name The `name` argument received by {@link Mapper#afterCreateMany}. + * @param {Object} records The `records` argument received by {@link Mapper#afterCreateMany}. + * @param {Object} opts The `opts` argument received by {@link Mapper#afterCreateMany}. + * @param {Object} result The `result` argument received by {@link Mapper#afterCreateMany}. + * @see Container#event:afterCreateMany + * @see Container#createMany + * @since 3.0.0 + *//** + * Wrapper for {@link Mapper#createMany}. + * + * @example + * // Create and save several new blog posts + * import {Container} from 'js-data' + * import RethinkDBAdapter from 'js-data-rethinkdb' + * const store = new Container() + * store.registerAdapter('rethinkdb', new RethinkDBAdapter(), { default: true }) + * store.defineMapper('post') + * + * store.createMany('post', [{ + * title: 'Modeling your data', + * status: 'draft' + * }, { + * title: 'Reading data', + * status: 'draft' + * }]).then((posts) => { + * console.log(posts[0]) // { id: 1234, status: 'draft', ... } + * console.log(posts[1]) // { id: 1235, status: 'draft', ... } + * }) + * + * @fires Container#beforeCreateMany + * @fires Container#afterCreateMany + * @method Container#createMany + * @param {string} name Name of the {@link Mapper} to target. + * @param {Record[]} records See {@link Mapper#createMany}. + * @param {Object} [opts] See {@link Mapper#createMany}. + * @returns {Promise} See {@link Mapper#createMany}. + * @see Mapper#createMany + * @since 3.0.0 + */'createMany',/** + * Wrapper for {@link Mapper#createRecord}. + * + * __Note:__ This method does __not__ interact with any adapter, and does + * __not__ save any data. It only creates new objects in memory. + * + * @example + * // Create empty unsaved record instance + * import {Container} from 'js-data' + * const store = new Container() + * store.defineMapper('post') + * const post = PostMapper.createRecord() + * + * @method Container#createRecord + * @param {string} name Name of the {@link Mapper} to target. + * @param {Object|Object[]} props See {@link Mapper#createRecord}. + * @param {Object} [opts] See {@link Mapper#createRecord}. + * @returns {Promise} See {@link Mapper#createRecord}. + * @see Mapper#createRecord + * @since 3.0.0 + */'createRecord',/** + * Fired during {@link Container#destroy}. See + * {@link Container~beforeDestroyListener} for how to listen for this event. + * + * @event Container#beforeDestroy + * @see Container~beforeDestroyListener + * @see Container#destroy + *//** + * Callback signature for the {@link Container#event:beforeDestroy} event. + * + * @example + * function onBeforeDestroy (mapperName, id, opts) { + * // do something + * } + * store.on('beforeDestroy', onBeforeDestroy) + * + * @callback Container~beforeDestroyListener + * @param {string} name The `name` argument received by {@link Mapper#beforeDestroy}. + * @param {string|number} id The `id` argument received by {@link Mapper#beforeDestroy}. + * @param {Object} opts The `opts` argument received by {@link Mapper#beforeDestroy}. + * @see Container#event:beforeDestroy + * @see Container#destroy + * @since 3.0.0 + *//** + * Fired during {@link Container#destroy}. See + * {@link Container~afterDestroyListener} for how to listen for this event. + * + * @event Container#afterDestroy + * @see Container~afterDestroyListener + * @see Container#destroy + *//** + * Callback signature for the {@link Container#event:afterDestroy} event. + * + * @example + * function onAfterDestroy (mapperName, id, opts, result) { + * // do something + * } + * store.on('afterDestroy', onAfterDestroy) + * + * @callback Container~afterDestroyListener + * @param {string} name The `name` argument received by {@link Mapper#afterDestroy}. + * @param {string|number} id The `id` argument received by {@link Mapper#afterDestroy}. + * @param {Object} opts The `opts` argument received by {@link Mapper#afterDestroy}. + * @param {Object} result The `result` argument received by {@link Mapper#afterDestroy}. + * @see Container#event:afterDestroy + * @see Container#destroy + * @since 3.0.0 + *//** + * Wrapper for {@link Mapper#destroy}. + * + * @example + * // Destroy a specific blog post + * import {Container} from 'js-data' + * import RethinkDBAdapter from 'js-data-rethinkdb' + * const store = new Container() + * store.registerAdapter('rethinkdb', new RethinkDBAdapter(), { default: true }) + * store.defineMapper('post') + * + * store.destroy('post', 1234).then(() => { + * // Blog post #1234 has been destroyed + * }) + * + * @fires Container#beforeDestroy + * @fires Container#afterDestroy + * @method Container#destroy + * @param {string} name Name of the {@link Mapper} to target. + * @param {(string|number)} id See {@link Mapper#destroy}. + * @param {Object} [opts] See {@link Mapper#destroy}. + * @returns {Promise} See {@link Mapper#destroy}. + * @see Mapper#destroy + * @since 3.0.0 + */'destroy',/** + * Fired during {@link Container#destroyAll}. See + * {@link Container~beforeDestroyAllListener} for how to listen for this event. + * + * @event Container#beforeDestroyAll + * @see Container~beforeDestroyAllListener + * @see Container#destroyAll + *//** + * Callback signature for the {@link Container#event:beforeDestroyAll} event. + * + * @example + * function onBeforeDestroyAll (mapperName, query, opts) { + * // do something + * } + * store.on('beforeDestroyAll', onBeforeDestroyAll) + * + * @callback Container~beforeDestroyAllListener + * @param {string} name The `name` argument received by {@link Mapper#beforeDestroyAll}. + * @param {Object} query The `query` argument received by {@link Mapper#beforeDestroyAll}. + * @param {Object} opts The `opts` argument received by {@link Mapper#beforeDestroyAll}. + * @see Container#event:beforeDestroyAll + * @see Container#destroyAll + * @since 3.0.0 + *//** + * Fired during {@link Container#destroyAll}. See + * {@link Container~afterDestroyAllListener} for how to listen for this event. + * + * @event Container#afterDestroyAll + * @see Container~afterDestroyAllListener + * @see Container#destroyAll + *//** + * Callback signature for the {@link Container#event:afterDestroyAll} event. + * + * @example + * function onAfterDestroyAll (mapperName, query, opts, result) { + * // do something + * } + * store.on('afterDestroyAll', onAfterDestroyAll) + * + * @callback Container~afterDestroyAllListener + * @param {string} name The `name` argument received by {@link Mapper#afterDestroyAll}. + * @param {Object} query The `query` argument received by {@link Mapper#afterDestroyAll}. + * @param {Object} opts The `opts` argument received by {@link Mapper#afterDestroyAll}. + * @param {Object} result The `result` argument received by {@link Mapper#afterDestroyAll}. + * @see Container#event:afterDestroyAll + * @see Container#destroyAll + * @since 3.0.0 + *//** + * Wrapper for {@link Mapper#destroyAll}. + * + * @example + * // Destroy all "draft" blog posts + * import {Container} from 'js-data' + * import RethinkDBAdapter from 'js-data-rethinkdb' + * const store = new Container() + * store.registerAdapter('rethinkdb', new RethinkDBAdapter(), { default: true }) + * store.defineMapper('post') + * + * store.destroyAll('post', { status: 'draft' }).then(() => { + * // All "draft" blog posts have been destroyed + * }) + * + * @fires Container#beforeDestroyAll + * @fires Container#afterDestroyAll + * @method Container#destroyAll + * @param {string} name Name of the {@link Mapper} to target. + * @param {Object} [query] See {@link Mapper#destroyAll}. + * @param {Object} [opts] See {@link Mapper#destroyAll}. + * @returns {Promise} See {@link Mapper#destroyAll}. + * @see Mapper#destroyAll + * @since 3.0.0 + */'destroyAll',/** + * Fired during {@link Container#find}. See + * {@link Container~beforeFindListener} for how to listen for this event. + * + * @event Container#beforeFind + * @see Container~beforeFindListener + * @see Container#find + *//** + * Callback signature for the {@link Container#event:beforeFind} event. + * + * @example + * function onBeforeFind (mapperName, id, opts) { + * // do something + * } + * store.on('beforeFind', onBeforeFind) + * + * @callback Container~beforeFindListener + * @param {string} name The `name` argument received by {@link Mapper#beforeFind}. + * @param {string|number} id The `id` argument received by {@link Mapper#beforeFind}. + * @param {Object} opts The `opts` argument received by {@link Mapper#beforeFind}. + * @see Container#event:beforeFind + * @see Container#find + * @since 3.0.0 + *//** + * Fired during {@link Container#find}. See + * {@link Container~afterFindListener} for how to listen for this event. + * + * @event Container#afterFind + * @see Container~afterFindListener + * @see Container#find + *//** + * Callback signature for the {@link Container#event:afterFind} event. + * + * @example + * function onAfterFind (mapperName, id, opts, result) { + * // do something + * } + * store.on('afterFind', onAfterFind) + * + * @callback Container~afterFindListener + * @param {string} name The `name` argument received by {@link Mapper#afterFind}. + * @param {string|number} id The `id` argument received by {@link Mapper#afterFind}. + * @param {Object} opts The `opts` argument received by {@link Mapper#afterFind}. + * @param {Object} result The `result` argument received by {@link Mapper#afterFind}. + * @see Container#event:afterFind + * @see Container#find + * @since 3.0.0 + *//** + * Wrapper for {@link Mapper#find}. + * + * @example + * import {Container} from 'js-data' + * import RethinkDBAdapter from 'js-data-rethinkdb' + * const store = new Container() + * store.registerAdapter('rethinkdb', new RethinkDBAdapter(), { default: true }) + * store.defineMapper('post') + * + * store.find('post', 1).then((post) => { + * console.log(post) // { id: 1, ...} + * }) + * + * @fires Container#beforeFind + * @fires Container#afterFind + * @method Container#find + * @param {string} name Name of the {@link Mapper} to target. + * @param {(string|number)} id See {@link Mapper#find}. + * @param {Object} [opts] See {@link Mapper#find}. + * @returns {Promise} See {@link Mapper#find}. + * @see Mapper#find + * @since 3.0.0 + */'find',/** + * Fired during {@link Container#findAll}. See + * {@link Container~beforeFindAllListener} for how to listen for this event. + * + * @event Container#beforeFindAll + * @see Container~beforeFindAllListener + * @see Container#findAll + *//** + * Callback signature for the {@link Container#event:beforeFindAll} event. + * + * @example + * function onBeforeFindAll (mapperName, query, opts) { + * // do something + * } + * store.on('beforeFindAll', onBeforeFindAll) + * + * @callback Container~beforeFindAllListener + * @param {string} name The `name` argument received by {@link Mapper#beforeFindAll}. + * @param {Object} query The `query` argument received by {@link Mapper#beforeFindAll}. + * @param {Object} opts The `opts` argument received by {@link Mapper#beforeFindAll}. + * @see Container#event:beforeFindAll + * @see Container#findAll + * @since 3.0.0 + *//** + * Fired during {@link Container#findAll}. See + * {@link Container~afterFindAllListener} for how to listen for this event. + * + * @event Container#afterFindAll + * @see Container~afterFindAllListener + * @see Container#findAll + *//** + * Callback signature for the {@link Container#event:afterFindAll} event. + * + * @example + * function onAfterFindAll (mapperName, query, opts, result) { + * // do something + * } + * store.on('afterFindAll', onAfterFindAll) + * + * @callback Container~afterFindAllListener + * @param {string} name The `name` argument received by {@link Mapper#afterFindAll}. + * @param {Object} query The `query` argument received by {@link Mapper#afterFindAll}. + * @param {Object} opts The `opts` argument received by {@link Mapper#afterFindAll}. + * @param {Object} result The `result` argument received by {@link Mapper#afterFindAll}. + * @see Container#event:afterFindAll + * @see Container#findAll + * @since 3.0.0 + *//** + * Wrapper for {@link Mapper#createRecord}. + * + * @example + * // Find all "published" blog posts + * import {Container} from 'js-data' + * import RethinkDBAdapter from 'js-data-rethinkdb' + * const store = new Container() + * store.registerAdapter('rethinkdb', new RethinkDBAdapter(), { default: true }) + * store.defineMapper('post') + * + * store.findAll('post', { status: 'published' }).then((posts) => { + * console.log(posts) // [{ id: 1, ...}, ...] + * }) + * + * @fires Container#beforeFindAll + * @fires Container#afterFindAll + * @method Container#findAll + * @param {string} name Name of the {@link Mapper} to target. + * @param {Object} [query] See {@link Mapper#findAll}. + * @param {Object} [opts] See {@link Mapper#findAll}. + * @returns {Promise} See {@link Mapper#findAll}. + * @see Mapper#findAll + * @since 3.0.0 + */'findAll',/** + * Wrapper for {@link Mapper#getSchema}. + * + * @method Container#getSchema + * @param {string} name Name of the {@link Mapper} to target. + * @returns {Schema} See {@link Mapper#getSchema}. + * @see Mapper#getSchema + * @since 3.0.0 + */'getSchema',/** + * Wrapper for {@link Mapper#is}. + * + * @example + * import {Container} from 'js-data' + * const store = new Container() + * store.defineMapper('post') + * const post = store.createRecord() + * + * console.log(store.is('post', post)) // true + * // Equivalent to what's above + * console.log(post instanceof store.getMapper('post').recordClass) // true + * + * @method Container#is + * @param {string} name Name of the {@link Mapper} to target. + * @param {Object|Record} record See {@link Mapper#is}. + * @returns {boolean} See {@link Mapper#is}. + * @see Mapper#is + * @since 3.0.0 + */'is',/** + * Wrapper for {@link Mapper#sum}. + * + * @example + * import {Container} from 'js-data' + * import RethinkDBAdapter from 'js-data-rethinkdb' + * const store = new Container() + * store.registerAdapter('rethinkdb', new RethinkDBAdapter(), { default: true }) + * store.defineMapper('purchase_order') + * + * store.sum('purchase_order', 'amount', { status: 'paid' }).then((amountPaid) => { + * console.log(amountPaid) // e.g. 451125.34 + * }) + * + * @method Container#sum + * @param {string} name Name of the {@link Mapper} to target. + * @param {string} field See {@link Mapper#sum}. + * @param {Object} [query] See {@link Mapper#sum}. + * @param {Object} [opts] See {@link Mapper#sum}. + * @returns {Promise} See {@link Mapper#sum}. + * @see Mapper#sum + * @since 3.0.0 + */'sum',/** + * Wrapper for {@link Mapper#toJSON}. + * + * @example + * import {Container} from 'js-data' + * import RethinkDBAdapter from 'js-data-rethinkdb' + * const store = new Container() + * store.registerAdapter('rethinkdb', new RethinkDBAdapter(), { default: true }) + * store.defineMapper('person', { + * schema: { + * properties: { + * name: { type: 'string' }, + * id: { type: 'string' } + * } + * } + * }) + * const person = store.createRecord('person', { id: 1, name: 'John', foo: 'bar' }) + * console.log(store.toJSON('person', person)) // {"id":1,"name":"John","foo":"bar"} + * console.log(store.toJSON('person', person), { strict: true }) // {"id":1,"name":"John"} + * + * @method Container#toJSON + * @param {string} name Name of the {@link Mapper} to target. + * @param {Record|Record[]} records See {@link Mapper#toJSON}. + * @param {Object} [opts] See {@link Mapper#toJSON}. + * @returns {Object|Object[]} See {@link Mapper#toJSON}. + * @see Mapper#toJSON + * @since 3.0.0 + */'toJSON',/** + * Fired during {@link Container#update}. See + * {@link Container~beforeUpdateListener} for how to listen for this event. + * + * @event Container#beforeUpdate + * @see Container~beforeUpdateListener + * @see Container#update + *//** + * Callback signature for the {@link Container#event:beforeUpdate} event. + * + * @example + * function onBeforeUpdate (mapperName, id, props, opts) { + * // do something + * } + * store.on('beforeUpdate', onBeforeUpdate) + * + * @callback Container~beforeUpdateListener + * @param {string} name The `name` argument received by {@link Mapper#beforeUpdate}. + * @param {string|number} id The `id` argument received by {@link Mapper#beforeUpdate}. + * @param {Object} props The `props` argument received by {@link Mapper#beforeUpdate}. + * @param {Object} opts The `opts` argument received by {@link Mapper#beforeUpdate}. + * @see Container#event:beforeUpdate + * @see Container#update + * @since 3.0.0 + *//** + * Fired during {@link Container#update}. See + * {@link Container~afterUpdateListener} for how to listen for this event. + * + * @event Container#afterUpdate + * @see Container~afterUpdateListener + * @see Container#update + *//** + * Callback signature for the {@link Container#event:afterUpdate} event. + * + * @example + * function onAfterUpdate (mapperName, id, props, opts, result) { + * // do something + * } + * store.on('afterUpdate', onAfterUpdate) + * + * @callback Container~afterUpdateListener + * @param {string} name The `name` argument received by {@link Mapper#afterUpdate}. + * @param {string|number} id The `id` argument received by {@link Mapper#afterUpdate}. + * @param {Object} props The `props` argument received by {@link Mapper#afterUpdate}. + * @param {Object} opts The `opts` argument received by {@link Mapper#afterUpdate}. + * @param {Object} result The `result` argument received by {@link Mapper#afterUpdate}. + * @see Container#event:afterUpdate + * @see Container#update + * @since 3.0.0 + *//** + * Wrapper for {@link Mapper#update}. + * + * @example + * import {Container} from 'js-data' + * import RethinkDBAdapter from 'js-data-rethinkdb' + * const store = new Container() + * store.registerAdapter('rethinkdb', new RethinkDBAdapter(), { default: true }) + * store.defineMapper('post') + * + * store.update('post', 1234, { + * status: 'published', + * published_at: new Date() + * }).then((post) => { + * console.log(post) // { id: 1234, status: 'published', ... } + * }) + * + * @fires Container#beforeUpdate + * @fires Container#afterUpdate + * @method Container#update + * @param {string} name Name of the {@link Mapper} to target. + * @param {(string|number)} id See {@link Mapper#update}. + * @param {Object} record See {@link Mapper#update}. + * @param {Object} [opts] See {@link Mapper#update}. + * @returns {Promise} See {@link Mapper#update}. + * @see Mapper#update + * @since 3.0.0 + * @tutorial ["http://www.js-data.io/v3.0/docs/saving-data","Saving data"] + */'update',/** + * Fired during {@link Container#updateAll}. See + * {@link Container~beforeUpdateAllListener} for how to listen for this event. + * + * @event Container#beforeUpdateAll + * @see Container~beforeUpdateAllListener + * @see Container#updateAll + *//** + * Callback signature for the {@link Container#event:beforeUpdateAll} event. + * + * @example + * function onBeforeUpdateAll (mapperName, props, query, opts) { + * // do something + * } + * store.on('beforeUpdateAll', onBeforeUpdateAll) + * + * @callback Container~beforeUpdateAllListener + * @param {string} name The `name` argument received by {@link Mapper#beforeUpdateAll}. + * @param {Object} props The `props` argument received by {@link Mapper#beforeUpdateAll}. + * @param {Object} query The `query` argument received by {@link Mapper#beforeUpdateAll}. + * @param {Object} opts The `opts` argument received by {@link Mapper#beforeUpdateAll}. + * @see Container#event:beforeUpdateAll + * @see Container#updateAll + * @since 3.0.0 + *//** + * Fired during {@link Container#updateAll}. See + * {@link Container~afterUpdateAllListener} for how to listen for this event. + * + * @event Container#afterUpdateAll + * @see Container~afterUpdateAllListener + * @see Container#updateAll + *//** + * Callback signature for the {@link Container#event:afterUpdateAll} event. + * + * @example + * function onAfterUpdateAll (mapperName, props, query, opts, result) { + * // do something + * } + * store.on('afterUpdateAll', onAfterUpdateAll) + * + * @callback Container~afterUpdateAllListener + * @param {string} name The `name` argument received by {@link Mapper#afterUpdateAll}. + * @param {Object} props The `props` argument received by {@link Mapper#afterUpdateAll}. + * @param {Object} query The `query` argument received by {@link Mapper#afterUpdateAll}. + * @param {Object} opts The `opts` argument received by {@link Mapper#afterUpdateAll}. + * @param {Object} result The `result` argument received by {@link Mapper#afterUpdateAll}. + * @see Container#event:afterUpdateAll + * @see Container#updateAll + * @since 3.0.0 + *//** + * Wrapper for {@link Mapper#updateAll}. + * + * @example + * // Turn all of John's blog posts into drafts. + * import {Container} from 'js-data' + * import RethinkDBAdapter from 'js-data-rethinkdb' + * const store = new Container() + * store.registerAdapter('rethinkdb', new RethinkDBAdapter(), { default: true }) + * store.defineMapper('post') + * + * const update = { status: draft: published_at: null } + * const query = { userId: 1234 } + * store.updateAll('post', update, query).then((posts) => { + * console.log(posts) // [...] + * }) + * + * @fires Container#beforeUpdateAll + * @fires Container#afterUpdateAll + * @method Container#updateAll + * @param {string} name Name of the {@link Mapper} to target. + * @param {Object} update See {@link Mapper#updateAll}. + * @param {Object} [query] See {@link Mapper#updateAll}. + * @param {Object} [opts] See {@link Mapper#updateAll}. + * @returns {Promise} See {@link Mapper#updateAll}. + * @see Mapper#updateAll + * @since 3.0.0 + */'updateAll',/** + * Fired during {@link Container#updateMany}. See + * {@link Container~beforeUpdateManyListener} for how to listen for this event. + * + * @event Container#beforeUpdateMany + * @see Container~beforeUpdateManyListener + * @see Container#updateMany + *//** + * Callback signature for the {@link Container#event:beforeUpdateMany} event. + * + * @example + * function onBeforeUpdateMany (mapperName, records, opts) { + * // do something + * } + * store.on('beforeUpdateMany', onBeforeUpdateMany) + * + * @callback Container~beforeUpdateManyListener + * @param {string} name The `name` argument received by {@link Mapper#beforeUpdateMany}. + * @param {Object} records The `records` argument received by {@link Mapper#beforeUpdateMany}. + * @param {Object} opts The `opts` argument received by {@link Mapper#beforeUpdateMany}. + * @see Container#event:beforeUpdateMany + * @see Container#updateMany + * @since 3.0.0 + *//** + * Fired during {@link Container#updateMany}. See + * {@link Container~afterUpdateManyListener} for how to listen for this event. + * + * @event Container#afterUpdateMany + * @see Container~afterUpdateManyListener + * @see Container#updateMany + *//** + * Callback signature for the {@link Container#event:afterUpdateMany} event. + * + * @example + * function onAfterUpdateMany (mapperName, records, opts, result) { + * // do something + * } + * store.on('afterUpdateMany', onAfterUpdateMany) + * + * @callback Container~afterUpdateManyListener + * @param {string} name The `name` argument received by {@link Mapper#afterUpdateMany}. + * @param {Object} records The `records` argument received by {@link Mapper#afterUpdateMany}. + * @param {Object} opts The `opts` argument received by {@link Mapper#afterUpdateMany}. + * @param {Object} result The `result` argument received by {@link Mapper#afterUpdateMany}. + * @see Container#event:afterUpdateMany + * @see Container#updateMany + * @since 3.0.0 + *//** + * Wrapper for {@link Mapper#updateMany}. + * + * @example + * import {Container} from 'js-data' + * import RethinkDBAdapter from 'js-data-rethinkdb' + * const store = new Container() + * store.registerAdapter('rethinkdb', new RethinkDBAdapter(), { default: true }) + * store.defineMapper('post') + * + * store.updateMany('post', [ + * { id: 1234, status: 'draft' }, + * { id: 2468, status: 'published', published_at: new Date() } + * ]).then((posts) => { + * console.log(posts) // [...] + * }) + * + * @fires Container#beforeUpdateMany + * @fires Container#afterUpdateMany + * @method Container#updateMany + * @param {string} name Name of the {@link Mapper} to target. + * @param {(Object[]|Record[])} records See {@link Mapper#updateMany}. + * @param {Object} [opts] See {@link Mapper#updateMany}. + * @returns {Promise} See {@link Mapper#updateMany}. + * @see Mapper#updateMany + * @since 3.0.0 + */'updateMany',/** + * Wrapper for {@link Mapper#validate}. + * + * @example + * import {Container} from 'js-data' + * const store = new Container() + * store.defineMapper('post', { + * schema: { + * properties: { + * name: { type: 'string' }, + * id: { type: 'string' } + * } + * } + * }) + * let errors = store.validate('post', { name: 'John' }) + * console.log(errors) // undefined + * errors = store.validate('post', { name: 123 }) + * console.log(errors) // [{ expected: 'one of (string)', actual: 'number', path: 'name' }] + * + * @method Container#validate + * @param {string} name Name of the {@link Mapper} to target. + * @param {(Object[]|Record[])} records See {@link Mapper#validate}. + * @param {Object} [opts] See {@link Mapper#validate}. + * @returns {Promise} See {@link Mapper#validate}. + * @see Mapper#validate + * @since 3.0.0 + */'validate'];/** + * The `Container` class is a place to define and store {@link Mapper} instances. + * + * `Container` makes it easy to manage your Mappers. Without a container, you + * need to manage Mappers yourself, including resolving circular dependencies + * among relations. All Mappers in a container share the same adapters, so you + * don't have to register adapters for every single Mapper. + * + * @example Container#constructor + * // import {Container} from 'js-data' + * const JSData = require('js-data@3.0.0-rc.4') + * const {Container} = JSData + * console.log('Using JSData v' + JSData.version.full) + * + * const store = new Container() + * + * @class Container + * @extends Component + * @param {Object} [opts] Configuration options. + * @param {boolean} [opts.debug=false] See {@link Component#debug}. + * @param {Constructor} [opts.mapperClass] See {@link Container#mapperClass}. + * @param {Object} [opts.mapperDefaults] See {@link Container#mapperDefaults}. + * @since 3.0.0 + */function Container(opts){utils.classCallCheck(this,Container);Component$1.call(this);opts||(opts={});Object.defineProperties(this,{/** + * The adapters registered with this Container, which are also shared by all + * Mappers in this Container. + * + * @name Container#_adapters + * @see Container#registerAdapter + * @since 3.0.0 + * @type {Object} + */_adapters:{value:{}},/** + * The the mappers in this container + * + * @name Container#_mappers + * @see Mapper + * @since 3.0.0 + * @type {Object} + */_mappers:{value:{}},/** + * Constructor function to use in {@link Container#defineMapper} to create new + * {@link Mapper} instances. {@link Container#mapperClass} should extend + * {@link Mapper}. By default {@link Mapper} is used to instantiate Mappers. + * + * @example Container#mapperClass + * // import {Container, Mapper} from 'js-data' + * const JSData = require('js-data@3.0.0-rc.4') + * const {Container} = JSData + * console.log('Using JSData v' + JSData.version.full) + * + * class MyMapperClass extends Mapper { + * foo () { return 'bar' } + * } + * const store = new Container({ + * mapperClass: MyMapperClass + * }) + * store.defineMapper('user') + * console.log(store.getMapper('user').foo()) + * + * @name Container#mapperClass + * @see Mapper + * @since 3.0.0 + * @type {Constructor} + */mapperClass:{value:undefined,writable:true}});// Apply options provided by the user +utils.fillIn(this,opts);/** + * Defaults options to pass to {@link Container#mapperClass} when creating a + * new {@link Mapper}. + * + * @example Container#mapperDefaults + * // import {Container} from 'js-data' + * const JSData = require('js-data@3.0.0-rc.4') + * const {Container} = JSData + * console.log('Using JSData v' + JSData.version.full) + * + * const store = new Container({ + * mapperDefaults: { + * idAttribute: '_id' + * } + * }) + * store.defineMapper('user') + * console.log(store.getMapper('user').idAttribute) + * + * @default {} + * @name Container#mapperDefaults + * @since 3.0.0 + * @type {Object} + */this.mapperDefaults=this.mapperDefaults||{};// Use the Mapper class if the user didn't provide a mapperClass +this.mapperClass||(this.mapperClass=Mapper$1);}var props={constructor:Container,/** + * Register a new event listener on this Container. + * + * Proxy for {@link Component#on}. If an event was emitted by a {@link Mapper} + * in the Container, then the name of the {@link Mapper} will be prepended to + * the arugments passed to the listener. + * + * @example Container#on + * // import {Container} from 'js-data' + * const JSData = require('js-data@3.0.0-rc.4') + * const {Container} = JSData + * console.log('Using JSData v' + JSData.version.full) + * + * const store = new Container() + * store.on('foo', function (...args) { console.log(args.join(':')) }) + * store.defineMapper('user') + * store.emit('foo', 'arg1', 'arg2') + * store.getMapper('user').emit('foo', 'arg1', 'arg2') + * + * @method Container#on + * @param {string} event Name of event to subsribe to. + * @param {Function} listener Listener function to handle the event. + * @param {*} [ctx] Optional content in which to invoke the listener. + * @since 3.0.0 + *//** + * Used to bind to events emitted by mappers in this container. + * + * @method Container#_onMapperEvent + * @param {string} name Name of the mapper that emitted the event. + * @param {...*} [args] Args See {@link Mapper#emit}. + * @private + * @since 3.0.0 + */_onMapperEvent:function _onMapperEvent(name){for(var _len=arguments.length,args=Array(_len>1?_len-1:0),_key=1;_key<_len;_key++){args[_key-1]=arguments[_key];}var type=args.shift();this.emit.apply(this,[type,name].concat(args));},/** + * Return a container scoped to a particular mapper. + * + * @example Container#as + * // import {Container} from 'js-data' + * const JSData = require('js-data@3.0.0-rc.4') + * const {Container} = JSData + * console.log('Using JSData v' + JSData.version.full) + * + * const store = new Container() + * const UserMapper = store.defineMapper('user') + * const UserStore = store.as('user') + * + * const user1 = store.createRecord('user', { name: 'John' }) + * const user2 = UserStore.createRecord({ name: 'John' }) + * const user3 = UserMapper.createRecord({ name: 'John' }) + * console.log(user1 === user2) + * console.log(user2 === user3) + * console.log(user1 === user3) + * + * @method Container#as + * @param {string} name Name of the {@link Mapper}. + * @returns {Object} A container scoped to a particular mapper. + * @since 3.0.0 + */as:function as(name){var props={};var original=this;proxiedMapperMethods.forEach(function(method){props[method]={writable:true,value:function value(){for(var _len2=arguments.length,args=Array(_len2),_key2=0;_key2<_len2;_key2++){args[_key2]=arguments[_key2];}return original[method].apply(original,[name].concat(args));}};});props.getMapper={writable:true,value:function value(){return original.getMapper(name);}};return Object.create(this,props);},/** + * Create a new mapper and register it in this container. + * + * @example Container#defineMapper + * // import {Container} from 'js-data' + * const JSData = require('js-data@3.0.0-rc.4') + * const {Container} = JSData + * console.log('Using JSData v' + JSData.version.full) + * + * const store = new Container({ + * mapperDefaults: { foo: 'bar' } + * }) + * // Container#defineMapper returns a direct reference to the newly created + * // Mapper. + * const UserMapper = store.defineMapper('user') + * console.log(UserMapper === store.getMapper('user')) + * console.log(UserMapper === store.as('user').getMapper()) + * console.log(UserMapper.foo) + * + * @method Container#defineMapper + * @param {string} name Name under which to register the new {@link Mapper}. + * {@link Mapper#name} will be set to this value. + * @param {Object} [opts] Configuration options. Passed to + * {@link Container#mapperClass} when creating the new {@link Mapper}. + * @returns {Mapper} The newly created instance of {@link Mapper}. + * @see Container#as + * @since 3.0.0 + */defineMapper:function defineMapper(name,opts){var _this=this;// For backwards compatibility with defineResource +if(utils.isObject(name)){opts=name;name=opts.name;}if(!utils.isString(name)){throw utils.err(DOMAIN$3+'#defineMapper','name')(400,'string',name);}// Default values for arguments +opts||(opts={});// Set Mapper#name +opts.name=name;opts.relations||(opts.relations={});// Check if the user is overriding the datastore's default mapperClass +var mapperClass=opts.mapperClass||this.mapperClass;delete opts.mapperClass;// Apply the datastore's defaults to the options going into the mapper +utils.fillIn(opts,this.mapperDefaults);// Instantiate a mapper +var mapper=this._mappers[name]=new mapperClass(opts);// eslint-disable-line +mapper.relations||(mapper.relations={});// Make sure the mapper's name is set +mapper.name=name;// All mappers in this datastore will share adapters +mapper._adapters=this.getAdapters();mapper.datastore=this;mapper.on('all',function(){for(var _len3=arguments.length,args=Array(_len3),_key3=0;_key3<_len3;_key3++){args[_key3]=arguments[_key3];}return _this._onMapperEvent.apply(_this,[name].concat(args));});mapper.defineRelations();return mapper;},defineResource:function defineResource(name,opts){console.warn('DEPRECATED: defineResource is deprecated, use defineMapper instead');return this.defineMapper(name,opts);},/** + * Return the registered adapter with the given name or the default adapter if + * no name is provided. + * + * @method Container#getAdapter + * @param {string} [name] The name of the adapter to retrieve. + * @returns {Adapter} The adapter. + * @since 3.0.0 + */getAdapter:function getAdapter(name){var adapter=this.getAdapterName(name);if(!adapter){throw utils.err(DOMAIN$3+'#getAdapter','name')(400,'string',name);}return this.getAdapters()[adapter];},/** + * Return the name of a registered adapter based on the given name or options, + * or the name of the default adapter if no name provided. + * + * @method Container#getAdapterName + * @param {(Object|string)} [opts] The name of an adapter or options, if any. + * @returns {string} The name of the adapter. + * @since 3.0.0 + */getAdapterName:function getAdapterName(opts){opts||(opts={});if(utils.isString(opts)){opts={adapter:opts};}return opts.adapter||this.mapperDefaults.defaultAdapter;},/** + * Return the registered adapters of this container. + * + * @method Container#getAdapters + * @returns {Adapter} + * @since 3.0.0 + */getAdapters:function getAdapters(){return this._adapters;},/** + * Return the mapper registered under the specified name. + * + * @example Container#getMapper + * // import {Container} from 'js-data' + * const JSData = require('js-data@3.0.0-rc.4') + * const {Container} = JSData + * console.log('Using JSData v' + JSData.version.full) + * + * const store = new Container() + * // Container#defineMapper returns a direct reference to the newly created + * // Mapper. + * const UserMapper = store.defineMapper('user') + * console.log(UserMapper === store.getMapper('user')) + * console.log(UserMapper === store.as('user').getMapper()) + * store.getMapper('profile') // throws Error, there is no mapper with name "profile" + * + * @method Container#getMapper + * @param {string} name {@link Mapper#name}. + * @returns {Mapper} + * @since 3.0.0 + */getMapper:function getMapper(name){var mapper=this.getMapperByName(name);if(!mapper){throw utils.err(DOMAIN$3+'#getMapper',name)(404,'mapper');}return mapper;},/** + * Return the mapper registered under the specified name. + * Doesn't throw error if mapper doesn't exist. + * + * @example Container#getMapperByName + * // import {Container} from 'js-data' + * const JSData = require('js-data@3.0.0-rc.4') + * const {Container} = JSData + * console.log('Using JSData v' + JSData.version.full) + * + * const store = new Container() + * // Container#defineMapper returns a direct reference to the newly created + * // Mapper. + * const UserMapper = store.defineMapper('user') + * console.log(UserMapper === store.getMapper('user')) + * console.log(UserMapper === store.as('user').getMapper()) + * console.log(store.getMapper('profile')) // Does NOT throw an error + * + * @method Container#getMapperByName + * @param {string} name {@link Mapper#name}. + * @returns {Mapper} + * @since 3.0.0 + */getMapperByName:function getMapperByName(name){return this._mappers[name];},/** + * Register an adapter on this container under the given name. Adapters + * registered on a container are shared by all mappers in the container. + * + * @example + * import {Container} from 'js-data' + * import {RethinkDBAdapter} from 'js-data-rethinkdb' + * const store = new Container() + * store.registerAdapter('rethinkdb', new RethinkDBAdapter(), { default: true }) + * + * @method Container#registerAdapter + * @param {string} name The name of the adapter to register. + * @param {Adapter} adapter The adapter to register. + * @param {Object} [opts] Configuration options. + * @param {boolean} [opts.default=false] Whether to make the adapter the + * default adapter for all Mappers in this container. + * @since 3.0.0 + * @tutorial ["http://www.js-data.io/v3.0/docs/connecting-to-a-data-source","Connecting to a data source"] + */registerAdapter:function registerAdapter(name,adapter,opts){opts||(opts={});this.getAdapters()[name]=adapter;// Optionally make it the default adapter for the target. +if(opts===true||opts.default){this.mapperDefaults.defaultAdapter=name;utils.forOwn(this._mappers,function(mapper){mapper.defaultAdapter=name;});}}};proxiedMapperMethods.forEach(function(method){props[method]=function(name){var _getMapper;for(var _len4=arguments.length,args=Array(_len4>1?_len4-1:0),_key4=1;_key4<_len4;_key4++){args[_key4-1]=arguments[_key4];}return(_getMapper=this.getMapper(name))[method].apply(_getMapper,args);};});Component$1.extend(props);/** + * Create a subclass of this Container: + * @example Container.extend + * // Normally you would do: import {Container} from 'js-data' + * const JSData = require('js-data@3.0.0-rc.4') + * const {Container} = JSData + * console.log('Using JSData v' + JSData.version.full) + * + * // Extend the class using ES2015 class syntax. + * class CustomContainerClass extends Container { + * foo () { return 'bar' } + * static beep () { return 'boop' } + * } + * const customContainer = new CustomContainerClass() + * console.log(customContainer.foo()) + * console.log(CustomContainerClass.beep()) + * + * // Extend the class using alternate method. + * const OtherContainerClass = Container.extend({ + * foo () { return 'bar' } + * }, { + * beep () { return 'boop' } + * }) + * const otherContainer = new OtherContainerClass() + * console.log(otherContainer.foo()) + * console.log(OtherContainerClass.beep()) + * + * // Extend the class, providing a custom constructor. + * function AnotherContainerClass () { + * Container.call(this) + * this.created_at = new Date().getTime() + * } + * Container.extend({ + * constructor: AnotherContainerClass, + * foo () { return 'bar' } + * }, { + * beep () { return 'boop' } + * }) + * const anotherContainer = new AnotherContainerClass() + * console.log(anotherContainer.created_at) + * console.log(anotherContainer.foo()) + * console.log(AnotherContainerClass.beep()) + * + * @method Container.extend + * @param {Object} [props={}] Properties to add to the prototype of the + * subclass. + * @param {Object} [props.constructor] Provide a custom constructor function + * to be used as the subclass itself. + * @param {Object} [classProps={}] Static properties to add to the subclass. + * @returns {Constructor} Subclass of this Container class. + * @since 3.0.0 + */var DOMAIN$9='SimpleStore';var proxiedCollectionMethods=[/** + * Wrapper for {@link Collection#add}. + * + * @example SimpleStore#add + * // Normally you would do: import {SimpleStore} from 'js-data' + * const JSData = require('js-data@3.0.0-rc.4') + * const {SimpleStore} = JSData + * console.log('Using JSData v' + JSData.version.full) + * + * const store = new SimpleStore() + * store.defineMapper('book') + * + * // Add one book to the in-memory store: + * store.add('book', { id: 1, title: 'Respect your Data' }) + * // Add multiple books to the in-memory store: + * store.add('book', [ + * { id: 2, title: 'Easy data recipes' }, + * { id: 3, title: 'Active Record 101' } + * ]) + * + * @fires SimpleStore#add + * @method SimpleStore#add + * @param {(string|number)} name Name of the {@link Mapper} to target. + * @param {(Object|Object[]|Record|Record[])} data See {@link Collection#add}. + * @param {Object} [opts] Configuration options. See {@link Collection#add}. + * @returns {(Object|Object[]|Record|Record[])} See {@link Collection#add}. + * @see Collection#add + * @see Collection#add + * @since 3.0.0 + */'add',/** + * Wrapper for {@link Collection#between}. + * + * @example + * // Get all users ages 18 to 30 + * const users = store.between('user', 18, 30, { index: 'age' }) + * + * @example + * // Same as above + * const users = store.between('user', [18], [30], { index: 'age' }) + * + * @method SimpleStore#between + * @param {(string|number)} name Name of the {@link Mapper} to target. + * @param {Array} leftKeys See {@link Collection#between}. + * @param {Array} rightKeys See {@link Collection#between}. + * @param {Object} [opts] Configuration options. See {@link Collection#between}. + * @returns {Object[]|Record[]} See {@link Collection#between}. + * @see Collection#between + * @see Collection#between + * @since 3.0.0 + */'between',/** + * Wrapper for {@link Collection#createIndex}. + * + * @example + * // Index users by age + * store.createIndex('user', 'age') + * + * @example + * // Index users by status and role + * store.createIndex('user', 'statusAndRole', ['status', 'role']) + * + * @method SimpleStore#createIndex + * @param {(string|number)} name Name of the {@link Mapper} to target. + * @param {string} name See {@link Collection#createIndex}. + * @param {string[]} [fieldList] See {@link Collection#createIndex}. + * @see Collection#createIndex + * @see Collection#createIndex + * @since 3.0.0 + */'createIndex',/** + * Wrapper for {@link Collection#filter}. + * + * @example SimpleStore#filter + * // import {SimpleStore} from 'js-data' + * const JSData = require('js-data@3.0.0-rc.4') + * const {SimpleStore} = JSData + * console.log('Using JSData v' + JSData.version.full) + * + * const store = new SimpleStore() + * store.defineMapper('post') + * store.add('post', [ + * { id: 1, status: 'draft', created_at_timestamp: new Date().getTime() } + * ]) + * + * // Get the draft posts created less than three months ago + * let posts = store.filter('post', { + * where: { + * status: { + * '==': 'draft' + * }, + * created_at_timestamp: { + * '>=': (new Date().getTime() - (1000 \* 60 \* 60 \* 24 \* 30 \* 3)) // 3 months ago + * } + * } + * }) + * console.log(posts) + * + * // Use a custom filter function + * posts = store.filter('post', function (post) { return post.id % 2 === 0 }) + * + * @method SimpleStore#filter + * @param {(string|number)} name Name of the {@link Mapper} to target. + * @param {(Object|Function)} [queryOrFn={}] See {@link Collection#filter}. + * @param {Object} [thisArg] See {@link Collection#filter}. + * @returns {Array} See {@link Collection#filter}. + * @see Collection#filter + * @see Collection#filter + * @since 3.0.0 + */'filter',/** + * Wrapper for {@link Collection#get}. + * + * @example SimpleStore#get + * // import {SimpleStore} from 'js-data' + * const JSData = require('js-data@3.0.0-rc.4') + * const {SimpleStore} = JSData + * console.log('Using JSData v' + JSData.version.full) + * + * const store = new SimpleStore() + * store.defineMapper('post') + * store.add('post', [ + * { id: 1, status: 'draft', created_at_timestamp: new Date().getTime() } + * ]) + * + * console.log(store.get('post', 1)) // {...} + * console.log(store.get('post', 2)) // undefined + * + * @method SimpleStore#get + * @param {(string|number)} name Name of the {@link Mapper} to target. + * @param {(string|number)} id See {@link Collection#get}. + * @returns {(Object|Record)} See {@link Collection#get}. + * @see Collection#get + * @see Collection#get + * @since 3.0.0 + */'get',/** + * Wrapper for {@link Collection#getAll}. + * + * @example + * // Get the posts where "status" is "draft" or "inReview" + * const posts = store.getAll('post', 'draft', 'inReview', { index: 'status' }) + * + * @example + * // Same as above + * const posts = store.getAll('post', ['draft'], ['inReview'], { index: 'status' }) + * + * @method SimpleStore#getAll + * @param {(string|number)} name Name of the {@link Mapper} to target. + * @param {...Array} [keyList] See {@link Collection#getAll}. + * @param {Object} [opts] See {@link Collection#getAll}. + * @returns {Array} See {@link Collection#getAll}. + * @see Collection#getAll + * @see Collection#getAll + * @since 3.0.0 + */'getAll',/** + * Wrapper for {@link Collection#prune}. + * + * @method SimpleStore#prune + * @param {Object} [opts] See {@link Collection#prune}. + * @returns {Array} See {@link Collection#prune}. + * @see Collection#prune + * @see Collection#prune + * @since 3.0.0 + */'prune',/** + * Wrapper for {@link Collection#query}. + * + * @example + * // Grab page 2 of users between ages 18 and 30 + * store.query('user') + * .between(18, 30, { index: 'age' }) // between ages 18 and 30 + * .skip(10) // second page + * .limit(10) // page size + * .run() + * + * @method SimpleStore#query + * @param {(string|number)} name Name of the {@link Mapper} to target. + * @returns {Query} See {@link Collection#query}. + * @see Collection#query + * @see Collection#query + * @since 3.0.0 + */'query',/** + * Wrapper for {@link Collection#toJSON}. + * + * @example + * store.defineMapper('post', { + * schema: { + * properties: { + * id: { type: 'number' }, + * title: { type: 'string' } + * } + * } + * }) + * store.add('post', [ + * { id: 1, status: 'published', title: 'Respect your Data' }, + * { id: 2, status: 'draft', title: 'Connecting to a data source' } + * ]) + * console.log(store.toJSON('post')) + * const draftsJSON = store.query('post') + * .filter({ status: 'draft' }) + * .mapCall('toJSON') + * .run() + * + * @method SimpleStore#toJSON + * @param {(string|number)} name Name of the {@link Mapper} to target. + * @param {Object} [opts] See {@link Collection#toJSON}. + * @returns {Array} See {@link Collection#toJSON}. + * @see Collection#toJSON + * @see Collection#toJSON + * @since 3.0.0 + */'toJSON',/** + * Wrapper for {@link Collection#unsaved}. + * + * @method SimpleStore#unsaved + * @returns {Array} See {@link Collection#unsaved}. + * @see Collection#unsaved + * @see Collection#unsaved + * @since 3.0.0 + */'unsaved'];var ownMethodsForScoping=['addToCache','cachedFind','cachedFindAll','cacheFind','cacheFindAll','hashQuery'];var cachedFn=function cachedFn(name,hashOrId,opts){var cached=this._completedQueries[name][hashOrId];if(utils.isFunction(cached)){return cached(name,hashOrId,opts);}return cached;};var SIMPLESTORE_DEFAULTS={/** + * Whether to use the pending query if a `find` request for the specified + * record is currently underway. Can be set to `true`, `false`, or to a + * function that returns `true` or `false`. + * + * @default true + * @name SimpleStore#usePendingFind + * @since 3.0.0 + * @type {boolean|Function} + */usePendingFind:true,/** + * Whether to use the pending query if a `findAll` request for the given query + * is currently underway. Can be set to `true`, `false`, or to a function that + * returns `true` or `false`. + * + * @default true + * @name SimpleStore#usePendingFindAll + * @since 3.0.0 + * @type {boolean|Function} + */usePendingFindAll:true};/** + * The `SimpleStore` class is an extension of {@link Container}. Not only does + * `SimpleStore` manage mappers, but also collections. `SimpleStore` implements the + * asynchronous {@link Mapper} methods, such as {@link Mapper#find} and + * {@link Mapper#create}. If you use the asynchronous `SimpleStore` methods + * instead of calling them directly on the mappers, then the results of the + * method calls will be inserted into the store's collections. You can think of + * a `SimpleStore` as an [Identity Map](https://en.wikipedia.org/wiki/Identity_map_pattern) + * for the [ORM](https://en.wikipedia.org/wiki/Object-relational_mapping) + * (the Mappers). + * + * ```javascript + * import {SimpleStore} from 'js-data' + * ``` + * + * @example + * import {SimpleStore} from 'js-data' + * import HttpAdapter from 'js-data-http' + * const store = new SimpleStore() + * + * // SimpleStore#defineMapper returns a direct reference to the newly created + * // Mapper. + * const UserMapper = store.defineMapper('user') + * + * // SimpleStore#as returns the store scoped to a particular Mapper. + * const UserStore = store.as('user') + * + * // Call "find" on "UserMapper" (Stateless ORM) + * UserMapper.find(1).then((user) => { + * // retrieved a "user" record via the http adapter, but that's it + * + * // Call "find" on "store" targeting "user" (Stateful SimpleStore) + * return store.find('user', 1) // same as "UserStore.find(1)" + * }).then((user) => { + * // not only was a "user" record retrieved, but it was added to the + * // store's "user" collection + * const cachedUser = store.getCollection('user').get(1) + * console.log(user === cachedUser) // true + * }) + * + * @class SimpleStore + * @extends Container + * @param {Object} [opts] Configuration options. See {@link Container}. + * @param {boolean} [opts.collectionClass={@link Collection}] See {@link SimpleStore#collectionClass}. + * @param {boolean} [opts.debug=false] See {@link Component#debug}. + * @param {boolean|Function} [opts.usePendingFind=true] See {@link SimpleStore#usePendingFind}. + * @param {boolean|Function} [opts.usePendingFindAll=true] See {@link SimpleStore#usePendingFindAll}. + * @returns {SimpleStore} + * @see Container + * @since 3.0.0 + * @tutorial ["http://www.js-data.io/v3.0/docs/components-of-jsdata#SimpleStore","Components of JSData: SimpleStore"] + * @tutorial ["http://www.js-data.io/v3.0/docs/working-with-the-SimpleStore","Working with the SimpleStore"] + * @tutorial ["http://www.js-data.io/v3.0/docs/jsdata-and-the-browser","Notes on using JSData in the Browser"] + */function SimpleStore(opts){utils.classCallCheck(this,SimpleStore);opts||(opts={});// Fill in any missing options with the defaults +utils.fillIn(opts,SIMPLESTORE_DEFAULTS);Container.call(this,opts);this.collectionClass=this.collectionClass||Collection$1;this._collections={};this._pendingQueries={};this._completedQueries={};}var props$2={constructor:SimpleStore,/** + * Internal method used to handle Mapper responses. + * + * @method SimpleStore#_end + * @private + * @param {string} name Name of the {@link Collection} to which to + * add the data. + * @param {Object} result The result from a Mapper. + * @param {Object} [opts] Configuration options. + * @returns {(Object|Array)} Result. + */_end:function _end(name,result,opts){var data=opts.raw?result.data:result;if(data&&utils.isFunction(this.addToCache)){data=this.addToCache(name,data,opts);if(opts.raw){result.data=data;}else{result=data;}}return result;},/** + * Register a new event listener on this SimpleStore. + * + * Proxy for {@link Container#on}. If an event was emitted by a Mapper or + * Collection in the SimpleStore, then the name of the Mapper or Collection will + * be prepended to the arugments passed to the provided event handler. + * + * @example + * // Listen for all "afterCreate" events in a SimpleStore + * store.on('afterCreate', (mapperName, props, opts, result) => { + * console.log(mapperName) // "post" + * console.log(props.id) // undefined + * console.log(result.id) // 1234 + * }) + * store.create('post', { title: 'Modeling your data' }).then((post) => { + * console.log(post.id) // 1234 + * }) + * + * @example + * // Listen for the "add" event on a collection + * store.on('add', (mapperName, records) => { + * console.log(records) // [...] + * }) + * + * @example + * // Listen for "change" events on a record + * store.on('change', (mapperName, record, changes) => { + * console.log(changes) // { changed: { title: 'Modeling your data' } } + * }) + * post.title = 'Modeling your data' + * + * @method SimpleStore#on + * @param {string} event Name of event to subsribe to. + * @param {Function} listener Listener function to handle the event. + * @param {*} [ctx] Optional content in which to invoke the listener. + *//** + * Used to bind to events emitted by collections in this store. + * + * @method SimpleStore#_onCollectionEvent + * @private + * @param {string} name Name of the collection that emitted the event. + * @param {...*} [args] Args passed to {@link Collection#emit}. + */_onCollectionEvent:function _onCollectionEvent(name){for(var _len=arguments.length,args=Array(_len>1?_len-1:0),_key=1;_key<_len;_key++){args[_key-1]=arguments[_key];}var type=args.shift();this.emit.apply(this,[type,name].concat(args));},/** + * This method takes the data received from {@link SimpleStore#find}, + * {@link SimpleStore#findAll}, {@link SimpleStore#update}, etc., and adds the + * data to the store. _You don't need to call this method directly._ + * + * If you're using the http adapter and your response data is in an unexpected + * format, you may need to override this method so the right data gets added + * to the store. + * + * @example + * const store = new SimpleStore({ + * addToCache (mapperName, data, opts) { + * // Let's say for a particular Resource, response data is in a weird format + * if (name === 'comment') { + * // Re-assign the variable to add the correct records into the stores + * data = data.items + * } + * // Now perform default behavior + * return SimpleStore.prototype.addToCache.call(this, mapperName, data, opts) + * } + * }) + * + * @example + * // Extend using ES2015 class syntax. + * class MyStore extends SimpleStore { + * addToCache (mapperName, data, opts) { + * // Let's say for a particular Resource, response data is in a weird format + * if (name === 'comment') { + * // Re-assign the variable to add the correct records into the stores + * data = data.items + * } + * // Now perform default behavior + * return super.addToCache(mapperName, data, opts) + * } + * } + * const store = new MyStore() + * + * @method SimpleStore#addToCache + * @param {string} name Name of the {@link Mapper} to target. + * @param {*} data Data from which data should be selected for add. + * @param {Object} [opts] Configuration options. + */addToCache:function addToCache(name,data,opts){return this.getCollection(name).add(data,opts);},/** + * Return the store scoped to a particular mapper/collection pair. + * + * @example SimpleStore.as + * // Normally you would do: import {SimpleStore} from 'js-data' + * const JSData = require('js-data@3.0.0-rc.4') + * const {SimpleStore} = JSData + * console.log('Using JSData v' + JSData.version.full) + * + * const store = new SimpleStore() + * const UserMapper = store.defineMapper('user') + * const UserStore = store.as('user') + * + * const user1 = store.createRecord('user', { name: 'John' }) + * const user2 = UserStore.createRecord({ name: 'John' }) + * const user3 = UserMapper.createRecord({ name: 'John' }) + * console.log(user1 === user2) + * console.log(user2 === user3) + * console.log(user1 === user3) + * + * @method SimpleStore#as + * @param {string} name Name of the {@link Mapper}. + * @returns {Object} The store, scoped to a particular Mapper/Collection pair. + * @since 3.0.0 + */as:function as(name){var props={};var original=this;var methods=ownMethodsForScoping.concat(proxiedMapperMethods).concat(proxiedCollectionMethods);methods.forEach(function(method){props[method]={writable:true,value:function value(){for(var _len2=arguments.length,args=Array(_len2),_key2=0;_key2<_len2;_key2++){args[_key2]=arguments[_key2];}return original[method].apply(original,[name].concat(args));}};});props.getMapper={writable:true,value:function value(){return original.getMapper(name);}};props.getCollection={writable:true,value:function value(){return original.getCollection(name);}};return Object.create(this,props);},/** + * Retrieve a cached `find` result, if any. This method is called during + * {@link SimpleStore#find} to determine if {@link Mapper#find} needs to be + * called. If this method returns `undefined` then {@link Mapper#find} will + * be called. Otherwise {@link SimpleStore#find} will immediately resolve with + * the return value of this method. + * + * When using {@link SimpleStore} in the browser, you can override this method + * to implement your own cache-busting strategy. + * + * @example + * const store = new SimpleStore({ + * cachedFind (mapperName, id, opts) { + * // Let's say for a particular Resource, we always want to pull fresh from the server + * if (mapperName === 'schedule') { + * // Return undefined to trigger a Mapper#find call + * return + * } + * // Otherwise perform default behavior + * return SimpleStore.prototype.cachedFind.call(this, mapperName, id, opts) + * } + * }) + * + * @example + * // Extend using ES2015 class syntax. + * class MyStore extends SimpleStore { + * cachedFind (mapperName, id, opts) { + * // Let's say for a particular Resource, we always want to pull fresh from the server + * if (mapperName === 'schedule') { + * // Return undefined to trigger a Mapper#find call + * return + * } + * // Otherwise perform default behavior + * return super.cachedFind(mapperName, id, opts) + * } + * } + * const store = new MyStore() + * + * @method SimpleStore#cachedFind + * @param {string} name The `name` argument passed to {@link SimpleStore#find}. + * @param {(string|number)} id The `id` argument passed to {@link SimpleStore#find}. + * @param {Object} opts The `opts` argument passed to {@link SimpleStore#find}. + * @since 3.0.0 + */cachedFind:cachedFn,/** + * Retrieve a cached `findAll` result, if any. This method is called during + * {@link SimpleStore#findAll} to determine if {@link Mapper#findAll} needs to be + * called. If this method returns `undefined` then {@link Mapper#findAll} will + * be called. Otherwise {@link SimpleStore#findAll} will immediately resolve with + * the return value of this method. + * + * When using {@link SimpleStore} in the browser, you can override this method + * to implement your own cache-busting strategy. + * + * @example + * const store = new SimpleStore({ + * cachedFindAll (mapperName, hash, opts) { + * // Let's say for a particular Resource, we always want to pull fresh from the server + * if (mapperName === 'schedule') { + * // Return undefined to trigger a Mapper#findAll call + * return undefined + * } + * // Otherwise perform default behavior + * return SimpleStore.prototype.cachedFindAll.call(this, mapperName, hash, opts) + * } + * }) + * + * @example + * // Extend using ES2015 class syntax. + * class MyStore extends SimpleStore { + * cachedFindAll (mapperName, hash, opts) { + * // Let's say for a particular Resource, we always want to pull fresh from the server + * if (mapperName === 'schedule') { + * // Return undefined to trigger a Mapper#findAll call + * return undefined + * } + * // Otherwise perform default behavior + * return super.cachedFindAll(mapperName, hash, opts) + * } + * } + * const store = new MyStore() + * + * @method SimpleStore#cachedFindAll + * @param {string} name The `name` argument passed to {@link SimpleStore#findAll}. + * @param {string} hash The result of calling {@link SimpleStore#hashQuery} on + * the `query` argument passed to {@link SimpleStore#findAll}. + * @param {Object} opts The `opts` argument passed to {@link SimpleStore#findAll}. + * @since 3.0.0 + */cachedFindAll:cachedFn,/** + * Mark a {@link Mapper#find} result as cached by adding an entry to + * {@link SimpleStore#_completedQueries}. By default, once a `find` entry is + * added it means subsequent calls to the same Resource with the same `id` + * argument will immediately resolve with the result of calling + * {@link SimpleStore#get} instead of delegating to {@link Mapper#find}. + * + * As part of implementing your own caching strategy, you may choose to + * override this method. + * + * @example + * const store = new SimpleStore({ + * cacheFind (mapperName, data, id, opts) { + * // Let's say for a particular Resource, we always want to pull fresh from the server + * if (mapperName === 'schedule') { + * // Return without saving an entry to SimpleStore#_completedQueries + * return + * } + * // Otherwise perform default behavior + * return SimpleStore.prototype.cacheFind.call(this, mapperName, data, id, opts) + * } + * }) + * + * @example + * // Extend using ES2015 class syntax. + * class MyStore extends SimpleStore { + * cacheFind (mapperName, data, id, opts) { + * // Let's say for a particular Resource, we always want to pull fresh from the server + * if (mapperName === 'schedule') { + * // Return without saving an entry to SimpleStore#_completedQueries + * return + * } + * // Otherwise perform default behavior + * return super.cacheFind(mapperName, data, id, opts) + * } + * } + * const store = new MyStore() + * + * @method SimpleStore#cacheFind + * @param {string} name The `name` argument passed to {@link SimpleStore#find}. + * @param {*} data The result to cache. + * @param {(string|number)} id The `id` argument passed to {@link SimpleStore#find}. + * @param {Object} opts The `opts` argument passed to {@link SimpleStore#find}. + * @since 3.0.0 + */cacheFind:function cacheFind(name,data,id,opts){var _this=this;this._completedQueries[name][id]=function(name,id,opts){return _this.get(name,id);};},/** + * Mark a {@link Mapper#findAll} result as cached by adding an entry to + * {@link SimpleStore#_completedQueries}. By default, once a `findAll` entry is + * added it means subsequent calls to the same Resource with the same `query` + * argument will immediately resolve with the result of calling + * {@link SimpleStore#filter} instead of delegating to {@link Mapper#findAll}. + * + * As part of implementing your own caching strategy, you may choose to + * override this method. + * + * @example + * const store = new SimpleStore({ + * cachedFindAll (mapperName, data, hash, opts) { + * // Let's say for a particular Resource, we always want to pull fresh from the server + * if (mapperName === 'schedule') { + * // Return without saving an entry to SimpleStore#_completedQueries + * return + * } + * // Otherwise perform default behavior. + * return SimpleStore.prototype.cachedFindAll.call(this, mapperName, data, hash, opts) + * } + * }) + * + * @example + * // Extend using ES2015 class syntax. + * class MyStore extends SimpleStore { + * cachedFindAll (mapperName, data, hash, opts) { + * // Let's say for a particular Resource, we always want to pull fresh from the server + * if (mapperName === 'schedule') { + * // Return without saving an entry to SimpleStore#_completedQueries + * return + * } + * // Otherwise perform default behavior. + * return super.cachedFindAll(mapperName, data, hash, opts) + * } + * } + * const store = new MyStore() + * + * @method SimpleStore#cacheFindAll + * @param {string} name The `name` argument passed to {@link SimpleStore#findAll}. + * @param {*} data The result to cache. + * @param {string} hash The result of calling {@link SimpleStore#hashQuery} on + * the `query` argument passed to {@link SimpleStore#findAll}. + * @param {Object} opts The `opts` argument passed to {@link SimpleStore#findAll}. + * @since 3.0.0 + */cacheFindAll:function cacheFindAll(name,data,hash,opts){var _this2=this;this._completedQueries[name][hash]=function(name,hash,opts){return _this2.filter(name,utils.fromJson(hash));};},/** + * Remove __all__ records from the in-memory store and reset + * {@link SimpleStore#_completedQueries}. + * + * @method SimpleStore#clear + * @returns {Object} Object containing all records that were in the store. + * @see SimpleStore#remove + * @see SimpleStore#removeAll + * @since 3.0.0 + */clear:function clear(){var _this3=this;var removed={};utils.forOwn(this._collections,function(collection,name){removed[name]=collection.removeAll();_this3._completedQueries[name]={};});return removed;},/** + * Fired during {@link SimpleStore#create}. See + * {@link SimpleStore~beforeCreateListener} for how to listen for this event. + * + * @event SimpleStore#beforeCreate + * @see SimpleStore~beforeCreateListener + * @see SimpleStore#create + *//** + * Callback signature for the {@link SimpleStore#event:beforeCreate} event. + * + * @example + * function onBeforeCreate (mapperName, props, opts) { + * // do something + * } + * store.on('beforeCreate', onBeforeCreate) + * + * @callback SimpleStore~beforeCreateListener + * @param {string} name The `name` argument received by {@link Mapper#beforeCreate}. + * @param {Object} props The `props` argument received by {@link Mapper#beforeCreate}. + * @param {Object} opts The `opts` argument received by {@link Mapper#beforeCreate}. + * @see SimpleStore#event:beforeCreate + * @see SimpleStore#create + * @since 3.0.0 + *//** + * Fired during {@link SimpleStore#create}. See + * {@link SimpleStore~afterCreateListener} for how to listen for this event. + * + * @event SimpleStore#afterCreate + * @see SimpleStore~afterCreateListener + * @see SimpleStore#create + *//** + * Callback signature for the {@link SimpleStore#event:afterCreate} event. + * + * @example + * function onAfterCreate (mapperName, props, opts, result) { + * // do something + * } + * store.on('afterCreate', onAfterCreate) + * + * @callback SimpleStore~afterCreateListener + * @param {string} name The `name` argument received by {@link Mapper#afterCreate}. + * @param {Object} props The `props` argument received by {@link Mapper#afterCreate}. + * @param {Object} opts The `opts` argument received by {@link Mapper#afterCreate}. + * @param {Object} result The `result` argument received by {@link Mapper#afterCreate}. + * @see SimpleStore#event:afterCreate + * @see SimpleStore#create + * @since 3.0.0 + *//** + * Wrapper for {@link Mapper#create}. Adds the created record to the store. + * + * @example + * import {SimpleStore} from 'js-data' + * import {HttpAdapter} from 'js-data-http' + * + * const store = new SimpleStore() + * store.registerAdapter('http', new HttpAdapter(), { default: true }) + * + * store.defineMapper('book') + * + * // Since this example uses the http adapter, we'll get something like: + * // + * // POST /book {"author_id":1234,...} + * store.create('book', { + * author_id: 1234, + * edition: 'First Edition', + * title: 'Respect your Data' + * }).then((book) => { + * console.log(book.id) // 120392 + * console.log(book.title) // "Respect your Data" + * }) + * + * @fires SimpleStore#beforeCreate + * @fires SimpleStore#afterCreate + * @fires SimpleStore#add + * @method SimpleStore#create + * @param {string} name Name of the {@link Mapper} to target. + * @param {Object} record Passed to {@link Mapper#create}. + * @param {Object} [opts] Passed to {@link Mapper#create}. See + * {@link Mapper#create} for more configuration options. + * @returns {Promise} Resolves with the result of the create. + * @since 3.0.0 + */create:function create(name,record,opts){var _this4=this;opts||(opts={});return Container.prototype.create.call(this,name,record,opts).then(function(result){return _this4._end(name,result,opts);});},/** + * Fired during {@link SimpleStore#createMany}. See + * {@link SimpleStore~beforeCreateManyListener} for how to listen for this event. + * + * @event SimpleStore#beforeCreateMany + * @see SimpleStore~beforeCreateManyListener + * @see SimpleStore#createMany + *//** + * Callback signature for the {@link SimpleStore#event:beforeCreateMany} event. + * + * @example + * function onBeforeCreateMany (mapperName, records, opts) { + * // do something + * } + * store.on('beforeCreateMany', onBeforeCreateMany) + * + * @callback SimpleStore~beforeCreateManyListener + * @param {string} name The `name` argument received by {@link Mapper#beforeCreateMany}. + * @param {Object} records The `records` argument received by {@link Mapper#beforeCreateMany}. + * @param {Object} opts The `opts` argument received by {@link Mapper#beforeCreateMany}. + * @see SimpleStore#event:beforeCreateMany + * @see SimpleStore#createMany + * @since 3.0.0 + *//** + * Fired during {@link SimpleStore#createMany}. See + * {@link SimpleStore~afterCreateManyListener} for how to listen for this event. + * + * @event SimpleStore#afterCreateMany + * @see SimpleStore~afterCreateManyListener + * @see SimpleStore#createMany + *//** + * Callback signature for the {@link SimpleStore#event:afterCreateMany} event. + * + * @example + * function onAfterCreateMany (mapperName, records, opts, result) { + * // do something + * } + * store.on('afterCreateMany', onAfterCreateMany) + * + * @callback SimpleStore~afterCreateManyListener + * @param {string} name The `name` argument received by {@link Mapper#afterCreateMany}. + * @param {Object} records The `records` argument received by {@link Mapper#afterCreateMany}. + * @param {Object} opts The `opts` argument received by {@link Mapper#afterCreateMany}. + * @param {Object} result The `result` argument received by {@link Mapper#afterCreateMany}. + * @see SimpleStore#event:afterCreateMany + * @see SimpleStore#createMany + * @since 3.0.0 + *//** + * Wrapper for {@link Mapper#createMany}. Adds the created records to the + * store. + * + * @example + * import {SimpleStore} from 'js-data' + * import {HttpAdapter} from 'js-data-http' + * + * const store = new SimpleStore() + * store.registerAdapter('http', new HttpAdapter(), { default: true }) + * + * store.defineMapper('book') + * + * // Since this example uses the http adapter, we'll get something like: + * // + * // POST /book [{"author_id":1234,...},{...}] + * store.createMany('book', [{ + * author_id: 1234, + * edition: 'First Edition', + * title: 'Respect your Data' + * }, { + * author_id: 1234, + * edition: 'Second Edition', + * title: 'Respect your Data' + * }]).then((books) => { + * console.log(books[0].id) // 142394 + * console.log(books[0].title) // "Respect your Data" + * }) + * + * @fires SimpleStore#beforeCreateMany + * @fires SimpleStore#afterCreateMany + * @fires SimpleStore#add + * @method SimpleStore#createMany + * @param {string} name Name of the {@link Mapper} to target. + * @param {Array} records Passed to {@link Mapper#createMany}. + * @param {Object} [opts] Passed to {@link Mapper#createMany}. See + * {@link Mapper#createMany} for more configuration options. + * @returns {Promise} Resolves with the result of the create. + * @since 3.0.0 + */createMany:function createMany(name,records,opts){var _this5=this;opts||(opts={});return Container.prototype.createMany.call(this,name,records,opts).then(function(result){return _this5._end(name,result,opts);});},defineMapper:function defineMapper(name,opts){var self=this;var mapper=Container.prototype.defineMapper.call(self,name,opts);self._pendingQueries[name]={};self._completedQueries[name]={};mapper.relationList||Object.defineProperty(mapper,'relationList',{value:[]});// The SimpleStore uses a subclass of Collection that is "SimpleStore-aware" +var collection=self._collections[name]=new self.collectionClass(null,{// eslint-disable-line +// Make sure the collection has somewhere to store "added" timestamps +_added:{},// Give the collection a reference to this SimpleStore +datastore:self,// The mapper tied to the collection +mapper:mapper});var schema=mapper.schema||{};var properties=schema.properties||{};// TODO: Make it possible index nested properties? +utils.forOwn(properties,function(opts,prop){if(opts.indexed){collection.createIndex(prop);}});// Create a secondary index on the "added" timestamps of records in the +// collection +collection.createIndex('addedTimestamps',['$'],{fieldGetter:function fieldGetter(obj){return collection._added[collection.recordId(obj)];}});collection.on('all',function(){for(var _len3=arguments.length,args=Array(_len3),_key3=0;_key3<_len3;_key3++){args[_key3]=arguments[_key3];}self._onCollectionEvent.apply(self,[name].concat(args));});return mapper;},/** + * Fired during {@link SimpleStore#destroy}. See + * {@link SimpleStore~beforeDestroyListener} for how to listen for this event. + * + * @event SimpleStore#beforeDestroy + * @see SimpleStore~beforeDestroyListener + * @see SimpleStore#destroy + *//** + * Callback signature for the {@link SimpleStore#event:beforeDestroy} event. + * + * @example + * function onBeforeDestroy (mapperName, id, opts) { + * // do something + * } + * store.on('beforeDestroy', onBeforeDestroy) + * + * @callback SimpleStore~beforeDestroyListener + * @param {string} name The `name` argument received by {@link Mapper#beforeDestroy}. + * @param {string|number} id The `id` argument received by {@link Mapper#beforeDestroy}. + * @param {Object} opts The `opts` argument received by {@link Mapper#beforeDestroy}. + * @see SimpleStore#event:beforeDestroy + * @see SimpleStore#destroy + * @since 3.0.0 + *//** + * Fired during {@link SimpleStore#destroy}. See + * {@link SimpleStore~afterDestroyListener} for how to listen for this event. + * + * @event SimpleStore#afterDestroy + * @see SimpleStore~afterDestroyListener + * @see SimpleStore#destroy + *//** + * Callback signature for the {@link SimpleStore#event:afterDestroy} event. + * + * @example + * function onAfterDestroy (mapperName, id, opts, result) { + * // do something + * } + * store.on('afterDestroy', onAfterDestroy) + * + * @callback SimpleStore~afterDestroyListener + * @param {string} name The `name` argument received by {@link Mapper#afterDestroy}. + * @param {string|number} id The `id` argument received by {@link Mapper#afterDestroy}. + * @param {Object} opts The `opts` argument received by {@link Mapper#afterDestroy}. + * @param {Object} result The `result` argument received by {@link Mapper#afterDestroy}. + * @see SimpleStore#event:afterDestroy + * @see SimpleStore#destroy + * @since 3.0.0 + *//** + * Wrapper for {@link Mapper#destroy}. Removes any destroyed record from the + * in-memory store. Clears out any {@link SimpleStore#_completedQueries} entries + * associated with the provided `id`. + * + * @example + * import {SimpleStore} from 'js-data' + * import {HttpAdapter} from 'js-data-http' + * + * const store = new SimpleStore() + * store.registerAdapter('http', new HttpAdapter(), { default: true }) + * + * store.defineMapper('book') + * + * store.add('book', { id: 1234, title: 'Data Management is Hard' }) + * + * // Since this example uses the http adapter, we'll get something like: + * // + * // DELETE /book/1234 + * store.destroy('book', 1234).then(() => { + * // The book record is no longer in the in-memory store + * console.log(store.get('book', 1234)) // undefined + * + * return store.find('book', 1234) + * }).then((book) { + * // The book was deleted from the database too + * console.log(book) // undefined + * }) + * + * @fires SimpleStore#beforeDestroy + * @fires SimpleStore#afterDestroy + * @fires SimpleStore#remove + * @method SimpleStore#destroy + * @param {string} name Name of the {@link Mapper} to target. + * @param {(string|number)} id Passed to {@link Mapper#destroy}. + * @param {Object} [opts] Passed to {@link Mapper#destroy}. See + * {@link Mapper#destroy} for more configuration options. + * @returns {Promise} Resolves when the destroy operation completes. + * @since 3.0.0 + */destroy:function destroy(name,id,opts){var _this6=this;opts||(opts={});return Container.prototype.destroy.call(this,name,id,opts).then(function(result){var record=_this6.getCollection(name).remove(id,opts);if(opts.raw){result.data=record;}else{result=record;}delete _this6._pendingQueries[name][id];delete _this6._completedQueries[name][id];return result;});},/** + * Fired during {@link SimpleStore#destroyAll}. See + * {@link SimpleStore~beforeDestroyAllListener} for how to listen for this event. + * + * @event SimpleStore#beforeDestroyAll + * @see SimpleStore~beforeDestroyAllListener + * @see SimpleStore#destroyAll + *//** + * Callback signature for the {@link SimpleStore#event:beforeDestroyAll} event. + * + * @example + * function onBeforeDestroyAll (mapperName, query, opts) { + * // do something + * } + * store.on('beforeDestroyAll', onBeforeDestroyAll) + * + * @callback SimpleStore~beforeDestroyAllListener + * @param {string} name The `name` argument received by {@link Mapper#beforeDestroyAll}. + * @param {Object} query The `query` argument received by {@link Mapper#beforeDestroyAll}. + * @param {Object} opts The `opts` argument received by {@link Mapper#beforeDestroyAll}. + * @see SimpleStore#event:beforeDestroyAll + * @see SimpleStore#destroyAll + * @since 3.0.0 + *//** + * Fired during {@link SimpleStore#destroyAll}. See + * {@link SimpleStore~afterDestroyAllListener} for how to listen for this event. + * + * @event SimpleStore#afterDestroyAll + * @see SimpleStore~afterDestroyAllListener + * @see SimpleStore#destroyAll + *//** + * Callback signature for the {@link SimpleStore#event:afterDestroyAll} event. + * + * @example + * function onAfterDestroyAll (mapperName, query, opts, result) { + * // do something + * } + * store.on('afterDestroyAll', onAfterDestroyAll) + * + * @callback SimpleStore~afterDestroyAllListener + * @param {string} name The `name` argument received by {@link Mapper#afterDestroyAll}. + * @param {Object} query The `query` argument received by {@link Mapper#afterDestroyAll}. + * @param {Object} opts The `opts` argument received by {@link Mapper#afterDestroyAll}. + * @param {Object} result The `result` argument received by {@link Mapper#afterDestroyAll}. + * @see SimpleStore#event:afterDestroyAll + * @see SimpleStore#destroyAll + * @since 3.0.0 + *//** + * Wrapper for {@link Mapper#destroyAll}. Removes any destroyed records from + * the in-memory store. + * + * @example + * import {SimpleStore} from 'js-data' + * import {HttpAdapter} from 'js-data-http' + * + * const store = new SimpleStore() + * store.registerAdapter('http', new HttpAdapter(), { default: true }) + * + * store.defineMapper('book') + * + * store.add('book', { id: 1234, title: 'Data Management is Hard' }) + * + * // Since this example uses the http adapter, we'll get something like: + * // + * // DELETE /book/1234 + * store.destroy('book', 1234).then(() => { + * // The book record is gone from the in-memory store + * console.log(store.get('book', 1234)) // undefined + * return store.find('book', 1234) + * }).then((book) { + * // The book was deleted from the database too + * console.log(book) // undefined + * }) + * + * @fires SimpleStore#beforeDestroyAll + * @fires SimpleStore#afterDestroyAll + * @fires SimpleStore#remove + * @method SimpleStore#destroyAll + * @param {string} name Name of the {@link Mapper} to target. + * @param {Object} [query] Passed to {@link Mapper#destroyAll}. + * @param {Object} [opts] Passed to {@link Mapper#destroyAll}. See + * {@link Mapper#destroyAll} for more configuration options. + * @returns {Promise} Resolves when the delete completes. + * @since 3.0.0 + */destroyAll:function destroyAll(name,query,opts){var _this7=this;opts||(opts={});return Container.prototype.destroyAll.call(this,name,query,opts).then(function(result){var records=_this7.getCollection(name).removeAll(query,opts);if(opts.raw){result.data=records;}else{result=records;}var hash=_this7.hashQuery(name,query,opts);delete _this7._pendingQueries[name][hash];delete _this7._completedQueries[name][hash];return result;});},eject:function eject(name,id,opts){console.warn('DEPRECATED: "eject" is deprecated, use "remove" instead');return this.remove(name,id,opts);},ejectAll:function ejectAll(name,query,opts){console.warn('DEPRECATED: "ejectAll" is deprecated, use "removeAll" instead');return this.removeAll(name,query,opts);},/** + * Fired during {@link SimpleStore#find}. See + * {@link SimpleStore~beforeFindListener} for how to listen for this event. + * + * @event SimpleStore#beforeFind + * @see SimpleStore~beforeFindListener + * @see SimpleStore#find + *//** + * Callback signature for the {@link SimpleStore#event:beforeFind} event. + * + * @example + * function onBeforeFind (mapperName, id, opts) { + * // do something + * } + * store.on('beforeFind', onBeforeFind) + * + * @callback SimpleStore~beforeFindListener + * @param {string} name The `name` argument received by {@link Mapper#beforeFind}. + * @param {string|number} id The `id` argument received by {@link Mapper#beforeFind}. + * @param {Object} opts The `opts` argument received by {@link Mapper#beforeFind}. + * @see SimpleStore#event:beforeFind + * @see SimpleStore#find + * @since 3.0.0 + *//** + * Fired during {@link SimpleStore#find}. See + * {@link SimpleStore~afterFindListener} for how to listen for this event. + * + * @event SimpleStore#afterFind + * @see SimpleStore~afterFindListener + * @see SimpleStore#find + *//** + * Callback signature for the {@link SimpleStore#event:afterFind} event. + * + * @example + * function onAfterFind (mapperName, id, opts, result) { + * // do something + * } + * store.on('afterFind', onAfterFind) + * + * @callback SimpleStore~afterFindListener + * @param {string} name The `name` argument received by {@link Mapper#afterFind}. + * @param {string|number} id The `id` argument received by {@link Mapper#afterFind}. + * @param {Object} opts The `opts` argument received by {@link Mapper#afterFind}. + * @param {Object} result The `result` argument received by {@link Mapper#afterFind}. + * @see SimpleStore#event:afterFind + * @see SimpleStore#find + * @since 3.0.0 + *//** + * Wrapper for {@link Mapper#find}. Adds any found record to the store. + * + * @example + * import {SimpleStore} from 'js-data' + * import {HttpAdapter} from 'js-data-http' + * + * const store = new SimpleStore() + * store.registerAdapter('http', new HttpAdapter(), { default: true }) + * + * store.defineMapper('book') + * + * // Since this example uses the http adapter, we'll get something like: + * // + * // GET /book/1234 + * store.find('book', 1234).then((book) => { + * // The book record is now in the in-memory store + * console.log(store.get('book', 1234) === book) // true + * }) + * + * @fires SimpleStore#beforeFind + * @fires SimpleStore#afterFind + * @fires SimpleStore#add + * @method SimpleStore#find + * @param {string} name Name of the {@link Mapper} to target. + * @param {(string|number)} id Passed to {@link Mapper#find}. + * @param {Object} [opts] Passed to {@link Mapper#find}. + * @param {boolean|Function} [opts.usePendingFind] See {@link SimpleStore#usePendingFind} + * @returns {Promise} Resolves with the result, if any. + * @since 3.0.0 + */find:function find(name,id,opts){var _this8=this;opts||(opts={});var mapper=this.getMapper(name);var pendingQuery=this._pendingQueries[name][id];var usePendingFind=opts.usePendingFind===undefined?this.usePendingFind:opts.usePendingFind;utils._(opts,mapper);if(pendingQuery&&(utils.isFunction(usePendingFind)?usePendingFind.call(this,name,id,opts):usePendingFind)){return pendingQuery;}var item=this.cachedFind(name,id,opts);var promise=void 0;if(opts.force||!item){promise=this._pendingQueries[name][id]=Container.prototype.find.call(this,name,id,opts).then(function(result){delete _this8._pendingQueries[name][id];result=_this8._end(name,result,opts);_this8.cacheFind(name,result,id,opts);return result;},function(err){delete _this8._pendingQueries[name][id];return utils.reject(err);});}else{promise=utils.resolve(item);}return promise;},/** + * Fired during {@link SimpleStore#findAll}. See + * {@link SimpleStore~beforeFindAllListener} for how to listen for this event. + * + * @event SimpleStore#beforeFindAll + * @see SimpleStore~beforeFindAllListener + * @see SimpleStore#findAll + *//** + * Callback signature for the {@link SimpleStore#event:beforeFindAll} event. + * + * @example + * function onBeforeFindAll (mapperName, query, opts) { + * // do something + * } + * store.on('beforeFindAll', onBeforeFindAll) + * + * @callback SimpleStore~beforeFindAllListener + * @param {string} name The `name` argument received by {@link Mapper#beforeFindAll}. + * @param {Object} query The `query` argument received by {@link Mapper#beforeFindAll}. + * @param {Object} opts The `opts` argument received by {@link Mapper#beforeFindAll}. + * @see SimpleStore#event:beforeFindAll + * @see SimpleStore#findAll + * @since 3.0.0 + *//** + * Fired during {@link SimpleStore#findAll}. See + * {@link SimpleStore~afterFindAllListener} for how to listen for this event. + * + * @event SimpleStore#afterFindAll + * @see SimpleStore~afterFindAllListener + * @see SimpleStore#findAll + *//** + * Callback signature for the {@link SimpleStore#event:afterFindAll} event. + * + * @example + * function onAfterFindAll (mapperName, query, opts, result) { + * // do something + * } + * store.on('afterFindAll', onAfterFindAll) + * + * @callback SimpleStore~afterFindAllListener + * @param {string} name The `name` argument received by {@link Mapper#afterFindAll}. + * @param {Object} query The `query` argument received by {@link Mapper#afterFindAll}. + * @param {Object} opts The `opts` argument received by {@link Mapper#afterFindAll}. + * @param {Object} result The `result` argument received by {@link Mapper#afterFindAll}. + * @see SimpleStore#event:afterFindAll + * @see SimpleStore#findAll + * @since 3.0.0 + *//** + * Wrapper for {@link Mapper#findAll}. Adds any found records to the store. + * + * @example + * import {SimpleStore} from 'js-data' + * import {HttpAdapter} from 'js-data-http' + * + * const store = new SimpleStore() + * store.registerAdapter('http', new HttpAdapter(), { default: true }) + * + * store.defineMapper('movie') + * + * // Since this example uses the http adapter, we'll get something like: + * // + * // GET /movie?rating=PG + * store.find('movie', { rating: 'PG' }).then((movies) => { + * // The movie records are now in the in-memory store + * console.log(store.filter('movie')) + * }) + * + * @fires SimpleStore#beforeFindAll + * @fires SimpleStore#afterFindAll + * @fires SimpleStore#add + * @method SimpleStore#findAll + * @param {string} name Name of the {@link Mapper} to target. + * @param {Object} [query] Passed to {@link Mapper.findAll}. + * @param {Object} [opts] Passed to {@link Mapper.findAll}. + * @param {boolean|Function} [opts.usePendingFindAll] See {@link SimpleStore#usePendingFindAll} + * @returns {Promise} Resolves with the result, if any. + * @since 3.0.0 + */findAll:function findAll(name,query,opts){var _this9=this;opts||(opts={});var mapper=this.getMapper(name);var hash=this.hashQuery(name,query,opts);var pendingQuery=this._pendingQueries[name][hash];var usePendingFindAll=opts.usePendingFindAll===undefined?this.usePendingFindAll:opts.usePendingFindAll;utils._(opts,mapper);if(pendingQuery&&(utils.isFunction(usePendingFindAll)?usePendingFindAll.call(this,name,query,opts):usePendingFindAll)){return pendingQuery;}var items=this.cachedFindAll(name,hash,opts);var promise=void 0;if(opts.force||!items){promise=this._pendingQueries[name][hash]=Container.prototype.findAll.call(this,name,query,opts).then(function(result){delete _this9._pendingQueries[name][hash];result=_this9._end(name,result,opts);_this9.cacheFindAll(name,result,hash,opts);return result;},function(err){delete _this9._pendingQueries[name][hash];return utils.reject(err);});}else{promise=utils.resolve(items);}return promise;},/** + * Return the {@link Collection} with the given name, if for some + * reason you need a direct reference to the collection. + * + * @method SimpleStore#getCollection + * @param {string} name Name of the {@link Collection} to retrieve. + * @returns {Collection} + * @since 3.0.0 + * @throws {Error} Thrown if the specified {@link Collection} does not + * exist. + */getCollection:function getCollection(name){var collection=this._collections[name];if(!collection){throw utils.err(DOMAIN$9+'#getCollection',name)(404,'collection');}return collection;},/** + * Hashing function used to cache {@link SimpleStore#find} and + * {@link SimpleStore#findAll} requests. This method simply JSONifies the + * `query` argument passed to {@link SimpleStore#find} or + * {@link SimpleStore#findAll}. + * + * Override this method for custom hashing behavior. + * @method SimpleStore#hashQuery + * @param {string} name The `name` argument passed to {@link SimpleStore#find} + * or {@link SimpleStore#findAll}. + * @param {Object} query The `query` argument passed to {@link SimpleStore#find} + * or {@link SimpleStore#findAll}. + * @returns {string} The JSONified `query`. + * @since 3.0.0 + */hashQuery:function hashQuery(name,query,opts){return utils.toJson(query);},inject:function inject(name,records,opts){console.warn('DEPRECATED: "inject" is deprecated, use "add" instead');return this.add(name,records,opts);},/** + * Wrapper for {@link Collection#remove}. Removes the specified + * {@link Record} from the store. + * + * @example SimpleStore#remove + * // Normally you would do: import {SimpleStore} from 'js-data' + * const JSData = require('js-data@3.0.0-rc.4') + * const {SimpleStore} = JSData + * console.log('Using JSData v' + JSData.version.full) + * + * const store = new SimpleStore() + * store.defineMapper('book') + * console.log(store.getAll('book').length) + * store.add('book', { id: 1234 }) + * console.log(store.getAll('book').length) + * store.remove('book', 1234) + * console.log(store.getAll('book').length) + * + * @fires SimpleStore#remove + * @method SimpleStore#remove + * @param {string} name The name of the {@link Collection} to target. + * @param {string|number} id The primary key of the {@link Record} to remove. + * @param {Object} [opts] Configuration options. + * @param {string[]} [opts.with] Relations of the {@link Record} to also + * remove from the store. + * @returns {Record} The removed {@link Record}, if any. + * @see Collection#add + * @see Collection#add + * @since 3.0.0 + */remove:function remove(name,id,opts){var record=this.getCollection(name).remove(id,opts);if(record){this.removeRelated(name,[record],opts);}return record;},/** + * Wrapper for {@link Collection#removeAll}. Removes the selected + * {@link Record}s from the store. + * + * @example SimpleStore#removeAll + * // Normally you would do: import {SimpleStore} from 'js-data' + * const JSData = require('js-data@3.0.0-rc.4') + * const {SimpleStore} = JSData + * console.log('Using JSData v' + JSData.version.full) + * + * const store = new SimpleStore() + * store.defineMapper('movie') + * console.log(store.getAll('movie').length) + * store.add('movie', [{ id: 3, rating: 'R' }, { id: 4, rating: 'PG-13' }) + * console.log(store.getAll('movie').length) + * store.removeAll('movie', { rating: 'R' }) + * console.log(store.getAll('movie').length) + * + * @fires SimpleStore#remove + * @method SimpleStore#removeAll + * @param {string} name The name of the {@link Collection} to target. + * @param {Object} [query={}] Selection query. See {@link query}. + * @param {Object} [query.where] See {@link query.where}. + * @param {number} [query.offset] See {@link query.offset}. + * @param {number} [query.limit] See {@link query.limit}. + * @param {string|Array[]} [query.orderBy] See {@link query.orderBy}. + * @param {Object} [opts] Configuration options. + * @param {string[]} [opts.with] Relations of the {@link Record} to also + * remove from the store. + * @returns {Record} The removed {@link Record}s, if any. + * @see Collection#add + * @see Collection#add + * @since 3.0.0 + */removeAll:function removeAll(name,query,opts){var records=this.getCollection(name).removeAll(query,opts);if(records.length){this.removeRelated(name,records,opts);}return records;},/** + * Remove from the store {@link Record}s that are related to the provided + * {@link Record}(s). + * + * @fires SimpleStore#remove + * @method SimpleStore#removeRelated + * @param {string} name The name of the {@link Collection} to target. + * @param {Record|Record[]} records {@link Record}s whose relations are to be + * removed. + * @param {Object} [opts] Configuration options. + * @param {string[]} [opts.with] Relations of the {@link Record}(s) to remove + * from the store. + * @since 3.0.0 + */removeRelated:function removeRelated(name,records,opts){var _this10=this;if(!utils.isArray(records)){records=[records];}utils.forEachRelation(this.getMapper(name),opts,function(def,optsCopy){records.forEach(function(record){var relatedData=void 0;var query=void 0;if(def.foreignKey&&(def.type===hasOneType||def.type===hasManyType)){query=defineProperty({},def.foreignKey,def.getForeignKey(record));}else if(def.type===hasManyType&&def.localKeys){query={where:defineProperty({},def.getRelation().idAttribute,{'in':utils.get(record,def.localKeys)})};}else if(def.type===hasManyType&&def.foreignKeys){query={where:defineProperty({},def.foreignKeys,{'contains':def.getForeignKey(record)})};}else if(def.type===belongsToType){relatedData=_this10.remove(def.relation,def.getForeignKey(record),optsCopy);}if(query){relatedData=_this10.removeAll(def.relation,query,optsCopy);}if(relatedData){if(utils.isArray(relatedData)&&!relatedData.length){return;}if(def.type===hasOneType){relatedData=relatedData[0];}def.setLocalField(record,relatedData);}});});},/** + * Fired during {@link SimpleStore#update}. See + * {@link SimpleStore~beforeUpdateListener} for how to listen for this event. + * + * @event SimpleStore#beforeUpdate + * @see SimpleStore~beforeUpdateListener + * @see SimpleStore#update + *//** + * Callback signature for the {@link SimpleStore#event:beforeUpdate} event. + * + * @example + * function onBeforeUpdate (mapperName, id, props, opts) { + * // do something + * } + * store.on('beforeUpdate', onBeforeUpdate) + * + * @callback SimpleStore~beforeUpdateListener + * @param {string} name The `name` argument received by {@link Mapper#beforeUpdate}. + * @param {string|number} id The `id` argument received by {@link Mapper#beforeUpdate}. + * @param {Object} props The `props` argument received by {@link Mapper#beforeUpdate}. + * @param {Object} opts The `opts` argument received by {@link Mapper#beforeUpdate}. + * @see SimpleStore#event:beforeUpdate + * @see SimpleStore#update + * @since 3.0.0 + *//** + * Fired during {@link SimpleStore#update}. See + * {@link SimpleStore~afterUpdateListener} for how to listen for this event. + * + * @event SimpleStore#afterUpdate + * @see SimpleStore~afterUpdateListener + * @see SimpleStore#update + *//** + * Callback signature for the {@link SimpleStore#event:afterUpdate} event. + * + * @example + * function onAfterUpdate (mapperName, id, props, opts, result) { + * // do something + * } + * store.on('afterUpdate', onAfterUpdate) + * + * @callback SimpleStore~afterUpdateListener + * @param {string} name The `name` argument received by {@link Mapper#afterUpdate}. + * @param {string|number} id The `id` argument received by {@link Mapper#afterUpdate}. + * @param {Object} props The `props` argument received by {@link Mapper#afterUpdate}. + * @param {Object} opts The `opts` argument received by {@link Mapper#afterUpdate}. + * @param {Object} result The `result` argument received by {@link Mapper#afterUpdate}. + * @see SimpleStore#event:afterUpdate + * @see SimpleStore#update + * @since 3.0.0 + *//** + * Wrapper for {@link Mapper#update}. Adds the updated {@link Record} to the + * store. + * + * @example + * import {SimpleStore} from 'js-data' + * import {HttpAdapter} from 'js-data-http' + * + * const store = new SimpleStore() + * store.registerAdapter('http', new HttpAdapter(), { default: true }) + * + * store.defineMapper('post') + * + * // Since this example uses the http adapter, we'll get something like: + * // + * // PUT /post/1234 {"status":"published"} + * store.update('post', 1, { status: 'published' }).then((post) => { + * // The post record has also been updated in the in-memory store + * console.log(store.get('post', 1234)) + * }) + * + * @fires SimpleStore#beforeUpdate + * @fires SimpleStore#afterUpdate + * @fires SimpleStore#add + * @method SimpleStore#update + * @param {string} name Name of the {@link Mapper} to target. + * @param {(string|number)} id Passed to {@link Mapper#update}. + * @param {Object} record Passed to {@link Mapper#update}. + * @param {Object} [opts] Passed to {@link Mapper#update}. See + * {@link Mapper#update} for more configuration options. + * @returns {Promise} Resolves with the result of the update. + * @since 3.0.0 + */update:function update(name,id,record,opts){var _this11=this;opts||(opts={});return Container.prototype.update.call(this,name,id,record,opts).then(function(result){return _this11._end(name,result,opts);});},/** + * Fired during {@link SimpleStore#updateAll}. See + * {@link SimpleStore~beforeUpdateAllListener} for how to listen for this event. + * + * @event SimpleStore#beforeUpdateAll + * @see SimpleStore~beforeUpdateAllListener + * @see SimpleStore#updateAll + *//** + * Callback signature for the {@link SimpleStore#event:beforeUpdateAll} event. + * + * @example + * function onBeforeUpdateAll (mapperName, props, query, opts) { + * // do something + * } + * store.on('beforeUpdateAll', onBeforeUpdateAll) + * + * @callback SimpleStore~beforeUpdateAllListener + * @param {string} name The `name` argument received by {@link Mapper#beforeUpdateAll}. + * @param {Object} props The `props` argument received by {@link Mapper#beforeUpdateAll}. + * @param {Object} query The `query` argument received by {@link Mapper#beforeUpdateAll}. + * @param {Object} opts The `opts` argument received by {@link Mapper#beforeUpdateAll}. + * @see SimpleStore#event:beforeUpdateAll + * @see SimpleStore#updateAll + * @since 3.0.0 + *//** + * Fired during {@link SimpleStore#updateAll}. See + * {@link SimpleStore~afterUpdateAllListener} for how to listen for this event. + * + * @event SimpleStore#afterUpdateAll + * @see SimpleStore~afterUpdateAllListener + * @see SimpleStore#updateAll + *//** + * Callback signature for the {@link SimpleStore#event:afterUpdateAll} event. + * + * @example + * function onAfterUpdateAll (mapperName, props, query, opts, result) { + * // do something + * } + * store.on('afterUpdateAll', onAfterUpdateAll) + * + * @callback SimpleStore~afterUpdateAllListener + * @param {string} name The `name` argument received by {@link Mapper#afterUpdateAll}. + * @param {Object} props The `props` argument received by {@link Mapper#afterUpdateAll}. + * @param {Object} query The `query` argument received by {@link Mapper#afterUpdateAll}. + * @param {Object} opts The `opts` argument received by {@link Mapper#afterUpdateAll}. + * @param {Object} result The `result` argument received by {@link Mapper#afterUpdateAll}. + * @see SimpleStore#event:afterUpdateAll + * @see SimpleStore#updateAll + * @since 3.0.0 + *//** + * Wrapper for {@link Mapper#updateAll}. Adds the updated {@link Record}s to + * the store. + * + * @example + * import {SimpleStore} from 'js-data' + * import {HttpAdapter} from 'js-data-http' + * + * const store = new SimpleStore() + * store.registerAdapter('http', new HttpAdapter(), { default: true }) + * + * store.defineMapper('post') + * + * // Since this example uses the http adapter, we'll get something like: + * // + * // PUT /post?author_id=1234 {"status":"published"} + * store.updateAll('post', { author_id: 1234 }, { status: 'published' }).then((posts) => { + * // The post records have also been updated in the in-memory store + * console.log(store.filter('posts', { author_id: 1234 })) + * }) + * + * @fires SimpleStore#beforeUpdateAll + * @fires SimpleStore#afterUpdateAll + * @fires SimpleStore#add + * @method SimpleStore#updateAll + * @param {string} name Name of the {@link Mapper} to target. + * @param {Object} props Passed to {@link Mapper#updateAll}. + * @param {Object} [query] Passed to {@link Mapper#updateAll}. + * @param {Object} [opts] Passed to {@link Mapper#updateAll}. See + * {@link Mapper#updateAll} for more configuration options. + * @returns {Promise} Resolves with the result of the update. + * @since 3.0.0 + */updateAll:function updateAll(name,props,query,opts){var _this12=this;opts||(opts={});return Container.prototype.updateAll.call(this,name,query,props,opts).then(function(result){return _this12._end(name,result,opts);});},/** + * Fired during {@link SimpleStore#updateMany}. See + * {@link SimpleStore~beforeUpdateManyListener} for how to listen for this event. + * + * @event SimpleStore#beforeUpdateMany + * @see SimpleStore~beforeUpdateManyListener + * @see SimpleStore#updateMany + *//** + * Callback signature for the {@link SimpleStore#event:beforeUpdateMany} event. + * + * @example + * function onBeforeUpdateMany (mapperName, records, opts) { + * // do something + * } + * store.on('beforeUpdateMany', onBeforeUpdateMany) + * + * @callback SimpleStore~beforeUpdateManyListener + * @param {string} name The `name` argument received by {@link Mapper#beforeUpdateMany}. + * @param {Object} records The `records` argument received by {@link Mapper#beforeUpdateMany}. + * @param {Object} opts The `opts` argument received by {@link Mapper#beforeUpdateMany}. + * @see SimpleStore#event:beforeUpdateMany + * @see SimpleStore#updateMany + * @since 3.0.0 + *//** + * Fired during {@link SimpleStore#updateMany}. See + * {@link SimpleStore~afterUpdateManyListener} for how to listen for this event. + * + * @event SimpleStore#afterUpdateMany + * @see SimpleStore~afterUpdateManyListener + * @see SimpleStore#updateMany + *//** + * Callback signature for the {@link SimpleStore#event:afterUpdateMany} event. + * + * @example + * function onAfterUpdateMany (mapperName, records, opts, result) { + * // do something + * } + * store.on('afterUpdateMany', onAfterUpdateMany) + * + * @callback SimpleStore~afterUpdateManyListener + * @param {string} name The `name` argument received by {@link Mapper#afterUpdateMany}. + * @param {Object} records The `records` argument received by {@link Mapper#afterUpdateMany}. + * @param {Object} opts The `opts` argument received by {@link Mapper#afterUpdateMany}. + * @param {Object} result The `result` argument received by {@link Mapper#afterUpdateMany}. + * @see SimpleStore#event:afterUpdateMany + * @see SimpleStore#updateMany + * @since 3.0.0 + *//** + * Wrapper for {@link Mapper#updateMany}. Adds the updated {@link Record}s to + * the store. + * + * @example + * import {SimpleStore} from 'js-data' + * import {HttpAdapter} from 'js-data-http' + * + * const store = new SimpleStore() + * store.registerAdapter('http', new HttpAdapter(), { default: true }) + * + * store.defineMapper('post') + * + * // Since this example uses the http adapter, we'll get something like: + * // + * // PUT /post [{"id":3,status":"published"},{"id":4,status":"published"}] + * store.updateMany('post', [ + * { id: 3, status: 'published' }, + * { id: 4, status: 'published' } + * ]).then((posts) => { + * // The post records have also been updated in the in-memory store + * console.log(store.getAll('post', 3, 4)) + * }) + * + * @fires SimpleStore#beforeUpdateMany + * @fires SimpleStore#afterUpdateMany + * @fires SimpleStore#add + * @method SimpleStore#updateMany + * @param {string} name Name of the {@link Mapper} to target. + * @param {(Object[]|Record[])} records Passed to {@link Mapper#updateMany}. + * @param {Object} [opts] Passed to {@link Mapper#updateMany}. See + * {@link Mapper#updateMany} for more configuration options. + * @returns {Promise} Resolves with the result of the update. + * @since 3.0.0 + */updateMany:function updateMany(name,records,opts){var _this13=this;opts||(opts={});return Container.prototype.updateMany.call(this,name,records,opts).then(function(result){return _this13._end(name,result,opts);});}};proxiedCollectionMethods.forEach(function(method){props$2[method]=function(name){var _getCollection;for(var _len4=arguments.length,args=Array(_len4>1?_len4-1:0),_key4=1;_key4<_len4;_key4++){args[_key4-1]=arguments[_key4];}return(_getCollection=this.getCollection(name))[method].apply(_getCollection,args);};});var SimpleStore$1=Container.extend(props$2);/** + * Fired when a record changes. Only works for records that have tracked fields. + * See {@link SimpleStore~changeListener} on how to listen for this event. + * + * @event SimpleStore#change + * @see SimpleStore~changeListener + *//** + * Callback signature for the {@link SimpleStore#event:change} event. + * + * @example + * function onChange (mapperName, record, changes) { + * // do something + * } + * store.on('change', onChange) + * + * @callback SimpleStore~changeListener + * @param {string} name The name of the associated {@link Mapper}. + * @param {Record} record The Record that changed. + * @param {Object} changes The changes. + * @see SimpleStore#event:change + * @since 3.0.0 + *//** + * Fired when one or more records are added to the in-memory store. See + * {@link SimpleStore~addListener} on how to listen for this event. + * + * @event SimpleStore#add + * @see SimpleStore~addListener + * @see SimpleStore#event:add + * @see SimpleStore#add + * @see SimpleStore#create + * @see SimpleStore#createMany + * @see SimpleStore#find + * @see SimpleStore#findAll + * @see SimpleStore#update + * @see SimpleStore#updateAll + * @see SimpleStore#updateMany + *//** + * Callback signature for the {@link SimpleStore#event:add} event. + * + * @example + * function onAdd (mapperName, recordOrRecords) { + * // do something + * } + * store.on('add', onAdd) + * + * @callback SimpleStore~addListener + * @param {string} name The name of the associated {@link Mapper}. + * @param {Record|Record[]} The Record or Records that were added. + * @see SimpleStore#event:add + * @see SimpleStore#add + * @see SimpleStore#create + * @see SimpleStore#createMany + * @see SimpleStore#find + * @see SimpleStore#findAll + * @see SimpleStore#update + * @see SimpleStore#updateAll + * @see SimpleStore#updateMany + * @since 3.0.0 + *//** + * Fired when one or more records are removed from the in-memory store. See + * {@link SimpleStore~removeListener} for how to listen for this event. + * + * @event SimpleStore#remove + * @see SimpleStore~removeListener + * @see SimpleStore#event:remove + * @see SimpleStore#clear + * @see SimpleStore#destroy + * @see SimpleStore#destroyAll + * @see SimpleStore#remove + * @see SimpleStore#removeAll + *//** + * Callback signature for the {@link SimpleStore#event:remove} event. + * + * @example + * function onRemove (mapperName, recordsOrRecords) { + * // do something + * } + * store.on('remove', onRemove) + * + * @callback SimpleStore~removeListener + * @param {string} name The name of the associated {@link Mapper}. + * @param {Record|Record[]} Record or Records that were removed. + * @see SimpleStore#event:remove + * @see SimpleStore#clear + * @see SimpleStore#destroy + * @see SimpleStore#destroyAll + * @see SimpleStore#remove + * @see SimpleStore#removeAll + * @since 3.0.0 + *//** + * Create a subclass of this SimpleStore: + * @example SimpleStore.extend + * // Normally you would do: import {SimpleStore} from 'js-data' + * const JSData = require('js-data@3.0.0-rc.4') + * const {SimpleStore} = JSData + * console.log('Using JSData v' + JSData.version.full) + * + * // Extend the class using ES2015 class syntax. + * class CustomSimpleStoreClass extends SimpleStore { + * foo () { return 'bar' } + * static beep () { return 'boop' } + * } + * const customSimpleStore = new CustomSimpleStoreClass() + * console.log(customSimpleStore.foo()) + * console.log(CustomSimpleStoreClass.beep()) + * + * // Extend the class using alternate method. + * const OtherSimpleStoreClass = SimpleStore.extend({ + * foo () { return 'bar' } + * }, { + * beep () { return 'boop' } + * }) + * const otherSimpleStore = new OtherSimpleStoreClass() + * console.log(otherSimpleStore.foo()) + * console.log(OtherSimpleStoreClass.beep()) + * + * // Extend the class, providing a custom constructor. + * function AnotherSimpleStoreClass () { + * SimpleStore.call(this) + * this.created_at = new Date().getTime() + * } + * SimpleStore.extend({ + * constructor: AnotherSimpleStoreClass, + * foo () { return 'bar' } + * }, { + * beep () { return 'boop' } + * }) + * const anotherSimpleStore = new AnotherSimpleStoreClass() + * console.log(anotherSimpleStore.created_at) + * console.log(anotherSimpleStore.foo()) + * console.log(AnotherSimpleStoreClass.beep()) + * + * @method SimpleStore.extend + * @param {Object} [props={}] Properties to add to the prototype of the + * subclass. + * @param {Object} [props.constructor] Provide a custom constructor function + * to be used as the subclass itself. + * @param {Object} [classProps={}] Static properties to add to the subclass. + * @returns {Constructor} Subclass of this SimpleStore class. + * @since 3.0.0 + */var DOMAIN$10='LinkedCollection';/** + * Extends {@link Collection}. Used by a {@link DataStore} to implement an + * Identity Map. + * + * ```javascript + * import {LinkedCollection} from 'js-data' + * ``` + * + * @class LinkedCollection + * @extends Collection + * @param {Array} [records] Initial set of records to insert into the + * collection. See {@link Collection}. + * @param {Object} [opts] Configuration options. See {@link Collection}. + * @returns {Mapper} + */function LinkedCollection(records,opts){utils.classCallCheck(this,LinkedCollection);// Make sure this collection has somewhere to store "added" timestamps +Object.defineProperties(this,{_added:{value:{}},datastore:{writable:true,value:undefined}});Collection$1.call(this,records,opts);// Make sure this collection has a reference to a datastore +if(!this.datastore){throw utils.err('new '+DOMAIN$10,'opts.datastore')(400,'DataStore',this.datastore);}}var LinkedCollection$1=Collection$1.extend({constructor:LinkedCollection,_addMeta:function _addMeta(record,timestamp){// Track when this record was added +this._added[this.recordId(record)]=timestamp;if(utils.isFunction(record._set)){record._set('$',timestamp);}},_clearMeta:function _clearMeta(record){delete this._added[this.recordId(record)];if(utils.isFunction(record._set)){record._set('$');// unset +}},_onRecordEvent:function _onRecordEvent(){for(var _len=arguments.length,args=Array(_len),_key=0;_key<_len;_key++){args[_key]=arguments[_key];}Collection$1.prototype._onRecordEvent.apply(this,args);var event=args[0];// This is a very brute force method +// Lots of room for optimization +if(utils.isString(event)&&event.indexOf('change')===0){this.updateIndexes(args[1]);}},add:function add(records,opts){var _this=this;var mapper=this.mapper;var timestamp=new Date().getTime();var singular=utils.isObject(records)&&!utils.isArray(records);if(singular){records=[records];}records=Collection$1.prototype.add.call(this,records,opts);if(mapper.relationList.length&&records.length){// Check the currently visited record for relations that need to be +// inserted into their respective collections. +mapper.relationList.forEach(function(def){def.addLinkedRecords(records);});}records.forEach(function(record){return _this._addMeta(record,timestamp);});return singular?records[0]:records;},remove:function remove(idOrRecord,opts){var mapper=this.mapper;var record=Collection$1.prototype.remove.call(this,idOrRecord,opts);if(record){this._clearMeta(record);}if(mapper.relationList.length&&record){mapper.relationList.forEach(function(def){def.removeLinkedRecords(mapper,[record]);});}return record;},removeAll:function removeAll(query,opts){var mapper=this.mapper;var records=Collection$1.prototype.removeAll.call(this,query,opts);records.forEach(this._clearMeta,this);if(mapper.relationList.length&&records.length){mapper.relationList.forEach(function(def){def.removeLinkedRecords(mapper,records);});}return records;}});/** + * Create a subclass of this LinkedCollection: + * + * @example LinkedCollection.extend + * // Normally you would do: import {LinkedCollection} from 'js-data' + * const JSData = require('js-data@3.0.0-rc.4') + * const {LinkedCollection} = JSData + * console.log('Using JSData v' + JSData.version.full) + * + * // Extend the class using ES2015 class syntax. + * class CustomLinkedCollectionClass extends LinkedCollection { + * foo () { return 'bar' } + * static beep () { return 'boop' } + * } + * const customLinkedCollection = new CustomLinkedCollectionClass() + * console.log(customLinkedCollection.foo()) + * console.log(CustomLinkedCollectionClass.beep()) + * + * // Extend the class using alternate method. + * const OtherLinkedCollectionClass = LinkedCollection.extend({ + * foo () { return 'bar' } + * }, { + * beep () { return 'boop' } + * }) + * const otherLinkedCollection = new OtherLinkedCollectionClass() + * console.log(otherLinkedCollection.foo()) + * console.log(OtherLinkedCollectionClass.beep()) + * + * // Extend the class, providing a custom constructor. + * function AnotherLinkedCollectionClass () { + * LinkedCollection.call(this) + * this.created_at = new Date().getTime() + * } + * LinkedCollection.extend({ + * constructor: AnotherLinkedCollectionClass, + * foo () { return 'bar' } + * }, { + * beep () { return 'boop' } + * }) + * const anotherLinkedCollection = new AnotherLinkedCollectionClass() + * console.log(anotherLinkedCollection.created_at) + * console.log(anotherLinkedCollection.foo()) + * console.log(AnotherLinkedCollectionClass.beep()) + * + * @method LinkedCollection.extend + * @param {Object} [props={}] Properties to add to the prototype of the + * subclass. + * @param {Object} [props.constructor] Provide a custom constructor function + * to be used as the subclass itself. + * @param {Object} [classProps={}] Static properties to add to the subclass. + * @returns {Constructor} Subclass of this LinkedCollection class. + * @since 3.0.0 + */var DATASTORE_DEFAULTS={/** + * Whether in-memory relations should be unlinked from records after they are + * destroyed. + * + * @default true + * @name DataStore#unlinkOnDestroy + * @since 3.0.0 + * @type {boolean} + */unlinkOnDestroy:true};/** + * The `DataStore` class is an extension of {@link SimpleStore}. Not only does + * `DataStore` manage mappers and store data in collections, it uses the + * {@link LinkedCollection} class to link related records together in memory. + * + * ```javascript + * import {DataStore} from 'js-data' + * ``` + * + * @example + * import {DataStore} from 'js-data' + * import HttpAdapter from 'js-data-http' + * const store = new DataStore() + * + * // DataStore#defineMapper returns a direct reference to the newly created + * // Mapper. + * const UserMapper = store.defineMapper('user') + * + * // DataStore#as returns the store scoped to a particular Mapper. + * const UserStore = store.as('user') + * + * // Call "find" on "UserMapper" (Stateless ORM) + * UserMapper.find(1).then((user) => { + * // retrieved a "user" record via the http adapter, but that's it + * + * // Call "find" on "store" targeting "user" (Stateful DataStore) + * return store.find('user', 1) // same as "UserStore.find(1)" + * }).then((user) => { + * // not only was a "user" record retrieved, but it was added to the + * // store's "user" collection + * const cachedUser = store.getCollection('user').get(1) + * console.log(user === cachedUser) // true + * }) + * + * @class DataStore + * @extends SimpleStore + * @param {Object} [opts] Configuration options. See {@link SimpleStore}. + * @param {boolean} [opts.collectionClass={@link LinkedCollection}] See {@link DataStore#collectionClass}. + * @param {boolean} [opts.debug=false] See {@link Component#debug}. + * @param {boolean} [opts.unlinkOnDestroy=true] See {@link DataStore#unlinkOnDestroy}. + * @param {boolean|Function} [opts.usePendingFind=true] See {@link DataStore#usePendingFind}. + * @param {boolean|Function} [opts.usePendingFindAll=true] See {@link DataStore#usePendingFindAll}. + * @returns {DataStore} + * @see SimpleStore + * @since 3.0.0 + * @tutorial ["http://www.js-data.io/v3.0/docs/components-of-jsdata#datastore","Components of JSData: DataStore"] + * @tutorial ["http://www.js-data.io/v3.0/docs/working-with-the-datastore","Working with the DataStore"] + * @tutorial ["http://www.js-data.io/v3.0/docs/jsdata-and-the-browser","Notes on using JSData in the Browser"] + */function DataStore(opts){utils.classCallCheck(this,DataStore);opts||(opts={});// Fill in any missing options with the defaults +utils.fillIn(opts,DATASTORE_DEFAULTS);opts.collectionClass||(opts.collectionClass=LinkedCollection$1);SimpleStore$1.call(this,opts);}var props$1={constructor:DataStore,defineMapper:function defineMapper(name,opts){// Complexity of this method is beyond simply using => functions to bind context +var self=this;var mapper=SimpleStore$1.prototype.defineMapper.call(self,name,opts);var idAttribute=mapper.idAttribute;var collection=this.getCollection(name);mapper.relationList.forEach(function(def){var relation=def.relation;var localField=def.localField;var path='links.'+localField;var foreignKey=def.foreignKey;var type=def.type;var updateOpts={index:foreignKey};var descriptor=void 0;var getter=function getter(){return this._get(path);};if(type===belongsToType){(function(){if(!collection.indexes[foreignKey]){collection.createIndex(foreignKey);}descriptor={get:getter,// e.g. profile.user = someUser +// or comment.post = somePost +set:function set(record){// e.g. const otherUser = profile.user +var currentParent=this._get(path);// e.g. profile.user === someUser +if(record===currentParent){return currentParent;}var id=utils.get(this,idAttribute);var inverseDef=def.getInverse(mapper);// e.g. profile.user !== someUser +// or comment.post !== somePost +if(currentParent&&inverseDef){this.removeInverseRelation(currentParent,id,inverseDef,idAttribute);}if(record){// e.g. profile.user = someUser +var relatedIdAttribute=def.getRelation().idAttribute;var relatedId=utils.get(record,relatedIdAttribute);// Prefer store record +if(relatedId!==undefined&&this._get('$')){record=self.get(relation,relatedId)||record;}// Set locals +// e.g. profile.user = someUser +// or comment.post = somePost +safeSetLink(this,localField,record);safeSetProp(this,foreignKey,relatedId);collection.updateIndex(this,updateOpts);if(inverseDef){this.setupInverseRelation(record,id,inverseDef,idAttribute);}}else{// Unset in-memory link only +// e.g. profile.user = undefined +// or comment.post = undefined +safeSetLink(this,localField,undefined);}return record;}};var foreignKeyDescriptor=Object.getOwnPropertyDescriptor(mapper.recordClass.prototype,foreignKey);if(!foreignKeyDescriptor){foreignKeyDescriptor={enumerable:true};}var originalGet=foreignKeyDescriptor.get;foreignKeyDescriptor.get=function(){if(originalGet){return originalGet.call(this);}return this._get('props.'+foreignKey);};var originalSet=foreignKeyDescriptor.set;foreignKeyDescriptor.set=function(value){var _this=this;if(originalSet){originalSet.call(this,value);}var currentParent=utils.get(this,localField);var id=utils.get(this,idAttribute);var inverseDef=def.getInverse(mapper);var currentParentId=currentParent?utils.get(currentParent,def.getRelation().idAttribute):undefined;if(currentParent&¤tParentId!==undefined&¤tParentId!==value){if(inverseDef.type===hasOneType){safeSetLink(currentParent,inverseDef.localField,undefined);}else if(inverseDef.type===hasManyType){var children=utils.get(currentParent,inverseDef.localField);if(id===undefined){utils.remove(children,function(child){return child===_this;});}else{utils.remove(children,function(child){return child===_this||id===utils.get(child,idAttribute);});}}}safeSetProp(this,foreignKey,value);collection.updateIndex(this,updateOpts);if(value===undefined||value===null){if(currentParentId!==undefined){// Unset locals +utils.set(this,localField,undefined);}}else if(this._get('$')){var storeRecord=self.get(relation,value);if(storeRecord){utils.set(this,localField,storeRecord);}}};Object.defineProperty(mapper.recordClass.prototype,foreignKey,foreignKeyDescriptor);})();}else if(type===hasManyType){(function(){var localKeys=def.localKeys;var foreignKeys=def.foreignKeys;// TODO: Handle case when belongsTo relation isn't ever defined +if(self._collections[relation]&&foreignKey&&!self.getCollection(relation).indexes[foreignKey]){self.getCollection(relation).createIndex(foreignKey);}descriptor={get:function get(){var current=getter.call(this);if(!current){this._set(path,[]);}return getter.call(this);},// e.g. post.comments = someComments +// or user.groups = someGroups +// or group.users = someUsers +set:function set(records){var _this2=this;if(records&&!utils.isArray(records)){records=[records];}var id=utils.get(this,idAttribute);var relatedIdAttribute=def.getRelation().idAttribute;var inverseDef=def.getInverse(mapper);var inverseLocalField=inverseDef.localField;var current=this._get(path)||[];var toLink=[];var toLinkIds={};if(records){records.forEach(function(record){// e.g. comment.id +var relatedId=utils.get(record,relatedIdAttribute);var currentParent=utils.get(record,inverseLocalField);if(currentParent&¤tParent!==_this2){var currentChildrenOfParent=utils.get(currentParent,localField);// e.g. somePost.comments.remove(comment) +if(relatedId===undefined){utils.remove(currentChildrenOfParent,function(child){return child===record;});}else{utils.remove(currentChildrenOfParent,function(child){return child===record||relatedId===utils.get(child,relatedIdAttribute);});}}if(relatedId!==undefined){if(_this2._get('$')){// Prefer store record +record=self.get(relation,relatedId)||record;}// e.g. toLinkIds[comment.id] = comment +toLinkIds[relatedId]=record;}toLink.push(record);});}// e.g. post.comments = someComments +if(foreignKey){current.forEach(function(record){// e.g. comment.id +var relatedId=utils.get(record,relatedIdAttribute);if(relatedId===undefined&&toLink.indexOf(record)===-1||relatedId!==undefined&&!(relatedId in toLinkIds)){// Update (unset) inverse relation +if(records){// e.g. comment.post_id = undefined +safeSetProp(record,foreignKey,undefined);// e.g. CommentCollection.updateIndex(comment, { index: 'post_id' }) +self.getCollection(relation).updateIndex(record,updateOpts);}// e.g. comment.post = undefined +safeSetLink(record,inverseLocalField,undefined);}});toLink.forEach(function(record){// Update (set) inverse relation +// e.g. comment.post_id = post.id +safeSetProp(record,foreignKey,id);// e.g. CommentCollection.updateIndex(comment, { index: 'post_id' }) +self.getCollection(relation).updateIndex(record,updateOpts);// e.g. comment.post = post +safeSetLink(record,inverseLocalField,_this2);});}else if(localKeys){// Update locals +// e.g. group.users = someUsers +// Update (set) inverse relation +var ids=toLink.map(function(child){return utils.get(child,relatedIdAttribute);}).filter(function(id){return id!==undefined;});// e.g. group.user_ids = [1,2,3,...] +utils.set(this,localKeys,ids);// Update (unset) inverse relation +if(inverseDef.foreignKeys){current.forEach(function(child){var relatedId=utils.get(child,relatedIdAttribute);if(relatedId===undefined&&toLink.indexOf(child)===-1||relatedId!==undefined&&!(relatedId in toLinkIds)){// Update inverse relation +// safeSetLink(child, inverseLocalField, undefined) +var parents=utils.get(child,inverseLocalField)||[];// e.g. someUser.groups.remove(group) +if(id===undefined){utils.remove(parents,function(parent){return parent===_this2;});}else{utils.remove(parents,function(parent){return parent===_this2||id===utils.get(parent,idAttribute);});}}});toLink.forEach(function(child){// Update (set) inverse relation +var parents=utils.get(child,inverseLocalField);// e.g. someUser.groups.push(group) +if(id===undefined){utils.noDupeAdd(parents,_this2,function(parent){return parent===_this2;});}else{utils.noDupeAdd(parents,_this2,function(parent){return parent===_this2||id===utils.get(parent,idAttribute);});}});}}else if(foreignKeys){// e.g. user.groups = someGroups +// Update (unset) inverse relation +current.forEach(function(parent){var ids=utils.get(parent,foreignKeys)||[];// e.g. someGroup.user_ids.remove(user.id) +utils.remove(ids,function(_key){return id===_key;});var children=utils.get(parent,inverseLocalField);// e.g. someGroup.users.remove(user) +if(id===undefined){utils.remove(children,function(child){return child===_this2;});}else{utils.remove(children,function(child){return child===_this2||id===utils.get(child,idAttribute);});}});// Update (set) inverse relation +toLink.forEach(function(parent){var ids=utils.get(parent,foreignKeys)||[];utils.noDupeAdd(ids,id,function(_key){return id===_key;});var children=utils.get(parent,inverseLocalField);if(id===undefined){utils.noDupeAdd(children,_this2,function(child){return child===_this2;});}else{utils.noDupeAdd(children,_this2,function(child){return child===_this2||id===utils.get(child,idAttribute);});}});}this._set(path,toLink);return toLink;}};})();}else if(type===hasOneType){// TODO: Handle case when belongsTo relation isn't ever defined +if(self._collections[relation]&&foreignKey&&!self.getCollection(relation).indexes[foreignKey]){self.getCollection(relation).createIndex(foreignKey);}descriptor={get:getter,// e.g. user.profile = someProfile +set:function set(record){var current=this._get(path);if(record===current){return current;}var inverseLocalField=def.getInverse(mapper).localField;// Update (unset) inverse relation +if(current){safeSetProp(current,foreignKey,undefined);self.getCollection(relation).updateIndex(current,updateOpts);safeSetLink(current,inverseLocalField,undefined);}if(record){var relatedId=utils.get(record,def.getRelation().idAttribute);// Prefer store record +if(relatedId!==undefined){record=self.get(relation,relatedId)||record;}// Set locals +safeSetLink(this,localField,record);// Update (set) inverse relation +safeSetProp(record,foreignKey,utils.get(this,idAttribute));self.getCollection(relation).updateIndex(record,updateOpts);safeSetLink(record,inverseLocalField,this);}else{// Unset locals +safeSetLink(this,localField,undefined);}return record;}};}if(descriptor){descriptor.enumerable=def.enumerable===undefined?false:def.enumerable;if(def.get){(function(){var origGet=descriptor.get;descriptor.get=function(){var _this3=this;return def.get(def,this,function(){for(var _len=arguments.length,args=Array(_len),_key2=0;_key2<_len;_key2++){args[_key2]=arguments[_key2];}return origGet.apply(_this3,args);});};})();}if(def.set){(function(){var origSet=descriptor.set;descriptor.set=function(related){var _this4=this;return def.set(def,this,related,function(value){return origSet.call(_this4,value===undefined?related:value);});};})();}Object.defineProperty(mapper.recordClass.prototype,localField,descriptor);}});return mapper;},destroy:function destroy(name,id,opts){var _this5=this;opts||(opts={});return SimpleStore$1.prototype.destroy.call(this,name,id,opts).then(function(result){var record=void 0;if(opts.raw){record=result.data;}else{record=result;}if(record&&_this5.unlinkOnDestroy){var _opts=utils.plainCopy(opts);_opts.withAll=true;utils.forEachRelation(_this5.getMapper(name),_opts,function(def){utils.set(record,def.localField,undefined);});}return result;});},destroyAll:function destroyAll(name,query,opts){var _this6=this;opts||(opts={});return SimpleStore$1.prototype.destroyAll.call(this,name,query,opts).then(function(result){var records=void 0;if(opts.raw){records=result.data;}else{records=result;}if(records&&records.length&&_this6.unlinkOnDestroy){var _opts=utils.plainCopy(opts);_opts.withAll=true;utils.forEachRelation(_this6.getMapper(name),_opts,function(def){records.forEach(function(record){utils.set(record,def.localField,undefined);});});}return result;});}};var DataStore$1=SimpleStore$1.extend(props$1);/** + * Create a subclass of this DataStore: + * @example DataStore.extend + * // Normally you would do: import {DataStore} from 'js-data' + * const JSData = require('js-data@3.0.0-rc.4') + * const {DataStore} = JSData + * console.log('Using JSData v' + JSData.version.full) + * + * // Extend the class using ES2015 class syntax. + * class CustomDataStoreClass extends DataStore { + * foo () { return 'bar' } + * static beep () { return 'boop' } + * } + * const customDataStore = new CustomDataStoreClass() + * console.log(customDataStore.foo()) + * console.log(CustomDataStoreClass.beep()) + * + * // Extend the class using alternate method. + * const OtherDataStoreClass = DataStore.extend({ + * foo () { return 'bar' } + * }, { + * beep () { return 'boop' } + * }) + * const otherDataStore = new OtherDataStoreClass() + * console.log(otherDataStore.foo()) + * console.log(OtherDataStoreClass.beep()) + * + * // Extend the class, providing a custom constructor. + * function AnotherDataStoreClass () { + * DataStore.call(this) + * this.created_at = new Date().getTime() + * } + * DataStore.extend({ + * constructor: AnotherDataStoreClass, + * foo () { return 'bar' } + * }, { + * beep () { return 'boop' } + * }) + * const anotherDataStore = new AnotherDataStoreClass() + * console.log(anotherDataStore.created_at) + * console.log(anotherDataStore.foo()) + * console.log(AnotherDataStoreClass.beep()) + * + * @method DataStore.extend + * @param {Object} [props={}] Properties to add to the prototype of the + * subclass. + * @param {Object} [props.constructor] Provide a custom constructor function + * to be used as the subclass itself. + * @param {Object} [classProps={}] Static properties to add to the subclass. + * @returns {Constructor} Subclass of this DataStore class. + * @since 3.0.0 + *//** + * Registered as `js-data` in NPM and Bower. + * + * Also available from CDN.JS and JSDelivr. + * + * @module js-data + * + * @example Install from NPM + * npm i --save js-data@beta + * @example Install from Bower + * bower i --save js-data@3.0.0-beta.1 + * @example Install from CDN.JS + * + * @example Install from JSDelivr + * + * @example Load into your app via script tag + * + * + * @example Load into your app via CommonJS + * var JSData = require('js-data'); + * @example Load into your app via ES2015 Modules + * import * as JSData from 'js-data'; + * @example Load into your app via AMD + * define('myApp', ['js-data'], function (JSData) { ... }) + *//** + * Describes the version of this `JSData` object. + * + * @example + * console.log(JSData.version.full) // "3.0.0-beta.1" + * + * @name version + * @memberof module:js-data + * @property {string} full The full semver value. + * @property {number} major The major version number. + * @property {number} minor The minor version number. + * @property {number} patch The patch version number. + * @property {(string|boolean)} alpha The alpha version value, otherwise `false` + * if the current version is not alpha. + * @property {(string|boolean)} beta The beta version value, otherwise `false` + * if the current version is not beta. + * @since 2.0.0 + * @type {Object} + */var version$1={full:'3.0.0-rc.5',major:3,minor:0,patch:0}; + + +var jsData_es2015 = Object.freeze({ + version: version$1, + Collection: Collection$1, + Component: Component$1, + Container: Container, + DataStore: DataStore$1, + Index: Index, + LinkedCollection: LinkedCollection$1, + Mapper: Mapper$1, + Query: Query$1, + Record: Record$1, + Schema: Schema$1, + Settable: Settable, + SimpleStore: SimpleStore$1, + utils: utils, + belongsTo: belongsTo, + hasMany: hasMany, + hasOne: hasOne, + belongsToType: belongsToType, + hasManyType: hasManyType, + hasOneType: hasOneType +}); + +var __moduleExports$2 = createCommonjsModule(function (module) { + /*! + * merge-descriptors + * Copyright(c) 2014 Jonathan Ong + * Copyright(c) 2015 Douglas Christopher Wilson + * MIT Licensed + */ + + 'use strict'; + + /** + * Module exports. + * @public + */ + + module.exports = merge; + + /** + * Module variables. + * @private + */ + + var hasOwnProperty = Object.prototype.hasOwnProperty; + + /** + * Merge the property descriptors of `src` into `dest` + * + * @param {object} dest Object to add descriptors to + * @param {object} src Object to clone descriptors from + * @param {boolean} [redefine=true] Redefine `dest` properties with `src` properties + * @returns {object} Reference to dest + * @public + */ + + function merge(dest, src, redefine) { + if (!dest) { + throw new TypeError('argument dest is required'); + } + + if (!src) { + throw new TypeError('argument src is required'); + } + + if (redefine === undefined) { + // Default to true + redefine = true; + } + + Object.getOwnPropertyNames(src).forEach(function forEachOwnPropertyName(name) { + if (!redefine && hasOwnProperty.call(dest, name)) { + // Skip desriptor + return; + } + + // Copy descriptor + var descriptor = Object.getOwnPropertyDescriptor(src, name); + Object.defineProperty(dest, name, descriptor); + }); + + return dest; + } +}); + +var __moduleExports$7 = createCommonjsModule(function (module) { + /** + * 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) { + str = '' + str; + if (str.length > 10000) return; + var match = /^((?:\d+)?\.?\d+) *(milliseconds?|msecs?|ms|seconds?|secs?|s|minutes?|mins?|m|hours?|hrs?|h|days?|d|years?|yrs?|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 'yrs': + case 'yr': + case 'y': + return n * y; + case 'days': + case 'day': + case 'd': + return n * d; + case 'hours': + case 'hour': + case 'hrs': + case 'hr': + case 'h': + return n * h; + case 'minutes': + case 'minute': + case 'mins': + case 'min': + case 'm': + return n * m; + case 'seconds': + case 'second': + case 'secs': + case 'sec': + case 's': + return n * s; + case 'milliseconds': + case 'millisecond': + case 'msecs': + case 'msec': + 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'; + } +}); + +var __moduleExports$6 = createCommonjsModule(function (module, exports) { + /** + * 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 = __moduleExports$7; + + /** + * 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; + } +}); + +var __moduleExports$5 = createCommonjsModule(function (module, exports) { + /** + * Module dependencies. + */ + + var tty$$ = tty; + var util$$ = util; + + /** + * This is the Node.js implementation of `debug()`. + * + * Expose `debug()` as the module. + */ + + exports = module.exports = __moduleExports$6; + exports.log = log; + exports.formatArgs = formatArgs; + exports.save = save; + exports.load = load; + exports.useColors = useColors; + + /** + * Colors. + */ + + exports.colors = [6, 2, 3, 4, 5, 1]; + + /** + * The file descriptor to write the `debug()` calls to. + * Set the `DEBUG_FD` env variable to override with another value. i.e.: + * + * $ DEBUG_FD=3 node script.js 3>debug.log + */ + + var fd = parseInt(process.env.DEBUG_FD, 10) || 2; + var stream = 1 === fd ? process.stdout : 2 === fd ? process.stderr : createWritableStdioStream(fd); + + /** + * 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(fd); + } 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] = ' \x1B[3' + c + ';1m' + name + ' ' + '\x1B[0m' + args[0] + '\x1B[3' + c + 'm' + ' +' + exports.humanize(this.diff) + '\x1B[0m'; + } else { + args[0] = new Date().toUTCString() + ' ' + name + ' ' + args[0]; + } + return args; + } + + /** + * Invokes `console.error()` with the specified arguments. + */ + + function log() { + return stream.write(util$$.format.apply(this, arguments) + '\n'); + } + + /** + * 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; + } + + /** + * Copied from `node/src/node.js`. + * + * XXX: It's lame that node doesn't expose this API out-of-the-box. It also + * relies on the undocumented `tty_wrap.guessHandleType()` which is also lame. + */ + + function createWritableStdioStream(fd) { + var stream; + var tty_wrap = process.binding('tty_wrap'); + + // Note stream._type is used for test-module-load-list.js + + switch (tty_wrap.guessHandleType(fd)) { + case 'TTY': + stream = new tty$$.WriteStream(fd); + stream._type = 'tty'; + + // Hack to have stream not keep the event loop alive. + // See https://github.com/joyent/node/issues/1726 + if (stream._handle && stream._handle.unref) { + stream._handle.unref(); + } + break; + + case 'FILE': + var fs$$ = fs; + stream = new fs$$.SyncWriteStream(fd, { autoClose: false }); + stream._type = 'fs'; + break; + + case 'PIPE': + case 'TCP': + var net$$ = net; + stream = new net$$.Socket({ + fd: fd, + readable: false, + writable: true + }); + + // FIXME Should probably have an option in net.Socket to create a + // stream from an existing fd which is writable only. But for now + // we'll just add this hack and set the `readable` member to false. + // Test: ./node test/fixtures/echo.js < /etc/passwd + stream.readable = false; + stream.read = null; + stream._type = 'pipe'; + + // FIXME Hack to have stream not keep the event loop alive. + // See https://github.com/joyent/node/issues/1726 + if (stream._handle && stream._handle.unref) { + stream._handle.unref(); + } + break; + + default: + // Probably an error on in uv_guess_handle() + throw new Error('Implement me. Unknown stream file type!'); + } + + // For supporting legacy API we put the FD here. + stream.fd = fd; + + stream._isStdio = true; + + return stream; + } + + /** + * Enable namespaces listed in `process.env.DEBUG` initially. + */ + + exports.enable(load()); +}); + +var __moduleExports$8 = createCommonjsModule(function (module) { + /*! + * escape-html + * Copyright(c) 2012-2013 TJ Holowaychuk + * Copyright(c) 2015 Andreas Lubbe + * Copyright(c) 2015 Tiancheng "Timothy" Gu + * MIT Licensed + */ + + 'use strict'; + + /** + * Module variables. + * @private + */ + + var matchHtmlRegExp = /["'&<>]/; + + /** + * Module exports. + * @public + */ + + module.exports = escapeHtml; + + /** + * Escape special characters in the given string of html. + * + * @param {string} string The string to escape for inserting into HTML + * @return {string} + * @public + */ + + function escapeHtml(string) { + var str = '' + string; + var match = matchHtmlRegExp.exec(str); + + if (!match) { + return str; + } + + var escape; + var html = ''; + var index = 0; + var lastIndex = 0; + + for (index = match.index; index < str.length; index++) { + switch (str.charCodeAt(index)) { + case 34: + // " + escape = '"'; + break; + case 38: + // & + escape = '&'; + break; + case 39: + // ' + escape = '''; + break; + case 60: + // < + escape = '<'; + break; + case 62: + // > + escape = '>'; + break; + default: + continue; + } + + if (lastIndex !== index) { + html += str.substring(lastIndex, index); + } + + lastIndex = index + 1; + html += escape; + } + + return lastIndex !== index ? html + str.substring(lastIndex, index) : html; + } +}); + +var __moduleExports$10 = createCommonjsModule(function (module) { + /*! + * ee-first + * Copyright(c) 2014 Jonathan Ong + * MIT Licensed + */ + + 'use strict'; + + /** + * Module exports. + * @public + */ + + module.exports = first; + + /** + * Get the first event in a set of event emitters and event pairs. + * + * @param {array} stuff + * @param {function} done + * @public + */ + + 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; + } + + /** + * Create the event listener. + * @private + */ + + 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); + }; + } +}); + +var __moduleExports$9 = createCommonjsModule(function (module) { + /*! + * on-finished + * Copyright(c) 2013 Jonathan Ong + * Copyright(c) 2014 Douglas Christopher Wilson + * MIT Licensed + */ + + 'use strict'; + + /** + * Module exports. + * @public + */ + + module.exports = onFinished; + module.exports.isFinished = isFinished; + + /** + * Module dependencies. + * @private + */ + + var first = __moduleExports$10; + + /** + * Variables. + * @private + */ + + /* 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} + * @public + */ + + function onFinished(msg, listener) { + if (isFinished(msg) !== false) { + defer(listener, null, msg); + return msg; + } + + // attach the listener to the message + attachListener(msg, listener); + + return msg; + } + + /** + * Determine if message is already finished. + * + * @param {object} msg + * @return {boolean} + * @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(msg.upgrade || !socket || !socket.readable || msg.complete && !msg.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} + * @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} + * @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, msg); + } + } + + 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); + }; + } +}); + +var codes = { + "100": "Continue", + "101": "Switching Protocols", + "102": "Processing", + "200": "OK", + "201": "Created", + "202": "Accepted", + "203": "Non-Authoritative Information", + "204": "No Content", + "205": "Reset Content", + "206": "Partial Content", + "207": "Multi-Status", + "208": "Already Reported", + "226": "IM Used", + "300": "Multiple Choices", + "301": "Moved Permanently", + "302": "Found", + "303": "See Other", + "304": "Not Modified", + "305": "Use Proxy", + "306": "(Unused)", + "307": "Temporary Redirect", + "308": "Permanent Redirect", + "400": "Bad Request", + "401": "Unauthorized", + "402": "Payment Required", + "403": "Forbidden", + "404": "Not Found", + "405": "Method Not Allowed", + "406": "Not Acceptable", + "407": "Proxy Authentication Required", + "408": "Request Timeout", + "409": "Conflict", + "410": "Gone", + "411": "Length Required", + "412": "Precondition Failed", + "413": "Payload Too Large", + "414": "URI Too Long", + "415": "Unsupported Media Type", + "416": "Range Not Satisfiable", + "417": "Expectation Failed", + "418": "I'm a teapot", + "421": "Misdirected Request", + "422": "Unprocessable Entity", + "423": "Locked", + "424": "Failed Dependency", + "425": "Unordered Collection", + "426": "Upgrade Required", + "428": "Precondition Required", + "429": "Too Many Requests", + "431": "Request Header Fields Too Large", + "451": "Unavailable For Legal Reasons", + "500": "Internal Server Error", + "501": "Not Implemented", + "502": "Bad Gateway", + "503": "Service Unavailable", + "504": "Gateway Timeout", + "505": "HTTP Version Not Supported", + "506": "Variant Also Negotiates", + "507": "Insufficient Storage", + "508": "Loop Detected", + "509": "Bandwidth Limit Exceeded", + "510": "Not Extended", + "511": "Network Authentication Required" }; -module.exports = MODULE; \ No newline at end of file +var codes$1 = Object.freeze({ + default: codes +}); + +var require$$0 = ( codes$1 && codes$1['default'] ) || codes$1; + +var __moduleExports$11 = createCommonjsModule(function (module) { + /*! + * statuses + * Copyright(c) 2014 Jonathan Ong + * Copyright(c) 2016 Douglas Christopher Wilson + * MIT Licensed + */ + + 'use strict'; + + /** + * Module dependencies. + * @private + */ + + var codes = require$$0; + + /** + * Module exports. + * @public + */ + + module.exports = status; + + // array of status codes + status.codes = populateStatusesMap(status, codes); + + // status codes for redirects + status.redirect = { + 300: true, + 301: true, + 302: true, + 303: true, + 305: true, + 307: true, + 308: true + }; + + // status codes for empty bodies + status.empty = { + 204: true, + 205: true, + 304: true + }; + + // status codes for when you should retry the request + status.retry = { + 502: true, + 503: true, + 504: true + }; + + /** + * Populate the statuses map for given codes. + * @private + */ + + function populateStatusesMap(statuses, codes) { + var arr = []; + + Object.keys(codes).forEach(function forEachCode(code) { + var message = codes[code]; + var status = Number(code); + + // Populate properties + statuses[status] = message; + statuses[message] = status; + statuses[message.toLowerCase()] = status; + + // Add to array + arr.push(status); + }); + + return arr; + } + + /** + * Get the status code. + * + * Given a number, this will throw if it is not a known status + * code, otherwise the code will be returned. Given a string, + * the string will be parsed for a number and return the code + * if valid, otherwise will lookup the code assuming this is + * the status message. + * + * @param {string|number} code + * @returns {string} + * @public + */ + + function status(code) { + if (typeof code === 'number') { + if (!status[code]) throw new Error('invalid status code: ' + code); + return code; + } + + if (typeof code !== 'string') { + throw new TypeError('code must be a number or string'); + } + + // '403' + var n = parseInt(code, 10); + if (!isNaN(n)) { + if (!status[n]) throw new Error('invalid status code: ' + n); + return n; + } + + n = status[code.toLowerCase()]; + if (!n) throw new Error('invalid status message: "' + code + '"'); + return n; + } +}); + +var __moduleExports$12 = createCommonjsModule(function (module) { + /*! + * unpipe + * Copyright(c) 2015 Douglas Christopher Wilson + * MIT Licensed + */ + + 'use strict'; + + /** + * Module exports. + * @public + */ + + module.exports = unpipe; + + /** + * Determine if there are Node.js pipe-like data listeners. + * @private + */ + + function hasPipeDataListeners(stream) { + var listeners = stream.listeners('data'); + + for (var i = 0; i < listeners.length; i++) { + if (listeners[i].name === 'ondata') { + return true; + } + } + + return false; + } + + /** + * Unpipe a stream from all destinations. + * + * @param {object} stream + * @public + */ + + function unpipe(stream) { + if (!stream) { + throw new TypeError('argument stream is required'); + } + + if (typeof stream.unpipe === 'function') { + // new-style + stream.unpipe(); + return; + } + + // Node.js 0.8 hack + if (!hasPipeDataListeners(stream)) { + return; + } + + 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); + } + } +}); + +var __moduleExports$4 = createCommonjsModule(function (module) { + /*! + * finalhandler + * Copyright(c) 2014-2015 Douglas Christopher Wilson + * MIT Licensed + */ + + 'use strict'; + + /** + * Module dependencies. + * @private + */ + + var debug = __moduleExports$5('finalhandler'); + var escapeHtml = __moduleExports$8; + var onFinished = __moduleExports$9; + var statuses = __moduleExports$11; + var unpipe = __moduleExports$12; + + /** + * Module variables. + * @private + */ + + /* istanbul ignore next */ + var defer = typeof setImmediate === 'function' ? setImmediate : function (fn) { + process.nextTick(fn.bind.apply(fn, arguments)); + }; + var isFinished = onFinished.isFinished; + + /** + * Module exports. + * @public + */ + + module.exports = finalhandler; + + /** + * Create a function to handle the final response. + * + * @param {Request} req + * @param {Response} res + * @param {Object} [options] + * @return {Function} + * @public + */ + + function finalhandler(req, res, options) { + var opts = options || {}; + + // get environment + var env = opts.env || process.env.NODE_ENV || 'development'; + + // get error callback + var onerror = opts.onerror; + + return function (err) { + var headers = Object.create(null); + var status; + + // ignore 404 on in-flight response + if (!err && res._header) { + debug('cannot 404 after headers sent'); + return; + } + + // unhandled error + if (err) { + // respect status code from error + status = getErrorStatusCode(err) || res.statusCode; + + // default status code to 500 if outside valid range + if (typeof status !== 'number' || status < 400 || status > 599) { + status = 500; + } + + // respect err.headers + if (err.headers && (err.status === status || err.statusCode === status)) { + var keys = Object.keys(err.headers); + for (var i = 0; i < keys.length; i++) { + var key = keys[i]; + headers[key] = err.headers[key]; + } + } + + // production gets a basic error message + var msg = env === 'production' ? statuses[status] : err.stack || err.toString(); + msg = escapeHtml(msg).replace(/\n/g, '
').replace(/\x20{2}/g, '  ') + '\n'; + } else { + status = 404; + msg = 'Cannot ' + escapeHtml(req.method) + ' ' + escapeHtml(req.originalUrl || req.url) + '\n'; + } + + debug('default %s', status); + + // schedule onerror callback + if (err && onerror) { + defer(onerror, err, req, res); + } + + // cannot actually respond + if (res._header) { + debug('cannot %d after headers sent', status); + req.socket.destroy(); + return; + } + + // send response + send(req, res, status, headers, msg); + }; + } + + /** + * Get status code from Error object. + * + * @param {Error} err + * @return {number} + * @private + */ + + function getErrorStatusCode(err) { + // check err.status + if (typeof err.status === 'number' && err.status >= 400 && err.status < 600) { + return err.status; + } + + // check err.statusCode + if (typeof err.statusCode === 'number' && err.statusCode >= 400 && err.statusCode < 600) { + return err.statusCode; + } + + return undefined; + } + + /** + * Send response. + * + * @param {IncomingMessage} req + * @param {OutgoingMessage} res + * @param {number} status + * @param {object} headers + * @param {string} body + * @private + */ + + function send(req, res, status, headers, body) { + function write() { + // response status + res.statusCode = status; + res.statusMessage = statuses[status]; + + // response headers + var keys = Object.keys(headers); + for (var i = 0; i < keys.length; i++) { + var key = keys[i]; + res.setHeader(key, headers[key]); + } + + // 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 (isFinished(req)) { + write(); + return; + } + + // unpipe everything from the request + unpipe(req); + + // flush the request + onFinished(req, write); + req.resume(); + } +}); + +var __moduleExports$15 = createCommonjsModule(function (module) { + 'use strict'; + + /** + * Expose `arrayFlatten`. + */ + + module.exports = arrayFlatten; + + /** + * Recursive flatten function with depth. + * + * @param {Array} array + * @param {Array} result + * @param {Number} depth + * @return {Array} + */ + function flattenWithDepth(array, result, depth) { + for (var i = 0; i < array.length; i++) { + var value = array[i]; + + if (depth > 0 && Array.isArray(value)) { + flattenWithDepth(value, result, depth - 1); + } else { + result.push(value); + } + } + + return result; + } + + /** + * Recursive flatten function. Omitting depth is slightly faster. + * + * @param {Array} array + * @param {Array} result + * @return {Array} + */ + function flattenForever(array, result) { + for (var i = 0; i < array.length; i++) { + var value = array[i]; + + if (Array.isArray(value)) { + flattenForever(value, result); + } else { + result.push(value); + } + } + + return result; + } + + /** + * Flatten an array, with the ability to define a depth. + * + * @param {Array} array + * @param {Number} depth + * @return {Array} + */ + function arrayFlatten(array, depth) { + if (depth == null) { + return flattenForever(array, []); + } + + return flattenWithDepth(array, [], depth); + } +}); + +var __moduleExports$17 = createCommonjsModule(function (module) { + /** + * Expose `pathtoRegexp`. + */ + + module.exports = pathtoRegexp; + + /** + * Match matching groups in a regular expression. + */ + var MATCHING_GROUP_REGEXP = /\((?!\?)/g; + + /** + * 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 || {}; + keys = keys || []; + var strict = options.strict; + var end = options.end !== false; + var flags = options.sensitive ? '' : 'i'; + var extraOffset = 0; + var keysOffset = keys.length; + var i = 0; + var name = 0; + var m; + + if (path instanceof RegExp) { + while (m = MATCHING_GROUP_REGEXP.exec(path.source)) { + keys.push({ + name: name++, + optional: false, + offset: m.index + }); + } + + 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, offset) { + slash = slash || ''; + format = format || ''; + capture = capture || '([^\\/' + format + ']+?)'; + optional = optional || ''; + + keys.push({ + name: key, + optional: !!optional, + offset: offset + extraOffset + }); + + var result = '' + (optional ? '' : slash) + '(?:' + format + (optional ? slash : '') + capture + (star ? '((?:[\\/' + format + '].+?)?)' : '') + ')' + optional; + + extraOffset += result.length - match.length; + + return result; + }).replace(/\*/g, function (star, index) { + var len = keys.length; + + while (len-- > keysOffset && keys[len].offset > index) { + keys[len].offset += 3; // Replacement length minus asterisk length. + } + + return '(.*)'; + }); + + // This is a workaround for handling unnamed matching groups. + while (m = MATCHING_GROUP_REGEXP.exec(path)) { + var escapeCount = 0; + var index = m.index; + + while (path.charAt(--index) === '\\') { + escapeCount++; + } + + // It's possible to escape the bracket. + if (escapeCount % 2 === 1) { + continue; + } + + if (keysOffset + i === keys.length || keys[keysOffset + i].offset > m.index) { + keys.splice(keysOffset + i, 0, { + name: name++, // Unnamed matching groups must be consistently linear. + optional: false, + offset: m.index + }); + } + + i++; + } + + // If the path is non-ending, match until the end or a slash. + path += end ? '$' : path[path.length - 1] === '/' ? '' : '(?=\\/|$)'; + + return new RegExp(path, flags); + }; +}); + +var __moduleExports$16 = createCommonjsModule(function (module) { + /*! + * express + * Copyright(c) 2009-2013 TJ Holowaychuk + * Copyright(c) 2013 Roman Shtylman + * Copyright(c) 2014-2015 Douglas Christopher Wilson + * MIT Licensed + */ + + 'use strict'; + + /** + * Module dependencies. + * @private + */ + + var pathRegexp = __moduleExports$17; + var debug = __moduleExports$5('express:router:layer'); + + /** + * Module variables. + * @private + */ + + var hasOwnProperty = Object.prototype.hasOwnProperty; + + /** + * Module exports. + * @public + */ + + module.exports = Layer; + + function Layer(path, options, fn) { + if (!(this instanceof Layer)) { + return new Layer(path, options, fn); + } + + debug('new %s', path); + var opts = options || {}; + + this.handle = fn; + this.name = fn.name || ''; + this.params = undefined; + this.path = undefined; + this.regexp = pathRegexp(path, this.keys = [], opts); + + if (path === '/' && opts.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 (path == null) { + // no path, nothing matches + this.params = undefined; + this.path = undefined; + return false; + } + + 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; + + for (var i = 1; i < m.length; i++) { + var key = keys[i - 1]; + var prop = key.name; + var 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} + * @private + */ + + function decode_param(val) { + if (typeof val !== 'string' || val.length === 0) { + return val; + } + + try { + return decodeURIComponent(val); + } catch (err) { + if (err instanceof URIError) { + err.message = 'Failed to decode param \'' + val + '\''; + err.status = err.statusCode = 400; + } + + throw err; + } + } +}); + +var __moduleExports$18 = createCommonjsModule(function (module) { + /*! + * methods + * Copyright(c) 2013-2014 TJ Holowaychuk + * Copyright(c) 2015-2016 Douglas Christopher Wilson + * MIT Licensed + */ + + 'use strict'; + + /** + * Module dependencies. + * @private + */ + + var http$$ = http; + + /** + * Module exports. + * @public + */ + + module.exports = getCurrentNodeMethods() || getBasicNodeMethods(); + + /** + * Get the current Node.js methods. + * @private + */ + + function getCurrentNodeMethods() { + return http$$.METHODS && http$$.METHODS.map(function lowerCaseMethod(method) { + return method.toLowerCase(); + }); + } + + /** + * Get the "basic" Node.js methods, a snapshot from Node.js 0.10. + * @private + */ + + function getBasicNodeMethods() { + return ['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']; + } +}); + +var __moduleExports$14 = createCommonjsModule(function (module) { + /*! + * express + * Copyright(c) 2009-2013 TJ Holowaychuk + * Copyright(c) 2013 Roman Shtylman + * Copyright(c) 2014-2015 Douglas Christopher Wilson + * MIT Licensed + */ + + 'use strict'; + + /** + * Module dependencies. + * @private + */ + + var debug = __moduleExports$5('express:router:route'); + var flatten = __moduleExports$15; + var Layer = __moduleExports$16; + var methods = __moduleExports$18; + + /** + * Module variables. + * @private + */ + + var slice = Array.prototype.slice; + var toString = Object.prototype.toString; + + /** + * Module exports. + * @public + */ + + module.exports = Route; + + /** + * Initialize `Route` with the given `path`, + * + * @param {String} path + * @public + */ + + function Route(path) { + this.path = path; + this.stack = []; + + debug('new %s', path); + + // route handlers for various http methods + this.methods = {}; + } + + /** + * Determine if the route handles a given method. + * @private + */ + + Route.prototype._handles_method = function _handles_method(method) { + if (this.methods._all) { + return true; + } + + var name = method.toLowerCase(); + + if (name === 'head' && !this.methods['head']) { + name = 'get'; + } + + return Boolean(this.methods[name]); + }; + + /** + * @return {Array} supported HTTP methods + * @private + */ + + Route.prototype._options = function _options() { + var methods = Object.keys(this.methods); + + // append automatic head + if (this.methods.get && !this.methods.head) { + methods.push('head'); + } + + for (var i = 0; i < methods.length; i++) { + // make upper case + methods[i] = methods[i].toUpperCase(); + } + + return methods; + }; + + /** + * dispatch req, res into this route + * @private + */ + + Route.prototype.dispatch = function dispatch(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 all() { + var handles = flatten(slice.call(arguments)); + + for (var i = 0; i < handles.length; i++) { + var handle = handles[i]; + + if (typeof handle !== 'function') { + var type = toString.call(handle); + var msg = 'Route.all() requires callback functions but got a ' + type; + throw new TypeError(msg); + } + + var layer = Layer('/', {}, handle); + layer.method = undefined; + + this.methods._all = true; + this.stack.push(layer); + } + + return this; + }; + + methods.forEach(function (method) { + Route.prototype[method] = function () { + var handles = flatten(slice.call(arguments)); + + for (var i = 0; i < handles.length; i++) { + var handle = handles[i]; + + if (typeof handle !== 'function') { + var type = toString.call(handle); + var msg = 'Route.' + method + '() requires callback functions but got a ' + type; + throw new Error(msg); + } + + debug('%s %s', method, this.path); + + var layer = Layer('/', {}, handle); + layer.method = method; + + this.methods[method] = true; + this.stack.push(layer); + } + + return this; + }; + }); +}); + +var __moduleExports$19 = createCommonjsModule(function (module, exports) { + /** + * 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; + }; +}); + +var __moduleExports$22 = createCommonjsModule(function (module) { + /*! + * depd + * Copyright(c) 2014 Douglas Christopher Wilson + * MIT Licensed + */ + + 'use strict'; + + /** + * 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; + } +}); + +var __moduleExports$23 = createCommonjsModule(function (module) { + /*! + * depd + * Copyright(c) 2014 Douglas Christopher Wilson + * MIT Licensed + */ + + 'use strict'; + + /** + * 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; + } +}); + +var __moduleExports$24 = createCommonjsModule(function (module) { + /*! + * depd + * Copyright(c) 2015 Douglas Christopher Wilson + * MIT Licensed + */ + + 'use strict'; + + /** + * Module exports. + * @public + */ + + module.exports = eventListenerCount; + + /** + * Get the count of listeners on an event emitter of a specific type. + */ + + function eventListenerCount(emitter, type) { + return emitter.listeners(type).length; + } +}); + +var __moduleExports$21 = createCommonjsModule(function (module) { + /*! + * depd + * Copyright(c) 2014-2015 Douglas Christopher Wilson + * MIT Licensed + */ + + 'use strict'; + + /** + * Module dependencies. + * @private + */ + + var Buffer = buffer; + var EventEmitter = events.EventEmitter; + + /** + * Module exports. + * @public + */ + + lazyProperty(module.exports, 'bufferConcat', function bufferConcat() { + return Buffer.concat || __moduleExports$22; + }); + + 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 : __moduleExports$23; + }); + + lazyProperty(module.exports, 'eventListenerCount', function eventListenerCount() { + return EventEmitter.listenerCount || __moduleExports$24; + }); + + /** + * 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(); + } +}); + +var __moduleExports$20 = createCommonjsModule(function (module) { + /*! + * depd + * Copyright(c) 2014-2015 Douglas Christopher Wilson + * MIT Licensed + */ + + /** + * Module dependencies. + */ + + var callSiteToString = __moduleExports$21.callSiteToString; + var eventListenerCount = __moduleExports$21.eventListenerCount; + var relative = path.relative; + + /** + * Module exports. + */ + + module.exports = depd; + + /** + * Get the path to base files on. + */ + + var basePath = process.cwd(); + + /** + * 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; + + // make useful anonymous name + if (!funcName) { + funcName = ''; + } + + var context = callSite.getThis(); + var typeName = context && callSite.getTypeName(); + + // ignore useless type name + if (typeName === 'Object') { + typeName = undefined; + } + + // make useful type name + if (typeName === 'Function') { + typeName = context.name || typeName; + } + + return typeName && 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 === 'undefined' ? 'undefined' : _typeof$1(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 get() { + if (stackString !== undefined) { + return stackString; + } + + // prepare stack trace + return stackString = createStackString.call(this, stack); + }, + set: function setter(val) { + stackString = val; + } + }); + + return error; + } +}); + +var __moduleExports$25 = createCommonjsModule(function (module) { + /*! + * parseurl + * Copyright(c) 2014 Jonathan Ong + * Copyright(c) 2014 Douglas Christopher Wilson + * MIT Licensed + */ + + 'use strict'; + + /** + * Module dependencies. + */ + + var url$$ = 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 === 'undefined' ? 'undefined' : _typeof$1(parsedUrl)) === 'object' && parsedUrl !== null && (Url === undefined || parsedUrl instanceof Url) && parsedUrl._raw === url$$; + } +}); + +var __moduleExports$13 = createCommonjsModule(function (module) { + /*! + * express + * Copyright(c) 2009-2013 TJ Holowaychuk + * Copyright(c) 2013 Roman Shtylman + * Copyright(c) 2014-2015 Douglas Christopher Wilson + * MIT Licensed + */ + + 'use strict'; + + /** + * Module dependencies. + * @private + */ + + var Route = __moduleExports$14; + var Layer = __moduleExports$16; + var methods = __moduleExports$18; + var mixin = __moduleExports$19; + var debug = __moduleExports$5('express:router'); + var deprecate = __moduleExports$20('express'); + var flatten = __moduleExports$15; + var parseUrl = __moduleExports$25; + + /** + * Module variables. + * @private + */ + + 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 + * @public + */ + + var proto = module.exports = function (options) { + var opts = options || {}; + + function router(req, res, next) { + router.handle(req, res, next); + } + + // mixin Router class functions + router.__proto__ = proto; + + router.params = {}; + router._params = []; + router.caseSensitive = opts.caseSensitive; + router.mergeParams = opts.mergeParams; + router.strict = opts.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 + * @public + */ + + proto.param = function param(name, fn) { + // param logic + if (typeof name === 'function') { + deprecate('router.param(fn): Refactor to use path params'); + this._params.push(name); + return; + } + + // apply param functions + var params = this._params; + var len = params.length; + var ret; + + if (name[0] === ':') { + deprecate('router.param(' + JSON.stringify(name) + ', fn): Use router.param(' + JSON.stringify(name.substr(1)) + ', fn) instead'); + 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. + * @private + */ + + proto.handle = function handle(req, res, out) { + 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 = req.url[0] !== '/' && 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 || ''; + var done = restore(out, 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); + sendOptionsResponse(res, options, old); + }); + } + + // setup basic req values + req.baseUrl = parentUrl; + req.originalUrl = req.originalUrl || req.url; + + next(); + + function next(err) { + var layerError = err === 'route' ? null : err; + + // remove added slash + if (slashAdded) { + req.url = req.url.substr(1); + slashAdded = false; + } + + // restore altered req.url + if (removed.length !== 0) { + req.baseUrl = parentUrl; + req.url = protohost + removed + req.url.substr(protohost.length); + removed = ''; + } + + // no more matching layers + if (idx >= stack.length) { + setImmediate(done, layerError); + return; + } + + // get pathname of request + var path = getPathname(req); + + if (path == null) { + return done(layerError); + } + + // find next matching layer + var layer; + var match; + var route; + + while (match !== true && idx < stack.length) { + layer = stack[idx++]; + match = matchLayer(layer, path); + route = layer.route; + + if (typeof match !== 'boolean') { + // hold on to layerError + layerError = layerError || match; + } + + if (match !== true) { + continue; + } + + if (!route) { + // process non-route handlers normally + continue; + } + + if (layerError) { + // routes do not match with a pending error + match = false; + continue; + } + + var method = req.method; + var has_method = route._handles_method(method); + + // build up automatic options response + if (!has_method && method === 'OPTIONS') { + appendMethods(options, route._options()); + } + + // don't even bother matching route + if (!has_method && method !== 'HEAD') { + match = false; + continue; + } + } + + // no match + if (match !== true) { + return done(layerError); + } + + // store route for dispatch on change + if (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); + } + } + }; + + /** + * Process any parameters for the layer. + * @private + */ + + proto.process_params = function process_params(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.match === paramVal || paramCalled.error && paramCalled.error !== 'route')) { + // 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. + * + * @public + */ + + proto.use = function use(fn) { + var offset = 0; + var path = '/'; + + // 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 = flatten(slice.call(arguments, offset)); + + if (callbacks.length === 0) { + throw new TypeError('Router.use() requires middleware functions'); + } + + for (var i = 0; i < callbacks.length; i++) { + var fn = callbacks[i]; + + 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: this.caseSensitive, + strict: false, + end: false + }, fn); + + layer.route = undefined; + + this.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} + * @public + */ + + proto.route = function route(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; + }; + }); + + // append methods to a list of methods + function appendMethods(list, addition) { + for (var i = 0; i < addition.length; i++) { + var method = addition[i]; + if (list.indexOf(method) === -1) { + list.push(method); + } + } + } + + // get pathname of request + function getPathname(req) { + try { + return parseUrl(req).pathname; + } catch (err) { + return undefined; + } + } + + // get type for error message + function gettype(obj) { + var type = typeof obj === 'undefined' ? 'undefined' : _typeof$1(obj); + + if (type !== 'object') { + return type; + } + + // inspect [[Class]] for objects + return toString.call(obj).replace(objectRegExp, '$1'); + } + + /** + * Match path to a layer. + * + * @param {Layer} layer + * @param {string} path + * @private + */ + + function matchLayer(layer, path) { + try { + return layer.match(path); + } catch (err) { + return err; + } + } + + // merge params with parent params + function mergeParams(params, parent) { + if ((typeof parent === 'undefined' ? 'undefined' : _typeof$1(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 in params) { + i++; + } + + while (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(obj, 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); + }; + } + + // send an OPTIONS response + function sendOptionsResponse(res, options, next) { + try { + var body = options.join(','); + res.set('Allow', body); + res.send(body); + } catch (err) { + next(err); + } + } + + // 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); + }; + } +}); + +var __moduleExports$26 = createCommonjsModule(function (module, exports) { + /*! + * express + * Copyright(c) 2009-2013 TJ Holowaychuk + * Copyright(c) 2013 Roman Shtylman + * Copyright(c) 2014-2015 Douglas Christopher Wilson + * MIT Licensed + */ + + 'use strict'; + + /** + * Initialization middleware, exposing the + * request and response to each other, 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(); + }; + }; +}); + +var init$$1 = __moduleExports$26.init; + +var __moduleExports$30 = createCommonjsModule(function (module, exports) { + 'use strict'; + + var hexTable = function () { + var array = new Array(256); + for (var i = 0; i < 256; ++i) { + array[i] = '%' + ((i < 16 ? '0' : '') + i.toString(16)).toUpperCase(); + } + + return array; + }(); + + exports.arrayToObject = function (source, options) { + var obj = options.plainObjects ? Object.create(null) : {}; + for (var i = 0; i < source.length; ++i) { + if (typeof source[i] !== 'undefined') { + obj[i] = source[i]; + } + } + + return obj; + }; + + exports.merge = function (target, source, options) { + if (!source) { + return target; + } + + if ((typeof source === 'undefined' ? 'undefined' : _typeof$1(source)) !== 'object') { + if (Array.isArray(target)) { + target.push(source); + } else if ((typeof target === 'undefined' ? 'undefined' : _typeof$1(target)) === 'object') { + target[source] = true; + } else { + return [target, source]; + } + + return target; + } + + if ((typeof target === 'undefined' ? 'undefined' : _typeof$1(target)) !== 'object') { + return [target].concat(source); + } + + var mergeTarget = target; + if (Array.isArray(target) && !Array.isArray(source)) { + mergeTarget = exports.arrayToObject(target, options); + } + + return Object.keys(source).reduce(function (acc, key) { + var value = source[key]; + + if (Object.prototype.hasOwnProperty.call(acc, key)) { + acc[key] = exports.merge(acc[key], value, options); + } else { + acc[key] = value; + } + return acc; + }, mergeTarget); + }; + + exports.decode = function (str) { + try { + return decodeURIComponent(str.replace(/\+/g, ' ')); + } catch (e) { + return str; + } + }; + + exports.encode = function (str) { + // This code was originally written by Brian White (mscdex) for the io.js core querystring library. + // It has been adapted here for stricter adherence to RFC 3986 + if (str.length === 0) { + return str; + } + + var string = typeof str === 'string' ? str : String(str); + + var out = ''; + for (var i = 0; i < string.length; ++i) { + var c = string.charCodeAt(i); + + if (c === 0x2D || // - + c === 0x2E || // . + c === 0x5F || // _ + c === 0x7E || // ~ + c >= 0x30 && c <= 0x39 || // 0-9 + c >= 0x41 && c <= 0x5A || // a-z + c >= 0x61 && c <= 0x7A // A-Z + ) { + out += string.charAt(i); + continue; + } + + if (c < 0x80) { + out = out + hexTable[c]; + continue; + } + + if (c < 0x800) { + out = out + (hexTable[0xC0 | c >> 6] + hexTable[0x80 | c & 0x3F]); + continue; + } + + if (c < 0xD800 || c >= 0xE000) { + out = out + (hexTable[0xE0 | c >> 12] + hexTable[0x80 | c >> 6 & 0x3F] + hexTable[0x80 | c & 0x3F]); + continue; + } + + i += 1; + c = 0x10000 + ((c & 0x3FF) << 10 | string.charCodeAt(i) & 0x3FF); + out += hexTable[0xF0 | c >> 18] + hexTable[0x80 | c >> 12 & 0x3F] + hexTable[0x80 | c >> 6 & 0x3F] + hexTable[0x80 | c & 0x3F]; + } + + return out; + }; + + exports.compact = function (obj, references) { + if ((typeof obj === 'undefined' ? 'undefined' : _typeof$1(obj)) !== 'object' || obj === null) { + return obj; + } + + var refs = references || []; + var lookup = refs.indexOf(obj); + if (lookup !== -1) { + return refs[lookup]; + } + + refs.push(obj); + + if (Array.isArray(obj)) { + var compacted = []; + + for (var i = 0; i < obj.length; ++i) { + if (obj[i] && _typeof$1(obj[i]) === 'object') { + compacted.push(exports.compact(obj[i], refs)); + } else if (typeof obj[i] !== 'undefined') { + compacted.push(obj[i]); + } + } + + return compacted; + } + + var keys = Object.keys(obj); + for (var j = 0; j < keys.length; ++j) { + var key = keys[j]; + 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 (obj === null || typeof obj === 'undefined') { + return false; + } + + return !!(obj.constructor && obj.constructor.isBuffer && obj.constructor.isBuffer(obj)); + }; +}); + +var __moduleExports$29 = createCommonjsModule(function (module) { + 'use strict'; + + var Utils = __moduleExports$30; + + var arrayPrefixGenerators = { + brackets: function brackets(prefix) { + return prefix + '[]'; + }, + indices: function indices(prefix, key) { + return prefix + '[' + key + ']'; + }, + repeat: function repeat(prefix) { + return prefix; + } + }; + + var defaults = { + delimiter: '&', + strictNullHandling: false, + skipNulls: false, + encode: true, + encoder: Utils.encode + }; + + var stringify = function stringify(object, prefix, generateArrayPrefix, strictNullHandling, skipNulls, encoder, filter, sort, allowDots) { + var obj = object; + if (typeof filter === 'function') { + obj = filter(prefix, obj); + } else if (obj instanceof Date) { + obj = obj.toISOString(); + } else if (obj === null) { + if (strictNullHandling) { + return encoder ? encoder(prefix) : prefix; + } + + obj = ''; + } + + if (typeof obj === 'string' || typeof obj === 'number' || typeof obj === 'boolean' || Utils.isBuffer(obj)) { + if (encoder) { + return [encoder(prefix) + '=' + encoder(obj)]; + } + return [prefix + '=' + String(obj)]; + } + + var values = []; + + if (typeof obj === 'undefined') { + return values; + } + + var objKeys; + if (Array.isArray(filter)) { + objKeys = filter; + } else { + var keys = Object.keys(obj); + objKeys = sort ? keys.sort(sort) : keys; + } + + for (var i = 0; i < objKeys.length; ++i) { + var key = objKeys[i]; + + if (skipNulls && obj[key] === null) { + continue; + } + + if (Array.isArray(obj)) { + values = values.concat(stringify(obj[key], generateArrayPrefix(prefix, key), generateArrayPrefix, strictNullHandling, skipNulls, encoder, filter, sort, allowDots)); + } else { + values = values.concat(stringify(obj[key], prefix + (allowDots ? '.' + key : '[' + key + ']'), generateArrayPrefix, strictNullHandling, skipNulls, encoder, filter, sort, allowDots)); + } + } + + return values; + }; + + module.exports = function (object, opts) { + var obj = object; + var options = opts || {}; + var delimiter = typeof options.delimiter === 'undefined' ? defaults.delimiter : options.delimiter; + var strictNullHandling = typeof options.strictNullHandling === 'boolean' ? options.strictNullHandling : defaults.strictNullHandling; + var skipNulls = typeof options.skipNulls === 'boolean' ? options.skipNulls : defaults.skipNulls; + var encode = typeof options.encode === 'boolean' ? options.encode : defaults.encode; + var encoder = encode ? typeof options.encoder === 'function' ? options.encoder : defaults.encoder : null; + var sort = typeof options.sort === 'function' ? options.sort : null; + var allowDots = typeof options.allowDots === 'undefined' ? false : options.allowDots; + var objKeys; + var filter; + + if (options.encoder !== null && options.encoder !== undefined && typeof options.encoder !== 'function') { + throw new TypeError('Encoder has to be a function.'); + } + + if (typeof options.filter === 'function') { + filter = options.filter; + obj = filter('', obj); + } else if (Array.isArray(options.filter)) { + objKeys = filter = options.filter; + } + + var keys = []; + + if ((typeof obj === 'undefined' ? 'undefined' : _typeof$1(obj)) !== 'object' || obj === null) { + return ''; + } + + var arrayFormat; + if (options.arrayFormat in arrayPrefixGenerators) { + arrayFormat = options.arrayFormat; + } else if ('indices' in options) { + arrayFormat = options.indices ? 'indices' : 'repeat'; + } else { + arrayFormat = 'indices'; + } + + var generateArrayPrefix = arrayPrefixGenerators[arrayFormat]; + + if (!objKeys) { + objKeys = Object.keys(obj); + } + + if (sort) { + objKeys.sort(sort); + } + + for (var i = 0; i < objKeys.length; ++i) { + var key = objKeys[i]; + + if (skipNulls && obj[key] === null) { + continue; + } + + keys = keys.concat(stringify(obj[key], key, generateArrayPrefix, strictNullHandling, skipNulls, encoder, filter, sort, allowDots)); + } + + return keys.join(delimiter); + }; +}); + +var __moduleExports$31 = createCommonjsModule(function (module) { + 'use strict'; + + var Utils = __moduleExports$30; + + var defaults = { + delimiter: '&', + depth: 5, + arrayLimit: 20, + parameterLimit: 1000, + strictNullHandling: false, + plainObjects: false, + allowPrototypes: false, + allowDots: false, + decoder: Utils.decode + }; + + var parseValues = function parseValues(str, options) { + var obj = {}; + var parts = str.split(options.delimiter, options.parameterLimit === Infinity ? undefined : options.parameterLimit); + + for (var i = 0; i < parts.length; ++i) { + var part = parts[i]; + var pos = part.indexOf(']=') === -1 ? part.indexOf('=') : part.indexOf(']=') + 1; + + if (pos === -1) { + obj[options.decoder(part)] = ''; + + if (options.strictNullHandling) { + obj[options.decoder(part)] = null; + } + } else { + var key = options.decoder(part.slice(0, pos)); + var val = options.decoder(part.slice(pos + 1)); + + if (Object.prototype.hasOwnProperty.call(obj, key)) { + obj[key] = [].concat(obj[key]).concat(val); + } else { + obj[key] = val; + } + } + } + + return obj; + }; + + var parseObject = function parseObject(chain, val, options) { + if (!chain.length) { + return val; + } + + var root = chain.shift(); + + var obj; + if (root === '[]') { + obj = []; + obj = obj.concat(parseObject(chain, val, options)); + } else { + obj = options.plainObjects ? Object.create(null) : {}; + var cleanRoot = root[0] === '[' && root[root.length - 1] === ']' ? root.slice(1, root.length - 1) : root; + var index = parseInt(cleanRoot, 10); + if (!isNaN(index) && root !== cleanRoot && String(index) === cleanRoot && index >= 0 && options.parseArrays && index <= options.arrayLimit) { + obj = []; + obj[index] = parseObject(chain, val, options); + } else { + obj[cleanRoot] = parseObject(chain, val, options); + } + } + + return obj; + }; + + var parseKeys = function parseKeys(givenKey, val, options) { + if (!givenKey) { + return; + } + + // Transform dot notation to bracket notation + var key = options.allowDots ? givenKey.replace(/\.([^\.\[]+)/g, '[$1]') : givenKey; + + // The regex chunks + + var parent = /^([^\[\]]*)/; + var child = /(\[[^\[\]]*\])/g; + + // Get the parent + + var segment = parent.exec(key); + + // Stash the parent if it exists + + var keys = []; + if (segment[1]) { + // If we aren't using plain objects, optionally prefix keys + // that would overwrite object prototype properties + if (!options.plainObjects && Object.prototype.hasOwnProperty(segment[1])) { + if (!options.allowPrototypes) { + return; + } + } + + 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 += 1; + if (!options.plainObjects && Object.prototype.hasOwnProperty(segment[1].replace(/\[|\]/g, ''))) { + if (!options.allowPrototypes) { + continue; + } + } + keys.push(segment[1]); + } + + // If there's a remainder, just add whatever is left + + if (segment) { + keys.push('[' + key.slice(segment.index) + ']'); + } + + return parseObject(keys, val, options); + }; + + module.exports = function (str, opts) { + var options = opts || {}; + + if (options.decoder !== null && options.decoder !== undefined && typeof options.decoder !== 'function') { + throw new TypeError('Decoder has to be a function.'); + } + + options.delimiter = typeof options.delimiter === 'string' || Utils.isRegExp(options.delimiter) ? options.delimiter : defaults.delimiter; + options.depth = typeof options.depth === 'number' ? options.depth : defaults.depth; + options.arrayLimit = typeof options.arrayLimit === 'number' ? options.arrayLimit : defaults.arrayLimit; + options.parseArrays = options.parseArrays !== false; + options.decoder = typeof options.decoder === 'function' ? options.decoder : defaults.decoder; + options.allowDots = typeof options.allowDots === 'boolean' ? options.allowDots : defaults.allowDots; + options.plainObjects = typeof options.plainObjects === 'boolean' ? options.plainObjects : defaults.plainObjects; + options.allowPrototypes = typeof options.allowPrototypes === 'boolean' ? options.allowPrototypes : defaults.allowPrototypes; + options.parameterLimit = typeof options.parameterLimit === 'number' ? options.parameterLimit : defaults.parameterLimit; + options.strictNullHandling = typeof options.strictNullHandling === 'boolean' ? options.strictNullHandling : defaults.strictNullHandling; + + if (str === '' || str === null || typeof str === 'undefined') { + return options.plainObjects ? Object.create(null) : {}; + } + + var tempObj = typeof str === 'string' ? parseValues(str, options) : str; + var obj = options.plainObjects ? Object.create(null) : {}; + + // Iterate over the keys and setup the new object + + var keys = Object.keys(tempObj); + for (var i = 0; i < keys.length; ++i) { + var key = keys[i]; + var newObj = parseKeys(key, tempObj[key], options); + obj = Utils.merge(obj, newObj, options); + } + + return Utils.compact(obj); + }; +}); + +var __moduleExports$28 = createCommonjsModule(function (module) { + 'use strict'; + + var Stringify = __moduleExports$29; + var Parse = __moduleExports$31; + + module.exports = { + stringify: Stringify, + parse: Parse + }; +}); + +var __moduleExports$27 = createCommonjsModule(function (module) { + /*! + * express + * Copyright(c) 2009-2013 TJ Holowaychuk + * Copyright(c) 2013 Roman Shtylman + * Copyright(c) 2014-2015 Douglas Christopher Wilson + * MIT Licensed + */ + + 'use strict'; + + /** + * Module dependencies. + */ + + var parseUrl = __moduleExports$25; + var qs = __moduleExports$28; + + /** + * @param {Object} options + * @return {Function} + * @api public + */ + + module.exports = function query(options) { + var opts = Object.create(options || null); + var queryparse = qs.parse; + + if (typeof options === 'function') { + queryparse = options; + opts = undefined; + } + + if (opts !== undefined && opts.allowPrototypes === undefined) { + // back-compat for qs module + opts.allowPrototypes = true; + } + + return function query(req, res, next) { + if (!req.query) { + var val = parseUrl(req).query; + req.query = queryparse(val, opts); + } + + next(); + }; + }; +}); + +var __moduleExports$34 = createCommonjsModule(function (module) { + /*! + * content-disposition + * Copyright(c) 2014 Douglas Christopher Wilson + * MIT Licensed + */ + + 'use strict'; + + /** + * Module exports. + */ + + module.exports = contentDisposition; + module.exports.parse = parse; + + /** + * Module dependencies. + */ + + var basename = path.basename; + + /** + * RegExp to match non attr-char, *after* encodeURIComponent (i.e. not including "%") + */ + + var encodeUriAttrCharRegExp = /[\x00-\x20"'\(\)*,\/:;<=>?@\[\\\]\{\}\x7f]/g; + + /** + * RegExp to match percent encoding escape. + */ + + var hexEscapeRegExp = /%[0-9A-Fa-f]{2}/; + var hexEscapeReplaceRegExp = /%([0-9A-Fa-f]{2})/g; + + /** + * RegExp to match non-latin1 characters. + */ + + var nonLatin1RegExp = /[^\x20-\x7e\xa0-\xff]/g; + + /** + * 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 for various RFC 2616 grammar + * + * 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 = + * HT = + * CTL = + * OCTET = + */ + + var paramRegExp = /; *([!#$%&'\*\+\-\.0-9A-Z\^_`a-z\|~]+) *= *("(?:[ !\x23-\x5b\x5d-\x7e\x80-\xff]|\\[\x20-\x7e])*"|[!#$%&'\*\+\-\.0-9A-Z\^_`a-z\|~]+) */g; + var textRegExp = /^[\x20-\x7e\x80-\xff]+$/; + var tokenRegExp = /^[!#$%&'\*\+\-\.0-9A-Z\^_`a-z\|~]+$/; + + /** + * RegExp for various RFC 5987 grammar + * + * ext-value = charset "'" [ language ] "'" value-chars + * charset = "UTF-8" / "ISO-8859-1" / mime-charset + * mime-charset = 1*mime-charsetc + * mime-charsetc = ALPHA / DIGIT + * / "!" / "#" / "$" / "%" / "&" + * / "+" / "-" / "^" / "_" / "`" + * / "{" / "}" / "~" + * language = ( 2*3ALPHA [ extlang ] ) + * / 4ALPHA + * / 5*8ALPHA + * extlang = *3( "-" 3ALPHA ) + * value-chars = *( pct-encoded / attr-char ) + * pct-encoded = "%" HEXDIG HEXDIG + * attr-char = ALPHA / DIGIT + * / "!" / "#" / "$" / "&" / "+" / "-" / "." + * / "^" / "_" / "`" / "|" / "~" + */ + + var extValueRegExp = /^([A-Za-z0-9!#$%&+\-^_`{}~]+)'(?:[A-Za-z]{2,3}(?:-[A-Za-z]{3}){0,3}|[A-Za-z]{4,8}|)'((?:%[0-9A-Fa-f]{2}|[A-Za-z0-9!#$&+\-\.^_`|~])+)$/; + + /** + * RegExp for various RFC 6266 grammar + * + * disposition-type = "inline" | "attachment" | disp-ext-type + * disp-ext-type = token + * disposition-parm = filename-parm | disp-ext-parm + * filename-parm = "filename" "=" value + * | "filename*" "=" ext-value + * disp-ext-parm = token "=" value + * | ext-token "=" ext-value + * ext-token = + */ + + var dispositionTypeRegExp = /^([!#$%&'\*\+\-\.0-9A-Z\^_`a-z\|~]+) *(?:$|;)/; + + /** + * Create an attachment Content-Disposition header. + * + * @param {string} [filename] + * @param {object} [options] + * @param {string} [options.type=attachment] + * @param {string|boolean} [options.fallback=true] + * @return {string} + * @api public + */ + + function contentDisposition(filename, options) { + var opts = options || {}; + + // get type + var type = opts.type || 'attachment'; + + // get parameters + var params = createparams(filename, opts.fallback); + + // format into string + return format(new ContentDisposition(type, params)); + } + + /** + * Create parameters object from filename and fallback. + * + * @param {string} [filename] + * @param {string|boolean} [fallback=true] + * @return {object} + * @api private + */ + + function createparams(filename, fallback) { + if (filename === undefined) { + return; + } + + var params = {}; + + if (typeof filename !== 'string') { + throw new TypeError('filename must be a string'); + } + + // fallback defaults to true + if (fallback === undefined) { + fallback = true; + } + + if (typeof fallback !== 'string' && typeof fallback !== 'boolean') { + throw new TypeError('fallback must be a string or boolean'); + } + + if (typeof fallback === 'string' && nonLatin1RegExp.test(fallback)) { + throw new TypeError('fallback must be ISO-8859-1 string'); + } + + // restrict to file base name + var name = basename(filename); + + // determine if name is suitable for quoted string + var isQuotedString = textRegExp.test(name); + + // generate fallback name + var fallbackName = typeof fallback !== 'string' ? fallback && getlatin1(name) : basename(fallback); + var hasFallback = typeof fallbackName === 'string' && fallbackName !== name; + + // set extended filename parameter + if (hasFallback || !isQuotedString || hexEscapeRegExp.test(name)) { + params['filename*'] = name; + } + + // set filename parameter + if (isQuotedString || hasFallback) { + params.filename = hasFallback ? fallbackName : name; + } + + return params; + } + + /** + * Format object to Content-Disposition header. + * + * @param {object} obj + * @param {string} obj.type + * @param {object} [obj.parameters] + * @return {string} + * @api private + */ + + function format(obj) { + var parameters = obj.parameters; + var type = obj.type; + + if (!type || typeof type !== 'string' || !tokenRegExp.test(type)) { + throw new TypeError('invalid type'); + } + + // start with normalized type + var string = String(type).toLowerCase(); + + // append parameters + if (parameters && (typeof parameters === 'undefined' ? 'undefined' : _typeof$1(parameters)) === 'object') { + var param; + var params = Object.keys(parameters).sort(); + + for (var i = 0; i < params.length; i++) { + param = params[i]; + + var val = param.substr(-1) === '*' ? ustring(parameters[param]) : qstring(parameters[param]); + + string += '; ' + param + '=' + val; + } + } + + return string; + } + + /** + * Decode a RFC 6987 field value (gracefully). + * + * @param {string} str + * @return {string} + * @api private + */ + + function decodefield(str) { + var match = extValueRegExp.exec(str); + + if (!match) { + throw new TypeError('invalid extended field value'); + } + + var charset = match[1].toLowerCase(); + var encoded = match[2]; + var value; + + // to binary string + var binary = encoded.replace(hexEscapeReplaceRegExp, pdecode); + + switch (charset) { + case 'iso-8859-1': + value = getlatin1(binary); + break; + case 'utf-8': + value = new Buffer(binary, 'binary').toString('utf8'); + break; + default: + throw new TypeError('unsupported charset in extended field'); + } + + return value; + } + + /** + * Get ISO-8859-1 version of string. + * + * @param {string} val + * @return {string} + * @api private + */ + + function getlatin1(val) { + // simple Unicode -> ISO-8859-1 transformation + return String(val).replace(nonLatin1RegExp, '?'); + } + + /** + * Parse Content-Disposition header string. + * + * @param {string} string + * @return {object} + * @api private + */ + + function parse(string) { + if (!string || typeof string !== 'string') { + throw new TypeError('argument string is required'); + } + + var match = dispositionTypeRegExp.exec(string); + + if (!match) { + throw new TypeError('invalid type format'); + } + + // normalize type + var index = match[0].length; + var type = match[1].toLowerCase(); + + var key; + var names = []; + var params = {}; + var value; + + // calculate index to start at + index = paramRegExp.lastIndex = match[0].substr(-1) === ';' ? index - 1 : index; + + // match parameters + 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 (names.indexOf(key) !== -1) { + throw new TypeError('invalid duplicate parameter'); + } + + names.push(key); + + if (key.indexOf('*') + 1 === key.length) { + // decode extended value + key = key.slice(0, -1); + value = decodefield(value); + + // overwrite existing value + params[key] = value; + continue; + } + + if (typeof params[key] === 'string') { + continue; + } + + 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'); + } + + return new ContentDisposition(type, params); + } + + /** + * Percent decode a single character. + * + * @param {string} str + * @param {string} hex + * @return {string} + * @api private + */ + + function pdecode(str, hex) { + return String.fromCharCode(parseInt(hex, 16)); + } + + /** + * Percent encode a single character. + * + * @param {string} char + * @return {string} + * @api private + */ + + function pencode(char) { + var hex = String(char).charCodeAt(0).toString(16).toUpperCase(); + return hex.length === 1 ? '%0' + hex : '%' + hex; + } + + /** + * Quote a string for HTTP. + * + * @param {string} val + * @return {string} + * @api private + */ + + function qstring(val) { + var str = String(val); + + return '"' + str.replace(quoteRegExp, '\\$1') + '"'; + } + + /** + * Encode a Unicode string for HTTP (RFC 5987). + * + * @param {string} val + * @return {string} + * @api private + */ + + function ustring(val) { + var str = String(val); + + // percent encode as UTF-8 + var encoded = encodeURIComponent(str).replace(encodeUriAttrCharRegExp, pencode); + + return 'UTF-8\'\'' + encoded; + } + + /** + * Class for parsed Content-Disposition header for v8 optimization + */ + + function ContentDisposition(type, parameters) { + this.type = type; + this.parameters = parameters; + } +}); + +var __moduleExports$35 = createCommonjsModule(function (module, exports) { + /*! + * content-type + * Copyright(c) 2015 Douglas Christopher Wilson + * MIT Licensed + */ + + 'use strict'; + + /** + * RegExp to match *( ";" parameter ) in RFC 7231 sec 3.1.1.1 + * + * parameter = token "=" ( token / quoted-string ) + * token = 1*tchar + * tchar = "!" / "#" / "$" / "%" / "&" / "'" / "*" + * / "+" / "-" / "." / "^" / "_" / "`" / "|" / "~" + * / DIGIT / ALPHA + * ; any VCHAR, except delimiters + * quoted-string = DQUOTE *( qdtext / quoted-pair ) DQUOTE + * qdtext = HTAB / SP / %x21 / %x23-5B / %x5D-7E / obs-text + * obs-text = %x80-FF + * quoted-pair = "\" ( HTAB / SP / VCHAR / obs-text ) + */ + + var paramRegExp = /; *([!#$%&'\*\+\-\.\^_`\|~0-9A-Za-z]+) *= *("(?:[\u000b\u0020\u0021\u0023-\u005b\u005d-\u007e\u0080-\u00ff]|\\[\u000b\u0020-\u00ff])*"|[!#$%&'\*\+\-\.\^_`\|~0-9A-Za-z]+) */g; + var textRegExp = /^[\u000b\u0020-\u007e\u0080-\u00ff]+$/; + var tokenRegExp = /^[!#$%&'\*\+\-\.\^_`\|~0-9A-Za-z]+$/; + + /** + * RegExp to match quoted-pair in RFC 7230 sec 3.2.6 + * + * quoted-pair = "\" ( HTAB / SP / VCHAR / obs-text ) + * obs-text = %x80-FF + */ + var qescRegExp = /\\([\u000b\u0020-\u00ff])/g; + + /** + * RegExp to match chars that must be quoted-pair in RFC 7230 sec 3.2.6 + */ + var quoteRegExp = /([\\"])/g; + + /** + * RegExp to match type in RFC 6838 + * + * media-type = type "/" subtype + * type = token + * subtype = token + */ + var typeRegExp = /^[!#$%&'\*\+\-\.\^_`\|~0-9A-Za-z]+\/[!#$%&'\*\+\-\.\^_`\|~0-9A-Za-z]+$/; + + /** + * Module exports. + * @public + */ + + exports.format = format; + exports.parse = parse; + + /** + * Format object to media type. + * + * @param {object} obj + * @return {string} + * @public + */ + + function format(obj) { + if (!obj || (typeof obj === 'undefined' ? 'undefined' : _typeof$1(obj)) !== 'object') { + throw new TypeError('argument obj is required'); + } + + var parameters = obj.parameters; + var type = obj.type; + + if (!type || !typeRegExp.test(type)) { + throw new TypeError('invalid type'); + } + + var string = type; + + // append parameters + if (parameters && (typeof parameters === 'undefined' ? 'undefined' : _typeof$1(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} + * @public + */ + + function parse(string) { + if (!string) { + throw new TypeError('argument string is required'); + } + + if ((typeof string === 'undefined' ? 'undefined' : _typeof$1(string)) === 'object') { + // support req/res-like objects as argument + string = getcontenttype(string); + + if (typeof string !== 'string') { + throw new TypeError('content-type header is missing from object'); + } + } + + 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).trim() : string.trim(); + + if (!typeRegExp.test(type)) { + throw new TypeError('invalid media type'); + } + + var key; + var match; + var obj = new ContentType(type.toLowerCase()); + 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'); + } + + obj.parameters[key] = value; + } + + if (index !== -1 && index !== string.length) { + throw new TypeError('invalid parameter format'); + } + + return obj; + } + + /** + * Get content-type from req/res objects. + * + * @param {object} + * @return {Object} + * @private + */ + + function getcontenttype(obj) { + if (typeof obj.getHeader === 'function') { + // res-like + return obj.getHeader('content-type'); + } + + if (_typeof$1(obj.headers) === 'object') { + // req-like + return obj.headers && obj.headers['content-type']; + } + } + + /** + * Quote a string if necessary. + * + * @param {string} val + * @return {string} + * @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') + '"'; + } + + /** + * Class to represent a content type. + * @private + */ + function ContentType(type) { + this.parameters = Object.create(null); + this.type = type; + } +}); + +var __moduleExports$38 = createCommonjsModule(function (module) { + module.exports = Object.setPrototypeOf || ({ __proto__: [] } instanceof Array ? setProtoOf : mixinProperties); + + function setProtoOf(obj, proto) { + obj.__proto__ = proto; + } + + function mixinProperties(obj, proto) { + for (var prop in proto) { + obj[prop] = proto[prop]; + } + } +}); + +var __moduleExports$39 = createCommonjsModule(function (module) { + module.exports = util.inherits; +}); + +var __moduleExports$37 = createCommonjsModule(function (module) { + /*! + * http-errors + * Copyright(c) 2014 Jonathan Ong + * Copyright(c) 2016 Douglas Christopher Wilson + * MIT Licensed + */ + + 'use strict'; + + /** + * Module dependencies. + * @private + */ + + var setPrototypeOf = __moduleExports$38; + var statuses = __moduleExports$11; + var inherits = __moduleExports$39; + + /** + * Module exports. + * @public + */ + + module.exports = createError; + module.exports.HttpError = createHttpErrorConstructor(); + + // Populate exports for all constructors + populateConstructorExports(module.exports, statuses.codes, module.exports.HttpError); + + /** + * Create a new HTTP Error. + * + * @returns {Error} + * @public + */ + + function createError() { + // so much arity going on ~_~ + var err; + var msg; + var status = 500; + var props = {}; + for (var i = 0; i < arguments.length; i++) { + var arg = arguments[i]; + if (arg instanceof Error) { + err = arg; + status = err.status || err.statusCode || status; + continue; + } + switch (typeof arg === 'undefined' ? 'undefined' : _typeof$1(arg)) { + case 'string': + msg = arg; + break; + case 'number': + status = arg; + break; + case 'object': + props = arg; + break; + } + } + + if (typeof status !== 'number' || !statuses[status]) { + status = 500; + } + + // constructor + var HttpError = createError[status]; + + if (!err) { + // create error + err = HttpError ? new HttpError(msg) : new Error(msg || statuses[status]); + Error.captureStackTrace(err, createError); + } + + if (!HttpError || !(err instanceof HttpError)) { + // add properties to generic error + err.expose = status < 500; + err.status = err.statusCode = status; + } + + for (var key in props) { + if (key !== 'status' && key !== 'statusCode') { + err[key] = props[key]; + } + } + + return err; + } + + /** + * Create HTTP error abstract base class. + * @private + */ + + function createHttpErrorConstructor() { + function HttpError() { + throw new TypeError('cannot construct abstract class'); + } + + inherits(HttpError, Error); + + return HttpError; + } + + /** + * Create a constructor for a client error. + * @private + */ + + function createClientErrorConstructor(HttpError, name, code) { + var className = name.match(/Error$/) ? name : name + 'Error'; + + function ClientError(message) { + // create the error object + var err = new Error(message != null ? message : statuses[code]); + + // capture a stack trace to the construction point + Error.captureStackTrace(err, ClientError); + + // adjust the [[Prototype]] + setPrototypeOf(err, ClientError.prototype); + + // redefine the error name + Object.defineProperty(err, 'name', { + enumerable: false, + configurable: true, + value: className, + writable: true + }); + + return err; + } + + inherits(ClientError, HttpError); + + ClientError.prototype.status = code; + ClientError.prototype.statusCode = code; + ClientError.prototype.expose = true; + + return ClientError; + } + + /** + * Create a constructor for a server error. + * @private + */ + + function createServerErrorConstructor(HttpError, name, code) { + var className = name.match(/Error$/) ? name : name + 'Error'; + + function ServerError(message) { + // create the error object + var err = new Error(message != null ? message : statuses[code]); + + // capture a stack trace to the construction point + Error.captureStackTrace(err, ServerError); + + // adjust the [[Prototype]] + setPrototypeOf(err, ServerError.prototype); + + // redefine the error name + Object.defineProperty(err, 'name', { + enumerable: false, + configurable: true, + value: className, + writable: true + }); + + return err; + } + + inherits(ServerError, HttpError); + + ServerError.prototype.status = code; + ServerError.prototype.statusCode = code; + ServerError.prototype.expose = false; + + return ServerError; + } + + /** + * Populate the exports object with constructors for every error class. + * @private + */ + + function populateConstructorExports(exports, codes, HttpError) { + codes.forEach(function forEachCode(code) { + var CodeError; + var name = toIdentifier(statuses[code]); + + switch (String(code).charAt(0)) { + case '4': + CodeError = createClientErrorConstructor(HttpError, name, code); + break; + case '5': + CodeError = createServerErrorConstructor(HttpError, name, code); + break; + } + + if (CodeError) { + // export the constructor + exports[code] = CodeError; + exports[name] = CodeError; + } + }); + + // backwards-compatibility + exports["I'mateapot"] = exports.ImATeapot; + } + + /** + * Convert a string of words to a JavaScript identifier. + * @private + */ + + function toIdentifier(str) { + return str.split(' ').map(function (token) { + return token.slice(0, 1).toUpperCase() + token.slice(1); + }).join('').replace(/[^ _0-9a-z]/gi, ''); + } +}); + +var __moduleExports$40 = createCommonjsModule(function (module) { + /*! + * destroy + * Copyright(c) 2014 Jonathan Ong + * MIT Licensed + */ + + 'use strict'; + + /** + * Module dependencies. + * @private + */ + + var ReadStream = fs.ReadStream; + var Stream = stream; + + /** + * Module exports. + * @public + */ + + module.exports = destroy; + + /** + * Destroy a stream. + * + * @param {object} stream + * @public + */ + + 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; + } + + /** + * Destroy a ReadStream. + * + * @param {object} stream + * @private + */ + + function destroyReadStream(stream) { + stream.destroy(); + + if (typeof stream.close === 'function') { + // node.js core bug work-around + stream.on('open', onOpenClose); + } + + return stream; + } + + /** + * On open handler to close stream. + * @private + */ + + function onOpenClose() { + if (typeof this.fd === 'number') { + // actually close down the fd + this.close(); + } + } +}); + +var __moduleExports$41 = createCommonjsModule(function (module) { + /*! + * encodeurl + * Copyright(c) 2016 Douglas Christopher Wilson + * MIT Licensed + */ + + 'use strict'; + + /** + * Module exports. + * @public + */ + + module.exports = encodeUrl; + + /** + * RegExp to match non-URL code points, *after* encoding (i.e. not including "%") + * and including invalid escape sequences. + * @private + */ + + var ENCODE_CHARS_REGEXP = /(?:[^\x21\x25\x26-\x3B\x3D\x3F-\x5B\x5D\x5F\x61-\x7A\x7E]|%(?:[^0-9A-Fa-f]|[0-9A-Fa-f][^0-9A-Fa-f]))+/g; + + /** + * RegExp to match unmatched surrogate pair. + * @private + */ + + var UNMATCHED_SURROGATE_PAIR_REGEXP = /(^|[^\uD800-\uDBFF])[\uDC00-\uDFFF]|[\uD800-\uDBFF]([^\uDC00-\uDFFF]|$)/g; + + /** + * String to replace unmatched surrogate pair with. + * @private + */ + + var UNMATCHED_SURROGATE_PAIR_REPLACE = '$1\uFFFD$2'; + + /** + * Encode a URL to a percent-encoded form, excluding already-encoded sequences. + * + * This function will take an already-encoded URL and encode all the non-URL + * code points. This function will not encode the "%" character unless it is + * not part of a valid sequence (`%20` will be left as-is, but `%foo` will + * be encoded as `%25foo`). + * + * This encode is meant to be "safe" and does not throw errors. It will try as + * hard as it can to properly encode the given URL, including replacing any raw, + * unpaired surrogate pairs with the Unicode replacement character prior to + * encoding. + * + * @param {string} url + * @return {string} + * @public + */ + + function encodeUrl(url) { + return String(url).replace(UNMATCHED_SURROGATE_PAIR_REGEXP, UNMATCHED_SURROGATE_PAIR_REPLACE).replace(ENCODE_CHARS_REGEXP, encodeURI); + } +}); + +var __moduleExports$42 = createCommonjsModule(function (module) { + /*! + * etag + * Copyright(c) 2014-2015 Douglas Christopher Wilson + * MIT Licensed + */ + + 'use strict'; + + /** + * Module exports. + * @public + */ + + module.exports = etag; + + /** + * Module dependencies. + * @private + */ + + var crypto$$ = crypto; + var Stats = fs.Stats; + + /** + * Module variables. + * @private + */ + + var base64PadCharRegExp = /=+$/; + var toString = Object.prototype.toString; + + /** + * Generate an entity tag. + * + * @param {Buffer|string} entity + * @return {string} + * @private + */ + + function entitytag(entity) { + if (entity.length === 0) { + // fast-path empty + return '"0-1B2M2Y8AsgTpgAmY7PhCfg"'; + } + + // compute hash of entity + var hash = crypto$$.createHash('md5').update(entity, 'utf8').digest('base64').replace(base64PadCharRegExp, ''); + + // compute length of entity + var len = typeof entity === 'string' ? Buffer.byteLength(entity, 'utf8') : entity.length; + + return '"' + len.toString(16) + '-' + hash + '"'; + } + + /** + * Create a simple ETag. + * + * @param {string|Buffer|Stats} entity + * @param {object} [options] + * @param {boolean} [options.weak] + * @return {String} + * @public + */ + + function etag(entity, options) { + if (entity == null) { + throw new TypeError('argument entity is required'); + } + + // support fs.Stats object + var isStats = isstats(entity); + var weak = options && typeof options.weak === 'boolean' ? options.weak : isStats; + + // validate argument + if (!isStats && typeof entity !== 'string' && !Buffer.isBuffer(entity)) { + throw new TypeError('argument entity must be string, Buffer, or fs.Stats'); + } + + // generate entity tag + var tag = isStats ? stattag(entity) : entitytag(entity); + + return weak ? 'W/' + tag : tag; + } + + /** + * Determine if object is a Stats object. + * + * @param {object} obj + * @return {boolean} + * @api private + */ + + function isstats(obj) { + // genuine fs.Stats + if (typeof Stats === 'function' && obj instanceof Stats) { + return true; + } + + // quack quack + return obj && (typeof obj === 'undefined' ? 'undefined' : _typeof$1(obj)) === 'object' && 'ctime' in obj && toString.call(obj.ctime) === '[object Date]' && 'mtime' in obj && toString.call(obj.mtime) === '[object Date]' && 'ino' in obj && typeof obj.ino === 'number' && 'size' in obj && typeof obj.size === 'number'; + } + + /** + * Generate a tag for a stat. + * + * @param {object} stat + * @return {string} + * @private + */ + + function stattag(stat) { + var mtime = stat.mtime.getTime().toString(16); + var size = stat.size.toString(16); + + return '"' + size + '-' + mtime + '"'; + } +}); + +var __moduleExports$43 = createCommonjsModule(function (module) { + /** + * 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.some(function (match) { + return match === '*' || match === etag || match === 'W/' + etag; + }); + } + + // if-modified-since + if (modifiedSince) { + modifiedSince = new Date(modifiedSince); + lastModified = new Date(lastModified); + notModified = lastModified <= modifiedSince; + } + + return !!(etagMatches && notModified); + } +}); + +var types$1 = { + "application/andrew-inset": ["ez"], + "application/applixware": ["aw"], + "application/atom+xml": ["atom"], + "application/atomcat+xml": ["atomcat"], + "application/atomsvc+xml": ["atomsvc"], + "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/cu-seeme": ["cu"], + "application/dash+xml": ["mdp"], + "application/davmount+xml": ["davmount"], + "application/docbook+xml": ["dbk"], + "application/dssc+der": ["dssc"], + "application/dssc+xml": ["xdssc"], + "application/ecmascript": ["ecma"], + "application/emma+xml": ["emma"], + "application/epub+zip": ["epub"], + "application/exi": ["exi"], + "application/font-tdpfr": ["pfr"], + "application/font-woff": ["woff"], + "application/font-woff2": ["woff2"], + "application/gml+xml": ["gml"], + "application/gpx+xml": ["gpx"], + "application/gxf": ["gxf"], + "application/hyperstudio": ["stk"], + "application/inkml+xml": ["ink", "inkml"], + "application/ipfix": ["ipfix"], + "application/java-archive": ["jar"], + "application/java-serialized-object": ["ser"], + "application/java-vm": ["class"], + "application/javascript": ["js"], + "application/json": ["json", "map"], + "application/json5": ["json5"], + "application/jsonml+json": ["jsonml"], + "application/lost+xml": ["lostxml"], + "application/mac-binhex40": ["hqx"], + "application/mac-compactpro": ["cpt"], + "application/mads+xml": ["mads"], + "application/marc": ["mrc"], + "application/marcxml+xml": ["mrcx"], + "application/mathematica": ["ma", "nb", "mb"], + "application/mathml+xml": ["mathml"], + "application/mbox": ["mbox"], + "application/mediaservercontrol+xml": ["mscml"], + "application/metalink+xml": ["metalink"], + "application/metalink4+xml": ["meta4"], + "application/mets+xml": ["mets"], + "application/mods+xml": ["mods"], + "application/mp21": ["m21", "mp21"], + "application/mp4": ["mp4s", "m4p"], + "application/msword": ["doc", "dot"], + "application/mxf": ["mxf"], + "application/octet-stream": ["bin", "dms", "lrf", "mar", "so", "dist", "distz", "pkg", "bpk", "dump", "elc", "deploy", "buffer"], + "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/patch-ops-error+xml": ["xer"], + "application/pdf": ["pdf"], + "application/pgp-encrypted": ["pgp"], + "application/pgp-signature": ["asc", "sig"], + "application/pics-rules": ["prf"], + "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/postscript": ["ai", "eps", "ps"], + "application/prs.cww": ["cww"], + "application/pskc+xml": ["pskcxml"], + "application/rdf+xml": ["rdf"], + "application/reginfo+xml": ["rif"], + "application/relax-ng-compact-syntax": ["rnc"], + "application/resource-lists+xml": ["rl"], + "application/resource-lists-diff+xml": ["rld"], + "application/rls-services+xml": ["rs"], + "application/rpki-ghostbusters": ["gbr"], + "application/rpki-manifest": ["mft"], + "application/rpki-roa": ["roa"], + "application/rsd+xml": ["rsd"], + "application/rss+xml": ["rss"], + "application/rtf": ["rtf"], + "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-initiation": ["setpay"], + "application/set-registration-initiation": ["setreg"], + "application/shf+xml": ["shf"], + "application/smil+xml": ["smi", "smil"], + "application/sparql-query": ["rq"], + "application/sparql-results+xml": ["srx"], + "application/srgs": ["gram"], + "application/srgs+xml": ["grxml"], + "application/sru+xml": ["sru"], + "application/ssdl+xml": ["ssdl"], + "application/ssml+xml": ["ssml"], + "application/tei+xml": ["tei", "teicorpus"], + "application/thraud+xml": ["tfi"], + "application/timestamped-data": ["tsd"], + "application/vnd.3gpp.pic-bw-large": ["plb"], + "application/vnd.3gpp.pic-bw-small": ["psb"], + "application/vnd.3gpp.pic-bw-var": ["pvb"], + "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.xdp+xml": ["xdp"], + "application/vnd.adobe.xfdf": ["xfdf"], + "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.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.aristanetworks.swi": ["swi"], + "application/vnd.astraea-software.iota": ["iota"], + "application/vnd.audiograph": ["aep"], + "application/vnd.blueice.multipass": ["mpm"], + "application/vnd.bmi": ["bmi"], + "application/vnd.businessobjects": ["rep"], + "application/vnd.chemdraw+xml": ["cdxml"], + "application/vnd.chipnuts.karaoke-mmd": ["mmd"], + "application/vnd.cinderella": ["cdy"], + "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.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.cups-ppd": ["ppd"], + "application/vnd.curl.car": ["car"], + "application/vnd.curl.pcurl": ["pcurl"], + "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.dna": ["dna"], + "application/vnd.dolby.mlp": ["mlp"], + "application/vnd.dpgraph": ["dpg"], + "application/vnd.dreamfactory": ["dfac"], + "application/vnd.ds-keypoint": ["kpxx"], + "application/vnd.dvb.ait": ["ait"], + "application/vnd.dvb.service": ["svc"], + "application/vnd.dynageo": ["geo"], + "application/vnd.ecowin.chart": ["mag"], + "application/vnd.enliven": ["nml"], + "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.eszigno3+xml": ["es3", "et3"], + "application/vnd.ezpix-album": ["ez2"], + "application/vnd.ezpix-package": ["ez3"], + "application/vnd.fdf": ["fdf"], + "application/vnd.fdsn.mseed": ["mseed"], + "application/vnd.fdsn.seed": ["seed", "dataless"], + "application/vnd.flographit": ["gph"], + "application/vnd.fluxtime.clip": ["ftc"], + "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.ddd": ["ddd"], + "application/vnd.fujixerox.docuworks": ["xdw"], + "application/vnd.fujixerox.docuworks.binder": ["xbd"], + "application/vnd.fuzzysheet": ["fzs"], + "application/vnd.genomatix.tuxedo": ["txd"], + "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.gmx": ["gmx"], + "application/vnd.google-earth.kml+xml": ["kml"], + "application/vnd.google-earth.kmz": ["kmz"], + "application/vnd.grafeq": ["gqf", "gqs"], + "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+xml": ["hal"], + "application/vnd.handheld-entertainment+xml": ["zmm"], + "application/vnd.hbci": ["hbci"], + "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.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.insors.igm": ["igm"], + "application/vnd.intercon.formnet": ["xpw", "xpx"], + "application/vnd.intergeo": ["i2g"], + "application/vnd.intu.qbo": ["qbo"], + "application/vnd.intu.qfx": ["qfx"], + "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.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.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.mcd": ["mcd"], + "application/vnd.medcalcdata": ["mc1"], + "application/vnd.mediastation.cdkey": ["cdkey"], + "application/vnd.mfer": ["mwf"], + "application/vnd.mfmp": ["mfm"], + "application/vnd.micrografx.flo": ["flo"], + "application/vnd.micrografx.igx": ["igx"], + "application/vnd.mif": ["mif"], + "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.mozilla.xul+xml": ["xul"], + "application/vnd.ms-artgalry": ["cil"], + "application/vnd.ms-cab-compressed": ["cab"], + "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-officetheme": ["thmx"], + "application/vnd.ms-pki.seccat": ["cat"], + "application/vnd.ms-pki.stl": ["stl"], + "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-project": ["mpp", "mpt"], + "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.musician": ["mus"], + "application/vnd.muvee.style": ["msty"], + "application/vnd.mynfc": ["taglet"], + "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.n-gage.data": ["ngdat"], + "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.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.olpc-sugar": ["xo"], + "application/vnd.oma.dd2+xml": ["dd2"], + "application/vnd.openofficeorg.extension": ["oxt"], + "application/vnd.openxmlformats-officedocument.presentationml.presentation": ["pptx"], + "application/vnd.openxmlformats-officedocument.presentationml.slide": ["sldx"], + "application/vnd.openxmlformats-officedocument.presentationml.slideshow": ["ppsx"], + "application/vnd.openxmlformats-officedocument.presentationml.template": ["potx"], + "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet": ["xlsx"], + "application/vnd.openxmlformats-officedocument.spreadsheetml.template": ["xltx"], + "application/vnd.openxmlformats-officedocument.wordprocessingml.document": ["docx"], + "application/vnd.openxmlformats-officedocument.wordprocessingml.template": ["dotx"], + "application/vnd.osgeo.mapguide.package": ["mgp"], + "application/vnd.osgi.dp": ["dp"], + "application/vnd.osgi.subsystem": ["esa"], + "application/vnd.palm": ["pdb", "pqa", "oprc"], + "application/vnd.pawaafile": ["paw"], + "application/vnd.pg.format": ["str"], + "application/vnd.pg.osasli": ["ei6"], + "application/vnd.picsel": ["efif"], + "application/vnd.pmi.widget": ["wg"], + "application/vnd.pocketlearn": ["plf"], + "application/vnd.powerbuilder6": ["pbd"], + "application/vnd.previewsystems.box": ["box"], + "application/vnd.proteus.magazine": ["mgz"], + "application/vnd.publishare-delta-tree": ["qps"], + "application/vnd.pvi.ptid1": ["ptid"], + "application/vnd.quark.quarkxpress": ["qxd", "qxt", "qwd", "qwt", "qxl", "qxb"], + "application/vnd.realvnc.bed": ["bed"], + "application/vnd.recordare.musicxml": ["mxl"], + "application/vnd.recordare.musicxml+xml": ["musicxml"], + "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.sailingtracker.track": ["st"], + "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.teacher": ["teacher"], + "application/vnd.solent.sdkm+xml": ["sdkm", "sdkd"], + "application/vnd.spotfire.dxp": ["dxp"], + "application/vnd.spotfire.sfs": ["sfs"], + "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.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.sus-calendar": ["sus", "susp"], + "application/vnd.svd": ["svd"], + "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.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.ufdl": ["ufd", "ufdl"], + "application/vnd.uiq.theme": ["utz"], + "application/vnd.umajin": ["umj"], + "application/vnd.unity": ["unityweb"], + "application/vnd.uoml+xml": ["uoml"], + "application/vnd.vcx": ["vcx"], + "application/vnd.visio": ["vsd", "vst", "vss", "vsw"], + "application/vnd.visionary": ["vis"], + "application/vnd.vsf": ["vsf"], + "application/vnd.wap.wbxml": ["wbxml"], + "application/vnd.wap.wmlc": ["wmlc"], + "application/vnd.wap.wmlscriptc": ["wmlsc"], + "application/vnd.webturbo": ["wtb"], + "application/vnd.wolfram.player": ["nbp"], + "application/vnd.wordperfect": ["wpd"], + "application/vnd.wqd": ["wqd"], + "application/vnd.wt.stf": ["stf"], + "application/vnd.xara": ["xar"], + "application/vnd.xfdl": ["xfdl"], + "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.smaf-audio": ["saf"], + "application/vnd.yamaha.smaf-phrase": ["spf"], + "application/vnd.yellowriver-custom-menu": ["cmp"], + "application/vnd.zul": ["zir", "zirz"], + "application/vnd.zzazz.deck+xml": ["zaz"], + "application/voicexml+xml": ["vxml"], + "application/widget": ["wgt"], + "application/winhlp": ["hlp"], + "application/wsdl+xml": ["wsdl"], + "application/wspolicy+xml": ["wspolicy"], + "application/x-7z-compressed": ["7z"], + "application/x-abiword": ["abw"], + "application/x-ace-compressed": ["ace"], + "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-chrome-extension": ["crx"], + "application/x-conference": ["nsc"], + "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-ghostscript": ["gsf"], + "application/x-font-linux-psf": ["psf"], + "application/x-font-otf": ["otf"], + "application/x-font-pcf": ["pcf"], + "application/x-font-snf": ["snf"], + "application/x-font-ttf": ["ttf", "ttc"], + "application/x-font-type1": ["pfa", "pfb", "pfm", "afm"], + "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-hdf": ["hdf"], + "application/x-install-instructions": ["install"], + "application/x-iso9660-image": ["iso"], + "application/x-java-jnlp-file": ["jnlp"], + "application/x-latex": ["latex"], + "application/x-lua-bytecode": ["luac"], + "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-web-app-manifest+json": ["webapp"], + "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/xaml+xml": ["xaml"], + "application/xcap-diff+xml": ["xdf"], + "application/xenc+xml": ["xenc"], + "application/xhtml+xml": ["xhtml", "xht"], + "application/xml": ["xml", "xsl", "xsd"], + "application/xml-dtd": ["dtd"], + "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/adpcm": ["adp"], + "audio/basic": ["au", "snd"], + "audio/midi": ["mid", "midi", "kar", "rmi"], + "audio/mp4": ["mp4a", "m4a"], + "audio/mpeg": ["mpga", "mp2", "mp2a", "mp3", "m2a", "m3a"], + "audio/ogg": ["oga", "ogg", "spx"], + "audio/s3m": ["s3m"], + "audio/silk": ["sil"], + "audio/vnd.dece.audio": ["uva", "uvva"], + "audio/vnd.digital-winds": ["eol"], + "audio/vnd.dra": ["dra"], + "audio/vnd.dts": ["dts"], + "audio/vnd.dts.hd": ["dtshd"], + "audio/vnd.lucent.voice": ["lvp"], + "audio/vnd.ms-playready.media.pya": ["pya"], + "audio/vnd.nuera.ecelp4800": ["ecelp4800"], + "audio/vnd.nuera.ecelp7470": ["ecelp7470"], + "audio/vnd.nuera.ecelp9600": ["ecelp9600"], + "audio/vnd.rip": ["rip"], + "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-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-xyz": ["xyz"], + "font/opentype": ["otf"], + "image/bmp": ["bmp"], + "image/cgm": ["cgm"], + "image/g3fax": ["g3"], + "image/gif": ["gif"], + "image/ief": ["ief"], + "image/jpeg": ["jpeg", "jpg", "jpe"], + "image/ktx": ["ktx"], + "image/png": ["png"], + "image/prs.btif": ["btif"], + "image/sgi": ["sgi"], + "image/svg+xml": ["svg", "svgz"], + "image/tiff": ["tiff", "tif"], + "image/vnd.adobe.photoshop": ["psd"], + "image/vnd.dece.graphic": ["uvi", "uvvi", "uvg", "uvvg"], + "image/vnd.djvu": ["djvu", "djv"], + "image/vnd.dvb.subtitle": ["sub"], + "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.ms-modi": ["mdi"], + "image/vnd.ms-photo": ["wdp"], + "image/vnd.net-fpx": ["npx"], + "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/rfc822": ["eml", "mime"], + "model/iges": ["igs", "iges"], + "model/mesh": ["msh", "mesh", "silo"], + "model/vnd.collada+xml": ["dae"], + "model/vnd.dwf": ["dwf"], + "model/vnd.gdl": ["gdl"], + "model/vnd.gtw": ["gtw"], + "model/vnd.mts": ["mts"], + "model/vnd.vtu": ["vtu"], + "model/vrml": ["wrl", "vrml"], + "model/x3d+binary": ["x3db", "x3dbz"], + "model/x3d+vrml": ["x3dv", "x3dvz"], + "model/x3d+xml": ["x3d", "x3dz"], + "text/cache-manifest": ["appcache", "manifest"], + "text/calendar": ["ics", "ifb"], + "text/coffeescript": ["coffee"], + "text/css": ["css"], + "text/csv": ["csv"], + "text/hjson": ["hjson"], + "text/html": ["html", "htm"], + "text/jade": ["jade"], + "text/jsx": ["jsx"], + "text/less": ["less"], + "text/n3": ["n3"], + "text/plain": ["txt", "text", "conf", "def", "list", "log", "in", "ini"], + "text/prs.lines.tag": ["dsc"], + "text/richtext": ["rtx"], + "text/sgml": ["sgml", "sgm"], + "text/stylus": ["stylus", "styl"], + "text/tab-separated-values": ["tsv"], + "text/troff": ["t", "tr", "roff", "man", "me", "ms"], + "text/turtle": ["ttl"], + "text/uri-list": ["uri", "uris", "urls"], + "text/vcard": ["vcard"], + "text/vnd.curl": ["curl"], + "text/vnd.curl.dcurl": ["dcurl"], + "text/vnd.curl.mcurl": ["mcurl"], + "text/vnd.curl.scurl": ["scurl"], + "text/vnd.dvb.subtitle": ["sub"], + "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.sun.j2me.app-descriptor": ["jad"], + "text/vnd.wap.wml": ["wml"], + "text/vnd.wap.wmlscript": ["wmls"], + "text/vtt": ["vtt"], + "text/x-asm": ["s", "asm"], + "text/x-c": ["c", "cc", "cxx", "cpp", "h", "hh", "dic"], + "text/x-component": ["htc"], + "text/x-fortran": ["f", "for", "f77", "f90"], + "text/x-handlebars-template": ["hbs"], + "text/x-java-source": ["java"], + "text/x-lua": ["lua"], + "text/x-markdown": ["markdown", "md", "mkd"], + "text/x-nfo": ["nfo"], + "text/x-opml": ["opml"], + "text/x-pascal": ["p", "pas"], + "text/x-sass": ["sass"], + "text/x-scss": ["scss"], + "text/x-setext": ["etx"], + "text/x-sfv": ["sfv"], + "text/x-uuencode": ["uu"], + "text/x-vcalendar": ["vcs"], + "text/x-vcard": ["vcf"], + "text/yaml": ["yaml", "yml"], + "video/3gpp": ["3gp"], + "video/3gpp2": ["3g2"], + "video/h261": ["h261"], + "video/h263": ["h263"], + "video/h264": ["h264"], + "video/jpeg": ["jpgv"], + "video/jpm": ["jpm", "jpgm"], + "video/mj2": ["mj2", "mjp2"], + "video/mp2t": ["ts"], + "video/mp4": ["mp4", "mp4v", "mpg4"], + "video/mpeg": ["mpeg", "mpg", "mpe", "m1v", "m2v"], + "video/ogg": ["ogv"], + "video/quicktime": ["qt", "mov"], + "video/vnd.dece.hd": ["uvh", "uvvh"], + "video/vnd.dece.mobile": ["uvm", "uvvm"], + "video/vnd.dece.pd": ["uvp", "uvvp"], + "video/vnd.dece.sd": ["uvs", "uvvs"], + "video/vnd.dece.video": ["uvv", "uvvv"], + "video/vnd.dvb.file": ["dvb"], + "video/vnd.fvt": ["fvt"], + "video/vnd.mpegurl": ["mxu", "m4u"], + "video/vnd.ms-playready.media.pyv": ["pyv"], + "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"] +}; + +var types$2 = Object.freeze({ + default: types$1 +}); + +var require$$0$1 = ( types$2 && types$2['default'] ) || types$2; + +var __moduleExports$44 = createCommonjsModule(function (module) { + var path$$ = path; + var fs$$ = 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(); + + // Define built-in types + mime.define(require$$0$1); + + // 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 lookup(mimeType, fallback) { + // Assume text types are utf8 + return (/^text\//.test(mimeType) ? 'UTF-8' : fallback + ); + } + }; + + module.exports = mime; +}); + +var __moduleExports$45 = createCommonjsModule(function (module) { + /*! + * range-parser + * Copyright(c) 2012-2014 TJ Holowaychuk + * Copyright(c) 2015-2016 Douglas Christopher Wilson + * MIT Licensed + */ + + 'use strict'; + + /** + * Module exports. + * @public + */ + + module.exports = rangeParser; + + /** + * Parse "Range" header `str` relative to the given file `size`. + * + * @param {Number} size + * @param {String} str + * @param {Object} [options] + * @return {Array} + * @public + */ + + function rangeParser(size, str, options) { + var index = str.indexOf('='); + + if (index === -1) { + return -2; + } + + // split the range string + var arr = str.slice(index + 1).split(','); + var ranges = []; + + // add ranges type + ranges.type = str.slice(0, index); + + // parse all ranges + for (var i = 0; i < arr.length; i++) { + var range = arr[i].split('-'); + var start = parseInt(range[0], 10); + var 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 or unsatisifiable + if (isNaN(start) || isNaN(end) || start > end || start < 0) { + continue; + } + + // add range + ranges.push({ + start: start, + end: end + }); + } + + if (ranges.length < 1) { + // unsatisifiable + return -1; + } + + return options && options.combine ? combineRanges(ranges) : ranges; + } + + /** + * Combine overlapping & adjacent ranges. + * @private + */ + + function combineRanges(ranges) { + var ordered = ranges.map(mapWithIndex).sort(sortByRangeStart); + + for (var j = 0, i = 1; i < ordered.length; i++) { + var range = ordered[i]; + var current = ordered[j]; + + if (range.start > current.end + 1) { + // next range + ordered[++j] = range; + } else if (range.end > current.end) { + // extend range + current.end = range.end; + current.index = Math.min(current.index, range.index); + } + } + + // trim ordered array + ordered.length = j + 1; + + // generate combined range + var combined = ordered.sort(sortByRangeIndex).map(mapWithoutIndex); + + // copy ranges type + combined.type = ranges.type; + + return combined; + } + + /** + * Map function to add index value to ranges. + * @private + */ + + function mapWithIndex(range, index) { + return { + start: range.start, + end: range.end, + index: index + }; + } + + /** + * Map function to remove index value from ranges. + * @private + */ + + function mapWithoutIndex(range) { + return { + start: range.start, + end: range.end + }; + } + + /** + * Sort function to sort ranges by index. + * @private + */ + + function sortByRangeIndex(a, b) { + return a.index - b.index; + } + + /** + * Sort function to sort ranges by start position. + * @private + */ + + function sortByRangeStart(a, b) { + return a.start - b.start; + } +}); + +var __moduleExports$36 = createCommonjsModule(function (module) { + /*! + * send + * Copyright(c) 2012 TJ Holowaychuk + * Copyright(c) 2014-2016 Douglas Christopher Wilson + * MIT Licensed + */ + + 'use strict'; + + /** + * Module dependencies. + * @private + */ + + var createError = __moduleExports$37; + var debug = __moduleExports$5('send'); + var deprecate = __moduleExports$20('send'); + var destroy = __moduleExports$40; + var encodeUrl = __moduleExports$41; + var escapeHtml = __moduleExports$8; + var etag = __moduleExports$42; + var EventEmitter = events.EventEmitter; + var fresh = __moduleExports$43; + var fs$$ = fs; + var mime = __moduleExports$44; + var ms = __moduleExports$7; + var onFinished = __moduleExports$9; + var parseRange = __moduleExports$45; + var path$$ = path; + var statuses = __moduleExports$11; + var Stream = stream; + var util$$ = util; + + /** + * Path function references. + * @private + */ + + var extname = path$$.extname; + var join = path$$.join; + var normalize = path$$.normalize; + var resolve = path$$.resolve; + var sep = path$$.sep; + + /** + * Regular expression for identifying a bytes Range header. + * @private + */ + + var BYTES_RANGE_REGEXP = /^ *bytes=/; + + /** + * Maximum value allowed for the max age. + * @private + */ + + var MAX_MAXAGE = 60 * 60 * 24 * 365 * 1000; // 1 year + + /** + * Regular expression to match a path with a directory up component. + * @private + */ + + var UP_PATH_REGEXP = /(?:^|[\\\/])\.\.(?:[\\\/]|$)/; + + /** + * Module exports. + * @public + */ + + module.exports = send; + 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 {object} req + * @param {string} path + * @param {object} [options] + * @return {SendStream} + * @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] + * @private + */ + + function SendStream(req, path$$, options) { + Stream.call(this); + + var opts = options || {}; + + this.options = opts; + this.path = path$$; + this.req = req; + + this._acceptRanges = opts.acceptRanges !== undefined ? Boolean(opts.acceptRanges) : true; + + this._cacheControl = opts.cacheControl !== undefined ? Boolean(opts.cacheControl) : true; + + this._etag = opts.etag !== undefined ? Boolean(opts.etag) : true; + + this._dotfiles = opts.dotfiles !== undefined ? opts.dotfiles : 'ignore'; + + if (this._dotfiles !== 'ignore' && this._dotfiles !== 'allow' && this._dotfiles !== 'deny') { + throw new TypeError('dotfiles option must be "allow", "deny", or "ignore"'); + } + + this._hidden = Boolean(opts.hidden); + + if (opts.hidden !== undefined) { + deprecate('hidden: use dotfiles: \'' + (this._hidden ? 'allow' : 'ignore') + '\' instead'); + } + + // legacy support + if (opts.dotfiles === undefined) { + this._dotfiles = undefined; + } + + this._extensions = opts.extensions !== undefined ? normalizeList(opts.extensions, 'extensions option') : []; + + this._index = opts.index !== undefined ? normalizeList(opts.index, 'index option') : ['index.html']; + + this._lastModified = opts.lastModified !== undefined ? Boolean(opts.lastModified) : true; + + this._maxage = opts.maxAge || opts.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), MAX_MAXAGE) : 0; + + this._root = opts.root ? resolve(opts.root) : null; + + if (!this._root && opts.from) { + this.from(opts.from); + } + } + + /** + * Inherits from `Stream`. + */ + + util$$.inherits(SendStream, Stream); + + /** + * Enable or disable etag generation. + * + * @param {Boolean} val + * @return {SendStream} + * @api public + */ + + SendStream.prototype.etag = deprecate.function(function etag(val) { + this._etag = Boolean(val); + debug('etag %s', this._etag); + 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) { + this._hidden = Boolean(val); + this._dotfiles = undefined; + debug('hidden %s', this._hidden); + 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, 'paths argument'); + 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 root(path$$) { + this._root = resolve(String(path$$)); + debug('root %s', this._root); + 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) { + this._maxage = typeof maxAge === 'string' ? ms(maxAge) : Number(maxAge); + this._maxage = !isNaN(this._maxage) ? Math.min(Math.max(0, this._maxage), MAX_MAXAGE) : 0; + debug('max-age %d', this._maxage); + return this; + }, 'send.maxage: pass maxAge as option'); + + /** + * Emit error with `status`. + * + * @param {number} status + * @param {Error} [error] + * @private + */ + + SendStream.prototype.error = function error(status, error) { + // emit if listeners instead of responding + if (listenerCount(this, 'error') !== 0) { + return this.emit('error', createError(error, status, { + expose: false + })); + } + + var res = this.res; + var msg = statuses[status]; + + // clear existing headers + clearHeaders(res); + + // add error headers + if (error && error.headers) { + setHeaders(res, error.headers); + } + + // send basic response + res.statusCode = status; + res.setHeader('Content-Type', 'text/plain; charset=UTF-8'); + res.setHeader('Content-Length', Buffer.byteLength(msg)); + res.setHeader('X-Content-Type-Options', 'nosniff'); + res.end(msg); + }; + + /** + * Check if the pathname ends with "/". + * + * @return {Boolean} + * @api private + */ + + SendStream.prototype.hasTrailingSlash = function hasTrailingSlash() { + return this.path[this.path.length - 1] === '/'; + }; + + /** + * Check if this is a conditional GET request. + * + * @return {Boolean} + * @api private + */ + + SendStream.prototype.isConditionalGET = function isConditionalGET() { + return this.req.headers['if-none-match'] || this.req.headers['if-modified-since']; + }; + + /** + * Strip content-* header fields. + * + * @private + */ + + SendStream.prototype.removeContentHeaderFields = function removeContentHeaderFields() { + var res = this.res; + var headers = Object.keys(res._headers || {}); + + for (var i = 0; i < headers.length; i++) { + var header = headers[i]; + if (header.substr(0, 8) === 'content-' && header !== 'content-location') { + res.removeHeader(header); + } + } + }; + + /** + * Respond with 304 not modified. + * + * @api private + */ + + SendStream.prototype.notModified = function notModified() { + 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 isCachable() { + var statusCode = this.res.statusCode; + return statusCode >= 200 && statusCode < 300 || statusCode === 304; + }; + + /** + * Handle stat() error. + * + * @param {Error} error + * @private + */ + + SendStream.prototype.onStatError = function onStatError(error) { + switch (error.code) { + case 'ENAMETOOLONG': + case 'ENOENT': + case 'ENOTDIR': + this.error(404, error); + break; + default: + this.error(500, error); + break; + } + }; + + /** + * Check if the cache is fresh. + * + * @return {Boolean} + * @api private + */ + + SendStream.prototype.isFresh = function isFresh() { + 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 + * @private + */ + + SendStream.prototype.redirect = function redirect(path$$) { + if (listenerCount(this, 'directory') !== 0) { + this.emit('directory'); + return; + } + + if (this.hasTrailingSlash()) { + this.error(403); + return; + } + + var loc = encodeUrl(collapseLeadingSlashes(path$$ + '/')); + var msg = 'Redirecting to ' + escapeHtml(loc) + '\n'; + var res = this.res; + + // redirect + res.statusCode = 301; + res.setHeader('Content-Type', 'text/html; charset=UTF-8'); + res.setHeader('Content-Length', Buffer.byteLength(msg)); + res.setHeader('X-Content-Type-Options', 'nosniff'); + res.setHeader('Location', loc); + res.end(msg); + }; + + /** + * Pipe to `res. + * + * @param {Stream} res + * @return {Stream} res + * @api public + */ + + SendStream.prototype.pipe = function pipe(res) { + // root path + var root = this._root; + + // references + this.res = res; + + // decode the path + var path$$ = decode(this.path); + if (path$$ === -1) { + this.error(400); + return res; + } + + // null byte(s) + if (~path$$.indexOf('\0')) { + this.error(400); + return res; + } + + var parts; + if (root !== null) { + // malicious path + if (UP_PATH_REGEXP.test(normalize('.' + sep + path$$))) { + debug('malicious path "%s"', path$$); + this.error(403); + return res; + } + + // join / normalize from optional root dir + path$$ = normalize(join(root, path$$)); + root = normalize(root + sep); + + // explode path parts + parts = path$$.substr(root.length).split(sep); + } else { + // ".." is malicious without "root" + if (UP_PATH_REGEXP.test(path$$)) { + debug('malicious path "%s"', path$$); + this.error(403); + return res; + } + + // 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': + this.error(403); + return res; + case 'ignore': + default: + this.error(404); + return res; + } + } + + // 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 send(path$$, stat) { + var len = stat.size; + var options = this.options; + var opts = {}; + 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 + this.headersAlreadySent(); + return; + } + + 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()) { + this.notModified(); + return; + } + + // 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 (this._acceptRanges && BYTES_RANGE_REGEXP.test(ranges)) { + // parse + ranges = parseRange(len, ranges, { + combine: true + }); + + // If-Range support + if (!this.isRangeFresh()) { + debug('range stale'); + ranges = -2; + } + + // unsatisfiable + if (ranges === -1) { + debug('range unsatisfiable'); + + // Content-Range + res.setHeader('Content-Range', contentRange('bytes', len)); + + // 416 Requested Range Not Satisfiable + return this.error(416, { + headers: { 'Content-Range': res.getHeader('Content-Range') } + }); + } + + // valid (syntactically invalid/multiple ranges are treated as a regular response) + if (ranges !== -2 && ranges.length === 1) { + debug('range %j', ranges); + + // Content-Range + res.statusCode = 206; + res.setHeader('Content-Range', contentRange('bytes', len, ranges[0])); + + // adjust for requested range + offset += ranges[0].start; + len = ranges[0].end - ranges[0].start + 1; + } + } + + // clone options + for (var prop in options) { + opts[prop] = options[prop]; + } + + // set read options + opts.start = offset; + opts.end = Math.max(offset, offset + len - 1); + + // content-length + res.setHeader('Content-Length', len); + + // HEAD support + if (req.method === 'HEAD') { + res.end(); + return; + } + + this.stream(path$$, opts); + }; + + /** + * 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 stream(path$$, options) { + // TODO: this is all lame, refactor meeee + var finished = false; + var self = this; + var res = this.res; + + // 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 type(path$$) { + var res = this.res; + + if (res.getHeader('Content-Type')) return; + + var type = mime.lookup(path$$); + + if (!type) { + debug('no content-type'); + return; + } + + 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 (this._acceptRanges && !res.getHeader('Accept-Ranges')) { + debug('accept ranges'); + res.setHeader('Accept-Ranges', 'bytes'); + } + + if (this._cacheControl && !res.getHeader('Cache-Control')) { + var cacheControl = 'public, max-age=' + Math.floor(this._maxage / 1000); + debug('cache-control %s', cacheControl); + res.setHeader('Cache-Control', cacheControl); + } + + 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); + } + }; + + /** + * Clear all headers from a response. + * + * @param {object} res + * @private + */ + + function clearHeaders(res) { + res._headers = {}; + res._headerNames = {}; + } + + /** + * Collapse all leading slashes into a single slash + * + * @param {string} str + * @private + */ + function collapseLeadingSlashes(str) { + for (var i = 0; i < str.length; i++) { + if (str[i] !== '/') { + break; + } + } + + return i > 1 ? '/' + str.substr(i) : str; + } + + /** + * 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; + } + + /** + * Create a Content-Range header. + * + * @param {string} type + * @param {number} size + * @param {array} [range] + */ + + function contentRange(type, size, range) { + return type + ' ' + (range ? range.start + '-' + range.end : '*') + '/' + size; + } + + /** + * 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 + * @param {string} name + * @private + */ + + function normalizeList(val, name) { + var list = [].concat(val || []); + + for (var i = 0; i < list.length; i++) { + if (typeof list[i] !== 'string') { + throw new TypeError(name + ' must be array of strings or false'); + } + } + + return list; + } + + /** + * Set an object of headers on a response. + * + * @param {object} res + * @param {object} headers + * @private + */ + + function setHeaders(res, headers) { + var keys = Object.keys(headers); + + for (var i = 0; i < keys.length; i++) { + var key = keys[i]; + res.setHeader(key, headers[key]); + } + } +}); + +var __moduleExports$47 = createCommonjsModule(function (module) { + /*! + * 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; + } +}); + +var __moduleExports$48 = createCommonjsModule(function (module) { + (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 matchCIDR(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 (rangeSubnets[0] && !(rangeSubnets[0] instanceof 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 should fit in 8 bits"); + } + } + 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) { + var _ref; + if (cidrRange === void 0) { + _ref = other, other = _ref[0], cidrRange = _ref[1]; + } + 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 = { + unspecified: [[new IPv4([0, 0, 0, 0]), 8]], + 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()); + }; + + IPv4.prototype.prefixLengthFromSubnetMask = function () { + var cidr, i, octet, stop, zeros, zerotable, _i; + zerotable = { + 0: 8, + 128: 7, + 192: 6, + 224: 5, + 240: 4, + 248: 3, + 252: 2, + 254: 1, + 255: 0 + }; + cidr = 0; + stop = false; + for (i = _i = 3; _i >= 0; i = _i += -1) { + octet = this.octets[i]; + if (octet in zerotable) { + zeros = zerotable[octet]; + if (stop && zeros !== 0) { + return null; + } + if (zeros !== 8) { + stop = true; + } + cidr += zeros; + } else { + return null; + } + } + return 32 - cidr; + }; + + 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 parseIntAuto(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]); + if (value > 0xffffffff || value < 0) { + throw new Error("ipaddr: address outside defined range"); + } + 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 i, part, _i, _j, _len, _ref; + if (parts.length === 16) { + this.parts = []; + for (i = _i = 0; _i <= 14; i = _i += 2) { + this.parts.push(parts[i] << 8 | parts[i + 1]); + } + } else if (parts.length === 8) { + this.parts = parts; + } else { + throw new Error("ipaddr: ipv6 part count should be 8 or 16"); + } + _ref = this.parts; + for (_j = 0, _len = _ref.length; _j < _len; _j++) { + part = _ref[_j]; + if (!(0 <= part && part <= 0xffff)) { + throw new Error("ipaddr: ipv6 part should fit in 16 bits"); + } + } + } + + 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 pushPart(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) { + var _ref; + if (cidrRange === void 0) { + _ref = other, other = _ref[0], cidrRange = _ref[1]; + } + 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 expandIPv6(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.substr(0, 2) === '::') { + colonCount--; + } + if (string.substr(-2, 2) === '::') { + colonCount--; + } + if (colonCount > parts) { + return null; + } + 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, octet, octets, parts, _i, _len; + 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) { + octets = [parseInt(match[2]), parseInt(match[3]), parseInt(match[4]), parseInt(match[5])]; + for (_i = 0, _len = octets.length; _i < _len; _i++) { + octet = octets[_i]; + if (!(0 <= octet && octet <= 255)) { + return null; + } + } + parts.push(octets[0] << 8 | octets[1]); + parts.push(octets[2] << 8 | octets[3]); + return parts; + } + } + return null; + }; + + ipaddr.IPv4.isIPv4 = ipaddr.IPv6.isIPv6 = function (string) { + return this.parser(string) !== null; + }; + + ipaddr.IPv4.isValid = function (string) { + var e; + try { + new this(this.parser(string)); + return true; + } catch (_error) { + e = _error; + return false; + } + }; + + ipaddr.IPv6.isValid = function (string) { + var e; + if (typeof string === "string" && string.indexOf(":") === -1) { + return false; + } + 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.IPv4.parseCIDR = function (string) { + var maskLength, match; + if (match = string.match(/^(.+)\/(\d+)$/)) { + maskLength = parseInt(match[2]); + if (maskLength >= 0 && maskLength <= 32) { + return [this.parse(match[1]), maskLength]; + } + } + throw new Error("ipaddr: string is not formatted like an IPv4 CIDR range"); + }; + + ipaddr.IPv6.parseCIDR = function (string) { + var maskLength, match; + if (match = string.match(/^(.+)\/(\d+)$/)) { + maskLength = parseInt(match[2]); + if (maskLength >= 0 && maskLength <= 128) { + return [this.parse(match[1]), maskLength]; + } + } + throw new Error("ipaddr: string is not formatted like an IPv6 CIDR range"); + }; + + ipaddr.isValid = function (string) { + return ipaddr.IPv6.isValid(string) || ipaddr.IPv4.isValid(string); + }; + + ipaddr.parse = function (string) { + if (ipaddr.IPv6.isValid(string)) { + return ipaddr.IPv6.parse(string); + } else if (ipaddr.IPv4.isValid(string)) { + return ipaddr.IPv4.parse(string); + } else { + throw new Error("ipaddr: the address has neither IPv6 nor IPv4 format"); + } + }; + + ipaddr.parseCIDR = function (string) { + var e; + try { + return ipaddr.IPv6.parseCIDR(string); + } catch (_error) { + e = _error; + try { + return ipaddr.IPv4.parseCIDR(string); + } catch (_error) { + e = _error; + throw new Error("ipaddr: the address has neither IPv6 nor IPv4 CIDR format"); + } + } + }; + + ipaddr.fromByteArray = function (bytes) { + var length; + length = bytes.length; + if (length === 4) { + return new ipaddr.IPv4(bytes); + } else if (length === 16) { + return new ipaddr.IPv6(bytes); + } else { + throw new Error("ipaddr: the binary input is neither an IPv6 nor IPv4 address"); + } + }; + + ipaddr.process = function (string) { + var addr; + addr = this.parse(string); + if (addr.kind() === 'ipv6' && addr.isIPv4MappedAddress()) { + return addr.toIPv4Address(); + } else { + return addr; + } + }; + }).call(commonjsGlobal); +}); + +var __moduleExports$46 = createCommonjsModule(function (module) { + /*! + * proxy-addr + * Copyright(c) 2014-2016 Douglas Christopher Wilson + * MIT Licensed + */ + + 'use strict'; + + /** + * Module exports. + */ + + module.exports = proxyaddr; + module.exports.all = alladdrs; + module.exports.compile = compile; + + /** + * Module dependencies. + */ + + var forwarded = __moduleExports$47; + var ipaddr = __moduleExports$48; + + /** + * 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 pos = note.lastIndexOf('/'); + var str = pos !== -1 ? note.substring(0, pos) : note; + + if (!isip(str)) { + throw new TypeError('invalid IP address: ' + str); + } + + var ip = parseip(str); + + if (pos === -1 && ip.kind() === 'ipv6' && ip.isIPv4MappedAddress()) { + // Store as IPv4 + ip = ip.toIPv4Address(); + } + + var max = ip.kind() === 'ipv6' ? 128 : 32; + + var range = pos !== -1 ? note.substring(pos + 1, note.length) : null; + + if (range === null) { + range = max; + } else if (digitre.test(range)) { + range = parseInt(range, 10); + } else if (ip.kind() === 'ipv4' && isip(range)) { + range = parseNetmask(range); + } else { + range = null; + } + + if (range <= 0 || range > max) { + throw new TypeError('invalid range on address: ' + note); + } + + return [ip, range]; + } + + /** + * Parse netmask string into CIDR range. + * + * @param {String} netmask + * @api private + */ + + function parseNetmask(netmask) { + var ip = parseip(netmask); + var kind = ip.kind(); + + return kind === 'ipv4' ? ip.prefixLengthFromSubnetMask() : null; + } + + /** + * 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 ipconv; + var kind = ip.kind(); + + for (var i = 0; i < subnets.length; i++) { + var subnet = subnets[i]; + var subnetip = subnet[0]; + var subnetkind = subnetip.kind(); + var subnetrange = subnet[1]; + var trusted = ip; + + if (kind !== subnetkind) { + if (subnetkind === 'ipv4' && !ip.isIPv4MappedAddress()) { + // Incompatible IP addresses + continue; + } + + if (!ipconv) { + // Convert IP to match subnet IP kind + ipconv = subnetkind === 'ipv4' ? ip.toIPv4Address() : ip.toIPv4MappedAddress(); + } + + trusted = ipconv; + } + + 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(); + + if (kind !== subnetkind) { + if (subnetisipv4 && !ip.isIPv4MappedAddress()) { + // Incompatible IP addresses + return false; + } + + // Convert IP to match subnet IP kind + ip = subnetisipv4 ? ip.toIPv4Address() : ip.toIPv4MappedAddress(); + } + + return ip.match(subnetip, subnetrange); + }; + } +}); + +var __moduleExports$33 = createCommonjsModule(function (module, exports) { + /*! + * express + * Copyright(c) 2009-2013 TJ Holowaychuk + * Copyright(c) 2014-2015 Douglas Christopher Wilson + * MIT Licensed + */ + + 'use strict'; + + /** + * Module dependencies. + * @api private + */ + + var contentDisposition = __moduleExports$34; + var contentType = __moduleExports$35; + var deprecate = __moduleExports$20('express'); + var flatten = __moduleExports$15; + var mime = __moduleExports$36.mime; + var basename = path.basename; + var etag = __moduleExports$42; + var proxyaddr = __moduleExports$46; + var qs = __moduleExports$28; + var querystring$$ = querystring; + + /** + * 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] || '/' === path[2])) return true; // Windows device path + if ('\\\\' === path.substring(0, 2)) return true; // Microsoft Azure absolute path + }; + + /** + * Flatten the given `arr`. + * + * @param {Array} arr + * @return {Array} + * @api private + */ + + exports.flatten = deprecate.function(flatten, 'utils.flatten: use array-flatten npm module instead'); + + /** + * 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 = deprecate.function(contentDisposition, 'utils.contentDisposition: use content-disposition npm module instead'); + + /** + * 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 = parseExtendedQueryString; + 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 setCharset(type, charset) { + if (!type || !charset) { + return type; + } + + // parse type + var parsed = contentType.parse(type); + + // set charset + parsed.parameters.charset = charset; + + // format type + return contentType.format(parsed); + }; + + /** + * Parse an extended query string with qs. + * + * @return {Object} + * @private + */ + + function parseExtendedQueryString(str) { + return qs.parse(str, { + allowPrototypes: true + }); + } + + /** + * Return new empty object. + * + * @return {Object} + * @api private + */ + + function newObject() { + return {}; + } +}); + +var __moduleExports$32 = createCommonjsModule(function (module) { + /*! + * express + * Copyright(c) 2009-2013 TJ Holowaychuk + * Copyright(c) 2013 Roman Shtylman + * Copyright(c) 2014-2015 Douglas Christopher Wilson + * MIT Licensed + */ + + 'use strict'; + + /** + * Module dependencies. + * @private + */ + + var debug = __moduleExports$5('express:view'); + var path$$ = path; + var fs$$ = fs; + var utils = __moduleExports$33; + + /** + * Module variables. + * @private + */ + + var dirname = path$$.dirname; + var basename = path$$.basename; + var extname = path$$.extname; + var join = path$$.join; + var resolve = path$$.resolve; + + /** + * Module exports. + * @public + */ + + 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 + * @public + */ + + function View(name, options) { + var opts = options || {}; + + this.defaultEngine = opts.defaultEngine; + this.ext = extname(name); + this.name = name; + this.root = opts.root; + + if (!this.ext && !this.defaultEngine) { + throw new Error('No default engine was specified and no extension was provided.'); + } + + var fileName = name; + + if (!this.ext) { + // get extension from default engine name + this.ext = this.defaultEngine[0] !== '.' ? '.' + this.defaultEngine : this.defaultEngine; + + fileName += this.ext; + } + + if (!opts.engines[this.ext]) { + // load engine + opts.engines[this.ext] = require(this.ext.substr(1)).__express; + } + + // store loaded engine + this.engine = opts.engines[this.ext]; + + // lookup path + this.path = this.lookup(fileName); + } + + /** + * Lookup view by the given `name` + * + * @param {string} name + * @private + */ + + View.prototype.lookup = function lookup(name) { + var path$$; + var roots = [].concat(this.root); + + debug('lookup "%s"', name); + + for (var i = 0; i < roots.length && !path$$; i++) { + var root = roots[i]; + + // resolve the path + var loc = resolve(root, name); + var dir = dirname(loc); + var file = basename(loc); + + // resolve the file + path$$ = this.resolve(dir, file); + } + + return path$$; + }; + + /** + * Render with the given options. + * + * @param {object} options + * @param {function} callback + * @private + */ + + View.prototype.render = function render(options, callback) { + debug('render "%s"', this.path); + this.engine(this.path, options, callback); + }; + + /** + * Resolve the file within the given directory. + * + * @param {string} dir + * @param {string} file + * @private + */ + + View.prototype.resolve = function resolve(dir, file) { + var ext = this.ext; + + // . + var path$$ = join(dir, file); + var stat = tryStat(path$$); + + if (stat && stat.isFile()) { + return path$$; + } + + // /index. + path$$ = join(dir, basename(file, ext), 'index' + ext); + stat = tryStat(path$$); + + if (stat && stat.isFile()) { + return path$$; + } + }; + + /** + * Return a stat, maybe. + * + * @param {string} path + * @return {fs.Stats} + * @private + */ + + function tryStat(path$$) { + debug('stat "%s"', path$$); + + try { + return fs$$.statSync(path$$); + } catch (e) { + return undefined; + } + } +}); + +var __moduleExports$3 = createCommonjsModule(function (module, exports) { + /*! + * express + * Copyright(c) 2009-2013 TJ Holowaychuk + * Copyright(c) 2013 Roman Shtylman + * Copyright(c) 2014-2015 Douglas Christopher Wilson + * MIT Licensed + */ + + 'use strict'; + + /** + * Module dependencies. + * @private + */ + + var finalhandler = __moduleExports$4; + var Router = __moduleExports$13; + var methods = __moduleExports$18; + var middleware = __moduleExports$26; + var query = __moduleExports$27; + var debug = __moduleExports$5('express:application'); + var View = __moduleExports$32; + var http$$ = http; + var compileETag = __moduleExports$33.compileETag; + var compileQueryParser = __moduleExports$33.compileQueryParser; + var compileTrust = __moduleExports$33.compileTrust; + var deprecate = __moduleExports$20('express'); + var flatten = __moduleExports$15; + var merge = __moduleExports$19; + var resolve = path.resolve; + var slice = Array.prototype.slice; + + /** + * Application prototype. + */ + + var app = exports = module.exports = {}; + + /** + * Variable for trust proxy inheritance back-compat + * @private + */ + + var trustProxyDefaultSymbol = '@@symbol:trust_proxy_default'; + + /** + * Initialize the server. + * + * - setup default configuration + * - setup default middleware + * - setup route reflection methods + * + * @private + */ + + app.init = function init() { + this.cache = {}; + this.engines = {}; + this.settings = {}; + + this.defaultConfiguration(); + }; + + /** + * Initialize application configuration. + * @private + */ + + app.defaultConfiguration = function defaultConfiguration() { + var env = process.env.NODE_ENV || 'development'; + + // default settings + this.enable('x-powered-by'); + this.set('etag', 'weak'); + this.set('env', env); + this.set('query parser', 'extended'); + this.set('subdomain offset', 2); + this.set('trust proxy', false); + + // trust proxy inherit back-compat + Object.defineProperty(this.settings, trustProxyDefaultSymbol, { + configurable: true, + value: true + }); + + debug('booting in %s mode', env); + + this.on('mount', function onmount(parent) { + // inherit trust proxy + if (this.settings[trustProxyDefaultSymbol] === true && typeof parent.settings['trust proxy fn'] === 'function') { + delete this.settings['trust proxy']; + delete this.settings['trust proxy fn']; + } + + // inherit protos + 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 get() { + 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. + * + * @private + */ + app.lazyrouter = function lazyrouter() { + 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 callback is provided, then default error handlers will respond + * in the event of an error bubbling through the stack. + * + * @private + */ + + app.handle = function handle(req, res, callback) { + var router = this._router; + + // final handler + var done = callback || 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. + * + * @public + */ + + app.use = function use(fn) { + var offset = 0; + var path = '/'; + + // 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 = this; + + // 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', this); + }, this); + + 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. + * + * @public + */ + + app.route = function route(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/tj/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 + * @public + */ + + app.engine = function engine(ext, fn) { + if (typeof fn !== 'function') { + throw new Error('callback function required'); + } + + // get file extension + var extension = ext[0] !== '.' ? '.' + ext : ext; + + // store engine + this.engines[extension] = 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 + * @public + */ + + app.param = function param(name, fn) { + this.lazyrouter(); + + if (Array.isArray(name)) { + for (var i = 0; i < name.length; i++) { + this.param(name[i], fn); + } + + return this; + } + + this._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 + * @public + */ + + app.set = function set(setting, val) { + if (arguments.length === 1) { + // app.get(setting) + return this.settings[setting]; + } + + debug('set "%s" to %o', setting, val); + + // set value + this.settings[setting] = val; + + // trigger matched settings + switch (setting) { + case 'etag': + this.set('etag fn', compileETag(val)); + break; + case 'query parser': + this.set('query parser fn', compileQueryParser(val)); + break; + case 'trust proxy': + this.set('trust proxy fn', compileTrust(val)); + + // trust proxy inherit back-compat + Object.defineProperty(this.settings, trustProxyDefaultSymbol, { + configurable: true, + value: false + }); + + 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} + * @private + */ + + app.path = function path() { + 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} + * @public + */ + + app.enabled = function enabled(setting) { + return Boolean(this.set(setting)); + }; + + /** + * Check if `setting` is disabled. + * + * app.disabled('foo') + * // => true + * + * app.enable('foo') + * app.disabled('foo') + * // => false + * + * @param {String} setting + * @return {Boolean} + * @public + */ + + app.disabled = function disabled(setting) { + return !this.set(setting); + }; + + /** + * Enable `setting`. + * + * @param {String} setting + * @return {app} for chaining + * @public + */ + + app.enable = function enable(setting) { + return this.set(setting, true); + }; + + /** + * Disable `setting`. + * + * @param {String} setting + * @return {app} for chaining + * @public + */ + + app.disable = function disable(setting) { + return this.set(setting, false); + }; + + /** + * Delegate `.VERB(...)` calls to `router.VERB(...)`. + */ + + methods.forEach(function (method) { + app[method] = function (path) { + if (method === 'get' && arguments.length === 1) { + // app.get(setting) + 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 + * @public + */ + + app.all = function all(path) { + this.lazyrouter(); + + var route = this._router.route(path); + var args = slice.call(arguments, 1); + + for (var i = 0; i < methods.length; i++) { + route[methods[i]].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 {Object|Function} options or fn + * @param {Function} callback + * @public + */ + + app.render = function render(name, options, callback) { + var cache = this.cache; + var done = callback; + var engines = this.engines; + var opts = options; + var renderOptions = {}; + var view; + + // support callback function as second arg + if (typeof options === 'function') { + done = options; + opts = {}; + } + + // merge app.locals + merge(renderOptions, this.locals); + + // merge options._locals + if (opts._locals) { + merge(renderOptions, opts._locals); + } + + // merge options + merge(renderOptions, opts); + + // set .cache unless explicitly provided + if (renderOptions.cache == null) { + renderOptions.cache = this.enabled('view cache'); + } + + // primed cache + if (renderOptions.cache) { + view = cache[name]; + } + + // view + if (!view) { + var View = this.get('view'); + + view = new View(name, { + defaultEngine: this.get('view engine'), + root: this.get('views'), + engines: engines + }); + + if (!view.path) { + var dirs = Array.isArray(view.root) && view.root.length > 1 ? 'directories "' + view.root.slice(0, -1).join('", "') + '" or "' + view.root[view.root.length - 1] + '"' : 'directory "' + view.root + '"'; + var err = new Error('Failed to lookup view "' + name + '" in views ' + dirs); + err.view = view; + return done(err); + } + + // prime the cache + if (renderOptions.cache) { + cache[name] = view; + } + } + + // render + tryRender(view, renderOptions, done); + }; + + /** + * 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} + * @public + */ + + app.listen = function listen() { + var server = http$$.createServer(this); + return server.listen.apply(server, arguments); + }; + + /** + * Log error using console.error. + * + * @param {Error} err + * @private + */ + + function logerror(err) { + /* istanbul ignore next */ + if (this.get('env') !== 'test') console.error(err.stack || err.toString()); + } + + /** + * Try rendering a view. + * @private + */ + + function tryRender(view, options, callback) { + try { + view.render(options, callback); + } catch (err) { + callback(err); + } + } +}); + +var __moduleExports$52 = createCommonjsModule(function (module) { + /** + * negotiator + * Copyright(c) 2012 Isaac Z. Schlueter + * Copyright(c) 2014 Federico Romero + * Copyright(c) 2014-2015 Douglas Christopher Wilson + * MIT Licensed + */ + + 'use strict'; + + /** + * Module exports. + * @public + */ + + module.exports = preferredCharsets; + module.exports.preferredCharsets = preferredCharsets; + + /** + * Module variables. + * @private + */ + + var simpleCharsetRegExp = /^\s*([^\s;]+)\s*(?:;(.*))?$/; + + /** + * Parse the Accept-Charset header. + * @private + */ + + function parseAcceptCharset(accept) { + var accepts = accept.split(','); + + for (var i = 0, j = 0; i < accepts.length; i++) { + var charset = parseCharset(accepts[i].trim(), i); + + if (charset) { + accepts[j++] = charset; + } + } + + // trim accepts + accepts.length = j; + + return accepts; + } + + /** + * Parse a charset from the Accept-Charset header. + * @private + */ + + function parseCharset(str, i) { + var match = simpleCharsetRegExp.exec(str); + 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 + }; + } + + /** + * Get the priority of a charset. + * @private + */ + + function getCharsetPriority(charset, accepted, index) { + var priority = { o: -1, q: 0, s: 0 }; + + for (var i = 0; i < accepted.length; i++) { + var spec = specify(charset, accepted[i], index); + + if (spec && (priority.s - spec.s || priority.q - spec.q || priority.o - spec.o) < 0) { + priority = spec; + } + } + + return priority; + } + + /** + * Get the specificity of the charset. + * @private + */ + + function specify(charset, spec, index) { + var s = 0; + if (spec.charset.toLowerCase() === charset.toLowerCase()) { + s |= 1; + } else if (spec.charset !== '*') { + return null; + } + + return { + i: index, + o: spec.i, + q: spec.q, + s: s + }; + } + + /** + * Get the preferred charsets from an Accept-Charset header. + * @public + */ + + function preferredCharsets(accept, provided) { + // RFC 2616 sec 14.2: no header = * + var accepts = parseAcceptCharset(accept === undefined ? '*' : accept || ''); + + if (!provided) { + // sorted list of all charsets + return accepts.filter(isQuality).sort(compareSpecs).map(getFullCharset); + } + + var priorities = provided.map(function getPriority(type, index) { + return getCharsetPriority(type, accepts, index); + }); + + // sorted list of accepted charsets + return priorities.filter(isQuality).sort(compareSpecs).map(function getCharset(priority) { + return provided[priorities.indexOf(priority)]; + }); + } + + /** + * Compare two specs. + * @private + */ + + function compareSpecs(a, b) { + return b.q - a.q || b.s - a.s || a.o - b.o || a.i - b.i || 0; + } + + /** + * Get full charset string. + * @private + */ + + function getFullCharset(spec) { + return spec.charset; + } + + /** + * Check if a spec has any quality. + * @private + */ + + function isQuality(spec) { + return spec.q > 0; + } +}); + +var __moduleExports$53 = createCommonjsModule(function (module) { + /** + * negotiator + * Copyright(c) 2012 Isaac Z. Schlueter + * Copyright(c) 2014 Federico Romero + * Copyright(c) 2014-2015 Douglas Christopher Wilson + * MIT Licensed + */ + + 'use strict'; + + /** + * Module exports. + * @public + */ + + module.exports = preferredEncodings; + module.exports.preferredEncodings = preferredEncodings; + + /** + * Module variables. + * @private + */ + + var simpleEncodingRegExp = /^\s*([^\s;]+)\s*(?:;(.*))?$/; + + /** + * Parse the Accept-Encoding header. + * @private + */ + + function parseAcceptEncoding(accept) { + var accepts = accept.split(','); + var hasIdentity = false; + var minQuality = 1; + + for (var i = 0, j = 0; i < accepts.length; i++) { + var encoding = parseEncoding(accepts[i].trim(), i); + + if (encoding) { + accepts[j++] = encoding; + hasIdentity = hasIdentity || specify('identity', encoding); + minQuality = Math.min(minQuality, encoding.q || 1); + } + } + + if (!hasIdentity) { + /* + * If identity doesn't explicitly appear in the accept-encoding header, + * it's added to the list of acceptable encoding with the lowest q + */ + accepts[j++] = { + encoding: 'identity', + q: minQuality, + i: i + }; + } + + // trim accepts + accepts.length = j; + + return accepts; + } + + /** + * Parse an encoding from the Accept-Encoding header. + * @private + */ + + function parseEncoding(str, i) { + var match = simpleEncodingRegExp.exec(str); + 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 + }; + } + + /** + * Get the priority of an encoding. + * @private + */ + + function getEncodingPriority(encoding, accepted, index) { + var priority = { o: -1, q: 0, s: 0 }; + + for (var i = 0; i < accepted.length; i++) { + var spec = specify(encoding, accepted[i], index); + + if (spec && (priority.s - spec.s || priority.q - spec.q || priority.o - spec.o) < 0) { + priority = spec; + } + } + + return priority; + } + + /** + * Get the specificity of the encoding. + * @private + */ + + function specify(encoding, spec, index) { + var s = 0; + if (spec.encoding.toLowerCase() === encoding.toLowerCase()) { + s |= 1; + } else if (spec.encoding !== '*') { + return null; + } + + return { + i: index, + o: spec.i, + q: spec.q, + s: s + }; + }; + + /** + * Get the preferred encodings from an Accept-Encoding header. + * @public + */ + + function preferredEncodings(accept, provided) { + var accepts = parseAcceptEncoding(accept || ''); + + if (!provided) { + // sorted list of all encodings + return accepts.filter(isQuality).sort(compareSpecs).map(getFullEncoding); + } + + var priorities = provided.map(function getPriority(type, index) { + return getEncodingPriority(type, accepts, index); + }); + + // sorted list of accepted encodings + return priorities.filter(isQuality).sort(compareSpecs).map(function getEncoding(priority) { + return provided[priorities.indexOf(priority)]; + }); + } + + /** + * Compare two specs. + * @private + */ + + function compareSpecs(a, b) { + return b.q - a.q || b.s - a.s || a.o - b.o || a.i - b.i || 0; + } + + /** + * Get full encoding string. + * @private + */ + + function getFullEncoding(spec) { + return spec.encoding; + } + + /** + * Check if a spec has any quality. + * @private + */ + + function isQuality(spec) { + return spec.q > 0; + } +}); + +var __moduleExports$54 = createCommonjsModule(function (module) { + /** + * negotiator + * Copyright(c) 2012 Isaac Z. Schlueter + * Copyright(c) 2014 Federico Romero + * Copyright(c) 2014-2015 Douglas Christopher Wilson + * MIT Licensed + */ + + 'use strict'; + + /** + * Module exports. + * @public + */ + + module.exports = preferredLanguages; + module.exports.preferredLanguages = preferredLanguages; + + /** + * Module variables. + * @private + */ + + var simpleLanguageRegExp = /^\s*([^\s\-;]+)(?:-([^\s;]+))?\s*(?:;(.*))?$/; + + /** + * Parse the Accept-Language header. + * @private + */ + + function parseAcceptLanguage(accept) { + var accepts = accept.split(','); + + for (var i = 0, j = 0; i < accepts.length; i++) { + var langauge = parseLanguage(accepts[i].trim(), i); + + if (langauge) { + accepts[j++] = langauge; + } + } + + // trim accepts + accepts.length = j; + + return accepts; + } + + /** + * Parse a language from the Accept-Language header. + * @private + */ + + function parseLanguage(str, i) { + var match = simpleLanguageRegExp.exec(str); + 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 + }; + } + + /** + * Get the priority of a language. + * @private + */ + + function getLanguagePriority(language, accepted, index) { + var priority = { o: -1, q: 0, s: 0 }; + + for (var i = 0; i < accepted.length; i++) { + var spec = specify(language, accepted[i], index); + + if (spec && (priority.s - spec.s || priority.q - spec.q || priority.o - spec.o) < 0) { + priority = spec; + } + } + + return priority; + } + + /** + * Get the specificity of the language. + * @private + */ + + function specify(language, spec, index) { + 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 { + i: index, + o: spec.i, + q: spec.q, + s: s + }; + }; + + /** + * Get the preferred languages from an Accept-Language header. + * @public + */ + + function preferredLanguages(accept, provided) { + // RFC 2616 sec 14.4: no header = * + var accepts = parseAcceptLanguage(accept === undefined ? '*' : accept || ''); + + if (!provided) { + // sorted list of all languages + return accepts.filter(isQuality).sort(compareSpecs).map(getFullLanguage); + } + + var priorities = provided.map(function getPriority(type, index) { + return getLanguagePriority(type, accepts, index); + }); + + // sorted list of accepted languages + return priorities.filter(isQuality).sort(compareSpecs).map(function getLanguage(priority) { + return provided[priorities.indexOf(priority)]; + }); + } + + /** + * Compare two specs. + * @private + */ + + function compareSpecs(a, b) { + return b.q - a.q || b.s - a.s || a.o - b.o || a.i - b.i || 0; + } + + /** + * Get full language string. + * @private + */ + + function getFullLanguage(spec) { + return spec.full; + } + + /** + * Check if a spec has any quality. + * @private + */ + + function isQuality(spec) { + return spec.q > 0; + } +}); + +var __moduleExports$55 = createCommonjsModule(function (module) { + /** + * negotiator + * Copyright(c) 2012 Isaac Z. Schlueter + * Copyright(c) 2014 Federico Romero + * Copyright(c) 2014-2015 Douglas Christopher Wilson + * MIT Licensed + */ + + 'use strict'; + + /** + * Module exports. + * @public + */ + + module.exports = preferredMediaTypes; + module.exports.preferredMediaTypes = preferredMediaTypes; + + /** + * Module variables. + * @private + */ + + var simpleMediaTypeRegExp = /^\s*([^\s\/;]+)\/([^;\s]+)\s*(?:;(.*))?$/; + + /** + * Parse the Accept header. + * @private + */ + + function parseAccept(accept) { + var accepts = splitMediaTypes(accept); + + for (var i = 0, j = 0; i < accepts.length; i++) { + var mediaType = parseMediaType(accepts[i].trim(), i); + + if (mediaType) { + accepts[j++] = mediaType; + } + } + + // trim accepts + accepts.length = j; + + return accepts; + } + + /** + * Parse a media type from the Accept header. + * @private + */ + + function parseMediaType(str, i) { + var match = simpleMediaTypeRegExp.exec(str); + if (!match) return null; + + var params = Object.create(null); + var q = 1; + var subtype = match[2]; + var type = match[1]; + + if (match[3]) { + var kvps = splitParameters(match[3]).map(splitKeyValuePair); + + for (var j = 0; j < kvps.length; j++) { + var pair = kvps[j]; + var key = pair[0].toLowerCase(); + var val = pair[1]; + + // get the value, unwrapping quotes + var value = val && val[0] === '"' && val[val.length - 1] === '"' ? val.substr(1, val.length - 2) : val; + + if (key === 'q') { + q = parseFloat(value); + break; + } + + // store parameter + params[key] = value; + } + } + + return { + type: type, + subtype: subtype, + params: params, + q: q, + i: i + }; + } + + /** + * Get the priority of a media type. + * @private + */ + + function getMediaTypePriority(type, accepted, index) { + var priority = { o: -1, q: 0, s: 0 }; + + for (var i = 0; i < accepted.length; i++) { + var spec = specify(type, accepted[i], index); + + if (spec && (priority.s - spec.s || priority.q - spec.q || priority.o - spec.o) < 0) { + priority = spec; + } + } + + return priority; + } + + /** + * Get the specificity of the media type. + * @private + */ + + function specify(type, spec, index) { + 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 { + i: index, + o: spec.i, + q: spec.q, + s: s + }; + } + + /** + * Get the preferred media types from an Accept header. + * @public + */ + + function preferredMediaTypes(accept, provided) { + // RFC 2616 sec 14.2: no header = */* + var accepts = parseAccept(accept === undefined ? '*/*' : accept || ''); + + if (!provided) { + // sorted list of all types + return accepts.filter(isQuality).sort(compareSpecs).map(getFullType); + } + + var priorities = provided.map(function getPriority(type, index) { + return getMediaTypePriority(type, accepts, index); + }); + + // sorted list of accepted types + return priorities.filter(isQuality).sort(compareSpecs).map(function getType(priority) { + return provided[priorities.indexOf(priority)]; + }); + } + + /** + * Compare two specs. + * @private + */ + + function compareSpecs(a, b) { + return b.q - a.q || b.s - a.s || a.o - b.o || a.i - b.i || 0; + } + + /** + * Get full type string. + * @private + */ + + function getFullType(spec) { + return spec.type + '/' + spec.subtype; + } + + /** + * Check if a spec has any quality. + * @private + */ + + function isQuality(spec) { + return spec.q > 0; + } + + /** + * Count the number of quotes in a string. + * @private + */ + + function quoteCount(string) { + var count = 0; + var index = 0; + + while ((index = string.indexOf('"', index)) !== -1) { + count++; + index++; + } + + return count; + } + + /** + * Split a key value pair. + * @private + */ + + function splitKeyValuePair(str) { + var index = str.indexOf('='); + var key; + var val; + + if (index === -1) { + key = str; + } else { + key = str.substr(0, index); + val = str.substr(index + 1); + } + + return [key, val]; + } + + /** + * Split an Accept header into media types. + * @private + */ + + function splitMediaTypes(accept) { + var accepts = accept.split(','); + + for (var i = 1, j = 0; i < accepts.length; i++) { + if (quoteCount(accepts[j]) % 2 == 0) { + accepts[++j] = accepts[i]; + } else { + accepts[j] += ',' + accepts[i]; + } + } + + // trim accepts + accepts.length = j + 1; + + return accepts; + } + + /** + * Split a string of parameters. + * @private + */ + + function splitParameters(str) { + var parameters = str.split(';'); + + for (var i = 1, j = 0; i < parameters.length; i++) { + if (quoteCount(parameters[j]) % 2 == 0) { + parameters[++j] = parameters[i]; + } else { + parameters[j] += ';' + parameters[i]; + } + } + + // trim parameters + parameters.length = j + 1; + + for (var i = 0; i < parameters.length; i++) { + parameters[i] = parameters[i].trim(); + } + + return parameters; + } +}); + +var __moduleExports$51 = createCommonjsModule(function (module) { + /*! + * negotiator + * Copyright(c) 2012 Federico Romero + * Copyright(c) 2012-2014 Isaac Z. Schlueter + * Copyright(c) 2015 Douglas Christopher Wilson + * MIT Licensed + */ + + 'use strict'; + + /** + * Cached loaded submodules. + * @private + */ + + var modules = Object.create(null); + + /** + * Module exports. + * @public + */ + + module.exports = Negotiator; + module.exports.Negotiator = Negotiator; + + /** + * Create a Negotiator instance from a request. + * @param {object} request + * @public + */ + + function Negotiator(request) { + if (!(this instanceof Negotiator)) { + return new Negotiator(request); + } + + this.request = request; + } + + Negotiator.prototype.charset = function charset(available) { + var set = this.charsets(available); + return set && set[0]; + }; + + Negotiator.prototype.charsets = function charsets(available) { + var preferredCharsets = loadModule('charset').preferredCharsets; + return preferredCharsets(this.request.headers['accept-charset'], available); + }; + + Negotiator.prototype.encoding = function encoding(available) { + var set = this.encodings(available); + return set && set[0]; + }; + + Negotiator.prototype.encodings = function encodings(available) { + var preferredEncodings = loadModule('encoding').preferredEncodings; + return preferredEncodings(this.request.headers['accept-encoding'], available); + }; + + Negotiator.prototype.language = function language(available) { + var set = this.languages(available); + return set && set[0]; + }; + + Negotiator.prototype.languages = function languages(available) { + var preferredLanguages = loadModule('language').preferredLanguages; + return preferredLanguages(this.request.headers['accept-language'], available); + }; + + Negotiator.prototype.mediaType = function mediaType(available) { + var set = this.mediaTypes(available); + return set && set[0]; + }; + + Negotiator.prototype.mediaTypes = function mediaTypes(available) { + var preferredMediaTypes = loadModule('mediaType').preferredMediaTypes; + return preferredMediaTypes(this.request.headers.accept, available); + }; + + // Backwards compatibility + Negotiator.prototype.preferredCharset = Negotiator.prototype.charset; + Negotiator.prototype.preferredCharsets = Negotiator.prototype.charsets; + Negotiator.prototype.preferredEncoding = Negotiator.prototype.encoding; + Negotiator.prototype.preferredEncodings = Negotiator.prototype.encodings; + Negotiator.prototype.preferredLanguage = Negotiator.prototype.language; + Negotiator.prototype.preferredLanguages = Negotiator.prototype.languages; + Negotiator.prototype.preferredMediaType = Negotiator.prototype.mediaType; + Negotiator.prototype.preferredMediaTypes = Negotiator.prototype.mediaTypes; + + /** + * Load the given module. + * @private + */ + + function loadModule(moduleName) { + var module = modules[moduleName]; + + if (module !== undefined) { + return module; + } + + // This uses a switch for static require analysis + switch (moduleName) { + case 'charset': + module = __moduleExports$52; + break; + case 'encoding': + module = __moduleExports$53; + break; + case 'language': + module = __moduleExports$54; + break; + case 'mediaType': + module = __moduleExports$55; + break; + default: + throw new Error('Cannot find module \'' + moduleName + '\''); + } + + // Store to prevent invoking require() + modules[moduleName] = module; + + return module; + } +}); + +var db = {"application/1d-interleaved-parityfec":{"source":"iana"},"application/3gpdash-qoe-report+xml":{"source":"iana"},"application/3gpp-ims+xml":{"source":"iana"},"application/a2l":{"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/aml":{"source":"iana"},"application/andrew-inset":{"source":"iana","extensions":["ez"]},"application/applefile":{"source":"iana"},"application/applixware":{"source":"apache","extensions":["aw"]},"application/atf":{"source":"iana"},"application/atfx":{"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/atxml":{"source":"iana"},"application/auth-policy+xml":{"source":"iana"},"application/bacnet-xdd+zip":{"source":"iana"},"application/batch-smtp":{"source":"iana"},"application/bdoc":{"compressible":false,"extensions":["bdoc"]},"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/cdfx+xml":{"source":"iana"},"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/cdni":{"source":"iana"},"application/cea":{"source":"iana"},"application/cea-2018+xml":{"source":"iana"},"application/cellml+xml":{"source":"iana"},"application/cfw":{"source":"iana"},"application/clue_info+xml":{"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/csvm+json":{"source":"iana","compressible":true},"application/cu-seeme":{"source":"apache","extensions":["cu"]},"application/cybercash":{"source":"iana"},"application/dart":{"compressible":true},"application/dash+xml":{"source":"iana","extensions":["mpd"]},"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/dii":{"source":"iana"},"application/dit":{"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/efi":{"source":"iana"},"application/emergencycalldata.comment+xml":{"source":"iana"},"application/emergencycalldata.deviceinfo+xml":{"source":"iana"},"application/emergencycalldata.providerinfo+xml":{"source":"iana"},"application/emergencycalldata.serviceinfo+xml":{"source":"iana"},"application/emergencycalldata.subscriberinfo+xml":{"source":"iana"},"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":"iana","extensions":["epub"]},"application/eshop":{"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/geo+json":{"source":"iana","compressible":true},"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","war","ear"]},"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/jose":{"source":"iana"},"application/jose+json":{"source":"iana","compressible":true},"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/json-seq":{"source":"iana"},"application/json5":{"extensions":["json5"]},"application/jsonml+json":{"source":"apache","compressible":true,"extensions":["jsonml"]},"application/jwk+json":{"source":"iana","compressible":true},"application/jwk-set+json":{"source":"iana","compressible":true},"application/jwt":{"source":"iana"},"application/kpml-request+xml":{"source":"iana"},"application/kpml-response+xml":{"source":"iana"},"application/ld+json":{"source":"iana","compressible":true,"extensions":["jsonld"]},"application/lgr+xml":{"source":"iana"},"application/link-format":{"source":"iana"},"application/load-control+xml":{"source":"iana"},"application/lost+xml":{"source":"iana","extensions":["lostxml"]},"application/lostsync+xml":{"source":"iana"},"application/lxf":{"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/manifest+json":{"charset":"UTF-8","compressible":true,"extensions":["webmanifest"]},"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":"iana","extensions":["mbox"]},"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/mf4":{"source":"iana"},"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":"iana"},"application/octet-stream":{"source":"iana","compressible":false,"extensions":["bin","dms","lrf","mar","so","dist","distz","pkg","bpk","dump","elc","deploy","exe","dll","deb","dmg","iso","img","msi","msp","msm","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/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/pkcs12":{"source":"iana"},"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/ppsp-tracker+json":{"source":"iana","compressible":true},"application/problem+json":{"source":"iana","compressible":true},"application/problem+xml":{"source":"iana"},"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/rdap+json":{"source":"iana","compressible":true},"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/rfc+xml":{"source":"iana"},"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/scim+json":{"source":"iana","compressible":true},"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.3gpp-prose+xml":{"source":"iana"},"application/vnd.3gpp-prose-pc3ch+xml":{"source":"iana"},"application/vnd.3gpp.access-transfer-events+xml":{"source":"iana"},"application/vnd.3gpp.bsf+xml":{"source":"iana"},"application/vnd.3gpp.mid-call+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.3gpp.sms+xml":{"source":"iana"},"application/vnd.3gpp.srvcc-ext+xml":{"source":"iana"},"application/vnd.3gpp.srvcc-info+xml":{"source":"iana"},"application/vnd.3gpp.state-and-event-info+xml":{"source":"iana"},"application/vnd.3gpp.ussd+xml":{"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.3lightssoftware.imagescal":{"source":"iana"},"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":"iana","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.amazon.mobi8-ebook":{"source":"iana"},"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.anki":{"source":"iana"},"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.apache.thrift.compact":{"source":"iana"},"application/vnd.apache.thrift.json":{"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.apple.pkpass":{"compressible":false,"extensions":["pkpass"]},"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.balsamiq.bmpr":{"source":"iana"},"application/vnd.bekitzur-stech+json":{"source":"iana","compressible":true},"application/vnd.biopax.rdf+xml":{"source":"iana"},"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.chess-pgn":{"source":"iana"},"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.citationstyles.style+xml":{"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.coffeescript":{"source":"iana"},"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.comicbook+zip":{"source":"iana"},"application/vnd.commerce-battelle":{"source":"iana"},"application/vnd.commonspace":{"source":"iana","extensions":["csp"]},"application/vnd.contact.cmsg":{"source":"iana","extensions":["cdbcmsg"]},"application/vnd.coreos.ignition+json":{"source":"iana","compressible":true},"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":"iana"},"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.d2l.coursepackage1p0+zip":{"source":"iana"},"application/vnd.dart":{"source":"iana","compressible":true,"extensions":["dart"]},"application/vnd.data-vision.rdz":{"source":"iana","extensions":["rdz"]},"application/vnd.debian.binary-package":{"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":"iana","extensions":["uvz","uvvz"]},"application/vnd.denovo.fcselayout-link":{"source":"iana","extensions":["fe_launch"]},"application/vnd.desmume-movie":{"source":"iana"},"application/vnd.desmume.movie":{"source":"apache"},"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.drive+json":{"source":"iana","compressible":true},"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":"iana","extensions":["svc"]},"application/vnd.dxr":{"source":"iana"},"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.enphase.envoy":{"source":"iana"},"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.espass-espass+zip":{"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.fastcopy-disk-image":{"source":"iana"},"application/vnd.fdf":{"source":"iana","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.filmit.zfc":{"source":"iana"},"application/vnd.fints":{"source":"iana"},"application/vnd.firemonkeys.cloudcell":{"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.gerber":{"source":"iana"},"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-apps.document":{"compressible":false,"extensions":["gdoc"]},"application/vnd.google-apps.presentation":{"compressible":false,"extensions":["gslides"]},"application/vnd.google-apps.spreadsheet":{"compressible":false,"extensions":["gsheet"]},"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.gov.sk.e-form+xml":{"source":"iana"},"application/vnd.gov.sk.e-form+zip":{"source":"iana"},"application/vnd.gov.sk.xmldatacontainer+xml":{"source":"iana"},"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.hdt":{"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","extensions":["sfd-hdstx"]},"application/vnd.hyperdrive+json":{"source":"iana","compressible":true},"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.imsccv1p1":{"source":"iana"},"application/vnd.ims.imsccv1p2":{"source":"iana"},"application/vnd.ims.imsccv1p3":{"source":"iana"},"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.mapbox-vector-tile":{"source":"iana"},"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.micro+json":{"source":"iana","compressible":true},"application/vnd.micrografx.flo":{"source":"iana","extensions":["flo"]},"application/vnd.micrografx.igx":{"source":"iana","extensions":["igx"]},"application/vnd.microsoft.portable-executable":{"source":"iana"},"application/vnd.miele+json":{"source":"iana","compressible":true},"application/vnd.mif":{"source":"iana","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-printdevicecapabilities+xml":{"source":"iana"},"application/vnd.ms-printing.printticket+xml":{"source":"apache"},"application/vnd.ms-printschematicket+xml":{"source":"iana"},"application/vnd.ms-project":{"source":"iana","extensions":["mpp","mpt"]},"application/vnd.ms-tnef":{"source":"iana"},"application/vnd.ms-windows.devicepairing":{"source":"iana"},"application/vnd.ms-windows.nwprinting.oob":{"source":"iana"},"application/vnd.ms-windows.printerpairing":{"source":"iana"},"application/vnd.ms-windows.wsd.oob":{"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.msa-disk-image":{"source":"iana"},"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.nearst.inv+json":{"source":"iana","compressible":true},"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","extensions":["n-gage"]},"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.lwm2m+json":{"source":"iana","compressible":true},"application/vnd.oma.lwm2m+tlv":{"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.onepager":{"source":"iana"},"application/vnd.openblox.game+xml":{"source":"iana"},"application/vnd.openblox.game-binary":{"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.oracle.resource+json":{"source":"iana","compressible":true},"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.oxli.countgraph":{"source":"iana"},"application/vnd.pagerduty+json":{"source":"iana","compressible":true},"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":"iana"},"application/vnd.pwg-xhtml-print+xml":{"source":"iana"},"application/vnd.qualcomm.brew-app-res":{"source":"iana"},"application/vnd.quarantainenet":{"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.rar":{"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.3df":{"source":"iana"},"application/vnd.sealed.csf":{"source":"iana"},"application/vnd.sealed.doc":{"source":"iana"},"application/vnd.sealed.eml":{"source":"iana"},"application/vnd.sealed.mht":{"source":"iana"},"application/vnd.sealed.net":{"source":"iana"},"application/vnd.sealed.ppt":{"source":"iana"},"application/vnd.sealed.tiff":{"source":"iana"},"application/vnd.sealed.xls":{"source":"iana"},"application/vnd.sealedmedia.softseal.html":{"source":"iana"},"application/vnd.sealedmedia.softseal.pdf":{"source":"iana"},"application/vnd.seemail":{"source":"iana","extensions":["see"]},"application/vnd.sema":{"source":"iana","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.tmd.mediaflex.api+xml":{"source":"iana"},"application/vnd.tml":{"source":"iana"},"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.uri-map":{"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.vel+json":{"source":"iana","compressible":true},"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.sic":{"source":"iana"},"application/vnd.wap.slc":{"source":"iana"},"application/vnd.wap.wbxml":{"source":"iana","extensions":["wbxml"]},"application/vnd.wap.wmlc":{"source":"iana","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/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-bdoc":{"compressible":false,"extensions":["bdoc"]},"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-cocoa":{"source":"nginx","extensions":["cco"]},"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-httpd-php":{"compressible":true,"extensions":["php"]},"application/x-install-instructions":{"source":"apache","extensions":["install"]},"application/x-iso9660-image":{"source":"apache","extensions":["iso"]},"application/x-java-archive-diff":{"source":"nginx","extensions":["jardiff"]},"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-makeself":{"source":"nginx","extensions":["run"]},"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-msdos-program":{"extensions":["exe"]},"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-ns-proxy-autoconfig":{"compressible":true,"extensions":["pac"]},"application/x-nzb":{"source":"apache","extensions":["nzb"]},"application/x-perl":{"source":"nginx","extensions":["pl","pm"]},"application/x-pilot":{"source":"nginx","extensions":["prc","pdb"]},"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-redhat-package-manager":{"source":"nginx","extensions":["rpm"]},"application/x-research-info-systems":{"source":"apache","extensions":["ris"]},"application/x-sea":{"source":"nginx","extensions":["sea"]},"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","tk"]},"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-urlencoded":{"source":"iana","compressible":true},"application/x-x509-ca-cert":{"source":"apache","extensions":["der","crt","pem"]},"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":"apache"},"application/xml":{"source":"iana","compressible":true,"extensions":["xml","xsl","xsd","rng"]},"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","compressible":false,"extensions":["3gpp"]},"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/evs":{"source":"iana"},"audio/fwdred":{"source":"iana"},"audio/g711-0":{"source":"iana"},"audio/g719":{"source":"iana"},"audio/g722":{"source":"iana"},"audio/g7221":{"source":"iana"},"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/mp3":{"compressible":false,"extensions":["mp3"]},"audio/mp4":{"source":"iana","compressible":false,"extensions":["m4a","mp4a"]},"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":"iana"},"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.vmx.cvsd":{"source":"iana"},"audio/vnd.wave":{"compressible":false},"audio/vorbis":{"source":"iana","compressible":false},"audio/vorbis-config":{"source":"iana"},"audio/wav":{"compressible":false,"extensions":["wav"]},"audio/wave":{"compressible":false,"extensions":["wav"]},"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-m4a":{"source":"nginx","extensions":["m4a"]},"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-realaudio":{"source":"nginx","extensions":["ra"]},"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":"iana","compressible":true,"extensions":["bmp"]},"image/cgm":{"source":"iana","extensions":["cgm"]},"image/dicom-rle":{"source":"iana"},"image/emf":{"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/jls":{"source":"iana"},"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.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":"iana","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.mozilla.apng":{"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.sealedmedia.softseal.gif":{"source":"iana"},"image/vnd.sealedmedia.softseal.jpg":{"source":"iana"},"image/vnd.svf":{"source":"iana"},"image/vnd.tencent.tap":{"source":"iana"},"image/vnd.valve.source.texture":{"source":"iana"},"image/vnd.wap.wbmp":{"source":"iana","extensions":["wbmp"]},"image/vnd.xiff":{"source":"iana","extensions":["xif"]},"image/vnd.zbrush.pcx":{"source":"iana"},"image/webp":{"source":"apache","extensions":["webp"]},"image/wmf":{"source":"iana"},"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-jng":{"source":"nginx","extensions":["jng"]},"image/x-mrsid-image":{"source":"apache","extensions":["sid"]},"image/x-ms-bmp":{"source":"nginx","compressible":true,"extensions":["bmp"]},"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/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/gltf+json":{"source":"iana","compressible":true},"model/iges":{"source":"iana","compressible":false,"extensions":["igs","iges"]},"model/mesh":{"source":"iana","compressible":false,"extensions":["msh","mesh","silo"]},"model/vnd.collada+xml":{"source":"iana","extensions":["dae"]},"model/vnd.dwf":{"source":"iana","extensions":["dwf"]},"model/vnd.flatland.3dml":{"source":"iana"},"model/vnd.gdl":{"source":"iana","extensions":["gdl"]},"model/vnd.gs-gdl":{"source":"apache"},"model/vnd.gs.gdl":{"source":"iana"},"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.rosette.annotated-data-model":{"source":"iana"},"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/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","litcoffee"]},"text/css":{"source":"iana","compressible":true,"extensions":["css"]},"text/csv":{"source":"iana","compressible":true,"extensions":["csv"]},"text/csv-schema":{"source":"iana"},"text/directory":{"source":"iana"},"text/dns":{"source":"iana"},"text/ecmascript":{"source":"iana"},"text/encaprtp":{"source":"iana"},"text/enriched":{"source":"iana"},"text/fwdred":{"source":"iana"},"text/grammar-ref-list":{"source":"iana"},"text/hjson":{"extensions":["hjson"]},"text/html":{"source":"iana","compressible":true,"extensions":["html","htm","shtml"]},"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/markdown":{"source":"iana"},"text/mathml":{"source":"nginx","extensions":["mml"]},"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/prs.prop.logic":{"source":"iana"},"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","compressible":true,"extensions":["rtf"]},"text/rtp-enc-aescm128":{"source":"iana"},"text/rtploopback":{"source":"iana"},"text/rtx":{"source":"iana"},"text/sgml":{"source":"iana","extensions":["sgml","sgm"]},"text/slim":{"extensions":["slim","slm"]},"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.abc":{"source":"iana"},"text/vnd.ascii-art":{"source":"iana"},"text/vnd.curl":{"source":"iana","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.si":{"source":"iana"},"text/vnd.wap.sl":{"source":"iana"},"text/vnd.wap.wml":{"source":"iana","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":{"source":"nginx","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-processing":{"compressible":true,"extensions":["pde"]},"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-suse-ymp":{"compressible":true,"extensions":["ymp"]},"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,"extensions":["xml"]},"text/xml-external-parsed-entity":{"source":"iana"},"text/yaml":{"extensions":["yaml","yml"]},"video/1d-interleaved-parityfec":{"source":"apache"},"video/3gpp":{"source":"apache","extensions":["3gp","3gpp"]},"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/encaprtp":{"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/h265":{"source":"apache"},"video/iso.segment":{"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/raptorfec":{"source":"apache"},"video/raw":{"source":"apache"},"video/rtp-enc-aescm128":{"source":"apache"},"video/rtploopback":{"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.radgamettools.bink":{"source":"apache"},"video/vnd.radgamettools.smacker":{"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/vp8":{"source":"apache"},"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}}; + +var db$1 = Object.freeze({ + default: db +}); + +var require$$0$2 = ( db$1 && db$1['default'] ) || db$1; + +var __moduleExports$57 = createCommonjsModule(function (module) { + /*! + * mime-db + * Copyright(c) 2014 Jonathan Ong + * MIT Licensed + */ + + /** + * Module exports. + */ + + module.exports = require$$0$2; +}); + +var __moduleExports$56 = createCommonjsModule(function (module, exports) { + /*! + * mime-types + * Copyright(c) 2014 Jonathan Ong + * Copyright(c) 2015 Douglas Christopher Wilson + * MIT Licensed + */ + + 'use strict'; + + /** + * Module dependencies. + * @private + */ + + var db = __moduleExports$57; + var extname = path.extname; + + /** + * Module variables. + * @private + */ + + var extractTypeRegExp = /^\s*([^;\s]*)(?:;|\s|$)/; + var textTypeRegExp = /^text\//i; + + /** + * Module exports. + * @public + */ + + exports.charset = charset; + exports.charsets = { lookup: charset }; + exports.contentType = contentType; + exports.extension = extension; + exports.extensions = Object.create(null); + exports.lookup = lookup; + exports.types = Object.create(null); + + // Populate the extensions/types maps + populateMaps(exports.extensions, exports.types); + + /** + * Get the default charset for a MIME type. + * + * @param {string} type + * @return {boolean|string} + */ + + function charset(type) { + if (!type || typeof type !== 'string') { + return false; + } + + // TODO: use media-typer + var match = extractTypeRegExp.exec(type); + var mime = match && db[match[1].toLowerCase()]; + + if (mime && mime.charset) { + return mime.charset; + } + + // default text/* to utf-8 + if (match && textTypeRegExp.test(match[1])) { + return 'UTF-8'; + } + + return false; + } + + /** + * Create a full Content-Type header given a MIME type or extension. + * + * @param {string} str + * @return {boolean|string} + */ + + function contentType(str) { + // TODO: should this even be in this module? + if (!str || typeof str !== 'string') { + return false; + } + + var mime = str.indexOf('/') === -1 ? exports.lookup(str) : str; + + if (!mime) { + return false; + } + + // TODO: use content-type or other module + if (mime.indexOf('charset') === -1) { + var charset = exports.charset(mime); + if (charset) mime += '; charset=' + charset.toLowerCase(); + } + + return mime; + } + + /** + * Get the default extension for a MIME type. + * + * @param {string} type + * @return {boolean|string} + */ + + function extension(type) { + if (!type || typeof type !== 'string') { + return false; + } + + // TODO: use media-typer + var match = extractTypeRegExp.exec(type); + + // get extensions + var exts = match && exports.extensions[match[1].toLowerCase()]; + + if (!exts || !exts.length) { + return false; + } + + return exts[0]; + } + + /** + * Lookup the MIME type for a file path/extension. + * + * @param {string} path + * @return {boolean|string} + */ + + function lookup(path) { + if (!path || typeof path !== 'string') { + return false; + } + + // get the extension ("ext" or ".ext" or full path) + var extension = extname('x.' + path).toLowerCase().substr(1); + + if (!extension) { + return false; + } + + return exports.types[extension] || false; + } + + /** + * Populate the extensions and types maps. + * @private + */ + + function populateMaps(extensions, types) { + // source preference (least -> most) + var preference = ['nginx', 'apache', undefined, 'iana']; + + Object.keys(db).forEach(function forEachMimeType(type) { + var mime = db[type]; + var exts = mime.extensions; + + if (!exts || !exts.length) { + return; + } + + // mime -> extensions + extensions[type] = exts; + + // extension -> mime + for (var i = 0; i < exts.length; i++) { + var extension = exts[i]; + + if (types[extension]) { + var from = preference.indexOf(db[types[extension]].source); + var to = preference.indexOf(mime.source); + + if (types[extension] !== 'application/octet-stream' && from > to || from === to && types[extension].substr(0, 12) === 'application/') { + // skip the remapping + continue; + } + } + + // set the extension -> mime + types[extension] = type; + } + }); + } +}); + +var __moduleExports$50 = createCommonjsModule(function (module) { + /*! + * accepts + * Copyright(c) 2014 Jonathan Ong + * Copyright(c) 2015 Douglas Christopher Wilson + * MIT Licensed + */ + + 'use strict'; + + /** + * Module dependencies. + * @private + */ + + var Negotiator = __moduleExports$51; + var mime = __moduleExports$56; + + /** + * Module exports. + * @public + */ + + module.exports = Accepts; + + /** + * Create a new Accepts object for the given req. + * + * @param {object} req + * @public + */ + + function Accepts(req) { + if (!(this instanceof Accepts)) return new Accepts(req); + + this.headers = req.headers; + this.negotiator = new 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} types... + * @return {String|Array|Boolean} + * @public + */ + + Accepts.prototype.type = Accepts.prototype.types = function (types_) { + var types = types_; + + // support flattened arguments + if (types && !Array.isArray(types)) { + types = new Array(arguments.length); + for (var i = 0; i < types.length; i++) { + types[i] = arguments[i]; + } + } + + // no types, return all requested types + if (!types || types.length === 0) { + return this.negotiator.mediaTypes(); + } + + if (!this.headers.accept) return types[0]; + var mimes = types.map(extToMime); + var accepts = this.negotiator.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} encodings... + * @return {String|Array} + * @public + */ + + Accepts.prototype.encoding = Accepts.prototype.encodings = function (encodings_) { + var encodings = encodings_; + + // support flattened arguments + if (encodings && !Array.isArray(encodings)) { + encodings = new Array(arguments.length); + for (var i = 0; i < encodings.length; i++) { + encodings[i] = arguments[i]; + } + } + + // no encodings, return all requested encodings + if (!encodings || encodings.length === 0) { + return this.negotiator.encodings(); + } + + return this.negotiator.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} charsets... + * @return {String|Array} + * @public + */ + + Accepts.prototype.charset = Accepts.prototype.charsets = function (charsets_) { + var charsets = charsets_; + + // support flattened arguments + if (charsets && !Array.isArray(charsets)) { + charsets = new Array(arguments.length); + for (var i = 0; i < charsets.length; i++) { + charsets[i] = arguments[i]; + } + } + + // no charsets, return all requested charsets + if (!charsets || charsets.length === 0) { + return this.negotiator.charsets(); + } + + return this.negotiator.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} langs... + * @return {Array|String} + * @public + */ + + Accepts.prototype.lang = Accepts.prototype.langs = Accepts.prototype.language = Accepts.prototype.languages = function (languages_) { + var languages = languages_; + + // support flattened arguments + if (languages && !Array.isArray(languages)) { + languages = new Array(arguments.length); + for (var i = 0; i < languages.length; i++) { + languages[i] = arguments[i]; + } + } + + // no languages, return all requested languages + if (!languages || languages.length === 0) { + return this.negotiator.languages(); + } + + return this.negotiator.languages(languages)[0] || false; + }; + + /** + * Convert extnames to mime. + * + * @param {String} type + * @return {String} + * @private + */ + + function extToMime(type) { + return type.indexOf('/') === -1 ? mime.lookup(type) : type; + } + + /** + * Check if mime is valid. + * + * @param {String} type + * @return {String} + * @private + */ + + function validMime(type) { + return typeof type === 'string'; + } +}); + +var __moduleExports$59 = createCommonjsModule(function (module, exports) { + /*! + * 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 === 'undefined' ? 'undefined' : _typeof$1(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 === 'undefined' ? 'undefined' : _typeof$1(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 === 'undefined' ? 'undefined' : _typeof$1(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$1(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; + } +}); + +var __moduleExports$58 = createCommonjsModule(function (module) { + /*! + * type-is + * Copyright(c) 2014 Jonathan Ong + * Copyright(c) 2014-2015 Douglas Christopher Wilson + * MIT Licensed + */ + + 'use strict'; + + /** + * Module dependencies. + * @private + */ + + var typer = __moduleExports$59; + var mime = __moduleExports$56; + + /** + * Module exports. + * @public + */ + + module.exports = typeofrequest; + module.exports.is = typeis; + module.exports.hasBody = hasbody; + module.exports.normalize = normalize; + module.exports.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 + * @public + */ + + function typeis(value, types_) { + var i; + var types = types_; + + // remove parameters and normalize + var val = tryNormalizeType(value); + + // no type or invalid + if (!val) { + 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 val; + } + + var type; + for (i = 0; i < types.length; i++) { + if (mimeMatch(normalize(type = types[i]), val)) { + return type[0] === '+' || type.indexOf('*') !== -1 ? val : 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} + * @public + */ + + function hasbody(req) { + return req.headers['transfer-encoding'] !== undefined || !isNaN(req.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} + * @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 + * @private + */ + + function normalize(type) { + if (typeof type !== 'string') { + // invalid type + return false; + } + + switch (type) { + case 'urlencoded': + return 'application/x-www-form-urlencoded'; + case 'multipart': + return 'multipart/*'; + } + + if (type[0] === '+') { + // "+json" -> "*/*+json" expando + return '*/*' + type; + } + + return type.indexOf('/') === -1 ? mime.lookup(type) : type; + } + + /** + * Check if `expected` mime type + * matches `actual` mime type with + * wildcard and +suffix support. + * + * @param {String} expected + * @param {String} actual + * @return {Boolean} + * @private + */ + + function mimeMatch(expected, actual) { + // invalid type + if (expected === false) { + return false; + } + + // split types + var actualParts = actual.split('/'); + var expectedParts = expected.split('/'); + + // invalid format + if (actualParts.length !== 2 || expectedParts.length !== 2) { + return false; + } + + // validate type + if (expectedParts[0] !== '*' && expectedParts[0] !== actualParts[0]) { + return false; + } + + // validate suffix wildcard + if (expectedParts[1].substr(0, 2) === '*+') { + return expectedParts[1].length <= actualParts[1].length + 1 && expectedParts[1].substr(1) === actualParts[1].substr(1 - expectedParts[1].length); + } + + // validate subtype + if (expectedParts[1] !== '*' && expectedParts[1] !== actualParts[1]) { + return false; + } + + return true; + } + + /** + * Normalize a type and remove parameters. + * + * @param {string} value + * @return {string} + * @private + */ + + function normalizeType(value) { + // parse the type + var type = typer.parse(value); + + // remove the parameters + type.parameters = undefined; + + // reformat it + return typer.format(type); + } + + /** + * Try to normalize a type and remove parameters. + * + * @param {string} value + * @return {string} + * @private + */ + + function tryNormalizeType(value) { + try { + return normalizeType(value); + } catch (err) { + return null; + } + } +}); + +var __moduleExports$49 = createCommonjsModule(function (module, exports) { + /*! + * express + * Copyright(c) 2009-2013 TJ Holowaychuk + * Copyright(c) 2013 Roman Shtylman + * Copyright(c) 2014-2015 Douglas Christopher Wilson + * MIT Licensed + */ + + 'use strict'; + + /** + * Module dependencies. + * @private + */ + + var accepts = __moduleExports$50; + var deprecate = __moduleExports$20('express'); + var isIP = net.isIP; + var typeis = __moduleExports$58; + var http$$ = http; + var fresh = __moduleExports$43; + var parseRange = __moduleExports$45; + var parse = __moduleExports$25; + var proxyaddr = __moduleExports$46; + + /** + * 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} + * @public + */ + + req.get = req.header = function header(name) { + if (!name) { + throw new TypeError('name argument is required to req.get'); + } + + if (typeof name !== 'string') { + throw new TypeError('name must be a string to req.get'); + } + + var lc = name.toLowerCase(); + + switch (lc) { + case 'referer': + case 'referrer': + return this.headers.referrer || this.headers.referer; + default: + return this.headers[lc]; + } + }; + + /** + * 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", an extension name + * such as "json", a comma-delimited 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|Array|Boolean} + * @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 {String|Array} + * @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 {String|Array} + * @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 {String|Array} + * @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 `undefined` is returned, `-1` when unsatisfiable, + * and `-2` when syntactically invalid. + * + * When ranges are returned, the array has a "type" property which is the type of + * range that is required (most commonly, "bytes"). Each array element is an object + * with a "start" and "end" property for the portion of the range. + * + * The "combine" option can be set to `true` and overlapping & adjacent ranges + * will be combined into a single range. + * + * 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 + * @param {object} [options] + * @param {boolean} [options.combine=false] + * @return {number|array} + * @public + */ + + req.range = function range(size, options) { + var range = this.get('Range'); + if (!range) return; + return parseRange(size, range, options); + }; + + /** + * 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} + * @public + */ + + req.param = function param(name, defaultValue) { + var params = this.params || {}; + var body = this.body || {}; + var query = this.query || {}; + + var args = arguments.length === 1 ? 'name' : 'name, default'; + deprecate('req.param(' + args + '): Use req.params, req.body, or req.query instead'); + + 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|Array} types... + * @return {String|false|null} + * @public + */ + + req.is = function is(types) { + var arr = types; + + // support flattened arguments + if (!Array.isArray(types)) { + arr = new Array(arguments.length); + for (var i = 0; i < arr.length; i++) { + arr[i] = arguments[i]; + } + } + + return typeis(this, arr); + }; + + /** + * 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} + * @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, 0)) { + 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} + * @public + */ + + defineGetter(req, 'secure', function secure() { + return this.protocol === 'https'; + }); + + /** + * Return the remote address from the trusted proxy. + * + * The is the remote address on the socket unless + * "trust proxy" is set. + * + * @return {String} + * @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} + * @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} + * @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} + * @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} + * @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, 0)) { + 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 !== -1 ? 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} + * @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} + * @public + */ + + defineGetter(req, 'stale', function stale() { + return !this.fresh; + }); + + /** + * Check if the request was an _XMLHttpRequest_. + * + * @return {Boolean} + * @public + */ + + defineGetter(req, 'xhr', function xhr() { + var val = this.get('X-Requested-With') || ''; + return val.toLowerCase() === 'xmlhttprequest'; + }); + + /** + * Helper function for creating a getter on an object. + * + * @param {Object} obj + * @param {String} name + * @param {Function} getter + * @private + */ + function defineGetter(obj, name, getter) { + Object.defineProperty(obj, name, { + configurable: true, + enumerable: true, + get: getter + }); + }; +}); + +var __moduleExports$61 = createCommonjsModule(function (module, exports) { + /** + * Module dependencies. + */ + + var crypto$$ = 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 value must be provided as a string."); + if ('string' != typeof secret) throw new TypeError("Secret string must be provided."); + 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("Signed cookie string must be provided."); + if ('string' != typeof secret) throw new TypeError("Secret string must be provided."); + 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'); + } +}); + +var __moduleExports$62 = createCommonjsModule(function (module, exports) { + /*! + * cookie + * Copyright(c) 2012-2014 Roman Shtylman + * Copyright(c) 2015 Douglas Christopher Wilson + * MIT Licensed + */ + + 'use strict'; + + /** + * Module exports. + * @public + */ + + exports.parse = parse; + exports.serialize = serialize; + + /** + * Module variables. + * @private + */ + + var decode = decodeURIComponent; + var encode = encodeURIComponent; + var pairSplitRegExp = /; */; + + /** + * RegExp to match field-content in RFC 7230 sec 3.2 + * + * field-content = field-vchar [ 1*( SP / HTAB ) field-vchar ] + * field-vchar = VCHAR / obs-text + * obs-text = %x80-FF + */ + + var fieldContentRegExp = /^[\u0009\u0020-\u007e\u0080-\u00ff]+$/; + + /** + * Parse a cookie header. + * + * Parse the given cookie header string into an object + * The object has the various cookies as keys(names) => values + * + * @param {string} str + * @param {object} [options] + * @return {object} + * @public + */ + + function parse(str, options) { + if (typeof str !== 'string') { + throw new TypeError('argument str must be a string'); + } + + var obj = {}; + var opt = options || {}; + var pairs = str.split(pairSplitRegExp); + var dec = opt.decode || decode; + + for (var i = 0; i < pairs.length; i++) { + var pair = pairs[i]; + var eq_idx = pair.indexOf('='); + + // skip things that don't look like key=value + if (eq_idx < 0) { + continue; + } + + 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]) { + obj[key] = tryDecode(val, dec); + } + } + + return obj; + } + + /** + * Serialize data into a cookie header. + * + * 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} + * @public + */ + + function serialize(name, val, options) { + var opt = options || {}; + var enc = opt.encode || encode; + + if (typeof enc !== 'function') { + throw new TypeError('option encode is invalid'); + } + + if (!fieldContentRegExp.test(name)) { + throw new TypeError('argument name is invalid'); + } + + var value = enc(val); + + if (value && !fieldContentRegExp.test(value)) { + throw new TypeError('argument val is invalid'); + } + + var str = name + '=' + value; + + if (null != opt.maxAge) { + var maxAge = opt.maxAge - 0; + if (isNaN(maxAge)) throw new Error('maxAge should be a Number'); + str += '; Max-Age=' + Math.floor(maxAge); + } + + if (opt.domain) { + if (!fieldContentRegExp.test(opt.domain)) { + throw new TypeError('option domain is invalid'); + } + + str += '; Domain=' + opt.domain; + } + + if (opt.path) { + if (!fieldContentRegExp.test(opt.path)) { + throw new TypeError('option path is invalid'); + } + + str += '; Path=' + opt.path; + } + + if (opt.expires) { + if (typeof opt.expires.toUTCString !== 'function') { + throw new TypeError('option expires is invalid'); + } + + str += '; Expires=' + opt.expires.toUTCString(); + } + + if (opt.httpOnly) { + str += '; HttpOnly'; + } + + if (opt.secure) { + str += '; Secure'; + } + + if (opt.sameSite) { + var sameSite = typeof opt.sameSite === 'string' ? opt.sameSite.toLowerCase() : opt.sameSite; + + switch (sameSite) { + case true: + str += '; SameSite=Strict'; + break; + case 'lax': + str += '; SameSite=Lax'; + break; + case 'strict': + str += '; SameSite=Strict'; + break; + default: + throw new TypeError('option sameSite is invalid'); + } + } + + return str; + } + + /** + * Try decoding a string using a decoding function. + * + * @param {string} str + * @param {function} decode + * @private + */ + + function tryDecode(str, decode) { + try { + return decode(str); + } catch (e) { + return str; + } + } +}); + +var __moduleExports$63 = createCommonjsModule(function (module) { + /*! + * vary + * Copyright(c) 2014-2015 Douglas Christopher Wilson + * MIT Licensed + */ + + 'use strict'; + + /** + * Module exports. + */ + + module.exports = vary; + module.exports.append = append; + + /** + * RegExp to match field-name in RFC 7230 sec 3.2 + * + * field-name = token + * token = 1*tchar + * tchar = "!" / "#" / "$" / "%" / "&" / "'" / "*" + * / "+" / "-" / "." / "^" / "_" / "`" / "|" / "~" + * / DIGIT / ALPHA + * ; any VCHAR, except delimiters + */ + + var fieldNameRegExp = /^[!#$%&'\*\+\-\.\^_`\|~0-9A-Za-z]+$/; + + /** + * 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 field names + for (var i = 0; i < fields.length; i++) { + if (!fieldNameRegExp.test(fields[i])) { + throw new TypeError('field argument contains an invalid header name'); + } + } + + // existing, unspecified vary + if (header === '*') { + return header; + } + + // enumerate current values + var val = header; + var vals = parse(header.toLowerCase()); + + // unspecified vary + if (fields.indexOf('*') !== -1 || vals.indexOf('*') !== -1) { + return '*'; + } + + for (var i = 0; i < fields.length; i++) { + var fld = fields[i].toLowerCase(); + + // append value (case-preserving) + if (vals.indexOf(fld) === -1) { + vals.push(fld); + val = val ? val + ', ' + fields[i] : fields[i]; + } + } + + return val; + } + + /** + * 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 + if (val = append(header, field)) { + res.setHeader('Vary', val); + } + } +}); + +var __moduleExports$60 = createCommonjsModule(function (module) { + /*! + * express + * Copyright(c) 2009-2013 TJ Holowaychuk + * Copyright(c) 2014-2015 Douglas Christopher Wilson + * MIT Licensed + */ + + 'use strict'; + + /** + * Module dependencies. + * @private + */ + + var contentDisposition = __moduleExports$34; + var deprecate = __moduleExports$20('express'); + var encodeUrl = __moduleExports$41; + var escapeHtml = __moduleExports$8; + var http$$ = http; + var isAbsolute = __moduleExports$33.isAbsolute; + var onFinished = __moduleExports$9; + var path$$ = path; + var merge = __moduleExports$19; + var sign = __moduleExports$61.sign; + var normalizeType = __moduleExports$33.normalizeType; + var normalizeTypes = __moduleExports$33.normalizeTypes; + var setCharset = __moduleExports$33.setCharset; + var statusCodes = http$$.STATUS_CODES; + var cookie = __moduleExports$62; + var send = __moduleExports$36; + var extname = path$$.extname; + var mime = send.mime; + var resolve = path$$.resolve; + var vary = __moduleExports$63; + + /** + * Response prototype. + */ + + var res = module.exports = { + __proto__: http$$.ServerResponse.prototype + }; + + /** + * Module variables. + * @private + */ + + var charsetRegExp = /;\s*charset\s*=/; + + /** + * Set status `code`. + * + * @param {Number} code + * @return {ServerResponse} + * @public + */ + + res.status = function status(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} + * @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 + * @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.sendStatus(status) instead'); + this.statusCode = chunk; + chunk = statusCodes[chunk]; + } + + switch (typeof chunk === 'undefined' ? 'undefined' : _typeof$1(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); + } + + // populate ETag + var etag; + var generateETag = len !== undefined && app.get('etag fn'); + if (typeof generateETag === 'function' && !this.get('ETag')) { + if (etag = generateETag(chunk, encoding)) { + 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 = ''; + } + + if (req.method === 'HEAD') { + // skip body for HEAD + this.end(); + } else { + // respond + this.end(chunk, encoding); + } + + return this; + }; + + /** + * Send JSON response. + * + * Examples: + * + * res.json(null); + * res.json({ user: 'tj' }); + * + * @param {string|number|boolean|object} obj + * @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 = 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 + * @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 = 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 + * @public + */ + + res.sendStatus = function sendStatus(statusCode) { + var body = statusCodes[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 `callback(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.'); + * } + * }); + * }); + * + * @public + */ + + res.sendFile = function sendFile(path$$, options, callback) { + var done = callback; + var req = this.req; + var res = this; + var next = req.next; + var opts = options || {}; + + if (!path$$) { + throw new TypeError('path argument is required to res.sendFile'); + } + + // support function as second arg + if (typeof options === 'function') { + done = options; + opts = {}; + } + + if (!opts.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, opts); + + // transfer + sendfile(res, file, opts, function (err) { + if (done) return done(err); + if (err && err.code === 'EISDIR') return next(); + + // next() all but write errors + if (err && err.code !== 'ECONNABORTED' && err.syscall !== 'write') { + next(err); + } + }); + }; + + /** + * Transfer the file at the given `path`. + * + * Automatically sets the _Content-Type_ response header field. + * The callback `callback(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.'); + * } + * }); + * }); + * + * @public + */ + + res.sendfile = function (path$$, options, callback) { + var done = callback; + var req = this.req; + var res = this; + var next = req.next; + var opts = options || {}; + + // support function as second arg + if (typeof options === 'function') { + done = options; + opts = {}; + } + + // create file stream + var file = send(req, path$$, opts); + + // transfer + sendfile(res, file, opts, function (err) { + if (done) return done(err); + if (err && err.code === 'EISDIR') return next(); + + // next() all but write errors + if (err && err.code !== 'ECONNABORT' && err.syscall !== 'write') { + 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 `callback(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()`. + * + * @public + */ + + res.download = function download(path$$, filename, callback) { + var done = callback; + var name = filename; + + // support function as second arg + if (typeof filename === 'function') { + done = filename; + name = null; + } + + // set Content-Disposition when file is sent + var headers = { + 'Content-Disposition': contentDisposition(name || path$$) + }; + + // Resolve the full path for sendFile + var fullPath = resolve(path$$); + + return this.sendFile(fullPath, { headers: headers }, done); + }; + + /** + * 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 + * @public + */ + + res.contentType = res.type = function contentType(type) { + var ct = type.indexOf('/') === -1 ? mime.lookup(type) : type; + + return this.set('Content-Type', ct); + }; + + /** + * 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 + * @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 = keys.length > 0 ? req.accepts(keys) : false; + + 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 = err.statusCode = 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} + * @public + */ + + res.attachment = function attachment(filename) { + if (filename) { + this.type(extname(filename)); + } + + this.set('Content-Disposition', contentDisposition(filename)); + + return this; + }; + + /** + * Append additional header `field` with value `val`. + * + * Example: + * + * res.append('Link', ['', '']); + * res.append('Set-Cookie', 'foo=bar; Path=/; HttpOnly'); + * res.append('Warning', '199 Miscellaneous warning'); + * + * @param {String} field + * @param {String|Array} val + * @return {ServerResponse} for chaining + * @public + */ + + res.append = function append(field, val) { + var prev = this.get(field); + var value = val; + + if (prev) { + // concat the new and prev vals + value = Array.isArray(prev) ? prev.concat(val) : Array.isArray(val) ? [prev].concat(val) : [prev, val]; + } + + return this.set(field, value); + }; + + /** + * 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} field + * @param {String|Array} val + * @return {ServerResponse} for chaining + * @public + */ + + res.set = res.header = function header(field, val) { + if (arguments.length === 2) { + var value = Array.isArray(val) ? val.map(String) : String(val); + + // add charset to content-type + if (field.toLowerCase() === 'content-type' && !charsetRegExp.test(value)) { + var charset = mime.charsets.lookup(value.split(';')[0]); + if (charset) value += '; charset=' + charset.toLowerCase(); + } + + this.setHeader(field, value); + } else { + for (var key in field) { + this.set(key, field[key]); + } + } + return this; + }; + + /** + * Get value for header `field`. + * + * @param {String} field + * @return {String} + * @public + */ + + res.get = function (field) { + return this.getHeader(field); + }; + + /** + * Clear cookie `name`. + * + * @param {String} name + * @param {Object} [options] + * @return {ServerResponse} for chaining + * @public + */ + + res.clearCookie = function clearCookie(name, options) { + var opts = merge({ expires: new Date(1), path: '/' }, options); + + return this.cookie(name, '', opts); + }; + + /** + * Set cookie `name` to `value`, 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} value + * @param {Options} options + * @return {ServerResponse} for chaining + * @public + */ + + res.cookie = function (name, value, options) { + var opts = merge({}, options); + var secret = this.req.secret; + var signed = opts.signed; + + if (signed && !secret) { + throw new Error('cookieParser("secret") required for signed cookies'); + } + + var val = (typeof value === 'undefined' ? 'undefined' : _typeof$1(value)) === 'object' ? 'j:' + JSON.stringify(value) : String(value); + + if (signed) { + val = 's:' + sign(val, secret); + } + + if ('maxAge' in opts) { + opts.expires = new Date(Date.now() + opts.maxAge); + opts.maxAge /= 1000; + } + + if (opts.path == null) { + opts.path = '/'; + } + + this.append('Set-Cookie', cookie.serialize(name, String(val), opts)); + + 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 + * @public + */ + + res.location = function location(url) { + var loc = url; + + // "back" is an alias for the referrer + if (url === 'back') { + loc = this.req.get('Referrer') || '/'; + } + + // set location + return this.set('Location', encodeUrl(loc)); + }; + + /** + * 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 + * + * @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 + address = this.location(address).get('Location'); + + // Support text/{plain,html} by default + this.format({ + text: function text() { + body = statusCodes[status] + '. Redirecting to ' + address; + }, + + html: function html() { + var u = escapeHtml(address); + body = '

' + statusCodes[status] + '. Redirecting to ' + u + '

'; + }, + + default: function _default() { + body = ''; + } + }); + + // Respond + this.statusCode = status; + this.set('Content-Length', Buffer.byteLength(body)); + + if (this.req.method === 'HEAD') { + this.end(); + } else { + 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 + * @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 + * + * @public + */ + + res.render = function render(view, options, callback) { + var app = this.req.app; + var done = callback; + var opts = options || {}; + var req = this.req; + var self = this; + + // support callback function as second arg + if (typeof options === 'function') { + done = options; + opts = {}; + } + + // merge res.locals + opts._locals = self.locals; + + // default callback to respond + done = done || function (err, str) { + if (err) return req.next(err); + self.send(str); + }; + + // render + app.render(view, opts, done); + }; + + // pipe the send file stream + function sendfile(res, file, options, callback) { + var done = false; + var streaming; + + // request aborted + function onaborted() { + if (done) return; + done = true; + + var err = new Error('Request aborted'); + err.code = 'ECONNABORTED'; + callback(err); + } + + // 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(); + } + + // file + function onfile() { + streaming = false; + } + + // finished + function onfinish(err) { + if (err && err.code === 'ECONNRESET') return onaborted(); + if (err) return onerror(err); + if (done) return; + + setImmediate(function () { + if (streaming !== false && !done) { + onaborted(); + return; + } + + if (done) return; + done = true; + callback(); + }); + } + + // streaming + function onstream() { + streaming = true; + } + + file.on('directory', ondirectory); + file.on('end', onend); + file.on('error', onerror); + file.on('file', onfile); + file.on('stream', onstream); + 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); + } + + /** + * Stringify JSON, like JSON.stringify, but v8 optimized. + * @private + */ + + function stringify(value, replacer, spaces) { + // v8 checks arguments.length for optimizing simple call + // https://bugs.chromium.org/p/v8/issues/detail?id=4730 + return replacer || spaces ? JSON.stringify(value, replacer, spaces) : JSON.stringify(value); + } +}); + +var __moduleExports$64 = createCommonjsModule(function (module) { + /*! + * serve-static + * Copyright(c) 2010 Sencha Inc. + * Copyright(c) 2011 TJ Holowaychuk + * Copyright(c) 2014-2016 Douglas Christopher Wilson + * MIT Licensed + */ + + 'use strict'; + + /** + * Module dependencies. + * @private + */ + + var encodeUrl = __moduleExports$41; + var escapeHtml = __moduleExports$8; + var parseUrl = __moduleExports$25; + var resolve = path.resolve; + var send = __moduleExports$36; + var url$$ = url; + + /** + * Module exports. + * @public + */ + + module.exports = serveStatic; + module.exports.mime = send.mime; + + /** + * @param {string} root + * @param {object} [options] + * @return {function} + * @public + */ + + 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 + var opts = Object.create(options || null); + + // fall-though + var fallthrough = opts.fallthrough !== false; + + // default redirect + var redirect = opts.redirect !== false; + + // headers listener + var setHeaders = opts.setHeaders; + + if (setHeaders && typeof setHeaders !== 'function') { + throw new TypeError('option setHeaders must be function'); + } + + // setup options for send + opts.maxage = opts.maxage || opts.maxAge || 0; + opts.root = resolve(root); + + // construct directory listener + var onDirectory = redirect ? createRedirectDirectoryListener() : createNotFoundDirectoryListener(); + + return function serveStatic(req, res, next) { + if (req.method !== 'GET' && req.method !== 'HEAD') { + if (fallthrough) { + return next(); + } + + // method not allowed + res.statusCode = 405; + res.setHeader('Allow', 'GET, HEAD'); + res.setHeader('Content-Length', '0'); + res.end(); + return; + } + + var forwardError = !fallthrough; + var originalUrl = parseUrl.original(req); + var path = parseUrl(req).pathname; + + // make sure redirect occurs at mount + if (path === '/' && originalUrl.pathname.substr(-1) !== '/') { + path = ''; + } + + // create send stream + var stream = send(req, path, opts); + + // add directory handler + stream.on('directory', onDirectory); + + // add headers listener + if (setHeaders) { + stream.on('headers', setHeaders); + } + + // add file listener for fallthrough + if (fallthrough) { + stream.on('file', function onFile() { + // once file is determined, always forward error + forwardError = true; + }); + } + + // forward errors + stream.on('error', function error(err) { + if (forwardError || !(err.statusCode < 500)) { + next(err); + return; + } + + next(); + }); + + // pipe + stream.pipe(res); + }; + } + + /** + * Collapse all leading slashes into a single slash + * @private + */ + function collapseLeadingSlashes(str) { + for (var i = 0; i < str.length; i++) { + if (str[i] !== '/') { + break; + } + } + + return i > 1 ? '/' + str.substr(i) : str; + } + + /** + * Create a directory listener that just 404s. + * @private + */ + + function createNotFoundDirectoryListener() { + return function notFound() { + this.error(404); + }; + } + + /** + * Create a directory listener that performs a redirect. + * @private + */ + + function createRedirectDirectoryListener() { + return function redirect() { + if (this.hasTrailingSlash()) { + this.error(404); + return; + } + + // get original URL + var originalUrl = parseUrl.original(this.req); + + // append trailing slash + originalUrl.path = null; + originalUrl.pathname = collapseLeadingSlashes(originalUrl.pathname + '/'); + + // reformat the URL + var loc = encodeUrl(url$$.format(originalUrl)); + var msg = 'Redirecting to ' + escapeHtml(loc) + '\n'; + var res = this.res; + + // send redirect response + res.statusCode = 301; + res.setHeader('Content-Type', 'text/html; charset=UTF-8'); + res.setHeader('Content-Length', Buffer.byteLength(msg)); + res.setHeader('X-Content-Type-Options', 'nosniff'); + res.setHeader('Location', loc); + res.end(msg); + }; + } +}); + +var __moduleExports$1 = createCommonjsModule(function (module, exports) { + /*! + * express + * Copyright(c) 2009-2013 TJ Holowaychuk + * Copyright(c) 2013 Roman Shtylman + * Copyright(c) 2014-2015 Douglas Christopher Wilson + * MIT Licensed + */ + + 'use strict'; + + /** + * Module dependencies. + */ + + var EventEmitter = events.EventEmitter; + var mixin = __moduleExports$2; + var proto = __moduleExports$3; + var Route = __moduleExports$14; + var Router = __moduleExports$13; + var req = __moduleExports$49; + var res = __moduleExports$60; + + /** + * Expose `createApplication()`. + */ + + exports = module.exports = createApplication; + + /** + * Create an express application. + * + * @return {Function} + * @api public + */ + + function createApplication() { + var app = function app(req, res, next) { + app.handle(req, res, next); + }; + + mixin(app, EventEmitter.prototype, false); + mixin(app, proto, false); + + 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 = __moduleExports$27; + exports.static = __moduleExports$64; + + /** + * 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 get() { + 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 + }); + }); +}); + +var __moduleExports = createCommonjsModule(function (module) { + /*! + * express + * Copyright(c) 2009-2013 TJ Holowaychuk + * Copyright(c) 2013 Roman Shtylman + * Copyright(c) 2014-2015 Douglas Christopher Wilson + * MIT Licensed + */ + + 'use strict'; + + module.exports = __moduleExports$1; +}); + +var __moduleExports$67 = createCommonjsModule(function (module) { + /*! + * bytes + * Copyright(c) 2012-2014 TJ Holowaychuk + * Copyright(c) 2015 Jed Watson + * MIT Licensed + */ + + 'use strict'; + + /** + * Module exports. + * @public + */ + + module.exports = bytes; + module.exports.format = format; + module.exports.parse = parse; + + /** + * Module variables. + * @private + */ + + var formatThousandsRegExp = /\B(?=(\d{3})+(?!\d))/g; + + var formatDecimalsRegExp = /(?:\.0*|(\.[^0]+)0+)$/; + + var map = { + b: 1, + kb: 1 << 10, + mb: 1 << 20, + gb: 1 << 30, + tb: (1 << 30) * 1024 + }; + + // TODO: use is-finite module? + var numberIsFinite = Number.isFinite || function (v) { + return typeof v === 'number' && isFinite(v); + }; + + var parseRegExp = /^((-|\+)?(\d+(?:\.\d+)?)) *(kb|mb|gb|tb)$/i; + + /** + * Convert the given value in bytes into a string or parse to string to an integer in bytes. + * + * @param {string|number} value + * @param {{ + * case: [string], + * decimalPlaces: [number] + * fixedDecimals: [boolean] + * thousandsSeparator: [string] + * unitSeparator: [string] + * }} [options] bytes options. + * + * @returns {string|number|null} + */ + + function bytes(value, options) { + if (typeof value === 'string') { + return parse(value); + } + + if (typeof value === 'number') { + return format(value, options); + } + + return null; + } + + /** + * Format the given value in bytes into a string. + * + * If the value is negative, it is kept as such. If it is a float, + * it is rounded. + * + * @param {number} value + * @param {object} [options] + * @param {number} [options.decimalPlaces=2] + * @param {number} [options.fixedDecimals=false] + * @param {string} [options.thousandsSeparator=] + * @param {string} [options.unitSeparator=] + * + * @returns {string|null} + * @public + */ + + function format(value, options) { + if (!numberIsFinite(value)) { + return null; + } + + var mag = Math.abs(value); + var thousandsSeparator = options && options.thousandsSeparator || ''; + var unitSeparator = options && options.unitSeparator || ''; + var decimalPlaces = options && options.decimalPlaces !== undefined ? options.decimalPlaces : 2; + var fixedDecimals = Boolean(options && options.fixedDecimals); + var unit = 'B'; + + if (mag >= map.tb) { + unit = 'TB'; + } else if (mag >= map.gb) { + unit = 'GB'; + } else if (mag >= map.mb) { + unit = 'MB'; + } else if (mag >= map.kb) { + unit = 'kB'; + } + + var val = value / map[unit.toLowerCase()]; + var str = val.toFixed(decimalPlaces); + + if (!fixedDecimals) { + str = str.replace(formatDecimalsRegExp, '$1'); + } + + if (thousandsSeparator) { + str = str.replace(formatThousandsRegExp, thousandsSeparator); + } + + return str + unitSeparator + unit; + } + + /** + * Parse the string value into an integer in bytes. + * + * If no unit is given, it is assumed the value is in bytes. + * + * @param {number|string} val + * + * @returns {number|null} + * @public + */ + + function parse(val) { + if (typeof val === 'number' && !isNaN(val)) { + return val; + } + + if (typeof val !== 'string') { + return null; + } + + // Test if the string passed is valid + var results = parseRegExp.exec(val); + var floatValue; + var unit = 'b'; + + if (!results) { + // Nothing could be extracted from the given string + floatValue = parseInt(val, 10); + unit = 'b'; + } else { + // Retrieve the value and the unit + floatValue = parseFloat(results[1]); + unit = results[4].toLowerCase(); + } + + return Math.floor(map[unit] * floatValue); + } +}); + +var __moduleExports$70 = createCommonjsModule(function (module) { + /*! + * bytes + * Copyright(c) 2012-2014 TJ Holowaychuk + * Copyright(c) 2015 Jed Watson + * MIT Licensed + */ + + 'use strict'; + + /** + * Module exports. + * @public + */ + + module.exports = bytes; + module.exports.format = format; + module.exports.parse = parse; + + /** + * Module variables. + * @private + */ + + var formatThousandsRegExp = /\B(?=(\d{3})+(?!\d))/g; + + var formatDecimalsRegExp = /(?:\.0*|(\.[^0]+)0+)$/; + + var map = { + b: 1, + kb: 1 << 10, + mb: 1 << 20, + gb: 1 << 30, + tb: (1 << 30) * 1024 + }; + + // TODO: use is-finite module? + var numberIsFinite = Number.isFinite || function (v) { + return typeof v === 'number' && isFinite(v); + }; + + var parseRegExp = /^((-|\+)?(\d+(?:\.\d+)?)) *(kb|mb|gb|tb)$/i; + + /** + * Convert the given value in bytes into a string or parse to string to an integer in bytes. + * + * @param {string|number} value + * @param {{ + * case: [string], + * decimalPlaces: [number] + * fixedDecimals: [boolean] + * thousandsSeparator: [string] + * unitSeparator: [string] + * }} [options] bytes options. + * + * @returns {string|number|null} + */ + + function bytes(value, options) { + if (typeof value === 'string') { + return parse(value); + } + + if (typeof value === 'number') { + return format(value, options); + } + + return null; + } + + /** + * Format the given value in bytes into a string. + * + * If the value is negative, it is kept as such. If it is a float, + * it is rounded. + * + * @param {number} value + * @param {object} [options] + * @param {number} [options.decimalPlaces=2] + * @param {number} [options.fixedDecimals=false] + * @param {string} [options.thousandsSeparator=] + * @param {string} [options.unitSeparator=] + * + * @returns {string|null} + * @public + */ + + function format(value, options) { + if (!numberIsFinite(value)) { + return null; + } + + var mag = Math.abs(value); + var thousandsSeparator = options && options.thousandsSeparator || ''; + var unitSeparator = options && options.unitSeparator || ''; + var decimalPlaces = options && options.decimalPlaces !== undefined ? options.decimalPlaces : 2; + var fixedDecimals = Boolean(options && options.fixedDecimals); + var unit = 'B'; + + if (mag >= map.tb) { + unit = 'TB'; + } else if (mag >= map.gb) { + unit = 'GB'; + } else if (mag >= map.mb) { + unit = 'MB'; + } else if (mag >= map.kb) { + unit = 'kB'; + } + + var val = value / map[unit.toLowerCase()]; + var str = val.toFixed(decimalPlaces); + + if (!fixedDecimals) { + str = str.replace(formatDecimalsRegExp, '$1'); + } + + if (thousandsSeparator) { + str = str.replace(formatThousandsRegExp, thousandsSeparator); + } + + return str + unitSeparator + unit; + } + + /** + * Parse the string value into an integer in bytes. + * + * If no unit is given, it is assumed the value is in bytes. + * + * @param {number|string} val + * + * @returns {number|null} + * @public + */ + + function parse(val) { + if (typeof val === 'number' && !isNaN(val)) { + return val; + } + + if (typeof val !== 'string') { + return null; + } + + // Test if the string passed is valid + var results = parseRegExp.exec(val); + var floatValue; + var unit = 'b'; + + if (!results) { + // Nothing could be extracted from the given string + floatValue = parseInt(val, 10); + unit = 'b'; + } else { + // Retrieve the value and the unit + floatValue = parseFloat(results[1]); + unit = results[4].toLowerCase(); + } + + return Math.floor(map[unit] * floatValue); + } +}); + +var __moduleExports$72 = createCommonjsModule(function (module, exports) { + "use strict"; + + var BOMChar = '\uFEFF'; + + exports.PrependBOM = PrependBOMWrapper; + function PrependBOMWrapper(encoder, options) { + this.encoder = encoder; + this.addBOM = true; + } + + PrependBOMWrapper.prototype.write = function (str) { + if (this.addBOM) { + str = BOMChar + str; + this.addBOM = false; + } + + return this.encoder.write(str); + }; + + PrependBOMWrapper.prototype.end = function () { + return this.encoder.end(); + }; + + //------------------------------------------------------------------------------ + + exports.StripBOM = StripBOMWrapper; + function StripBOMWrapper(decoder, options) { + this.decoder = decoder; + this.pass = false; + this.options = options || {}; + } + + StripBOMWrapper.prototype.write = function (buf) { + var res = this.decoder.write(buf); + if (this.pass || !res) return res; + + if (res[0] === BOMChar) { + res = res.slice(1); + if (typeof this.options.stripBOM === 'function') this.options.stripBOM(); + } + + this.pass = true; + return res; + }; + + StripBOMWrapper.prototype.end = function () { + return this.decoder.end(); + }; +}); + +var __moduleExports$74 = createCommonjsModule(function (module) { + "use strict"; + + // Export Node.js internal encodings. + + module.exports = { + // Encodings + utf8: { type: "_internal", bomAware: true }, + cesu8: { type: "_internal", bomAware: true }, + unicode11utf8: "utf8", + + ucs2: { type: "_internal", bomAware: true }, + utf16le: "ucs2", + + binary: { type: "_internal" }, + base64: { type: "_internal" }, + hex: { type: "_internal" }, + + // Codec. + _internal: InternalCodec + }; + + //------------------------------------------------------------------------------ + + function InternalCodec(codecOptions, iconv) { + this.enc = codecOptions.encodingName; + this.bomAware = codecOptions.bomAware; + + if (this.enc === "base64") this.encoder = InternalEncoderBase64;else if (this.enc === "cesu8") { + this.enc = "utf8"; // Use utf8 for decoding. + this.encoder = InternalEncoderCesu8; + + // Add decoder for versions of Node not supporting CESU-8 + if (new Buffer("eda080", 'hex').toString().length == 3) { + this.decoder = InternalDecoderCesu8; + this.defaultCharUnicode = iconv.defaultCharUnicode; + } + } + } + + InternalCodec.prototype.encoder = InternalEncoder; + InternalCodec.prototype.decoder = InternalDecoder; + + //------------------------------------------------------------------------------ + + // We use node.js internal decoder. Its signature is the same as ours. + var StringDecoder = string_decoder.StringDecoder; + + if (!StringDecoder.prototype.end) // Node v0.8 doesn't have this method. + StringDecoder.prototype.end = function () {}; + + function InternalDecoder(options, codec) { + StringDecoder.call(this, codec.enc); + } + + InternalDecoder.prototype = StringDecoder.prototype; + + //------------------------------------------------------------------------------ + // Encoder is mostly trivial + + function InternalEncoder(options, codec) { + this.enc = codec.enc; + } + + InternalEncoder.prototype.write = function (str) { + return new Buffer(str, this.enc); + }; + + InternalEncoder.prototype.end = function () {}; + + //------------------------------------------------------------------------------ + // Except base64 encoder, which must keep its state. + + function InternalEncoderBase64(options, codec) { + this.prevStr = ''; + } + + InternalEncoderBase64.prototype.write = function (str) { + str = this.prevStr + str; + var completeQuads = str.length - str.length % 4; + this.prevStr = str.slice(completeQuads); + str = str.slice(0, completeQuads); + + return new Buffer(str, "base64"); + }; + + InternalEncoderBase64.prototype.end = function () { + return new Buffer(this.prevStr, "base64"); + }; + + //------------------------------------------------------------------------------ + // CESU-8 encoder is also special. + + function InternalEncoderCesu8(options, codec) {} + + InternalEncoderCesu8.prototype.write = function (str) { + var buf = new Buffer(str.length * 3), + bufIdx = 0; + for (var i = 0; i < str.length; i++) { + var charCode = str.charCodeAt(i); + // Naive implementation, but it works because CESU-8 is especially easy + // to convert from UTF-16 (which all JS strings are encoded in). + if (charCode < 0x80) buf[bufIdx++] = charCode;else if (charCode < 0x800) { + buf[bufIdx++] = 0xC0 + (charCode >>> 6); + buf[bufIdx++] = 0x80 + (charCode & 0x3f); + } else { + // charCode will always be < 0x10000 in javascript. + buf[bufIdx++] = 0xE0 + (charCode >>> 12); + buf[bufIdx++] = 0x80 + (charCode >>> 6 & 0x3f); + buf[bufIdx++] = 0x80 + (charCode & 0x3f); + } + } + return buf.slice(0, bufIdx); + }; + + InternalEncoderCesu8.prototype.end = function () {}; + + //------------------------------------------------------------------------------ + // CESU-8 decoder is not implemented in Node v4.0+ + + function InternalDecoderCesu8(options, codec) { + this.acc = 0; + this.contBytes = 0; + this.accBytes = 0; + this.defaultCharUnicode = codec.defaultCharUnicode; + } + + InternalDecoderCesu8.prototype.write = function (buf) { + var acc = this.acc, + contBytes = this.contBytes, + accBytes = this.accBytes, + res = ''; + for (var i = 0; i < buf.length; i++) { + var curByte = buf[i]; + if ((curByte & 0xC0) !== 0x80) { + // Leading byte + if (contBytes > 0) { + // Previous code is invalid + res += this.defaultCharUnicode; + contBytes = 0; + } + + if (curByte < 0x80) { + // Single-byte code + res += String.fromCharCode(curByte); + } else if (curByte < 0xE0) { + // Two-byte code + acc = curByte & 0x1F; + contBytes = 1;accBytes = 1; + } else if (curByte < 0xF0) { + // Three-byte code + acc = curByte & 0x0F; + contBytes = 2;accBytes = 1; + } else { + // Four or more are not supported for CESU-8. + res += this.defaultCharUnicode; + } + } else { + // Continuation byte + if (contBytes > 0) { + // We're waiting for it. + acc = acc << 6 | curByte & 0x3f; + contBytes--;accBytes++; + if (contBytes === 0) { + // Check for overlong encoding, but support Modified UTF-8 (encoding NULL as C0 80) + if (accBytes === 2 && acc < 0x80 && acc > 0) res += this.defaultCharUnicode;else if (accBytes === 3 && acc < 0x800) res += this.defaultCharUnicode;else + // Actually add character. + res += String.fromCharCode(acc); + } + } else { + // Unexpected continuation byte + res += this.defaultCharUnicode; + } + } + } + this.acc = acc;this.contBytes = contBytes;this.accBytes = accBytes; + return res; + }; + + InternalDecoderCesu8.prototype.end = function () { + var res = 0; + if (this.contBytes > 0) res += this.defaultCharUnicode; + return res; + }; +}); + +var __moduleExports$75 = createCommonjsModule(function (module, exports) { + "use strict"; + + // == UTF16-BE codec. ========================================================== + + exports.utf16be = Utf16BECodec; + function Utf16BECodec() {} + + Utf16BECodec.prototype.encoder = Utf16BEEncoder; + Utf16BECodec.prototype.decoder = Utf16BEDecoder; + Utf16BECodec.prototype.bomAware = true; + + // -- Encoding + + function Utf16BEEncoder() {} + + Utf16BEEncoder.prototype.write = function (str) { + var buf = new Buffer(str, 'ucs2'); + for (var i = 0; i < buf.length; i += 2) { + var tmp = buf[i];buf[i] = buf[i + 1];buf[i + 1] = tmp; + } + return buf; + }; + + Utf16BEEncoder.prototype.end = function () {}; + + // -- Decoding + + function Utf16BEDecoder() { + this.overflowByte = -1; + } + + Utf16BEDecoder.prototype.write = function (buf) { + if (buf.length == 0) return ''; + + var buf2 = new Buffer(buf.length + 1), + i = 0, + j = 0; + + if (this.overflowByte !== -1) { + buf2[0] = buf[0]; + buf2[1] = this.overflowByte; + i = 1;j = 2; + } + + for (; i < buf.length - 1; i += 2, j += 2) { + buf2[j] = buf[i + 1]; + buf2[j + 1] = buf[i]; + } + + this.overflowByte = i == buf.length - 1 ? buf[buf.length - 1] : -1; + + return buf2.slice(0, j).toString('ucs2'); + }; + + Utf16BEDecoder.prototype.end = function () {}; + + // == UTF-16 codec ============================================================= + // Decoder chooses automatically from UTF-16LE and UTF-16BE using BOM and space-based heuristic. + // Defaults to UTF-16LE, as it's prevalent and default in Node. + // http://en.wikipedia.org/wiki/UTF-16 and http://encoding.spec.whatwg.org/#utf-16le + // Decoder default can be changed: iconv.decode(buf, 'utf16', {defaultEncoding: 'utf-16be'}); + + // Encoder uses UTF-16LE and prepends BOM (which can be overridden with addBOM: false). + + exports.utf16 = Utf16Codec; + function Utf16Codec(codecOptions, iconv) { + this.iconv = iconv; + } + + Utf16Codec.prototype.encoder = Utf16Encoder; + Utf16Codec.prototype.decoder = Utf16Decoder; + + // -- Encoding (pass-through) + + function Utf16Encoder(options, codec) { + options = options || {}; + if (options.addBOM === undefined) options.addBOM = true; + this.encoder = codec.iconv.getEncoder('utf-16le', options); + } + + Utf16Encoder.prototype.write = function (str) { + return this.encoder.write(str); + }; + + Utf16Encoder.prototype.end = function () { + return this.encoder.end(); + }; + + // -- Decoding + + function Utf16Decoder(options, codec) { + this.decoder = null; + this.initialBytes = []; + this.initialBytesLen = 0; + + this.options = options || {}; + this.iconv = codec.iconv; + } + + Utf16Decoder.prototype.write = function (buf) { + if (!this.decoder) { + // Codec is not chosen yet. Accumulate initial bytes. + this.initialBytes.push(buf); + this.initialBytesLen += buf.length; + + if (this.initialBytesLen < 16) // We need more bytes to use space heuristic (see below) + return ''; + + // We have enough bytes -> detect endianness. + var buf = Buffer.concat(this.initialBytes), + encoding = detectEncoding(buf, this.options.defaultEncoding); + this.decoder = this.iconv.getDecoder(encoding, this.options); + this.initialBytes.length = this.initialBytesLen = 0; + } + + return this.decoder.write(buf); + }; + + Utf16Decoder.prototype.end = function () { + if (!this.decoder) { + var buf = Buffer.concat(this.initialBytes), + encoding = detectEncoding(buf, this.options.defaultEncoding); + this.decoder = this.iconv.getDecoder(encoding, this.options); + + var res = this.decoder.write(buf), + trail = this.decoder.end(); + + return trail ? res + trail : res; + } + return this.decoder.end(); + }; + + function detectEncoding(buf, defaultEncoding) { + var enc = defaultEncoding || 'utf-16le'; + + if (buf.length >= 2) { + // Check BOM. + if (buf[0] == 0xFE && buf[1] == 0xFF) // UTF-16BE BOM + enc = 'utf-16be';else if (buf[0] == 0xFF && buf[1] == 0xFE) // UTF-16LE BOM + enc = 'utf-16le';else { + // No BOM found. Try to deduce encoding from initial content. + // Most of the time, the content has ASCII chars (U+00**), but the opposite (U+**00) is uncommon. + // So, we count ASCII as if it was LE or BE, and decide from that. + var asciiCharsLE = 0, + asciiCharsBE = 0, + // Counts of chars in both positions + _len = Math.min(buf.length - buf.length % 2, 64); // Len is always even. + + for (var i = 0; i < _len; i += 2) { + if (buf[i] === 0 && buf[i + 1] !== 0) asciiCharsBE++; + if (buf[i] !== 0 && buf[i + 1] === 0) asciiCharsLE++; + } + + if (asciiCharsBE > asciiCharsLE) enc = 'utf-16be';else if (asciiCharsBE < asciiCharsLE) enc = 'utf-16le'; + } + } + + return enc; + } +}); + +var utf16$$1 = __moduleExports$75.utf16; + +var __moduleExports$76 = createCommonjsModule(function (module, exports) { + "use strict"; + + // UTF-7 codec, according to https://tools.ietf.org/html/rfc2152 + // See also below a UTF-7-IMAP codec, according to http://tools.ietf.org/html/rfc3501#section-5.1.3 + + exports.utf7 = Utf7Codec; + exports.unicode11utf7 = 'utf7'; // Alias UNICODE-1-1-UTF-7 + function Utf7Codec(codecOptions, iconv) { + this.iconv = iconv; + }; + + Utf7Codec.prototype.encoder = Utf7Encoder; + Utf7Codec.prototype.decoder = Utf7Decoder; + Utf7Codec.prototype.bomAware = true; + + // -- Encoding + + var nonDirectChars = /[^A-Za-z0-9'\(\),-\.\/:\? \n\r\t]+/g; + + function Utf7Encoder(options, codec) { + this.iconv = codec.iconv; + } + + Utf7Encoder.prototype.write = function (str) { + // Naive implementation. + // Non-direct chars are encoded as "+-"; single "+" char is encoded as "+-". + return new Buffer(str.replace(nonDirectChars, function (chunk) { + return "+" + (chunk === '+' ? '' : this.iconv.encode(chunk, 'utf16-be').toString('base64').replace(/=+$/, '')) + "-"; + }.bind(this))); + }; + + Utf7Encoder.prototype.end = function () {}; + + // -- Decoding + + function Utf7Decoder(options, codec) { + this.iconv = codec.iconv; + this.inBase64 = false; + this.base64Accum = ''; + } + + var base64Regex = /[A-Za-z0-9\/+]/; + var base64Chars = []; + for (var i = 0; i < 256; i++) { + base64Chars[i] = base64Regex.test(String.fromCharCode(i)); + }var plusChar = '+'.charCodeAt(0), + minusChar = '-'.charCodeAt(0), + andChar = '&'.charCodeAt(0); + + Utf7Decoder.prototype.write = function (buf) { + var res = "", + lastI = 0, + inBase64 = this.inBase64, + base64Accum = this.base64Accum; + + // The decoder is more involved as we must handle chunks in stream. + + for (var i = 0; i < buf.length; i++) { + if (!inBase64) { + // We're in direct mode. + // Write direct chars until '+' + if (buf[i] == plusChar) { + res += this.iconv.decode(buf.slice(lastI, i), "ascii"); // Write direct chars. + lastI = i + 1; + inBase64 = true; + } + } else { + // We decode base64. + if (!base64Chars[buf[i]]) { + // Base64 ended. + if (i == lastI && buf[i] == minusChar) { + // "+-" -> "+" + res += "+"; + } else { + var b64str = base64Accum + buf.slice(lastI, i).toString(); + res += this.iconv.decode(new Buffer(b64str, 'base64'), "utf16-be"); + } + + if (buf[i] != minusChar) // Minus is absorbed after base64. + i--; + + lastI = i + 1; + inBase64 = false; + base64Accum = ''; + } + } + } + + if (!inBase64) { + res += this.iconv.decode(buf.slice(lastI), "ascii"); // Write direct chars. + } else { + var b64str = base64Accum + buf.slice(lastI).toString(); + + var canBeDecoded = b64str.length - b64str.length % 8; // Minimal chunk: 2 quads -> 2x3 bytes -> 3 chars. + base64Accum = b64str.slice(canBeDecoded); // The rest will be decoded in future. + b64str = b64str.slice(0, canBeDecoded); + + res += this.iconv.decode(new Buffer(b64str, 'base64'), "utf16-be"); + } + + this.inBase64 = inBase64; + this.base64Accum = base64Accum; + + return res; + }; + + Utf7Decoder.prototype.end = function () { + var res = ""; + if (this.inBase64 && this.base64Accum.length > 0) res = this.iconv.decode(new Buffer(this.base64Accum, 'base64'), "utf16-be"); + + this.inBase64 = false; + this.base64Accum = ''; + return res; + }; + + // UTF-7-IMAP codec. + // RFC3501 Sec. 5.1.3 Modified UTF-7 (http://tools.ietf.org/html/rfc3501#section-5.1.3) + // Differences: + // * Base64 part is started by "&" instead of "+" + // * Direct characters are 0x20-0x7E, except "&" (0x26) + // * In Base64, "," is used instead of "/" + // * Base64 must not be used to represent direct characters. + // * No implicit shift back from Base64 (should always end with '-') + // * String must end in non-shifted position. + // * "-&" while in base64 is not allowed. + + + exports.utf7imap = Utf7IMAPCodec; + function Utf7IMAPCodec(codecOptions, iconv) { + this.iconv = iconv; + }; + + Utf7IMAPCodec.prototype.encoder = Utf7IMAPEncoder; + Utf7IMAPCodec.prototype.decoder = Utf7IMAPDecoder; + Utf7IMAPCodec.prototype.bomAware = true; + + // -- Encoding + + function Utf7IMAPEncoder(options, codec) { + this.iconv = codec.iconv; + this.inBase64 = false; + this.base64Accum = new Buffer(6); + this.base64AccumIdx = 0; + } + + Utf7IMAPEncoder.prototype.write = function (str) { + var inBase64 = this.inBase64, + base64Accum = this.base64Accum, + base64AccumIdx = this.base64AccumIdx, + buf = new Buffer(str.length * 5 + 10), + bufIdx = 0; + + for (var i = 0; i < str.length; i++) { + var uChar = str.charCodeAt(i); + if (0x20 <= uChar && uChar <= 0x7E) { + // Direct character or '&'. + if (inBase64) { + if (base64AccumIdx > 0) { + bufIdx += buf.write(base64Accum.slice(0, base64AccumIdx).toString('base64').replace(/\//g, ',').replace(/=+$/, ''), bufIdx); + base64AccumIdx = 0; + } + + buf[bufIdx++] = minusChar; // Write '-', then go to direct mode. + inBase64 = false; + } + + if (!inBase64) { + buf[bufIdx++] = uChar; // Write direct character + + if (uChar === andChar) // Ampersand -> '&-' + buf[bufIdx++] = minusChar; + } + } else { + // Non-direct character + if (!inBase64) { + buf[bufIdx++] = andChar; // Write '&', then go to base64 mode. + inBase64 = true; + } + if (inBase64) { + base64Accum[base64AccumIdx++] = uChar >> 8; + base64Accum[base64AccumIdx++] = uChar & 0xFF; + + if (base64AccumIdx == base64Accum.length) { + bufIdx += buf.write(base64Accum.toString('base64').replace(/\//g, ','), bufIdx); + base64AccumIdx = 0; + } + } + } + } + + this.inBase64 = inBase64; + this.base64AccumIdx = base64AccumIdx; + + return buf.slice(0, bufIdx); + }; + + Utf7IMAPEncoder.prototype.end = function () { + var buf = new Buffer(10), + bufIdx = 0; + if (this.inBase64) { + if (this.base64AccumIdx > 0) { + bufIdx += buf.write(this.base64Accum.slice(0, this.base64AccumIdx).toString('base64').replace(/\//g, ',').replace(/=+$/, ''), bufIdx); + this.base64AccumIdx = 0; + } + + buf[bufIdx++] = minusChar; // Write '-', then go to direct mode. + this.inBase64 = false; + } + + return buf.slice(0, bufIdx); + }; + + // -- Decoding + + function Utf7IMAPDecoder(options, codec) { + this.iconv = codec.iconv; + this.inBase64 = false; + this.base64Accum = ''; + } + + var base64IMAPChars = base64Chars.slice(); + base64IMAPChars[','.charCodeAt(0)] = true; + + Utf7IMAPDecoder.prototype.write = function (buf) { + var res = "", + lastI = 0, + inBase64 = this.inBase64, + base64Accum = this.base64Accum; + + // The decoder is more involved as we must handle chunks in stream. + // It is forgiving, closer to standard UTF-7 (for example, '-' is optional at the end). + + for (var i = 0; i < buf.length; i++) { + if (!inBase64) { + // We're in direct mode. + // Write direct chars until '&' + if (buf[i] == andChar) { + res += this.iconv.decode(buf.slice(lastI, i), "ascii"); // Write direct chars. + lastI = i + 1; + inBase64 = true; + } + } else { + // We decode base64. + if (!base64IMAPChars[buf[i]]) { + // Base64 ended. + if (i == lastI && buf[i] == minusChar) { + // "&-" -> "&" + res += "&"; + } else { + var b64str = base64Accum + buf.slice(lastI, i).toString().replace(/,/g, '/'); + res += this.iconv.decode(new Buffer(b64str, 'base64'), "utf16-be"); + } + + if (buf[i] != minusChar) // Minus may be absorbed after base64. + i--; + + lastI = i + 1; + inBase64 = false; + base64Accum = ''; + } + } + } + + if (!inBase64) { + res += this.iconv.decode(buf.slice(lastI), "ascii"); // Write direct chars. + } else { + var b64str = base64Accum + buf.slice(lastI).toString().replace(/,/g, '/'); + + var canBeDecoded = b64str.length - b64str.length % 8; // Minimal chunk: 2 quads -> 2x3 bytes -> 3 chars. + base64Accum = b64str.slice(canBeDecoded); // The rest will be decoded in future. + b64str = b64str.slice(0, canBeDecoded); + + res += this.iconv.decode(new Buffer(b64str, 'base64'), "utf16-be"); + } + + this.inBase64 = inBase64; + this.base64Accum = base64Accum; + + return res; + }; + + Utf7IMAPDecoder.prototype.end = function () { + var res = ""; + if (this.inBase64 && this.base64Accum.length > 0) res = this.iconv.decode(new Buffer(this.base64Accum, 'base64'), "utf16-be"); + + this.inBase64 = false; + this.base64Accum = ''; + return res; + }; +}); + +var utf7$$1 = __moduleExports$76.utf7; + +var __moduleExports$77 = createCommonjsModule(function (module, exports) { + "use strict"; + + // Single-byte codec. Needs a 'chars' string parameter that contains 256 or 128 chars that + // correspond to encoded bytes (if 128 - then lower half is ASCII). + + exports._sbcs = SBCSCodec; + function SBCSCodec(codecOptions, iconv) { + if (!codecOptions) throw new Error("SBCS codec is called without the data."); + + // Prepare char buffer for decoding. + if (!codecOptions.chars || codecOptions.chars.length !== 128 && codecOptions.chars.length !== 256) throw new Error("Encoding '" + codecOptions.type + "' has incorrect 'chars' (must be of len 128 or 256)"); + + if (codecOptions.chars.length === 128) { + var asciiString = ""; + for (var i = 0; i < 128; i++) { + asciiString += String.fromCharCode(i); + }codecOptions.chars = asciiString + codecOptions.chars; + } + + this.decodeBuf = new Buffer(codecOptions.chars, 'ucs2'); + + // Encoding buffer. + var encodeBuf = new Buffer(65536); + encodeBuf.fill(iconv.defaultCharSingleByte.charCodeAt(0)); + + for (var i = 0; i < codecOptions.chars.length; i++) { + encodeBuf[codecOptions.chars.charCodeAt(i)] = i; + }this.encodeBuf = encodeBuf; + } + + SBCSCodec.prototype.encoder = SBCSEncoder; + SBCSCodec.prototype.decoder = SBCSDecoder; + + function SBCSEncoder(options, codec) { + this.encodeBuf = codec.encodeBuf; + } + + SBCSEncoder.prototype.write = function (str) { + var buf = new Buffer(str.length); + for (var i = 0; i < str.length; i++) { + buf[i] = this.encodeBuf[str.charCodeAt(i)]; + }return buf; + }; + + SBCSEncoder.prototype.end = function () {}; + + function SBCSDecoder(options, codec) { + this.decodeBuf = codec.decodeBuf; + } + + SBCSDecoder.prototype.write = function (buf) { + // Strings are immutable in JS -> we use ucs2 buffer to speed up computations. + var decodeBuf = this.decodeBuf; + var newBuf = new Buffer(buf.length * 2); + var idx1 = 0, + idx2 = 0; + for (var i = 0; i < buf.length; i++) { + idx1 = buf[i] * 2;idx2 = i * 2; + newBuf[idx2] = decodeBuf[idx1]; + newBuf[idx2 + 1] = decodeBuf[idx1 + 1]; + } + return newBuf.toString('ucs2'); + }; + + SBCSDecoder.prototype.end = function () {}; +}); + +var __moduleExports$78 = createCommonjsModule(function (module) { + "use strict"; + + // Manually added data to be used by sbcs codec in addition to generated one. + + module.exports = { + // Not supported by iconv, not sure why. + "10029": "maccenteuro", + "maccenteuro": { + "type": "_sbcs", + "chars": "ÄĀāÉĄÖÜáąČäčĆć鏟ĎíďĒēĖóėôöõúĚěü†°Ę£§•¶ß®©™ę¨≠ģĮįĪ≤≥īĶ∂∑łĻļĽľĹĺŅņѬ√ńŇ∆«»… ňŐÕőŌ–—“”‘’÷◊ōŔŕŘ‹›řŖŗŠ‚„šŚśÁŤťÍŽžŪÓÔūŮÚůŰűŲųÝýķŻŁżĢˇ" + }, + + "808": "cp808", + "ibm808": "cp808", + "cp808": { + "type": "_sbcs", + "chars": "АБВГДЕЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯабвгдежзийклмноп░▒▓│┤╡╢╖╕╣║╗╝╜╛┐└┴┬├─┼╞╟╚╔╩╦╠═╬╧╨╤╥╙╘╒╓╫╪┘┌█▄▌▐▀рстуфхцчшщъыьэюяЁёЄєЇїЎў°∙·√№€■ " + }, + + // Aliases of generated encodings. + "ascii8bit": "ascii", + "usascii": "ascii", + "ansix34": "ascii", + "ansix341968": "ascii", + "ansix341986": "ascii", + "csascii": "ascii", + "cp367": "ascii", + "ibm367": "ascii", + "isoir6": "ascii", + "iso646us": "ascii", + "iso646irv": "ascii", + "us": "ascii", + + "latin1": "iso88591", + "latin2": "iso88592", + "latin3": "iso88593", + "latin4": "iso88594", + "latin5": "iso88599", + "latin6": "iso885910", + "latin7": "iso885913", + "latin8": "iso885914", + "latin9": "iso885915", + "latin10": "iso885916", + + "csisolatin1": "iso88591", + "csisolatin2": "iso88592", + "csisolatin3": "iso88593", + "csisolatin4": "iso88594", + "csisolatincyrillic": "iso88595", + "csisolatinarabic": "iso88596", + "csisolatingreek": "iso88597", + "csisolatinhebrew": "iso88598", + "csisolatin5": "iso88599", + "csisolatin6": "iso885910", + + "l1": "iso88591", + "l2": "iso88592", + "l3": "iso88593", + "l4": "iso88594", + "l5": "iso88599", + "l6": "iso885910", + "l7": "iso885913", + "l8": "iso885914", + "l9": "iso885915", + "l10": "iso885916", + + "isoir14": "iso646jp", + "isoir57": "iso646cn", + "isoir100": "iso88591", + "isoir101": "iso88592", + "isoir109": "iso88593", + "isoir110": "iso88594", + "isoir144": "iso88595", + "isoir127": "iso88596", + "isoir126": "iso88597", + "isoir138": "iso88598", + "isoir148": "iso88599", + "isoir157": "iso885910", + "isoir166": "tis620", + "isoir179": "iso885913", + "isoir199": "iso885914", + "isoir203": "iso885915", + "isoir226": "iso885916", + + "cp819": "iso88591", + "ibm819": "iso88591", + + "cyrillic": "iso88595", + + "arabic": "iso88596", + "arabic8": "iso88596", + "ecma114": "iso88596", + "asmo708": "iso88596", + + "greek": "iso88597", + "greek8": "iso88597", + "ecma118": "iso88597", + "elot928": "iso88597", + + "hebrew": "iso88598", + "hebrew8": "iso88598", + + "turkish": "iso88599", + "turkish8": "iso88599", + + "thai": "iso885911", + "thai8": "iso885911", + + "celtic": "iso885914", + "celtic8": "iso885914", + "isoceltic": "iso885914", + + "tis6200": "tis620", + "tis62025291": "tis620", + "tis62025330": "tis620", + + "10000": "macroman", + "10006": "macgreek", + "10007": "maccyrillic", + "10079": "maciceland", + "10081": "macturkish", + + "cspc8codepage437": "cp437", + "cspc775baltic": "cp775", + "cspc850multilingual": "cp850", + "cspcp852": "cp852", + "cspc862latinhebrew": "cp862", + "cpgr": "cp869", + + "msee": "cp1250", + "mscyrl": "cp1251", + "msansi": "cp1252", + "msgreek": "cp1253", + "msturk": "cp1254", + "mshebr": "cp1255", + "msarab": "cp1256", + "winbaltrim": "cp1257", + + "cp20866": "koi8r", + "20866": "koi8r", + "ibm878": "koi8r", + "cskoi8r": "koi8r", + + "cp21866": "koi8u", + "21866": "koi8u", + "ibm1168": "koi8u", + + "strk10482002": "rk1048", + + "tcvn5712": "tcvn", + "tcvn57121": "tcvn", + + "gb198880": "iso646cn", + "cn": "iso646cn", + + "csiso14jisc6220ro": "iso646jp", + "jisc62201969ro": "iso646jp", + "jp": "iso646jp", + + "cshproman8": "hproman8", + "r8": "hproman8", + "roman8": "hproman8", + "xroman8": "hproman8", + "ibm1051": "hproman8", + + "mac": "macintosh", + "csmacintosh": "macintosh" + }; +}); + +var __moduleExports$79 = createCommonjsModule(function (module) { + "use strict"; + + // Generated data for sbcs codec. Don't edit manually. Regenerate using generation/gen-sbcs.js script. + + module.exports = { + "437": "cp437", + "737": "cp737", + "775": "cp775", + "850": "cp850", + "852": "cp852", + "855": "cp855", + "856": "cp856", + "857": "cp857", + "858": "cp858", + "860": "cp860", + "861": "cp861", + "862": "cp862", + "863": "cp863", + "864": "cp864", + "865": "cp865", + "866": "cp866", + "869": "cp869", + "874": "windows874", + "922": "cp922", + "1046": "cp1046", + "1124": "cp1124", + "1125": "cp1125", + "1129": "cp1129", + "1133": "cp1133", + "1161": "cp1161", + "1162": "cp1162", + "1163": "cp1163", + "1250": "windows1250", + "1251": "windows1251", + "1252": "windows1252", + "1253": "windows1253", + "1254": "windows1254", + "1255": "windows1255", + "1256": "windows1256", + "1257": "windows1257", + "1258": "windows1258", + "28591": "iso88591", + "28592": "iso88592", + "28593": "iso88593", + "28594": "iso88594", + "28595": "iso88595", + "28596": "iso88596", + "28597": "iso88597", + "28598": "iso88598", + "28599": "iso88599", + "28600": "iso885910", + "28601": "iso885911", + "28603": "iso885913", + "28604": "iso885914", + "28605": "iso885915", + "28606": "iso885916", + "windows874": { + "type": "_sbcs", + "chars": "€����…�����������‘’“”•–—�������� กขฃคฅฆงจฉชซฌญฎฏฐฑฒณดตถทธนบปผฝพฟภมยรฤลฦวศษสหฬอฮฯะัาำิีึืฺุู����฿เแโใไๅๆ็่้๊๋์ํ๎๏๐๑๒๓๔๕๖๗๘๙๚๛����" + }, + "win874": "windows874", + "cp874": "windows874", + "windows1250": { + "type": "_sbcs", + "chars": "€�‚�„…†‡�‰Š‹ŚŤŽŹ�‘’“”•–—�™š›śťžź ˇ˘Ł¤Ą¦§¨©Ş«¬­®Ż°±˛ł´µ¶·¸ąş»Ľ˝ľżŔÁÂĂÄĹĆÇČÉĘËĚÍÎĎĐŃŇÓÔŐÖ×ŘŮÚŰÜÝŢßŕáâăäĺćçčéęëěíîďđńňóôőö÷řůúűüýţ˙" + }, + "win1250": "windows1250", + "cp1250": "windows1250", + "windows1251": { + "type": "_sbcs", + "chars": "ЂЃ‚ѓ„…†‡€‰Љ‹ЊЌЋЏђ‘’“”•–—�™љ›њќћџ ЎўЈ¤Ґ¦§Ё©Є«¬­®Ї°±Ііґµ¶·ё№є»јЅѕїАБВГДЕЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯабвгдежзийклмнопрстуфхцчшщъыьэюя" + }, + "win1251": "windows1251", + "cp1251": "windows1251", + "windows1252": { + "type": "_sbcs", + "chars": "€�‚ƒ„…†‡ˆ‰Š‹Œ�Ž��‘’“”•–—˜™š›œ�žŸ ¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖ×ØÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ" + }, + "win1252": "windows1252", + "cp1252": "windows1252", + "windows1253": { + "type": "_sbcs", + "chars": "€�‚ƒ„…†‡�‰�‹�����‘’“”•–—�™�›���� ΅Ά£¤¥¦§¨©�«¬­®―°±²³΄µ¶·ΈΉΊ»Ό½ΎΏΐΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡ�ΣΤΥΦΧΨΩΪΫάέήίΰαβγδεζηθικλμνξοπρςστυφχψωϊϋόύώ�" + }, + "win1253": "windows1253", + "cp1253": "windows1253", + "windows1254": { + "type": "_sbcs", + "chars": "€�‚ƒ„…†‡ˆ‰Š‹Œ����‘’“”•–—˜™š›œ��Ÿ ¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏĞÑÒÓÔÕÖ×ØÙÚÛÜİŞßàáâãäåæçèéêëìíîïğñòóôõö÷øùúûüışÿ" + }, + "win1254": "windows1254", + "cp1254": "windows1254", + "windows1255": { + "type": "_sbcs", + "chars": "€�‚ƒ„…†‡ˆ‰�‹�����‘’“”•–—˜™�›���� ¡¢£₪¥¦§¨©×«¬­®¯°±²³´µ¶·¸¹÷»¼½¾¿ְֱֲֳִֵֶַָֹ�ֻּֽ־ֿ׀ׁׂ׃װױײ׳״�������אבגדהוזחטיךכלםמןנסעףפץצקרשת��‎‏�" + }, + "win1255": "windows1255", + "cp1255": "windows1255", + "windows1256": { + "type": "_sbcs", + "chars": "€پ‚ƒ„…†‡ˆ‰ٹ‹Œچژڈگ‘’“”•–—ک™ڑ›œ‌‍ں ،¢£¤¥¦§¨©ھ«¬­®¯°±²³´µ¶·¸¹؛»¼½¾؟ہءآأؤإئابةتثجحخدذرزسشصض×طظعغـفقكàلâمنهوçèéêëىيîïًٌٍَôُِ÷ّùْûü‎‏ے" + }, + "win1256": "windows1256", + "cp1256": "windows1256", + "windows1257": { + "type": "_sbcs", + "chars": "€�‚�„…†‡�‰�‹�¨ˇ¸�‘’“”•–—�™�›�¯˛� �¢£¤�¦§Ø©Ŗ«¬­®Æ°±²³´µ¶·ø¹ŗ»¼½¾æĄĮĀĆÄÅĘĒČÉŹĖĢĶĪĻŠŃŅÓŌÕÖ×ŲŁŚŪÜŻŽßąįāćäåęēčéźėģķīļšńņóōõö÷ųłśūüżž˙" + }, + "win1257": "windows1257", + "cp1257": "windows1257", + "windows1258": { + "type": "_sbcs", + "chars": "€�‚ƒ„…†‡ˆ‰�‹Œ����‘’“”•–—˜™�›œ��Ÿ ¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂĂÄÅÆÇÈÉÊË̀ÍÎÏĐÑ̉ÓÔƠÖ×ØÙÚÛÜỮßàáâăäåæçèéêë́íîïđṇ̃óôơö÷øùúûüư₫ÿ" + }, + "win1258": "windows1258", + "cp1258": "windows1258", + "iso88591": { + "type": "_sbcs", + "chars": "€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ ¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖ×ØÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ" + }, + "cp28591": "iso88591", + "iso88592": { + "type": "_sbcs", + "chars": "€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ Ą˘Ł¤ĽŚ§¨ŠŞŤŹ­ŽŻ°ą˛ł´ľśˇ¸šşťź˝žżŔÁÂĂÄĹĆÇČÉĘËĚÍÎĎĐŃŇÓÔŐÖ×ŘŮÚŰÜÝŢßŕáâăäĺćçčéęëěíîďđńňóôőö÷řůúűüýţ˙" + }, + "cp28592": "iso88592", + "iso88593": { + "type": "_sbcs", + "chars": "€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ Ħ˘£¤�Ĥ§¨İŞĞĴ­�Ż°ħ²³´µĥ·¸ışğĵ½�żÀÁÂ�ÄĊĈÇÈÉÊËÌÍÎÏ�ÑÒÓÔĠÖ×ĜÙÚÛÜŬŜßàáâ�äċĉçèéêëìíîï�ñòóôġö÷ĝùúûüŭŝ˙" + }, + "cp28593": "iso88593", + "iso88594": { + "type": "_sbcs", + "chars": "€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ ĄĸŖ¤ĨĻ§¨ŠĒĢŦ­Ž¯°ą˛ŗ´ĩļˇ¸šēģŧŊžŋĀÁÂÃÄÅÆĮČÉĘËĖÍÎĪĐŅŌĶÔÕÖ×ØŲÚÛÜŨŪßāáâãäåæįčéęëėíîīđņōķôõö÷øųúûüũū˙" + }, + "cp28594": "iso88594", + "iso88595": { + "type": "_sbcs", + "chars": "€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ ЁЂЃЄЅІЇЈЉЊЋЌ­ЎЏАБВГДЕЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯабвгдежзийклмнопрстуфхцчшщъыьэюя№ёђѓєѕіїјљњћќ§ўџ" + }, + "cp28595": "iso88595", + "iso88596": { + "type": "_sbcs", + "chars": "€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ ���¤�������،­�������������؛���؟�ءآأؤإئابةتثجحخدذرزسشصضطظعغ�����ـفقكلمنهوىيًٌٍَُِّْ�������������" + }, + "cp28596": "iso88596", + "iso88597": { + "type": "_sbcs", + "chars": "€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ ‘’£€₯¦§¨©ͺ«¬­�―°±²³΄΅Ά·ΈΉΊ»Ό½ΎΏΐΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡ�ΣΤΥΦΧΨΩΪΫάέήίΰαβγδεζηθικλμνξοπρςστυφχψωϊϋόύώ�" + }, + "cp28597": "iso88597", + "iso88598": { + "type": "_sbcs", + "chars": "€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ �¢£¤¥¦§¨©×«¬­®¯°±²³´µ¶·¸¹÷»¼½¾��������������������������������‗אבגדהוזחטיךכלםמןנסעףפץצקרשת��‎‏�" + }, + "cp28598": "iso88598", + "iso88599": { + "type": "_sbcs", + "chars": "€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ ¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏĞÑÒÓÔÕÖ×ØÙÚÛÜİŞßàáâãäåæçèéêëìíîïğñòóôõö÷øùúûüışÿ" + }, + "cp28599": "iso88599", + "iso885910": { + "type": "_sbcs", + "chars": "€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ ĄĒĢĪĨĶ§ĻĐŠŦŽ­ŪŊ°ąēģīĩķ·ļđšŧž―ūŋĀÁÂÃÄÅÆĮČÉĘËĖÍÎÏÐŅŌÓÔÕÖŨØŲÚÛÜÝÞßāáâãäåæįčéęëėíîïðņōóôõöũøųúûüýþĸ" + }, + "cp28600": "iso885910", + "iso885911": { + "type": "_sbcs", + "chars": "€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ กขฃคฅฆงจฉชซฌญฎฏฐฑฒณดตถทธนบปผฝพฟภมยรฤลฦวศษสหฬอฮฯะัาำิีึืฺุู����฿เแโใไๅๆ็่้๊๋์ํ๎๏๐๑๒๓๔๕๖๗๘๙๚๛����" + }, + "cp28601": "iso885911", + "iso885913": { + "type": "_sbcs", + "chars": "€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ ”¢£¤„¦§Ø©Ŗ«¬­®Æ°±²³“µ¶·ø¹ŗ»¼½¾æĄĮĀĆÄÅĘĒČÉŹĖĢĶĪĻŠŃŅÓŌÕÖ×ŲŁŚŪÜŻŽßąįāćäåęēčéźėģķīļšńņóōõö÷ųłśūüżž’" + }, + "cp28603": "iso885913", + "iso885914": { + "type": "_sbcs", + "chars": "€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ Ḃḃ£ĊċḊ§Ẁ©ẂḋỲ­®ŸḞḟĠġṀṁ¶ṖẁṗẃṠỳẄẅṡÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏŴÑÒÓÔÕÖṪØÙÚÛÜÝŶßàáâãäåæçèéêëìíîïŵñòóôõöṫøùúûüýŷÿ" + }, + "cp28604": "iso885914", + "iso885915": { + "type": "_sbcs", + "chars": "€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ ¡¢£€¥Š§š©ª«¬­®¯°±²³Žµ¶·ž¹º»ŒœŸ¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖ×ØÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ" + }, + "cp28605": "iso885915", + "iso885916": { + "type": "_sbcs", + "chars": "€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ ĄąŁ€„Š§š©Ș«Ź­źŻ°±ČłŽ”¶·žčș»ŒœŸżÀÁÂĂÄĆÆÇÈÉÊËÌÍÎÏĐŃÒÓÔŐÖŚŰÙÚÛÜĘȚßàáâăäćæçèéêëìíîïđńòóôőöśűùúûüęțÿ" + }, + "cp28606": "iso885916", + "cp437": { + "type": "_sbcs", + "chars": "ÇüéâäàåçêëèïîìÄÅÉæÆôöòûùÿÖÜ¢£¥₧ƒáíóúñѪº¿⌐¬½¼¡«»░▒▓│┤╡╢╖╕╣║╗╝╜╛┐└┴┬├─┼╞╟╚╔╩╦╠═╬╧╨╤╥╙╘╒╓╫╪┘┌█▄▌▐▀αßΓπΣσµτΦΘΩδ∞φε∩≡±≥≤⌠⌡÷≈°∙·√ⁿ²■ " + }, + "ibm437": "cp437", + "csibm437": "cp437", + "cp737": { + "type": "_sbcs", + "chars": "ΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡΣΤΥΦΧΨΩαβγδεζηθικλμνξοπρσςτυφχψ░▒▓│┤╡╢╖╕╣║╗╝╜╛┐└┴┬├─┼╞╟╚╔╩╦╠═╬╧╨╤╥╙╘╒╓╫╪┘┌█▄▌▐▀ωάέήϊίόύϋώΆΈΉΊΌΎΏ±≥≤ΪΫ÷≈°∙·√ⁿ²■ " + }, + "ibm737": "cp737", + "csibm737": "cp737", + "cp775": { + "type": "_sbcs", + "chars": "ĆüéāäģåćłēŖŗīŹÄÅÉæÆōöĢ¢ŚśÖÜø£ØפĀĪóŻżź”¦©®¬½¼Ł«»░▒▓│┤ĄČĘĖ╣║╗╝ĮŠ┐└┴┬├─┼ŲŪ╚╔╩╦╠═╬Žąčęėįšųūž┘┌█▄▌▐▀ÓßŌŃõÕµńĶķĻļņĒŅ’­±“¾¶§÷„°∙·¹³²■ " + }, + "ibm775": "cp775", + "csibm775": "cp775", + "cp850": { + "type": "_sbcs", + "chars": "ÇüéâäàåçêëèïîìÄÅÉæÆôöòûùÿÖÜø£Ø׃áíóúñѪº¿®¬½¼¡«»░▒▓│┤ÁÂÀ©╣║╗╝¢¥┐└┴┬├─┼ãÃ╚╔╩╦╠═╬¤ðÐÊËÈıÍÎÏ┘┌█▄¦Ì▀ÓßÔÒõÕµþÞÚÛÙýݯ´­±‗¾¶§÷¸°¨·¹³²■ " + }, + "ibm850": "cp850", + "csibm850": "cp850", + "cp852": { + "type": "_sbcs", + "chars": "ÇüéâäůćçłëŐőîŹÄĆÉĹĺôöĽľŚśÖÜŤťŁ×čáíóúĄąŽžĘ꬟Ⱥ«»░▒▓│┤ÁÂĚŞ╣║╗╝Żż┐└┴┬├─┼Ăă╚╔╩╦╠═╬¤đĐĎËďŇÍÎě┘┌█▄ŢŮ▀ÓßÔŃńňŠšŔÚŕŰýÝţ´­˝˛ˇ˘§÷¸°¨˙űŘř■ " + }, + "ibm852": "cp852", + "csibm852": "cp852", + "cp855": { + "type": "_sbcs", + "chars": "ђЂѓЃёЁєЄѕЅіІїЇјЈљЉњЊћЋќЌўЎџЏюЮъЪаАбБцЦдДеЕфФгГ«»░▒▓│┤хХиИ╣║╗╝йЙ┐└┴┬├─┼кК╚╔╩╦╠═╬¤лЛмМнНоОп┘┌█▄Пя▀ЯрРсСтТуУжЖвВьЬ№­ыЫзЗшШэЭщЩчЧ§■ " + }, + "ibm855": "cp855", + "csibm855": "cp855", + "cp856": { + "type": "_sbcs", + "chars": "אבגדהוזחטיךכלםמןנסעףפץצקרשת�£�×����������®¬½¼�«»░▒▓│┤���©╣║╗╝¢¥┐└┴┬├─┼��╚╔╩╦╠═╬¤���������┘┌█▄¦�▀������µ�������¯´­±‗¾¶§÷¸°¨·¹³²■ " + }, + "ibm856": "cp856", + "csibm856": "cp856", + "cp857": { + "type": "_sbcs", + "chars": "ÇüéâäàåçêëèïîıÄÅÉæÆôöòûùİÖÜø£ØŞşáíóúñÑĞ𿮬½¼¡«»░▒▓│┤ÁÂÀ©╣║╗╝¢¥┐└┴┬├─┼ãÃ╚╔╩╦╠═╬¤ºªÊËÈ�ÍÎÏ┘┌█▄¦Ì▀ÓßÔÒõÕµ�×ÚÛÙìÿ¯´­±�¾¶§÷¸°¨·¹³²■ " + }, + "ibm857": "cp857", + "csibm857": "cp857", + "cp858": { + "type": "_sbcs", + "chars": "ÇüéâäàåçêëèïîìÄÅÉæÆôöòûùÿÖÜø£Ø׃áíóúñѪº¿®¬½¼¡«»░▒▓│┤ÁÂÀ©╣║╗╝¢¥┐└┴┬├─┼ãÃ╚╔╩╦╠═╬¤ðÐÊËÈ€ÍÎÏ┘┌█▄¦Ì▀ÓßÔÒõÕµþÞÚÛÙýݯ´­±‗¾¶§÷¸°¨·¹³²■ " + }, + "ibm858": "cp858", + "csibm858": "cp858", + "cp860": { + "type": "_sbcs", + "chars": "ÇüéâãàÁçêÊèÍÔìÃÂÉÀÈôõòÚùÌÕÜ¢£Ù₧ÓáíóúñѪº¿Ò¬½¼¡«»░▒▓│┤╡╢╖╕╣║╗╝╜╛┐└┴┬├─┼╞╟╚╔╩╦╠═╬╧╨╤╥╙╘╒╓╫╪┘┌█▄▌▐▀αßΓπΣσµτΦΘΩδ∞φε∩≡±≥≤⌠⌡÷≈°∙·√ⁿ²■ " + }, + "ibm860": "cp860", + "csibm860": "cp860", + "cp861": { + "type": "_sbcs", + "chars": "ÇüéâäàåçêëèÐðÞÄÅÉæÆôöþûÝýÖÜø£Ø₧ƒáíóúÁÍÓÚ¿⌐¬½¼¡«»░▒▓│┤╡╢╖╕╣║╗╝╜╛┐└┴┬├─┼╞╟╚╔╩╦╠═╬╧╨╤╥╙╘╒╓╫╪┘┌█▄▌▐▀αßΓπΣσµτΦΘΩδ∞φε∩≡±≥≤⌠⌡÷≈°∙·√ⁿ²■ " + }, + "ibm861": "cp861", + "csibm861": "cp861", + "cp862": { + "type": "_sbcs", + "chars": "אבגדהוזחטיךכלםמןנסעףפץצקרשת¢£¥₧ƒáíóúñѪº¿⌐¬½¼¡«»░▒▓│┤╡╢╖╕╣║╗╝╜╛┐└┴┬├─┼╞╟╚╔╩╦╠═╬╧╨╤╥╙╘╒╓╫╪┘┌█▄▌▐▀αßΓπΣσµτΦΘΩδ∞φε∩≡±≥≤⌠⌡÷≈°∙·√ⁿ²■ " + }, + "ibm862": "cp862", + "csibm862": "cp862", + "cp863": { + "type": "_sbcs", + "chars": "ÇüéâÂà¶çêëèïî‗À§ÉÈÊôËÏûù¤ÔÜ¢£ÙÛƒ¦´óú¨¸³¯Î⌐¬½¼¾«»░▒▓│┤╡╢╖╕╣║╗╝╜╛┐└┴┬├─┼╞╟╚╔╩╦╠═╬╧╨╤╥╙╘╒╓╫╪┘┌█▄▌▐▀αßΓπΣσµτΦΘΩδ∞φε∩≡±≥≤⌠⌡÷≈°∙·√ⁿ²■ " + }, + "ibm863": "cp863", + "csibm863": "cp863", + "cp864": { + "type": "_sbcs", + "chars": "\0\x01\x02\x03\x04\x05\x06\x07\b\t\n\x0B\f\r\x0E\x0F\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1A\x1B\x1C\x1D\x1E\x1F !\"#$\u066A&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\x7F\xB0\xB7\u2219\u221A\u2592\u2500\u2502\u253C\u2524\u252C\u251C\u2534\u2510\u250C\u2514\u2518\u03B2\u221E\u03C6\xB1\xBD\xBC\u2248\xAB\xBB\uFEF7\uFEF8\uFFFD\uFFFD\uFEFB\uFEFC\uFFFD\xA0\xAD\uFE82\xA3\xA4\uFE84\uFFFD\uFFFD\uFE8E\uFE8F\uFE95\uFE99\u060C\uFE9D\uFEA1\uFEA5\u0660\u0661\u0662\u0663\u0664\u0665\u0666\u0667\u0668\u0669\uFED1\u061B\uFEB1\uFEB5\uFEB9\u061F\xA2\uFE80\uFE81\uFE83\uFE85\uFECA\uFE8B\uFE8D\uFE91\uFE93\uFE97\uFE9B\uFE9F\uFEA3\uFEA7\uFEA9\uFEAB\uFEAD\uFEAF\uFEB3\uFEB7\uFEBB\uFEBF\uFEC1\uFEC5\uFECB\uFECF\xA6\xAC\xF7\xD7\uFEC9\u0640\uFED3\uFED7\uFEDB\uFEDF\uFEE3\uFEE7\uFEEB\uFEED\uFEEF\uFEF3\uFEBD\uFECC\uFECE\uFECD\uFEE1\uFE7D\u0651\uFEE5\uFEE9\uFEEC\uFEF0\uFEF2\uFED0\uFED5\uFEF5\uFEF6\uFEDD\uFED9\uFEF1\u25A0\uFFFD" + }, + "ibm864": "cp864", + "csibm864": "cp864", + "cp865": { + "type": "_sbcs", + "chars": "ÇüéâäàåçêëèïîìÄÅÉæÆôöòûùÿÖÜø£Ø₧ƒáíóúñѪº¿⌐¬½¼¡«¤░▒▓│┤╡╢╖╕╣║╗╝╜╛┐└┴┬├─┼╞╟╚╔╩╦╠═╬╧╨╤╥╙╘╒╓╫╪┘┌█▄▌▐▀αßΓπΣσµτΦΘΩδ∞φε∩≡±≥≤⌠⌡÷≈°∙·√ⁿ²■ " + }, + "ibm865": "cp865", + "csibm865": "cp865", + "cp866": { + "type": "_sbcs", + "chars": "АБВГДЕЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯабвгдежзийклмноп░▒▓│┤╡╢╖╕╣║╗╝╜╛┐└┴┬├─┼╞╟╚╔╩╦╠═╬╧╨╤╥╙╘╒╓╫╪┘┌█▄▌▐▀рстуфхцчшщъыьэюяЁёЄєЇїЎў°∙·√№¤■ " + }, + "ibm866": "cp866", + "csibm866": "cp866", + "cp869": { + "type": "_sbcs", + "chars": "������Ά�·¬¦‘’Έ―ΉΊΪΌ��ΎΫ©Ώ²³ά£έήίϊΐόύΑΒΓΔΕΖΗ½ΘΙ«»░▒▓│┤ΚΛΜΝ╣║╗╝ΞΟ┐└┴┬├─┼ΠΡ╚╔╩╦╠═╬ΣΤΥΦΧΨΩαβγ┘┌█▄δε▀ζηθικλμνξοπρσςτ΄­±υφχ§ψ΅°¨ωϋΰώ■ " + }, + "ibm869": "cp869", + "csibm869": "cp869", + "cp922": { + "type": "_sbcs", + "chars": "€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ ¡¢£¤¥¦§¨©ª«¬­®‾°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏŠÑÒÓÔÕÖ×ØÙÚÛÜÝŽßàáâãäåæçèéêëìíîïšñòóôõö÷øùúûüýžÿ" + }, + "ibm922": "cp922", + "csibm922": "cp922", + "cp1046": { + "type": "_sbcs", + "chars": "ﺈ×÷ﹱˆ■│─┐┌└┘ﹹﹻﹽﹿﹷﺊﻰﻳﻲﻎﻏﻐﻶﻸﻺﻼ ¤ﺋﺑﺗﺛﺟﺣ،­ﺧﺳ٠١٢٣٤٥٦٧٨٩ﺷ؛ﺻﺿﻊ؟ﻋءآأؤإئابةتثجحخدذرزسشصضطﻇعغﻌﺂﺄﺎﻓـفقكلمنهوىيًٌٍَُِّْﻗﻛﻟﻵﻷﻹﻻﻣﻧﻬﻩ�" + }, + "ibm1046": "cp1046", + "csibm1046": "cp1046", + "cp1124": { + "type": "_sbcs", + "chars": "€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ ЁЂҐЄЅІЇЈЉЊЋЌ­ЎЏАБВГДЕЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯабвгдежзийклмнопрстуфхцчшщъыьэюя№ёђґєѕіїјљњћќ§ўџ" + }, + "ibm1124": "cp1124", + "csibm1124": "cp1124", + "cp1125": { + "type": "_sbcs", + "chars": "АБВГДЕЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯабвгдежзийклмноп░▒▓│┤╡╢╖╕╣║╗╝╜╛┐└┴┬├─┼╞╟╚╔╩╦╠═╬╧╨╤╥╙╘╒╓╫╪┘┌█▄▌▐▀рстуфхцчшщъыьэюяЁёҐґЄєІіЇї·√№¤■ " + }, + "ibm1125": "cp1125", + "csibm1125": "cp1125", + "cp1129": { + "type": "_sbcs", + "chars": "€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ ¡¢£¤¥¦§œ©ª«¬­®¯°±²³Ÿµ¶·Œ¹º»¼½¾¿ÀÁÂĂÄÅÆÇÈÉÊË̀ÍÎÏĐÑ̉ÓÔƠÖ×ØÙÚÛÜỮßàáâăäåæçèéêë́íîïđṇ̃óôơö÷øùúûüư₫ÿ" + }, + "ibm1129": "cp1129", + "csibm1129": "cp1129", + "cp1133": { + "type": "_sbcs", + "chars": "€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ ກຂຄງຈສຊຍດຕຖທນບປຜຝພຟມຢຣລວຫອຮ���ຯະາຳິີຶືຸູຼັົຽ���ເແໂໃໄ່້໊໋໌ໍໆ�ໜໝ₭����������������໐໑໒໓໔໕໖໗໘໙��¢¬¦�" + }, + "ibm1133": "cp1133", + "csibm1133": "cp1133", + "cp1161": { + "type": "_sbcs", + "chars": "��������������������������������่กขฃคฅฆงจฉชซฌญฎฏฐฑฒณดตถทธนบปผฝพฟภมยรฤลฦวศษสหฬอฮฯะัาำิีึืฺุู้๊๋€฿เแโใไๅๆ็่้๊๋์ํ๎๏๐๑๒๓๔๕๖๗๘๙๚๛¢¬¦ " + }, + "ibm1161": "cp1161", + "csibm1161": "cp1161", + "cp1162": { + "type": "_sbcs", + "chars": "€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ กขฃคฅฆงจฉชซฌญฎฏฐฑฒณดตถทธนบปผฝพฟภมยรฤลฦวศษสหฬอฮฯะัาำิีึืฺุู����฿เแโใไๅๆ็่้๊๋์ํ๎๏๐๑๒๓๔๕๖๗๘๙๚๛����" + }, + "ibm1162": "cp1162", + "csibm1162": "cp1162", + "cp1163": { + "type": "_sbcs", + "chars": "€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ ¡¢£€¥¦§œ©ª«¬­®¯°±²³Ÿµ¶·Œ¹º»¼½¾¿ÀÁÂĂÄÅÆÇÈÉÊË̀ÍÎÏĐÑ̉ÓÔƠÖ×ØÙÚÛÜỮßàáâăäåæçèéêë́íîïđṇ̃óôơö÷øùúûüư₫ÿ" + }, + "ibm1163": "cp1163", + "csibm1163": "cp1163", + "maccroatian": { + "type": "_sbcs", + "chars": "ÄÅÇÉÑÖÜáàâäãåçéèêëíìîïñóòôöõúùûü†°¢£§•¶ß®Š™´¨≠ŽØ∞±≤≥∆µ∂∑∏š∫ªºΩžø¿¡¬√ƒ≈Ć«Č… ÀÃÕŒœĐ—“”‘’÷◊�©⁄¤‹›Æ»–·‚„‰ÂćÁčÈÍÎÏÌÓÔđÒÚÛÙıˆ˜¯πË˚¸Êæˇ" + }, + "maccyrillic": { + "type": "_sbcs", + "chars": "АБВГДЕЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯ†°¢£§•¶І®©™Ђђ≠Ѓѓ∞±≤≥іµ∂ЈЄєЇїЉљЊњјЅ¬√ƒ≈∆«»… ЋћЌќѕ–—“”‘’÷„ЎўЏџ№Ёёяабвгдежзийклмнопрстуфхцчшщъыьэю¤" + }, + "macgreek": { + "type": "_sbcs", + "chars": "Ĺ²É³ÖÜ΅àâä΄¨çéèê룙î‰ôö¦­ùûü†ΓΔΘΛΞΠß®©ΣΪ§≠°·Α±≤≥¥ΒΕΖΗΙΚΜΦΫΨΩάΝ¬ΟΡ≈Τ«»… ΥΧΆΈœ–―“”‘’÷ΉΊΌΎέήίόΏύαβψδεφγηιξκλμνοπώρστθωςχυζϊϋΐΰ�" + }, + "maciceland": { + "type": "_sbcs", + "chars": "ÄÅÇÉÑÖÜáàâäãåçéèêëíìîïñóòôöõúùûüÝ°¢£§•¶ß®©™´¨≠ÆØ∞±≤≥¥µ∂∑∏π∫ªºΩæø¿¡¬√ƒ≈∆«»… ÀÃÕŒœ–—“”‘’÷◊ÿŸ⁄¤ÐðÞþý·‚„‰ÂÊÁËÈÍÎÏÌÓÔ�ÒÚÛÙıˆ˜¯˘˙˚¸˝˛ˇ" + }, + "macroman": { + "type": "_sbcs", + "chars": "ÄÅÇÉÑÖÜáàâäãåçéèêëíìîïñóòôöõúùûü†°¢£§•¶ß®©™´¨≠ÆØ∞±≤≥¥µ∂∑∏π∫ªºΩæø¿¡¬√ƒ≈∆«»… ÀÃÕŒœ–—“”‘’÷◊ÿŸ⁄¤‹›fifl‡·‚„‰ÂÊÁËÈÍÎÏÌÓÔ�ÒÚÛÙıˆ˜¯˘˙˚¸˝˛ˇ" + }, + "macromania": { + "type": "_sbcs", + "chars": "ÄÅÇÉÑÖÜáàâäãåçéèêëíìîïñóòôöõúùûü†°¢£§•¶ß®©™´¨≠ĂŞ∞±≤≥¥µ∂∑∏π∫ªºΩăş¿¡¬√ƒ≈∆«»… ÀÃÕŒœ–—“”‘’÷◊ÿŸ⁄¤‹›Ţţ‡·‚„‰ÂÊÁËÈÍÎÏÌÓÔ�ÒÚÛÙıˆ˜¯˘˙˚¸˝˛ˇ" + }, + "macthai": { + "type": "_sbcs", + "chars": "«»…“”�•‘’� กขฃคฅฆงจฉชซฌญฎฏฐฑฒณดตถทธนบปผฝพฟภมยรฤลฦวศษสหฬอฮฯะัาำิีึืฺุู​–—฿เแโใไๅๆ็่้๊๋์ํ™๏๐๑๒๓๔๕๖๗๘๙®©����" + }, + "macturkish": { + "type": "_sbcs", + "chars": "ÄÅÇÉÑÖÜáàâäãåçéèêëíìîïñóòôöõúùûü†°¢£§•¶ß®©™´¨≠ÆØ∞±≤≥¥µ∂∑∏π∫ªºΩæø¿¡¬√ƒ≈∆«»… ÀÃÕŒœ–—“”‘’÷◊ÿŸĞğİıŞş‡·‚„‰ÂÊÁËÈÍÎÏÌÓÔ�ÒÚÛÙ�ˆ˜¯˘˙˚¸˝˛ˇ" + }, + "macukraine": { + "type": "_sbcs", + "chars": "АБВГДЕЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯ†°Ґ£§•¶І®©™Ђђ≠Ѓѓ∞±≤≥іµґЈЄєЇїЉљЊњјЅ¬√ƒ≈∆«»… ЋћЌќѕ–—“”‘’÷„ЎўЏџ№Ёёяабвгдежзийклмнопрстуфхцчшщъыьэю¤" + }, + "koi8r": { + "type": "_sbcs", + "chars": "─│┌┐└┘├┤┬┴┼▀▄█▌▐░▒▓⌠■∙√≈≤≥ ⌡°²·÷═║╒ё╓╔╕╖╗╘╙╚╛╜╝╞╟╠╡Ё╢╣╤╥╦╧╨╩╪╫╬©юабцдефгхийклмнопярстужвьызшэщчъЮАБЦДЕФГХИЙКЛМНОПЯРСТУЖВЬЫЗШЭЩЧЪ" + }, + "koi8u": { + "type": "_sbcs", + "chars": "─│┌┐└┘├┤┬┴┼▀▄█▌▐░▒▓⌠■∙√≈≤≥ ⌡°²·÷═║╒ёє╔ії╗╘╙╚╛ґ╝╞╟╠╡ЁЄ╣ІЇ╦╧╨╩╪Ґ╬©юабцдефгхийклмнопярстужвьызшэщчъЮАБЦДЕФГХИЙКЛМНОПЯРСТУЖВЬЫЗШЭЩЧЪ" + }, + "koi8ru": { + "type": "_sbcs", + "chars": "─│┌┐└┘├┤┬┴┼▀▄█▌▐░▒▓⌠■∙√≈≤≥ ⌡°²·÷═║╒ёє╔ії╗╘╙╚╛ґў╞╟╠╡ЁЄ╣ІЇ╦╧╨╩╪ҐЎ©юабцдефгхийклмнопярстужвьызшэщчъЮАБЦДЕФГХИЙКЛМНОПЯРСТУЖВЬЫЗШЭЩЧЪ" + }, + "koi8t": { + "type": "_sbcs", + "chars": "қғ‚Ғ„…†‡�‰ҳ‹ҲҷҶ�Қ‘’“”•–—�™�›�����ӯӮё¤ӣ¦§���«¬­®�°±²Ё�Ӣ¶·�№�»���©юабцдефгхийклмнопярстужвьызшэщчъЮАБЦДЕФГХИЙКЛМНОПЯРСТУЖВЬЫЗШЭЩЧЪ" + }, + "armscii8": { + "type": "_sbcs", + "chars": "€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ �և։)(»«—.՝,-֊…՜՛՞ԱաԲբԳգԴդԵեԶզԷէԸըԹթԺժԻիԼլԽխԾծԿկՀհՁձՂղՃճՄմՅյՆնՇշՈոՉչՊպՋջՌռՍսՎվՏտՐրՑցՒւՓփՔքՕօՖֆ՚�" + }, + "rk1048": { + "type": "_sbcs", + "chars": "ЂЃ‚ѓ„…†‡€‰Љ‹ЊҚҺЏђ‘’“”•–—�™љ›њқһџ ҰұӘ¤Ө¦§Ё©Ғ«¬­®Ү°±Ііөµ¶·ё№ғ»әҢңүАБВГДЕЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯабвгдежзийклмнопрстуфхцчшщъыьэюя" + }, + "tcvn": { + "type": "_sbcs", + "chars": "\0\xDA\u1EE4\x03\u1EEA\u1EEC\u1EEE\x07\b\t\n\x0B\f\r\x0E\x0F\x10\u1EE8\u1EF0\u1EF2\u1EF6\u1EF8\xDD\u1EF4\x18\x19\x1A\x1B\x1C\x1D\x1E\x1F !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\x7F\xC0\u1EA2\xC3\xC1\u1EA0\u1EB6\u1EAC\xC8\u1EBA\u1EBC\xC9\u1EB8\u1EC6\xCC\u1EC8\u0128\xCD\u1ECA\xD2\u1ECE\xD5\xD3\u1ECC\u1ED8\u1EDC\u1EDE\u1EE0\u1EDA\u1EE2\xD9\u1EE6\u0168\xA0\u0102\xC2\xCA\xD4\u01A0\u01AF\u0110\u0103\xE2\xEA\xF4\u01A1\u01B0\u0111\u1EB0\u0300\u0309\u0303\u0301\u0323\xE0\u1EA3\xE3\xE1\u1EA1\u1EB2\u1EB1\u1EB3\u1EB5\u1EAF\u1EB4\u1EAE\u1EA6\u1EA8\u1EAA\u1EA4\u1EC0\u1EB7\u1EA7\u1EA9\u1EAB\u1EA5\u1EAD\xE8\u1EC2\u1EBB\u1EBD\xE9\u1EB9\u1EC1\u1EC3\u1EC5\u1EBF\u1EC7\xEC\u1EC9\u1EC4\u1EBE\u1ED2\u0129\xED\u1ECB\xF2\u1ED4\u1ECF\xF5\xF3\u1ECD\u1ED3\u1ED5\u1ED7\u1ED1\u1ED9\u1EDD\u1EDF\u1EE1\u1EDB\u1EE3\xF9\u1ED6\u1EE7\u0169\xFA\u1EE5\u1EEB\u1EED\u1EEF\u1EE9\u1EF1\u1EF3\u1EF7\u1EF9\xFD\u1EF5\u1ED0" + }, + "georgianacademy": { + "type": "_sbcs", + "chars": "€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ ¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿აბგდევზთიკლმნოპჟრსტუფქღყშჩცძწჭხჯჰჱჲჳჴჵჶçèéêëìíîïðñòóôõö÷øùúûüýþÿ" + }, + "georgianps": { + "type": "_sbcs", + "chars": "€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ ¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿აბგდევზჱთიკლმნჲოპჟრსტჳუფქღყშჩცძწჭხჴჯჰჵæçèéêëìíîïðñòóôõö÷øùúûüýþÿ" + }, + "pt154": { + "type": "_sbcs", + "chars": "ҖҒӮғ„…ҶҮҲүҠӢҢҚҺҸҗ‘’“”•–—ҳҷҡӣңқһҹ ЎўЈӨҘҰ§Ё©Ә«¬ӯ®Ҝ°ұІіҙө¶·ё№ә»јҪҫҝАБВГДЕЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯабвгдежзийклмнопрстуфхцчшщъыьэюя" + }, + "viscii": { + "type": "_sbcs", + "chars": "\0\x01\u1EB2\x03\x04\u1EB4\u1EAA\x07\b\t\n\x0B\f\r\x0E\x0F\x10\x11\x12\x13\u1EF6\x15\x16\x17\x18\u1EF8\x1A\x1B\x1C\x1D\u1EF4\x1F !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\x7F\u1EA0\u1EAE\u1EB0\u1EB6\u1EA4\u1EA6\u1EA8\u1EAC\u1EBC\u1EB8\u1EBE\u1EC0\u1EC2\u1EC4\u1EC6\u1ED0\u1ED2\u1ED4\u1ED6\u1ED8\u1EE2\u1EDA\u1EDC\u1EDE\u1ECA\u1ECE\u1ECC\u1EC8\u1EE6\u0168\u1EE4\u1EF2\xD5\u1EAF\u1EB1\u1EB7\u1EA5\u1EA7\u1EA9\u1EAD\u1EBD\u1EB9\u1EBF\u1EC1\u1EC3\u1EC5\u1EC7\u1ED1\u1ED3\u1ED5\u1ED7\u1EE0\u01A0\u1ED9\u1EDD\u1EDF\u1ECB\u1EF0\u1EE8\u1EEA\u1EEC\u01A1\u1EDB\u01AF\xC0\xC1\xC2\xC3\u1EA2\u0102\u1EB3\u1EB5\xC8\xC9\xCA\u1EBA\xCC\xCD\u0128\u1EF3\u0110\u1EE9\xD2\xD3\xD4\u1EA1\u1EF7\u1EEB\u1EED\xD9\xDA\u1EF9\u1EF5\xDD\u1EE1\u01B0\xE0\xE1\xE2\xE3\u1EA3\u0103\u1EEF\u1EAB\xE8\xE9\xEA\u1EBB\xEC\xED\u0129\u1EC9\u0111\u1EF1\xF2\xF3\xF4\xF5\u1ECF\u1ECD\u1EE5\xF9\xFA\u0169\u1EE7\xFD\u1EE3\u1EEE" + }, + "iso646cn": { + "type": "_sbcs", + "chars": "\0\x01\x02\x03\x04\x05\x06\x07\b\t\n\x0B\f\r\x0E\x0F\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1A\x1B\x1C\x1D\x1E\x1F !\"#\xA5%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}\u203E\x7F\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD" + }, + "iso646jp": { + "type": "_sbcs", + "chars": "\0\x01\x02\x03\x04\x05\x06\x07\b\t\n\x0B\f\r\x0E\x0F\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1A\x1B\x1C\x1D\x1E\x1F !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\xA5]^_`abcdefghijklmnopqrstuvwxyz{|}\u203E\x7F\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD" + }, + "hproman8": { + "type": "_sbcs", + "chars": "€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ ÀÂÈÊËÎÏ´ˋˆ¨˜ÙÛ₤¯Ýý°ÇçÑñ¡¿¤£¥§ƒ¢âêôûáéóúàèòùäëöüÅîØÆåíøæÄìÖÜÉïßÔÁÃãÐðÍÌÓÒÕõŠšÚŸÿÞþ·µ¶¾—¼½ªº«■»±�" + }, + "macintosh": { + "type": "_sbcs", + "chars": "ÄÅÇÉÑÖÜáàâäãåçéèêëíìîïñóòôöõúùûü†°¢£§•¶ß®©™´¨≠ÆØ∞±≤≥¥µ∂∑∏π∫ªºΩæø¿¡¬√ƒ≈∆«»… ÀÃÕŒœ–—“”‘’÷◊ÿŸ⁄¤‹›fifl‡·‚„‰ÂÊÁËÈÍÎÏÌÓÔ�ÒÚÛÙıˆ˜¯˘˙˚¸˝˛ˇ" + }, + "ascii": { + "type": "_sbcs", + "chars": "��������������������������������������������������������������������������������������������������������������������������������" + }, + "tis620": { + "type": "_sbcs", + "chars": "���������������������������������กขฃคฅฆงจฉชซฌญฎฏฐฑฒณดตถทธนบปผฝพฟภมยรฤลฦวศษสหฬอฮฯะัาำิีึืฺุู����฿เแโใไๅๆ็่้๊๋์ํ๎๏๐๑๒๓๔๕๖๗๘๙๚๛����" + } + }; +}); + +var __moduleExports$80 = createCommonjsModule(function (module, exports) { + "use strict"; + + // Multibyte codec. In this scheme, a character is represented by 1 or more bytes. + // Our codec supports UTF-16 surrogates, extensions for GB18030 and unicode sequences. + // To save memory and loading time, we read table files only when requested. + + exports._dbcs = DBCSCodec; + + var UNASSIGNED = -1, + GB18030_CODE = -2, + SEQ_START = -10, + NODE_START = -1000, + UNASSIGNED_NODE = new Array(0x100), + DEF_CHAR = -1; + + for (var i = 0; i < 0x100; i++) { + UNASSIGNED_NODE[i] = UNASSIGNED; + } // Class DBCSCodec reads and initializes mapping tables. + function DBCSCodec(codecOptions, iconv) { + this.encodingName = codecOptions.encodingName; + if (!codecOptions) throw new Error("DBCS codec is called without the data."); + if (!codecOptions.table) throw new Error("Encoding '" + this.encodingName + "' has no data."); + + // Load tables. + var mappingTable = codecOptions.table(); + + // Decode tables: MBCS -> Unicode. + + // decodeTables is a trie, encoded as an array of arrays of integers. Internal arrays are trie nodes and all have len = 256. + // Trie root is decodeTables[0]. + // Values: >= 0 -> unicode character code. can be > 0xFFFF + // == UNASSIGNED -> unknown/unassigned sequence. + // == GB18030_CODE -> this is the end of a GB18030 4-byte sequence. + // <= NODE_START -> index of the next node in our trie to process next byte. + // <= SEQ_START -> index of the start of a character code sequence, in decodeTableSeq. + this.decodeTables = []; + this.decodeTables[0] = UNASSIGNED_NODE.slice(0); // Create root node. + + // Sometimes a MBCS char corresponds to a sequence of unicode chars. We store them as arrays of integers here. + this.decodeTableSeq = []; + + // Actual mapping tables consist of chunks. Use them to fill up decode tables. + for (var i = 0; i < mappingTable.length; i++) { + this._addDecodeChunk(mappingTable[i]); + }this.defaultCharUnicode = iconv.defaultCharUnicode; + + // Encode tables: Unicode -> DBCS. + + // `encodeTable` is array mapping from unicode char to encoded char. All its values are integers for performance. + // Because it can be sparse, it is represented as array of buckets by 256 chars each. Bucket can be null. + // Values: >= 0 -> it is a normal char. Write the value (if <=256 then 1 byte, if <=65536 then 2 bytes, etc.). + // == UNASSIGNED -> no conversion found. Output a default char. + // <= SEQ_START -> it's an index in encodeTableSeq, see below. The character starts a sequence. + this.encodeTable = []; + + // `encodeTableSeq` is used when a sequence of unicode characters is encoded as a single code. We use a tree of + // objects where keys correspond to characters in sequence and leafs are the encoded dbcs values. A special DEF_CHAR key + // means end of sequence (needed when one sequence is a strict subsequence of another). + // Objects are kept separately from encodeTable to increase performance. + this.encodeTableSeq = []; + + // Some chars can be decoded, but need not be encoded. + var skipEncodeChars = {}; + if (codecOptions.encodeSkipVals) for (var i = 0; i < codecOptions.encodeSkipVals.length; i++) { + var val = codecOptions.encodeSkipVals[i]; + if (typeof val === 'number') skipEncodeChars[val] = true;else for (var j = val.from; j <= val.to; j++) { + skipEncodeChars[j] = true; + } + } + + // Use decode trie to recursively fill out encode tables. + this._fillEncodeTable(0, 0, skipEncodeChars); + + // Add more encoding pairs when needed. + if (codecOptions.encodeAdd) { + for (var uChar in codecOptions.encodeAdd) { + if (Object.prototype.hasOwnProperty.call(codecOptions.encodeAdd, uChar)) this._setEncodeChar(uChar.charCodeAt(0), codecOptions.encodeAdd[uChar]); + } + } + + this.defCharSB = this.encodeTable[0][iconv.defaultCharSingleByte.charCodeAt(0)]; + if (this.defCharSB === UNASSIGNED) this.defCharSB = this.encodeTable[0]['?']; + if (this.defCharSB === UNASSIGNED) this.defCharSB = "?".charCodeAt(0); + + // Load & create GB18030 tables when needed. + if (typeof codecOptions.gb18030 === 'function') { + this.gb18030 = codecOptions.gb18030(); // Load GB18030 ranges. + + // Add GB18030 decode tables. + var thirdByteNodeIdx = this.decodeTables.length; + var thirdByteNode = this.decodeTables[thirdByteNodeIdx] = UNASSIGNED_NODE.slice(0); + + var fourthByteNodeIdx = this.decodeTables.length; + var fourthByteNode = this.decodeTables[fourthByteNodeIdx] = UNASSIGNED_NODE.slice(0); + + for (var i = 0x81; i <= 0xFE; i++) { + var secondByteNodeIdx = NODE_START - this.decodeTables[0][i]; + var secondByteNode = this.decodeTables[secondByteNodeIdx]; + for (var j = 0x30; j <= 0x39; j++) { + secondByteNode[j] = NODE_START - thirdByteNodeIdx; + } + } + for (var i = 0x81; i <= 0xFE; i++) { + thirdByteNode[i] = NODE_START - fourthByteNodeIdx; + }for (var i = 0x30; i <= 0x39; i++) { + fourthByteNode[i] = GB18030_CODE; + } + } + } + + DBCSCodec.prototype.encoder = DBCSEncoder; + DBCSCodec.prototype.decoder = DBCSDecoder; + + // Decoder helpers + DBCSCodec.prototype._getDecodeTrieNode = function (addr) { + var bytes = []; + for (; addr > 0; addr >>= 8) { + bytes.push(addr & 0xFF); + }if (bytes.length == 0) bytes.push(0); + + var node = this.decodeTables[0]; + for (var i = bytes.length - 1; i > 0; i--) { + // Traverse nodes deeper into the trie. + var val = node[bytes[i]]; + + if (val == UNASSIGNED) { + // Create new node. + node[bytes[i]] = NODE_START - this.decodeTables.length; + this.decodeTables.push(node = UNASSIGNED_NODE.slice(0)); + } else if (val <= NODE_START) { + // Existing node. + node = this.decodeTables[NODE_START - val]; + } else throw new Error("Overwrite byte in " + this.encodingName + ", addr: " + addr.toString(16)); + } + return node; + }; + + DBCSCodec.prototype._addDecodeChunk = function (chunk) { + // First element of chunk is the hex mbcs code where we start. + var curAddr = parseInt(chunk[0], 16); + + // Choose the decoding node where we'll write our chars. + var writeTable = this._getDecodeTrieNode(curAddr); + curAddr = curAddr & 0xFF; + + // Write all other elements of the chunk to the table. + for (var k = 1; k < chunk.length; k++) { + var part = chunk[k]; + if (typeof part === "string") { + // String, write as-is. + for (var l = 0; l < part.length;) { + var code = part.charCodeAt(l++); + if (0xD800 <= code && code < 0xDC00) { + // Decode surrogate + var codeTrail = part.charCodeAt(l++); + if (0xDC00 <= codeTrail && codeTrail < 0xE000) writeTable[curAddr++] = 0x10000 + (code - 0xD800) * 0x400 + (codeTrail - 0xDC00);else throw new Error("Incorrect surrogate pair in " + this.encodingName + " at chunk " + chunk[0]); + } else if (0x0FF0 < code && code <= 0x0FFF) { + // Character sequence (our own encoding used) + var len = 0xFFF - code + 2; + var seq = []; + for (var m = 0; m < len; m++) { + seq.push(part.charCodeAt(l++)); + } // Simple variation: don't support surrogates or subsequences in seq. + + writeTable[curAddr++] = SEQ_START - this.decodeTableSeq.length; + this.decodeTableSeq.push(seq); + } else writeTable[curAddr++] = code; // Basic char + } + } else if (typeof part === "number") { + // Integer, meaning increasing sequence starting with prev character. + var charCode = writeTable[curAddr - 1] + 1; + for (var l = 0; l < part; l++) { + writeTable[curAddr++] = charCode++; + } + } else throw new Error("Incorrect type '" + (typeof part === "undefined" ? "undefined" : _typeof$1(part)) + "' given in " + this.encodingName + " at chunk " + chunk[0]); + } + if (curAddr > 0xFF) throw new Error("Incorrect chunk in " + this.encodingName + " at addr " + chunk[0] + ": too long" + curAddr); + }; + + // Encoder helpers + DBCSCodec.prototype._getEncodeBucket = function (uCode) { + var high = uCode >> 8; // This could be > 0xFF because of astral characters. + if (this.encodeTable[high] === undefined) this.encodeTable[high] = UNASSIGNED_NODE.slice(0); // Create bucket on demand. + return this.encodeTable[high]; + }; + + DBCSCodec.prototype._setEncodeChar = function (uCode, dbcsCode) { + var bucket = this._getEncodeBucket(uCode); + var low = uCode & 0xFF; + if (bucket[low] <= SEQ_START) this.encodeTableSeq[SEQ_START - bucket[low]][DEF_CHAR] = dbcsCode; // There's already a sequence, set a single-char subsequence of it. + else if (bucket[low] == UNASSIGNED) bucket[low] = dbcsCode; + }; + + DBCSCodec.prototype._setEncodeSequence = function (seq, dbcsCode) { + + // Get the root of character tree according to first character of the sequence. + var uCode = seq[0]; + var bucket = this._getEncodeBucket(uCode); + var low = uCode & 0xFF; + + var node; + if (bucket[low] <= SEQ_START) { + // There's already a sequence with - use it. + node = this.encodeTableSeq[SEQ_START - bucket[low]]; + } else { + // There was no sequence object - allocate a new one. + node = {}; + if (bucket[low] !== UNASSIGNED) node[DEF_CHAR] = bucket[low]; // If a char was set before - make it a single-char subsequence. + bucket[low] = SEQ_START - this.encodeTableSeq.length; + this.encodeTableSeq.push(node); + } + + // Traverse the character tree, allocating new nodes as needed. + for (var j = 1; j < seq.length - 1; j++) { + var oldVal = node[uCode]; + if ((typeof oldVal === "undefined" ? "undefined" : _typeof$1(oldVal)) === 'object') node = oldVal;else { + node = node[uCode] = {}; + if (oldVal !== undefined) node[DEF_CHAR] = oldVal; + } + } + + // Set the leaf to given dbcsCode. + uCode = seq[seq.length - 1]; + node[uCode] = dbcsCode; + }; + + DBCSCodec.prototype._fillEncodeTable = function (nodeIdx, prefix, skipEncodeChars) { + var node = this.decodeTables[nodeIdx]; + for (var i = 0; i < 0x100; i++) { + var uCode = node[i]; + var mbCode = prefix + i; + if (skipEncodeChars[mbCode]) continue; + + if (uCode >= 0) this._setEncodeChar(uCode, mbCode);else if (uCode <= NODE_START) this._fillEncodeTable(NODE_START - uCode, mbCode << 8, skipEncodeChars);else if (uCode <= SEQ_START) this._setEncodeSequence(this.decodeTableSeq[SEQ_START - uCode], mbCode); + } + }; + + // == Encoder ================================================================== + + function DBCSEncoder(options, codec) { + // Encoder state + this.leadSurrogate = -1; + this.seqObj = undefined; + + // Static data + this.encodeTable = codec.encodeTable; + this.encodeTableSeq = codec.encodeTableSeq; + this.defaultCharSingleByte = codec.defCharSB; + this.gb18030 = codec.gb18030; + } + + DBCSEncoder.prototype.write = function (str) { + var newBuf = new Buffer(str.length * (this.gb18030 ? 4 : 3)), + leadSurrogate = this.leadSurrogate, + seqObj = this.seqObj, + nextChar = -1, + i = 0, + j = 0; + + while (true) { + // 0. Get next character. + if (nextChar === -1) { + if (i == str.length) break; + var uCode = str.charCodeAt(i++); + } else { + var uCode = nextChar; + nextChar = -1; + } + + // 1. Handle surrogates. + if (0xD800 <= uCode && uCode < 0xE000) { + // Char is one of surrogates. + if (uCode < 0xDC00) { + // We've got lead surrogate. + if (leadSurrogate === -1) { + leadSurrogate = uCode; + continue; + } else { + leadSurrogate = uCode; + // Double lead surrogate found. + uCode = UNASSIGNED; + } + } else { + // We've got trail surrogate. + if (leadSurrogate !== -1) { + uCode = 0x10000 + (leadSurrogate - 0xD800) * 0x400 + (uCode - 0xDC00); + leadSurrogate = -1; + } else { + // Incomplete surrogate pair - only trail surrogate found. + uCode = UNASSIGNED; + } + } + } else if (leadSurrogate !== -1) { + // Incomplete surrogate pair - only lead surrogate found. + nextChar = uCode;uCode = UNASSIGNED; // Write an error, then current char. + leadSurrogate = -1; + } + + // 2. Convert uCode character. + var dbcsCode = UNASSIGNED; + if (seqObj !== undefined && uCode != UNASSIGNED) { + // We are in the middle of the sequence + var resCode = seqObj[uCode]; + if ((typeof resCode === "undefined" ? "undefined" : _typeof$1(resCode)) === 'object') { + // Sequence continues. + seqObj = resCode; + continue; + } else if (typeof resCode == 'number') { + // Sequence finished. Write it. + dbcsCode = resCode; + } else if (resCode == undefined) { + // Current character is not part of the sequence. + + // Try default character for this sequence + resCode = seqObj[DEF_CHAR]; + if (resCode !== undefined) { + dbcsCode = resCode; // Found. Write it. + nextChar = uCode; // Current character will be written too in the next iteration. + } else { + // TODO: What if we have no default? (resCode == undefined) + // Then, we should write first char of the sequence as-is and try the rest recursively. + // Didn't do it for now because no encoding has this situation yet. + // Currently, just skip the sequence and write current char. + } + } + seqObj = undefined; + } else if (uCode >= 0) { + // Regular character + var subtable = this.encodeTable[uCode >> 8]; + if (subtable !== undefined) dbcsCode = subtable[uCode & 0xFF]; + + if (dbcsCode <= SEQ_START) { + // Sequence start + seqObj = this.encodeTableSeq[SEQ_START - dbcsCode]; + continue; + } + + if (dbcsCode == UNASSIGNED && this.gb18030) { + // Use GB18030 algorithm to find character(s) to write. + var idx = findIdx(this.gb18030.uChars, uCode); + if (idx != -1) { + var dbcsCode = this.gb18030.gbChars[idx] + (uCode - this.gb18030.uChars[idx]); + newBuf[j++] = 0x81 + Math.floor(dbcsCode / 12600);dbcsCode = dbcsCode % 12600; + newBuf[j++] = 0x30 + Math.floor(dbcsCode / 1260);dbcsCode = dbcsCode % 1260; + newBuf[j++] = 0x81 + Math.floor(dbcsCode / 10);dbcsCode = dbcsCode % 10; + newBuf[j++] = 0x30 + dbcsCode; + continue; + } + } + } + + // 3. Write dbcsCode character. + if (dbcsCode === UNASSIGNED) dbcsCode = this.defaultCharSingleByte; + + if (dbcsCode < 0x100) { + newBuf[j++] = dbcsCode; + } else if (dbcsCode < 0x10000) { + newBuf[j++] = dbcsCode >> 8; // high byte + newBuf[j++] = dbcsCode & 0xFF; // low byte + } else { + newBuf[j++] = dbcsCode >> 16; + newBuf[j++] = dbcsCode >> 8 & 0xFF; + newBuf[j++] = dbcsCode & 0xFF; + } + } + + this.seqObj = seqObj; + this.leadSurrogate = leadSurrogate; + return newBuf.slice(0, j); + }; + + DBCSEncoder.prototype.end = function () { + if (this.leadSurrogate === -1 && this.seqObj === undefined) return; // All clean. Most often case. + + var newBuf = new Buffer(10), + j = 0; + + if (this.seqObj) { + // We're in the sequence. + var dbcsCode = this.seqObj[DEF_CHAR]; + if (dbcsCode !== undefined) { + // Write beginning of the sequence. + if (dbcsCode < 0x100) { + newBuf[j++] = dbcsCode; + } else { + newBuf[j++] = dbcsCode >> 8; // high byte + newBuf[j++] = dbcsCode & 0xFF; // low byte + } + } else { + // See todo above. + } + this.seqObj = undefined; + } + + if (this.leadSurrogate !== -1) { + // Incomplete surrogate pair - only lead surrogate found. + newBuf[j++] = this.defaultCharSingleByte; + this.leadSurrogate = -1; + } + + return newBuf.slice(0, j); + }; + + // Export for testing + DBCSEncoder.prototype.findIdx = findIdx; + + // == Decoder ================================================================== + + function DBCSDecoder(options, codec) { + // Decoder state + this.nodeIdx = 0; + this.prevBuf = new Buffer(0); + + // Static data + this.decodeTables = codec.decodeTables; + this.decodeTableSeq = codec.decodeTableSeq; + this.defaultCharUnicode = codec.defaultCharUnicode; + this.gb18030 = codec.gb18030; + } + + DBCSDecoder.prototype.write = function (buf) { + var newBuf = new Buffer(buf.length * 2), + nodeIdx = this.nodeIdx, + prevBuf = this.prevBuf, + prevBufOffset = this.prevBuf.length, + seqStart = -this.prevBuf.length, + // idx of the start of current parsed sequence. + uCode; + + if (prevBufOffset > 0) // Make prev buf overlap a little to make it easier to slice later. + prevBuf = Buffer.concat([prevBuf, buf.slice(0, 10)]); + + for (var i = 0, j = 0; i < buf.length; i++) { + var curByte = i >= 0 ? buf[i] : prevBuf[i + prevBufOffset]; + + // Lookup in current trie node. + var uCode = this.decodeTables[nodeIdx][curByte]; + + if (uCode >= 0) { + // Normal character, just use it. + } else if (uCode === UNASSIGNED) { + // Unknown char. + // TODO: Callback with seq. + //var curSeq = (seqStart >= 0) ? buf.slice(seqStart, i+1) : prevBuf.slice(seqStart + prevBufOffset, i+1 + prevBufOffset); + i = seqStart; // Try to parse again, after skipping first byte of the sequence ('i' will be incremented by 'for' cycle). + uCode = this.defaultCharUnicode.charCodeAt(0); + } else if (uCode === GB18030_CODE) { + var curSeq = seqStart >= 0 ? buf.slice(seqStart, i + 1) : prevBuf.slice(seqStart + prevBufOffset, i + 1 + prevBufOffset); + var ptr = (curSeq[0] - 0x81) * 12600 + (curSeq[1] - 0x30) * 1260 + (curSeq[2] - 0x81) * 10 + (curSeq[3] - 0x30); + var idx = findIdx(this.gb18030.gbChars, ptr); + uCode = this.gb18030.uChars[idx] + ptr - this.gb18030.gbChars[idx]; + } else if (uCode <= NODE_START) { + // Go to next trie node. + nodeIdx = NODE_START - uCode; + continue; + } else if (uCode <= SEQ_START) { + // Output a sequence of chars. + var seq = this.decodeTableSeq[SEQ_START - uCode]; + for (var k = 0; k < seq.length - 1; k++) { + uCode = seq[k]; + newBuf[j++] = uCode & 0xFF; + newBuf[j++] = uCode >> 8; + } + uCode = seq[seq.length - 1]; + } else throw new Error("iconv-lite internal error: invalid decoding table value " + uCode + " at " + nodeIdx + "/" + curByte); + + // Write the character to buffer, handling higher planes using surrogate pair. + if (uCode > 0xFFFF) { + uCode -= 0x10000; + var uCodeLead = 0xD800 + Math.floor(uCode / 0x400); + newBuf[j++] = uCodeLead & 0xFF; + newBuf[j++] = uCodeLead >> 8; + + uCode = 0xDC00 + uCode % 0x400; + } + newBuf[j++] = uCode & 0xFF; + newBuf[j++] = uCode >> 8; + + // Reset trie node. + nodeIdx = 0;seqStart = i + 1; + } + + this.nodeIdx = nodeIdx; + this.prevBuf = seqStart >= 0 ? buf.slice(seqStart) : prevBuf.slice(seqStart + prevBufOffset); + return newBuf.slice(0, j).toString('ucs2'); + }; + + DBCSDecoder.prototype.end = function () { + var ret = ''; + + // Try to parse all remaining chars. + while (this.prevBuf.length > 0) { + // Skip 1 character in the buffer. + ret += this.defaultCharUnicode; + var buf = this.prevBuf.slice(1); + + // Parse remaining as usual. + this.prevBuf = new Buffer(0); + this.nodeIdx = 0; + if (buf.length > 0) ret += this.write(buf); + } + + this.nodeIdx = 0; + return ret; + }; + + // Binary search for GB18030. Returns largest i such that table[i] <= val. + function findIdx(table, val) { + if (table[0] > val) return -1; + + var l = 0, + r = table.length; + while (l < r - 1) { + // always table[l] <= val < table[r] + var mid = l + Math.floor((r - l + 1) / 2); + if (table[mid] <= val) l = mid;else r = mid; + } + return l; + } +}); + +var shiftjis = [["0", "\0", 128], ["a1", "。", 62], ["8140", " 、。,.・:;?!゛゜´`¨^ ̄_ヽヾゝゞ〃仝々〆〇ー―‐/\~∥|…‥‘’“”()〔〕[]{}〈", 9, "+-±×"], ["8180", "÷=≠<>≦≧∞∴♂♀°′″℃¥$¢£%#&*@§☆★○●◎◇◆□■△▲▽▼※〒→←↑↓〓"], ["81b8", "∈∋⊆⊇⊂⊃∪∩"], ["81c8", "∧∨¬⇒⇔∀∃"], ["81da", "∠⊥⌒∂∇≡≒≪≫√∽∝∵∫∬"], ["81f0", "ʼn♯♭♪†‡¶"], ["81fc", "◯"], ["824f", "0", 9], ["8260", "A", 25], ["8281", "a", 25], ["829f", "ぁ", 82], ["8340", "ァ", 62], ["8380", "ム", 22], ["839f", "Α", 16, "Σ", 6], ["83bf", "α", 16, "σ", 6], ["8440", "А", 5, "ЁЖ", 25], ["8470", "а", 5, "ёж", 7], ["8480", "о", 17], ["849f", "─│┌┐┘└├┬┤┴┼━┃┏┓┛┗┣┳┫┻╋┠┯┨┷┿┝┰┥┸╂"], ["8740", "①", 19, "Ⅰ", 9], ["875f", "㍉㌔㌢㍍㌘㌧㌃㌶㍑㍗㌍㌦㌣㌫㍊㌻㎜㎝㎞㎎㎏㏄㎡"], ["877e", "㍻"], ["8780", "〝〟№㏍℡㊤", 4, "㈱㈲㈹㍾㍽㍼≒≡∫∮∑√⊥∠∟⊿∵∩∪"], ["889f", "亜唖娃阿哀愛挨姶逢葵茜穐悪握渥旭葦芦鯵梓圧斡扱宛姐虻飴絢綾鮎或粟袷安庵按暗案闇鞍杏以伊位依偉囲夷委威尉惟意慰易椅為畏異移維緯胃萎衣謂違遺医井亥域育郁磯一壱溢逸稲茨芋鰯允印咽員因姻引飲淫胤蔭"], ["8940", "院陰隠韻吋右宇烏羽迂雨卯鵜窺丑碓臼渦嘘唄欝蔚鰻姥厩浦瓜閏噂云運雲荏餌叡営嬰影映曳栄永泳洩瑛盈穎頴英衛詠鋭液疫益駅悦謁越閲榎厭円"], ["8980", "園堰奄宴延怨掩援沿演炎焔煙燕猿縁艶苑薗遠鉛鴛塩於汚甥凹央奥往応押旺横欧殴王翁襖鴬鴎黄岡沖荻億屋憶臆桶牡乙俺卸恩温穏音下化仮何伽価佳加可嘉夏嫁家寡科暇果架歌河火珂禍禾稼箇花苛茄荷華菓蝦課嘩貨迦過霞蚊俄峨我牙画臥芽蛾賀雅餓駕介会解回塊壊廻快怪悔恢懐戒拐改"], ["8a40", "魁晦械海灰界皆絵芥蟹開階貝凱劾外咳害崖慨概涯碍蓋街該鎧骸浬馨蛙垣柿蛎鈎劃嚇各廓拡撹格核殻獲確穫覚角赫較郭閣隔革学岳楽額顎掛笠樫"], ["8a80", "橿梶鰍潟割喝恰括活渇滑葛褐轄且鰹叶椛樺鞄株兜竃蒲釜鎌噛鴨栢茅萱粥刈苅瓦乾侃冠寒刊勘勧巻喚堪姦完官寛干幹患感慣憾換敢柑桓棺款歓汗漢澗潅環甘監看竿管簡緩缶翰肝艦莞観諌貫還鑑間閑関陥韓館舘丸含岸巌玩癌眼岩翫贋雁頑顔願企伎危喜器基奇嬉寄岐希幾忌揮机旗既期棋棄"], ["8b40", "機帰毅気汽畿祈季稀紀徽規記貴起軌輝飢騎鬼亀偽儀妓宜戯技擬欺犠疑祇義蟻誼議掬菊鞠吉吃喫桔橘詰砧杵黍却客脚虐逆丘久仇休及吸宮弓急救"], ["8b80", "朽求汲泣灸球究窮笈級糾給旧牛去居巨拒拠挙渠虚許距鋸漁禦魚亨享京供侠僑兇競共凶協匡卿叫喬境峡強彊怯恐恭挟教橋況狂狭矯胸脅興蕎郷鏡響饗驚仰凝尭暁業局曲極玉桐粁僅勤均巾錦斤欣欽琴禁禽筋緊芹菌衿襟謹近金吟銀九倶句区狗玖矩苦躯駆駈駒具愚虞喰空偶寓遇隅串櫛釧屑屈"], ["8c40", "掘窟沓靴轡窪熊隈粂栗繰桑鍬勲君薫訓群軍郡卦袈祁係傾刑兄啓圭珪型契形径恵慶慧憩掲携敬景桂渓畦稽系経継繋罫茎荊蛍計詣警軽頚鶏芸迎鯨"], ["8c80", "劇戟撃激隙桁傑欠決潔穴結血訣月件倹倦健兼券剣喧圏堅嫌建憲懸拳捲検権牽犬献研硯絹県肩見謙賢軒遣鍵険顕験鹸元原厳幻弦減源玄現絃舷言諺限乎個古呼固姑孤己庫弧戸故枯湖狐糊袴股胡菰虎誇跨鈷雇顧鼓五互伍午呉吾娯後御悟梧檎瑚碁語誤護醐乞鯉交佼侯候倖光公功効勾厚口向"], ["8d40", "后喉坑垢好孔孝宏工巧巷幸広庚康弘恒慌抗拘控攻昂晃更杭校梗構江洪浩港溝甲皇硬稿糠紅紘絞綱耕考肯肱腔膏航荒行衡講貢購郊酵鉱砿鋼閤降"], ["8d80", "項香高鴻剛劫号合壕拷濠豪轟麹克刻告国穀酷鵠黒獄漉腰甑忽惚骨狛込此頃今困坤墾婚恨懇昏昆根梱混痕紺艮魂些佐叉唆嵯左差査沙瑳砂詐鎖裟坐座挫債催再最哉塞妻宰彩才採栽歳済災采犀砕砦祭斎細菜裁載際剤在材罪財冴坂阪堺榊肴咲崎埼碕鷺作削咋搾昨朔柵窄策索錯桜鮭笹匙冊刷"], ["8e40", "察拶撮擦札殺薩雑皐鯖捌錆鮫皿晒三傘参山惨撒散桟燦珊産算纂蚕讃賛酸餐斬暫残仕仔伺使刺司史嗣四士始姉姿子屍市師志思指支孜斯施旨枝止"], ["8e80", "死氏獅祉私糸紙紫肢脂至視詞詩試誌諮資賜雌飼歯事似侍児字寺慈持時次滋治爾璽痔磁示而耳自蒔辞汐鹿式識鴫竺軸宍雫七叱執失嫉室悉湿漆疾質実蔀篠偲柴芝屡蕊縞舎写射捨赦斜煮社紗者謝車遮蛇邪借勺尺杓灼爵酌釈錫若寂弱惹主取守手朱殊狩珠種腫趣酒首儒受呪寿授樹綬需囚収周"], ["8f40", "宗就州修愁拾洲秀秋終繍習臭舟蒐衆襲讐蹴輯週酋酬集醜什住充十従戎柔汁渋獣縦重銃叔夙宿淑祝縮粛塾熟出術述俊峻春瞬竣舜駿准循旬楯殉淳"], ["8f80", "準潤盾純巡遵醇順処初所暑曙渚庶緒署書薯藷諸助叙女序徐恕鋤除傷償勝匠升召哨商唱嘗奨妾娼宵将小少尚庄床廠彰承抄招掌捷昇昌昭晶松梢樟樵沼消渉湘焼焦照症省硝礁祥称章笑粧紹肖菖蒋蕉衝裳訟証詔詳象賞醤鉦鍾鐘障鞘上丈丞乗冗剰城場壌嬢常情擾条杖浄状畳穣蒸譲醸錠嘱埴飾"], ["9040", "拭植殖燭織職色触食蝕辱尻伸信侵唇娠寝審心慎振新晋森榛浸深申疹真神秦紳臣芯薪親診身辛進針震人仁刃塵壬尋甚尽腎訊迅陣靭笥諏須酢図厨"], ["9080", "逗吹垂帥推水炊睡粋翠衰遂酔錐錘随瑞髄崇嵩数枢趨雛据杉椙菅頗雀裾澄摺寸世瀬畝是凄制勢姓征性成政整星晴棲栖正清牲生盛精聖声製西誠誓請逝醒青静斉税脆隻席惜戚斥昔析石積籍績脊責赤跡蹟碩切拙接摂折設窃節説雪絶舌蝉仙先千占宣専尖川戦扇撰栓栴泉浅洗染潜煎煽旋穿箭線"], ["9140", "繊羨腺舛船薦詮賎践選遷銭銑閃鮮前善漸然全禅繕膳糎噌塑岨措曾曽楚狙疏疎礎祖租粗素組蘇訴阻遡鼠僧創双叢倉喪壮奏爽宋層匝惣想捜掃挿掻"], ["9180", "操早曹巣槍槽漕燥争痩相窓糟総綜聡草荘葬蒼藻装走送遭鎗霜騒像増憎臓蔵贈造促側則即息捉束測足速俗属賊族続卒袖其揃存孫尊損村遜他多太汰詑唾堕妥惰打柁舵楕陀駄騨体堆対耐岱帯待怠態戴替泰滞胎腿苔袋貸退逮隊黛鯛代台大第醍題鷹滝瀧卓啄宅托択拓沢濯琢託鐸濁諾茸凧蛸只"], ["9240", "叩但達辰奪脱巽竪辿棚谷狸鱈樽誰丹単嘆坦担探旦歎淡湛炭短端箪綻耽胆蛋誕鍛団壇弾断暖檀段男談値知地弛恥智池痴稚置致蜘遅馳築畜竹筑蓄"], ["9280", "逐秩窒茶嫡着中仲宙忠抽昼柱注虫衷註酎鋳駐樗瀦猪苧著貯丁兆凋喋寵帖帳庁弔張彫徴懲挑暢朝潮牒町眺聴脹腸蝶調諜超跳銚長頂鳥勅捗直朕沈珍賃鎮陳津墜椎槌追鎚痛通塚栂掴槻佃漬柘辻蔦綴鍔椿潰坪壷嬬紬爪吊釣鶴亭低停偵剃貞呈堤定帝底庭廷弟悌抵挺提梯汀碇禎程締艇訂諦蹄逓"], ["9340", "邸鄭釘鼎泥摘擢敵滴的笛適鏑溺哲徹撤轍迭鉄典填天展店添纏甜貼転顛点伝殿澱田電兎吐堵塗妬屠徒斗杜渡登菟賭途都鍍砥砺努度土奴怒倒党冬"], ["9380", "凍刀唐塔塘套宕島嶋悼投搭東桃梼棟盗淘湯涛灯燈当痘祷等答筒糖統到董蕩藤討謄豆踏逃透鐙陶頭騰闘働動同堂導憧撞洞瞳童胴萄道銅峠鴇匿得徳涜特督禿篤毒独読栃橡凸突椴届鳶苫寅酉瀞噸屯惇敦沌豚遁頓呑曇鈍奈那内乍凪薙謎灘捺鍋楢馴縄畷南楠軟難汝二尼弐迩匂賑肉虹廿日乳入"], ["9440", "如尿韮任妊忍認濡禰祢寧葱猫熱年念捻撚燃粘乃廼之埜嚢悩濃納能脳膿農覗蚤巴把播覇杷波派琶破婆罵芭馬俳廃拝排敗杯盃牌背肺輩配倍培媒梅"], ["9480", "楳煤狽買売賠陪這蝿秤矧萩伯剥博拍柏泊白箔粕舶薄迫曝漠爆縛莫駁麦函箱硲箸肇筈櫨幡肌畑畠八鉢溌発醗髪伐罰抜筏閥鳩噺塙蛤隼伴判半反叛帆搬斑板氾汎版犯班畔繁般藩販範釆煩頒飯挽晩番盤磐蕃蛮匪卑否妃庇彼悲扉批披斐比泌疲皮碑秘緋罷肥被誹費避非飛樋簸備尾微枇毘琵眉美"], ["9540", "鼻柊稗匹疋髭彦膝菱肘弼必畢筆逼桧姫媛紐百謬俵彪標氷漂瓢票表評豹廟描病秒苗錨鋲蒜蛭鰭品彬斌浜瀕貧賓頻敏瓶不付埠夫婦富冨布府怖扶敷"], ["9580", "斧普浮父符腐膚芙譜負賦赴阜附侮撫武舞葡蕪部封楓風葺蕗伏副復幅服福腹複覆淵弗払沸仏物鮒分吻噴墳憤扮焚奮粉糞紛雰文聞丙併兵塀幣平弊柄並蔽閉陛米頁僻壁癖碧別瞥蔑箆偏変片篇編辺返遍便勉娩弁鞭保舗鋪圃捕歩甫補輔穂募墓慕戊暮母簿菩倣俸包呆報奉宝峰峯崩庖抱捧放方朋"], ["9640", "法泡烹砲縫胞芳萌蓬蜂褒訪豊邦鋒飽鳳鵬乏亡傍剖坊妨帽忘忙房暴望某棒冒紡肪膨謀貌貿鉾防吠頬北僕卜墨撲朴牧睦穆釦勃没殆堀幌奔本翻凡盆"], ["9680", "摩磨魔麻埋妹昧枚毎哩槙幕膜枕鮪柾鱒桝亦俣又抹末沫迄侭繭麿万慢満漫蔓味未魅巳箕岬密蜜湊蓑稔脈妙粍民眠務夢無牟矛霧鵡椋婿娘冥名命明盟迷銘鳴姪牝滅免棉綿緬面麺摸模茂妄孟毛猛盲網耗蒙儲木黙目杢勿餅尤戻籾貰問悶紋門匁也冶夜爺耶野弥矢厄役約薬訳躍靖柳薮鑓愉愈油癒"], ["9740", "諭輸唯佑優勇友宥幽悠憂揖有柚湧涌猶猷由祐裕誘遊邑郵雄融夕予余与誉輿預傭幼妖容庸揚揺擁曜楊様洋溶熔用窯羊耀葉蓉要謡踊遥陽養慾抑欲"], ["9780", "沃浴翌翼淀羅螺裸来莱頼雷洛絡落酪乱卵嵐欄濫藍蘭覧利吏履李梨理璃痢裏裡里離陸律率立葎掠略劉流溜琉留硫粒隆竜龍侶慮旅虜了亮僚両凌寮料梁涼猟療瞭稜糧良諒遼量陵領力緑倫厘林淋燐琳臨輪隣鱗麟瑠塁涙累類令伶例冷励嶺怜玲礼苓鈴隷零霊麗齢暦歴列劣烈裂廉恋憐漣煉簾練聯"], ["9840", "蓮連錬呂魯櫓炉賂路露労婁廊弄朗楼榔浪漏牢狼篭老聾蝋郎六麓禄肋録論倭和話歪賄脇惑枠鷲亙亘鰐詫藁蕨椀湾碗腕"], ["989f", "弌丐丕个丱丶丼丿乂乖乘亂亅豫亊舒弍于亞亟亠亢亰亳亶从仍仄仆仂仗仞仭仟价伉佚估佛佝佗佇佶侈侏侘佻佩佰侑佯來侖儘俔俟俎俘俛俑俚俐俤俥倚倨倔倪倥倅伜俶倡倩倬俾俯們倆偃假會偕偐偈做偖偬偸傀傚傅傴傲"], ["9940", "僉僊傳僂僖僞僥僭僣僮價僵儉儁儂儖儕儔儚儡儺儷儼儻儿兀兒兌兔兢竸兩兪兮冀冂囘册冉冏冑冓冕冖冤冦冢冩冪冫决冱冲冰况冽凅凉凛几處凩凭"], ["9980", "凰凵凾刄刋刔刎刧刪刮刳刹剏剄剋剌剞剔剪剴剩剳剿剽劍劔劒剱劈劑辨辧劬劭劼劵勁勍勗勞勣勦飭勠勳勵勸勹匆匈甸匍匐匏匕匚匣匯匱匳匸區卆卅丗卉卍凖卞卩卮夘卻卷厂厖厠厦厥厮厰厶參簒雙叟曼燮叮叨叭叺吁吽呀听吭吼吮吶吩吝呎咏呵咎呟呱呷呰咒呻咀呶咄咐咆哇咢咸咥咬哄哈咨"], ["9a40", "咫哂咤咾咼哘哥哦唏唔哽哮哭哺哢唹啀啣啌售啜啅啖啗唸唳啝喙喀咯喊喟啻啾喘喞單啼喃喩喇喨嗚嗅嗟嗄嗜嗤嗔嘔嗷嘖嗾嗽嘛嗹噎噐營嘴嘶嘲嘸"], ["9a80", "噫噤嘯噬噪嚆嚀嚊嚠嚔嚏嚥嚮嚶嚴囂嚼囁囃囀囈囎囑囓囗囮囹圀囿圄圉圈國圍圓團圖嗇圜圦圷圸坎圻址坏坩埀垈坡坿垉垓垠垳垤垪垰埃埆埔埒埓堊埖埣堋堙堝塲堡塢塋塰毀塒堽塹墅墹墟墫墺壞墻墸墮壅壓壑壗壙壘壥壜壤壟壯壺壹壻壼壽夂夊夐夛梦夥夬夭夲夸夾竒奕奐奎奚奘奢奠奧奬奩"], ["9b40", "奸妁妝佞侫妣妲姆姨姜妍姙姚娥娟娑娜娉娚婀婬婉娵娶婢婪媚媼媾嫋嫂媽嫣嫗嫦嫩嫖嫺嫻嬌嬋嬖嬲嫐嬪嬶嬾孃孅孀孑孕孚孛孥孩孰孳孵學斈孺宀"], ["9b80", "它宦宸寃寇寉寔寐寤實寢寞寥寫寰寶寳尅將專對尓尠尢尨尸尹屁屆屎屓屐屏孱屬屮乢屶屹岌岑岔妛岫岻岶岼岷峅岾峇峙峩峽峺峭嶌峪崋崕崗嵜崟崛崑崔崢崚崙崘嵌嵒嵎嵋嵬嵳嵶嶇嶄嶂嶢嶝嶬嶮嶽嶐嶷嶼巉巍巓巒巖巛巫已巵帋帚帙帑帛帶帷幄幃幀幎幗幔幟幢幤幇幵并幺麼广庠廁廂廈廐廏"], ["9c40", "廖廣廝廚廛廢廡廨廩廬廱廳廰廴廸廾弃弉彝彜弋弑弖弩弭弸彁彈彌彎弯彑彖彗彙彡彭彳彷徃徂彿徊很徑徇從徙徘徠徨徭徼忖忻忤忸忱忝悳忿怡恠"], ["9c80", "怙怐怩怎怱怛怕怫怦怏怺恚恁恪恷恟恊恆恍恣恃恤恂恬恫恙悁悍惧悃悚悄悛悖悗悒悧悋惡悸惠惓悴忰悽惆悵惘慍愕愆惶惷愀惴惺愃愡惻惱愍愎慇愾愨愧慊愿愼愬愴愽慂慄慳慷慘慙慚慫慴慯慥慱慟慝慓慵憙憖憇憬憔憚憊憑憫憮懌懊應懷懈懃懆憺懋罹懍懦懣懶懺懴懿懽懼懾戀戈戉戍戌戔戛"], ["9d40", "戞戡截戮戰戲戳扁扎扞扣扛扠扨扼抂抉找抒抓抖拔抃抔拗拑抻拏拿拆擔拈拜拌拊拂拇抛拉挌拮拱挧挂挈拯拵捐挾捍搜捏掖掎掀掫捶掣掏掉掟掵捫"], ["9d80", "捩掾揩揀揆揣揉插揶揄搖搴搆搓搦搶攝搗搨搏摧摯摶摎攪撕撓撥撩撈撼據擒擅擇撻擘擂擱擧舉擠擡抬擣擯攬擶擴擲擺攀擽攘攜攅攤攣攫攴攵攷收攸畋效敖敕敍敘敞敝敲數斂斃變斛斟斫斷旃旆旁旄旌旒旛旙无旡旱杲昊昃旻杳昵昶昴昜晏晄晉晁晞晝晤晧晨晟晢晰暃暈暎暉暄暘暝曁暹曉暾暼"], ["9e40", "曄暸曖曚曠昿曦曩曰曵曷朏朖朞朦朧霸朮朿朶杁朸朷杆杞杠杙杣杤枉杰枩杼杪枌枋枦枡枅枷柯枴柬枳柩枸柤柞柝柢柮枹柎柆柧檜栞框栩桀桍栲桎"], ["9e80", "梳栫桙档桷桿梟梏梭梔條梛梃檮梹桴梵梠梺椏梍桾椁棊椈棘椢椦棡椌棍棔棧棕椶椒椄棗棣椥棹棠棯椨椪椚椣椡棆楹楷楜楸楫楔楾楮椹楴椽楙椰楡楞楝榁楪榲榮槐榿槁槓榾槎寨槊槝榻槃榧樮榑榠榜榕榴槞槨樂樛槿權槹槲槧樅榱樞槭樔槫樊樒櫁樣樓橄樌橲樶橸橇橢橙橦橈樸樢檐檍檠檄檢檣"], ["9f40", "檗蘗檻櫃櫂檸檳檬櫞櫑櫟檪櫚櫪櫻欅蘖櫺欒欖鬱欟欸欷盜欹飮歇歃歉歐歙歔歛歟歡歸歹歿殀殄殃殍殘殕殞殤殪殫殯殲殱殳殷殼毆毋毓毟毬毫毳毯"], ["9f80", "麾氈氓气氛氤氣汞汕汢汪沂沍沚沁沛汾汨汳沒沐泄泱泓沽泗泅泝沮沱沾沺泛泯泙泪洟衍洶洫洽洸洙洵洳洒洌浣涓浤浚浹浙涎涕濤涅淹渕渊涵淇淦涸淆淬淞淌淨淒淅淺淙淤淕淪淮渭湮渮渙湲湟渾渣湫渫湶湍渟湃渺湎渤滿渝游溂溪溘滉溷滓溽溯滄溲滔滕溏溥滂溟潁漑灌滬滸滾漿滲漱滯漲滌"], ["e040", "漾漓滷澆潺潸澁澀潯潛濳潭澂潼潘澎澑濂潦澳澣澡澤澹濆澪濟濕濬濔濘濱濮濛瀉瀋濺瀑瀁瀏濾瀛瀚潴瀝瀘瀟瀰瀾瀲灑灣炙炒炯烱炬炸炳炮烟烋烝"], ["e080", "烙焉烽焜焙煥煕熈煦煢煌煖煬熏燻熄熕熨熬燗熹熾燒燉燔燎燠燬燧燵燼燹燿爍爐爛爨爭爬爰爲爻爼爿牀牆牋牘牴牾犂犁犇犒犖犢犧犹犲狃狆狄狎狒狢狠狡狹狷倏猗猊猜猖猝猴猯猩猥猾獎獏默獗獪獨獰獸獵獻獺珈玳珎玻珀珥珮珞璢琅瑯琥珸琲琺瑕琿瑟瑙瑁瑜瑩瑰瑣瑪瑶瑾璋璞璧瓊瓏瓔珱"], ["e140", "瓠瓣瓧瓩瓮瓲瓰瓱瓸瓷甄甃甅甌甎甍甕甓甞甦甬甼畄畍畊畉畛畆畚畩畤畧畫畭畸當疆疇畴疊疉疂疔疚疝疥疣痂疳痃疵疽疸疼疱痍痊痒痙痣痞痾痿"], ["e180", "痼瘁痰痺痲痳瘋瘍瘉瘟瘧瘠瘡瘢瘤瘴瘰瘻癇癈癆癜癘癡癢癨癩癪癧癬癰癲癶癸發皀皃皈皋皎皖皓皙皚皰皴皸皹皺盂盍盖盒盞盡盥盧盪蘯盻眈眇眄眩眤眞眥眦眛眷眸睇睚睨睫睛睥睿睾睹瞎瞋瞑瞠瞞瞰瞶瞹瞿瞼瞽瞻矇矍矗矚矜矣矮矼砌砒礦砠礪硅碎硴碆硼碚碌碣碵碪碯磑磆磋磔碾碼磅磊磬"], ["e240", "磧磚磽磴礇礒礑礙礬礫祀祠祗祟祚祕祓祺祿禊禝禧齋禪禮禳禹禺秉秕秧秬秡秣稈稍稘稙稠稟禀稱稻稾稷穃穗穉穡穢穩龝穰穹穽窈窗窕窘窖窩竈窰"], ["e280", "窶竅竄窿邃竇竊竍竏竕竓站竚竝竡竢竦竭竰笂笏笊笆笳笘笙笞笵笨笶筐筺笄筍笋筌筅筵筥筴筧筰筱筬筮箝箘箟箍箜箚箋箒箏筝箙篋篁篌篏箴篆篝篩簑簔篦篥籠簀簇簓篳篷簗簍篶簣簧簪簟簷簫簽籌籃籔籏籀籐籘籟籤籖籥籬籵粃粐粤粭粢粫粡粨粳粲粱粮粹粽糀糅糂糘糒糜糢鬻糯糲糴糶糺紆"], ["e340", "紂紜紕紊絅絋紮紲紿紵絆絳絖絎絲絨絮絏絣經綉絛綏絽綛綺綮綣綵緇綽綫總綢綯緜綸綟綰緘緝緤緞緻緲緡縅縊縣縡縒縱縟縉縋縢繆繦縻縵縹繃縷"], ["e380", "縲縺繧繝繖繞繙繚繹繪繩繼繻纃緕繽辮繿纈纉續纒纐纓纔纖纎纛纜缸缺罅罌罍罎罐网罕罔罘罟罠罨罩罧罸羂羆羃羈羇羌羔羞羝羚羣羯羲羹羮羶羸譱翅翆翊翕翔翡翦翩翳翹飜耆耄耋耒耘耙耜耡耨耿耻聊聆聒聘聚聟聢聨聳聲聰聶聹聽聿肄肆肅肛肓肚肭冐肬胛胥胙胝胄胚胖脉胯胱脛脩脣脯腋"], ["e440", "隋腆脾腓腑胼腱腮腥腦腴膃膈膊膀膂膠膕膤膣腟膓膩膰膵膾膸膽臀臂膺臉臍臑臙臘臈臚臟臠臧臺臻臾舁舂舅與舊舍舐舖舩舫舸舳艀艙艘艝艚艟艤"], ["e480", "艢艨艪艫舮艱艷艸艾芍芒芫芟芻芬苡苣苟苒苴苳苺莓范苻苹苞茆苜茉苙茵茴茖茲茱荀茹荐荅茯茫茗茘莅莚莪莟莢莖茣莎莇莊荼莵荳荵莠莉莨菴萓菫菎菽萃菘萋菁菷萇菠菲萍萢萠莽萸蔆菻葭萪萼蕚蒄葷葫蒭葮蒂葩葆萬葯葹萵蓊葢蒹蒿蒟蓙蓍蒻蓚蓐蓁蓆蓖蒡蔡蓿蓴蔗蔘蔬蔟蔕蔔蓼蕀蕣蕘蕈"], ["e540", "蕁蘂蕋蕕薀薤薈薑薊薨蕭薔薛藪薇薜蕷蕾薐藉薺藏薹藐藕藝藥藜藹蘊蘓蘋藾藺蘆蘢蘚蘰蘿虍乕虔號虧虱蚓蚣蚩蚪蚋蚌蚶蚯蛄蛆蚰蛉蠣蚫蛔蛞蛩蛬"], ["e580", "蛟蛛蛯蜒蜆蜈蜀蜃蛻蜑蜉蜍蛹蜊蜴蜿蜷蜻蜥蜩蜚蝠蝟蝸蝌蝎蝴蝗蝨蝮蝙蝓蝣蝪蠅螢螟螂螯蟋螽蟀蟐雖螫蟄螳蟇蟆螻蟯蟲蟠蠏蠍蟾蟶蟷蠎蟒蠑蠖蠕蠢蠡蠱蠶蠹蠧蠻衄衂衒衙衞衢衫袁衾袞衵衽袵衲袂袗袒袮袙袢袍袤袰袿袱裃裄裔裘裙裝裹褂裼裴裨裲褄褌褊褓襃褞褥褪褫襁襄褻褶褸襌褝襠襞"], ["e640", "襦襤襭襪襯襴襷襾覃覈覊覓覘覡覩覦覬覯覲覺覽覿觀觚觜觝觧觴觸訃訖訐訌訛訝訥訶詁詛詒詆詈詼詭詬詢誅誂誄誨誡誑誥誦誚誣諄諍諂諚諫諳諧"], ["e680", "諤諱謔諠諢諷諞諛謌謇謚諡謖謐謗謠謳鞫謦謫謾謨譁譌譏譎證譖譛譚譫譟譬譯譴譽讀讌讎讒讓讖讙讚谺豁谿豈豌豎豐豕豢豬豸豺貂貉貅貊貍貎貔豼貘戝貭貪貽貲貳貮貶賈賁賤賣賚賽賺賻贄贅贊贇贏贍贐齎贓賍贔贖赧赭赱赳趁趙跂趾趺跏跚跖跌跛跋跪跫跟跣跼踈踉跿踝踞踐踟蹂踵踰踴蹊"], ["e740", "蹇蹉蹌蹐蹈蹙蹤蹠踪蹣蹕蹶蹲蹼躁躇躅躄躋躊躓躑躔躙躪躡躬躰軆躱躾軅軈軋軛軣軼軻軫軾輊輅輕輒輙輓輜輟輛輌輦輳輻輹轅轂輾轌轉轆轎轗轜"], ["e780", "轢轣轤辜辟辣辭辯辷迚迥迢迪迯邇迴逅迹迺逑逕逡逍逞逖逋逧逶逵逹迸遏遐遑遒逎遉逾遖遘遞遨遯遶隨遲邂遽邁邀邊邉邏邨邯邱邵郢郤扈郛鄂鄒鄙鄲鄰酊酖酘酣酥酩酳酲醋醉醂醢醫醯醪醵醴醺釀釁釉釋釐釖釟釡釛釼釵釶鈞釿鈔鈬鈕鈑鉞鉗鉅鉉鉤鉈銕鈿鉋鉐銜銖銓銛鉚鋏銹銷鋩錏鋺鍄錮"], ["e840", "錙錢錚錣錺錵錻鍜鍠鍼鍮鍖鎰鎬鎭鎔鎹鏖鏗鏨鏥鏘鏃鏝鏐鏈鏤鐚鐔鐓鐃鐇鐐鐶鐫鐵鐡鐺鑁鑒鑄鑛鑠鑢鑞鑪鈩鑰鑵鑷鑽鑚鑼鑾钁鑿閂閇閊閔閖閘閙"], ["e880", "閠閨閧閭閼閻閹閾闊濶闃闍闌闕闔闖關闡闥闢阡阨阮阯陂陌陏陋陷陜陞陝陟陦陲陬隍隘隕隗險隧隱隲隰隴隶隸隹雎雋雉雍襍雜霍雕雹霄霆霈霓霎霑霏霖霙霤霪霰霹霽霾靄靆靈靂靉靜靠靤靦靨勒靫靱靹鞅靼鞁靺鞆鞋鞏鞐鞜鞨鞦鞣鞳鞴韃韆韈韋韜韭齏韲竟韶韵頏頌頸頤頡頷頽顆顏顋顫顯顰"], ["e940", "顱顴顳颪颯颱颶飄飃飆飩飫餃餉餒餔餘餡餝餞餤餠餬餮餽餾饂饉饅饐饋饑饒饌饕馗馘馥馭馮馼駟駛駝駘駑駭駮駱駲駻駸騁騏騅駢騙騫騷驅驂驀驃"], ["e980", "騾驕驍驛驗驟驢驥驤驩驫驪骭骰骼髀髏髑髓體髞髟髢髣髦髯髫髮髴髱髷髻鬆鬘鬚鬟鬢鬣鬥鬧鬨鬩鬪鬮鬯鬲魄魃魏魍魎魑魘魴鮓鮃鮑鮖鮗鮟鮠鮨鮴鯀鯊鮹鯆鯏鯑鯒鯣鯢鯤鯔鯡鰺鯲鯱鯰鰕鰔鰉鰓鰌鰆鰈鰒鰊鰄鰮鰛鰥鰤鰡鰰鱇鰲鱆鰾鱚鱠鱧鱶鱸鳧鳬鳰鴉鴈鳫鴃鴆鴪鴦鶯鴣鴟鵄鴕鴒鵁鴿鴾鵆鵈"], ["ea40", "鵝鵞鵤鵑鵐鵙鵲鶉鶇鶫鵯鵺鶚鶤鶩鶲鷄鷁鶻鶸鶺鷆鷏鷂鷙鷓鷸鷦鷭鷯鷽鸚鸛鸞鹵鹹鹽麁麈麋麌麒麕麑麝麥麩麸麪麭靡黌黎黏黐黔黜點黝黠黥黨黯"], ["ea80", "黴黶黷黹黻黼黽鼇鼈皷鼕鼡鼬鼾齊齒齔齣齟齠齡齦齧齬齪齷齲齶龕龜龠堯槇遙瑤凜熙"], ["ed40", "纊褜鍈銈蓜俉炻昱棈鋹曻彅丨仡仼伀伃伹佖侒侊侚侔俍偀倢俿倞偆偰偂傔僴僘兊兤冝冾凬刕劜劦勀勛匀匇匤卲厓厲叝﨎咜咊咩哿喆坙坥垬埈埇﨏"], ["ed80", "塚增墲夋奓奛奝奣妤妺孖寀甯寘寬尞岦岺峵崧嵓﨑嵂嵭嶸嶹巐弡弴彧德忞恝悅悊惞惕愠惲愑愷愰憘戓抦揵摠撝擎敎昀昕昻昉昮昞昤晥晗晙晴晳暙暠暲暿曺朎朗杦枻桒柀栁桄棏﨓楨﨔榘槢樰橫橆橳橾櫢櫤毖氿汜沆汯泚洄涇浯涖涬淏淸淲淼渹湜渧渼溿澈澵濵瀅瀇瀨炅炫焏焄煜煆煇凞燁燾犱"], ["ee40", "犾猤猪獷玽珉珖珣珒琇珵琦琪琩琮瑢璉璟甁畯皂皜皞皛皦益睆劯砡硎硤硺礰礼神祥禔福禛竑竧靖竫箞精絈絜綷綠緖繒罇羡羽茁荢荿菇菶葈蒴蕓蕙"], ["ee80", "蕫﨟薰蘒﨡蠇裵訒訷詹誧誾諟諸諶譓譿賰賴贒赶﨣軏﨤逸遧郞都鄕鄧釚釗釞釭釮釤釥鈆鈐鈊鈺鉀鈼鉎鉙鉑鈹鉧銧鉷鉸鋧鋗鋙鋐﨧鋕鋠鋓錥錡鋻﨨錞鋿錝錂鍰鍗鎤鏆鏞鏸鐱鑅鑈閒隆﨩隝隯霳霻靃靍靏靑靕顗顥飯飼餧館馞驎髙髜魵魲鮏鮱鮻鰀鵰鵫鶴鸙黑"], ["eeef", "ⅰ", 9, "¬¦'""], ["f040", "", 62], ["f080", "", 124], ["f140", "", 62], ["f180", "", 124], ["f240", "", 62], ["f280", "", 124], ["f340", "", 62], ["f380", "", 124], ["f440", "", 62], ["f480", "", 124], ["f540", "", 62], ["f580", "", 124], ["f640", "", 62], ["f680", "", 124], ["f740", "", 62], ["f780", "", 124], ["f840", "", 62], ["f880", "", 124], ["f940", ""], ["fa40", "ⅰ", 9, "Ⅰ", 9, "¬¦'"㈱№℡∵纊褜鍈銈蓜俉炻昱棈鋹曻彅丨仡仼伀伃伹佖侒侊侚侔俍偀倢俿倞偆偰偂傔僴僘兊"], ["fa80", "兤冝冾凬刕劜劦勀勛匀匇匤卲厓厲叝﨎咜咊咩哿喆坙坥垬埈埇﨏塚增墲夋奓奛奝奣妤妺孖寀甯寘寬尞岦岺峵崧嵓﨑嵂嵭嶸嶹巐弡弴彧德忞恝悅悊惞惕愠惲愑愷愰憘戓抦揵摠撝擎敎昀昕昻昉昮昞昤晥晗晙晴晳暙暠暲暿曺朎朗杦枻桒柀栁桄棏﨓楨﨔榘槢樰橫橆橳橾櫢櫤毖氿汜沆汯泚洄涇浯"], ["fb40", "涖涬淏淸淲淼渹湜渧渼溿澈澵濵瀅瀇瀨炅炫焏焄煜煆煇凞燁燾犱犾猤猪獷玽珉珖珣珒琇珵琦琪琩琮瑢璉璟甁畯皂皜皞皛皦益睆劯砡硎硤硺礰礼神"], ["fb80", "祥禔福禛竑竧靖竫箞精絈絜綷綠緖繒罇羡羽茁荢荿菇菶葈蒴蕓蕙蕫﨟薰蘒﨡蠇裵訒訷詹誧誾諟諸諶譓譿賰賴贒赶﨣軏﨤逸遧郞都鄕鄧釚釗釞釭釮釤釥鈆鈐鈊鈺鉀鈼鉎鉙鉑鈹鉧銧鉷鉸鋧鋗鋙鋐﨧鋕鋠鋓錥錡鋻﨨錞鋿錝錂鍰鍗鎤鏆鏞鏸鐱鑅鑈閒隆﨩隝隯霳霻靃靍靏靑靕顗顥飯飼餧館馞驎髙"], ["fc40", "髜魵魲鮏鮱鮻鰀鵰鵫鶴鸙黑"]]; + +var shiftjis$1 = Object.freeze({ + default: shiftjis +}); + +var eucjp = [["0", "\0", 127], ["8ea1", "。", 62], ["a1a1", " 、。,.・:;?!゛゜´`¨^ ̄_ヽヾゝゞ〃仝々〆〇ー―‐/\~∥|…‥‘’“”()〔〕[]{}〈", 9, "+-±×÷=≠<>≦≧∞∴♂♀°′″℃¥$¢£%#&*@§☆★○●◎◇"], ["a2a1", "◆□■△▲▽▼※〒→←↑↓〓"], ["a2ba", "∈∋⊆⊇⊂⊃∪∩"], ["a2ca", "∧∨¬⇒⇔∀∃"], ["a2dc", "∠⊥⌒∂∇≡≒≪≫√∽∝∵∫∬"], ["a2f2", "ʼn♯♭♪†‡¶"], ["a2fe", "◯"], ["a3b0", "0", 9], ["a3c1", "A", 25], ["a3e1", "a", 25], ["a4a1", "ぁ", 82], ["a5a1", "ァ", 85], ["a6a1", "Α", 16, "Σ", 6], ["a6c1", "α", 16, "σ", 6], ["a7a1", "А", 5, "ЁЖ", 25], ["a7d1", "а", 5, "ёж", 25], ["a8a1", "─│┌┐┘└├┬┤┴┼━┃┏┓┛┗┣┳┫┻╋┠┯┨┷┿┝┰┥┸╂"], ["ada1", "①", 19, "Ⅰ", 9], ["adc0", "㍉㌔㌢㍍㌘㌧㌃㌶㍑㍗㌍㌦㌣㌫㍊㌻㎜㎝㎞㎎㎏㏄㎡"], ["addf", "㍻〝〟№㏍℡㊤", 4, "㈱㈲㈹㍾㍽㍼≒≡∫∮∑√⊥∠∟⊿∵∩∪"], ["b0a1", "亜唖娃阿哀愛挨姶逢葵茜穐悪握渥旭葦芦鯵梓圧斡扱宛姐虻飴絢綾鮎或粟袷安庵按暗案闇鞍杏以伊位依偉囲夷委威尉惟意慰易椅為畏異移維緯胃萎衣謂違遺医井亥域育郁磯一壱溢逸稲茨芋鰯允印咽員因姻引飲淫胤蔭"], ["b1a1", "院陰隠韻吋右宇烏羽迂雨卯鵜窺丑碓臼渦嘘唄欝蔚鰻姥厩浦瓜閏噂云運雲荏餌叡営嬰影映曳栄永泳洩瑛盈穎頴英衛詠鋭液疫益駅悦謁越閲榎厭円園堰奄宴延怨掩援沿演炎焔煙燕猿縁艶苑薗遠鉛鴛塩於汚甥凹央奥往応"], ["b2a1", "押旺横欧殴王翁襖鴬鴎黄岡沖荻億屋憶臆桶牡乙俺卸恩温穏音下化仮何伽価佳加可嘉夏嫁家寡科暇果架歌河火珂禍禾稼箇花苛茄荷華菓蝦課嘩貨迦過霞蚊俄峨我牙画臥芽蛾賀雅餓駕介会解回塊壊廻快怪悔恢懐戒拐改"], ["b3a1", "魁晦械海灰界皆絵芥蟹開階貝凱劾外咳害崖慨概涯碍蓋街該鎧骸浬馨蛙垣柿蛎鈎劃嚇各廓拡撹格核殻獲確穫覚角赫較郭閣隔革学岳楽額顎掛笠樫橿梶鰍潟割喝恰括活渇滑葛褐轄且鰹叶椛樺鞄株兜竃蒲釜鎌噛鴨栢茅萱"], ["b4a1", "粥刈苅瓦乾侃冠寒刊勘勧巻喚堪姦完官寛干幹患感慣憾換敢柑桓棺款歓汗漢澗潅環甘監看竿管簡緩缶翰肝艦莞観諌貫還鑑間閑関陥韓館舘丸含岸巌玩癌眼岩翫贋雁頑顔願企伎危喜器基奇嬉寄岐希幾忌揮机旗既期棋棄"], ["b5a1", "機帰毅気汽畿祈季稀紀徽規記貴起軌輝飢騎鬼亀偽儀妓宜戯技擬欺犠疑祇義蟻誼議掬菊鞠吉吃喫桔橘詰砧杵黍却客脚虐逆丘久仇休及吸宮弓急救朽求汲泣灸球究窮笈級糾給旧牛去居巨拒拠挙渠虚許距鋸漁禦魚亨享京"], ["b6a1", "供侠僑兇競共凶協匡卿叫喬境峡強彊怯恐恭挟教橋況狂狭矯胸脅興蕎郷鏡響饗驚仰凝尭暁業局曲極玉桐粁僅勤均巾錦斤欣欽琴禁禽筋緊芹菌衿襟謹近金吟銀九倶句区狗玖矩苦躯駆駈駒具愚虞喰空偶寓遇隅串櫛釧屑屈"], ["b7a1", "掘窟沓靴轡窪熊隈粂栗繰桑鍬勲君薫訓群軍郡卦袈祁係傾刑兄啓圭珪型契形径恵慶慧憩掲携敬景桂渓畦稽系経継繋罫茎荊蛍計詣警軽頚鶏芸迎鯨劇戟撃激隙桁傑欠決潔穴結血訣月件倹倦健兼券剣喧圏堅嫌建憲懸拳捲"], ["b8a1", "検権牽犬献研硯絹県肩見謙賢軒遣鍵険顕験鹸元原厳幻弦減源玄現絃舷言諺限乎個古呼固姑孤己庫弧戸故枯湖狐糊袴股胡菰虎誇跨鈷雇顧鼓五互伍午呉吾娯後御悟梧檎瑚碁語誤護醐乞鯉交佼侯候倖光公功効勾厚口向"], ["b9a1", "后喉坑垢好孔孝宏工巧巷幸広庚康弘恒慌抗拘控攻昂晃更杭校梗構江洪浩港溝甲皇硬稿糠紅紘絞綱耕考肯肱腔膏航荒行衡講貢購郊酵鉱砿鋼閤降項香高鴻剛劫号合壕拷濠豪轟麹克刻告国穀酷鵠黒獄漉腰甑忽惚骨狛込"], ["baa1", "此頃今困坤墾婚恨懇昏昆根梱混痕紺艮魂些佐叉唆嵯左差査沙瑳砂詐鎖裟坐座挫債催再最哉塞妻宰彩才採栽歳済災采犀砕砦祭斎細菜裁載際剤在材罪財冴坂阪堺榊肴咲崎埼碕鷺作削咋搾昨朔柵窄策索錯桜鮭笹匙冊刷"], ["bba1", "察拶撮擦札殺薩雑皐鯖捌錆鮫皿晒三傘参山惨撒散桟燦珊産算纂蚕讃賛酸餐斬暫残仕仔伺使刺司史嗣四士始姉姿子屍市師志思指支孜斯施旨枝止死氏獅祉私糸紙紫肢脂至視詞詩試誌諮資賜雌飼歯事似侍児字寺慈持時"], ["bca1", "次滋治爾璽痔磁示而耳自蒔辞汐鹿式識鴫竺軸宍雫七叱執失嫉室悉湿漆疾質実蔀篠偲柴芝屡蕊縞舎写射捨赦斜煮社紗者謝車遮蛇邪借勺尺杓灼爵酌釈錫若寂弱惹主取守手朱殊狩珠種腫趣酒首儒受呪寿授樹綬需囚収周"], ["bda1", "宗就州修愁拾洲秀秋終繍習臭舟蒐衆襲讐蹴輯週酋酬集醜什住充十従戎柔汁渋獣縦重銃叔夙宿淑祝縮粛塾熟出術述俊峻春瞬竣舜駿准循旬楯殉淳準潤盾純巡遵醇順処初所暑曙渚庶緒署書薯藷諸助叙女序徐恕鋤除傷償"], ["bea1", "勝匠升召哨商唱嘗奨妾娼宵将小少尚庄床廠彰承抄招掌捷昇昌昭晶松梢樟樵沼消渉湘焼焦照症省硝礁祥称章笑粧紹肖菖蒋蕉衝裳訟証詔詳象賞醤鉦鍾鐘障鞘上丈丞乗冗剰城場壌嬢常情擾条杖浄状畳穣蒸譲醸錠嘱埴飾"], ["bfa1", "拭植殖燭織職色触食蝕辱尻伸信侵唇娠寝審心慎振新晋森榛浸深申疹真神秦紳臣芯薪親診身辛進針震人仁刃塵壬尋甚尽腎訊迅陣靭笥諏須酢図厨逗吹垂帥推水炊睡粋翠衰遂酔錐錘随瑞髄崇嵩数枢趨雛据杉椙菅頗雀裾"], ["c0a1", "澄摺寸世瀬畝是凄制勢姓征性成政整星晴棲栖正清牲生盛精聖声製西誠誓請逝醒青静斉税脆隻席惜戚斥昔析石積籍績脊責赤跡蹟碩切拙接摂折設窃節説雪絶舌蝉仙先千占宣専尖川戦扇撰栓栴泉浅洗染潜煎煽旋穿箭線"], ["c1a1", "繊羨腺舛船薦詮賎践選遷銭銑閃鮮前善漸然全禅繕膳糎噌塑岨措曾曽楚狙疏疎礎祖租粗素組蘇訴阻遡鼠僧創双叢倉喪壮奏爽宋層匝惣想捜掃挿掻操早曹巣槍槽漕燥争痩相窓糟総綜聡草荘葬蒼藻装走送遭鎗霜騒像増憎"], ["c2a1", "臓蔵贈造促側則即息捉束測足速俗属賊族続卒袖其揃存孫尊損村遜他多太汰詑唾堕妥惰打柁舵楕陀駄騨体堆対耐岱帯待怠態戴替泰滞胎腿苔袋貸退逮隊黛鯛代台大第醍題鷹滝瀧卓啄宅托択拓沢濯琢託鐸濁諾茸凧蛸只"], ["c3a1", "叩但達辰奪脱巽竪辿棚谷狸鱈樽誰丹単嘆坦担探旦歎淡湛炭短端箪綻耽胆蛋誕鍛団壇弾断暖檀段男談値知地弛恥智池痴稚置致蜘遅馳築畜竹筑蓄逐秩窒茶嫡着中仲宙忠抽昼柱注虫衷註酎鋳駐樗瀦猪苧著貯丁兆凋喋寵"], ["c4a1", "帖帳庁弔張彫徴懲挑暢朝潮牒町眺聴脹腸蝶調諜超跳銚長頂鳥勅捗直朕沈珍賃鎮陳津墜椎槌追鎚痛通塚栂掴槻佃漬柘辻蔦綴鍔椿潰坪壷嬬紬爪吊釣鶴亭低停偵剃貞呈堤定帝底庭廷弟悌抵挺提梯汀碇禎程締艇訂諦蹄逓"], ["c5a1", "邸鄭釘鼎泥摘擢敵滴的笛適鏑溺哲徹撤轍迭鉄典填天展店添纏甜貼転顛点伝殿澱田電兎吐堵塗妬屠徒斗杜渡登菟賭途都鍍砥砺努度土奴怒倒党冬凍刀唐塔塘套宕島嶋悼投搭東桃梼棟盗淘湯涛灯燈当痘祷等答筒糖統到"], ["c6a1", "董蕩藤討謄豆踏逃透鐙陶頭騰闘働動同堂導憧撞洞瞳童胴萄道銅峠鴇匿得徳涜特督禿篤毒独読栃橡凸突椴届鳶苫寅酉瀞噸屯惇敦沌豚遁頓呑曇鈍奈那内乍凪薙謎灘捺鍋楢馴縄畷南楠軟難汝二尼弐迩匂賑肉虹廿日乳入"], ["c7a1", "如尿韮任妊忍認濡禰祢寧葱猫熱年念捻撚燃粘乃廼之埜嚢悩濃納能脳膿農覗蚤巴把播覇杷波派琶破婆罵芭馬俳廃拝排敗杯盃牌背肺輩配倍培媒梅楳煤狽買売賠陪這蝿秤矧萩伯剥博拍柏泊白箔粕舶薄迫曝漠爆縛莫駁麦"], ["c8a1", "函箱硲箸肇筈櫨幡肌畑畠八鉢溌発醗髪伐罰抜筏閥鳩噺塙蛤隼伴判半反叛帆搬斑板氾汎版犯班畔繁般藩販範釆煩頒飯挽晩番盤磐蕃蛮匪卑否妃庇彼悲扉批披斐比泌疲皮碑秘緋罷肥被誹費避非飛樋簸備尾微枇毘琵眉美"], ["c9a1", "鼻柊稗匹疋髭彦膝菱肘弼必畢筆逼桧姫媛紐百謬俵彪標氷漂瓢票表評豹廟描病秒苗錨鋲蒜蛭鰭品彬斌浜瀕貧賓頻敏瓶不付埠夫婦富冨布府怖扶敷斧普浮父符腐膚芙譜負賦赴阜附侮撫武舞葡蕪部封楓風葺蕗伏副復幅服"], ["caa1", "福腹複覆淵弗払沸仏物鮒分吻噴墳憤扮焚奮粉糞紛雰文聞丙併兵塀幣平弊柄並蔽閉陛米頁僻壁癖碧別瞥蔑箆偏変片篇編辺返遍便勉娩弁鞭保舗鋪圃捕歩甫補輔穂募墓慕戊暮母簿菩倣俸包呆報奉宝峰峯崩庖抱捧放方朋"], ["cba1", "法泡烹砲縫胞芳萌蓬蜂褒訪豊邦鋒飽鳳鵬乏亡傍剖坊妨帽忘忙房暴望某棒冒紡肪膨謀貌貿鉾防吠頬北僕卜墨撲朴牧睦穆釦勃没殆堀幌奔本翻凡盆摩磨魔麻埋妹昧枚毎哩槙幕膜枕鮪柾鱒桝亦俣又抹末沫迄侭繭麿万慢満"], ["cca1", "漫蔓味未魅巳箕岬密蜜湊蓑稔脈妙粍民眠務夢無牟矛霧鵡椋婿娘冥名命明盟迷銘鳴姪牝滅免棉綿緬面麺摸模茂妄孟毛猛盲網耗蒙儲木黙目杢勿餅尤戻籾貰問悶紋門匁也冶夜爺耶野弥矢厄役約薬訳躍靖柳薮鑓愉愈油癒"], ["cda1", "諭輸唯佑優勇友宥幽悠憂揖有柚湧涌猶猷由祐裕誘遊邑郵雄融夕予余与誉輿預傭幼妖容庸揚揺擁曜楊様洋溶熔用窯羊耀葉蓉要謡踊遥陽養慾抑欲沃浴翌翼淀羅螺裸来莱頼雷洛絡落酪乱卵嵐欄濫藍蘭覧利吏履李梨理璃"], ["cea1", "痢裏裡里離陸律率立葎掠略劉流溜琉留硫粒隆竜龍侶慮旅虜了亮僚両凌寮料梁涼猟療瞭稜糧良諒遼量陵領力緑倫厘林淋燐琳臨輪隣鱗麟瑠塁涙累類令伶例冷励嶺怜玲礼苓鈴隷零霊麗齢暦歴列劣烈裂廉恋憐漣煉簾練聯"], ["cfa1", "蓮連錬呂魯櫓炉賂路露労婁廊弄朗楼榔浪漏牢狼篭老聾蝋郎六麓禄肋録論倭和話歪賄脇惑枠鷲亙亘鰐詫藁蕨椀湾碗腕"], ["d0a1", "弌丐丕个丱丶丼丿乂乖乘亂亅豫亊舒弍于亞亟亠亢亰亳亶从仍仄仆仂仗仞仭仟价伉佚估佛佝佗佇佶侈侏侘佻佩佰侑佯來侖儘俔俟俎俘俛俑俚俐俤俥倚倨倔倪倥倅伜俶倡倩倬俾俯們倆偃假會偕偐偈做偖偬偸傀傚傅傴傲"], ["d1a1", "僉僊傳僂僖僞僥僭僣僮價僵儉儁儂儖儕儔儚儡儺儷儼儻儿兀兒兌兔兢竸兩兪兮冀冂囘册冉冏冑冓冕冖冤冦冢冩冪冫决冱冲冰况冽凅凉凛几處凩凭凰凵凾刄刋刔刎刧刪刮刳刹剏剄剋剌剞剔剪剴剩剳剿剽劍劔劒剱劈劑辨"], ["d2a1", "辧劬劭劼劵勁勍勗勞勣勦飭勠勳勵勸勹匆匈甸匍匐匏匕匚匣匯匱匳匸區卆卅丗卉卍凖卞卩卮夘卻卷厂厖厠厦厥厮厰厶參簒雙叟曼燮叮叨叭叺吁吽呀听吭吼吮吶吩吝呎咏呵咎呟呱呷呰咒呻咀呶咄咐咆哇咢咸咥咬哄哈咨"], ["d3a1", "咫哂咤咾咼哘哥哦唏唔哽哮哭哺哢唹啀啣啌售啜啅啖啗唸唳啝喙喀咯喊喟啻啾喘喞單啼喃喩喇喨嗚嗅嗟嗄嗜嗤嗔嘔嗷嘖嗾嗽嘛嗹噎噐營嘴嘶嘲嘸噫噤嘯噬噪嚆嚀嚊嚠嚔嚏嚥嚮嚶嚴囂嚼囁囃囀囈囎囑囓囗囮囹圀囿圄圉"], ["d4a1", "圈國圍圓團圖嗇圜圦圷圸坎圻址坏坩埀垈坡坿垉垓垠垳垤垪垰埃埆埔埒埓堊埖埣堋堙堝塲堡塢塋塰毀塒堽塹墅墹墟墫墺壞墻墸墮壅壓壑壗壙壘壥壜壤壟壯壺壹壻壼壽夂夊夐夛梦夥夬夭夲夸夾竒奕奐奎奚奘奢奠奧奬奩"], ["d5a1", "奸妁妝佞侫妣妲姆姨姜妍姙姚娥娟娑娜娉娚婀婬婉娵娶婢婪媚媼媾嫋嫂媽嫣嫗嫦嫩嫖嫺嫻嬌嬋嬖嬲嫐嬪嬶嬾孃孅孀孑孕孚孛孥孩孰孳孵學斈孺宀它宦宸寃寇寉寔寐寤實寢寞寥寫寰寶寳尅將專對尓尠尢尨尸尹屁屆屎屓"], ["d6a1", "屐屏孱屬屮乢屶屹岌岑岔妛岫岻岶岼岷峅岾峇峙峩峽峺峭嶌峪崋崕崗嵜崟崛崑崔崢崚崙崘嵌嵒嵎嵋嵬嵳嵶嶇嶄嶂嶢嶝嶬嶮嶽嶐嶷嶼巉巍巓巒巖巛巫已巵帋帚帙帑帛帶帷幄幃幀幎幗幔幟幢幤幇幵并幺麼广庠廁廂廈廐廏"], ["d7a1", "廖廣廝廚廛廢廡廨廩廬廱廳廰廴廸廾弃弉彝彜弋弑弖弩弭弸彁彈彌彎弯彑彖彗彙彡彭彳彷徃徂彿徊很徑徇從徙徘徠徨徭徼忖忻忤忸忱忝悳忿怡恠怙怐怩怎怱怛怕怫怦怏怺恚恁恪恷恟恊恆恍恣恃恤恂恬恫恙悁悍惧悃悚"], ["d8a1", "悄悛悖悗悒悧悋惡悸惠惓悴忰悽惆悵惘慍愕愆惶惷愀惴惺愃愡惻惱愍愎慇愾愨愧慊愿愼愬愴愽慂慄慳慷慘慙慚慫慴慯慥慱慟慝慓慵憙憖憇憬憔憚憊憑憫憮懌懊應懷懈懃懆憺懋罹懍懦懣懶懺懴懿懽懼懾戀戈戉戍戌戔戛"], ["d9a1", "戞戡截戮戰戲戳扁扎扞扣扛扠扨扼抂抉找抒抓抖拔抃抔拗拑抻拏拿拆擔拈拜拌拊拂拇抛拉挌拮拱挧挂挈拯拵捐挾捍搜捏掖掎掀掫捶掣掏掉掟掵捫捩掾揩揀揆揣揉插揶揄搖搴搆搓搦搶攝搗搨搏摧摯摶摎攪撕撓撥撩撈撼"], ["daa1", "據擒擅擇撻擘擂擱擧舉擠擡抬擣擯攬擶擴擲擺攀擽攘攜攅攤攣攫攴攵攷收攸畋效敖敕敍敘敞敝敲數斂斃變斛斟斫斷旃旆旁旄旌旒旛旙无旡旱杲昊昃旻杳昵昶昴昜晏晄晉晁晞晝晤晧晨晟晢晰暃暈暎暉暄暘暝曁暹曉暾暼"], ["dba1", "曄暸曖曚曠昿曦曩曰曵曷朏朖朞朦朧霸朮朿朶杁朸朷杆杞杠杙杣杤枉杰枩杼杪枌枋枦枡枅枷柯枴柬枳柩枸柤柞柝柢柮枹柎柆柧檜栞框栩桀桍栲桎梳栫桙档桷桿梟梏梭梔條梛梃檮梹桴梵梠梺椏梍桾椁棊椈棘椢椦棡椌棍"], ["dca1", "棔棧棕椶椒椄棗棣椥棹棠棯椨椪椚椣椡棆楹楷楜楸楫楔楾楮椹楴椽楙椰楡楞楝榁楪榲榮槐榿槁槓榾槎寨槊槝榻槃榧樮榑榠榜榕榴槞槨樂樛槿權槹槲槧樅榱樞槭樔槫樊樒櫁樣樓橄樌橲樶橸橇橢橙橦橈樸樢檐檍檠檄檢檣"], ["dda1", "檗蘗檻櫃櫂檸檳檬櫞櫑櫟檪櫚櫪櫻欅蘖櫺欒欖鬱欟欸欷盜欹飮歇歃歉歐歙歔歛歟歡歸歹歿殀殄殃殍殘殕殞殤殪殫殯殲殱殳殷殼毆毋毓毟毬毫毳毯麾氈氓气氛氤氣汞汕汢汪沂沍沚沁沛汾汨汳沒沐泄泱泓沽泗泅泝沮沱沾"], ["dea1", "沺泛泯泙泪洟衍洶洫洽洸洙洵洳洒洌浣涓浤浚浹浙涎涕濤涅淹渕渊涵淇淦涸淆淬淞淌淨淒淅淺淙淤淕淪淮渭湮渮渙湲湟渾渣湫渫湶湍渟湃渺湎渤滿渝游溂溪溘滉溷滓溽溯滄溲滔滕溏溥滂溟潁漑灌滬滸滾漿滲漱滯漲滌"], ["dfa1", "漾漓滷澆潺潸澁澀潯潛濳潭澂潼潘澎澑濂潦澳澣澡澤澹濆澪濟濕濬濔濘濱濮濛瀉瀋濺瀑瀁瀏濾瀛瀚潴瀝瀘瀟瀰瀾瀲灑灣炙炒炯烱炬炸炳炮烟烋烝烙焉烽焜焙煥煕熈煦煢煌煖煬熏燻熄熕熨熬燗熹熾燒燉燔燎燠燬燧燵燼"], ["e0a1", "燹燿爍爐爛爨爭爬爰爲爻爼爿牀牆牋牘牴牾犂犁犇犒犖犢犧犹犲狃狆狄狎狒狢狠狡狹狷倏猗猊猜猖猝猴猯猩猥猾獎獏默獗獪獨獰獸獵獻獺珈玳珎玻珀珥珮珞璢琅瑯琥珸琲琺瑕琿瑟瑙瑁瑜瑩瑰瑣瑪瑶瑾璋璞璧瓊瓏瓔珱"], ["e1a1", "瓠瓣瓧瓩瓮瓲瓰瓱瓸瓷甄甃甅甌甎甍甕甓甞甦甬甼畄畍畊畉畛畆畚畩畤畧畫畭畸當疆疇畴疊疉疂疔疚疝疥疣痂疳痃疵疽疸疼疱痍痊痒痙痣痞痾痿痼瘁痰痺痲痳瘋瘍瘉瘟瘧瘠瘡瘢瘤瘴瘰瘻癇癈癆癜癘癡癢癨癩癪癧癬癰"], ["e2a1", "癲癶癸發皀皃皈皋皎皖皓皙皚皰皴皸皹皺盂盍盖盒盞盡盥盧盪蘯盻眈眇眄眩眤眞眥眦眛眷眸睇睚睨睫睛睥睿睾睹瞎瞋瞑瞠瞞瞰瞶瞹瞿瞼瞽瞻矇矍矗矚矜矣矮矼砌砒礦砠礪硅碎硴碆硼碚碌碣碵碪碯磑磆磋磔碾碼磅磊磬"], ["e3a1", "磧磚磽磴礇礒礑礙礬礫祀祠祗祟祚祕祓祺祿禊禝禧齋禪禮禳禹禺秉秕秧秬秡秣稈稍稘稙稠稟禀稱稻稾稷穃穗穉穡穢穩龝穰穹穽窈窗窕窘窖窩竈窰窶竅竄窿邃竇竊竍竏竕竓站竚竝竡竢竦竭竰笂笏笊笆笳笘笙笞笵笨笶筐"], ["e4a1", "筺笄筍笋筌筅筵筥筴筧筰筱筬筮箝箘箟箍箜箚箋箒箏筝箙篋篁篌篏箴篆篝篩簑簔篦篥籠簀簇簓篳篷簗簍篶簣簧簪簟簷簫簽籌籃籔籏籀籐籘籟籤籖籥籬籵粃粐粤粭粢粫粡粨粳粲粱粮粹粽糀糅糂糘糒糜糢鬻糯糲糴糶糺紆"], ["e5a1", "紂紜紕紊絅絋紮紲紿紵絆絳絖絎絲絨絮絏絣經綉絛綏絽綛綺綮綣綵緇綽綫總綢綯緜綸綟綰緘緝緤緞緻緲緡縅縊縣縡縒縱縟縉縋縢繆繦縻縵縹繃縷縲縺繧繝繖繞繙繚繹繪繩繼繻纃緕繽辮繿纈纉續纒纐纓纔纖纎纛纜缸缺"], ["e6a1", "罅罌罍罎罐网罕罔罘罟罠罨罩罧罸羂羆羃羈羇羌羔羞羝羚羣羯羲羹羮羶羸譱翅翆翊翕翔翡翦翩翳翹飜耆耄耋耒耘耙耜耡耨耿耻聊聆聒聘聚聟聢聨聳聲聰聶聹聽聿肄肆肅肛肓肚肭冐肬胛胥胙胝胄胚胖脉胯胱脛脩脣脯腋"], ["e7a1", "隋腆脾腓腑胼腱腮腥腦腴膃膈膊膀膂膠膕膤膣腟膓膩膰膵膾膸膽臀臂膺臉臍臑臙臘臈臚臟臠臧臺臻臾舁舂舅與舊舍舐舖舩舫舸舳艀艙艘艝艚艟艤艢艨艪艫舮艱艷艸艾芍芒芫芟芻芬苡苣苟苒苴苳苺莓范苻苹苞茆苜茉苙"], ["e8a1", "茵茴茖茲茱荀茹荐荅茯茫茗茘莅莚莪莟莢莖茣莎莇莊荼莵荳荵莠莉莨菴萓菫菎菽萃菘萋菁菷萇菠菲萍萢萠莽萸蔆菻葭萪萼蕚蒄葷葫蒭葮蒂葩葆萬葯葹萵蓊葢蒹蒿蒟蓙蓍蒻蓚蓐蓁蓆蓖蒡蔡蓿蓴蔗蔘蔬蔟蔕蔔蓼蕀蕣蕘蕈"], ["e9a1", "蕁蘂蕋蕕薀薤薈薑薊薨蕭薔薛藪薇薜蕷蕾薐藉薺藏薹藐藕藝藥藜藹蘊蘓蘋藾藺蘆蘢蘚蘰蘿虍乕虔號虧虱蚓蚣蚩蚪蚋蚌蚶蚯蛄蛆蚰蛉蠣蚫蛔蛞蛩蛬蛟蛛蛯蜒蜆蜈蜀蜃蛻蜑蜉蜍蛹蜊蜴蜿蜷蜻蜥蜩蜚蝠蝟蝸蝌蝎蝴蝗蝨蝮蝙"], ["eaa1", "蝓蝣蝪蠅螢螟螂螯蟋螽蟀蟐雖螫蟄螳蟇蟆螻蟯蟲蟠蠏蠍蟾蟶蟷蠎蟒蠑蠖蠕蠢蠡蠱蠶蠹蠧蠻衄衂衒衙衞衢衫袁衾袞衵衽袵衲袂袗袒袮袙袢袍袤袰袿袱裃裄裔裘裙裝裹褂裼裴裨裲褄褌褊褓襃褞褥褪褫襁襄褻褶褸襌褝襠襞"], ["eba1", "襦襤襭襪襯襴襷襾覃覈覊覓覘覡覩覦覬覯覲覺覽覿觀觚觜觝觧觴觸訃訖訐訌訛訝訥訶詁詛詒詆詈詼詭詬詢誅誂誄誨誡誑誥誦誚誣諄諍諂諚諫諳諧諤諱謔諠諢諷諞諛謌謇謚諡謖謐謗謠謳鞫謦謫謾謨譁譌譏譎證譖譛譚譫"], ["eca1", "譟譬譯譴譽讀讌讎讒讓讖讙讚谺豁谿豈豌豎豐豕豢豬豸豺貂貉貅貊貍貎貔豼貘戝貭貪貽貲貳貮貶賈賁賤賣賚賽賺賻贄贅贊贇贏贍贐齎贓賍贔贖赧赭赱赳趁趙跂趾趺跏跚跖跌跛跋跪跫跟跣跼踈踉跿踝踞踐踟蹂踵踰踴蹊"], ["eda1", "蹇蹉蹌蹐蹈蹙蹤蹠踪蹣蹕蹶蹲蹼躁躇躅躄躋躊躓躑躔躙躪躡躬躰軆躱躾軅軈軋軛軣軼軻軫軾輊輅輕輒輙輓輜輟輛輌輦輳輻輹轅轂輾轌轉轆轎轗轜轢轣轤辜辟辣辭辯辷迚迥迢迪迯邇迴逅迹迺逑逕逡逍逞逖逋逧逶逵逹迸"], ["eea1", "遏遐遑遒逎遉逾遖遘遞遨遯遶隨遲邂遽邁邀邊邉邏邨邯邱邵郢郤扈郛鄂鄒鄙鄲鄰酊酖酘酣酥酩酳酲醋醉醂醢醫醯醪醵醴醺釀釁釉釋釐釖釟釡釛釼釵釶鈞釿鈔鈬鈕鈑鉞鉗鉅鉉鉤鉈銕鈿鉋鉐銜銖銓銛鉚鋏銹銷鋩錏鋺鍄錮"], ["efa1", "錙錢錚錣錺錵錻鍜鍠鍼鍮鍖鎰鎬鎭鎔鎹鏖鏗鏨鏥鏘鏃鏝鏐鏈鏤鐚鐔鐓鐃鐇鐐鐶鐫鐵鐡鐺鑁鑒鑄鑛鑠鑢鑞鑪鈩鑰鑵鑷鑽鑚鑼鑾钁鑿閂閇閊閔閖閘閙閠閨閧閭閼閻閹閾闊濶闃闍闌闕闔闖關闡闥闢阡阨阮阯陂陌陏陋陷陜陞"], ["f0a1", "陝陟陦陲陬隍隘隕隗險隧隱隲隰隴隶隸隹雎雋雉雍襍雜霍雕雹霄霆霈霓霎霑霏霖霙霤霪霰霹霽霾靄靆靈靂靉靜靠靤靦靨勒靫靱靹鞅靼鞁靺鞆鞋鞏鞐鞜鞨鞦鞣鞳鞴韃韆韈韋韜韭齏韲竟韶韵頏頌頸頤頡頷頽顆顏顋顫顯顰"], ["f1a1", "顱顴顳颪颯颱颶飄飃飆飩飫餃餉餒餔餘餡餝餞餤餠餬餮餽餾饂饉饅饐饋饑饒饌饕馗馘馥馭馮馼駟駛駝駘駑駭駮駱駲駻駸騁騏騅駢騙騫騷驅驂驀驃騾驕驍驛驗驟驢驥驤驩驫驪骭骰骼髀髏髑髓體髞髟髢髣髦髯髫髮髴髱髷"], ["f2a1", "髻鬆鬘鬚鬟鬢鬣鬥鬧鬨鬩鬪鬮鬯鬲魄魃魏魍魎魑魘魴鮓鮃鮑鮖鮗鮟鮠鮨鮴鯀鯊鮹鯆鯏鯑鯒鯣鯢鯤鯔鯡鰺鯲鯱鯰鰕鰔鰉鰓鰌鰆鰈鰒鰊鰄鰮鰛鰥鰤鰡鰰鱇鰲鱆鰾鱚鱠鱧鱶鱸鳧鳬鳰鴉鴈鳫鴃鴆鴪鴦鶯鴣鴟鵄鴕鴒鵁鴿鴾鵆鵈"], ["f3a1", "鵝鵞鵤鵑鵐鵙鵲鶉鶇鶫鵯鵺鶚鶤鶩鶲鷄鷁鶻鶸鶺鷆鷏鷂鷙鷓鷸鷦鷭鷯鷽鸚鸛鸞鹵鹹鹽麁麈麋麌麒麕麑麝麥麩麸麪麭靡黌黎黏黐黔黜點黝黠黥黨黯黴黶黷黹黻黼黽鼇鼈皷鼕鼡鼬鼾齊齒齔齣齟齠齡齦齧齬齪齷齲齶龕龜龠"], ["f4a1", "堯槇遙瑤凜熙"], ["f9a1", "纊褜鍈銈蓜俉炻昱棈鋹曻彅丨仡仼伀伃伹佖侒侊侚侔俍偀倢俿倞偆偰偂傔僴僘兊兤冝冾凬刕劜劦勀勛匀匇匤卲厓厲叝﨎咜咊咩哿喆坙坥垬埈埇﨏塚增墲夋奓奛奝奣妤妺孖寀甯寘寬尞岦岺峵崧嵓﨑嵂嵭嶸嶹巐弡弴彧德"], ["faa1", "忞恝悅悊惞惕愠惲愑愷愰憘戓抦揵摠撝擎敎昀昕昻昉昮昞昤晥晗晙晴晳暙暠暲暿曺朎朗杦枻桒柀栁桄棏﨓楨﨔榘槢樰橫橆橳橾櫢櫤毖氿汜沆汯泚洄涇浯涖涬淏淸淲淼渹湜渧渼溿澈澵濵瀅瀇瀨炅炫焏焄煜煆煇凞燁燾犱"], ["fba1", "犾猤猪獷玽珉珖珣珒琇珵琦琪琩琮瑢璉璟甁畯皂皜皞皛皦益睆劯砡硎硤硺礰礼神祥禔福禛竑竧靖竫箞精絈絜綷綠緖繒罇羡羽茁荢荿菇菶葈蒴蕓蕙蕫﨟薰蘒﨡蠇裵訒訷詹誧誾諟諸諶譓譿賰賴贒赶﨣軏﨤逸遧郞都鄕鄧釚"], ["fca1", "釗釞釭釮釤釥鈆鈐鈊鈺鉀鈼鉎鉙鉑鈹鉧銧鉷鉸鋧鋗鋙鋐﨧鋕鋠鋓錥錡鋻﨨錞鋿錝錂鍰鍗鎤鏆鏞鏸鐱鑅鑈閒隆﨩隝隯霳霻靃靍靏靑靕顗顥飯飼餧館馞驎髙髜魵魲鮏鮱鮻鰀鵰鵫鶴鸙黑"], ["fcf1", "ⅰ", 9, "¬¦'""], ["8fa2af", "˘ˇ¸˙˝¯˛˚~΄΅"], ["8fa2c2", "¡¦¿"], ["8fa2eb", "ºª©®™¤№"], ["8fa6e1", "ΆΈΉΊΪ"], ["8fa6e7", "Ό"], ["8fa6e9", "ΎΫ"], ["8fa6ec", "Ώ"], ["8fa6f1", "άέήίϊΐόςύϋΰώ"], ["8fa7c2", "Ђ", 10, "ЎЏ"], ["8fa7f2", "ђ", 10, "ўџ"], ["8fa9a1", "ÆĐ"], ["8fa9a4", "Ħ"], ["8fa9a6", "IJ"], ["8fa9a8", "ŁĿ"], ["8fa9ab", "ŊØŒ"], ["8fa9af", "ŦÞ"], ["8fa9c1", "æđðħıijĸłŀʼnŋøœßŧþ"], ["8faaa1", "ÁÀÄÂĂǍĀĄÅÃĆĈČÇĊĎÉÈËÊĚĖĒĘ"], ["8faaba", "ĜĞĢĠĤÍÌÏÎǏİĪĮĨĴĶĹĽĻŃŇŅÑÓÒÖÔǑŐŌÕŔŘŖŚŜŠŞŤŢÚÙÜÛŬǓŰŪŲŮŨǗǛǙǕŴÝŸŶŹŽŻ"], ["8faba1", "áàäâăǎāąåãćĉčçċďéèëêěėēęǵĝğ"], ["8fabbd", "ġĥíìïîǐ"], ["8fabc5", "īįĩĵķĺľļńňņñóòöôǒőōõŕřŗśŝšşťţúùüûŭǔűūųůũǘǜǚǖŵýÿŷźžż"], ["8fb0a1", "丂丄丅丌丒丟丣两丨丫丮丯丰丵乀乁乄乇乑乚乜乣乨乩乴乵乹乿亍亖亗亝亯亹仃仐仚仛仠仡仢仨仯仱仳仵份仾仿伀伂伃伈伋伌伒伕伖众伙伮伱你伳伵伷伹伻伾佀佂佈佉佋佌佒佔佖佘佟佣佪佬佮佱佷佸佹佺佽佾侁侂侄"], ["8fb1a1", "侅侉侊侌侎侐侒侓侔侗侙侚侞侟侲侷侹侻侼侽侾俀俁俅俆俈俉俋俌俍俏俒俜俠俢俰俲俼俽俿倀倁倄倇倊倌倎倐倓倗倘倛倜倝倞倢倧倮倰倲倳倵偀偁偂偅偆偊偌偎偑偒偓偗偙偟偠偢偣偦偧偪偭偰偱倻傁傃傄傆傊傎傏傐"], ["8fb2a1", "傒傓傔傖傛傜傞", 4, "傪傯傰傹傺傽僀僃僄僇僌僎僐僓僔僘僜僝僟僢僤僦僨僩僯僱僶僺僾儃儆儇儈儋儌儍儎僲儐儗儙儛儜儝儞儣儧儨儬儭儯儱儳儴儵儸儹兂兊兏兓兕兗兘兟兤兦兾冃冄冋冎冘冝冡冣冭冸冺冼冾冿凂"], ["8fb3a1", "凈减凑凒凓凕凘凞凢凥凮凲凳凴凷刁刂刅划刓刕刖刘刢刨刱刲刵刼剅剉剕剗剘剚剜剟剠剡剦剮剷剸剹劀劂劅劊劌劓劕劖劗劘劚劜劤劥劦劧劯劰劶劷劸劺劻劽勀勄勆勈勌勏勑勔勖勛勜勡勥勨勩勪勬勰勱勴勶勷匀匃匊匋"], ["8fb4a1", "匌匑匓匘匛匜匞匟匥匧匨匩匫匬匭匰匲匵匼匽匾卂卌卋卙卛卡卣卥卬卭卲卹卾厃厇厈厎厓厔厙厝厡厤厪厫厯厲厴厵厷厸厺厽叀叅叏叒叓叕叚叝叞叠另叧叵吂吓吚吡吧吨吪启吱吴吵呃呄呇呍呏呞呢呤呦呧呩呫呭呮呴呿"], ["8fb5a1", "咁咃咅咈咉咍咑咕咖咜咟咡咦咧咩咪咭咮咱咷咹咺咻咿哆哊响哎哠哪哬哯哶哼哾哿唀唁唅唈唉唌唍唎唕唪唫唲唵唶唻唼唽啁啇啉啊啍啐啑啘啚啛啞啠啡啤啦啿喁喂喆喈喎喏喑喒喓喔喗喣喤喭喲喿嗁嗃嗆嗉嗋嗌嗎嗑嗒"], ["8fb6a1", "嗓嗗嗘嗛嗞嗢嗩嗶嗿嘅嘈嘊嘍", 5, "嘙嘬嘰嘳嘵嘷嘹嘻嘼嘽嘿噀噁噃噄噆噉噋噍噏噔噞噠噡噢噣噦噩噭噯噱噲噵嚄嚅嚈嚋嚌嚕嚙嚚嚝嚞嚟嚦嚧嚨嚩嚫嚬嚭嚱嚳嚷嚾囅囉囊囋囏囐囌囍囙囜囝囟囡囤", 4, "囱囫园"], ["8fb7a1", "囶囷圁圂圇圊圌圑圕圚圛圝圠圢圣圤圥圩圪圬圮圯圳圴圽圾圿坅坆坌坍坒坢坥坧坨坫坭", 4, "坳坴坵坷坹坺坻坼坾垁垃垌垔垗垙垚垜垝垞垟垡垕垧垨垩垬垸垽埇埈埌埏埕埝埞埤埦埧埩埭埰埵埶埸埽埾埿堃堄堈堉埡"], ["8fb8a1", "堌堍堛堞堟堠堦堧堭堲堹堿塉塌塍塏塐塕塟塡塤塧塨塸塼塿墀墁墇墈墉墊墌墍墏墐墔墖墝墠墡墢墦墩墱墲壄墼壂壈壍壎壐壒壔壖壚壝壡壢壩壳夅夆夋夌夒夓夔虁夝夡夣夤夨夯夰夳夵夶夿奃奆奒奓奙奛奝奞奟奡奣奫奭"], ["8fb9a1", "奯奲奵奶她奻奼妋妌妎妒妕妗妟妤妧妭妮妯妰妳妷妺妼姁姃姄姈姊姍姒姝姞姟姣姤姧姮姯姱姲姴姷娀娄娌娍娎娒娓娞娣娤娧娨娪娭娰婄婅婇婈婌婐婕婞婣婥婧婭婷婺婻婾媋媐媓媖媙媜媞媟媠媢媧媬媱媲媳媵媸媺媻媿"], ["8fbaa1", "嫄嫆嫈嫏嫚嫜嫠嫥嫪嫮嫵嫶嫽嬀嬁嬈嬗嬴嬙嬛嬝嬡嬥嬭嬸孁孋孌孒孖孞孨孮孯孼孽孾孿宁宄宆宊宎宐宑宓宔宖宨宩宬宭宯宱宲宷宺宼寀寁寍寏寖", 4, "寠寯寱寴寽尌尗尞尟尣尦尩尫尬尮尰尲尵尶屙屚屜屢屣屧屨屩"], ["8fbba1", "屭屰屴屵屺屻屼屽岇岈岊岏岒岝岟岠岢岣岦岪岲岴岵岺峉峋峒峝峗峮峱峲峴崁崆崍崒崫崣崤崦崧崱崴崹崽崿嵂嵃嵆嵈嵕嵑嵙嵊嵟嵠嵡嵢嵤嵪嵭嵰嵹嵺嵾嵿嶁嶃嶈嶊嶒嶓嶔嶕嶙嶛嶟嶠嶧嶫嶰嶴嶸嶹巃巇巋巐巎巘巙巠巤"], ["8fbca1", "巩巸巹帀帇帍帒帔帕帘帟帠帮帨帲帵帾幋幐幉幑幖幘幛幜幞幨幪", 4, "幰庀庋庎庢庤庥庨庪庬庱庳庽庾庿廆廌廋廎廑廒廔廕廜廞廥廫异弆弇弈弎弙弜弝弡弢弣弤弨弫弬弮弰弴弶弻弽弿彀彄彅彇彍彐彔彘彛彠彣彤彧"], ["8fbda1", "彯彲彴彵彸彺彽彾徉徍徏徖徜徝徢徧徫徤徬徯徰徱徸忄忇忈忉忋忐", 4, "忞忡忢忨忩忪忬忭忮忯忲忳忶忺忼怇怊怍怓怔怗怘怚怟怤怭怳怵恀恇恈恉恌恑恔恖恗恝恡恧恱恾恿悂悆悈悊悎悑悓悕悘悝悞悢悤悥您悰悱悷"], ["8fbea1", "悻悾惂惄惈惉惊惋惎惏惔惕惙惛惝惞惢惥惲惵惸惼惽愂愇愊愌愐", 4, "愖愗愙愜愞愢愪愫愰愱愵愶愷愹慁慅慆慉慞慠慬慲慸慻慼慿憀憁憃憄憋憍憒憓憗憘憜憝憟憠憥憨憪憭憸憹憼懀懁懂懎懏懕懜懝懞懟懡懢懧懩懥"], ["8fbfa1", "懬懭懯戁戃戄戇戓戕戜戠戢戣戧戩戫戹戽扂扃扄扆扌扐扑扒扔扖扚扜扤扭扯扳扺扽抍抎抏抐抦抨抳抶抷抺抾抿拄拎拕拖拚拪拲拴拼拽挃挄挊挋挍挐挓挖挘挩挪挭挵挶挹挼捁捂捃捄捆捊捋捎捒捓捔捘捛捥捦捬捭捱捴捵"], ["8fc0a1", "捸捼捽捿掂掄掇掊掐掔掕掙掚掞掤掦掭掮掯掽揁揅揈揎揑揓揔揕揜揠揥揪揬揲揳揵揸揹搉搊搐搒搔搘搞搠搢搤搥搩搪搯搰搵搽搿摋摏摑摒摓摔摚摛摜摝摟摠摡摣摭摳摴摻摽撅撇撏撐撑撘撙撛撝撟撡撣撦撨撬撳撽撾撿"], ["8fc1a1", "擄擉擊擋擌擎擐擑擕擗擤擥擩擪擭擰擵擷擻擿攁攄攈攉攊攏攓攔攖攙攛攞攟攢攦攩攮攱攺攼攽敃敇敉敐敒敔敟敠敧敫敺敽斁斅斊斒斕斘斝斠斣斦斮斲斳斴斿旂旈旉旎旐旔旖旘旟旰旲旴旵旹旾旿昀昄昈昉昍昑昒昕昖昝"], ["8fc2a1", "昞昡昢昣昤昦昩昪昫昬昮昰昱昳昹昷晀晅晆晊晌晑晎晗晘晙晛晜晠晡曻晪晫晬晾晳晵晿晷晸晹晻暀晼暋暌暍暐暒暙暚暛暜暟暠暤暭暱暲暵暻暿曀曂曃曈曌曎曏曔曛曟曨曫曬曮曺朅朇朎朓朙朜朠朢朳朾杅杇杈杌杔杕杝"], ["8fc3a1", "杦杬杮杴杶杻极构枎枏枑枓枖枘枙枛枰枱枲枵枻枼枽柹柀柂柃柅柈柉柒柗柙柜柡柦柰柲柶柷桒栔栙栝栟栨栧栬栭栯栰栱栳栻栿桄桅桊桌桕桗桘桛桫桮", 4, "桵桹桺桻桼梂梄梆梈梖梘梚梜梡梣梥梩梪梮梲梻棅棈棌棏"], ["8fc4a1", "棐棑棓棖棙棜棝棥棨棪棫棬棭棰棱棵棶棻棼棽椆椉椊椐椑椓椖椗椱椳椵椸椻楂楅楉楎楗楛楣楤楥楦楨楩楬楰楱楲楺楻楿榀榍榒榖榘榡榥榦榨榫榭榯榷榸榺榼槅槈槑槖槗槢槥槮槯槱槳槵槾樀樁樃樏樑樕樚樝樠樤樨樰樲"], ["8fc5a1", "樴樷樻樾樿橅橆橉橊橎橐橑橒橕橖橛橤橧橪橱橳橾檁檃檆檇檉檋檑檛檝檞檟檥檫檯檰檱檴檽檾檿櫆櫉櫈櫌櫐櫔櫕櫖櫜櫝櫤櫧櫬櫰櫱櫲櫼櫽欂欃欆欇欉欏欐欑欗欛欞欤欨欫欬欯欵欶欻欿歆歊歍歒歖歘歝歠歧歫歮歰歵歽"], ["8fc6a1", "歾殂殅殗殛殟殠殢殣殨殩殬殭殮殰殸殹殽殾毃毄毉毌毖毚毡毣毦毧毮毱毷毹毿氂氄氅氉氍氎氐氒氙氟氦氧氨氬氮氳氵氶氺氻氿汊汋汍汏汒汔汙汛汜汫汭汯汴汶汸汹汻沅沆沇沉沔沕沗沘沜沟沰沲沴泂泆泍泏泐泑泒泔泖"], ["8fc7a1", "泚泜泠泧泩泫泬泮泲泴洄洇洊洎洏洑洓洚洦洧洨汧洮洯洱洹洼洿浗浞浟浡浥浧浯浰浼涂涇涑涒涔涖涗涘涪涬涴涷涹涽涿淄淈淊淎淏淖淛淝淟淠淢淥淩淯淰淴淶淼渀渄渞渢渧渲渶渹渻渼湄湅湈湉湋湏湑湒湓湔湗湜湝湞"], ["8fc8a1", "湢湣湨湳湻湽溍溓溙溠溧溭溮溱溳溻溿滀滁滃滇滈滊滍滎滏滫滭滮滹滻滽漄漈漊漌漍漖漘漚漛漦漩漪漯漰漳漶漻漼漭潏潑潒潓潗潙潚潝潞潡潢潨潬潽潾澃澇澈澋澌澍澐澒澓澔澖澚澟澠澥澦澧澨澮澯澰澵澶澼濅濇濈濊"], ["8fc9a1", "濚濞濨濩濰濵濹濼濽瀀瀅瀆瀇瀍瀗瀠瀣瀯瀴瀷瀹瀼灃灄灈灉灊灋灔灕灝灞灎灤灥灬灮灵灶灾炁炅炆炔", 4, "炛炤炫炰炱炴炷烊烑烓烔烕烖烘烜烤烺焃", 4, "焋焌焏焞焠焫焭焯焰焱焸煁煅煆煇煊煋煐煒煗煚煜煞煠"], ["8fcaa1", "煨煹熀熅熇熌熒熚熛熠熢熯熰熲熳熺熿燀燁燄燋燌燓燖燙燚燜燸燾爀爇爈爉爓爗爚爝爟爤爫爯爴爸爹牁牂牃牅牎牏牐牓牕牖牚牜牞牠牣牨牫牮牯牱牷牸牻牼牿犄犉犍犎犓犛犨犭犮犱犴犾狁狇狉狌狕狖狘狟狥狳狴狺狻"], ["8fcba1", "狾猂猄猅猇猋猍猒猓猘猙猞猢猤猧猨猬猱猲猵猺猻猽獃獍獐獒獖獘獝獞獟獠獦獧獩獫獬獮獯獱獷獹獼玀玁玃玅玆玎玐玓玕玗玘玜玞玟玠玢玥玦玪玫玭玵玷玹玼玽玿珅珆珉珋珌珏珒珓珖珙珝珡珣珦珧珩珴珵珷珹珺珻珽"], ["8fcca1", "珿琀琁琄琇琊琑琚琛琤琦琨", 9, "琹瑀瑃瑄瑆瑇瑋瑍瑑瑒瑗瑝瑢瑦瑧瑨瑫瑭瑮瑱瑲璀璁璅璆璇璉璏璐璑璒璘璙璚璜璟璠璡璣璦璨璩璪璫璮璯璱璲璵璹璻璿瓈瓉瓌瓐瓓瓘瓚瓛瓞瓟瓤瓨瓪瓫瓯瓴瓺瓻瓼瓿甆"], ["8fcda1", "甒甖甗甠甡甤甧甩甪甯甶甹甽甾甿畀畃畇畈畎畐畒畗畞畟畡畯畱畹", 5, "疁疅疐疒疓疕疙疜疢疤疴疺疿痀痁痄痆痌痎痏痗痜痟痠痡痤痧痬痮痯痱痹瘀瘂瘃瘄瘇瘈瘊瘌瘏瘒瘓瘕瘖瘙瘛瘜瘝瘞瘣瘥瘦瘩瘭瘲瘳瘵瘸瘹"], ["8fcea1", "瘺瘼癊癀癁癃癄癅癉癋癕癙癟癤癥癭癮癯癱癴皁皅皌皍皕皛皜皝皟皠皢", 6, "皪皭皽盁盅盉盋盌盎盔盙盠盦盨盬盰盱盶盹盼眀眆眊眎眒眔眕眗眙眚眜眢眨眭眮眯眴眵眶眹眽眾睂睅睆睊睍睎睏睒睖睗睜睞睟睠睢"], ["8fcfa1", "睤睧睪睬睰睲睳睴睺睽瞀瞄瞌瞍瞔瞕瞖瞚瞟瞢瞧瞪瞮瞯瞱瞵瞾矃矉矑矒矕矙矞矟矠矤矦矪矬矰矱矴矸矻砅砆砉砍砎砑砝砡砢砣砭砮砰砵砷硃硄硇硈硌硎硒硜硞硠硡硣硤硨硪确硺硾碊碏碔碘碡碝碞碟碤碨碬碭碰碱碲碳"], ["8fd0a1", "碻碽碿磇磈磉磌磎磒磓磕磖磤磛磟磠磡磦磪磲磳礀磶磷磺磻磿礆礌礐礚礜礞礟礠礥礧礩礭礱礴礵礻礽礿祄祅祆祊祋祏祑祔祘祛祜祧祩祫祲祹祻祼祾禋禌禑禓禔禕禖禘禛禜禡禨禩禫禯禱禴禸离秂秄秇秈秊秏秔秖秚秝秞"], ["8fd1a1", "秠秢秥秪秫秭秱秸秼稂稃稇稉稊稌稑稕稛稞稡稧稫稭稯稰稴稵稸稹稺穄穅穇穈穌穕穖穙穜穝穟穠穥穧穪穭穵穸穾窀窂窅窆窊窋窐窑窔窞窠窣窬窳窵窹窻窼竆竉竌竎竑竛竨竩竫竬竱竴竻竽竾笇笔笟笣笧笩笪笫笭笮笯笰"], ["8fd2a1", "笱笴笽笿筀筁筇筎筕筠筤筦筩筪筭筯筲筳筷箄箉箎箐箑箖箛箞箠箥箬箯箰箲箵箶箺箻箼箽篂篅篈篊篔篖篗篙篚篛篨篪篲篴篵篸篹篺篼篾簁簂簃簄簆簉簋簌簎簏簙簛簠簥簦簨簬簱簳簴簶簹簺籆籊籕籑籒籓籙", 5], ["8fd3a1", "籡籣籧籩籭籮籰籲籹籼籽粆粇粏粔粞粠粦粰粶粷粺粻粼粿糄糇糈糉糍糏糓糔糕糗糙糚糝糦糩糫糵紃紇紈紉紏紑紒紓紖紝紞紣紦紪紭紱紼紽紾絀絁絇絈絍絑絓絗絙絚絜絝絥絧絪絰絸絺絻絿綁綂綃綅綆綈綋綌綍綑綖綗綝"], ["8fd4a1", "綞綦綧綪綳綶綷綹緂", 4, "緌緍緎緗緙縀緢緥緦緪緫緭緱緵緶緹緺縈縐縑縕縗縜縝縠縧縨縬縭縯縳縶縿繄繅繇繎繐繒繘繟繡繢繥繫繮繯繳繸繾纁纆纇纊纍纑纕纘纚纝纞缼缻缽缾缿罃罄罇罏罒罓罛罜罝罡罣罤罥罦罭"], ["8fd5a1", "罱罽罾罿羀羋羍羏羐羑羖羗羜羡羢羦羪羭羴羼羿翀翃翈翎翏翛翟翣翥翨翬翮翯翲翺翽翾翿耇耈耊耍耎耏耑耓耔耖耝耞耟耠耤耦耬耮耰耴耵耷耹耺耼耾聀聄聠聤聦聭聱聵肁肈肎肜肞肦肧肫肸肹胈胍胏胒胔胕胗胘胠胭胮"], ["8fd6a1", "胰胲胳胶胹胺胾脃脋脖脗脘脜脞脠脤脧脬脰脵脺脼腅腇腊腌腒腗腠腡腧腨腩腭腯腷膁膐膄膅膆膋膎膖膘膛膞膢膮膲膴膻臋臃臅臊臎臏臕臗臛臝臞臡臤臫臬臰臱臲臵臶臸臹臽臿舀舃舏舓舔舙舚舝舡舢舨舲舴舺艃艄艅艆"], ["8fd7a1", "艋艎艏艑艖艜艠艣艧艭艴艻艽艿芀芁芃芄芇芉芊芎芑芔芖芘芚芛芠芡芣芤芧芨芩芪芮芰芲芴芷芺芼芾芿苆苐苕苚苠苢苤苨苪苭苯苶苷苽苾茀茁茇茈茊茋荔茛茝茞茟茡茢茬茭茮茰茳茷茺茼茽荂荃荄荇荍荎荑荕荖荗荰荸"], ["8fd8a1", "荽荿莀莂莄莆莍莒莔莕莘莙莛莜莝莦莧莩莬莾莿菀菇菉菏菐菑菔菝荓菨菪菶菸菹菼萁萆萊萏萑萕萙莭萯萹葅葇葈葊葍葏葑葒葖葘葙葚葜葠葤葥葧葪葰葳葴葶葸葼葽蒁蒅蒒蒓蒕蒞蒦蒨蒩蒪蒯蒱蒴蒺蒽蒾蓀蓂蓇蓈蓌蓏蓓"], ["8fd9a1", "蓜蓧蓪蓯蓰蓱蓲蓷蔲蓺蓻蓽蔂蔃蔇蔌蔎蔐蔜蔞蔢蔣蔤蔥蔧蔪蔫蔯蔳蔴蔶蔿蕆蕏", 4, "蕖蕙蕜", 6, "蕤蕫蕯蕹蕺蕻蕽蕿薁薅薆薉薋薌薏薓薘薝薟薠薢薥薧薴薶薷薸薼薽薾薿藂藇藊藋藎薭藘藚藟藠藦藨藭藳藶藼"], ["8fdaa1", "藿蘀蘄蘅蘍蘎蘐蘑蘒蘘蘙蘛蘞蘡蘧蘩蘶蘸蘺蘼蘽虀虂虆虒虓虖虗虘虙虝虠", 4, "虩虬虯虵虶虷虺蚍蚑蚖蚘蚚蚜蚡蚦蚧蚨蚭蚱蚳蚴蚵蚷蚸蚹蚿蛀蛁蛃蛅蛑蛒蛕蛗蛚蛜蛠蛣蛥蛧蚈蛺蛼蛽蜄蜅蜇蜋蜎蜏蜐蜓蜔蜙蜞蜟蜡蜣"], ["8fdba1", "蜨蜮蜯蜱蜲蜹蜺蜼蜽蜾蝀蝃蝅蝍蝘蝝蝡蝤蝥蝯蝱蝲蝻螃", 6, "螋螌螐螓螕螗螘螙螞螠螣螧螬螭螮螱螵螾螿蟁蟈蟉蟊蟎蟕蟖蟙蟚蟜蟟蟢蟣蟤蟪蟫蟭蟱蟳蟸蟺蟿蠁蠃蠆蠉蠊蠋蠐蠙蠒蠓蠔蠘蠚蠛蠜蠞蠟蠨蠭蠮蠰蠲蠵"], ["8fdca1", "蠺蠼衁衃衅衈衉衊衋衎衑衕衖衘衚衜衟衠衤衩衱衹衻袀袘袚袛袜袟袠袨袪袺袽袾裀裊", 4, "裑裒裓裛裞裧裯裰裱裵裷褁褆褍褎褏褕褖褘褙褚褜褠褦褧褨褰褱褲褵褹褺褾襀襂襅襆襉襏襒襗襚襛襜襡襢襣襫襮襰襳襵襺"], ["8fdda1", "襻襼襽覉覍覐覔覕覛覜覟覠覥覰覴覵覶覷覼觔", 4, "觥觩觫觭觱觳觶觹觽觿訄訅訇訏訑訒訔訕訞訠訢訤訦訫訬訯訵訷訽訾詀詃詅詇詉詍詎詓詖詗詘詜詝詡詥詧詵詶詷詹詺詻詾詿誀誃誆誋誏誐誒誖誗誙誟誧誩誮誯誳"], ["8fdea1", "誶誷誻誾諃諆諈諉諊諑諓諔諕諗諝諟諬諰諴諵諶諼諿謅謆謋謑謜謞謟謊謭謰謷謼譂", 4, "譈譒譓譔譙譍譞譣譭譶譸譹譼譾讁讄讅讋讍讏讔讕讜讞讟谸谹谽谾豅豇豉豋豏豑豓豔豗豘豛豝豙豣豤豦豨豩豭豳豵豶豻豾貆"], ["8fdfa1", "貇貋貐貒貓貙貛貜貤貹貺賅賆賉賋賏賖賕賙賝賡賨賬賯賰賲賵賷賸賾賿贁贃贉贒贗贛赥赩赬赮赿趂趄趈趍趐趑趕趞趟趠趦趫趬趯趲趵趷趹趻跀跅跆跇跈跊跎跑跔跕跗跙跤跥跧跬跰趼跱跲跴跽踁踄踅踆踋踑踔踖踠踡踢"], ["8fe0a1", "踣踦踧踱踳踶踷踸踹踽蹀蹁蹋蹍蹎蹏蹔蹛蹜蹝蹞蹡蹢蹩蹬蹭蹯蹰蹱蹹蹺蹻躂躃躉躐躒躕躚躛躝躞躢躧躩躭躮躳躵躺躻軀軁軃軄軇軏軑軔軜軨軮軰軱軷軹軺軭輀輂輇輈輏輐輖輗輘輞輠輡輣輥輧輨輬輭輮輴輵輶輷輺轀轁"], ["8fe1a1", "轃轇轏轑", 4, "轘轝轞轥辝辠辡辤辥辦辵辶辸达迀迁迆迊迋迍运迒迓迕迠迣迤迨迮迱迵迶迻迾适逄逈逌逘逛逨逩逯逪逬逭逳逴逷逿遃遄遌遛遝遢遦遧遬遰遴遹邅邈邋邌邎邐邕邗邘邙邛邠邡邢邥邰邲邳邴邶邽郌邾郃"], ["8fe2a1", "郄郅郇郈郕郗郘郙郜郝郟郥郒郶郫郯郰郴郾郿鄀鄄鄅鄆鄈鄍鄐鄔鄖鄗鄘鄚鄜鄞鄠鄥鄢鄣鄧鄩鄮鄯鄱鄴鄶鄷鄹鄺鄼鄽酃酇酈酏酓酗酙酚酛酡酤酧酭酴酹酺酻醁醃醅醆醊醎醑醓醔醕醘醞醡醦醨醬醭醮醰醱醲醳醶醻醼醽醿"], ["8fe3a1", "釂釃釅釓釔釗釙釚釞釤釥釩釪釬", 5, "釷釹釻釽鈀鈁鈄鈅鈆鈇鈉鈊鈌鈐鈒鈓鈖鈘鈜鈝鈣鈤鈥鈦鈨鈮鈯鈰鈳鈵鈶鈸鈹鈺鈼鈾鉀鉂鉃鉆鉇鉊鉍鉎鉏鉑鉘鉙鉜鉝鉠鉡鉥鉧鉨鉩鉮鉯鉰鉵", 4, "鉻鉼鉽鉿銈銉銊銍銎銒銗"], ["8fe4a1", "銙銟銠銤銥銧銨銫銯銲銶銸銺銻銼銽銿", 4, "鋅鋆鋇鋈鋋鋌鋍鋎鋐鋓鋕鋗鋘鋙鋜鋝鋟鋠鋡鋣鋥鋧鋨鋬鋮鋰鋹鋻鋿錀錂錈錍錑錔錕錜錝錞錟錡錤錥錧錩錪錳錴錶錷鍇鍈鍉鍐鍑鍒鍕鍗鍘鍚鍞鍤鍥鍧鍩鍪鍭鍯鍰鍱鍳鍴鍶"], ["8fe5a1", "鍺鍽鍿鎀鎁鎂鎈鎊鎋鎍鎏鎒鎕鎘鎛鎞鎡鎣鎤鎦鎨鎫鎴鎵鎶鎺鎩鏁鏄鏅鏆鏇鏉", 4, "鏓鏙鏜鏞鏟鏢鏦鏧鏹鏷鏸鏺鏻鏽鐁鐂鐄鐈鐉鐍鐎鐏鐕鐖鐗鐟鐮鐯鐱鐲鐳鐴鐻鐿鐽鑃鑅鑈鑊鑌鑕鑙鑜鑟鑡鑣鑨鑫鑭鑮鑯鑱鑲钄钃镸镹"], ["8fe6a1", "镾閄閈閌閍閎閝閞閟閡閦閩閫閬閴閶閺閽閿闆闈闉闋闐闑闒闓闙闚闝闞闟闠闤闦阝阞阢阤阥阦阬阱阳阷阸阹阺阼阽陁陒陔陖陗陘陡陮陴陻陼陾陿隁隂隃隄隉隑隖隚隝隟隤隥隦隩隮隯隳隺雊雒嶲雘雚雝雞雟雩雯雱雺霂"], ["8fe7a1", "霃霅霉霚霛霝霡霢霣霨霱霳靁靃靊靎靏靕靗靘靚靛靣靧靪靮靳靶靷靸靻靽靿鞀鞉鞕鞖鞗鞙鞚鞞鞟鞢鞬鞮鞱鞲鞵鞶鞸鞹鞺鞼鞾鞿韁韄韅韇韉韊韌韍韎韐韑韔韗韘韙韝韞韠韛韡韤韯韱韴韷韸韺頇頊頙頍頎頔頖頜頞頠頣頦"], ["8fe8a1", "頫頮頯頰頲頳頵頥頾顄顇顊顑顒顓顖顗顙顚顢顣顥顦顪顬颫颭颮颰颴颷颸颺颻颿飂飅飈飌飡飣飥飦飧飪飳飶餂餇餈餑餕餖餗餚餛餜餟餢餦餧餫餱", 4, "餹餺餻餼饀饁饆饇饈饍饎饔饘饙饛饜饞饟饠馛馝馟馦馰馱馲馵"], ["8fe9a1", "馹馺馽馿駃駉駓駔駙駚駜駞駧駪駫駬駰駴駵駹駽駾騂騃騄騋騌騐騑騖騞騠騢騣騤騧騭騮騳騵騶騸驇驁驄驊驋驌驎驑驔驖驝骪骬骮骯骲骴骵骶骹骻骾骿髁髃髆髈髎髐髒髕髖髗髛髜髠髤髥髧髩髬髲髳髵髹髺髽髿", 4], ["8feaa1", "鬄鬅鬈鬉鬋鬌鬍鬎鬐鬒鬖鬙鬛鬜鬠鬦鬫鬭鬳鬴鬵鬷鬹鬺鬽魈魋魌魕魖魗魛魞魡魣魥魦魨魪", 4, "魳魵魷魸魹魿鮀鮄鮅鮆鮇鮉鮊鮋鮍鮏鮐鮔鮚鮝鮞鮦鮧鮩鮬鮰鮱鮲鮷鮸鮻鮼鮾鮿鯁鯇鯈鯎鯐鯗鯘鯝鯟鯥鯧鯪鯫鯯鯳鯷鯸"], ["8feba1", "鯹鯺鯽鯿鰀鰂鰋鰏鰑鰖鰘鰙鰚鰜鰞鰢鰣鰦", 4, "鰱鰵鰶鰷鰽鱁鱃鱄鱅鱉鱊鱎鱏鱐鱓鱔鱖鱘鱛鱝鱞鱟鱣鱩鱪鱜鱫鱨鱮鱰鱲鱵鱷鱻鳦鳲鳷鳹鴋鴂鴑鴗鴘鴜鴝鴞鴯鴰鴲鴳鴴鴺鴼鵅鴽鵂鵃鵇鵊鵓鵔鵟鵣鵢鵥鵩鵪鵫鵰鵶鵷鵻"], ["8feca1", "鵼鵾鶃鶄鶆鶊鶍鶎鶒鶓鶕鶖鶗鶘鶡鶪鶬鶮鶱鶵鶹鶼鶿鷃鷇鷉鷊鷔鷕鷖鷗鷚鷞鷟鷠鷥鷧鷩鷫鷮鷰鷳鷴鷾鸊鸂鸇鸎鸐鸑鸒鸕鸖鸙鸜鸝鹺鹻鹼麀麂麃麄麅麇麎麏麖麘麛麞麤麨麬麮麯麰麳麴麵黆黈黋黕黟黤黧黬黭黮黰黱黲黵"], ["8feda1", "黸黿鼂鼃鼉鼏鼐鼑鼒鼔鼖鼗鼙鼚鼛鼟鼢鼦鼪鼫鼯鼱鼲鼴鼷鼹鼺鼼鼽鼿齁齃", 4, "齓齕齖齗齘齚齝齞齨齩齭", 4, "齳齵齺齽龏龐龑龒龔龖龗龞龡龢龣龥"]]; + +var eucjp$1 = Object.freeze({ + default: eucjp +}); + +var cp936 = [["0", "\0", 127, "€"], ["8140", "丂丄丅丆丏丒丗丟丠両丣並丩丮丯丱丳丵丷丼乀乁乂乄乆乊乑乕乗乚乛乢乣乤乥乧乨乪", 5, "乲乴", 9, "乿", 6, "亇亊"], ["8180", "亐亖亗亙亜亝亞亣亪亯亰亱亴亶亷亸亹亼亽亾仈仌仏仐仒仚仛仜仠仢仦仧仩仭仮仯仱仴仸仹仺仼仾伀伂", 6, "伋伌伒", 4, "伜伝伡伣伨伩伬伭伮伱伳伵伷伹伻伾", 4, "佄佅佇", 5, "佒佔佖佡佢佦佨佪佫佭佮佱佲併佷佸佹佺佽侀侁侂侅來侇侊侌侎侐侒侓侕侖侘侙侚侜侞侟価侢"], ["8240", "侤侫侭侰", 4, "侶", 8, "俀俁係俆俇俈俉俋俌俍俒", 4, "俙俛俠俢俤俥俧俫俬俰俲俴俵俶俷俹俻俼俽俿", 11], ["8280", "個倎倐們倓倕倖倗倛倝倞倠倢倣値倧倫倯", 10, "倻倽倿偀偁偂偄偅偆偉偊偋偍偐", 4, "偖偗偘偙偛偝", 7, "偦", 5, "偭", 8, "偸偹偺偼偽傁傂傃傄傆傇傉傊傋傌傎", 20, "傤傦傪傫傭", 4, "傳", 6, "傼"], ["8340", "傽", 17, "僐", 5, "僗僘僙僛", 10, "僨僩僪僫僯僰僱僲僴僶", 4, "僼", 9, "儈"], ["8380", "儉儊儌", 5, "儓", 13, "儢", 28, "兂兇兊兌兎兏児兒兓兗兘兙兛兝", 4, "兣兤兦內兩兪兯兲兺兾兿冃冄円冇冊冋冎冏冐冑冓冔冘冚冝冞冟冡冣冦", 4, "冭冮冴冸冹冺冾冿凁凂凃凅凈凊凍凎凐凒", 5], ["8440", "凘凙凚凜凞凟凢凣凥", 5, "凬凮凱凲凴凷凾刄刅刉刋刌刏刐刓刔刕刜刞刟刡刢刣別刦刧刪刬刯刱刲刴刵刼刾剄", 5, "剋剎剏剒剓剕剗剘"], ["8480", "剙剚剛剝剟剠剢剣剤剦剨剫剬剭剮剰剱剳", 9, "剾劀劃", 4, "劉", 6, "劑劒劔", 6, "劜劤劥劦劧劮劯劰労", 9, "勀勁勂勄勅勆勈勊勌勍勎勏勑勓勔動勗務", 5, "勠勡勢勣勥", 10, "勱", 7, "勻勼勽匁匂匃匄匇匉匊匋匌匎"], ["8540", "匑匒匓匔匘匛匜匞匟匢匤匥匧匨匩匫匬匭匯", 9, "匼匽區卂卄卆卋卌卍卐協単卙卛卝卥卨卪卬卭卲卶卹卻卼卽卾厀厁厃厇厈厊厎厏"], ["8580", "厐", 4, "厖厗厙厛厜厞厠厡厤厧厪厫厬厭厯", 6, "厷厸厹厺厼厽厾叀參", 4, "収叏叐叒叓叕叚叜叝叞叡叢叧叴叺叾叿吀吂吅吇吋吔吘吙吚吜吢吤吥吪吰吳吶吷吺吽吿呁呂呄呅呇呉呌呍呎呏呑呚呝", 4, "呣呥呧呩", 7, "呴呹呺呾呿咁咃咅咇咈咉咊咍咑咓咗咘咜咞咟咠咡"], ["8640", "咢咥咮咰咲咵咶咷咹咺咼咾哃哅哊哋哖哘哛哠", 4, "哫哬哯哰哱哴", 5, "哻哾唀唂唃唄唅唈唊", 4, "唒唓唕", 5, "唜唝唞唟唡唥唦"], ["8680", "唨唩唫唭唲唴唵唶唸唹唺唻唽啀啂啅啇啈啋", 4, "啑啒啓啔啗", 4, "啝啞啟啠啢啣啨啩啫啯", 5, "啹啺啽啿喅喆喌喍喎喐喒喓喕喖喗喚喛喞喠", 6, "喨", 8, "喲喴営喸喺喼喿", 4, "嗆嗇嗈嗊嗋嗎嗏嗐嗕嗗", 4, "嗞嗠嗢嗧嗩嗭嗮嗰嗱嗴嗶嗸", 4, "嗿嘂嘃嘄嘅"], ["8740", "嘆嘇嘊嘋嘍嘐", 7, "嘙嘚嘜嘝嘠嘡嘢嘥嘦嘨嘩嘪嘫嘮嘯嘰嘳嘵嘷嘸嘺嘼嘽嘾噀", 11, "噏", 4, "噕噖噚噛噝", 4], ["8780", "噣噥噦噧噭噮噯噰噲噳噴噵噷噸噹噺噽", 7, "嚇", 6, "嚐嚑嚒嚔", 14, "嚤", 10, "嚰", 6, "嚸嚹嚺嚻嚽", 12, "囋", 8, "囕囖囘囙囜団囥", 5, "囬囮囯囲図囶囷囸囻囼圀圁圂圅圇國", 6], ["8840", "園", 9, "圝圞圠圡圢圤圥圦圧圫圱圲圴", 4, "圼圽圿坁坃坄坅坆坈坉坋坒", 4, "坘坙坢坣坥坧坬坮坰坱坲坴坵坸坹坺坽坾坿垀"], ["8880", "垁垇垈垉垊垍", 4, "垔", 6, "垜垝垞垟垥垨垪垬垯垰垱垳垵垶垷垹", 8, "埄", 6, "埌埍埐埑埓埖埗埛埜埞埡埢埣埥", 7, "埮埰埱埲埳埵埶執埻埼埾埿堁堃堄堅堈堉堊堌堎堏堐堒堓堔堖堗堘堚堛堜堝堟堢堣堥", 4, "堫", 4, "報堲堳場堶", 7], ["8940", "堾", 5, "塅", 6, "塎塏塐塒塓塕塖塗塙", 4, "塟", 5, "塦", 4, "塭", 16, "塿墂墄墆墇墈墊墋墌"], ["8980", "墍", 4, "墔", 4, "墛墜墝墠", 7, "墪", 17, "墽墾墿壀壂壃壄壆", 10, "壒壓壔壖", 13, "壥", 5, "壭壯壱売壴壵壷壸壺", 7, "夃夅夆夈", 4, "夎夐夑夒夓夗夘夛夝夞夠夡夢夣夦夨夬夰夲夳夵夶夻"], ["8a40", "夽夾夿奀奃奅奆奊奌奍奐奒奓奙奛", 4, "奡奣奤奦", 12, "奵奷奺奻奼奾奿妀妅妉妋妌妎妏妐妑妔妕妘妚妛妜妝妟妠妡妢妦"], ["8a80", "妧妬妭妰妱妳", 5, "妺妼妽妿", 6, "姇姈姉姌姍姎姏姕姖姙姛姞", 4, "姤姦姧姩姪姫姭", 11, "姺姼姽姾娀娂娊娋娍娎娏娐娒娔娕娖娗娙娚娛娝娞娡娢娤娦娧娨娪", 6, "娳娵娷", 4, "娽娾娿婁", 4, "婇婈婋", 9, "婖婗婘婙婛", 5], ["8b40", "婡婣婤婥婦婨婩婫", 8, "婸婹婻婼婽婾媀", 17, "媓", 6, "媜", 13, "媫媬"], ["8b80", "媭", 4, "媴媶媷媹", 4, "媿嫀嫃", 5, "嫊嫋嫍", 4, "嫓嫕嫗嫙嫚嫛嫝嫞嫟嫢嫤嫥嫧嫨嫪嫬", 4, "嫲", 22, "嬊", 11, "嬘", 25, "嬳嬵嬶嬸", 7, "孁", 6], ["8c40", "孈", 7, "孒孖孞孠孡孧孨孫孭孮孯孲孴孶孷學孹孻孼孾孿宂宆宊宍宎宐宑宒宔宖実宧宨宩宬宭宮宯宱宲宷宺宻宼寀寁寃寈寉寊寋寍寎寏"], ["8c80", "寑寔", 8, "寠寢寣實寧審", 4, "寯寱", 6, "寽対尀専尃尅將專尋尌對導尐尒尓尗尙尛尞尟尠尡尣尦尨尩尪尫尭尮尯尰尲尳尵尶尷屃屄屆屇屌屍屒屓屔屖屗屘屚屛屜屝屟屢層屧", 6, "屰屲", 6, "屻屼屽屾岀岃", 4, "岉岊岋岎岏岒岓岕岝", 4, "岤", 4], ["8d40", "岪岮岯岰岲岴岶岹岺岻岼岾峀峂峃峅", 5, "峌", 5, "峓", 5, "峚", 6, "峢峣峧峩峫峬峮峯峱", 9, "峼", 4], ["8d80", "崁崄崅崈", 5, "崏", 4, "崕崗崘崙崚崜崝崟", 4, "崥崨崪崫崬崯", 4, "崵", 7, "崿", 7, "嵈嵉嵍", 10, "嵙嵚嵜嵞", 10, "嵪嵭嵮嵰嵱嵲嵳嵵", 12, "嶃", 21, "嶚嶛嶜嶞嶟嶠"], ["8e40", "嶡", 21, "嶸", 12, "巆", 6, "巎", 12, "巜巟巠巣巤巪巬巭"], ["8e80", "巰巵巶巸", 4, "巿帀帄帇帉帊帋帍帎帒帓帗帞", 7, "帨", 4, "帯帰帲", 4, "帹帺帾帿幀幁幃幆", 5, "幍", 6, "幖", 4, "幜幝幟幠幣", 14, "幵幷幹幾庁庂広庅庈庉庌庍庎庒庘庛庝庡庢庣庤庨", 4, "庮", 4, "庴庺庻庼庽庿", 6], ["8f40", "廆廇廈廋", 5, "廔廕廗廘廙廚廜", 11, "廩廫", 8, "廵廸廹廻廼廽弅弆弇弉弌弍弎弐弒弔弖弙弚弜弝弞弡弢弣弤"], ["8f80", "弨弫弬弮弰弲", 6, "弻弽弾弿彁", 14, "彑彔彙彚彛彜彞彟彠彣彥彧彨彫彮彯彲彴彵彶彸彺彽彾彿徃徆徍徎徏徑従徔徖徚徛徝從徟徠徢", 5, "復徫徬徯", 5, "徶徸徹徺徻徾", 4, "忇忈忊忋忎忓忔忕忚忛応忞忟忢忣忥忦忨忩忬忯忰忲忳忴忶忷忹忺忼怇"], ["9040", "怈怉怋怌怐怑怓怗怘怚怞怟怢怣怤怬怭怮怰", 4, "怶", 4, "怽怾恀恄", 6, "恌恎恏恑恓恔恖恗恘恛恜恞恟恠恡恥恦恮恱恲恴恵恷恾悀"], ["9080", "悁悂悅悆悇悈悊悋悎悏悐悑悓悕悗悘悙悜悞悡悢悤悥悧悩悪悮悰悳悵悶悷悹悺悽", 7, "惇惈惉惌", 4, "惒惓惔惖惗惙惛惞惡", 4, "惪惱惲惵惷惸惻", 4, "愂愃愄愅愇愊愋愌愐", 4, "愖愗愘愙愛愜愝愞愡愢愥愨愩愪愬", 18, "慀", 6], ["9140", "慇慉態慍慏慐慒慓慔慖", 6, "慞慟慠慡慣慤慥慦慩", 6, "慱慲慳慴慶慸", 18, "憌憍憏", 4, "憕"], ["9180", "憖", 6, "憞", 8, "憪憫憭", 9, "憸", 5, "憿懀懁懃", 4, "應懌", 4, "懓懕", 16, "懧", 13, "懶", 8, "戀", 5, "戇戉戓戔戙戜戝戞戠戣戦戧戨戩戫戭戯戰戱戲戵戶戸", 4, "扂扄扅扆扊"], ["9240", "扏扐払扖扗扙扚扜", 6, "扤扥扨扱扲扴扵扷扸扺扻扽抁抂抃抅抆抇抈抋", 5, "抔抙抜抝択抣抦抧抩抪抭抮抯抰抲抳抴抶抷抸抺抾拀拁"], ["9280", "拃拋拏拑拕拝拞拠拡拤拪拫拰拲拵拸拹拺拻挀挃挄挅挆挊挋挌挍挏挐挒挓挔挕挗挘挙挜挦挧挩挬挭挮挰挱挳", 5, "挻挼挾挿捀捁捄捇捈捊捑捒捓捔捖", 7, "捠捤捥捦捨捪捫捬捯捰捲捳捴捵捸捹捼捽捾捿掁掃掄掅掆掋掍掑掓掔掕掗掙", 6, "採掤掦掫掯掱掲掵掶掹掻掽掿揀"], ["9340", "揁揂揃揅揇揈揊揋揌揑揓揔揕揗", 6, "揟揢揤", 4, "揫揬揮揯揰揱揳揵揷揹揺揻揼揾搃搄搆", 4, "損搎搑搒搕", 5, "搝搟搢搣搤"], ["9380", "搥搧搨搩搫搮", 5, "搵", 4, "搻搼搾摀摂摃摉摋", 6, "摓摕摖摗摙", 4, "摟", 7, "摨摪摫摬摮", 9, "摻", 6, "撃撆撈", 8, "撓撔撗撘撚撛撜撝撟", 4, "撥撦撧撨撪撫撯撱撲撳撴撶撹撻撽撾撿擁擃擄擆", 6, "擏擑擓擔擕擖擙據"], ["9440", "擛擜擝擟擠擡擣擥擧", 24, "攁", 7, "攊", 7, "攓", 4, "攙", 8], ["9480", "攢攣攤攦", 4, "攬攭攰攱攲攳攷攺攼攽敀", 4, "敆敇敊敋敍敎敐敒敓敔敗敘敚敜敟敠敡敤敥敧敨敩敪敭敮敯敱敳敵敶數", 14, "斈斉斊斍斎斏斒斔斕斖斘斚斝斞斠斢斣斦斨斪斬斮斱", 7, "斺斻斾斿旀旂旇旈旉旊旍旐旑旓旔旕旘", 7, "旡旣旤旪旫"], ["9540", "旲旳旴旵旸旹旻", 4, "昁昄昅昇昈昉昋昍昐昑昒昖昗昘昚昛昜昞昡昢昣昤昦昩昪昫昬昮昰昲昳昷", 4, "昽昿晀時晄", 6, "晍晎晐晑晘"], ["9580", "晙晛晜晝晞晠晢晣晥晧晩", 4, "晱晲晳晵晸晹晻晼晽晿暀暁暃暅暆暈暉暊暋暍暎暏暐暒暓暔暕暘", 4, "暞", 8, "暩", 4, "暯", 4, "暵暶暷暸暺暻暼暽暿", 25, "曚曞", 7, "曧曨曪", 5, "曱曵曶書曺曻曽朁朂會"], ["9640", "朄朅朆朇朌朎朏朑朒朓朖朘朙朚朜朞朠", 5, "朧朩朮朰朲朳朶朷朸朹朻朼朾朿杁杄杅杇杊杋杍杒杔杕杗", 4, "杝杢杣杤杦杧杫杬杮東杴杶"], ["9680", "杸杹杺杻杽枀枂枃枅枆枈枊枌枍枎枏枑枒枓枔枖枙枛枟枠枡枤枦枩枬枮枱枲枴枹", 7, "柂柅", 9, "柕柖柗柛柟柡柣柤柦柧柨柪柫柭柮柲柵", 7, "柾栁栂栃栄栆栍栐栒栔栕栘", 4, "栞栟栠栢", 6, "栫", 6, "栴栵栶栺栻栿桇桋桍桏桒桖", 5], ["9740", "桜桝桞桟桪桬", 7, "桵桸", 8, "梂梄梇", 7, "梐梑梒梔梕梖梘", 9, "梣梤梥梩梪梫梬梮梱梲梴梶梷梸"], ["9780", "梹", 6, "棁棃", 5, "棊棌棎棏棐棑棓棔棖棗棙棛", 4, "棡棢棤", 9, "棯棲棳棴棶棷棸棻棽棾棿椀椂椃椄椆", 4, "椌椏椑椓", 11, "椡椢椣椥", 7, "椮椯椱椲椳椵椶椷椸椺椻椼椾楀楁楃", 16, "楕楖楘楙楛楜楟"], ["9840", "楡楢楤楥楧楨楩楪楬業楯楰楲", 4, "楺楻楽楾楿榁榃榅榊榋榌榎", 5, "榖榗榙榚榝", 9, "榩榪榬榮榯榰榲榳榵榶榸榹榺榼榽"], ["9880", "榾榿槀槂", 7, "構槍槏槑槒槓槕", 5, "槜槝槞槡", 11, "槮槯槰槱槳", 9, "槾樀", 9, "樋", 11, "標", 5, "樠樢", 5, "権樫樬樭樮樰樲樳樴樶", 6, "樿", 4, "橅橆橈", 7, "橑", 6, "橚"], ["9940", "橜", 4, "橢橣橤橦", 10, "橲", 6, "橺橻橽橾橿檁檂檃檅", 8, "檏檒", 4, "檘", 7, "檡", 5], ["9980", "檧檨檪檭", 114, "欥欦欨", 6], ["9a40", "欯欰欱欳欴欵欶欸欻欼欽欿歀歁歂歄歅歈歊歋歍", 11, "歚", 7, "歨歩歫", 13, "歺歽歾歿殀殅殈"], ["9a80", "殌殎殏殐殑殔殕殗殘殙殜", 4, "殢", 7, "殫", 7, "殶殸", 6, "毀毃毄毆", 4, "毌毎毐毑毘毚毜", 4, "毢", 7, "毬毭毮毰毱毲毴毶毷毸毺毻毼毾", 6, "氈", 4, "氎氒気氜氝氞氠氣氥氫氬氭氱氳氶氷氹氺氻氼氾氿汃汄汅汈汋", 4, "汑汒汓汖汘"], ["9b40", "汙汚汢汣汥汦汧汫", 4, "汱汳汵汷汸決汻汼汿沀沄沇沊沋沍沎沑沒沕沖沗沘沚沜沝沞沠沢沨沬沯沰沴沵沶沷沺泀況泂泃泆泇泈泋泍泎泏泑泒泘"], ["9b80", "泙泚泜泝泟泤泦泧泩泬泭泲泴泹泿洀洂洃洅洆洈洉洊洍洏洐洑洓洔洕洖洘洜洝洟", 5, "洦洨洩洬洭洯洰洴洶洷洸洺洿浀浂浄浉浌浐浕浖浗浘浛浝浟浡浢浤浥浧浨浫浬浭浰浱浲浳浵浶浹浺浻浽", 4, "涃涄涆涇涊涋涍涏涐涒涖", 4, "涜涢涥涬涭涰涱涳涴涶涷涹", 5, "淁淂淃淈淉淊"], ["9c40", "淍淎淏淐淒淓淔淕淗淚淛淜淟淢淣淥淧淨淩淪淭淯淰淲淴淵淶淸淺淽", 7, "渆渇済渉渋渏渒渓渕渘渙減渜渞渟渢渦渧渨渪測渮渰渱渳渵"], ["9c80", "渶渷渹渻", 7, "湅", 7, "湏湐湑湒湕湗湙湚湜湝湞湠", 10, "湬湭湯", 14, "満溁溂溄溇溈溊", 4, "溑", 6, "溙溚溛溝溞溠溡溣溤溦溨溩溫溬溭溮溰溳溵溸溹溼溾溿滀滃滄滅滆滈滉滊滌滍滎滐滒滖滘滙滛滜滝滣滧滪", 5], ["9d40", "滰滱滲滳滵滶滷滸滺", 7, "漃漄漅漇漈漊", 4, "漐漑漒漖", 9, "漡漢漣漥漦漧漨漬漮漰漲漴漵漷", 6, "漿潀潁潂"], ["9d80", "潃潄潅潈潉潊潌潎", 9, "潙潚潛潝潟潠潡潣潤潥潧", 5, "潯潰潱潳潵潶潷潹潻潽", 6, "澅澆澇澊澋澏", 12, "澝澞澟澠澢", 4, "澨", 10, "澴澵澷澸澺", 5, "濁濃", 5, "濊", 6, "濓", 10, "濟濢濣濤濥"], ["9e40", "濦", 7, "濰", 32, "瀒", 7, "瀜", 6, "瀤", 6], ["9e80", "瀫", 9, "瀶瀷瀸瀺", 17, "灍灎灐", 13, "灟", 11, "灮灱灲灳灴灷灹灺灻災炁炂炃炄炆炇炈炋炌炍炏炐炑炓炗炘炚炛炞", 12, "炰炲炴炵炶為炾炿烄烅烆烇烉烋", 12, "烚"], ["9f40", "烜烝烞烠烡烢烣烥烪烮烰", 6, "烸烺烻烼烾", 10, "焋", 4, "焑焒焔焗焛", 10, "焧", 7, "焲焳焴"], ["9f80", "焵焷", 13, "煆煇煈煉煋煍煏", 12, "煝煟", 4, "煥煩", 4, "煯煰煱煴煵煶煷煹煻煼煾", 5, "熅", 4, "熋熌熍熎熐熑熒熓熕熖熗熚", 4, "熡", 6, "熩熪熫熭", 5, "熴熶熷熸熺", 8, "燄", 9, "燏", 4], ["a040", "燖", 9, "燡燢燣燤燦燨", 5, "燯", 9, "燺", 11, "爇", 19], ["a080", "爛爜爞", 9, "爩爫爭爮爯爲爳爴爺爼爾牀", 6, "牉牊牋牎牏牐牑牓牔牕牗牘牚牜牞牠牣牤牥牨牪牫牬牭牰牱牳牴牶牷牸牻牼牽犂犃犅", 4, "犌犎犐犑犓", 11, "犠", 11, "犮犱犲犳犵犺", 6, "狅狆狇狉狊狋狌狏狑狓狔狕狖狘狚狛"], ["a1a1", " 、。·ˉˇ¨〃々—~‖…‘’“”〔〕〈", 7, "〖〗【】±×÷∶∧∨∑∏∪∩∈∷√⊥∥∠⌒⊙∫∮≡≌≈∽∝≠≮≯≤≥∞∵∴♂♀°′″℃$¤¢£‰§№☆★○●◎◇◆□■△▲※→←↑↓〓"], ["a2a1", "ⅰ", 9], ["a2b1", "⒈", 19, "⑴", 19, "①", 9], ["a2e5", "㈠", 9], ["a2f1", "Ⅰ", 11], ["a3a1", "!"#¥%", 88, " ̄"], ["a4a1", "ぁ", 82], ["a5a1", "ァ", 85], ["a6a1", "Α", 16, "Σ", 6], ["a6c1", "α", 16, "σ", 6], ["a6e0", "︵︶︹︺︿﹀︽︾﹁﹂﹃﹄"], ["a6ee", "︻︼︷︸︱"], ["a6f4", "︳︴"], ["a7a1", "А", 5, "ЁЖ", 25], ["a7d1", "а", 5, "ёж", 25], ["a840", "ˊˋ˙–―‥‵℅℉↖↗↘↙∕∟∣≒≦≧⊿═", 35, "▁", 6], ["a880", "█", 7, "▓▔▕▼▽◢◣◤◥☉⊕〒〝〞"], ["a8a1", "āáǎàēéěèīíǐìōóǒòūúǔùǖǘǚǜüêɑ"], ["a8bd", "ńň"], ["a8c0", "ɡ"], ["a8c5", "ㄅ", 36], ["a940", "〡", 8, "㊣㎎㎏㎜㎝㎞㎡㏄㏎㏑㏒㏕︰¬¦"], ["a959", "℡㈱"], ["a95c", "‐"], ["a960", "ー゛゜ヽヾ〆ゝゞ﹉", 9, "﹔﹕﹖﹗﹙", 8], ["a980", "﹢", 4, "﹨﹩﹪﹫"], ["a996", "〇"], ["a9a4", "─", 75], ["aa40", "狜狝狟狢", 5, "狪狫狵狶狹狽狾狿猀猂猄", 5, "猋猌猍猏猐猑猒猔猘猙猚猟猠猣猤猦猧猨猭猯猰猲猳猵猶猺猻猼猽獀", 8], ["aa80", "獉獊獋獌獎獏獑獓獔獕獖獘", 7, "獡", 10, "獮獰獱"], ["ab40", "獲", 11, "獿", 4, "玅玆玈玊玌玍玏玐玒玓玔玕玗玘玙玚玜玝玞玠玡玣", 5, "玪玬玭玱玴玵玶玸玹玼玽玾玿珁珃", 4], ["ab80", "珋珌珎珒", 6, "珚珛珜珝珟珡珢珣珤珦珨珪珫珬珮珯珰珱珳", 4], ["ac40", "珸", 10, "琄琇琈琋琌琍琎琑", 8, "琜", 5, "琣琤琧琩琫琭琯琱琲琷", 4, "琽琾琿瑀瑂", 11], ["ac80", "瑎", 6, "瑖瑘瑝瑠", 12, "瑮瑯瑱", 4, "瑸瑹瑺"], ["ad40", "瑻瑼瑽瑿璂璄璅璆璈璉璊璌璍璏璑", 10, "璝璟", 7, "璪", 15, "璻", 12], ["ad80", "瓈", 9, "瓓", 8, "瓝瓟瓡瓥瓧", 6, "瓰瓱瓲"], ["ae40", "瓳瓵瓸", 6, "甀甁甂甃甅", 7, "甎甐甒甔甕甖甗甛甝甞甠", 4, "甦甧甪甮甴甶甹甼甽甿畁畂畃畄畆畇畉畊畍畐畑畒畓畕畖畗畘"], ["ae80", "畝", 7, "畧畨畩畫", 6, "畳畵當畷畺", 4, "疀疁疂疄疅疇"], ["af40", "疈疉疊疌疍疎疐疓疕疘疛疜疞疢疦", 4, "疭疶疷疺疻疿痀痁痆痋痌痎痏痐痑痓痗痙痚痜痝痟痠痡痥痩痬痭痮痯痲痳痵痶痷痸痺痻痽痾瘂瘄瘆瘇"], ["af80", "瘈瘉瘋瘍瘎瘏瘑瘒瘓瘔瘖瘚瘜瘝瘞瘡瘣瘧瘨瘬瘮瘯瘱瘲瘶瘷瘹瘺瘻瘽癁療癄"], ["b040", "癅", 6, "癎", 5, "癕癗", 4, "癝癟癠癡癢癤", 6, "癬癭癮癰", 7, "癹発發癿皀皁皃皅皉皊皌皍皏皐皒皔皕皗皘皚皛"], ["b080", "皜", 7, "皥", 8, "皯皰皳皵", 9, "盀盁盃啊阿埃挨哎唉哀皑癌蔼矮艾碍爱隘鞍氨安俺按暗岸胺案肮昂盎凹敖熬翱袄傲奥懊澳芭捌扒叭吧笆八疤巴拔跋靶把耙坝霸罢爸白柏百摆佰败拜稗斑班搬扳般颁板版扮拌伴瓣半办绊邦帮梆榜膀绑棒磅蚌镑傍谤苞胞包褒剥"], ["b140", "盄盇盉盋盌盓盕盙盚盜盝盞盠", 4, "盦", 7, "盰盳盵盶盷盺盻盽盿眀眂眃眅眆眊県眎", 10, "眛眜眝眞眡眣眤眥眧眪眫"], ["b180", "眬眮眰", 4, "眹眻眽眾眿睂睄睅睆睈", 7, "睒", 7, "睜薄雹保堡饱宝抱报暴豹鲍爆杯碑悲卑北辈背贝钡倍狈备惫焙被奔苯本笨崩绷甭泵蹦迸逼鼻比鄙笔彼碧蓖蔽毕毙毖币庇痹闭敝弊必辟壁臂避陛鞭边编贬扁便变卞辨辩辫遍标彪膘表鳖憋别瘪彬斌濒滨宾摈兵冰柄丙秉饼炳"], ["b240", "睝睞睟睠睤睧睩睪睭", 11, "睺睻睼瞁瞂瞃瞆", 5, "瞏瞐瞓", 11, "瞡瞣瞤瞦瞨瞫瞭瞮瞯瞱瞲瞴瞶", 4], ["b280", "瞼瞾矀", 12, "矎", 8, "矘矙矚矝", 4, "矤病并玻菠播拨钵波博勃搏铂箔伯帛舶脖膊渤泊驳捕卜哺补埠不布步簿部怖擦猜裁材才财睬踩采彩菜蔡餐参蚕残惭惨灿苍舱仓沧藏操糙槽曹草厕策侧册测层蹭插叉茬茶查碴搽察岔差诧拆柴豺搀掺蝉馋谗缠铲产阐颤昌猖"], ["b340", "矦矨矪矯矰矱矲矴矵矷矹矺矻矼砃", 5, "砊砋砎砏砐砓砕砙砛砞砠砡砢砤砨砪砫砮砯砱砲砳砵砶砽砿硁硂硃硄硆硈硉硊硋硍硏硑硓硔硘硙硚"], ["b380", "硛硜硞", 11, "硯", 7, "硸硹硺硻硽", 6, "场尝常长偿肠厂敞畅唱倡超抄钞朝嘲潮巢吵炒车扯撤掣彻澈郴臣辰尘晨忱沉陈趁衬撑称城橙成呈乘程惩澄诚承逞骋秤吃痴持匙池迟弛驰耻齿侈尺赤翅斥炽充冲虫崇宠抽酬畴踌稠愁筹仇绸瞅丑臭初出橱厨躇锄雏滁除楚"], ["b440", "碄碅碆碈碊碋碏碐碒碔碕碖碙碝碞碠碢碤碦碨", 7, "碵碶碷碸確碻碼碽碿磀磂磃磄磆磇磈磌磍磎磏磑磒磓磖磗磘磚", 9], ["b480", "磤磥磦磧磩磪磫磭", 4, "磳磵磶磸磹磻", 5, "礂礃礄礆", 6, "础储矗搐触处揣川穿椽传船喘串疮窗幢床闯创吹炊捶锤垂春椿醇唇淳纯蠢戳绰疵茨磁雌辞慈瓷词此刺赐次聪葱囱匆从丛凑粗醋簇促蹿篡窜摧崔催脆瘁粹淬翠村存寸磋撮搓措挫错搭达答瘩打大呆歹傣戴带殆代贷袋待逮"], ["b540", "礍", 5, "礔", 9, "礟", 4, "礥", 14, "礵", 4, "礽礿祂祃祄祅祇祊", 8, "祔祕祘祙祡祣"], ["b580", "祤祦祩祪祫祬祮祰", 6, "祹祻", 4, "禂禃禆禇禈禉禋禌禍禎禐禑禒怠耽担丹单郸掸胆旦氮但惮淡诞弹蛋当挡党荡档刀捣蹈倒岛祷导到稻悼道盗德得的蹬灯登等瞪凳邓堤低滴迪敌笛狄涤翟嫡抵底地蒂第帝弟递缔颠掂滇碘点典靛垫电佃甸店惦奠淀殿碉叼雕凋刁掉吊钓调跌爹碟蝶迭谍叠"], ["b640", "禓", 6, "禛", 11, "禨", 10, "禴", 4, "禼禿秂秄秅秇秈秊秌秎秏秐秓秔秖秗秙", 5, "秠秡秢秥秨秪"], ["b680", "秬秮秱", 6, "秹秺秼秾秿稁稄稅稇稈稉稊稌稏", 4, "稕稖稘稙稛稜丁盯叮钉顶鼎锭定订丢东冬董懂动栋侗恫冻洞兜抖斗陡豆逗痘都督毒犊独读堵睹赌杜镀肚度渡妒端短锻段断缎堆兑队对墩吨蹲敦顿囤钝盾遁掇哆多夺垛躲朵跺舵剁惰堕蛾峨鹅俄额讹娥恶厄扼遏鄂饿恩而儿耳尔饵洱二"], ["b740", "稝稟稡稢稤", 14, "稴稵稶稸稺稾穀", 5, "穇", 9, "穒", 4, "穘", 16], ["b780", "穩", 6, "穱穲穳穵穻穼穽穾窂窅窇窉窊窋窌窎窏窐窓窔窙窚窛窞窡窢贰发罚筏伐乏阀法珐藩帆番翻樊矾钒繁凡烦反返范贩犯饭泛坊芳方肪房防妨仿访纺放菲非啡飞肥匪诽吠肺废沸费芬酚吩氛分纷坟焚汾粉奋份忿愤粪丰封枫蜂峰锋风疯烽逢冯缝讽奉凤佛否夫敷肤孵扶拂辐幅氟符伏俘服"], ["b840", "窣窤窧窩窪窫窮", 4, "窴", 10, "竀", 10, "竌", 9, "竗竘竚竛竜竝竡竢竤竧", 5, "竮竰竱竲竳"], ["b880", "竴", 4, "竻竼竾笀笁笂笅笇笉笌笍笎笐笒笓笖笗笘笚笜笝笟笡笢笣笧笩笭浮涪福袱弗甫抚辅俯釜斧脯腑府腐赴副覆赋复傅付阜父腹负富讣附妇缚咐噶嘎该改概钙盖溉干甘杆柑竿肝赶感秆敢赣冈刚钢缸肛纲岗港杠篙皋高膏羔糕搞镐稿告哥歌搁戈鸽胳疙割革葛格蛤阁隔铬个各给根跟耕更庚羹"], ["b940", "笯笰笲笴笵笶笷笹笻笽笿", 5, "筆筈筊筍筎筓筕筗筙筜筞筟筡筣", 10, "筯筰筳筴筶筸筺筼筽筿箁箂箃箄箆", 6, "箎箏"], ["b980", "箑箒箓箖箘箙箚箛箞箟箠箣箤箥箮箯箰箲箳箵箶箷箹", 7, "篂篃範埂耿梗工攻功恭龚供躬公宫弓巩汞拱贡共钩勾沟苟狗垢构购够辜菇咕箍估沽孤姑鼓古蛊骨谷股故顾固雇刮瓜剐寡挂褂乖拐怪棺关官冠观管馆罐惯灌贯光广逛瑰规圭硅归龟闺轨鬼诡癸桂柜跪贵刽辊滚棍锅郭国果裹过哈"], ["ba40", "篅篈築篊篋篍篎篏篐篒篔", 4, "篛篜篞篟篠篢篣篤篧篨篩篫篬篭篯篰篲", 4, "篸篹篺篻篽篿", 7, "簈簉簊簍簎簐", 5, "簗簘簙"], ["ba80", "簚", 4, "簠", 5, "簨簩簫", 12, "簹", 5, "籂骸孩海氦亥害骇酣憨邯韩含涵寒函喊罕翰撼捍旱憾悍焊汗汉夯杭航壕嚎豪毫郝好耗号浩呵喝荷菏核禾和何合盒貉阂河涸赫褐鹤贺嘿黑痕很狠恨哼亨横衡恒轰哄烘虹鸿洪宏弘红喉侯猴吼厚候后呼乎忽瑚壶葫胡蝴狐糊湖"], ["bb40", "籃", 9, "籎", 36, "籵", 5, "籾", 9], ["bb80", "粈粊", 6, "粓粔粖粙粚粛粠粡粣粦粧粨粩粫粬粭粯粰粴", 4, "粺粻弧虎唬护互沪户花哗华猾滑画划化话槐徊怀淮坏欢环桓还缓换患唤痪豢焕涣宦幻荒慌黄磺蝗簧皇凰惶煌晃幌恍谎灰挥辉徽恢蛔回毁悔慧卉惠晦贿秽会烩汇讳诲绘荤昏婚魂浑混豁活伙火获或惑霍货祸击圾基机畸稽积箕"], ["bc40", "粿糀糂糃糄糆糉糋糎", 6, "糘糚糛糝糞糡", 6, "糩", 5, "糰", 7, "糹糺糼", 13, "紋", 5], ["bc80", "紑", 14, "紡紣紤紥紦紨紩紪紬紭紮細", 6, "肌饥迹激讥鸡姬绩缉吉极棘辑籍集及急疾汲即嫉级挤几脊己蓟技冀季伎祭剂悸济寄寂计记既忌际妓继纪嘉枷夹佳家加荚颊贾甲钾假稼价架驾嫁歼监坚尖笺间煎兼肩艰奸缄茧检柬碱硷拣捡简俭剪减荐槛鉴践贱见键箭件"], ["bd40", "紷", 54, "絯", 7], ["bd80", "絸", 32, "健舰剑饯渐溅涧建僵姜将浆江疆蒋桨奖讲匠酱降蕉椒礁焦胶交郊浇骄娇嚼搅铰矫侥脚狡角饺缴绞剿教酵轿较叫窖揭接皆秸街阶截劫节桔杰捷睫竭洁结解姐戒藉芥界借介疥诫届巾筋斤金今津襟紧锦仅谨进靳晋禁近烬浸"], ["be40", "継", 12, "綧", 6, "綯", 42], ["be80", "線", 32, "尽劲荆兢茎睛晶鲸京惊精粳经井警景颈静境敬镜径痉靖竟竞净炯窘揪究纠玖韭久灸九酒厩救旧臼舅咎就疚鞠拘狙疽居驹菊局咀矩举沮聚拒据巨具距踞锯俱句惧炬剧捐鹃娟倦眷卷绢撅攫抉掘倔爵觉决诀绝均菌钧军君峻"], ["bf40", "緻", 62], ["bf80", "縺縼", 4, "繂", 4, "繈", 21, "俊竣浚郡骏喀咖卡咯开揩楷凯慨刊堪勘坎砍看康慷糠扛抗亢炕考拷烤靠坷苛柯棵磕颗科壳咳可渴克刻客课肯啃垦恳坑吭空恐孔控抠口扣寇枯哭窟苦酷库裤夸垮挎跨胯块筷侩快宽款匡筐狂框矿眶旷况亏盔岿窥葵奎魁傀"], ["c040", "繞", 35, "纃", 23, "纜纝纞"], ["c080", "纮纴纻纼绖绤绬绹缊缐缞缷缹缻", 6, "罃罆", 9, "罒罓馈愧溃坤昆捆困括扩廓阔垃拉喇蜡腊辣啦莱来赖蓝婪栏拦篮阑兰澜谰揽览懒缆烂滥琅榔狼廊郎朗浪捞劳牢老佬姥酪烙涝勒乐雷镭蕾磊累儡垒擂肋类泪棱楞冷厘梨犁黎篱狸离漓理李里鲤礼莉荔吏栗丽厉励砾历利傈例俐"], ["c140", "罖罙罛罜罝罞罠罣", 4, "罫罬罭罯罰罳罵罶罷罸罺罻罼罽罿羀羂", 7, "羋羍羏", 4, "羕", 4, "羛羜羠羢羣羥羦羨", 6, "羱"], ["c180", "羳", 4, "羺羻羾翀翂翃翄翆翇翈翉翋翍翏", 4, "翖翗翙", 5, "翢翣痢立粒沥隶力璃哩俩联莲连镰廉怜涟帘敛脸链恋炼练粮凉梁粱良两辆量晾亮谅撩聊僚疗燎寥辽潦了撂镣廖料列裂烈劣猎琳林磷霖临邻鳞淋凛赁吝拎玲菱零龄铃伶羚凌灵陵岭领另令溜琉榴硫馏留刘瘤流柳六龙聋咙笼窿"], ["c240", "翤翧翨翪翫翬翭翯翲翴", 6, "翽翾翿耂耇耈耉耊耎耏耑耓耚耛耝耞耟耡耣耤耫", 5, "耲耴耹耺耼耾聀聁聄聅聇聈聉聎聏聐聑聓聕聖聗"], ["c280", "聙聛", 13, "聫", 5, "聲", 11, "隆垄拢陇楼娄搂篓漏陋芦卢颅庐炉掳卤虏鲁麓碌露路赂鹿潞禄录陆戮驴吕铝侣旅履屡缕虑氯律率滤绿峦挛孪滦卵乱掠略抡轮伦仑沦纶论萝螺罗逻锣箩骡裸落洛骆络妈麻玛码蚂马骂嘛吗埋买麦卖迈脉瞒馒蛮满蔓曼慢漫"], ["c340", "聾肁肂肅肈肊肍", 5, "肔肕肗肙肞肣肦肧肨肬肰肳肵肶肸肹肻胅胇", 4, "胏", 6, "胘胟胠胢胣胦胮胵胷胹胻胾胿脀脁脃脄脅脇脈脋"], ["c380", "脌脕脗脙脛脜脝脟", 12, "脭脮脰脳脴脵脷脹", 4, "脿谩芒茫盲氓忙莽猫茅锚毛矛铆卯茂冒帽貌贸么玫枚梅酶霉煤没眉媒镁每美昧寐妹媚门闷们萌蒙檬盟锰猛梦孟眯醚靡糜迷谜弥米秘觅泌蜜密幂棉眠绵冕免勉娩缅面苗描瞄藐秒渺庙妙蔑灭民抿皿敏悯闽明螟鸣铭名命谬摸"], ["c440", "腀", 5, "腇腉腍腎腏腒腖腗腘腛", 4, "腡腢腣腤腦腨腪腫腬腯腲腳腵腶腷腸膁膃", 4, "膉膋膌膍膎膐膒", 5, "膙膚膞", 4, "膤膥"], ["c480", "膧膩膫", 7, "膴", 5, "膼膽膾膿臄臅臇臈臉臋臍", 6, "摹蘑模膜磨摩魔抹末莫墨默沫漠寞陌谋牟某拇牡亩姆母墓暮幕募慕木目睦牧穆拿哪呐钠那娜纳氖乃奶耐奈南男难囊挠脑恼闹淖呢馁内嫩能妮霓倪泥尼拟你匿腻逆溺蔫拈年碾撵捻念娘酿鸟尿捏聂孽啮镊镍涅您柠狞凝宁"], ["c540", "臔", 14, "臤臥臦臨臩臫臮", 4, "臵", 5, "臽臿舃與", 4, "舎舏舑舓舕", 5, "舝舠舤舥舦舧舩舮舲舺舼舽舿"], ["c580", "艀艁艂艃艅艆艈艊艌艍艎艐", 7, "艙艛艜艝艞艠", 7, "艩拧泞牛扭钮纽脓浓农弄奴努怒女暖虐疟挪懦糯诺哦欧鸥殴藕呕偶沤啪趴爬帕怕琶拍排牌徘湃派攀潘盘磐盼畔判叛乓庞旁耪胖抛咆刨炮袍跑泡呸胚培裴赔陪配佩沛喷盆砰抨烹澎彭蓬棚硼篷膨朋鹏捧碰坯砒霹批披劈琵毗"], ["c640", "艪艫艬艭艱艵艶艷艸艻艼芀芁芃芅芆芇芉芌芐芓芔芕芖芚芛芞芠芢芣芧芲芵芶芺芻芼芿苀苂苃苅苆苉苐苖苙苚苝苢苧苨苩苪苬苭苮苰苲苳苵苶苸"], ["c680", "苺苼", 4, "茊茋茍茐茒茓茖茘茙茝", 9, "茩茪茮茰茲茷茻茽啤脾疲皮匹痞僻屁譬篇偏片骗飘漂瓢票撇瞥拼频贫品聘乒坪苹萍平凭瓶评屏坡泼颇婆破魄迫粕剖扑铺仆莆葡菩蒲埔朴圃普浦谱曝瀑期欺栖戚妻七凄漆柒沏其棋奇歧畦崎脐齐旗祈祁骑起岂乞企启契砌器气迄弃汽泣讫掐"], ["c740", "茾茿荁荂荄荅荈荊", 4, "荓荕", 4, "荝荢荰", 6, "荹荺荾", 6, "莇莈莊莋莌莍莏莐莑莔莕莖莗莙莚莝莟莡", 6, "莬莭莮"], ["c780", "莯莵莻莾莿菂菃菄菆菈菉菋菍菎菐菑菒菓菕菗菙菚菛菞菢菣菤菦菧菨菫菬菭恰洽牵扦钎铅千迁签仟谦乾黔钱钳前潜遣浅谴堑嵌欠歉枪呛腔羌墙蔷强抢橇锹敲悄桥瞧乔侨巧鞘撬翘峭俏窍切茄且怯窃钦侵亲秦琴勤芹擒禽寝沁青轻氢倾卿清擎晴氰情顷请庆琼穷秋丘邱球求囚酋泅趋区蛆曲躯屈驱渠"], ["c840", "菮華菳", 4, "菺菻菼菾菿萀萂萅萇萈萉萊萐萒", 5, "萙萚萛萞", 5, "萩", 7, "萲", 5, "萹萺萻萾", 7, "葇葈葉"], ["c880", "葊", 6, "葒", 4, "葘葝葞葟葠葢葤", 4, "葪葮葯葰葲葴葷葹葻葼取娶龋趣去圈颧权醛泉全痊拳犬券劝缺炔瘸却鹊榷确雀裙群然燃冉染瓤壤攘嚷让饶扰绕惹热壬仁人忍韧任认刃妊纫扔仍日戎茸蓉荣融熔溶容绒冗揉柔肉茹蠕儒孺如辱乳汝入褥软阮蕊瑞锐闰润若弱撒洒萨腮鳃塞赛三叁"], ["c940", "葽", 4, "蒃蒄蒅蒆蒊蒍蒏", 7, "蒘蒚蒛蒝蒞蒟蒠蒢", 12, "蒰蒱蒳蒵蒶蒷蒻蒼蒾蓀蓂蓃蓅蓆蓇蓈蓋蓌蓎蓏蓒蓔蓕蓗"], ["c980", "蓘", 4, "蓞蓡蓢蓤蓧", 4, "蓭蓮蓯蓱", 10, "蓽蓾蔀蔁蔂伞散桑嗓丧搔骚扫嫂瑟色涩森僧莎砂杀刹沙纱傻啥煞筛晒珊苫杉山删煽衫闪陕擅赡膳善汕扇缮墒伤商赏晌上尚裳梢捎稍烧芍勺韶少哨邵绍奢赊蛇舌舍赦摄射慑涉社设砷申呻伸身深娠绅神沈审婶甚肾慎渗声生甥牲升绳"], ["ca40", "蔃", 8, "蔍蔎蔏蔐蔒蔔蔕蔖蔘蔙蔛蔜蔝蔞蔠蔢", 8, "蔭", 9, "蔾", 4, "蕄蕅蕆蕇蕋", 10], ["ca80", "蕗蕘蕚蕛蕜蕝蕟", 4, "蕥蕦蕧蕩", 8, "蕳蕵蕶蕷蕸蕼蕽蕿薀薁省盛剩胜圣师失狮施湿诗尸虱十石拾时什食蚀实识史矢使屎驶始式示士世柿事拭誓逝势是嗜噬适仕侍释饰氏市恃室视试收手首守寿授售受瘦兽蔬枢梳殊抒输叔舒淑疏书赎孰熟薯暑曙署蜀黍鼠属术述树束戍竖墅庶数漱"], ["cb40", "薂薃薆薈", 6, "薐", 10, "薝", 6, "薥薦薧薩薫薬薭薱", 5, "薸薺", 6, "藂", 6, "藊", 4, "藑藒"], ["cb80", "藔藖", 5, "藝", 6, "藥藦藧藨藪", 14, "恕刷耍摔衰甩帅栓拴霜双爽谁水睡税吮瞬顺舜说硕朔烁斯撕嘶思私司丝死肆寺嗣四伺似饲巳松耸怂颂送宋讼诵搜艘擞嗽苏酥俗素速粟僳塑溯宿诉肃酸蒜算虽隋随绥髓碎岁穗遂隧祟孙损笋蓑梭唆缩琐索锁所塌他它她塔"], ["cc40", "藹藺藼藽藾蘀", 4, "蘆", 10, "蘒蘓蘔蘕蘗", 15, "蘨蘪", 13, "蘹蘺蘻蘽蘾蘿虀"], ["cc80", "虁", 11, "虒虓處", 4, "虛虜虝號虠虡虣", 7, "獭挞蹋踏胎苔抬台泰酞太态汰坍摊贪瘫滩坛檀痰潭谭谈坦毯袒碳探叹炭汤塘搪堂棠膛唐糖倘躺淌趟烫掏涛滔绦萄桃逃淘陶讨套特藤腾疼誊梯剔踢锑提题蹄啼体替嚏惕涕剃屉天添填田甜恬舔腆挑条迢眺跳贴铁帖厅听烃"], ["cd40", "虭虯虰虲", 6, "蚃", 6, "蚎", 4, "蚔蚖", 5, "蚞", 4, "蚥蚦蚫蚭蚮蚲蚳蚷蚸蚹蚻", 4, "蛁蛂蛃蛅蛈蛌蛍蛒蛓蛕蛖蛗蛚蛜"], ["cd80", "蛝蛠蛡蛢蛣蛥蛦蛧蛨蛪蛫蛬蛯蛵蛶蛷蛺蛻蛼蛽蛿蜁蜄蜅蜆蜋蜌蜎蜏蜐蜑蜔蜖汀廷停亭庭挺艇通桐酮瞳同铜彤童桶捅筒统痛偷投头透凸秃突图徒途涂屠土吐兔湍团推颓腿蜕褪退吞屯臀拖托脱鸵陀驮驼椭妥拓唾挖哇蛙洼娃瓦袜歪外豌弯湾玩顽丸烷完碗挽晚皖惋宛婉万腕汪王亡枉网往旺望忘妄威"], ["ce40", "蜙蜛蜝蜟蜠蜤蜦蜧蜨蜪蜫蜬蜭蜯蜰蜲蜳蜵蜶蜸蜹蜺蜼蜽蝀", 6, "蝊蝋蝍蝏蝐蝑蝒蝔蝕蝖蝘蝚", 5, "蝡蝢蝦", 7, "蝯蝱蝲蝳蝵"], ["ce80", "蝷蝸蝹蝺蝿螀螁螄螆螇螉螊螌螎", 4, "螔螕螖螘", 6, "螠", 4, "巍微危韦违桅围唯惟为潍维苇萎委伟伪尾纬未蔚味畏胃喂魏位渭谓尉慰卫瘟温蚊文闻纹吻稳紊问嗡翁瓮挝蜗涡窝我斡卧握沃巫呜钨乌污诬屋无芜梧吾吴毋武五捂午舞伍侮坞戊雾晤物勿务悟误昔熙析西硒矽晰嘻吸锡牺"], ["cf40", "螥螦螧螩螪螮螰螱螲螴螶螷螸螹螻螼螾螿蟁", 4, "蟇蟈蟉蟌", 4, "蟔", 6, "蟜蟝蟞蟟蟡蟢蟣蟤蟦蟧蟨蟩蟫蟬蟭蟯", 9], ["cf80", "蟺蟻蟼蟽蟿蠀蠁蠂蠄", 5, "蠋", 7, "蠔蠗蠘蠙蠚蠜", 4, "蠣稀息希悉膝夕惜熄烯溪汐犀檄袭席习媳喜铣洗系隙戏细瞎虾匣霞辖暇峡侠狭下厦夏吓掀锨先仙鲜纤咸贤衔舷闲涎弦嫌显险现献县腺馅羡宪陷限线相厢镶香箱襄湘乡翔祥详想响享项巷橡像向象萧硝霄削哮嚣销消宵淆晓"], ["d040", "蠤", 13, "蠳", 5, "蠺蠻蠽蠾蠿衁衂衃衆", 5, "衎", 5, "衕衖衘衚", 6, "衦衧衪衭衯衱衳衴衵衶衸衹衺"], ["d080", "衻衼袀袃袆袇袉袊袌袎袏袐袑袓袔袕袗", 4, "袝", 4, "袣袥", 5, "小孝校肖啸笑效楔些歇蝎鞋协挟携邪斜胁谐写械卸蟹懈泄泻谢屑薪芯锌欣辛新忻心信衅星腥猩惺兴刑型形邢行醒幸杏性姓兄凶胸匈汹雄熊休修羞朽嗅锈秀袖绣墟戌需虚嘘须徐许蓄酗叙旭序畜恤絮婿绪续轩喧宣悬旋玄"], ["d140", "袬袮袯袰袲", 4, "袸袹袺袻袽袾袿裀裃裄裇裈裊裋裌裍裏裐裑裓裖裗裚", 4, "裠裡裦裧裩", 6, "裲裵裶裷裺裻製裿褀褁褃", 5], ["d180", "褉褋", 4, "褑褔", 4, "褜", 4, "褢褣褤褦褧褨褩褬褭褮褯褱褲褳褵褷选癣眩绚靴薛学穴雪血勋熏循旬询寻驯巡殉汛训讯逊迅压押鸦鸭呀丫芽牙蚜崖衙涯雅哑亚讶焉咽阉烟淹盐严研蜒岩延言颜阎炎沿奄掩眼衍演艳堰燕厌砚雁唁彦焰宴谚验殃央鸯秧杨扬佯疡羊洋阳氧仰痒养样漾邀腰妖瑶"], ["d240", "褸", 8, "襂襃襅", 24, "襠", 5, "襧", 19, "襼"], ["d280", "襽襾覀覂覄覅覇", 26, "摇尧遥窑谣姚咬舀药要耀椰噎耶爷野冶也页掖业叶曳腋夜液一壹医揖铱依伊衣颐夷遗移仪胰疑沂宜姨彝椅蚁倚已乙矣以艺抑易邑屹亿役臆逸肄疫亦裔意毅忆义益溢诣议谊译异翼翌绎茵荫因殷音阴姻吟银淫寅饮尹引隐"], ["d340", "覢", 30, "觃觍觓觔觕觗觘觙觛觝觟觠觡觢觤觧觨觩觪觬觭觮觰觱觲觴", 6], ["d380", "觻", 4, "訁", 5, "計", 21, "印英樱婴鹰应缨莹萤营荧蝇迎赢盈影颖硬映哟拥佣臃痈庸雍踊蛹咏泳涌永恿勇用幽优悠忧尤由邮铀犹油游酉有友右佑釉诱又幼迂淤于盂榆虞愚舆余俞逾鱼愉渝渔隅予娱雨与屿禹宇语羽玉域芋郁吁遇喻峪御愈欲狱育誉"], ["d440", "訞", 31, "訿", 8, "詉", 21], ["d480", "詟", 25, "詺", 6, "浴寓裕预豫驭鸳渊冤元垣袁原援辕园员圆猿源缘远苑愿怨院曰约越跃钥岳粤月悦阅耘云郧匀陨允运蕴酝晕韵孕匝砸杂栽哉灾宰载再在咱攒暂赞赃脏葬遭糟凿藻枣早澡蚤躁噪造皂灶燥责择则泽贼怎增憎曾赠扎喳渣札轧"], ["d540", "誁", 7, "誋", 7, "誔", 46], ["d580", "諃", 32, "铡闸眨栅榨咋乍炸诈摘斋宅窄债寨瞻毡詹粘沾盏斩辗崭展蘸栈占战站湛绽樟章彰漳张掌涨杖丈帐账仗胀瘴障招昭找沼赵照罩兆肇召遮折哲蛰辙者锗蔗这浙珍斟真甄砧臻贞针侦枕疹诊震振镇阵蒸挣睁征狰争怔整拯正政"], ["d640", "諤", 34, "謈", 27], ["d680", "謤謥謧", 30, "帧症郑证芝枝支吱蜘知肢脂汁之织职直植殖执值侄址指止趾只旨纸志挚掷至致置帜峙制智秩稚质炙痔滞治窒中盅忠钟衷终种肿重仲众舟周州洲诌粥轴肘帚咒皱宙昼骤珠株蛛朱猪诸诛逐竹烛煮拄瞩嘱主著柱助蛀贮铸筑"], ["d740", "譆", 31, "譧", 4, "譭", 25], ["d780", "讇", 24, "讬讱讻诇诐诪谉谞住注祝驻抓爪拽专砖转撰赚篆桩庄装妆撞壮状椎锥追赘坠缀谆准捉拙卓桌琢茁酌啄着灼浊兹咨资姿滋淄孜紫仔籽滓子自渍字鬃棕踪宗综总纵邹走奏揍租足卒族祖诅阻组钻纂嘴醉最罪尊遵昨左佐柞做作坐座"], ["d840", "谸", 8, "豂豃豄豅豈豊豋豍", 7, "豖豗豘豙豛", 5, "豣", 6, "豬", 6, "豴豵豶豷豻", 6, "貃貄貆貇"], ["d880", "貈貋貍", 6, "貕貖貗貙", 20, "亍丌兀丐廿卅丕亘丞鬲孬噩丨禺丿匕乇夭爻卮氐囟胤馗毓睾鼗丶亟鼐乜乩亓芈孛啬嘏仄厍厝厣厥厮靥赝匚叵匦匮匾赜卦卣刂刈刎刭刳刿剀剌剞剡剜蒯剽劂劁劐劓冂罔亻仃仉仂仨仡仫仞伛仳伢佤仵伥伧伉伫佞佧攸佚佝"], ["d940", "貮", 62], ["d980", "賭", 32, "佟佗伲伽佶佴侑侉侃侏佾佻侪佼侬侔俦俨俪俅俚俣俜俑俟俸倩偌俳倬倏倮倭俾倜倌倥倨偾偃偕偈偎偬偻傥傧傩傺僖儆僭僬僦僮儇儋仝氽佘佥俎龠汆籴兮巽黉馘冁夔勹匍訇匐凫夙兕亠兖亳衮袤亵脔裒禀嬴蠃羸冫冱冽冼"], ["da40", "贎", 14, "贠赑赒赗赟赥赨赩赪赬赮赯赱赲赸", 8, "趂趃趆趇趈趉趌", 4, "趒趓趕", 9, "趠趡"], ["da80", "趢趤", 12, "趲趶趷趹趻趽跀跁跂跅跇跈跉跊跍跐跒跓跔凇冖冢冥讠讦讧讪讴讵讷诂诃诋诏诎诒诓诔诖诘诙诜诟诠诤诨诩诮诰诳诶诹诼诿谀谂谄谇谌谏谑谒谔谕谖谙谛谘谝谟谠谡谥谧谪谫谮谯谲谳谵谶卩卺阝阢阡阱阪阽阼陂陉陔陟陧陬陲陴隈隍隗隰邗邛邝邙邬邡邴邳邶邺"], ["db40", "跕跘跙跜跠跡跢跥跦跧跩跭跮跰跱跲跴跶跼跾", 6, "踆踇踈踋踍踎踐踑踒踓踕", 7, "踠踡踤", 4, "踫踭踰踲踳踴踶踷踸踻踼踾"], ["db80", "踿蹃蹅蹆蹌", 4, "蹓", 5, "蹚", 11, "蹧蹨蹪蹫蹮蹱邸邰郏郅邾郐郄郇郓郦郢郜郗郛郫郯郾鄄鄢鄞鄣鄱鄯鄹酃酆刍奂劢劬劭劾哿勐勖勰叟燮矍廴凵凼鬯厶弁畚巯坌垩垡塾墼壅壑圩圬圪圳圹圮圯坜圻坂坩垅坫垆坼坻坨坭坶坳垭垤垌垲埏垧垴垓垠埕埘埚埙埒垸埴埯埸埤埝"], ["dc40", "蹳蹵蹷", 4, "蹽蹾躀躂躃躄躆躈", 6, "躑躒躓躕", 6, "躝躟", 11, "躭躮躰躱躳", 6, "躻", 7], ["dc80", "軃", 10, "軏", 21, "堋堍埽埭堀堞堙塄堠塥塬墁墉墚墀馨鼙懿艹艽艿芏芊芨芄芎芑芗芙芫芸芾芰苈苊苣芘芷芮苋苌苁芩芴芡芪芟苄苎芤苡茉苷苤茏茇苜苴苒苘茌苻苓茑茚茆茔茕苠苕茜荑荛荜茈莒茼茴茱莛荞茯荏荇荃荟荀茗荠茭茺茳荦荥"], ["dd40", "軥", 62], ["dd80", "輤", 32, "荨茛荩荬荪荭荮莰荸莳莴莠莪莓莜莅荼莶莩荽莸荻莘莞莨莺莼菁萁菥菘堇萘萋菝菽菖萜萸萑萆菔菟萏萃菸菹菪菅菀萦菰菡葜葑葚葙葳蒇蒈葺蒉葸萼葆葩葶蒌蒎萱葭蓁蓍蓐蓦蒽蓓蓊蒿蒺蓠蒡蒹蒴蒗蓥蓣蔌甍蔸蓰蔹蔟蔺"], ["de40", "轅", 32, "轪辀辌辒辝辠辡辢辤辥辦辧辪辬辭辮辯農辳辴辵辷辸辺辻込辿迀迃迆"], ["de80", "迉", 4, "迏迒迖迗迚迠迡迣迧迬迯迱迲迴迵迶迺迻迼迾迿逇逈逌逎逓逕逘蕖蔻蓿蓼蕙蕈蕨蕤蕞蕺瞢蕃蕲蕻薤薨薇薏蕹薮薜薅薹薷薰藓藁藜藿蘧蘅蘩蘖蘼廾弈夼奁耷奕奚奘匏尢尥尬尴扌扪抟抻拊拚拗拮挢拶挹捋捃掭揶捱捺掎掴捭掬掊捩掮掼揲揸揠揿揄揞揎摒揆掾摅摁搋搛搠搌搦搡摞撄摭撖"], ["df40", "這逜連逤逥逧", 5, "逰", 4, "逷逹逺逽逿遀遃遅遆遈", 4, "過達違遖遙遚遜", 5, "遤遦遧適遪遫遬遯", 4, "遶", 6, "遾邁"], ["df80", "還邅邆邇邉邊邌", 4, "邒邔邖邘邚邜邞邟邠邤邥邧邨邩邫邭邲邷邼邽邿郀摺撷撸撙撺擀擐擗擤擢攉攥攮弋忒甙弑卟叱叽叩叨叻吒吖吆呋呒呓呔呖呃吡呗呙吣吲咂咔呷呱呤咚咛咄呶呦咝哐咭哂咴哒咧咦哓哔呲咣哕咻咿哌哙哚哜咩咪咤哝哏哞唛哧唠哽唔哳唢唣唏唑唧唪啧喏喵啉啭啁啕唿啐唼"], ["e040", "郂郃郆郈郉郋郌郍郒郔郕郖郘郙郚郞郟郠郣郤郥郩郪郬郮郰郱郲郳郵郶郷郹郺郻郼郿鄀鄁鄃鄅", 19, "鄚鄛鄜"], ["e080", "鄝鄟鄠鄡鄤", 10, "鄰鄲", 6, "鄺", 8, "酄唷啖啵啶啷唳唰啜喋嗒喃喱喹喈喁喟啾嗖喑啻嗟喽喾喔喙嗪嗷嗉嘟嗑嗫嗬嗔嗦嗝嗄嗯嗥嗲嗳嗌嗍嗨嗵嗤辔嘞嘈嘌嘁嘤嘣嗾嘀嘧嘭噘嘹噗嘬噍噢噙噜噌噔嚆噤噱噫噻噼嚅嚓嚯囔囗囝囡囵囫囹囿圄圊圉圜帏帙帔帑帱帻帼"], ["e140", "酅酇酈酑酓酔酕酖酘酙酛酜酟酠酦酧酨酫酭酳酺酻酼醀", 4, "醆醈醊醎醏醓", 6, "醜", 5, "醤", 5, "醫醬醰醱醲醳醶醷醸醹醻"], ["e180", "醼", 10, "釈釋釐釒", 9, "針", 8, "帷幄幔幛幞幡岌屺岍岐岖岈岘岙岑岚岜岵岢岽岬岫岱岣峁岷峄峒峤峋峥崂崃崧崦崮崤崞崆崛嵘崾崴崽嵬嵛嵯嵝嵫嵋嵊嵩嵴嶂嶙嶝豳嶷巅彳彷徂徇徉後徕徙徜徨徭徵徼衢彡犭犰犴犷犸狃狁狎狍狒狨狯狩狲狴狷猁狳猃狺"], ["e240", "釦", 62], ["e280", "鈥", 32, "狻猗猓猡猊猞猝猕猢猹猥猬猸猱獐獍獗獠獬獯獾舛夥飧夤夂饣饧", 5, "饴饷饽馀馄馇馊馍馐馑馓馔馕庀庑庋庖庥庠庹庵庾庳赓廒廑廛廨廪膺忄忉忖忏怃忮怄忡忤忾怅怆忪忭忸怙怵怦怛怏怍怩怫怊怿怡恸恹恻恺恂"], ["e340", "鉆", 45, "鉵", 16], ["e380", "銆", 7, "銏", 24, "恪恽悖悚悭悝悃悒悌悛惬悻悱惝惘惆惚悴愠愦愕愣惴愀愎愫慊慵憬憔憧憷懔懵忝隳闩闫闱闳闵闶闼闾阃阄阆阈阊阋阌阍阏阒阕阖阗阙阚丬爿戕氵汔汜汊沣沅沐沔沌汨汩汴汶沆沩泐泔沭泷泸泱泗沲泠泖泺泫泮沱泓泯泾"], ["e440", "銨", 5, "銯", 24, "鋉", 31], ["e480", "鋩", 32, "洹洧洌浃浈洇洄洙洎洫浍洮洵洚浏浒浔洳涑浯涞涠浞涓涔浜浠浼浣渚淇淅淞渎涿淠渑淦淝淙渖涫渌涮渫湮湎湫溲湟溆湓湔渲渥湄滟溱溘滠漭滢溥溧溽溻溷滗溴滏溏滂溟潢潆潇漤漕滹漯漶潋潴漪漉漩澉澍澌潸潲潼潺濑"], ["e540", "錊", 51, "錿", 10], ["e580", "鍊", 31, "鍫濉澧澹澶濂濡濮濞濠濯瀚瀣瀛瀹瀵灏灞宀宄宕宓宥宸甯骞搴寤寮褰寰蹇謇辶迓迕迥迮迤迩迦迳迨逅逄逋逦逑逍逖逡逵逶逭逯遄遑遒遐遨遘遢遛暹遴遽邂邈邃邋彐彗彖彘尻咫屐屙孱屣屦羼弪弩弭艴弼鬻屮妁妃妍妩妪妣"], ["e640", "鍬", 34, "鎐", 27], ["e680", "鎬", 29, "鏋鏌鏍妗姊妫妞妤姒妲妯姗妾娅娆姝娈姣姘姹娌娉娲娴娑娣娓婀婧婊婕娼婢婵胬媪媛婷婺媾嫫媲嫒嫔媸嫠嫣嫱嫖嫦嫘嫜嬉嬗嬖嬲嬷孀尕尜孚孥孳孑孓孢驵驷驸驺驿驽骀骁骅骈骊骐骒骓骖骘骛骜骝骟骠骢骣骥骧纟纡纣纥纨纩"], ["e740", "鏎", 7, "鏗", 54], ["e780", "鐎", 32, "纭纰纾绀绁绂绉绋绌绐绔绗绛绠绡绨绫绮绯绱绲缍绶绺绻绾缁缂缃缇缈缋缌缏缑缒缗缙缜缛缟缡", 6, "缪缫缬缭缯", 4, "缵幺畿巛甾邕玎玑玮玢玟珏珂珑玷玳珀珉珈珥珙顼琊珩珧珞玺珲琏琪瑛琦琥琨琰琮琬"], ["e840", "鐯", 14, "鐿", 43, "鑬鑭鑮鑯"], ["e880", "鑰", 20, "钑钖钘铇铏铓铔铚铦铻锜锠琛琚瑁瑜瑗瑕瑙瑷瑭瑾璜璎璀璁璇璋璞璨璩璐璧瓒璺韪韫韬杌杓杞杈杩枥枇杪杳枘枧杵枨枞枭枋杷杼柰栉柘栊柩枰栌柙枵柚枳柝栀柃枸柢栎柁柽栲栳桠桡桎桢桄桤梃栝桕桦桁桧桀栾桊桉栩梵梏桴桷梓桫棂楮棼椟椠棹"], ["e940", "锧锳锽镃镈镋镕镚镠镮镴镵長", 7, "門", 42], ["e980", "閫", 32, "椤棰椋椁楗棣椐楱椹楠楂楝榄楫榀榘楸椴槌榇榈槎榉楦楣楹榛榧榻榫榭槔榱槁槊槟榕槠榍槿樯槭樗樘橥槲橄樾檠橐橛樵檎橹樽樨橘橼檑檐檩檗檫猷獒殁殂殇殄殒殓殍殚殛殡殪轫轭轱轲轳轵轶轸轷轹轺轼轾辁辂辄辇辋"], ["ea40", "闌", 27, "闬闿阇阓阘阛阞阠阣", 6, "阫阬阭阯阰阷阸阹阺阾陁陃陊陎陏陑陒陓陖陗"], ["ea80", "陘陙陚陜陝陞陠陣陥陦陫陭", 4, "陳陸", 12, "隇隉隊辍辎辏辘辚軎戋戗戛戟戢戡戥戤戬臧瓯瓴瓿甏甑甓攴旮旯旰昊昙杲昃昕昀炅曷昝昴昱昶昵耆晟晔晁晏晖晡晗晷暄暌暧暝暾曛曜曦曩贲贳贶贻贽赀赅赆赈赉赇赍赕赙觇觊觋觌觎觏觐觑牮犟牝牦牯牾牿犄犋犍犏犒挈挲掰"], ["eb40", "隌階隑隒隓隕隖隚際隝", 9, "隨", 7, "隱隲隴隵隷隸隺隻隿雂雃雈雊雋雐雑雓雔雖", 9, "雡", 6, "雫"], ["eb80", "雬雭雮雰雱雲雴雵雸雺電雼雽雿霂霃霅霊霋霌霐霑霒霔霕霗", 4, "霝霟霠搿擘耄毪毳毽毵毹氅氇氆氍氕氘氙氚氡氩氤氪氲攵敕敫牍牒牖爰虢刖肟肜肓肼朊肽肱肫肭肴肷胧胨胩胪胛胂胄胙胍胗朐胝胫胱胴胭脍脎胲胼朕脒豚脶脞脬脘脲腈腌腓腴腙腚腱腠腩腼腽腭腧塍媵膈膂膑滕膣膪臌朦臊膻"], ["ec40", "霡", 8, "霫霬霮霯霱霳", 4, "霺霻霼霽霿", 18, "靔靕靗靘靚靜靝靟靣靤靦靧靨靪", 7], ["ec80", "靲靵靷", 4, "靽", 7, "鞆", 4, "鞌鞎鞏鞐鞓鞕鞖鞗鞙", 4, "臁膦欤欷欹歃歆歙飑飒飓飕飙飚殳彀毂觳斐齑斓於旆旄旃旌旎旒旖炀炜炖炝炻烀炷炫炱烨烊焐焓焖焯焱煳煜煨煅煲煊煸煺熘熳熵熨熠燠燔燧燹爝爨灬焘煦熹戾戽扃扈扉礻祀祆祉祛祜祓祚祢祗祠祯祧祺禅禊禚禧禳忑忐"], ["ed40", "鞞鞟鞡鞢鞤", 6, "鞬鞮鞰鞱鞳鞵", 46], ["ed80", "韤韥韨韮", 4, "韴韷", 23, "怼恝恚恧恁恙恣悫愆愍慝憩憝懋懑戆肀聿沓泶淼矶矸砀砉砗砘砑斫砭砜砝砹砺砻砟砼砥砬砣砩硎硭硖硗砦硐硇硌硪碛碓碚碇碜碡碣碲碹碥磔磙磉磬磲礅磴礓礤礞礴龛黹黻黼盱眄眍盹眇眈眚眢眙眭眦眵眸睐睑睇睃睚睨"], ["ee40", "頏", 62], ["ee80", "顎", 32, "睢睥睿瞍睽瞀瞌瞑瞟瞠瞰瞵瞽町畀畎畋畈畛畲畹疃罘罡罟詈罨罴罱罹羁罾盍盥蠲钅钆钇钋钊钌钍钏钐钔钗钕钚钛钜钣钤钫钪钭钬钯钰钲钴钶", 4, "钼钽钿铄铈", 6, "铐铑铒铕铖铗铙铘铛铞铟铠铢铤铥铧铨铪"], ["ef40", "顯", 5, "颋颎颒颕颙颣風", 37, "飏飐飔飖飗飛飜飝飠", 4], ["ef80", "飥飦飩", 30, "铩铫铮铯铳铴铵铷铹铼铽铿锃锂锆锇锉锊锍锎锏锒", 4, "锘锛锝锞锟锢锪锫锩锬锱锲锴锶锷锸锼锾锿镂锵镄镅镆镉镌镎镏镒镓镔镖镗镘镙镛镞镟镝镡镢镤", 8, "镯镱镲镳锺矧矬雉秕秭秣秫稆嵇稃稂稞稔"], ["f040", "餈", 4, "餎餏餑", 28, "餯", 26], ["f080", "饊", 9, "饖", 12, "饤饦饳饸饹饻饾馂馃馉稹稷穑黏馥穰皈皎皓皙皤瓞瓠甬鸠鸢鸨", 4, "鸲鸱鸶鸸鸷鸹鸺鸾鹁鹂鹄鹆鹇鹈鹉鹋鹌鹎鹑鹕鹗鹚鹛鹜鹞鹣鹦", 6, "鹱鹭鹳疒疔疖疠疝疬疣疳疴疸痄疱疰痃痂痖痍痣痨痦痤痫痧瘃痱痼痿瘐瘀瘅瘌瘗瘊瘥瘘瘕瘙"], ["f140", "馌馎馚", 10, "馦馧馩", 47], ["f180", "駙", 32, "瘛瘼瘢瘠癀瘭瘰瘿瘵癃瘾瘳癍癞癔癜癖癫癯翊竦穸穹窀窆窈窕窦窠窬窨窭窳衤衩衲衽衿袂袢裆袷袼裉裢裎裣裥裱褚裼裨裾裰褡褙褓褛褊褴褫褶襁襦襻疋胥皲皴矜耒耔耖耜耠耢耥耦耧耩耨耱耋耵聃聆聍聒聩聱覃顸颀颃"], ["f240", "駺", 62], ["f280", "騹", 32, "颉颌颍颏颔颚颛颞颟颡颢颥颦虍虔虬虮虿虺虼虻蚨蚍蚋蚬蚝蚧蚣蚪蚓蚩蚶蛄蚵蛎蚰蚺蚱蚯蛉蛏蚴蛩蛱蛲蛭蛳蛐蜓蛞蛴蛟蛘蛑蜃蜇蛸蜈蜊蜍蜉蜣蜻蜞蜥蜮蜚蜾蝈蜴蜱蜩蜷蜿螂蜢蝽蝾蝻蝠蝰蝌蝮螋蝓蝣蝼蝤蝙蝥螓螯螨蟒"], ["f340", "驚", 17, "驲骃骉骍骎骔骕骙骦骩", 6, "骲骳骴骵骹骻骽骾骿髃髄髆", 4, "髍髎髏髐髒體髕髖髗髙髚髛髜"], ["f380", "髝髞髠髢髣髤髥髧髨髩髪髬髮髰", 8, "髺髼", 6, "鬄鬅鬆蟆螈螅螭螗螃螫蟥螬螵螳蟋蟓螽蟑蟀蟊蟛蟪蟠蟮蠖蠓蟾蠊蠛蠡蠹蠼缶罂罄罅舐竺竽笈笃笄笕笊笫笏筇笸笪笙笮笱笠笥笤笳笾笞筘筚筅筵筌筝筠筮筻筢筲筱箐箦箧箸箬箝箨箅箪箜箢箫箴篑篁篌篝篚篥篦篪簌篾篼簏簖簋"], ["f440", "鬇鬉", 5, "鬐鬑鬒鬔", 10, "鬠鬡鬢鬤", 10, "鬰鬱鬳", 7, "鬽鬾鬿魀魆魊魋魌魎魐魒魓魕", 5], ["f480", "魛", 32, "簟簪簦簸籁籀臾舁舂舄臬衄舡舢舣舭舯舨舫舸舻舳舴舾艄艉艋艏艚艟艨衾袅袈裘裟襞羝羟羧羯羰羲籼敉粑粝粜粞粢粲粼粽糁糇糌糍糈糅糗糨艮暨羿翎翕翥翡翦翩翮翳糸絷綦綮繇纛麸麴赳趄趔趑趱赧赭豇豉酊酐酎酏酤"], ["f540", "魼", 62], ["f580", "鮻", 32, "酢酡酰酩酯酽酾酲酴酹醌醅醐醍醑醢醣醪醭醮醯醵醴醺豕鹾趸跫踅蹙蹩趵趿趼趺跄跖跗跚跞跎跏跛跆跬跷跸跣跹跻跤踉跽踔踝踟踬踮踣踯踺蹀踹踵踽踱蹉蹁蹂蹑蹒蹊蹰蹶蹼蹯蹴躅躏躔躐躜躞豸貂貊貅貘貔斛觖觞觚觜"], ["f640", "鯜", 62], ["f680", "鰛", 32, "觥觫觯訾謦靓雩雳雯霆霁霈霏霎霪霭霰霾龀龃龅", 5, "龌黾鼋鼍隹隼隽雎雒瞿雠銎銮鋈錾鍪鏊鎏鐾鑫鱿鲂鲅鲆鲇鲈稣鲋鲎鲐鲑鲒鲔鲕鲚鲛鲞", 5, "鲥", 4, "鲫鲭鲮鲰", 7, "鲺鲻鲼鲽鳄鳅鳆鳇鳊鳋"], ["f740", "鰼", 62], ["f780", "鱻鱽鱾鲀鲃鲄鲉鲊鲌鲏鲓鲖鲗鲘鲙鲝鲪鲬鲯鲹鲾", 4, "鳈鳉鳑鳒鳚鳛鳠鳡鳌", 4, "鳓鳔鳕鳗鳘鳙鳜鳝鳟鳢靼鞅鞑鞒鞔鞯鞫鞣鞲鞴骱骰骷鹘骶骺骼髁髀髅髂髋髌髑魅魃魇魉魈魍魑飨餍餮饕饔髟髡髦髯髫髻髭髹鬈鬏鬓鬟鬣麽麾縻麂麇麈麋麒鏖麝麟黛黜黝黠黟黢黩黧黥黪黯鼢鼬鼯鼹鼷鼽鼾齄"], ["f840", "鳣", 62], ["f880", "鴢", 32], ["f940", "鵃", 62], ["f980", "鶂", 32], ["fa40", "鶣", 62], ["fa80", "鷢", 32], ["fb40", "鸃", 27, "鸤鸧鸮鸰鸴鸻鸼鹀鹍鹐鹒鹓鹔鹖鹙鹝鹟鹠鹡鹢鹥鹮鹯鹲鹴", 9, "麀"], ["fb80", "麁麃麄麅麆麉麊麌", 5, "麔", 8, "麞麠", 5, "麧麨麩麪"], ["fc40", "麫", 8, "麵麶麷麹麺麼麿", 4, "黅黆黇黈黊黋黌黐黒黓黕黖黗黙黚點黡黣黤黦黨黫黬黭黮黰", 8, "黺黽黿", 6], ["fc80", "鼆", 4, "鼌鼏鼑鼒鼔鼕鼖鼘鼚", 5, "鼡鼣", 8, "鼭鼮鼰鼱"], ["fd40", "鼲", 4, "鼸鼺鼼鼿", 4, "齅", 10, "齒", 38], ["fd80", "齹", 5, "龁龂龍", 11, "龜龝龞龡", 4, "郎凉秊裏隣"], ["fe40", "兀嗀﨎﨏﨑﨓﨔礼﨟蘒﨡﨣﨤﨧﨨﨩"]]; + +var cp936$1 = Object.freeze({ + default: cp936 +}); + +var gbkAdded = [["a140", "", 62], ["a180", "", 32], ["a240", "", 62], ["a280", "", 32], ["a2ab", "", 5], ["a2e3", "€"], ["a2ef", ""], ["a2fd", ""], ["a340", "", 62], ["a380", "", 31, " "], ["a440", "", 62], ["a480", "", 32], ["a4f4", "", 10], ["a540", "", 62], ["a580", "", 32], ["a5f7", "", 7], ["a640", "", 62], ["a680", "", 32], ["a6b9", "", 7], ["a6d9", "", 6], ["a6ec", ""], ["a6f3", ""], ["a6f6", "", 8], ["a740", "", 62], ["a780", "", 32], ["a7c2", "", 14], ["a7f2", "", 12], ["a896", "", 10], ["a8bc", ""], ["a8bf", "ǹ"], ["a8c1", ""], ["a8ea", "", 20], ["a958", ""], ["a95b", ""], ["a95d", ""], ["a989", "〾⿰", 11], ["a997", "", 12], ["a9f0", "", 14], ["aaa1", "", 93], ["aba1", "", 93], ["aca1", "", 93], ["ada1", "", 93], ["aea1", "", 93], ["afa1", "", 93], ["d7fa", "", 4], ["f8a1", "", 93], ["f9a1", "", 93], ["faa1", "", 93], ["fba1", "", 93], ["fca1", "", 93], ["fda1", "", 93], ["fe50", "⺁⺄㑳㑇⺈⺋㖞㘚㘎⺌⺗㥮㤘㧏㧟㩳㧐㭎㱮㳠⺧⺪䁖䅟⺮䌷⺳⺶⺷䎱䎬⺻䏝䓖䙡䙌"], ["fe80", "䜣䜩䝼䞍⻊䥇䥺䥽䦂䦃䦅䦆䦟䦛䦷䦶䲣䲟䲠䲡䱷䲢䴓", 6, "䶮", 93]]; + +var gbkAdded$1 = Object.freeze({ + default: gbkAdded +}); + +var uChars = [128, 165, 169, 178, 184, 216, 226, 235, 238, 244, 248, 251, 253, 258, 276, 284, 300, 325, 329, 334, 364, 463, 465, 467, 469, 471, 473, 475, 477, 506, 594, 610, 712, 716, 730, 930, 938, 962, 970, 1026, 1104, 1106, 8209, 8215, 8218, 8222, 8231, 8241, 8244, 8246, 8252, 8365, 8452, 8454, 8458, 8471, 8482, 8556, 8570, 8596, 8602, 8713, 8720, 8722, 8726, 8731, 8737, 8740, 8742, 8748, 8751, 8760, 8766, 8777, 8781, 8787, 8802, 8808, 8816, 8854, 8858, 8870, 8896, 8979, 9322, 9372, 9548, 9588, 9616, 9622, 9634, 9652, 9662, 9672, 9676, 9680, 9702, 9735, 9738, 9793, 9795, 11906, 11909, 11913, 11917, 11928, 11944, 11947, 11951, 11956, 11960, 11964, 11979, 12284, 12292, 12312, 12319, 12330, 12351, 12436, 12447, 12535, 12543, 12586, 12842, 12850, 12964, 13200, 13215, 13218, 13253, 13263, 13267, 13270, 13384, 13428, 13727, 13839, 13851, 14617, 14703, 14801, 14816, 14964, 15183, 15471, 15585, 16471, 16736, 17208, 17325, 17330, 17374, 17623, 17997, 18018, 18212, 18218, 18301, 18318, 18760, 18811, 18814, 18820, 18823, 18844, 18848, 18872, 19576, 19620, 19738, 19887, 40870, 59244, 59336, 59367, 59413, 59417, 59423, 59431, 59437, 59443, 59452, 59460, 59478, 59493, 63789, 63866, 63894, 63976, 63986, 64016, 64018, 64021, 64025, 64034, 64037, 64042, 65074, 65093, 65107, 65112, 65127, 65132, 65375, 65510, 65536]; +var gbChars = [0, 36, 38, 45, 50, 81, 89, 95, 96, 100, 103, 104, 105, 109, 126, 133, 148, 172, 175, 179, 208, 306, 307, 308, 309, 310, 311, 312, 313, 341, 428, 443, 544, 545, 558, 741, 742, 749, 750, 805, 819, 820, 7922, 7924, 7925, 7927, 7934, 7943, 7944, 7945, 7950, 8062, 8148, 8149, 8152, 8164, 8174, 8236, 8240, 8262, 8264, 8374, 8380, 8381, 8384, 8388, 8390, 8392, 8393, 8394, 8396, 8401, 8406, 8416, 8419, 8424, 8437, 8439, 8445, 8482, 8485, 8496, 8521, 8603, 8936, 8946, 9046, 9050, 9063, 9066, 9076, 9092, 9100, 9108, 9111, 9113, 9131, 9162, 9164, 9218, 9219, 11329, 11331, 11334, 11336, 11346, 11361, 11363, 11366, 11370, 11372, 11375, 11389, 11682, 11686, 11687, 11692, 11694, 11714, 11716, 11723, 11725, 11730, 11736, 11982, 11989, 12102, 12336, 12348, 12350, 12384, 12393, 12395, 12397, 12510, 12553, 12851, 12962, 12973, 13738, 13823, 13919, 13933, 14080, 14298, 14585, 14698, 15583, 15847, 16318, 16434, 16438, 16481, 16729, 17102, 17122, 17315, 17320, 17402, 17418, 17859, 17909, 17911, 17915, 17916, 17936, 17939, 17961, 18664, 18703, 18814, 18962, 19043, 33469, 33470, 33471, 33484, 33485, 33490, 33497, 33501, 33505, 33513, 33520, 33536, 33550, 37845, 37921, 37948, 38029, 38038, 38064, 38065, 38066, 38069, 38075, 38076, 38078, 39108, 39109, 39113, 39114, 39115, 39116, 39265, 39394, 189000]; +var gb18030Ranges = { + uChars: uChars, + gbChars: gbChars +}; + +var gb18030Ranges$1 = Object.freeze({ + uChars: uChars, + gbChars: gbChars, + default: gb18030Ranges +}); + +var cp949 = [["0", "\0", 127], ["8141", "갂갃갅갆갋", 4, "갘갞갟갡갢갣갥", 6, "갮갲갳갴"], ["8161", "갵갶갷갺갻갽갾갿걁", 9, "걌걎", 5, "걕"], ["8181", "걖걗걙걚걛걝", 18, "걲걳걵걶걹걻", 4, "겂겇겈겍겎겏겑겒겓겕", 6, "겞겢", 5, "겫겭겮겱", 6, "겺겾겿곀곂곃곅곆곇곉곊곋곍", 7, "곖곘", 7, "곢곣곥곦곩곫곭곮곲곴곷", 4, "곾곿괁괂괃괅괇", 4, "괎괐괒괓"], ["8241", "괔괕괖괗괙괚괛괝괞괟괡", 7, "괪괫괮", 5], ["8261", "괶괷괹괺괻괽", 6, "굆굈굊", 5, "굑굒굓굕굖굗"], ["8281", "굙", 7, "굢굤", 7, "굮굯굱굲굷굸굹굺굾궀궃", 4, "궊궋궍궎궏궑", 10, "궞", 5, "궥", 17, "궸", 7, "귂귃귅귆귇귉", 6, "귒귔", 7, "귝귞귟귡귢귣귥", 18], ["8341", "귺귻귽귾긂", 5, "긊긌긎", 5, "긕", 7], ["8361", "긝", 18, "긲긳긵긶긹긻긼"], ["8381", "긽긾긿깂깄깇깈깉깋깏깑깒깓깕깗", 4, "깞깢깣깤깦깧깪깫깭깮깯깱", 6, "깺깾", 5, "꺆", 5, "꺍", 46, "꺿껁껂껃껅", 6, "껎껒", 5, "껚껛껝", 8], ["8441", "껦껧껩껪껬껮", 5, "껵껶껷껹껺껻껽", 8], ["8461", "꼆꼉꼊꼋꼌꼎꼏꼑", 18], ["8481", "꼤", 7, "꼮꼯꼱꼳꼵", 6, "꼾꽀꽄꽅꽆꽇꽊", 5, "꽑", 10, "꽞", 5, "꽦", 18, "꽺", 5, "꾁꾂꾃꾅꾆꾇꾉", 6, "꾒꾓꾔꾖", 5, "꾝", 26, "꾺꾻꾽꾾"], ["8541", "꾿꿁", 5, "꿊꿌꿏", 4, "꿕", 6, "꿝", 4], ["8561", "꿢", 5, "꿪", 5, "꿲꿳꿵꿶꿷꿹", 6, "뀂뀃"], ["8581", "뀅", 6, "뀍뀎뀏뀑뀒뀓뀕", 6, "뀞", 9, "뀩", 26, "끆끇끉끋끍끏끐끑끒끖끘끚끛끜끞", 29, "끾끿낁낂낃낅", 6, "낎낐낒", 5, "낛낝낞낣낤"], ["8641", "낥낦낧낪낰낲낶낷낹낺낻낽", 6, "냆냊", 5, "냒"], ["8661", "냓냕냖냗냙", 6, "냡냢냣냤냦", 10], ["8681", "냱", 22, "넊넍넎넏넑넔넕넖넗넚넞", 4, "넦넧넩넪넫넭", 6, "넶넺", 5, "녂녃녅녆녇녉", 6, "녒녓녖녗녙녚녛녝녞녟녡", 22, "녺녻녽녾녿놁놃", 4, "놊놌놎놏놐놑놕놖놗놙놚놛놝"], ["8741", "놞", 9, "놩", 15], ["8761", "놹", 18, "뇍뇎뇏뇑뇒뇓뇕"], ["8781", "뇖", 5, "뇞뇠", 7, "뇪뇫뇭뇮뇯뇱", 7, "뇺뇼뇾", 5, "눆눇눉눊눍", 6, "눖눘눚", 5, "눡", 18, "눵", 6, "눽", 26, "뉙뉚뉛뉝뉞뉟뉡", 6, "뉪", 4], ["8841", "뉯", 4, "뉶", 5, "뉽", 6, "늆늇늈늊", 4], ["8861", "늏늒늓늕늖늗늛", 4, "늢늤늧늨늩늫늭늮늯늱늲늳늵늶늷"], ["8881", "늸", 15, "닊닋닍닎닏닑닓", 4, "닚닜닞닟닠닡닣닧닩닪닰닱닲닶닼닽닾댂댃댅댆댇댉", 6, "댒댖", 5, "댝", 54, "덗덙덚덝덠덡덢덣"], ["8941", "덦덨덪덬덭덯덲덳덵덶덷덹", 6, "뎂뎆", 5, "뎍"], ["8961", "뎎뎏뎑뎒뎓뎕", 10, "뎢", 5, "뎩뎪뎫뎭"], ["8981", "뎮", 21, "돆돇돉돊돍돏돑돒돓돖돘돚돜돞돟돡돢돣돥돦돧돩", 18, "돽", 18, "됑", 6, "됙됚됛됝됞됟됡", 6, "됪됬", 7, "됵", 15], ["8a41", "둅", 10, "둒둓둕둖둗둙", 6, "둢둤둦"], ["8a61", "둧", 4, "둭", 18, "뒁뒂"], ["8a81", "뒃", 4, "뒉", 19, "뒞", 5, "뒥뒦뒧뒩뒪뒫뒭", 7, "뒶뒸뒺", 5, "듁듂듃듅듆듇듉", 6, "듑듒듓듔듖", 5, "듞듟듡듢듥듧", 4, "듮듰듲", 5, "듹", 26, "딖딗딙딚딝"], ["8b41", "딞", 5, "딦딫", 4, "딲딳딵딶딷딹", 6, "땂땆"], ["8b61", "땇땈땉땊땎땏땑땒땓땕", 6, "땞땢", 8], ["8b81", "땫", 52, "떢떣떥떦떧떩떬떭떮떯떲떶", 4, "떾떿뗁뗂뗃뗅", 6, "뗎뗒", 5, "뗙", 18, "뗭", 18], ["8c41", "똀", 15, "똒똓똕똖똗똙", 4], ["8c61", "똞", 6, "똦", 5, "똭", 6, "똵", 5], ["8c81", "똻", 12, "뙉", 26, "뙥뙦뙧뙩", 50, "뚞뚟뚡뚢뚣뚥", 5, "뚭뚮뚯뚰뚲", 16], ["8d41", "뛃", 16, "뛕", 8], ["8d61", "뛞", 17, "뛱뛲뛳뛵뛶뛷뛹뛺"], ["8d81", "뛻", 4, "뜂뜃뜄뜆", 33, "뜪뜫뜭뜮뜱", 6, "뜺뜼", 7, "띅띆띇띉띊띋띍", 6, "띖", 9, "띡띢띣띥띦띧띩", 6, "띲띴띶", 5, "띾띿랁랂랃랅", 6, "랎랓랔랕랚랛랝랞"], ["8e41", "랟랡", 6, "랪랮", 5, "랶랷랹", 8], ["8e61", "럂", 4, "럈럊", 19], ["8e81", "럞", 13, "럮럯럱럲럳럵", 6, "럾렂", 4, "렊렋렍렎렏렑", 6, "렚렜렞", 5, "렦렧렩렪렫렭", 6, "렶렺", 5, "롁롂롃롅", 11, "롒롔", 7, "롞롟롡롢롣롥", 6, "롮롰롲", 5, "롹롺롻롽", 7], ["8f41", "뢅", 7, "뢎", 17], ["8f61", "뢠", 7, "뢩", 6, "뢱뢲뢳뢵뢶뢷뢹", 4], ["8f81", "뢾뢿룂룄룆", 5, "룍룎룏룑룒룓룕", 7, "룞룠룢", 5, "룪룫룭룮룯룱", 6, "룺룼룾", 5, "뤅", 18, "뤙", 6, "뤡", 26, "뤾뤿륁륂륃륅", 6, "륍륎륐륒", 5], ["9041", "륚륛륝륞륟륡", 6, "륪륬륮", 5, "륶륷륹륺륻륽"], ["9061", "륾", 5, "릆릈릋릌릏", 15], ["9081", "릟", 12, "릮릯릱릲릳릵", 6, "릾맀맂", 5, "맊맋맍맓", 4, "맚맜맟맠맢맦맧맩맪맫맭", 6, "맶맻", 4, "먂", 5, "먉", 11, "먖", 33, "먺먻먽먾먿멁멃멄멅멆"], ["9141", "멇멊멌멏멐멑멒멖멗멙멚멛멝", 6, "멦멪", 5], ["9161", "멲멳멵멶멷멹", 9, "몆몈몉몊몋몍", 5], ["9181", "몓", 20, "몪몭몮몯몱몳", 4, "몺몼몾", 5, "뫅뫆뫇뫉", 14, "뫚", 33, "뫽뫾뫿묁묂묃묅", 7, "묎묐묒", 5, "묙묚묛묝묞묟묡", 6], ["9241", "묨묪묬", 7, "묷묹묺묿", 4, "뭆뭈뭊뭋뭌뭎뭑뭒"], ["9261", "뭓뭕뭖뭗뭙", 7, "뭢뭤", 7, "뭭", 4], ["9281", "뭲", 21, "뮉뮊뮋뮍뮎뮏뮑", 18, "뮥뮦뮧뮩뮪뮫뮭", 6, "뮵뮶뮸", 7, "믁믂믃믅믆믇믉", 6, "믑믒믔", 35, "믺믻믽믾밁"], ["9341", "밃", 4, "밊밎밐밒밓밙밚밠밡밢밣밦밨밪밫밬밮밯밲밳밵"], ["9361", "밶밷밹", 6, "뱂뱆뱇뱈뱊뱋뱎뱏뱑", 8], ["9381", "뱚뱛뱜뱞", 37, "벆벇벉벊벍벏", 4, "벖벘벛", 4, "벢벣벥벦벩", 6, "벲벶", 5, "벾벿볁볂볃볅", 7, "볎볒볓볔볖볗볙볚볛볝", 22, "볷볹볺볻볽"], ["9441", "볾", 5, "봆봈봊", 5, "봑봒봓봕", 8], ["9461", "봞", 5, "봥", 6, "봭", 12], ["9481", "봺", 5, "뵁", 6, "뵊뵋뵍뵎뵏뵑", 6, "뵚", 9, "뵥뵦뵧뵩", 22, "붂붃붅붆붋", 4, "붒붔붖붗붘붛붝", 6, "붥", 10, "붱", 6, "붹", 24], ["9541", "뷒뷓뷖뷗뷙뷚뷛뷝", 11, "뷪", 5, "뷱"], ["9561", "뷲뷳뷵뷶뷷뷹", 6, "븁븂븄븆", 5, "븎븏븑븒븓"], ["9581", "븕", 6, "븞븠", 35, "빆빇빉빊빋빍빏", 4, "빖빘빜빝빞빟빢빣빥빦빧빩빫", 4, "빲빶", 4, "빾빿뺁뺂뺃뺅", 6, "뺎뺒", 5, "뺚", 13, "뺩", 14], ["9641", "뺸", 23, "뻒뻓"], ["9661", "뻕뻖뻙", 6, "뻡뻢뻦", 5, "뻭", 8], ["9681", "뻶", 10, "뼂", 5, "뼊", 13, "뼚뼞", 33, "뽂뽃뽅뽆뽇뽉", 6, "뽒뽓뽔뽖", 44], ["9741", "뾃", 16, "뾕", 8], ["9761", "뾞", 17, "뾱", 7], ["9781", "뾹", 11, "뿆", 5, "뿎뿏뿑뿒뿓뿕", 6, "뿝뿞뿠뿢", 89, "쀽쀾쀿"], ["9841", "쁀", 16, "쁒", 5, "쁙쁚쁛"], ["9861", "쁝쁞쁟쁡", 6, "쁪", 15], ["9881", "쁺", 21, "삒삓삕삖삗삙", 6, "삢삤삦", 5, "삮삱삲삷", 4, "삾샂샃샄샆샇샊샋샍샎샏샑", 6, "샚샞", 5, "샦샧샩샪샫샭", 6, "샶샸샺", 5, "섁섂섃섅섆섇섉", 6, "섑섒섓섔섖", 5, "섡섢섥섨섩섪섫섮"], ["9941", "섲섳섴섵섷섺섻섽섾섿셁", 6, "셊셎", 5, "셖셗"], ["9961", "셙셚셛셝", 6, "셦셪", 5, "셱셲셳셵셶셷셹셺셻"], ["9981", "셼", 8, "솆", 5, "솏솑솒솓솕솗", 4, "솞솠솢솣솤솦솧솪솫솭솮솯솱", 11, "솾", 5, "쇅쇆쇇쇉쇊쇋쇍", 6, "쇕쇖쇙", 6, "쇡쇢쇣쇥쇦쇧쇩", 6, "쇲쇴", 7, "쇾쇿숁숂숃숅", 6, "숎숐숒", 5, "숚숛숝숞숡숢숣"], ["9a41", "숤숥숦숧숪숬숮숰숳숵", 16], ["9a61", "쉆쉇쉉", 6, "쉒쉓쉕쉖쉗쉙", 6, "쉡쉢쉣쉤쉦"], ["9a81", "쉧", 4, "쉮쉯쉱쉲쉳쉵", 6, "쉾슀슂", 5, "슊", 5, "슑", 6, "슙슚슜슞", 5, "슦슧슩슪슫슮", 5, "슶슸슺", 33, "싞싟싡싢싥", 5, "싮싰싲싳싴싵싷싺싽싾싿쌁", 6, "쌊쌋쌎쌏"], ["9b41", "쌐쌑쌒쌖쌗쌙쌚쌛쌝", 6, "쌦쌧쌪", 8], ["9b61", "쌳", 17, "썆", 7], ["9b81", "썎", 25, "썪썫썭썮썯썱썳", 4, "썺썻썾", 5, "쎅쎆쎇쎉쎊쎋쎍", 50, "쏁", 22, "쏚"], ["9c41", "쏛쏝쏞쏡쏣", 4, "쏪쏫쏬쏮", 5, "쏶쏷쏹", 5], ["9c61", "쏿", 8, "쐉", 6, "쐑", 9], ["9c81", "쐛", 8, "쐥", 6, "쐭쐮쐯쐱쐲쐳쐵", 6, "쐾", 9, "쑉", 26, "쑦쑧쑩쑪쑫쑭", 6, "쑶쑷쑸쑺", 5, "쒁", 18, "쒕", 6, "쒝", 12], ["9d41", "쒪", 13, "쒹쒺쒻쒽", 8], ["9d61", "쓆", 25], ["9d81", "쓠", 8, "쓪", 5, "쓲쓳쓵쓶쓷쓹쓻쓼쓽쓾씂", 9, "씍씎씏씑씒씓씕", 6, "씝", 10, "씪씫씭씮씯씱", 6, "씺씼씾", 5, "앆앇앋앏앐앑앒앖앚앛앜앟앢앣앥앦앧앩", 6, "앲앶", 5, "앾앿얁얂얃얅얆얈얉얊얋얎얐얒얓얔"], ["9e41", "얖얙얚얛얝얞얟얡", 7, "얪", 9, "얶"], ["9e61", "얷얺얿", 4, "엋엍엏엒엓엕엖엗엙", 6, "엢엤엦엧"], ["9e81", "엨엩엪엫엯엱엲엳엵엸엹엺엻옂옃옄옉옊옋옍옎옏옑", 6, "옚옝", 6, "옦옧옩옪옫옯옱옲옶옸옺옼옽옾옿왂왃왅왆왇왉", 6, "왒왖", 5, "왞왟왡", 10, "왭왮왰왲", 5, "왺왻왽왾왿욁", 6, "욊욌욎", 5, "욖욗욙욚욛욝", 6, "욦"], ["9f41", "욨욪", 5, "욲욳욵욶욷욻", 4, "웂웄웆", 5, "웎"], ["9f61", "웏웑웒웓웕", 6, "웞웟웢", 5, "웪웫웭웮웯웱웲"], ["9f81", "웳", 4, "웺웻웼웾", 5, "윆윇윉윊윋윍", 6, "윖윘윚", 5, "윢윣윥윦윧윩", 6, "윲윴윶윸윹윺윻윾윿읁읂읃읅", 4, "읋읎읐읙읚읛읝읞읟읡", 6, "읩읪읬", 7, "읶읷읹읺읻읿잀잁잂잆잋잌잍잏잒잓잕잙잛", 4, "잢잧", 4, "잮잯잱잲잳잵잶잷"], ["a041", "잸잹잺잻잾쟂", 5, "쟊쟋쟍쟏쟑", 6, "쟙쟚쟛쟜"], ["a061", "쟞", 5, "쟥쟦쟧쟩쟪쟫쟭", 13], ["a081", "쟻", 4, "젂젃젅젆젇젉젋", 4, "젒젔젗", 4, "젞젟젡젢젣젥", 6, "젮젰젲", 5, "젹젺젻젽젾젿졁", 6, "졊졋졎", 5, "졕", 26, "졲졳졵졶졷졹졻", 4, "좂좄좈좉좊좎", 5, "좕", 7, "좞좠좢좣좤"], ["a141", "좥좦좧좩", 18, "좾좿죀죁"], ["a161", "죂죃죅죆죇죉죊죋죍", 6, "죖죘죚", 5, "죢죣죥"], ["a181", "죦", 14, "죶", 5, "죾죿줁줂줃줇", 4, "줎 、。·‥…¨〃­―∥\∼‘’“”〔〕〈", 9, "±×÷≠≤≥∞∴°′″℃Å¢£¥♂♀∠⊥⌒∂∇≡≒§※☆★○●◎◇◆□■△▲▽▼→←↑↓↔〓≪≫√∽∝∵∫∬∈∋⊆⊇⊂⊃∪∩∧∨¬"], ["a241", "줐줒", 5, "줙", 18], ["a261", "줭", 6, "줵", 18], ["a281", "쥈", 7, "쥒쥓쥕쥖쥗쥙", 6, "쥢쥤", 7, "쥭쥮쥯⇒⇔∀∃´~ˇ˘˝˚˙¸˛¡¿ː∮∑∏¤℉‰◁◀▷▶♤♠♡♥♧♣⊙◈▣◐◑▒▤▥▨▧▦▩♨☏☎☜☞¶†‡↕↗↙↖↘♭♩♪♬㉿㈜№㏇™㏂㏘℡€®"], ["a341", "쥱쥲쥳쥵", 6, "쥽", 10, "즊즋즍즎즏"], ["a361", "즑", 6, "즚즜즞", 16], ["a381", "즯", 16, "짂짃짅짆짉짋", 4, "짒짔짗짘짛!", 58, "₩]", 32, " ̄"], ["a441", "짞짟짡짣짥짦짨짩짪짫짮짲", 5, "짺짻짽짾짿쨁쨂쨃쨄"], ["a461", "쨅쨆쨇쨊쨎", 5, "쨕쨖쨗쨙", 12], ["a481", "쨦쨧쨨쨪", 28, "ㄱ", 93], ["a541", "쩇", 4, "쩎쩏쩑쩒쩓쩕", 6, "쩞쩢", 5, "쩩쩪"], ["a561", "쩫", 17, "쩾", 5, "쪅쪆"], ["a581", "쪇", 16, "쪙", 14, "ⅰ", 9], ["a5b0", "Ⅰ", 9], ["a5c1", "Α", 16, "Σ", 6], ["a5e1", "α", 16, "σ", 6], ["a641", "쪨", 19, "쪾쪿쫁쫂쫃쫅"], ["a661", "쫆", 5, "쫎쫐쫒쫔쫕쫖쫗쫚", 5, "쫡", 6], ["a681", "쫨쫩쫪쫫쫭", 6, "쫵", 18, "쬉쬊─│┌┐┘└├┬┤┴┼━┃┏┓┛┗┣┳┫┻╋┠┯┨┷┿┝┰┥┸╂┒┑┚┙┖┕┎┍┞┟┡┢┦┧┩┪┭┮┱┲┵┶┹┺┽┾╀╁╃", 7], ["a741", "쬋", 4, "쬑쬒쬓쬕쬖쬗쬙", 6, "쬢", 7], ["a761", "쬪", 22, "쭂쭃쭄"], ["a781", "쭅쭆쭇쭊쭋쭍쭎쭏쭑", 6, "쭚쭛쭜쭞", 5, "쭥", 7, "㎕㎖㎗ℓ㎘㏄㎣㎤㎥㎦㎙", 9, "㏊㎍㎎㎏㏏㎈㎉㏈㎧㎨㎰", 9, "㎀", 4, "㎺", 5, "㎐", 4, "Ω㏀㏁㎊㎋㎌㏖㏅㎭㎮㎯㏛㎩㎪㎫㎬㏝㏐㏓㏃㏉㏜㏆"], ["a841", "쭭", 10, "쭺", 14], ["a861", "쮉", 18, "쮝", 6], ["a881", "쮤", 19, "쮹", 11, "ÆЪĦ"], ["a8a6", "IJ"], ["a8a8", "ĿŁØŒºÞŦŊ"], ["a8b1", "㉠", 27, "ⓐ", 25, "①", 14, "½⅓⅔¼¾⅛⅜⅝⅞"], ["a941", "쯅", 14, "쯕", 10], ["a961", "쯠쯡쯢쯣쯥쯦쯨쯪", 18], ["a981", "쯽", 14, "찎찏찑찒찓찕", 6, "찞찟찠찣찤æđðħıijĸŀłøœßþŧŋʼn㈀", 27, "⒜", 25, "⑴", 14, "¹²³⁴ⁿ₁₂₃₄"], ["aa41", "찥찦찪찫찭찯찱", 6, "찺찿", 4, "챆챇챉챊챋챍챎"], ["aa61", "챏", 4, "챖챚", 5, "챡챢챣챥챧챩", 6, "챱챲"], ["aa81", "챳챴챶", 29, "ぁ", 82], ["ab41", "첔첕첖첗첚첛첝첞첟첡", 6, "첪첮", 5, "첶첷첹"], ["ab61", "첺첻첽", 6, "쳆쳈쳊", 5, "쳑쳒쳓쳕", 5], ["ab81", "쳛", 8, "쳥", 6, "쳭쳮쳯쳱", 12, "ァ", 85], ["ac41", "쳾쳿촀촂", 5, "촊촋촍촎촏촑", 6, "촚촜촞촟촠"], ["ac61", "촡촢촣촥촦촧촩촪촫촭", 11, "촺", 4], ["ac81", "촿", 28, "쵝쵞쵟А", 5, "ЁЖ", 25], ["acd1", "а", 5, "ёж", 25], ["ad41", "쵡쵢쵣쵥", 6, "쵮쵰쵲", 5, "쵹", 7], ["ad61", "춁", 6, "춉", 10, "춖춗춙춚춛춝춞춟"], ["ad81", "춠춡춢춣춦춨춪", 5, "춱", 18, "췅"], ["ae41", "췆", 5, "췍췎췏췑", 16], ["ae61", "췢", 5, "췩췪췫췭췮췯췱", 6, "췺췼췾", 4], ["ae81", "츃츅츆츇츉츊츋츍", 6, "츕츖츗츘츚", 5, "츢츣츥츦츧츩츪츫"], ["af41", "츬츭츮츯츲츴츶", 19], ["af61", "칊", 13, "칚칛칝칞칢", 5, "칪칬"], ["af81", "칮", 5, "칶칷칹칺칻칽", 6, "캆캈캊", 5, "캒캓캕캖캗캙"], ["b041", "캚", 5, "캢캦", 5, "캮", 12], ["b061", "캻", 5, "컂", 19], ["b081", "컖", 13, "컦컧컩컪컭", 6, "컶컺", 5, "가각간갇갈갉갊감", 7, "같", 4, "갠갤갬갭갯갰갱갸갹갼걀걋걍걔걘걜거걱건걷걸걺검겁것겄겅겆겉겊겋게겐겔겜겝겟겠겡겨격겪견겯결겸겹겻겼경곁계곈곌곕곗고곡곤곧골곪곬곯곰곱곳공곶과곽관괄괆"], ["b141", "켂켃켅켆켇켉", 6, "켒켔켖", 5, "켝켞켟켡켢켣"], ["b161", "켥", 6, "켮켲", 5, "켹", 11], ["b181", "콅", 14, "콖콗콙콚콛콝", 6, "콦콨콪콫콬괌괍괏광괘괜괠괩괬괭괴괵괸괼굄굅굇굉교굔굘굡굣구국군굳굴굵굶굻굼굽굿궁궂궈궉권궐궜궝궤궷귀귁귄귈귐귑귓규균귤그극근귿글긁금급긋긍긔기긱긴긷길긺김깁깃깅깆깊까깍깎깐깔깖깜깝깟깠깡깥깨깩깬깰깸"], ["b241", "콭콮콯콲콳콵콶콷콹", 6, "쾁쾂쾃쾄쾆", 5, "쾍"], ["b261", "쾎", 18, "쾢", 5, "쾩"], ["b281", "쾪", 5, "쾱", 18, "쿅", 6, "깹깻깼깽꺄꺅꺌꺼꺽꺾껀껄껌껍껏껐껑께껙껜껨껫껭껴껸껼꼇꼈꼍꼐꼬꼭꼰꼲꼴꼼꼽꼿꽁꽂꽃꽈꽉꽐꽜꽝꽤꽥꽹꾀꾄꾈꾐꾑꾕꾜꾸꾹꾼꿀꿇꿈꿉꿋꿍꿎꿔꿜꿨꿩꿰꿱꿴꿸뀀뀁뀄뀌뀐뀔뀜뀝뀨끄끅끈끊끌끎끓끔끕끗끙"], ["b341", "쿌", 19, "쿢쿣쿥쿦쿧쿩"], ["b361", "쿪", 5, "쿲쿴쿶", 5, "쿽쿾쿿퀁퀂퀃퀅", 5], ["b381", "퀋", 5, "퀒", 5, "퀙", 19, "끝끼끽낀낄낌낍낏낑나낙낚난낟날낡낢남납낫", 4, "낱낳내낵낸낼냄냅냇냈냉냐냑냔냘냠냥너넉넋넌널넒넓넘넙넛넜넝넣네넥넨넬넴넵넷넸넹녀녁년녈념녑녔녕녘녜녠노녹논놀놂놈놉놋농높놓놔놘놜놨뇌뇐뇔뇜뇝"], ["b441", "퀮", 5, "퀶퀷퀹퀺퀻퀽", 6, "큆큈큊", 5], ["b461", "큑큒큓큕큖큗큙", 6, "큡", 10, "큮큯"], ["b481", "큱큲큳큵", 6, "큾큿킀킂", 18, "뇟뇨뇩뇬뇰뇹뇻뇽누눅눈눋눌눔눕눗눙눠눴눼뉘뉜뉠뉨뉩뉴뉵뉼늄늅늉느늑는늘늙늚늠늡늣능늦늪늬늰늴니닉닌닐닒님닙닛닝닢다닥닦단닫", 4, "닳담답닷", 4, "닿대댁댄댈댐댑댓댔댕댜더덕덖던덛덜덞덟덤덥"], ["b541", "킕", 14, "킦킧킩킪킫킭", 5], ["b561", "킳킶킸킺", 5, "탂탃탅탆탇탊", 5, "탒탖", 4], ["b581", "탛탞탟탡탢탣탥", 6, "탮탲", 5, "탹", 11, "덧덩덫덮데덱덴델뎀뎁뎃뎄뎅뎌뎐뎔뎠뎡뎨뎬도독돈돋돌돎돐돔돕돗동돛돝돠돤돨돼됐되된될됨됩됫됴두둑둔둘둠둡둣둥둬뒀뒈뒝뒤뒨뒬뒵뒷뒹듀듄듈듐듕드득든듣들듦듬듭듯등듸디딕딘딛딜딤딥딧딨딩딪따딱딴딸"], ["b641", "턅", 7, "턎", 17], ["b661", "턠", 15, "턲턳턵턶턷턹턻턼턽턾"], ["b681", "턿텂텆", 5, "텎텏텑텒텓텕", 6, "텞텠텢", 5, "텩텪텫텭땀땁땃땄땅땋때땍땐땔땜땝땟땠땡떠떡떤떨떪떫떰떱떳떴떵떻떼떽뗀뗄뗌뗍뗏뗐뗑뗘뗬또똑똔똘똥똬똴뙈뙤뙨뚜뚝뚠뚤뚫뚬뚱뛔뛰뛴뛸뜀뜁뜅뜨뜩뜬뜯뜰뜸뜹뜻띄띈띌띔띕띠띤띨띰띱띳띵라락란랄람랍랏랐랑랒랖랗"], ["b741", "텮", 13, "텽", 6, "톅톆톇톉톊"], ["b761", "톋", 20, "톢톣톥톦톧"], ["b781", "톩", 6, "톲톴톶톷톸톹톻톽톾톿퇁", 14, "래랙랜랠램랩랫랬랭랴략랸럇량러럭런럴럼럽럿렀렁렇레렉렌렐렘렙렛렝려력련렬렴렵렷렸령례롄롑롓로록론롤롬롭롯롱롸롼뢍뢨뢰뢴뢸룀룁룃룅료룐룔룝룟룡루룩룬룰룸룹룻룽뤄뤘뤠뤼뤽륀륄륌륏륑류륙륜률륨륩"], ["b841", "퇐", 7, "퇙", 17], ["b861", "퇫", 8, "퇵퇶퇷퇹", 13], ["b881", "툈툊", 5, "툑", 24, "륫륭르륵른를름릅릇릉릊릍릎리릭린릴림립릿링마막만많", 4, "맘맙맛망맞맡맣매맥맨맬맴맵맷맸맹맺먀먁먈먕머먹먼멀멂멈멉멋멍멎멓메멕멘멜멤멥멧멨멩며멱면멸몃몄명몇몌모목몫몬몰몲몸몹못몽뫄뫈뫘뫙뫼"], ["b941", "툪툫툮툯툱툲툳툵", 6, "툾퉀퉂", 5, "퉉퉊퉋퉌"], ["b961", "퉍", 14, "퉝", 6, "퉥퉦퉧퉨"], ["b981", "퉩", 22, "튂튃튅튆튇튉튊튋튌묀묄묍묏묑묘묜묠묩묫무묵묶문묻물묽묾뭄뭅뭇뭉뭍뭏뭐뭔뭘뭡뭣뭬뮈뮌뮐뮤뮨뮬뮴뮷므믄믈믐믓미믹민믿밀밂밈밉밋밌밍및밑바", 4, "받", 4, "밤밥밧방밭배백밴밸뱀뱁뱃뱄뱅뱉뱌뱍뱐뱝버벅번벋벌벎범법벗"], ["ba41", "튍튎튏튒튓튔튖", 5, "튝튞튟튡튢튣튥", 6, "튭"], ["ba61", "튮튯튰튲", 5, "튺튻튽튾틁틃", 4, "틊틌", 5], ["ba81", "틒틓틕틖틗틙틚틛틝", 6, "틦", 9, "틲틳틵틶틷틹틺벙벚베벡벤벧벨벰벱벳벴벵벼벽변별볍볏볐병볕볘볜보복볶본볼봄봅봇봉봐봔봤봬뵀뵈뵉뵌뵐뵘뵙뵤뵨부북분붇불붉붊붐붑붓붕붙붚붜붤붰붸뷔뷕뷘뷜뷩뷰뷴뷸븀븃븅브븍븐블븜븝븟비빅빈빌빎빔빕빗빙빚빛빠빡빤"], ["bb41", "틻", 4, "팂팄팆", 5, "팏팑팒팓팕팗", 4, "팞팢팣"], ["bb61", "팤팦팧팪팫팭팮팯팱", 6, "팺팾", 5, "퍆퍇퍈퍉"], ["bb81", "퍊", 31, "빨빪빰빱빳빴빵빻빼빽뺀뺄뺌뺍뺏뺐뺑뺘뺙뺨뻐뻑뻔뻗뻘뻠뻣뻤뻥뻬뼁뼈뼉뼘뼙뼛뼜뼝뽀뽁뽄뽈뽐뽑뽕뾔뾰뿅뿌뿍뿐뿔뿜뿟뿡쀼쁑쁘쁜쁠쁨쁩삐삑삔삘삠삡삣삥사삭삯산삳살삵삶삼삽삿샀상샅새색샌샐샘샙샛샜생샤"], ["bc41", "퍪", 17, "퍾퍿펁펂펃펅펆펇"], ["bc61", "펈펉펊펋펎펒", 5, "펚펛펝펞펟펡", 6, "펪펬펮"], ["bc81", "펯", 4, "펵펶펷펹펺펻펽", 6, "폆폇폊", 5, "폑", 5, "샥샨샬샴샵샷샹섀섄섈섐섕서", 4, "섣설섦섧섬섭섯섰성섶세섹센셀셈셉셋셌셍셔셕션셜셤셥셧셨셩셰셴셸솅소속솎손솔솖솜솝솟송솥솨솩솬솰솽쇄쇈쇌쇔쇗쇘쇠쇤쇨쇰쇱쇳쇼쇽숀숄숌숍숏숑수숙순숟술숨숩숫숭"], ["bd41", "폗폙", 7, "폢폤", 7, "폮폯폱폲폳폵폶폷"], ["bd61", "폸폹폺폻폾퐀퐂", 5, "퐉", 13], ["bd81", "퐗", 5, "퐞", 25, "숯숱숲숴쉈쉐쉑쉔쉘쉠쉥쉬쉭쉰쉴쉼쉽쉿슁슈슉슐슘슛슝스슥슨슬슭슴습슷승시식신싣실싫심십싯싱싶싸싹싻싼쌀쌈쌉쌌쌍쌓쌔쌕쌘쌜쌤쌥쌨쌩썅써썩썬썰썲썸썹썼썽쎄쎈쎌쏀쏘쏙쏜쏟쏠쏢쏨쏩쏭쏴쏵쏸쐈쐐쐤쐬쐰"], ["be41", "퐸", 7, "푁푂푃푅", 14], ["be61", "푔", 7, "푝푞푟푡푢푣푥", 7, "푮푰푱푲"], ["be81", "푳", 4, "푺푻푽푾풁풃", 4, "풊풌풎", 5, "풕", 8, "쐴쐼쐽쑈쑤쑥쑨쑬쑴쑵쑹쒀쒔쒜쒸쒼쓩쓰쓱쓴쓸쓺쓿씀씁씌씐씔씜씨씩씬씰씸씹씻씽아악안앉않알앍앎앓암압앗았앙앝앞애액앤앨앰앱앳앴앵야약얀얄얇얌얍얏양얕얗얘얜얠얩어억언얹얻얼얽얾엄", 6, "엌엎"], ["bf41", "풞", 10, "풪", 14], ["bf61", "풹", 18, "퓍퓎퓏퓑퓒퓓퓕"], ["bf81", "퓖", 5, "퓝퓞퓠", 7, "퓩퓪퓫퓭퓮퓯퓱", 6, "퓹퓺퓼에엑엔엘엠엡엣엥여역엮연열엶엷염", 5, "옅옆옇예옌옐옘옙옛옜오옥온올옭옮옰옳옴옵옷옹옻와왁완왈왐왑왓왔왕왜왝왠왬왯왱외왹왼욀욈욉욋욍요욕욘욜욤욥욧용우욱운울욹욺움웁웃웅워웍원월웜웝웠웡웨"], ["c041", "퓾", 5, "픅픆픇픉픊픋픍", 6, "픖픘", 5], ["c061", "픞", 25], ["c081", "픸픹픺픻픾픿핁핂핃핅", 6, "핎핐핒", 5, "핚핛핝핞핟핡핢핣웩웬웰웸웹웽위윅윈윌윔윕윗윙유육윤율윰윱윳융윷으윽은을읊음읍읏응", 7, "읜읠읨읫이익인일읽읾잃임입잇있잉잊잎자작잔잖잗잘잚잠잡잣잤장잦재잭잰잴잼잽잿쟀쟁쟈쟉쟌쟎쟐쟘쟝쟤쟨쟬저적전절젊"], ["c141", "핤핦핧핪핬핮", 5, "핶핷핹핺핻핽", 6, "햆햊햋"], ["c161", "햌햍햎햏햑", 19, "햦햧"], ["c181", "햨", 31, "점접젓정젖제젝젠젤젬젭젯젱져젼졀졈졉졌졍졔조족존졸졺좀좁좃종좆좇좋좌좍좔좝좟좡좨좼좽죄죈죌죔죕죗죙죠죡죤죵주죽준줄줅줆줌줍줏중줘줬줴쥐쥑쥔쥘쥠쥡쥣쥬쥰쥴쥼즈즉즌즐즘즙즛증지직진짇질짊짐집짓"], ["c241", "헊헋헍헎헏헑헓", 4, "헚헜헞", 5, "헦헧헩헪헫헭헮"], ["c261", "헯", 4, "헶헸헺", 5, "혂혃혅혆혇혉", 6, "혒"], ["c281", "혖", 5, "혝혞혟혡혢혣혥", 7, "혮", 9, "혺혻징짖짙짚짜짝짠짢짤짧짬짭짯짰짱째짹짼쨀쨈쨉쨋쨌쨍쨔쨘쨩쩌쩍쩐쩔쩜쩝쩟쩠쩡쩨쩽쪄쪘쪼쪽쫀쫄쫌쫍쫏쫑쫓쫘쫙쫠쫬쫴쬈쬐쬔쬘쬠쬡쭁쭈쭉쭌쭐쭘쭙쭝쭤쭸쭹쮜쮸쯔쯤쯧쯩찌찍찐찔찜찝찡찢찧차착찬찮찰참찹찻"], ["c341", "혽혾혿홁홂홃홄홆홇홊홌홎홏홐홒홓홖홗홙홚홛홝", 4], ["c361", "홢", 4, "홨홪", 5, "홲홳홵", 11], ["c381", "횁횂횄횆", 5, "횎횏횑횒횓횕", 7, "횞횠횢", 5, "횩횪찼창찾채책챈챌챔챕챗챘챙챠챤챦챨챰챵처척천철첨첩첫첬청체첵첸첼쳄쳅쳇쳉쳐쳔쳤쳬쳰촁초촉촌촐촘촙촛총촤촨촬촹최쵠쵤쵬쵭쵯쵱쵸춈추축춘출춤춥춧충춰췄췌췐취췬췰췸췹췻췽츄츈츌츔츙츠측츤츨츰츱츳층"], ["c441", "횫횭횮횯횱", 7, "횺횼", 7, "훆훇훉훊훋"], ["c461", "훍훎훏훐훒훓훕훖훘훚", 5, "훡훢훣훥훦훧훩", 4], ["c481", "훮훯훱훲훳훴훶", 5, "훾훿휁휂휃휅", 11, "휒휓휔치칙친칟칠칡침칩칫칭카칵칸칼캄캅캇캉캐캑캔캘캠캡캣캤캥캬캭컁커컥컨컫컬컴컵컷컸컹케켁켄켈켐켑켓켕켜켠켤켬켭켯켰켱켸코콕콘콜콤콥콧콩콰콱콴콸쾀쾅쾌쾡쾨쾰쿄쿠쿡쿤쿨쿰쿱쿳쿵쿼퀀퀄퀑퀘퀭퀴퀵퀸퀼"], ["c541", "휕휖휗휚휛휝휞휟휡", 6, "휪휬휮", 5, "휶휷휹"], ["c561", "휺휻휽", 6, "흅흆흈흊", 5, "흒흓흕흚", 4], ["c581", "흟흢흤흦흧흨흪흫흭흮흯흱흲흳흵", 6, "흾흿힀힂", 5, "힊힋큄큅큇큉큐큔큘큠크큭큰클큼큽킁키킥킨킬킴킵킷킹타탁탄탈탉탐탑탓탔탕태택탠탤탬탭탯탰탱탸턍터턱턴털턺텀텁텃텄텅테텍텐텔템텝텟텡텨텬텼톄톈토톡톤톨톰톱톳통톺톼퇀퇘퇴퇸툇툉툐투툭툰툴툼툽툿퉁퉈퉜"], ["c641", "힍힎힏힑", 6, "힚힜힞", 5], ["c6a1", "퉤튀튁튄튈튐튑튕튜튠튤튬튱트특튼튿틀틂틈틉틋틔틘틜틤틥티틱틴틸팀팁팃팅파팍팎판팔팖팜팝팟팠팡팥패팩팬팰팸팹팻팼팽퍄퍅퍼퍽펀펄펌펍펏펐펑페펙펜펠펨펩펫펭펴편펼폄폅폈평폐폘폡폣포폭폰폴폼폽폿퐁"], ["c7a1", "퐈퐝푀푄표푠푤푭푯푸푹푼푿풀풂품풉풋풍풔풩퓌퓐퓔퓜퓟퓨퓬퓰퓸퓻퓽프픈플픔픕픗피픽핀필핌핍핏핑하학한할핥함합핫항해핵핸핼햄햅햇했행햐향허헉헌헐헒험헙헛헝헤헥헨헬헴헵헷헹혀혁현혈혐협혓혔형혜혠"], ["c8a1", "혤혭호혹혼홀홅홈홉홋홍홑화확환활홧황홰홱홴횃횅회획횐횔횝횟횡효횬횰횹횻후훅훈훌훑훔훗훙훠훤훨훰훵훼훽휀휄휑휘휙휜휠휨휩휫휭휴휵휸휼흄흇흉흐흑흔흖흗흘흙흠흡흣흥흩희흰흴흼흽힁히힉힌힐힘힙힛힝"], ["caa1", "伽佳假價加可呵哥嘉嫁家暇架枷柯歌珂痂稼苛茄街袈訶賈跏軻迦駕刻却各恪慤殼珏脚覺角閣侃刊墾奸姦干幹懇揀杆柬桿澗癎看磵稈竿簡肝艮艱諫間乫喝曷渴碣竭葛褐蝎鞨勘坎堪嵌感憾戡敢柑橄減甘疳監瞰紺邯鑑鑒龕"], ["cba1", "匣岬甲胛鉀閘剛堈姜岡崗康强彊慷江畺疆糠絳綱羌腔舡薑襁講鋼降鱇介价個凱塏愷愾慨改槪漑疥皆盖箇芥蓋豈鎧開喀客坑更粳羹醵倨去居巨拒据據擧渠炬祛距踞車遽鉅鋸乾件健巾建愆楗腱虔蹇鍵騫乞傑杰桀儉劍劒檢"], ["cca1", "瞼鈐黔劫怯迲偈憩揭擊格檄激膈覡隔堅牽犬甄絹繭肩見譴遣鵑抉決潔結缺訣兼慊箝謙鉗鎌京俓倞傾儆勁勍卿坰境庚徑慶憬擎敬景暻更梗涇炅烱璟璥瓊痙硬磬竟競絅經耕耿脛莖警輕逕鏡頃頸驚鯨係啓堺契季屆悸戒桂械"], ["cda1", "棨溪界癸磎稽系繫繼計誡谿階鷄古叩告呱固姑孤尻庫拷攷故敲暠枯槁沽痼皐睾稿羔考股膏苦苽菰藁蠱袴誥賈辜錮雇顧高鼓哭斛曲梏穀谷鵠困坤崑昆梱棍滾琨袞鯤汨滑骨供公共功孔工恐恭拱控攻珙空蚣貢鞏串寡戈果瓜"], ["cea1", "科菓誇課跨過鍋顆廓槨藿郭串冠官寬慣棺款灌琯瓘管罐菅觀貫關館刮恝括适侊光匡壙廣曠洸炚狂珖筐胱鑛卦掛罫乖傀塊壞怪愧拐槐魁宏紘肱轟交僑咬喬嬌嶠巧攪敎校橋狡皎矯絞翹膠蕎蛟較轎郊餃驕鮫丘久九仇俱具勾"], ["cfa1", "區口句咎嘔坵垢寇嶇廐懼拘救枸柩構歐毆毬求溝灸狗玖球瞿矩究絿耉臼舅舊苟衢謳購軀逑邱鉤銶駒驅鳩鷗龜國局菊鞠鞫麴君窘群裙軍郡堀屈掘窟宮弓穹窮芎躬倦券勸卷圈拳捲權淃眷厥獗蕨蹶闕机櫃潰詭軌饋句晷歸貴"], ["d0a1", "鬼龜叫圭奎揆槻珪硅窺竅糾葵規赳逵閨勻均畇筠菌鈞龜橘克剋劇戟棘極隙僅劤勤懃斤根槿瑾筋芹菫覲謹近饉契今妗擒昑檎琴禁禽芩衾衿襟金錦伋及急扱汲級給亘兢矜肯企伎其冀嗜器圻基埼夔奇妓寄岐崎己幾忌技旗旣"], ["d1a1", "朞期杞棋棄機欺氣汽沂淇玘琦琪璂璣畸畿碁磯祁祇祈祺箕紀綺羈耆耭肌記譏豈起錡錤飢饑騎騏驥麒緊佶吉拮桔金喫儺喇奈娜懦懶拏拿癩", 5, "那樂", 4, "諾酪駱亂卵暖欄煖爛蘭難鸞捏捺南嵐枏楠湳濫男藍襤拉"], ["d2a1", "納臘蠟衲囊娘廊", 4, "乃來內奈柰耐冷女年撚秊念恬拈捻寧寗努勞奴弩怒擄櫓爐瑙盧", 5, "駑魯", 10, "濃籠聾膿農惱牢磊腦賂雷尿壘", 7, "嫩訥杻紐勒", 5, "能菱陵尼泥匿溺多茶"], ["d3a1", "丹亶但單團壇彖斷旦檀段湍短端簞緞蛋袒鄲鍛撻澾獺疸達啖坍憺擔曇淡湛潭澹痰聃膽蕁覃談譚錟沓畓答踏遝唐堂塘幢戇撞棠當糖螳黨代垈坮大對岱帶待戴擡玳臺袋貸隊黛宅德悳倒刀到圖堵塗導屠島嶋度徒悼挑掉搗桃"], ["d4a1", "棹櫂淘渡滔濤燾盜睹禱稻萄覩賭跳蹈逃途道都鍍陶韜毒瀆牘犢獨督禿篤纛讀墩惇敦旽暾沌焞燉豚頓乭突仝冬凍動同憧東桐棟洞潼疼瞳童胴董銅兜斗杜枓痘竇荳讀豆逗頭屯臀芚遁遯鈍得嶝橙燈登等藤謄鄧騰喇懶拏癩羅"], ["d5a1", "蘿螺裸邏樂洛烙珞絡落諾酪駱丹亂卵欄欒瀾爛蘭鸞剌辣嵐擥攬欖濫籃纜藍襤覽拉臘蠟廊朗浪狼琅瑯螂郞來崍徠萊冷掠略亮倆兩凉梁樑粮粱糧良諒輛量侶儷勵呂廬慮戾旅櫚濾礪藜蠣閭驢驪麗黎力曆歷瀝礫轢靂憐戀攣漣"], ["d6a1", "煉璉練聯蓮輦連鍊冽列劣洌烈裂廉斂殮濂簾獵令伶囹寧岺嶺怜玲笭羚翎聆逞鈴零靈領齡例澧禮醴隷勞怒撈擄櫓潞瀘爐盧老蘆虜路輅露魯鷺鹵碌祿綠菉錄鹿麓論壟弄朧瀧瓏籠聾儡瀨牢磊賂賚賴雷了僚寮廖料燎療瞭聊蓼"], ["d7a1", "遼鬧龍壘婁屢樓淚漏瘻累縷蔞褸鏤陋劉旒柳榴流溜瀏琉瑠留瘤硫謬類六戮陸侖倫崙淪綸輪律慄栗率隆勒肋凜凌楞稜綾菱陵俚利厘吏唎履悧李梨浬犁狸理璃異痢籬罹羸莉裏裡里釐離鯉吝潾燐璘藺躪隣鱗麟林淋琳臨霖砬"], ["d8a1", "立笠粒摩瑪痲碼磨馬魔麻寞幕漠膜莫邈万卍娩巒彎慢挽晩曼滿漫灣瞞萬蔓蠻輓饅鰻唜抹末沫茉襪靺亡妄忘忙望網罔芒茫莽輞邙埋妹媒寐昧枚梅每煤罵買賣邁魅脈貊陌驀麥孟氓猛盲盟萌冪覓免冕勉棉沔眄眠綿緬面麵滅"], ["d9a1", "蔑冥名命明暝椧溟皿瞑茗蓂螟酩銘鳴袂侮冒募姆帽慕摸摹暮某模母毛牟牡瑁眸矛耗芼茅謀謨貌木沐牧目睦穆鶩歿沒夢朦蒙卯墓妙廟描昴杳渺猫竗苗錨務巫憮懋戊拇撫无楙武毋無珷畝繆舞茂蕪誣貿霧鵡墨默們刎吻問文"], ["daa1", "汶紊紋聞蚊門雯勿沕物味媚尾嵋彌微未梶楣渼湄眉米美薇謎迷靡黴岷悶愍憫敏旻旼民泯玟珉緡閔密蜜謐剝博拍搏撲朴樸泊珀璞箔粕縛膊舶薄迫雹駁伴半反叛拌搬攀斑槃泮潘班畔瘢盤盼磐磻礬絆般蟠返頒飯勃拔撥渤潑"], ["dba1", "發跋醱鉢髮魃倣傍坊妨尨幇彷房放方旁昉枋榜滂磅紡肪膀舫芳蒡蚌訪謗邦防龐倍俳北培徘拜排杯湃焙盃背胚裴裵褙賠輩配陪伯佰帛柏栢白百魄幡樊煩燔番磻繁蕃藩飜伐筏罰閥凡帆梵氾汎泛犯範范法琺僻劈壁擘檗璧癖"], ["dca1", "碧蘗闢霹便卞弁變辨辯邊別瞥鱉鼈丙倂兵屛幷昞昺柄棅炳甁病秉竝輧餠騈保堡報寶普步洑湺潽珤甫菩補褓譜輔伏僕匐卜宓復服福腹茯蔔複覆輹輻馥鰒本乶俸奉封峯峰捧棒烽熢琫縫蓬蜂逢鋒鳳不付俯傅剖副否咐埠夫婦"], ["dda1", "孚孵富府復扶敷斧浮溥父符簿缶腐腑膚艀芙莩訃負賦賻赴趺部釜阜附駙鳧北分吩噴墳奔奮忿憤扮昐汾焚盆粉糞紛芬賁雰不佛弗彿拂崩朋棚硼繃鵬丕備匕匪卑妃婢庇悲憊扉批斐枇榧比毖毗毘沸泌琵痺砒碑秕秘粃緋翡肥"], ["dea1", "脾臂菲蜚裨誹譬費鄙非飛鼻嚬嬪彬斌檳殯浜濱瀕牝玭貧賓頻憑氷聘騁乍事些仕伺似使俟僿史司唆嗣四士奢娑寫寺射巳師徙思捨斜斯柶査梭死沙泗渣瀉獅砂社祀祠私篩紗絲肆舍莎蓑蛇裟詐詞謝賜赦辭邪飼駟麝削數朔索"], ["dfa1", "傘刪山散汕珊産疝算蒜酸霰乷撒殺煞薩三參杉森渗芟蔘衫揷澁鈒颯上傷像償商喪嘗孀尙峠常床庠廂想桑橡湘爽牀狀相祥箱翔裳觴詳象賞霜塞璽賽嗇塞穡索色牲生甥省笙墅壻嶼序庶徐恕抒捿敍暑曙書栖棲犀瑞筮絮緖署"], ["e0a1", "胥舒薯西誓逝鋤黍鼠夕奭席惜昔晳析汐淅潟石碩蓆釋錫仙僊先善嬋宣扇敾旋渲煽琁瑄璇璿癬禪線繕羨腺膳船蘚蟬詵跣選銑鐥饍鮮卨屑楔泄洩渫舌薛褻設說雪齧剡暹殲纖蟾贍閃陝攝涉燮葉城姓宬性惺成星晟猩珹盛省筬"], ["e1a1", "聖聲腥誠醒世勢歲洗稅笹細說貰召嘯塑宵小少巢所掃搔昭梳沼消溯瀟炤燒甦疏疎瘙笑篠簫素紹蔬蕭蘇訴逍遡邵銷韶騷俗屬束涑粟續謖贖速孫巽損蓀遜飡率宋悚松淞訟誦送頌刷殺灑碎鎖衰釗修受嗽囚垂壽嫂守岫峀帥愁"], ["e2a1", "戍手授搜收數樹殊水洙漱燧狩獸琇璲瘦睡秀穗竪粹綏綬繡羞脩茱蒐蓚藪袖誰讐輸遂邃酬銖銹隋隧隨雖需須首髓鬚叔塾夙孰宿淑潚熟琡璹肅菽巡徇循恂旬栒楯橓殉洵淳珣盾瞬筍純脣舜荀蓴蕣詢諄醇錞順馴戌術述鉥崇崧"], ["e3a1", "嵩瑟膝蝨濕拾習褶襲丞乘僧勝升承昇繩蠅陞侍匙嘶始媤尸屎屍市弑恃施是時枾柴猜矢示翅蒔蓍視試詩諡豕豺埴寔式息拭植殖湜熄篒蝕識軾食飾伸侁信呻娠宸愼新晨燼申神紳腎臣莘薪藎蜃訊身辛辰迅失室實悉審尋心沁"], ["e4a1", "沈深瀋甚芯諶什十拾雙氏亞俄兒啞娥峨我牙芽莪蛾衙訝阿雅餓鴉鵝堊岳嶽幄惡愕握樂渥鄂鍔顎鰐齷安岸按晏案眼雁鞍顔鮟斡謁軋閼唵岩巖庵暗癌菴闇壓押狎鴨仰央怏昻殃秧鴦厓哀埃崖愛曖涯碍艾隘靄厄扼掖液縊腋額"], ["e5a1", "櫻罌鶯鸚也倻冶夜惹揶椰爺耶若野弱掠略約若葯蒻藥躍亮佯兩凉壤孃恙揚攘敭暘梁楊樣洋瀁煬痒瘍禳穰糧羊良襄諒讓釀陽量養圄御於漁瘀禦語馭魚齬億憶抑檍臆偃堰彦焉言諺孼蘖俺儼嚴奄掩淹嶪業円予余勵呂女如廬"], ["e6a1", "旅歟汝濾璵礖礪與艅茹輿轝閭餘驪麗黎亦力域役易曆歷疫繹譯轢逆驛嚥堧姸娟宴年延憐戀捐挻撚椽沇沿涎涓淵演漣烟然煙煉燃燕璉硏硯秊筵緣練縯聯衍軟輦蓮連鉛鍊鳶列劣咽悅涅烈熱裂說閱厭廉念捻染殮炎焰琰艶苒"], ["e7a1", "簾閻髥鹽曄獵燁葉令囹塋寧嶺嶸影怜映暎楹榮永泳渶潁濚瀛瀯煐營獰玲瑛瑩瓔盈穎纓羚聆英詠迎鈴鍈零霙靈領乂倪例刈叡曳汭濊猊睿穢芮藝蘂禮裔詣譽豫醴銳隸霓預五伍俉傲午吾吳嗚塢墺奧娛寤悟惡懊敖旿晤梧汚澳"], ["e8a1", "烏熬獒筽蜈誤鰲鼇屋沃獄玉鈺溫瑥瘟穩縕蘊兀壅擁瓮甕癰翁邕雍饔渦瓦窩窪臥蛙蝸訛婉完宛梡椀浣玩琓琬碗緩翫脘腕莞豌阮頑曰往旺枉汪王倭娃歪矮外嵬巍猥畏了僚僥凹堯夭妖姚寥寮尿嶢拗搖撓擾料曜樂橈燎燿瑤療"], ["e9a1", "窈窯繇繞耀腰蓼蟯要謠遙遼邀饒慾欲浴縟褥辱俑傭冗勇埇墉容庸慂榕涌湧溶熔瑢用甬聳茸蓉踊鎔鏞龍于佑偶優又友右宇寓尤愚憂旴牛玗瑀盂祐禑禹紆羽芋藕虞迂遇郵釪隅雨雩勖彧旭昱栯煜稶郁頊云暈橒殞澐熉耘芸蕓"], ["eaa1", "運隕雲韻蔚鬱亐熊雄元原員圓園垣媛嫄寃怨愿援沅洹湲源爰猿瑗苑袁轅遠阮院願鴛月越鉞位偉僞危圍委威尉慰暐渭爲瑋緯胃萎葦蔿蝟衛褘謂違韋魏乳侑儒兪劉唯喩孺宥幼幽庾悠惟愈愉揄攸有杻柔柚柳楡楢油洧流游溜"], ["eba1", "濡猶猷琉瑜由留癒硫紐維臾萸裕誘諛諭踰蹂遊逾遺酉釉鍮類六堉戮毓肉育陸倫允奫尹崙淪潤玧胤贇輪鈗閏律慄栗率聿戎瀜絨融隆垠恩慇殷誾銀隱乙吟淫蔭陰音飮揖泣邑凝應膺鷹依倚儀宜意懿擬椅毅疑矣義艤薏蟻衣誼"], ["eca1", "議醫二以伊利吏夷姨履已弛彛怡易李梨泥爾珥理異痍痢移罹而耳肄苡荑裏裡貽貳邇里離飴餌匿溺瀷益翊翌翼謚人仁刃印吝咽因姻寅引忍湮燐璘絪茵藺蚓認隣靭靷鱗麟一佚佾壹日溢逸鎰馹任壬妊姙恁林淋稔臨荏賃入卄"], ["eda1", "立笠粒仍剩孕芿仔刺咨姉姿子字孜恣慈滋炙煮玆瓷疵磁紫者自茨蔗藉諮資雌作勺嚼斫昨灼炸爵綽芍酌雀鵲孱棧殘潺盞岑暫潛箴簪蠶雜丈仗匠場墻壯奬將帳庄張掌暲杖樟檣欌漿牆狀獐璋章粧腸臟臧莊葬蔣薔藏裝贓醬長"], ["eea1", "障再哉在宰才材栽梓渽滓災縡裁財載齋齎爭箏諍錚佇低儲咀姐底抵杵楮樗沮渚狙猪疽箸紵苧菹著藷詛貯躇這邸雎齟勣吊嫡寂摘敵滴狄炙的積笛籍績翟荻謫賊赤跡蹟迪迹適鏑佃佺傳全典前剪塡塼奠專展廛悛戰栓殿氈澱"], ["efa1", "煎琠田甸畑癲筌箋箭篆纏詮輾轉鈿銓錢鐫電顚顫餞切截折浙癤竊節絶占岾店漸点粘霑鮎點接摺蝶丁井亭停偵呈姃定幀庭廷征情挺政整旌晶晸柾楨檉正汀淀淨渟湞瀞炡玎珽町睛碇禎程穽精綎艇訂諪貞鄭酊釘鉦鋌錠霆靖"], ["f0a1", "靜頂鼎制劑啼堤帝弟悌提梯濟祭第臍薺製諸蹄醍除際霽題齊俎兆凋助嘲弔彫措操早晁曺曹朝條棗槽漕潮照燥爪璪眺祖祚租稠窕粗糟組繰肇藻蚤詔調趙躁造遭釣阻雕鳥族簇足鏃存尊卒拙猝倧宗從悰慫棕淙琮種終綜縱腫"], ["f1a1", "踪踵鍾鐘佐坐左座挫罪主住侏做姝胄呪周嗾奏宙州廚晝朱柱株注洲湊澍炷珠疇籌紂紬綢舟蛛註誅走躊輳週酎酒鑄駐竹粥俊儁准埈寯峻晙樽浚準濬焌畯竣蠢逡遵雋駿茁中仲衆重卽櫛楫汁葺增憎曾拯烝甑症繒蒸證贈之只"], ["f2a1", "咫地址志持指摯支旨智枝枳止池沚漬知砥祉祗紙肢脂至芝芷蜘誌識贄趾遲直稙稷織職唇嗔塵振搢晉晋桭榛殄津溱珍瑨璡畛疹盡眞瞋秦縉縝臻蔯袗診賑軫辰進鎭陣陳震侄叱姪嫉帙桎瓆疾秩窒膣蛭質跌迭斟朕什執潗緝輯"], ["f3a1", "鏶集徵懲澄且侘借叉嗟嵯差次此磋箚茶蹉車遮捉搾着窄錯鑿齪撰澯燦璨瓚竄簒纂粲纘讚贊鑽餐饌刹察擦札紮僭參塹慘慙懺斬站讒讖倉倡創唱娼廠彰愴敞昌昶暢槍滄漲猖瘡窓脹艙菖蒼債埰寀寨彩採砦綵菜蔡采釵冊柵策"], ["f4a1", "責凄妻悽處倜刺剔尺慽戚拓擲斥滌瘠脊蹠陟隻仟千喘天川擅泉淺玔穿舛薦賤踐遷釧闡阡韆凸哲喆徹撤澈綴輟轍鐵僉尖沾添甛瞻簽籤詹諂堞妾帖捷牒疊睫諜貼輒廳晴淸聽菁請靑鯖切剃替涕滯締諦逮遞體初剿哨憔抄招梢"], ["f5a1", "椒楚樵炒焦硝礁礎秒稍肖艸苕草蕉貂超酢醋醮促囑燭矗蜀觸寸忖村邨叢塚寵悤憁摠總聰蔥銃撮催崔最墜抽推椎楸樞湫皺秋芻萩諏趨追鄒酋醜錐錘鎚雛騶鰍丑畜祝竺筑築縮蓄蹙蹴軸逐春椿瑃出朮黜充忠沖蟲衝衷悴膵萃"], ["f6a1", "贅取吹嘴娶就炊翠聚脆臭趣醉驟鷲側仄厠惻測層侈値嗤峙幟恥梔治淄熾痔痴癡稚穉緇緻置致蚩輜雉馳齒則勅飭親七柒漆侵寢枕沈浸琛砧針鍼蟄秤稱快他咤唾墮妥惰打拖朶楕舵陀馱駝倬卓啄坼度托拓擢晫柝濁濯琢琸託"], ["f7a1", "鐸呑嘆坦彈憚歎灘炭綻誕奪脫探眈耽貪塔搭榻宕帑湯糖蕩兌台太怠態殆汰泰笞胎苔跆邰颱宅擇澤撑攄兎吐土討慟桶洞痛筒統通堆槌腿褪退頹偸套妬投透鬪慝特闖坡婆巴把播擺杷波派爬琶破罷芭跛頗判坂板版瓣販辦鈑"], ["f8a1", "阪八叭捌佩唄悖敗沛浿牌狽稗覇貝彭澎烹膨愎便偏扁片篇編翩遍鞭騙貶坪平枰萍評吠嬖幣廢弊斃肺蔽閉陛佈包匍匏咆哺圃布怖抛抱捕暴泡浦疱砲胞脯苞葡蒲袍褒逋鋪飽鮑幅暴曝瀑爆輻俵剽彪慓杓標漂瓢票表豹飇飄驃"], ["f9a1", "品稟楓諷豊風馮彼披疲皮被避陂匹弼必泌珌畢疋筆苾馝乏逼下何厦夏廈昰河瑕荷蝦賀遐霞鰕壑學虐謔鶴寒恨悍旱汗漢澣瀚罕翰閑閒限韓割轄函含咸啣喊檻涵緘艦銜陷鹹合哈盒蛤閤闔陜亢伉姮嫦巷恒抗杭桁沆港缸肛航"], ["faa1", "行降項亥偕咳垓奚孩害懈楷海瀣蟹解該諧邂駭骸劾核倖幸杏荇行享向嚮珦鄕響餉饗香噓墟虛許憲櫶獻軒歇險驗奕爀赫革俔峴弦懸晛泫炫玄玹現眩睍絃絢縣舷衒見賢鉉顯孑穴血頁嫌俠協夾峽挾浹狹脅脇莢鋏頰亨兄刑型"], ["fba1", "形泂滎瀅灐炯熒珩瑩荊螢衡逈邢鎣馨兮彗惠慧暳蕙蹊醯鞋乎互呼壕壺好岵弧戶扈昊晧毫浩淏湖滸澔濠濩灝狐琥瑚瓠皓祜糊縞胡芦葫蒿虎號蝴護豪鎬頀顥惑或酷婚昏混渾琿魂忽惚笏哄弘汞泓洪烘紅虹訌鴻化和嬅樺火畵"], ["fca1", "禍禾花華話譁貨靴廓擴攫確碻穫丸喚奐宦幻患換歡晥桓渙煥環紈還驩鰥活滑猾豁闊凰幌徨恍惶愰慌晃晄榥況湟滉潢煌璜皇篁簧荒蝗遑隍黃匯回廻徊恢悔懷晦會檜淮澮灰獪繪膾茴蛔誨賄劃獲宖橫鐄哮嚆孝效斅曉梟涍淆"], ["fda1", "爻肴酵驍侯候厚后吼喉嗅帿後朽煦珝逅勛勳塤壎焄熏燻薰訓暈薨喧暄煊萱卉喙毁彙徽揮暉煇諱輝麾休携烋畦虧恤譎鷸兇凶匈洶胸黑昕欣炘痕吃屹紇訖欠欽歆吸恰洽翕興僖凞喜噫囍姬嬉希憙憘戱晞曦熙熹熺犧禧稀羲詰"]]; + +var cp949$1 = Object.freeze({ + default: cp949 +}); + +var cp950 = [["0", "\0", 127], ["a140", " ,、。.‧;:?!︰…‥﹐﹑﹒·﹔﹕﹖﹗|–︱—︳╴︴﹏()︵︶{}︷︸〔〕︹︺【】︻︼《》︽︾〈〉︿﹀「」﹁﹂『』﹃﹄﹙﹚"], ["a1a1", "﹛﹜﹝﹞‘’“”〝〞‵′#&*※§〃○●△▲◎☆★◇◆□■▽▼㊣℅¯ ̄_ˍ﹉﹊﹍﹎﹋﹌﹟﹠﹡+-×÷±√<>=≦≧≠∞≒≡﹢", 4, "~∩∪⊥∠∟⊿㏒㏑∫∮∵∴♀♂⊕⊙↑↓←→↖↗↙↘∥∣/"], ["a240", "\∕﹨$¥〒¢£%@℃℉﹩﹪﹫㏕㎜㎝㎞㏎㎡㎎㎏㏄°兙兛兞兝兡兣嗧瓩糎▁", 7, "▏▎▍▌▋▊▉┼┴┬┤├▔─│▕┌┐└┘╭"], ["a2a1", "╮╰╯═╞╪╡◢◣◥◤╱╲╳0", 9, "Ⅰ", 9, "〡", 8, "十卄卅A", 25, "a", 21], ["a340", "wxyzΑ", 16, "Σ", 6, "α", 16, "σ", 6, "ㄅ", 10], ["a3a1", "ㄐ", 25, "˙ˉˊˇˋ"], ["a3e1", "€"], ["a440", "一乙丁七乃九了二人儿入八几刀刁力匕十卜又三下丈上丫丸凡久么也乞于亡兀刃勺千叉口土士夕大女子孑孓寸小尢尸山川工己已巳巾干廾弋弓才"], ["a4a1", "丑丐不中丰丹之尹予云井互五亢仁什仃仆仇仍今介仄元允內六兮公冗凶分切刈勻勾勿化匹午升卅卞厄友及反壬天夫太夭孔少尤尺屯巴幻廿弔引心戈戶手扎支文斗斤方日曰月木欠止歹毋比毛氏水火爪父爻片牙牛犬王丙"], ["a540", "世丕且丘主乍乏乎以付仔仕他仗代令仙仞充兄冉冊冬凹出凸刊加功包匆北匝仟半卉卡占卯卮去可古右召叮叩叨叼司叵叫另只史叱台句叭叻四囚外"], ["a5a1", "央失奴奶孕它尼巨巧左市布平幼弁弘弗必戊打扔扒扑斥旦朮本未末札正母民氐永汁汀氾犯玄玉瓜瓦甘生用甩田由甲申疋白皮皿目矛矢石示禾穴立丞丟乒乓乩亙交亦亥仿伉伙伊伕伍伐休伏仲件任仰仳份企伋光兇兆先全"], ["a640", "共再冰列刑划刎刖劣匈匡匠印危吉吏同吊吐吁吋各向名合吃后吆吒因回囝圳地在圭圬圯圩夙多夷夸妄奸妃好她如妁字存宇守宅安寺尖屹州帆并年"], ["a6a1", "式弛忙忖戎戌戍成扣扛托收早旨旬旭曲曳有朽朴朱朵次此死氖汝汗汙江池汐汕污汛汍汎灰牟牝百竹米糸缶羊羽老考而耒耳聿肉肋肌臣自至臼舌舛舟艮色艾虫血行衣西阡串亨位住佇佗佞伴佛何估佐佑伽伺伸佃佔似但佣"], ["a740", "作你伯低伶余佝佈佚兌克免兵冶冷別判利刪刨劫助努劬匣即卵吝吭吞吾否呎吧呆呃吳呈呂君吩告吹吻吸吮吵吶吠吼呀吱含吟听囪困囤囫坊坑址坍"], ["a7a1", "均坎圾坐坏圻壯夾妝妒妨妞妣妙妖妍妤妓妊妥孝孜孚孛完宋宏尬局屁尿尾岐岑岔岌巫希序庇床廷弄弟彤形彷役忘忌志忍忱快忸忪戒我抄抗抖技扶抉扭把扼找批扳抒扯折扮投抓抑抆改攻攸旱更束李杏材村杜杖杞杉杆杠"], ["a840", "杓杗步每求汞沙沁沈沉沅沛汪決沐汰沌汨沖沒汽沃汲汾汴沆汶沍沔沘沂灶灼災灸牢牡牠狄狂玖甬甫男甸皂盯矣私秀禿究系罕肖肓肝肘肛肚育良芒"], ["a8a1", "芋芍見角言谷豆豕貝赤走足身車辛辰迂迆迅迄巡邑邢邪邦那酉釆里防阮阱阪阬並乖乳事些亞享京佯依侍佳使佬供例來侃佰併侈佩佻侖佾侏侑佺兔兒兕兩具其典冽函刻券刷刺到刮制剁劾劻卒協卓卑卦卷卸卹取叔受味呵"], ["a940", "咖呸咕咀呻呷咄咒咆呼咐呱呶和咚呢周咋命咎固垃坷坪坩坡坦坤坼夜奉奇奈奄奔妾妻委妹妮姑姆姐姍始姓姊妯妳姒姅孟孤季宗定官宜宙宛尚屈居"], ["a9a1", "屆岷岡岸岩岫岱岳帘帚帖帕帛帑幸庚店府底庖延弦弧弩往征彿彼忝忠忽念忿怏怔怯怵怖怪怕怡性怩怫怛或戕房戾所承拉拌拄抿拂抹拒招披拓拔拋拈抨抽押拐拙拇拍抵拚抱拘拖拗拆抬拎放斧於旺昔易昌昆昂明昀昏昕昊"], ["aa40", "昇服朋杭枋枕東果杳杷枇枝林杯杰板枉松析杵枚枓杼杪杲欣武歧歿氓氛泣注泳沱泌泥河沽沾沼波沫法泓沸泄油況沮泗泅泱沿治泡泛泊沬泯泜泖泠"], ["aaa1", "炕炎炒炊炙爬爭爸版牧物狀狎狙狗狐玩玨玟玫玥甽疝疙疚的盂盲直知矽社祀祁秉秈空穹竺糾罔羌羋者肺肥肢肱股肫肩肴肪肯臥臾舍芳芝芙芭芽芟芹花芬芥芯芸芣芰芾芷虎虱初表軋迎返近邵邸邱邶采金長門阜陀阿阻附"], ["ab40", "陂隹雨青非亟亭亮信侵侯便俠俑俏保促侶俘俟俊俗侮俐俄係俚俎俞侷兗冒冑冠剎剃削前剌剋則勇勉勃勁匍南卻厚叛咬哀咨哎哉咸咦咳哇哂咽咪品"], ["aba1", "哄哈咯咫咱咻咩咧咿囿垂型垠垣垢城垮垓奕契奏奎奐姜姘姿姣姨娃姥姪姚姦威姻孩宣宦室客宥封屎屏屍屋峙峒巷帝帥帟幽庠度建弈弭彥很待徊律徇後徉怒思怠急怎怨恍恰恨恢恆恃恬恫恪恤扁拜挖按拼拭持拮拽指拱拷"], ["ac40", "拯括拾拴挑挂政故斫施既春昭映昧是星昨昱昤曷柿染柱柔某柬架枯柵柩柯柄柑枴柚查枸柏柞柳枰柙柢柝柒歪殃殆段毒毗氟泉洋洲洪流津洌洱洞洗"], ["aca1", "活洽派洶洛泵洹洧洸洩洮洵洎洫炫為炳炬炯炭炸炮炤爰牲牯牴狩狠狡玷珊玻玲珍珀玳甚甭畏界畎畋疫疤疥疢疣癸皆皇皈盈盆盃盅省盹相眉看盾盼眇矜砂研砌砍祆祉祈祇禹禺科秒秋穿突竿竽籽紂紅紀紉紇約紆缸美羿耄"], ["ad40", "耐耍耑耶胖胥胚胃胄背胡胛胎胞胤胝致舢苧范茅苣苛苦茄若茂茉苒苗英茁苜苔苑苞苓苟苯茆虐虹虻虺衍衫要觔計訂訃貞負赴赳趴軍軌述迦迢迪迥"], ["ada1", "迭迫迤迨郊郎郁郃酋酊重閂限陋陌降面革韋韭音頁風飛食首香乘亳倌倍倣俯倦倥俸倩倖倆值借倚倒們俺倀倔倨俱倡個候倘俳修倭倪俾倫倉兼冤冥冢凍凌准凋剖剜剔剛剝匪卿原厝叟哨唐唁唷哼哥哲唆哺唔哩哭員唉哮哪"], ["ae40", "哦唧唇哽唏圃圄埂埔埋埃堉夏套奘奚娑娘娜娟娛娓姬娠娣娩娥娌娉孫屘宰害家宴宮宵容宸射屑展屐峭峽峻峪峨峰島崁峴差席師庫庭座弱徒徑徐恙"], ["aea1", "恣恥恐恕恭恩息悄悟悚悍悔悌悅悖扇拳挈拿捎挾振捕捂捆捏捉挺捐挽挪挫挨捍捌效敉料旁旅時晉晏晃晒晌晅晁書朔朕朗校核案框桓根桂桔栩梳栗桌桑栽柴桐桀格桃株桅栓栘桁殊殉殷氣氧氨氦氤泰浪涕消涇浦浸海浙涓"], ["af40", "浬涉浮浚浴浩涌涊浹涅浥涔烊烘烤烙烈烏爹特狼狹狽狸狷玆班琉珮珠珪珞畔畝畜畚留疾病症疲疳疽疼疹痂疸皋皰益盍盎眩真眠眨矩砰砧砸砝破砷"], ["afa1", "砥砭砠砟砲祕祐祠祟祖神祝祗祚秤秣秧租秦秩秘窄窈站笆笑粉紡紗紋紊素索純紐紕級紜納紙紛缺罟羔翅翁耆耘耕耙耗耽耿胱脂胰脅胭胴脆胸胳脈能脊胼胯臭臬舀舐航舫舨般芻茫荒荔荊茸荐草茵茴荏茲茹茶茗荀茱茨荃"], ["b040", "虔蚊蚪蚓蚤蚩蚌蚣蚜衰衷袁袂衽衹記訐討訌訕訊託訓訖訏訑豈豺豹財貢起躬軒軔軏辱送逆迷退迺迴逃追逅迸邕郡郝郢酒配酌釘針釗釜釙閃院陣陡"], ["b0a1", "陛陝除陘陞隻飢馬骨高鬥鬲鬼乾偺偽停假偃偌做偉健偶偎偕偵側偷偏倏偯偭兜冕凰剪副勒務勘動匐匏匙匿區匾參曼商啪啦啄啞啡啃啊唱啖問啕唯啤唸售啜唬啣唳啁啗圈國圉域堅堊堆埠埤基堂堵執培夠奢娶婁婉婦婪婀"], ["b140", "娼婢婚婆婊孰寇寅寄寂宿密尉專將屠屜屝崇崆崎崛崖崢崑崩崔崙崤崧崗巢常帶帳帷康庸庶庵庾張強彗彬彩彫得徙從徘御徠徜恿患悉悠您惋悴惦悽"], ["b1a1", "情悻悵惜悼惘惕惆惟悸惚惇戚戛扈掠控捲掖探接捷捧掘措捱掩掉掃掛捫推掄授掙採掬排掏掀捻捩捨捺敝敖救教敗啟敏敘敕敔斜斛斬族旋旌旎晝晚晤晨晦晞曹勗望梁梯梢梓梵桿桶梱梧梗械梃棄梭梆梅梔條梨梟梡梂欲殺"], ["b240", "毫毬氫涎涼淳淙液淡淌淤添淺清淇淋涯淑涮淞淹涸混淵淅淒渚涵淚淫淘淪深淮淨淆淄涪淬涿淦烹焉焊烽烯爽牽犁猜猛猖猓猙率琅琊球理現琍瓠瓶"], ["b2a1", "瓷甜產略畦畢異疏痔痕疵痊痍皎盔盒盛眷眾眼眶眸眺硫硃硎祥票祭移窒窕笠笨笛第符笙笞笮粒粗粕絆絃統紮紹紼絀細紳組累終紲紱缽羞羚翌翎習耜聊聆脯脖脣脫脩脰脤舂舵舷舶船莎莞莘荸莢莖莽莫莒莊莓莉莠荷荻荼"], ["b340", "莆莧處彪蛇蛀蚶蛄蚵蛆蛋蚱蚯蛉術袞袈被袒袖袍袋覓規訪訝訣訥許設訟訛訢豉豚販責貫貨貪貧赧赦趾趺軛軟這逍通逗連速逝逐逕逞造透逢逖逛途"], ["b3a1", "部郭都酗野釵釦釣釧釭釩閉陪陵陳陸陰陴陶陷陬雀雪雩章竟頂頃魚鳥鹵鹿麥麻傢傍傅備傑傀傖傘傚最凱割剴創剩勞勝勛博厥啻喀喧啼喊喝喘喂喜喪喔喇喋喃喳單喟唾喲喚喻喬喱啾喉喫喙圍堯堪場堤堰報堡堝堠壹壺奠"], ["b440", "婷媚婿媒媛媧孳孱寒富寓寐尊尋就嵌嵐崴嵇巽幅帽幀幃幾廊廁廂廄弼彭復循徨惑惡悲悶惠愜愣惺愕惰惻惴慨惱愎惶愉愀愒戟扉掣掌描揀揩揉揆揍"], ["b4a1", "插揣提握揖揭揮捶援揪換摒揚揹敞敦敢散斑斐斯普晰晴晶景暑智晾晷曾替期朝棺棕棠棘棗椅棟棵森棧棹棒棲棣棋棍植椒椎棉棚楮棻款欺欽殘殖殼毯氮氯氬港游湔渡渲湧湊渠渥渣減湛湘渤湖湮渭渦湯渴湍渺測湃渝渾滋"], ["b540", "溉渙湎湣湄湲湩湟焙焚焦焰無然煮焜牌犄犀猶猥猴猩琺琪琳琢琥琵琶琴琯琛琦琨甥甦畫番痢痛痣痙痘痞痠登發皖皓皴盜睏短硝硬硯稍稈程稅稀窘"], ["b5a1", "窗窖童竣等策筆筐筒答筍筋筏筑粟粥絞結絨絕紫絮絲絡給絢絰絳善翔翕耋聒肅腕腔腋腑腎脹腆脾腌腓腴舒舜菩萃菸萍菠菅萋菁華菱菴著萊菰萌菌菽菲菊萸萎萄菜萇菔菟虛蛟蛙蛭蛔蛛蛤蛐蛞街裁裂袱覃視註詠評詞証詁"], ["b640", "詔詛詐詆訴診訶詖象貂貯貼貳貽賁費賀貴買貶貿貸越超趁跎距跋跚跑跌跛跆軻軸軼辜逮逵週逸進逶鄂郵鄉郾酣酥量鈔鈕鈣鈉鈞鈍鈐鈇鈑閔閏開閑"], ["b6a1", "間閒閎隊階隋陽隅隆隍陲隄雁雅雄集雇雯雲韌項順須飧飪飯飩飲飭馮馭黃黍黑亂傭債傲傳僅傾催傷傻傯僇剿剷剽募勦勤勢勣匯嗟嗨嗓嗦嗎嗜嗇嗑嗣嗤嗯嗚嗡嗅嗆嗥嗉園圓塞塑塘塗塚塔填塌塭塊塢塒塋奧嫁嫉嫌媾媽媼"], ["b740", "媳嫂媲嵩嵯幌幹廉廈弒彙徬微愚意慈感想愛惹愁愈慎慌慄慍愾愴愧愍愆愷戡戢搓搾搞搪搭搽搬搏搜搔損搶搖搗搆敬斟新暗暉暇暈暖暄暘暍會榔業"], ["b7a1", "楚楷楠楔極椰概楊楨楫楞楓楹榆楝楣楛歇歲毀殿毓毽溢溯滓溶滂源溝滇滅溥溘溼溺溫滑準溜滄滔溪溧溴煎煙煩煤煉照煜煬煦煌煥煞煆煨煖爺牒猷獅猿猾瑯瑚瑕瑟瑞瑁琿瑙瑛瑜當畸瘀痰瘁痲痱痺痿痴痳盞盟睛睫睦睞督"], ["b840", "睹睪睬睜睥睨睢矮碎碰碗碘碌碉硼碑碓硿祺祿禁萬禽稜稚稠稔稟稞窟窠筷節筠筮筧粱粳粵經絹綑綁綏絛置罩罪署義羨群聖聘肆肄腱腰腸腥腮腳腫"], ["b8a1", "腹腺腦舅艇蒂葷落萱葵葦葫葉葬葛萼萵葡董葩葭葆虞虜號蛹蜓蜈蜇蜀蛾蛻蜂蜃蜆蜊衙裟裔裙補裘裝裡裊裕裒覜解詫該詳試詩詰誇詼詣誠話誅詭詢詮詬詹詻訾詨豢貊貉賊資賈賄貲賃賂賅跡跟跨路跳跺跪跤跦躲較載軾輊"], ["b940", "辟農運遊道遂達逼違遐遇遏過遍遑逾遁鄒鄗酬酪酩釉鈷鉗鈸鈽鉀鈾鉛鉋鉤鉑鈴鉉鉍鉅鈹鈿鉚閘隘隔隕雍雋雉雊雷電雹零靖靴靶預頑頓頊頒頌飼飴"], ["b9a1", "飽飾馳馱馴髡鳩麂鼎鼓鼠僧僮僥僖僭僚僕像僑僱僎僩兢凳劃劂匱厭嗾嘀嘛嘗嗽嘔嘆嘉嘍嘎嗷嘖嘟嘈嘐嗶團圖塵塾境墓墊塹墅塽壽夥夢夤奪奩嫡嫦嫩嫗嫖嫘嫣孵寞寧寡寥實寨寢寤察對屢嶄嶇幛幣幕幗幔廓廖弊彆彰徹慇"], ["ba40", "愿態慷慢慣慟慚慘慵截撇摘摔撤摸摟摺摑摧搴摭摻敲斡旗旖暢暨暝榜榨榕槁榮槓構榛榷榻榫榴槐槍榭槌榦槃榣歉歌氳漳演滾漓滴漩漾漠漬漏漂漢"], ["baa1", "滿滯漆漱漸漲漣漕漫漯澈漪滬漁滲滌滷熔熙煽熊熄熒爾犒犖獄獐瑤瑣瑪瑰瑭甄疑瘧瘍瘋瘉瘓盡監瞄睽睿睡磁碟碧碳碩碣禎福禍種稱窪窩竭端管箕箋筵算箝箔箏箸箇箄粹粽精綻綰綜綽綾綠緊綴網綱綺綢綿綵綸維緒緇綬"], ["bb40", "罰翠翡翟聞聚肇腐膀膏膈膊腿膂臧臺與舔舞艋蓉蒿蓆蓄蒙蒞蒲蒜蓋蒸蓀蓓蒐蒼蓑蓊蜿蜜蜻蜢蜥蜴蜘蝕蜷蜩裳褂裴裹裸製裨褚裯誦誌語誣認誡誓誤"], ["bba1", "說誥誨誘誑誚誧豪貍貌賓賑賒赫趙趕跼輔輒輕輓辣遠遘遜遣遙遞遢遝遛鄙鄘鄞酵酸酷酴鉸銀銅銘銖鉻銓銜銨鉼銑閡閨閩閣閥閤隙障際雌雒需靼鞅韶頗領颯颱餃餅餌餉駁骯骰髦魁魂鳴鳶鳳麼鼻齊億儀僻僵價儂儈儉儅凜"], ["bc40", "劇劈劉劍劊勰厲嘮嘻嘹嘲嘿嘴嘩噓噎噗噴嘶嘯嘰墀墟增墳墜墮墩墦奭嬉嫻嬋嫵嬌嬈寮寬審寫層履嶝嶔幢幟幡廢廚廟廝廣廠彈影德徵慶慧慮慝慕憂"], ["bca1", "慼慰慫慾憧憐憫憎憬憚憤憔憮戮摩摯摹撞撲撈撐撰撥撓撕撩撒撮播撫撚撬撙撢撳敵敷數暮暫暴暱樣樟槨樁樞標槽模樓樊槳樂樅槭樑歐歎殤毅毆漿潼澄潑潦潔澆潭潛潸潮澎潺潰潤澗潘滕潯潠潟熟熬熱熨牖犛獎獗瑩璋璃"], ["bd40", "瑾璀畿瘠瘩瘟瘤瘦瘡瘢皚皺盤瞎瞇瞌瞑瞋磋磅確磊碾磕碼磐稿稼穀稽稷稻窯窮箭箱範箴篆篇篁箠篌糊締練緯緻緘緬緝編緣線緞緩綞緙緲緹罵罷羯"], ["bda1", "翩耦膛膜膝膠膚膘蔗蔽蔚蓮蔬蔭蔓蔑蔣蔡蔔蓬蔥蓿蔆螂蝴蝶蝠蝦蝸蝨蝙蝗蝌蝓衛衝褐複褒褓褕褊誼諒談諄誕請諸課諉諂調誰論諍誶誹諛豌豎豬賠賞賦賤賬賭賢賣賜質賡赭趟趣踫踐踝踢踏踩踟踡踞躺輝輛輟輩輦輪輜輞"], ["be40", "輥適遮遨遭遷鄰鄭鄧鄱醇醉醋醃鋅銻銷鋪銬鋤鋁銳銼鋒鋇鋰銲閭閱霄霆震霉靠鞍鞋鞏頡頫頜颳養餓餒餘駝駐駟駛駑駕駒駙骷髮髯鬧魅魄魷魯鴆鴉"], ["bea1", "鴃麩麾黎墨齒儒儘儔儐儕冀冪凝劑劓勳噙噫噹噩噤噸噪器噥噱噯噬噢噶壁墾壇壅奮嬝嬴學寰導彊憲憑憩憊懍憶憾懊懈戰擅擁擋撻撼據擄擇擂操撿擒擔撾整曆曉暹曄曇暸樽樸樺橙橫橘樹橄橢橡橋橇樵機橈歙歷氅濂澱澡"], ["bf40", "濃澤濁澧澳激澹澶澦澠澴熾燉燐燒燈燕熹燎燙燜燃燄獨璜璣璘璟璞瓢甌甍瘴瘸瘺盧盥瞠瞞瞟瞥磨磚磬磧禦積穎穆穌穋窺篙簑築篤篛篡篩篦糕糖縊"], ["bfa1", "縑縈縛縣縞縝縉縐罹羲翰翱翮耨膳膩膨臻興艘艙蕊蕙蕈蕨蕩蕃蕉蕭蕪蕞螃螟螞螢融衡褪褲褥褫褡親覦諦諺諫諱謀諜諧諮諾謁謂諷諭諳諶諼豫豭貓賴蹄踱踴蹂踹踵輻輯輸輳辨辦遵遴選遲遼遺鄴醒錠錶鋸錳錯錢鋼錫錄錚"], ["c040", "錐錦錡錕錮錙閻隧隨險雕霎霑霖霍霓霏靛靜靦鞘頰頸頻頷頭頹頤餐館餞餛餡餚駭駢駱骸骼髻髭鬨鮑鴕鴣鴦鴨鴒鴛默黔龍龜優償儡儲勵嚎嚀嚐嚅嚇"], ["c0a1", "嚏壕壓壑壎嬰嬪嬤孺尷屨嶼嶺嶽嶸幫彌徽應懂懇懦懋戲戴擎擊擘擠擰擦擬擱擢擭斂斃曙曖檀檔檄檢檜櫛檣橾檗檐檠歜殮毚氈濘濱濟濠濛濤濫濯澀濬濡濩濕濮濰燧營燮燦燥燭燬燴燠爵牆獰獲璩環璦璨癆療癌盪瞳瞪瞰瞬"], ["c140", "瞧瞭矯磷磺磴磯礁禧禪穗窿簇簍篾篷簌篠糠糜糞糢糟糙糝縮績繆縷縲繃縫總縱繅繁縴縹繈縵縿縯罄翳翼聱聲聰聯聳臆臃膺臂臀膿膽臉膾臨舉艱薪"], ["c1a1", "薄蕾薜薑薔薯薛薇薨薊虧蟀蟑螳蟒蟆螫螻螺蟈蟋褻褶襄褸褽覬謎謗謙講謊謠謝謄謐豁谿豳賺賽購賸賻趨蹉蹋蹈蹊轄輾轂轅輿避遽還邁邂邀鄹醣醞醜鍍鎂錨鍵鍊鍥鍋錘鍾鍬鍛鍰鍚鍔闊闋闌闈闆隱隸雖霜霞鞠韓顆颶餵騁"], ["c240", "駿鮮鮫鮪鮭鴻鴿麋黏點黜黝黛鼾齋叢嚕嚮壙壘嬸彝懣戳擴擲擾攆擺擻擷斷曜朦檳檬櫃檻檸櫂檮檯歟歸殯瀉瀋濾瀆濺瀑瀏燻燼燾燸獷獵璧璿甕癖癘"], ["c2a1", "癒瞽瞿瞻瞼礎禮穡穢穠竄竅簫簧簪簞簣簡糧織繕繞繚繡繒繙罈翹翻職聶臍臏舊藏薩藍藐藉薰薺薹薦蟯蟬蟲蟠覆覲觴謨謹謬謫豐贅蹙蹣蹦蹤蹟蹕軀轉轍邇邃邈醫醬釐鎔鎊鎖鎢鎳鎮鎬鎰鎘鎚鎗闔闖闐闕離雜雙雛雞霤鞣鞦"], ["c340", "鞭韹額顏題顎顓颺餾餿餽餮馥騎髁鬃鬆魏魎魍鯊鯉鯽鯈鯀鵑鵝鵠黠鼕鼬儳嚥壞壟壢寵龐廬懲懷懶懵攀攏曠曝櫥櫝櫚櫓瀛瀟瀨瀚瀝瀕瀘爆爍牘犢獸"], ["c3a1", "獺璽瓊瓣疇疆癟癡矇礙禱穫穩簾簿簸簽簷籀繫繭繹繩繪羅繳羶羹羸臘藩藝藪藕藤藥藷蟻蠅蠍蟹蟾襠襟襖襞譁譜識證譚譎譏譆譙贈贊蹼蹲躇蹶蹬蹺蹴轔轎辭邊邋醱醮鏡鏑鏟鏃鏈鏜鏝鏖鏢鏍鏘鏤鏗鏨關隴難霪霧靡韜韻類"], ["c440", "願顛颼饅饉騖騙鬍鯨鯧鯖鯛鶉鵡鵲鵪鵬麒麗麓麴勸嚨嚷嚶嚴嚼壤孀孃孽寶巉懸懺攘攔攙曦朧櫬瀾瀰瀲爐獻瓏癢癥礦礪礬礫竇競籌籃籍糯糰辮繽繼"], ["c4a1", "纂罌耀臚艦藻藹蘑藺蘆蘋蘇蘊蠔蠕襤覺觸議譬警譯譟譫贏贍躉躁躅躂醴釋鐘鐃鏽闡霰飄饒饑馨騫騰騷騵鰓鰍鹹麵黨鼯齟齣齡儷儸囁囀囂夔屬巍懼懾攝攜斕曩櫻欄櫺殲灌爛犧瓖瓔癩矓籐纏續羼蘗蘭蘚蠣蠢蠡蠟襪襬覽譴"], ["c540", "護譽贓躊躍躋轟辯醺鐮鐳鐵鐺鐸鐲鐫闢霸霹露響顧顥饗驅驃驀騾髏魔魑鰭鰥鶯鶴鷂鶸麝黯鼙齜齦齧儼儻囈囊囉孿巔巒彎懿攤權歡灑灘玀瓤疊癮癬"], ["c5a1", "禳籠籟聾聽臟襲襯觼讀贖贗躑躓轡酈鑄鑑鑒霽霾韃韁顫饕驕驍髒鬚鱉鰱鰾鰻鷓鷗鼴齬齪龔囌巖戀攣攫攪曬欐瓚竊籤籣籥纓纖纔臢蘸蘿蠱變邐邏鑣鑠鑤靨顯饜驚驛驗髓體髑鱔鱗鱖鷥麟黴囑壩攬灞癱癲矗罐羈蠶蠹衢讓讒"], ["c640", "讖艷贛釀鑪靂靈靄韆顰驟鬢魘鱟鷹鷺鹼鹽鼇齷齲廳欖灣籬籮蠻觀躡釁鑲鑰顱饞髖鬣黌灤矚讚鑷韉驢驥纜讜躪釅鑽鑾鑼鱷鱸黷豔鑿鸚爨驪鬱鸛鸞籲"], ["c940", "乂乜凵匚厂万丌乇亍囗兀屮彳丏冇与丮亓仂仉仈冘勼卬厹圠夃夬尐巿旡殳毌气爿丱丼仨仜仩仡仝仚刌匜卌圢圣夗夯宁宄尒尻屴屳帄庀庂忉戉扐氕"], ["c9a1", "氶汃氿氻犮犰玊禸肊阞伎优伬仵伔仱伀价伈伝伂伅伢伓伄仴伒冱刓刉刐劦匢匟卍厊吇囡囟圮圪圴夼妀奼妅奻奾奷奿孖尕尥屼屺屻屾巟幵庄异弚彴忕忔忏扜扞扤扡扦扢扙扠扚扥旯旮朾朹朸朻机朿朼朳氘汆汒汜汏汊汔汋"], ["ca40", "汌灱牞犴犵玎甪癿穵网艸艼芀艽艿虍襾邙邗邘邛邔阢阤阠阣佖伻佢佉体佤伾佧佒佟佁佘伭伳伿佡冏冹刜刞刡劭劮匉卣卲厎厏吰吷吪呔呅吙吜吥吘"], ["caa1", "吽呏呁吨吤呇囮囧囥坁坅坌坉坋坒夆奀妦妘妠妗妎妢妐妏妧妡宎宒尨尪岍岏岈岋岉岒岊岆岓岕巠帊帎庋庉庌庈庍弅弝彸彶忒忑忐忭忨忮忳忡忤忣忺忯忷忻怀忴戺抃抌抎抏抔抇扱扻扺扰抁抈扷扽扲扴攷旰旴旳旲旵杅杇"], ["cb40", "杙杕杌杈杝杍杚杋毐氙氚汸汧汫沄沋沏汱汯汩沚汭沇沕沜汦汳汥汻沎灴灺牣犿犽狃狆狁犺狅玕玗玓玔玒町甹疔疕皁礽耴肕肙肐肒肜芐芏芅芎芑芓"], ["cba1", "芊芃芄豸迉辿邟邡邥邞邧邠阰阨阯阭丳侘佼侅佽侀侇佶佴侉侄佷佌侗佪侚佹侁佸侐侜侔侞侒侂侕佫佮冞冼冾刵刲刳剆刱劼匊匋匼厒厔咇呿咁咑咂咈呫呺呾呥呬呴呦咍呯呡呠咘呣呧呤囷囹坯坲坭坫坱坰坶垀坵坻坳坴坢"], ["cc40", "坨坽夌奅妵妺姏姎妲姌姁妶妼姃姖妱妽姀姈妴姇孢孥宓宕屄屇岮岤岠岵岯岨岬岟岣岭岢岪岧岝岥岶岰岦帗帔帙弨弢弣弤彔徂彾彽忞忥怭怦怙怲怋"], ["cca1", "怴怊怗怳怚怞怬怢怍怐怮怓怑怌怉怜戔戽抭抴拑抾抪抶拊抮抳抯抻抩抰抸攽斨斻昉旼昄昒昈旻昃昋昍昅旽昑昐曶朊枅杬枎枒杶杻枘枆构杴枍枌杺枟枑枙枃杽极杸杹枔欥殀歾毞氝沓泬泫泮泙沶泔沭泧沷泐泂沺泃泆泭泲"], ["cd40", "泒泝沴沊沝沀泞泀洰泍泇沰泹泏泩泑炔炘炅炓炆炄炑炖炂炚炃牪狖狋狘狉狜狒狔狚狌狑玤玡玭玦玢玠玬玝瓝瓨甿畀甾疌疘皯盳盱盰盵矸矼矹矻矺"], ["cda1", "矷祂礿秅穸穻竻籵糽耵肏肮肣肸肵肭舠芠苀芫芚芘芛芵芧芮芼芞芺芴芨芡芩苂芤苃芶芢虰虯虭虮豖迒迋迓迍迖迕迗邲邴邯邳邰阹阽阼阺陃俍俅俓侲俉俋俁俔俜俙侻侳俛俇俖侺俀侹俬剄剉勀勂匽卼厗厖厙厘咺咡咭咥哏"], ["ce40", "哃茍咷咮哖咶哅哆咠呰咼咢咾呲哞咰垵垞垟垤垌垗垝垛垔垘垏垙垥垚垕壴复奓姡姞姮娀姱姝姺姽姼姶姤姲姷姛姩姳姵姠姾姴姭宨屌峐峘峌峗峋峛"], ["cea1", "峞峚峉峇峊峖峓峔峏峈峆峎峟峸巹帡帢帣帠帤庰庤庢庛庣庥弇弮彖徆怷怹恔恲恞恅恓恇恉恛恌恀恂恟怤恄恘恦恮扂扃拏挍挋拵挎挃拫拹挏挌拸拶挀挓挔拺挕拻拰敁敃斪斿昶昡昲昵昜昦昢昳昫昺昝昴昹昮朏朐柁柲柈枺"], ["cf40", "柜枻柸柘柀枷柅柫柤柟枵柍枳柷柶柮柣柂枹柎柧柰枲柼柆柭柌枮柦柛柺柉柊柃柪柋欨殂殄殶毖毘毠氠氡洨洴洭洟洼洿洒洊泚洳洄洙洺洚洑洀洝浂"], ["cfa1", "洁洘洷洃洏浀洇洠洬洈洢洉洐炷炟炾炱炰炡炴炵炩牁牉牊牬牰牳牮狊狤狨狫狟狪狦狣玅珌珂珈珅玹玶玵玴珫玿珇玾珃珆玸珋瓬瓮甮畇畈疧疪癹盄眈眃眄眅眊盷盻盺矧矨砆砑砒砅砐砏砎砉砃砓祊祌祋祅祄秕种秏秖秎窀"], ["d040", "穾竑笀笁籺籸籹籿粀粁紃紈紁罘羑羍羾耇耎耏耔耷胘胇胠胑胈胂胐胅胣胙胜胊胕胉胏胗胦胍臿舡芔苙苾苹茇苨茀苕茺苫苖苴苬苡苲苵茌苻苶苰苪"], ["d0a1", "苤苠苺苳苭虷虴虼虳衁衎衧衪衩觓訄訇赲迣迡迮迠郱邽邿郕郅邾郇郋郈釔釓陔陏陑陓陊陎倞倅倇倓倢倰倛俵俴倳倷倬俶俷倗倜倠倧倵倯倱倎党冔冓凊凄凅凈凎剡剚剒剞剟剕剢勍匎厞唦哢唗唒哧哳哤唚哿唄唈哫唑唅哱"], ["d140", "唊哻哷哸哠唎唃唋圁圂埌堲埕埒垺埆垽垼垸垶垿埇埐垹埁夎奊娙娖娭娮娕娏娗娊娞娳孬宧宭宬尃屖屔峬峿峮峱峷崀峹帩帨庨庮庪庬弳弰彧恝恚恧"], ["d1a1", "恁悢悈悀悒悁悝悃悕悛悗悇悜悎戙扆拲挐捖挬捄捅挶捃揤挹捋捊挼挩捁挴捘捔捙挭捇挳捚捑挸捗捀捈敊敆旆旃旄旂晊晟晇晑朒朓栟栚桉栲栳栻桋桏栖栱栜栵栫栭栯桎桄栴栝栒栔栦栨栮桍栺栥栠欬欯欭欱欴歭肂殈毦毤"], ["d240", "毨毣毢毧氥浺浣浤浶洍浡涒浘浢浭浯涑涍淯浿涆浞浧浠涗浰浼浟涂涘洯浨涋浾涀涄洖涃浻浽浵涐烜烓烑烝烋缹烢烗烒烞烠烔烍烅烆烇烚烎烡牂牸"], ["d2a1", "牷牶猀狺狴狾狶狳狻猁珓珙珥珖玼珧珣珩珜珒珛珔珝珚珗珘珨瓞瓟瓴瓵甡畛畟疰痁疻痄痀疿疶疺皊盉眝眛眐眓眒眣眑眕眙眚眢眧砣砬砢砵砯砨砮砫砡砩砳砪砱祔祛祏祜祓祒祑秫秬秠秮秭秪秜秞秝窆窉窅窋窌窊窇竘笐"], ["d340", "笄笓笅笏笈笊笎笉笒粄粑粊粌粈粍粅紞紝紑紎紘紖紓紟紒紏紌罜罡罞罠罝罛羖羒翃翂翀耖耾耹胺胲胹胵脁胻脀舁舯舥茳茭荄茙荑茥荖茿荁茦茜茢"], ["d3a1", "荂荎茛茪茈茼荍茖茤茠茷茯茩荇荅荌荓茞茬荋茧荈虓虒蚢蚨蚖蚍蚑蚞蚇蚗蚆蚋蚚蚅蚥蚙蚡蚧蚕蚘蚎蚝蚐蚔衃衄衭衵衶衲袀衱衿衯袃衾衴衼訒豇豗豻貤貣赶赸趵趷趶軑軓迾迵适迿迻逄迼迶郖郠郙郚郣郟郥郘郛郗郜郤酐"], ["d440", "酎酏釕釢釚陜陟隼飣髟鬯乿偰偪偡偞偠偓偋偝偲偈偍偁偛偊偢倕偅偟偩偫偣偤偆偀偮偳偗偑凐剫剭剬剮勖勓匭厜啵啶唼啍啐唴唪啑啢唶唵唰啒啅"], ["d4a1", "唌唲啥啎唹啈唭唻啀啋圊圇埻堔埢埶埜埴堀埭埽堈埸堋埳埏堇埮埣埲埥埬埡堎埼堐埧堁堌埱埩埰堍堄奜婠婘婕婧婞娸娵婭婐婟婥婬婓婤婗婃婝婒婄婛婈媎娾婍娹婌婰婩婇婑婖婂婜孲孮寁寀屙崞崋崝崚崠崌崨崍崦崥崏"], ["d540", "崰崒崣崟崮帾帴庱庴庹庲庳弶弸徛徖徟悊悐悆悾悰悺惓惔惏惤惙惝惈悱惛悷惊悿惃惍惀挲捥掊掂捽掽掞掭掝掗掫掎捯掇掐据掯捵掜捭掮捼掤挻掟"], ["d5a1", "捸掅掁掑掍捰敓旍晥晡晛晙晜晢朘桹梇梐梜桭桮梮梫楖桯梣梬梩桵桴梲梏桷梒桼桫桲梪梀桱桾梛梖梋梠梉梤桸桻梑梌梊桽欶欳欷欸殑殏殍殎殌氪淀涫涴涳湴涬淩淢涷淶淔渀淈淠淟淖涾淥淜淝淛淴淊涽淭淰涺淕淂淏淉"], ["d640", "淐淲淓淽淗淍淣涻烺焍烷焗烴焌烰焄烳焐烼烿焆焓焀烸烶焋焂焎牾牻牼牿猝猗猇猑猘猊猈狿猏猞玈珶珸珵琄琁珽琇琀珺珼珿琌琋珴琈畤畣痎痒痏"], ["d6a1", "痋痌痑痐皏皉盓眹眯眭眱眲眴眳眽眥眻眵硈硒硉硍硊硌砦硅硐祤祧祩祪祣祫祡离秺秸秶秷窏窔窐笵筇笴笥笰笢笤笳笘笪笝笱笫笭笯笲笸笚笣粔粘粖粣紵紽紸紶紺絅紬紩絁絇紾紿絊紻紨罣羕羜羝羛翊翋翍翐翑翇翏翉耟"], ["d740", "耞耛聇聃聈脘脥脙脛脭脟脬脞脡脕脧脝脢舑舸舳舺舴舲艴莐莣莨莍荺荳莤荴莏莁莕莙荵莔莩荽莃莌莝莛莪莋荾莥莯莈莗莰荿莦莇莮荶莚虙虖蚿蚷"], ["d7a1", "蛂蛁蛅蚺蚰蛈蚹蚳蚸蛌蚴蚻蚼蛃蚽蚾衒袉袕袨袢袪袚袑袡袟袘袧袙袛袗袤袬袌袓袎覂觖觙觕訰訧訬訞谹谻豜豝豽貥赽赻赹趼跂趹趿跁軘軞軝軜軗軠軡逤逋逑逜逌逡郯郪郰郴郲郳郔郫郬郩酖酘酚酓酕釬釴釱釳釸釤釹釪"], ["d840", "釫釷釨釮镺閆閈陼陭陫陱陯隿靪頄飥馗傛傕傔傞傋傣傃傌傎傝偨傜傒傂傇兟凔匒匑厤厧喑喨喥喭啷噅喢喓喈喏喵喁喣喒喤啽喌喦啿喕喡喎圌堩堷"], ["d8a1", "堙堞堧堣堨埵塈堥堜堛堳堿堶堮堹堸堭堬堻奡媯媔媟婺媢媞婸媦婼媥媬媕媮娷媄媊媗媃媋媩婻婽媌媜媏媓媝寪寍寋寔寑寊寎尌尰崷嵃嵫嵁嵋崿崵嵑嵎嵕崳崺嵒崽崱嵙嵂崹嵉崸崼崲崶嵀嵅幄幁彘徦徥徫惉悹惌惢惎惄愔"], ["d940", "惲愊愖愅惵愓惸惼惾惁愃愘愝愐惿愄愋扊掔掱掰揎揥揨揯揃撝揳揊揠揶揕揲揵摡揟掾揝揜揄揘揓揂揇揌揋揈揰揗揙攲敧敪敤敜敨敥斌斝斞斮旐旒"], ["d9a1", "晼晬晻暀晱晹晪晲朁椌棓椄棜椪棬棪棱椏棖棷棫棤棶椓椐棳棡椇棌椈楰梴椑棯棆椔棸棐棽棼棨椋椊椗棎棈棝棞棦棴棑椆棔棩椕椥棇欹欻欿欼殔殗殙殕殽毰毲毳氰淼湆湇渟湉溈渼渽湅湢渫渿湁湝湳渜渳湋湀湑渻渃渮湞"], ["da40", "湨湜湡渱渨湠湱湫渹渢渰湓湥渧湸湤湷湕湹湒湦渵渶湚焠焞焯烻焮焱焣焥焢焲焟焨焺焛牋牚犈犉犆犅犋猒猋猰猢猱猳猧猲猭猦猣猵猌琮琬琰琫琖"], ["daa1", "琚琡琭琱琤琣琝琩琠琲瓻甯畯畬痧痚痡痦痝痟痤痗皕皒盚睆睇睄睍睅睊睎睋睌矞矬硠硤硥硜硭硱硪确硰硩硨硞硢祴祳祲祰稂稊稃稌稄窙竦竤筊笻筄筈筌筎筀筘筅粢粞粨粡絘絯絣絓絖絧絪絏絭絜絫絒絔絩絑絟絎缾缿罥"], ["db40", "罦羢羠羡翗聑聏聐胾胔腃腊腒腏腇脽腍脺臦臮臷臸臹舄舼舽舿艵茻菏菹萣菀菨萒菧菤菼菶萐菆菈菫菣莿萁菝菥菘菿菡菋菎菖菵菉萉萏菞萑萆菂菳"], ["dba1", "菕菺菇菑菪萓菃菬菮菄菻菗菢萛菛菾蛘蛢蛦蛓蛣蛚蛪蛝蛫蛜蛬蛩蛗蛨蛑衈衖衕袺裗袹袸裀袾袶袼袷袽袲褁裉覕覘覗觝觚觛詎詍訹詙詀詗詘詄詅詒詈詑詊詌詏豟貁貀貺貾貰貹貵趄趀趉跘跓跍跇跖跜跏跕跙跈跗跅軯軷軺"], ["dc40", "軹軦軮軥軵軧軨軶軫軱軬軴軩逭逴逯鄆鄬鄄郿郼鄈郹郻鄁鄀鄇鄅鄃酡酤酟酢酠鈁鈊鈥鈃鈚鈦鈏鈌鈀鈒釿釽鈆鈄鈧鈂鈜鈤鈙鈗鈅鈖镻閍閌閐隇陾隈"], ["dca1", "隉隃隀雂雈雃雱雰靬靰靮頇颩飫鳦黹亃亄亶傽傿僆傮僄僊傴僈僂傰僁傺傱僋僉傶傸凗剺剸剻剼嗃嗛嗌嗐嗋嗊嗝嗀嗔嗄嗩喿嗒喍嗏嗕嗢嗖嗈嗲嗍嗙嗂圔塓塨塤塏塍塉塯塕塎塝塙塥塛堽塣塱壼嫇嫄嫋媺媸媱媵媰媿嫈媻嫆"], ["dd40", "媷嫀嫊媴媶嫍媹媐寖寘寙尟尳嵱嵣嵊嵥嵲嵬嵞嵨嵧嵢巰幏幎幊幍幋廅廌廆廋廇彀徯徭惷慉慊愫慅愶愲愮慆愯慏愩慀戠酨戣戥戤揅揱揫搐搒搉搠搤"], ["dda1", "搳摃搟搕搘搹搷搢搣搌搦搰搨摁搵搯搊搚摀搥搧搋揧搛搮搡搎敯斒旓暆暌暕暐暋暊暙暔晸朠楦楟椸楎楢楱椿楅楪椹楂楗楙楺楈楉椵楬椳椽楥棰楸椴楩楀楯楄楶楘楁楴楌椻楋椷楜楏楑椲楒椯楻椼歆歅歃歂歈歁殛嗀毻毼"], ["de40", "毹毷毸溛滖滈溏滀溟溓溔溠溱溹滆滒溽滁溞滉溷溰滍溦滏溲溾滃滜滘溙溒溎溍溤溡溿溳滐滊溗溮溣煇煔煒煣煠煁煝煢煲煸煪煡煂煘煃煋煰煟煐煓"], ["dea1", "煄煍煚牏犍犌犑犐犎猼獂猻猺獀獊獉瑄瑊瑋瑒瑑瑗瑀瑏瑐瑎瑂瑆瑍瑔瓡瓿瓾瓽甝畹畷榃痯瘏瘃痷痾痼痹痸瘐痻痶痭痵痽皙皵盝睕睟睠睒睖睚睩睧睔睙睭矠碇碚碔碏碄碕碅碆碡碃硹碙碀碖硻祼禂祽祹稑稘稙稒稗稕稢稓"], ["df40", "稛稐窣窢窞竫筦筤筭筴筩筲筥筳筱筰筡筸筶筣粲粴粯綈綆綀綍絿綅絺綎絻綃絼綌綔綄絽綒罭罫罧罨罬羦羥羧翛翜耡腤腠腷腜腩腛腢腲朡腞腶腧腯"], ["dfa1", "腄腡舝艉艄艀艂艅蓱萿葖葶葹蒏蒍葥葑葀蒆葧萰葍葽葚葙葴葳葝蔇葞萷萺萴葺葃葸萲葅萩菙葋萯葂萭葟葰萹葎葌葒葯蓅蒎萻葇萶萳葨葾葄萫葠葔葮葐蜋蜄蛷蜌蛺蛖蛵蝍蛸蜎蜉蜁蛶蜍蜅裖裋裍裎裞裛裚裌裐覅覛觟觥觤"], ["e040", "觡觠觢觜触詶誆詿詡訿詷誂誄詵誃誁詴詺谼豋豊豥豤豦貆貄貅賌赨赩趑趌趎趏趍趓趔趐趒跰跠跬跱跮跐跩跣跢跧跲跫跴輆軿輁輀輅輇輈輂輋遒逿"], ["e0a1", "遄遉逽鄐鄍鄏鄑鄖鄔鄋鄎酮酯鉈鉒鈰鈺鉦鈳鉥鉞銃鈮鉊鉆鉭鉬鉏鉠鉧鉯鈶鉡鉰鈱鉔鉣鉐鉲鉎鉓鉌鉖鈲閟閜閞閛隒隓隑隗雎雺雽雸雵靳靷靸靲頏頍頎颬飶飹馯馲馰馵骭骫魛鳪鳭鳧麀黽僦僔僗僨僳僛僪僝僤僓僬僰僯僣僠"], ["e140", "凘劀劁勩勫匰厬嘧嘕嘌嘒嗼嘏嘜嘁嘓嘂嗺嘝嘄嗿嗹墉塼墐墘墆墁塿塴墋塺墇墑墎塶墂墈塻墔墏壾奫嫜嫮嫥嫕嫪嫚嫭嫫嫳嫢嫠嫛嫬嫞嫝嫙嫨嫟孷寠"], ["e1a1", "寣屣嶂嶀嵽嶆嵺嶁嵷嶊嶉嶈嵾嵼嶍嵹嵿幘幙幓廘廑廗廎廜廕廙廒廔彄彃彯徶愬愨慁慞慱慳慒慓慲慬憀慴慔慺慛慥愻慪慡慖戩戧戫搫摍摛摝摴摶摲摳摽摵摦撦摎撂摞摜摋摓摠摐摿搿摬摫摙摥摷敳斠暡暠暟朅朄朢榱榶槉"], ["e240", "榠槎榖榰榬榼榑榙榎榧榍榩榾榯榿槄榽榤槔榹槊榚槏榳榓榪榡榞槙榗榐槂榵榥槆歊歍歋殞殟殠毃毄毾滎滵滱漃漥滸漷滻漮漉潎漙漚漧漘漻漒滭漊"], ["e2a1", "漶潳滹滮漭潀漰漼漵滫漇漎潃漅滽滶漹漜滼漺漟漍漞漈漡熇熐熉熀熅熂熏煻熆熁熗牄牓犗犕犓獃獍獑獌瑢瑳瑱瑵瑲瑧瑮甀甂甃畽疐瘖瘈瘌瘕瘑瘊瘔皸瞁睼瞅瞂睮瞀睯睾瞃碲碪碴碭碨硾碫碞碥碠碬碢碤禘禊禋禖禕禔禓"], ["e340", "禗禈禒禐稫穊稰稯稨稦窨窫窬竮箈箜箊箑箐箖箍箌箛箎箅箘劄箙箤箂粻粿粼粺綧綷緂綣綪緁緀緅綝緎緄緆緋緌綯綹綖綼綟綦綮綩綡緉罳翢翣翥翞"], ["e3a1", "耤聝聜膉膆膃膇膍膌膋舕蒗蒤蒡蒟蒺蓎蓂蒬蒮蒫蒹蒴蓁蓍蒪蒚蒱蓐蒝蒧蒻蒢蒔蓇蓌蒛蒩蒯蒨蓖蒘蒶蓏蒠蓗蓔蓒蓛蒰蒑虡蜳蜣蜨蝫蝀蜮蜞蜡蜙蜛蝃蜬蝁蜾蝆蜠蜲蜪蜭蜼蜒蜺蜱蜵蝂蜦蜧蜸蜤蜚蜰蜑裷裧裱裲裺裾裮裼裶裻"], ["e440", "裰裬裫覝覡覟覞觩觫觨誫誙誋誒誏誖谽豨豩賕賏賗趖踉踂跿踍跽踊踃踇踆踅跾踀踄輐輑輎輍鄣鄜鄠鄢鄟鄝鄚鄤鄡鄛酺酲酹酳銥銤鉶銛鉺銠銔銪銍"], ["e4a1", "銦銚銫鉹銗鉿銣鋮銎銂銕銢鉽銈銡銊銆銌銙銧鉾銇銩銝銋鈭隞隡雿靘靽靺靾鞃鞀鞂靻鞄鞁靿韎韍頖颭颮餂餀餇馝馜駃馹馻馺駂馽駇骱髣髧鬾鬿魠魡魟鳱鳲鳵麧僿儃儰僸儆儇僶僾儋儌僽儊劋劌勱勯噈噂噌嘵噁噊噉噆噘"], ["e540", "噚噀嘳嘽嘬嘾嘸嘪嘺圚墫墝墱墠墣墯墬墥墡壿嫿嫴嫽嫷嫶嬃嫸嬂嫹嬁嬇嬅嬏屧嶙嶗嶟嶒嶢嶓嶕嶠嶜嶡嶚嶞幩幝幠幜緳廛廞廡彉徲憋憃慹憱憰憢憉"], ["e5a1", "憛憓憯憭憟憒憪憡憍慦憳戭摮摰撖撠撅撗撜撏撋撊撌撣撟摨撱撘敶敺敹敻斲斳暵暰暩暲暷暪暯樀樆樗槥槸樕槱槤樠槿槬槢樛樝槾樧槲槮樔槷槧橀樈槦槻樍槼槫樉樄樘樥樏槶樦樇槴樖歑殥殣殢殦氁氀毿氂潁漦潾澇濆澒"], ["e640", "澍澉澌潢潏澅潚澖潶潬澂潕潲潒潐潗澔澓潝漀潡潫潽潧澐潓澋潩潿澕潣潷潪潻熲熯熛熰熠熚熩熵熝熥熞熤熡熪熜熧熳犘犚獘獒獞獟獠獝獛獡獚獙"], ["e6a1", "獢璇璉璊璆璁瑽璅璈瑼瑹甈甇畾瘥瘞瘙瘝瘜瘣瘚瘨瘛皜皝皞皛瞍瞏瞉瞈磍碻磏磌磑磎磔磈磃磄磉禚禡禠禜禢禛歶稹窲窴窳箷篋箾箬篎箯箹篊箵糅糈糌糋緷緛緪緧緗緡縃緺緦緶緱緰緮緟罶羬羰羭翭翫翪翬翦翨聤聧膣膟"], ["e740", "膞膕膢膙膗舖艏艓艒艐艎艑蔤蔻蔏蔀蔩蔎蔉蔍蔟蔊蔧蔜蓻蔫蓺蔈蔌蓴蔪蓲蔕蓷蓫蓳蓼蔒蓪蓩蔖蓾蔨蔝蔮蔂蓽蔞蓶蔱蔦蓧蓨蓰蓯蓹蔘蔠蔰蔋蔙蔯虢"], ["e7a1", "蝖蝣蝤蝷蟡蝳蝘蝔蝛蝒蝡蝚蝑蝞蝭蝪蝐蝎蝟蝝蝯蝬蝺蝮蝜蝥蝏蝻蝵蝢蝧蝩衚褅褌褔褋褗褘褙褆褖褑褎褉覢覤覣觭觰觬諏諆誸諓諑諔諕誻諗誾諀諅諘諃誺誽諙谾豍貏賥賟賙賨賚賝賧趠趜趡趛踠踣踥踤踮踕踛踖踑踙踦踧"], ["e840", "踔踒踘踓踜踗踚輬輤輘輚輠輣輖輗遳遰遯遧遫鄯鄫鄩鄪鄲鄦鄮醅醆醊醁醂醄醀鋐鋃鋄鋀鋙銶鋏鋱鋟鋘鋩鋗鋝鋌鋯鋂鋨鋊鋈鋎鋦鋍鋕鋉鋠鋞鋧鋑鋓"], ["e8a1", "銵鋡鋆銴镼閬閫閮閰隤隢雓霅霈霂靚鞊鞎鞈韐韏頞頝頦頩頨頠頛頧颲餈飺餑餔餖餗餕駜駍駏駓駔駎駉駖駘駋駗駌骳髬髫髳髲髱魆魃魧魴魱魦魶魵魰魨魤魬鳼鳺鳽鳿鳷鴇鴀鳹鳻鴈鴅鴄麃黓鼏鼐儜儓儗儚儑凞匴叡噰噠噮"], ["e940", "噳噦噣噭噲噞噷圜圛壈墽壉墿墺壂墼壆嬗嬙嬛嬡嬔嬓嬐嬖嬨嬚嬠嬞寯嶬嶱嶩嶧嶵嶰嶮嶪嶨嶲嶭嶯嶴幧幨幦幯廩廧廦廨廥彋徼憝憨憖懅憴懆懁懌憺"], ["e9a1", "憿憸憌擗擖擐擏擉撽撉擃擛擳擙攳敿敼斢曈暾曀曊曋曏暽暻暺曌朣樴橦橉橧樲橨樾橝橭橶橛橑樨橚樻樿橁橪橤橐橏橔橯橩橠樼橞橖橕橍橎橆歕歔歖殧殪殫毈毇氄氃氆澭濋澣濇澼濎濈潞濄澽澞濊澨瀄澥澮澺澬澪濏澿澸"], ["ea40", "澢濉澫濍澯澲澰燅燂熿熸燖燀燁燋燔燊燇燏熽燘熼燆燚燛犝犞獩獦獧獬獥獫獪瑿璚璠璔璒璕璡甋疀瘯瘭瘱瘽瘳瘼瘵瘲瘰皻盦瞚瞝瞡瞜瞛瞢瞣瞕瞙"], ["eaa1", "瞗磝磩磥磪磞磣磛磡磢磭磟磠禤穄穈穇窶窸窵窱窷篞篣篧篝篕篥篚篨篹篔篪篢篜篫篘篟糒糔糗糐糑縒縡縗縌縟縠縓縎縜縕縚縢縋縏縖縍縔縥縤罃罻罼罺羱翯耪耩聬膱膦膮膹膵膫膰膬膴膲膷膧臲艕艖艗蕖蕅蕫蕍蕓蕡蕘"], ["eb40", "蕀蕆蕤蕁蕢蕄蕑蕇蕣蔾蕛蕱蕎蕮蕵蕕蕧蕠薌蕦蕝蕔蕥蕬虣虥虤螛螏螗螓螒螈螁螖螘蝹螇螣螅螐螑螝螄螔螜螚螉褞褦褰褭褮褧褱褢褩褣褯褬褟觱諠"], ["eba1", "諢諲諴諵諝謔諤諟諰諈諞諡諨諿諯諻貑貒貐賵賮賱賰賳赬赮趥趧踳踾踸蹀蹅踶踼踽蹁踰踿躽輶輮輵輲輹輷輴遶遹遻邆郺鄳鄵鄶醓醐醑醍醏錧錞錈錟錆錏鍺錸錼錛錣錒錁鍆錭錎錍鋋錝鋺錥錓鋹鋷錴錂錤鋿錩錹錵錪錔錌"], ["ec40", "錋鋾錉錀鋻錖閼闍閾閹閺閶閿閵閽隩雔霋霒霐鞙鞗鞔韰韸頵頯頲餤餟餧餩馞駮駬駥駤駰駣駪駩駧骹骿骴骻髶髺髹髷鬳鮀鮅鮇魼魾魻鮂鮓鮒鮐魺鮕"], ["eca1", "魽鮈鴥鴗鴠鴞鴔鴩鴝鴘鴢鴐鴙鴟麈麆麇麮麭黕黖黺鼒鼽儦儥儢儤儠儩勴嚓嚌嚍嚆嚄嚃噾嚂噿嚁壖壔壏壒嬭嬥嬲嬣嬬嬧嬦嬯嬮孻寱寲嶷幬幪徾徻懃憵憼懧懠懥懤懨懞擯擩擣擫擤擨斁斀斶旚曒檍檖檁檥檉檟檛檡檞檇檓檎"], ["ed40", "檕檃檨檤檑橿檦檚檅檌檒歛殭氉濌澩濴濔濣濜濭濧濦濞濲濝濢濨燡燱燨燲燤燰燢獳獮獯璗璲璫璐璪璭璱璥璯甐甑甒甏疄癃癈癉癇皤盩瞵瞫瞲瞷瞶"], ["eda1", "瞴瞱瞨矰磳磽礂磻磼磲礅磹磾礄禫禨穜穛穖穘穔穚窾竀竁簅簏篲簀篿篻簎篴簋篳簂簉簃簁篸篽簆篰篱簐簊糨縭縼繂縳顈縸縪繉繀繇縩繌縰縻縶繄縺罅罿罾罽翴翲耬膻臄臌臊臅臇膼臩艛艚艜薃薀薏薧薕薠薋薣蕻薤薚薞"], ["ee40", "蕷蕼薉薡蕺蕸蕗薎薖薆薍薙薝薁薢薂薈薅蕹蕶薘薐薟虨螾螪螭蟅螰螬螹螵螼螮蟉蟃蟂蟌螷螯蟄蟊螴螶螿螸螽蟞螲褵褳褼褾襁襒褷襂覭覯覮觲觳謞"], ["eea1", "謘謖謑謅謋謢謏謒謕謇謍謈謆謜謓謚豏豰豲豱豯貕貔賹赯蹎蹍蹓蹐蹌蹇轃轀邅遾鄸醚醢醛醙醟醡醝醠鎡鎃鎯鍤鍖鍇鍼鍘鍜鍶鍉鍐鍑鍠鍭鎏鍌鍪鍹鍗鍕鍒鍏鍱鍷鍻鍡鍞鍣鍧鎀鍎鍙闇闀闉闃闅閷隮隰隬霠霟霘霝霙鞚鞡鞜"], ["ef40", "鞞鞝韕韔韱顁顄顊顉顅顃餥餫餬餪餳餲餯餭餱餰馘馣馡騂駺駴駷駹駸駶駻駽駾駼騃骾髾髽鬁髼魈鮚鮨鮞鮛鮦鮡鮥鮤鮆鮢鮠鮯鴳鵁鵧鴶鴮鴯鴱鴸鴰"], ["efa1", "鵅鵂鵃鴾鴷鵀鴽翵鴭麊麉麍麰黈黚黻黿鼤鼣鼢齔龠儱儭儮嚘嚜嚗嚚嚝嚙奰嬼屩屪巀幭幮懘懟懭懮懱懪懰懫懖懩擿攄擽擸攁攃擼斔旛曚曛曘櫅檹檽櫡櫆檺檶檷櫇檴檭歞毉氋瀇瀌瀍瀁瀅瀔瀎濿瀀濻瀦濼濷瀊爁燿燹爃燽獶"], ["f040", "璸瓀璵瓁璾璶璻瓂甔甓癜癤癙癐癓癗癚皦皽盬矂瞺磿礌礓礔礉礐礒礑禭禬穟簜簩簙簠簟簭簝簦簨簢簥簰繜繐繖繣繘繢繟繑繠繗繓羵羳翷翸聵臑臒"], ["f0a1", "臐艟艞薴藆藀藃藂薳薵薽藇藄薿藋藎藈藅薱薶藒蘤薸薷薾虩蟧蟦蟢蟛蟫蟪蟥蟟蟳蟤蟔蟜蟓蟭蟘蟣螤蟗蟙蠁蟴蟨蟝襓襋襏襌襆襐襑襉謪謧謣謳謰謵譇謯謼謾謱謥謷謦謶謮謤謻謽謺豂豵貙貘貗賾贄贂贀蹜蹢蹠蹗蹖蹞蹥蹧"], ["f140", "蹛蹚蹡蹝蹩蹔轆轇轈轋鄨鄺鄻鄾醨醥醧醯醪鎵鎌鎒鎷鎛鎝鎉鎧鎎鎪鎞鎦鎕鎈鎙鎟鎍鎱鎑鎲鎤鎨鎴鎣鎥闒闓闑隳雗雚巂雟雘雝霣霢霥鞬鞮鞨鞫鞤鞪"], ["f1a1", "鞢鞥韗韙韖韘韺顐顑顒颸饁餼餺騏騋騉騍騄騑騊騅騇騆髀髜鬈鬄鬅鬩鬵魊魌魋鯇鯆鯃鮿鯁鮵鮸鯓鮶鯄鮹鮽鵜鵓鵏鵊鵛鵋鵙鵖鵌鵗鵒鵔鵟鵘鵚麎麌黟鼁鼀鼖鼥鼫鼪鼩鼨齌齕儴儵劖勷厴嚫嚭嚦嚧嚪嚬壚壝壛夒嬽嬾嬿巃幰"], ["f240", "徿懻攇攐攍攉攌攎斄旞旝曞櫧櫠櫌櫑櫙櫋櫟櫜櫐櫫櫏櫍櫞歠殰氌瀙瀧瀠瀖瀫瀡瀢瀣瀩瀗瀤瀜瀪爌爊爇爂爅犥犦犤犣犡瓋瓅璷瓃甖癠矉矊矄矱礝礛"], ["f2a1", "礡礜礗礞禰穧穨簳簼簹簬簻糬糪繶繵繸繰繷繯繺繲繴繨罋罊羃羆羷翽翾聸臗臕艤艡艣藫藱藭藙藡藨藚藗藬藲藸藘藟藣藜藑藰藦藯藞藢蠀蟺蠃蟶蟷蠉蠌蠋蠆蟼蠈蟿蠊蠂襢襚襛襗襡襜襘襝襙覈覷覶觶譐譈譊譀譓譖譔譋譕"], ["f340", "譑譂譒譗豃豷豶貚贆贇贉趬趪趭趫蹭蹸蹳蹪蹯蹻軂轒轑轏轐轓辴酀鄿醰醭鏞鏇鏏鏂鏚鏐鏹鏬鏌鏙鎩鏦鏊鏔鏮鏣鏕鏄鏎鏀鏒鏧镽闚闛雡霩霫霬霨霦"], ["f3a1", "鞳鞷鞶韝韞韟顜顙顝顗颿颽颻颾饈饇饃馦馧騚騕騥騝騤騛騢騠騧騣騞騜騔髂鬋鬊鬎鬌鬷鯪鯫鯠鯞鯤鯦鯢鯰鯔鯗鯬鯜鯙鯥鯕鯡鯚鵷鶁鶊鶄鶈鵱鶀鵸鶆鶋鶌鵽鵫鵴鵵鵰鵩鶅鵳鵻鶂鵯鵹鵿鶇鵨麔麑黀黼鼭齀齁齍齖齗齘匷嚲"], ["f440", "嚵嚳壣孅巆巇廮廯忀忁懹攗攖攕攓旟曨曣曤櫳櫰櫪櫨櫹櫱櫮櫯瀼瀵瀯瀷瀴瀱灂瀸瀿瀺瀹灀瀻瀳灁爓爔犨獽獼璺皫皪皾盭矌矎矏矍矲礥礣礧礨礤礩"], ["f4a1", "禲穮穬穭竷籉籈籊籇籅糮繻繾纁纀羺翿聹臛臙舋艨艩蘢藿蘁藾蘛蘀藶蘄蘉蘅蘌藽蠙蠐蠑蠗蠓蠖襣襦覹觷譠譪譝譨譣譥譧譭趮躆躈躄轙轖轗轕轘轚邍酃酁醷醵醲醳鐋鐓鏻鐠鐏鐔鏾鐕鐐鐨鐙鐍鏵鐀鏷鐇鐎鐖鐒鏺鐉鏸鐊鏿"], ["f540", "鏼鐌鏶鐑鐆闞闠闟霮霯鞹鞻韽韾顠顢顣顟飁飂饐饎饙饌饋饓騲騴騱騬騪騶騩騮騸騭髇髊髆鬐鬒鬑鰋鰈鯷鰅鰒鯸鱀鰇鰎鰆鰗鰔鰉鶟鶙鶤鶝鶒鶘鶐鶛"], ["f5a1", "鶠鶔鶜鶪鶗鶡鶚鶢鶨鶞鶣鶿鶩鶖鶦鶧麙麛麚黥黤黧黦鼰鼮齛齠齞齝齙龑儺儹劘劗囃嚽嚾孈孇巋巏廱懽攛欂櫼欃櫸欀灃灄灊灈灉灅灆爝爚爙獾甗癪矐礭礱礯籔籓糲纊纇纈纋纆纍罍羻耰臝蘘蘪蘦蘟蘣蘜蘙蘧蘮蘡蘠蘩蘞蘥"], ["f640", "蠩蠝蠛蠠蠤蠜蠫衊襭襩襮襫觺譹譸譅譺譻贐贔趯躎躌轞轛轝酆酄酅醹鐿鐻鐶鐩鐽鐼鐰鐹鐪鐷鐬鑀鐱闥闤闣霵霺鞿韡顤飉飆飀饘饖騹騽驆驄驂驁騺"], ["f6a1", "騿髍鬕鬗鬘鬖鬺魒鰫鰝鰜鰬鰣鰨鰩鰤鰡鶷鶶鶼鷁鷇鷊鷏鶾鷅鷃鶻鶵鷎鶹鶺鶬鷈鶱鶭鷌鶳鷍鶲鹺麜黫黮黭鼛鼘鼚鼱齎齥齤龒亹囆囅囋奱孋孌巕巑廲攡攠攦攢欋欈欉氍灕灖灗灒爞爟犩獿瓘瓕瓙瓗癭皭礵禴穰穱籗籜籙籛籚"], ["f740", "糴糱纑罏羇臞艫蘴蘵蘳蘬蘲蘶蠬蠨蠦蠪蠥襱覿覾觻譾讄讂讆讅譿贕躕躔躚躒躐躖躗轠轢酇鑌鑐鑊鑋鑏鑇鑅鑈鑉鑆霿韣顪顩飋饔饛驎驓驔驌驏驈驊"], ["f7a1", "驉驒驐髐鬙鬫鬻魖魕鱆鱈鰿鱄鰹鰳鱁鰼鰷鰴鰲鰽鰶鷛鷒鷞鷚鷋鷐鷜鷑鷟鷩鷙鷘鷖鷵鷕鷝麶黰鼵鼳鼲齂齫龕龢儽劙壨壧奲孍巘蠯彏戁戃戄攩攥斖曫欑欒欏毊灛灚爢玂玁玃癰矔籧籦纕艬蘺虀蘹蘼蘱蘻蘾蠰蠲蠮蠳襶襴襳觾"], ["f840", "讌讎讋讈豅贙躘轤轣醼鑢鑕鑝鑗鑞韄韅頀驖驙鬞鬟鬠鱒鱘鱐鱊鱍鱋鱕鱙鱌鱎鷻鷷鷯鷣鷫鷸鷤鷶鷡鷮鷦鷲鷰鷢鷬鷴鷳鷨鷭黂黐黲黳鼆鼜鼸鼷鼶齃齏"], ["f8a1", "齱齰齮齯囓囍孎屭攭曭曮欓灟灡灝灠爣瓛瓥矕礸禷禶籪纗羉艭虃蠸蠷蠵衋讔讕躞躟躠躝醾醽釂鑫鑨鑩雥靆靃靇韇韥驞髕魙鱣鱧鱦鱢鱞鱠鸂鷾鸇鸃鸆鸅鸀鸁鸉鷿鷽鸄麠鼞齆齴齵齶囔攮斸欘欙欗欚灢爦犪矘矙礹籩籫糶纚"], ["f940", "纘纛纙臠臡虆虇虈襹襺襼襻觿讘讙躥躤躣鑮鑭鑯鑱鑳靉顲饟鱨鱮鱭鸋鸍鸐鸏鸒鸑麡黵鼉齇齸齻齺齹圞灦籯蠼趲躦釃鑴鑸鑶鑵驠鱴鱳鱱鱵鸔鸓黶鼊"], ["f9a1", "龤灨灥糷虪蠾蠽蠿讞貜躩軉靋顳顴飌饡馫驤驦驧鬤鸕鸗齈戇欞爧虌躨钂钀钁驩驨鬮鸙爩虋讟钃鱹麷癵驫鱺鸝灩灪麤齾齉龘碁銹裏墻恒粧嫺╔╦╗╠╬╣╚╩╝╒╤╕╞╪╡╘╧╛╓╥╖╟╫╢╙╨╜║═╭╮╰╯▓"]]; + +var cp950$1 = Object.freeze({ + default: cp950 +}); + +var big5Added = [["8740", "䏰䰲䘃䖦䕸𧉧䵷䖳𧲱䳢𧳅㮕䜶䝄䱇䱀𤊿𣘗𧍒𦺋𧃒䱗𪍑䝏䗚䲅𧱬䴇䪤䚡𦬣爥𥩔𡩣𣸆𣽡晍囻"], ["8767", "綕夝𨮹㷴霴𧯯寛𡵞媤㘥𩺰嫑宷峼杮薓𩥅瑡璝㡵𡵓𣚞𦀡㻬"], ["87a1", "𥣞㫵竼龗𤅡𨤍𣇪𠪊𣉞䌊蒄龖鐯䤰蘓墖靊鈘秐稲晠権袝瑌篅枂稬剏遆㓦珄𥶹瓆鿇垳䤯呌䄱𣚎堘穲𧭥讏䚮𦺈䆁𥶙箮𢒼鿈𢓁𢓉𢓌鿉蔄𣖻䂴鿊䓡𪷿拁灮鿋"], ["8840", "㇀", 4, "𠄌㇅𠃑𠃍㇆㇇𠃋𡿨㇈𠃊㇉㇊㇋㇌𠄎㇍㇎ĀÁǍÀĒÉĚÈŌÓǑÒ࿿Ê̄Ế࿿Ê̌ỀÊāáǎàɑēéěèīíǐìōóǒòūúǔùǖǘǚ"], ["88a1", "ǜü࿿ê̄ế࿿ê̌ềêɡ⏚⏛"], ["8940", "𪎩𡅅"], ["8943", "攊"], ["8946", "丽滝鵎釟"], ["894c", "𧜵撑会伨侨兖兴农凤务动医华发变团声处备夲头学实実岚庆总斉柾栄桥济炼电纤纬纺织经统缆缷艺苏药视设询车轧轮"], ["89a1", "琑糼緍楆竉刧"], ["89ab", "醌碸酞肼"], ["89b0", "贋胶𠧧"], ["89b5", "肟黇䳍鷉鸌䰾𩷶𧀎鸊𪄳㗁"], ["89c1", "溚舾甙"], ["89c5", "䤑马骏龙禇𨑬𡷊𠗐𢫦两亁亀亇亿仫伷㑌侽㹈倃傈㑽㒓㒥円夅凛凼刅争剹劐匧㗇厩㕑厰㕓参吣㕭㕲㚁咓咣咴咹哐哯唘唣唨㖘唿㖥㖿嗗㗅"], ["8a40", "𧶄唥"], ["8a43", "𠱂𠴕𥄫喐𢳆㧬𠍁蹆𤶸𩓥䁓𨂾睺𢰸㨴䟕𨅝𦧲𤷪擝𠵼𠾴𠳕𡃴撍蹾𠺖𠰋𠽤𢲩𨉖𤓓"], ["8a64", "𠵆𩩍𨃩䟴𤺧𢳂骲㩧𩗴㿭㔆𥋇𩟔𧣈𢵄鵮頕"], ["8a76", "䏙𦂥撴哣𢵌𢯊𡁷㧻𡁯"], ["8aa1", "𦛚𦜖𧦠擪𥁒𠱃蹨𢆡𨭌𠜱"], ["8aac", "䠋𠆩㿺塳𢶍"], ["8ab2", "𤗈𠓼𦂗𠽌𠶖啹䂻䎺"], ["8abb", "䪴𢩦𡂝膪飵𠶜捹㧾𢝵跀嚡摼㹃"], ["8ac9", "𪘁𠸉𢫏𢳉"], ["8ace", "𡃈𣧂㦒㨆𨊛㕸𥹉𢃇噒𠼱𢲲𩜠㒼氽𤸻"], ["8adf", "𧕴𢺋𢈈𪙛𨳍𠹺𠰴𦠜羓𡃏𢠃𢤹㗻𥇣𠺌𠾍𠺪㾓𠼰𠵇𡅏𠹌"], ["8af6", "𠺫𠮩𠵈𡃀𡄽㿹𢚖搲𠾭"], ["8b40", "𣏴𧘹𢯎𠵾𠵿𢱑𢱕㨘𠺘𡃇𠼮𪘲𦭐𨳒𨶙𨳊閪哌苄喹"], ["8b55", "𩻃鰦骶𧝞𢷮煀腭胬尜𦕲脴㞗卟𨂽醶𠻺𠸏𠹷𠻻㗝𤷫㘉𠳖嚯𢞵𡃉𠸐𠹸𡁸𡅈𨈇𡑕𠹹𤹐𢶤婔𡀝𡀞𡃵𡃶垜𠸑"], ["8ba1", "𧚔𨋍𠾵𠹻𥅾㜃𠾶𡆀𥋘𪊽𤧚𡠺𤅷𨉼墙剨㘚𥜽箲孨䠀䬬鼧䧧鰟鮍𥭴𣄽嗻㗲嚉丨夂𡯁屮靑𠂆乛亻㔾尣彑忄㣺扌攵歺氵氺灬爫丬犭𤣩罒礻糹罓𦉪㓁"], ["8bde", "𦍋耂肀𦘒𦥑卝衤见𧢲讠贝钅镸长门𨸏韦页风飞饣𩠐鱼鸟黄歯龜丷𠂇阝户钢"], ["8c40", "倻淾𩱳龦㷉袏𤅎灷峵䬠𥇍㕙𥴰愢𨨲辧釶熑朙玺𣊁𪄇㲋𡦀䬐磤琂冮𨜏䀉橣𪊺䈣蘏𠩯稪𩥇𨫪靕灍匤𢁾鏴盙𨧣龧矝亣俰傼丯众龨吴綋墒壐𡶶庒庙忂𢜒斋"], ["8ca1", "𣏹椙橃𣱣泿"], ["8ca7", "爀𤔅玌㻛𤨓嬕璹讃𥲤𥚕窓篬糃繬苸薗龩袐龪躹龫迏蕟駠鈡龬𨶹𡐿䁱䊢娚"], ["8cc9", "顨杫䉶圽"], ["8cce", "藖𤥻芿𧄍䲁𦵴嵻𦬕𦾾龭龮宖龯曧繛湗秊㶈䓃𣉖𢞖䎚䔶"], ["8ce6", "峕𣬚諹屸㴒𣕑嵸龲煗䕘𤃬𡸣䱷㥸㑊𠆤𦱁諌侴𠈹妿腬顖𩣺弻"], ["8d40", "𠮟"], ["8d42", "𢇁𨥭䄂䚻𩁹㼇龳𪆵䃸㟖䛷𦱆䅼𨚲𧏿䕭㣔𥒚䕡䔛䶉䱻䵶䗪㿈𤬏㙡䓞䒽䇭崾嵈嵖㷼㠏嶤嶹㠠㠸幂庽弥徃㤈㤔㤿㥍惗愽峥㦉憷憹懏㦸戬抐拥挘㧸嚱"], ["8da1", "㨃揢揻搇摚㩋擀崕嘡龟㪗斆㪽旿晓㫲暒㬢朖㭂枤栀㭘桊梄㭲㭱㭻椉楃牜楤榟榅㮼槖㯝橥橴橱檂㯬檙㯲檫檵櫔櫶殁毁毪汵沪㳋洂洆洦涁㳯涤涱渕渘温溆𨧀溻滢滚齿滨滩漤漴㵆𣽁澁澾㵪㵵熷岙㶊瀬㶑灐灔灯灿炉𠌥䏁㗱𠻘"], ["8e40", "𣻗垾𦻓焾𥟠㙎榢𨯩孴穉𥣡𩓙穥穽𥦬窻窰竂竃燑𦒍䇊竚竝竪䇯咲𥰁笋筕笩𥌎𥳾箢筯莜𥮴𦱿篐萡箒箸𥴠㶭𥱥蒒篺簆簵𥳁籄粃𤢂粦晽𤕸糉糇糦籴糳糵糎"], ["8ea1", "繧䔝𦹄絝𦻖璍綉綫焵綳緒𤁗𦀩緤㴓緵𡟹緥𨍭縝𦄡𦅚繮纒䌫鑬縧罀罁罇礶𦋐駡羗𦍑羣𡙡𠁨䕜𣝦䔃𨌺翺𦒉者耈耝耨耯𪂇𦳃耻耼聡𢜔䦉𦘦𣷣𦛨朥肧𨩈脇脚墰𢛶汿𦒘𤾸擧𡒊舘𡡞橓𤩥𤪕䑺舩𠬍𦩒𣵾俹𡓽蓢荢𦬊𤦧𣔰𡝳𣷸芪椛芳䇛"], ["8f40", "蕋苐茚𠸖𡞴㛁𣅽𣕚艻苢茘𣺋𦶣𦬅𦮗𣗎㶿茝嗬莅䔋𦶥莬菁菓㑾𦻔橗蕚㒖𦹂𢻯葘𥯤葱㷓䓤檧葊𣲵祘蒨𦮖𦹷𦹃蓞萏莑䒠蒓蓤𥲑䉀𥳀䕃蔴嫲𦺙䔧蕳䔖枿蘖"], ["8fa1", "𨘥𨘻藁𧂈蘂𡖂𧃍䕫䕪蘨㙈𡢢号𧎚虾蝱𪃸蟮𢰧螱蟚蠏噡虬桖䘏衅衆𧗠𣶹𧗤衞袜䙛袴袵揁装睷𧜏覇覊覦覩覧覼𨨥觧𧤤𧪽誜瞓釾誐𧩙竩𧬺𣾏䜓𧬸煼謌謟𥐰𥕥謿譌譍誩𤩺讐讛誯𡛟䘕衏貛𧵔𧶏貫㜥𧵓賖𧶘𧶽贒贃𡤐賛灜贑𤳉㻐起"], ["9040", "趩𨀂𡀔𤦊㭼𨆼𧄌竧躭躶軃鋔輙輭𨍥𨐒辥錃𪊟𠩐辳䤪𨧞𨔽𣶻廸𣉢迹𪀔𨚼𨔁𢌥㦀𦻗逷𨔼𧪾遡𨕬𨘋邨𨜓郄𨛦邮都酧㫰醩釄粬𨤳𡺉鈎沟鉁鉢𥖹銹𨫆𣲛𨬌𥗛"], ["90a1", "𠴱錬鍫𨫡𨯫炏嫃𨫢𨫥䥥鉄𨯬𨰹𨯿鍳鑛躼閅閦鐦閠濶䊹𢙺𨛘𡉼𣸮䧟氜陻隖䅬隣𦻕懚隶磵𨫠隽双䦡𦲸𠉴𦐐𩂯𩃥𤫑𡤕𣌊霱虂霶䨏䔽䖅𤫩灵孁霛靜𩇕靗孊𩇫靟鐥僐𣂷𣂼鞉鞟鞱鞾韀韒韠𥑬韮琜𩐳響韵𩐝𧥺䫑頴頳顋顦㬎𧅵㵑𠘰𤅜"], ["9140", "𥜆飊颷飈飇䫿𦴧𡛓喰飡飦飬鍸餹𤨩䭲𩡗𩤅駵騌騻騐驘𥜥㛄𩂱𩯕髠髢𩬅髴䰎鬔鬭𨘀倴鬴𦦨㣃𣁽魐魀𩴾婅𡡣鮎𤉋鰂鯿鰌𩹨鷔𩾷𪆒𪆫𪃡𪄣𪇟鵾鶃𪄴鸎梈"], ["91a1", "鷄𢅛𪆓𪈠𡤻𪈳鴹𪂹𪊴麐麕麞麢䴴麪麯𤍤黁㭠㧥㴝伲㞾𨰫鼂鼈䮖鐤𦶢鼗鼖鼹嚟嚊齅馸𩂋韲葿齢齩竜龎爖䮾𤥵𤦻煷𤧸𤍈𤩑玞𨯚𡣺禟𨥾𨸶鍩鏳𨩄鋬鎁鏋𨥬𤒹爗㻫睲穃烐𤑳𤏸煾𡟯炣𡢾𣖙㻇𡢅𥐯𡟸㜢𡛻𡠹㛡𡝴𡣑𥽋㜣𡛀坛𤨥𡏾𡊨"], ["9240", "𡏆𡒶蔃𣚦蔃葕𤦔𧅥𣸱𥕜𣻻𧁒䓴𣛮𩦝𦼦柹㜳㰕㷧塬𡤢栐䁗𣜿𤃡𤂋𤄏𦰡哋嚞𦚱嚒𠿟𠮨𠸍鏆𨬓鎜仸儫㠙𤐶亼𠑥𠍿佋侊𥙑婨𠆫𠏋㦙𠌊𠐔㐵伩𠋀𨺳𠉵諚𠈌亘"], ["92a1", "働儍侢伃𤨎𣺊佂倮偬傁俌俥偘僼兙兛兝兞湶𣖕𣸹𣺿浲𡢄𣺉冨凃𠗠䓝𠒣𠒒𠒑赺𨪜𠜎剙劤𠡳勡鍮䙺熌𤎌𠰠𤦬𡃤槑𠸝瑹㻞璙琔瑖玘䮎𤪼𤂍叐㖄爏𤃉喴𠍅响𠯆圝鉝雴鍦埝垍坿㘾壋媙𨩆𡛺𡝯𡜐娬妸銏婾嫏娒𥥆𡧳𡡡𤊕㛵洅瑃娡𥺃"], ["9340", "媁𨯗𠐓鏠璌𡌃焅䥲鐈𨧻鎽㞠尞岞幞幈𡦖𡥼𣫮廍孏𡤃𡤄㜁𡢠㛝𡛾㛓脪𨩇𡶺𣑲𨦨弌弎𡤧𡞫婫𡜻孄蘔𧗽衠恾𢡠𢘫忛㺸𢖯𢖾𩂈𦽳懀𠀾𠁆𢘛憙憘恵𢲛𢴇𤛔𩅍"], ["93a1", "摱𤙥𢭪㨩𢬢𣑐𩣪𢹸挷𪑛撶挱揑𤧣𢵧护𢲡搻敫楲㯴𣂎𣊭𤦉𣊫唍𣋠𡣙𩐿曎𣊉𣆳㫠䆐𥖄𨬢𥖏𡛼𥕛𥐥磮𣄃𡠪𣈴㑤𣈏𣆂𤋉暎𦴤晫䮓昰𧡰𡷫晣𣋒𣋡昞𥡲㣑𣠺𣞼㮙𣞢𣏾瓐㮖枏𤘪梶栞㯄檾㡣𣟕𤒇樳橒櫉欅𡤒攑梘橌㯗橺歗𣿀𣲚鎠鋲𨯪𨫋"], ["9440", "銉𨀞𨧜鑧涥漋𤧬浧𣽿㶏渄𤀼娽渊塇洤硂焻𤌚𤉶烱牐犇犔𤞏𤜥兹𤪤𠗫瑺𣻸𣙟𤩊𤤗𥿡㼆㺱𤫟𨰣𣼵悧㻳瓌琼鎇琷䒟𦷪䕑疃㽣𤳙𤴆㽘畕癳𪗆㬙瑨𨫌𤦫𤦎㫻"], ["94a1", "㷍𤩎㻿𤧅𤣳釺圲鍂𨫣𡡤僟𥈡𥇧睸𣈲眎眏睻𤚗𣞁㩞𤣰琸璛㺿𤪺𤫇䃈𤪖𦆮錇𥖁砞碍碈磒珐祙𧝁𥛣䄎禛蒖禥樭𣻺稺秴䅮𡛦䄲鈵秱𠵌𤦌𠊙𣶺𡝮㖗啫㕰㚪𠇔𠰍竢婙𢛵𥪯𥪜娍𠉛磰娪𥯆竾䇹籝籭䈑𥮳𥺼𥺦糍𤧹𡞰粎籼粮檲緜縇緓罎𦉡"], ["9540", "𦅜𧭈綗𥺂䉪𦭵𠤖柖𠁎𣗏埄𦐒𦏸𤥢翝笧𠠬𥫩𥵃笌𥸎駦虅驣樜𣐿㧢𤧷𦖭騟𦖠蒀𧄧𦳑䓪脷䐂胆脉腂𦞴飃𦩂艢艥𦩑葓𦶧蘐𧈛媆䅿𡡀嬫𡢡嫤𡣘蚠蜨𣶏蠭𧐢娂"], ["95a1", "衮佅袇袿裦襥襍𥚃襔𧞅𧞄𨯵𨯙𨮜𨧹㺭蒣䛵䛏㟲訽訜𩑈彍鈫𤊄旔焩烄𡡅鵭貟賩𧷜妚矃姰䍮㛔踪躧𤰉輰轊䋴汘澻𢌡䢛潹溋𡟚鯩㚵𤤯邻邗啱䤆醻鐄𨩋䁢𨫼鐧𨰝𨰻蓥訫閙閧閗閖𨴴瑅㻂𤣿𤩂𤏪㻧𣈥随𨻧𨹦𨹥㻌𤧭𤩸𣿮琒瑫㻼靁𩂰"], ["9640", "桇䨝𩂓𥟟靝鍨𨦉𨰦𨬯𦎾銺嬑譩䤼珹𤈛鞛靱餸𠼦巁𨯅𤪲頟𩓚鋶𩗗釥䓀𨭐𤩧𨭤飜𨩅㼀鈪䤥萔餻饍𧬆㷽馛䭯馪驜𨭥𥣈檏騡嫾騯𩣱䮐𩥈馼䮽䮗鍽塲𡌂堢𤦸"], ["96a1", "𡓨硄𢜟𣶸棅㵽鑘㤧慐𢞁𢥫愇鱏鱓鱻鰵鰐魿鯏𩸭鮟𪇵𪃾鴡䲮𤄄鸘䲰鴌𪆴𪃭𪃳𩤯鶥蒽𦸒𦿟𦮂藼䔳𦶤𦺄𦷰萠藮𦸀𣟗𦁤秢𣖜𣙀䤭𤧞㵢鏛銾鍈𠊿碹鉷鑍俤㑀遤𥕝砽硔碶硋𡝗𣇉𤥁㚚佲濚濙瀞瀞吔𤆵垻壳垊鴖埗焴㒯𤆬燫𦱀𤾗嬨𡞵𨩉"], ["9740", "愌嫎娋䊼𤒈㜬䭻𨧼鎻鎸𡣖𠼝葲𦳀𡐓𤋺𢰦𤏁妔𣶷𦝁綨𦅛𦂤𤦹𤦋𨧺鋥珢㻩璴𨭣𡢟㻡𤪳櫘珳珻㻖𤨾𤪔𡟙𤩦𠎧𡐤𤧥瑈𤤖炥𤥶銄珦鍟𠓾錱𨫎𨨖鎆𨯧𥗕䤵𨪂煫"], ["97a1", "𤥃𠳿嚤𠘚𠯫𠲸唂秄𡟺緾𡛂𤩐𡡒䔮鐁㜊𨫀𤦭妰𡢿𡢃𧒄媡㛢𣵛㚰鉟婹𨪁𡡢鍴㳍𠪴䪖㦊僴㵩㵌𡎜煵䋻𨈘渏𩃤䓫浗𧹏灧沯㳖𣿭𣸭渂漌㵯𠏵畑㚼㓈䚀㻚䡱姄鉮䤾轁𨰜𦯀堒埈㛖𡑒烾𤍢𤩱𢿣𡊰𢎽梹楧𡎘𣓥𧯴𣛟𨪃𣟖𣏺𤲟樚𣚭𦲷萾䓟䓎"], ["9840", "𦴦𦵑𦲂𦿞漗𧄉茽𡜺菭𦲀𧁓𡟛妉媂𡞳婡婱𡤅𤇼㜭姯𡜼㛇熎鎐暚𤊥婮娫𤊓樫𣻹𧜶𤑛𤋊焝𤉙𨧡侰𦴨峂𤓎𧹍𤎽樌𤉖𡌄炦焳𤏩㶥泟勇𤩏繥姫崯㷳彜𤩝𡟟綤萦"], ["98a1", "咅𣫺𣌀𠈔坾𠣕𠘙㿥𡾞𪊶瀃𩅛嵰玏糓𨩙𩐠俈翧狍猐𧫴猸猹𥛶獁獈㺩𧬘遬燵𤣲珡臶㻊県㻑沢国琙琞琟㻢㻰㻴㻺瓓㼎㽓畂畭畲疍㽼痈痜㿀癍㿗癴㿜発𤽜熈嘣覀塩䀝睃䀹条䁅㗛瞘䁪䁯属瞾矋売砘点砜䂨砹硇硑硦葈𥔵礳栃礲䄃"], ["9940", "䄉禑禙辻稆込䅧窑䆲窼艹䇄竏竛䇏両筢筬筻簒簛䉠䉺类粜䊌粸䊔糭输烀𠳏総緔緐緽羮羴犟䎗耠耥笹耮耱联㷌垴炠肷胩䏭脌猪脎脒畠脔䐁㬹腖腙腚"], ["99a1", "䐓堺腼膄䐥膓䐭膥埯臁臤艔䒏芦艶苊苘苿䒰荗险榊萅烵葤惣蒈䔄蒾蓡蓸蔐蔸蕒䔻蕯蕰藠䕷虲蚒蚲蛯际螋䘆䘗袮裿褤襇覑𧥧訩訸誔誴豑賔賲贜䞘塟跃䟭仮踺嗘坔蹱嗵躰䠷軎転軤軭軲辷迁迊迌逳駄䢭飠鈓䤞鈨鉘鉫銱銮銿"], ["9a40", "鋣鋫鋳鋴鋽鍃鎄鎭䥅䥑麿鐗匁鐝鐭鐾䥪鑔鑹锭関䦧间阳䧥枠䨤靀䨵鞲韂噔䫤惨颹䬙飱塄餎餙冴餜餷饂饝饢䭰駅䮝騼鬏窃魩鮁鯝鯱鯴䱭鰠㝯𡯂鵉鰺"], ["9aa1", "黾噐鶓鶽鷀鷼银辶鹻麬麱麽黆铜黢黱黸竈齄𠂔𠊷𠎠椚铃妬𠓗塀铁㞹𠗕𠘕𠙶𡚺块煳𠫂𠫍𠮿呪吆𠯋咞𠯻𠰻𠱓𠱥𠱼惧𠲍噺𠲵𠳝𠳭𠵯𠶲𠷈楕鰯螥𠸄𠸎𠻗𠾐𠼭𠹳尠𠾼帋𡁜𡁏𡁶朞𡁻𡂈𡂖㙇𡂿𡃓𡄯𡄻卤蒭𡋣𡍵𡌶讁𡕷𡘙𡟃𡟇乸炻𡠭𡥪"], ["9b40", "𡨭𡩅𡰪𡱰𡲬𡻈拃𡻕𡼕熘桕𢁅槩㛈𢉼𢏗𢏺𢜪𢡱𢥏苽𢥧𢦓𢫕覥𢫨辠𢬎鞸𢬿顇骽𢱌"], ["9b62", "𢲈𢲷𥯨𢴈𢴒𢶷𢶕𢹂𢽴𢿌𣀳𣁦𣌟𣏞徱晈暿𧩹𣕧𣗳爁𤦺矗𣘚𣜖纇𠍆墵朎"], ["9ba1", "椘𣪧𧙗𥿢𣸑𣺹𧗾𢂚䣐䪸𤄙𨪚𤋮𤌍𤀻𤌴𤎖𤩅𠗊凒𠘑妟𡺨㮾𣳿𤐄𤓖垈𤙴㦛𤜯𨗨𩧉㝢𢇃譞𨭎駖𤠒𤣻𤨕爉𤫀𠱸奥𤺥𤾆𠝹軚𥀬劏圿煱𥊙𥐙𣽊𤪧喼𥑆𥑮𦭒釔㑳𥔿𧘲𥕞䜘𥕢𥕦𥟇𤤿𥡝偦㓻𣏌惞𥤃䝼𨥈𥪮𥮉𥰆𡶐垡煑澶𦄂𧰒遖𦆲𤾚譢𦐂𦑊"], ["9c40", "嵛𦯷輶𦒄𡤜諪𤧶𦒈𣿯𦔒䯀𦖿𦚵𢜛鑥𥟡憕娧晉侻嚹𤔡𦛼乪𤤴陖涏𦲽㘘襷𦞙𦡮𦐑𦡞營𦣇筂𩃀𠨑𦤦鄄𦤹穅鷰𦧺騦𦨭㙟𦑩𠀡禃𦨴𦭛崬𣔙菏𦮝䛐𦲤画补𦶮墶"], ["9ca1", "㜜𢖍𧁋𧇍㱔𧊀𧊅銁𢅺𧊋錰𧋦𤧐氹钟𧑐𠻸蠧裵𢤦𨑳𡞱溸𤨪𡠠㦤㚹尐秣䔿暶𩲭𩢤襃𧟌𧡘囖䃟𡘊㦡𣜯𨃨𡏅熭荦𧧝𩆨婧䲷𧂯𨦫𧧽𧨊𧬋𧵦𤅺筃祾𨀉澵𪋟樃𨌘厢𦸇鎿栶靝𨅯𨀣𦦵𡏭𣈯𨁈嶅𨰰𨂃圕頣𨥉嶫𤦈斾槕叒𤪥𣾁㰑朶𨂐𨃴𨄮𡾡𨅏"], ["9d40", "𨆉𨆯𨈚𨌆𨌯𨎊㗊𨑨𨚪䣺揦𨥖砈鉕𨦸䏲𨧧䏟𨧨𨭆𨯔姸𨰉輋𨿅𩃬筑𩄐𩄼㷷𩅞𤫊运犏嚋𩓧𩗩𩖰𩖸𩜲𩣑𩥉𩥪𩧃𩨨𩬎𩵚𩶛纟𩻸𩼣䲤镇𪊓熢𪋿䶑递𪗋䶜𠲜达嗁"], ["9da1", "辺𢒰边𤪓䔉繿潖檱仪㓤𨬬𧢝㜺躀𡟵𨀤𨭬𨮙𧨾𦚯㷫𧙕𣲷𥘵𥥖亚𥺁𦉘嚿𠹭踎孭𣺈𤲞揞拐𡟶𡡻攰嘭𥱊吚𥌑㷆𩶘䱽嘢嘞罉𥻘奵𣵀蝰东𠿪𠵉𣚺脗鵞贘瘻鱅癎瞹鍅吲腈苷嘥脲萘肽嗪祢噃吖𠺝㗎嘅嗱曱𨋢㘭甴嗰喺咗啲𠱁𠲖廐𥅈𠹶𢱢"], ["9e40", "𠺢麫絚嗞𡁵抝靭咔賍燶酶揼掹揾啩𢭃鱲𢺳冚㓟𠶧冧呍唞唓癦踭𦢊疱肶蠄螆裇膶萜𡃁䓬猄𤜆宐茋𦢓噻𢛴𧴯𤆣𧵳𦻐𧊶酰𡇙鈈𣳼𪚩𠺬𠻹牦𡲢䝎𤿂𧿹𠿫䃺"], ["9ea1", "鱝攟𢶠䣳𤟠𩵼𠿬𠸊恢𧖣𠿭"], ["9ead", "𦁈𡆇熣纎鵐业丄㕷嬍沲卧㚬㧜卽㚥𤘘墚𤭮舭呋垪𥪕𠥹"], ["9ec5", "㩒𢑥獴𩺬䴉鯭𣳾𩼰䱛𤾩𩖞𩿞葜𣶶𧊲𦞳𣜠挮紥𣻷𣸬㨪逈勌㹴㙺䗩𠒎癀嫰𠺶硺𧼮墧䂿噼鮋嵴癔𪐴麅䳡痹㟻愙𣃚𤏲"], ["9ef5", "噝𡊩垧𤥣𩸆刴𧂮㖭汊鵼"], ["9f40", "籖鬹埞𡝬屓擓𩓐𦌵𧅤蚭𠴨𦴢𤫢𠵱"], ["9f4f", "凾𡼏嶎霃𡷑麁遌笟鬂峑箣扨挵髿篏鬪籾鬮籂粆鰕篼鬉鼗鰛𤤾齚啳寃俽麘俲剠㸆勑坧偖妷帒韈鶫轜呩鞴饀鞺匬愰"], ["9fa1", "椬叚鰊鴂䰻陁榀傦畆𡝭駚剳"], ["9fae", "酙隁酜"], ["9fb2", "酑𨺗捿𦴣櫊嘑醎畺抅𠏼獏籰𥰡𣳽"], ["9fc1", "𤤙盖鮝个𠳔莾衂"], ["9fc9", "届槀僭坺刟巵从氱𠇲伹咜哚劚趂㗾弌㗳"], ["9fdb", "歒酼龥鮗頮颴骺麨麄煺笔"], ["9fe7", "毺蠘罸"], ["9feb", "嘠𪙊蹷齓"], ["9ff0", "跔蹏鸜踁抂𨍽踨蹵竓𤩷稾磘泪詧瘇"], ["a040", "𨩚鼦泎蟖痃𪊲硓咢贌狢獱謭猂瓱賫𤪻蘯徺袠䒷"], ["a055", "𡠻𦸅"], ["a058", "詾𢔛"], ["a05b", "惽癧髗鵄鍮鮏蟵"], ["a063", "蠏賷猬霡鮰㗖犲䰇籑饊𦅙慙䰄麖慽"], ["a073", "坟慯抦戹拎㩜懢厪𣏵捤栂㗒"], ["a0a1", "嵗𨯂迚𨸹"], ["a0a6", "僙𡵆礆匲阸𠼻䁥"], ["a0ae", "矾"], ["a0b0", "糂𥼚糚稭聦聣絍甅瓲覔舚朌聢𧒆聛瓰脃眤覉𦟌畓𦻑螩蟎臈螌詉貭譃眫瓸蓚㘵榲趦"], ["a0d4", "覩瑨涹蟁𤀑瓧㷛煶悤憜㳑煢恷"], ["a0e2", "罱𨬭牐惩䭾删㰘𣳇𥻗𧙖𥔱𡥄𡋾𩤃𦷜𧂭峁𦆭𨨏𣙷𠃮𦡆𤼎䕢嬟𦍌齐麦𦉫"], ["a3c0", "␀", 31, "␡"], ["c6a1", "①", 9, "⑴", 9, "ⅰ", 9, "丶丿亅亠冂冖冫勹匸卩厶夊宀巛⼳广廴彐彡攴无疒癶辵隶¨ˆヽヾゝゞ〃仝々〆〇ー[]✽ぁ", 23], ["c740", "す", 58, "ァアィイ"], ["c7a1", "ゥ", 81, "А", 5, "ЁЖ", 4], ["c840", "Л", 26, "ёж", 25, "⇧↸↹㇏𠃌乚𠂊刂䒑"], ["c8a1", "龰冈龱𧘇"], ["c8cd", "¬¦'"㈱№℡゛゜⺀⺄⺆⺇⺈⺊⺌⺍⺕⺜⺝⺥⺧⺪⺬⺮⺶⺼⺾⻆⻊⻌⻍⻏⻖⻗⻞⻣"], ["c8f5", "ʃɐɛɔɵœøŋʊɪ"], ["f9fe", "■"], ["fa40", "𠕇鋛𠗟𣿅蕌䊵珯况㙉𤥂𨧤鍄𡧛苮𣳈砼杄拟𤤳𨦪𠊠𦮳𡌅侫𢓭倈𦴩𧪄𣘀𤪱𢔓倩𠍾徤𠎀𠍇滛𠐟偽儁㑺儎顬㝃萖𤦤𠒇兠𣎴兪𠯿𢃼𠋥𢔰𠖎𣈳𡦃宂蝽𠖳𣲙冲冸"], ["faa1", "鴴凉减凑㳜凓𤪦决凢卂凭菍椾𣜭彻刋刦刼劵剗劔効勅簕蕂勠蘍𦬓包𨫞啉滙𣾀𠥔𣿬匳卄𠯢泋𡜦栛珕恊㺪㣌𡛨燝䒢卭却𨚫卾卿𡖖𡘓矦厓𨪛厠厫厮玧𥝲㽙玜叁叅汉义埾叙㪫𠮏叠𣿫𢶣叶𠱷吓灹唫晗浛呭𦭓𠵴啝咏咤䞦𡜍𠻝㶴𠵍"], ["fb40", "𨦼𢚘啇䳭启琗喆喩嘅𡣗𤀺䕒𤐵暳𡂴嘷曍𣊊暤暭噍噏磱囱鞇叾圀囯园𨭦㘣𡉏坆𤆥汮炋坂㚱𦱾埦𡐖堃𡑔𤍣堦𤯵塜墪㕡壠壜𡈼壻寿坃𪅐𤉸鏓㖡够梦㛃湙"], ["fba1", "𡘾娤啓𡚒蔅姉𠵎𦲁𦴪𡟜姙𡟻𡞲𦶦浱𡠨𡛕姹𦹅媫婣㛦𤦩婷㜈媖瑥嫓𦾡𢕔㶅𡤑㜲𡚸広勐孶斈孼𧨎䀄䡝𠈄寕慠𡨴𥧌𠖥寳宝䴐尅𡭄尓珎尔𡲥𦬨屉䣝岅峩峯嶋𡷹𡸷崐崘嵆𡺤岺巗苼㠭𤤁𢁉𢅳芇㠶㯂帮檊幵幺𤒼𠳓厦亷廐厨𡝱帉廴𨒂"], ["fc40", "廹廻㢠廼栾鐛弍𠇁弢㫞䢮𡌺强𦢈𢏐彘𢑱彣鞽𦹮彲鍀𨨶徧嶶㵟𥉐𡽪𧃸𢙨釖𠊞𨨩怱暅𡡷㥣㷇㘹垐𢞴祱㹀悞悤悳𤦂𤦏𧩓璤僡媠慤萤慂慈𦻒憁凴𠙖憇宪𣾷"], ["fca1", "𢡟懓𨮝𩥝懐㤲𢦀𢣁怣慜攞掋𠄘担𡝰拕𢸍捬𤧟㨗搸揸𡎎𡟼撐澊𢸶頔𤂌𥜝擡擥鑻㩦携㩗敍漖𤨨𤨣斅敭敟𣁾斵𤥀䬷旑䃘𡠩无旣忟𣐀昘𣇷𣇸晄𣆤𣆥晋𠹵晧𥇦晳晴𡸽𣈱𨗴𣇈𥌓矅𢣷馤朂𤎜𤨡㬫槺𣟂杞杧杢𤇍𩃭柗䓩栢湐鈼栁𣏦𦶠桝"], ["fd40", "𣑯槡樋𨫟楳棃𣗍椁椀㴲㨁𣘼㮀枬楡𨩊䋼椶榘㮡𠏉荣傐槹𣙙𢄪橅𣜃檝㯳枱櫈𩆜㰍欝𠤣惞欵歴𢟍溵𣫛𠎵𡥘㝀吡𣭚毡𣻼毜氷𢒋𤣱𦭑汚舦汹𣶼䓅𣶽𤆤𤤌𤤀"], ["fda1", "𣳉㛥㳫𠴲鮃𣇹𢒑羏样𦴥𦶡𦷫涖浜湼漄𤥿𤂅𦹲蔳𦽴凇沜渝萮𨬡港𣸯瑓𣾂秌湏媑𣁋濸㜍澝𣸰滺𡒗𤀽䕕鏰潄潜㵎潴𩅰㴻澟𤅄濓𤂑𤅕𤀹𣿰𣾴𤄿凟𤅖𤅗𤅀𦇝灋灾炧炁烌烕烖烟䄄㷨熴熖𤉷焫煅媈煊煮岜𤍥煏鍢𤋁焬𤑚𤨧𤨢熺𨯨炽爎"], ["fe40", "鑂爕夑鑃爤鍁𥘅爮牀𤥴梽牕牗㹕𣁄栍漽犂猪猫𤠣𨠫䣭𨠄猨献珏玪𠰺𦨮珉瑉𤇢𡛧𤨤昣㛅𤦷𤦍𤧻珷琕椃𤨦琹𠗃㻗瑜𢢭瑠𨺲瑇珤瑶莹瑬㜰瑴鏱樬璂䥓𤪌"], ["fea1", "𤅟𤩹𨮏孆𨰃𡢞瓈𡦈甎瓩甞𨻙𡩋寗𨺬鎅畍畊畧畮𤾂㼄𤴓疎瑝疞疴瘂瘬癑癏癯癶𦏵皐臯㟸𦤑𦤎皡皥皷盌𦾟葢𥂝𥅽𡸜眞眦着撯𥈠睘𣊬瞯𨥤𨥨𡛁矴砉𡍶𤨒棊碯磇磓隥礮𥗠磗礴碱𧘌辸袄𨬫𦂃𢘜禆褀椂禀𥡗禝𧬹礼禩渪𧄦㺨秆𩄍秔"]]; + +var big5Added$1 = Object.freeze({ + default: big5Added +}); + +var require$$7 = ( shiftjis$1 && shiftjis$1['default'] ) || shiftjis$1; + +var require$$6 = ( eucjp$1 && eucjp$1['default'] ) || eucjp$1; + +var require$$5 = ( cp936$1 && cp936$1['default'] ) || cp936$1; + +var require$$4 = ( gbkAdded$1 && gbkAdded$1['default'] ) || gbkAdded$1; + +var require$$3 = ( gb18030Ranges$1 && gb18030Ranges$1['default'] ) || gb18030Ranges$1; + +var require$$2 = ( cp949$1 && cp949$1['default'] ) || cp949$1; + +var require$$1 = ( cp950$1 && cp950$1['default'] ) || cp950$1; + +var require$$0$3 = ( big5Added$1 && big5Added$1['default'] ) || big5Added$1; + +var __moduleExports$81 = createCommonjsModule(function (module) { + "use strict"; + + // Description of supported double byte encodings and aliases. + // Tables are not require()-d until they are needed to speed up library load. + // require()-s are direct to support Browserify. + + module.exports = { + + // == Japanese/ShiftJIS ==================================================== + // All japanese encodings are based on JIS X set of standards: + // JIS X 0201 - Single-byte encoding of ASCII + ¥ + Kana chars at 0xA1-0xDF. + // JIS X 0208 - Main set of 6879 characters, placed in 94x94 plane, to be encoded by 2 bytes. + // Has several variations in 1978, 1983, 1990 and 1997. + // JIS X 0212 - Supplementary plane of 6067 chars in 94x94 plane. 1990. Effectively dead. + // JIS X 0213 - Extension and modern replacement of 0208 and 0212. Total chars: 11233. + // 2 planes, first is superset of 0208, second - revised 0212. + // Introduced in 2000, revised 2004. Some characters are in Unicode Plane 2 (0x2xxxx) + + // Byte encodings are: + // * Shift_JIS: Compatible with 0201, uses not defined chars in top half as lead bytes for double-byte + // encoding of 0208. Lead byte ranges: 0x81-0x9F, 0xE0-0xEF; Trail byte ranges: 0x40-0x7E, 0x80-0x9E, 0x9F-0xFC. + // Windows CP932 is a superset of Shift_JIS. Some companies added more chars, notably KDDI. + // * EUC-JP: Up to 3 bytes per character. Used mostly on *nixes. + // 0x00-0x7F - lower part of 0201 + // 0x8E, 0xA1-0xDF - upper part of 0201 + // (0xA1-0xFE)x2 - 0208 plane (94x94). + // 0x8F, (0xA1-0xFE)x2 - 0212 plane (94x94). + // * JIS X 208: 7-bit, direct encoding of 0208. Byte ranges: 0x21-0x7E (94 values). Uncommon. + // Used as-is in ISO2022 family. + // * ISO2022-JP: Stateful encoding, with escape sequences to switch between ASCII, + // 0201-1976 Roman, 0208-1978, 0208-1983. + // * ISO2022-JP-1: Adds esc seq for 0212-1990. + // * ISO2022-JP-2: Adds esc seq for GB2313-1980, KSX1001-1992, ISO8859-1, ISO8859-7. + // * ISO2022-JP-3: Adds esc seq for 0201-1976 Kana set, 0213-2000 Planes 1, 2. + // * ISO2022-JP-2004: Adds 0213-2004 Plane 1. + // + // After JIS X 0213 appeared, Shift_JIS-2004, EUC-JISX0213 and ISO2022-JP-2004 followed, with just changing the planes. + // + // Overall, it seems that it's a mess :( http://www8.plala.or.jp/tkubota1/unicode-symbols-map2.html + + + 'shiftjis': { + type: '_dbcs', + table: function table() { + return require$$7; + }, + encodeAdd: { '\xA5': 0x5C, '\u203E': 0x7E }, + encodeSkipVals: [{ from: 0xED40, to: 0xF940 }] + }, + 'csshiftjis': 'shiftjis', + 'mskanji': 'shiftjis', + 'sjis': 'shiftjis', + 'windows31j': 'shiftjis', + 'xsjis': 'shiftjis', + 'windows932': 'shiftjis', + '932': 'shiftjis', + 'cp932': 'shiftjis', + + 'eucjp': { + type: '_dbcs', + table: function table() { + return require$$6; + }, + encodeAdd: { '\xA5': 0x5C, '\u203E': 0x7E } + }, + + // TODO: KDDI extension to Shift_JIS + // TODO: IBM CCSID 942 = CP932, but F0-F9 custom chars and other char changes. + // TODO: IBM CCSID 943 = Shift_JIS = CP932 with original Shift_JIS lower 128 chars. + + // == Chinese/GBK ========================================================== + // http://en.wikipedia.org/wiki/GBK + + // Oldest GB2312 (1981, ~7600 chars) is a subset of CP936 + 'gb2312': 'cp936', + 'gb231280': 'cp936', + 'gb23121980': 'cp936', + 'csgb2312': 'cp936', + 'csiso58gb231280': 'cp936', + 'euccn': 'cp936', + 'isoir58': 'gbk', + + // Microsoft's CP936 is a subset and approximation of GBK. + // TODO: Euro = 0x80 in cp936, but not in GBK (where it's valid but undefined) + 'windows936': 'cp936', + '936': 'cp936', + 'cp936': { + type: '_dbcs', + table: function table() { + return require$$5; + } + }, + + // GBK (~22000 chars) is an extension of CP936 that added user-mapped chars and some other. + 'gbk': { + type: '_dbcs', + table: function table() { + return require$$5.concat(require$$4); + } + }, + 'xgbk': 'gbk', + + // GB18030 is an algorithmic extension of GBK. + 'gb18030': { + type: '_dbcs', + table: function table() { + return require$$5.concat(require$$4); + }, + gb18030: function gb18030() { + return require$$3; + } + }, + + 'chinese': 'gb18030', + + // TODO: Support GB18030 (~27000 chars + whole unicode mapping, cp54936) + // http://icu-project.org/docs/papers/gb18030.html + // http://source.icu-project.org/repos/icu/data/trunk/charset/data/xml/gb-18030-2000.xml + // http://www.khngai.com/chinese/charmap/tblgbk.php?page=0 + + // == Korean =============================================================== + // EUC-KR, KS_C_5601 and KS X 1001 are exactly the same. + 'windows949': 'cp949', + '949': 'cp949', + 'cp949': { + type: '_dbcs', + table: function table() { + return require$$2; + } + }, + + 'cseuckr': 'cp949', + 'csksc56011987': 'cp949', + 'euckr': 'cp949', + 'isoir149': 'cp949', + 'korean': 'cp949', + 'ksc56011987': 'cp949', + 'ksc56011989': 'cp949', + 'ksc5601': 'cp949', + + // == Big5/Taiwan/Hong Kong ================================================ + // There are lots of tables for Big5 and cp950. Please see the following links for history: + // http://moztw.org/docs/big5/ http://www.haible.de/bruno/charsets/conversion-tables/Big5.html + // Variations, in roughly number of defined chars: + // * Windows CP 950: Microsoft variant of Big5. Canonical: http://www.unicode.org/Public/MAPPINGS/VENDORS/MICSFT/WINDOWS/CP950.TXT + // * Windows CP 951: Microsoft variant of Big5-HKSCS-2001. Seems to be never public. http://me.abelcheung.org/articles/research/what-is-cp951/ + // * Big5-2003 (Taiwan standard) almost superset of cp950. + // * Unicode-at-on (UAO) / Mozilla 1.8. Falling out of use on the Web. Not supported by other browsers. + // * Big5-HKSCS (-2001, -2004, -2008). Hong Kong standard. + // many unicode code points moved from PUA to Supplementary plane (U+2XXXX) over the years. + // Plus, it has 4 combining sequences. + // Seems that Mozilla refused to support it for 10 yrs. https://bugzilla.mozilla.org/show_bug.cgi?id=162431 https://bugzilla.mozilla.org/show_bug.cgi?id=310299 + // because big5-hkscs is the only encoding to include astral characters in non-algorithmic way. + // Implementations are not consistent within browsers; sometimes labeled as just big5. + // MS Internet Explorer switches from big5 to big5-hkscs when a patch applied. + // Great discussion & recap of what's going on https://bugzilla.mozilla.org/show_bug.cgi?id=912470#c31 + // In the encoder, it might make sense to support encoding old PUA mappings to Big5 bytes seq-s. + // Official spec: http://www.ogcio.gov.hk/en/business/tech_promotion/ccli/terms/doc/2003cmp_2008.txt + // http://www.ogcio.gov.hk/tc/business/tech_promotion/ccli/terms/doc/hkscs-2008-big5-iso.txt + // + // Current understanding of how to deal with Big5(-HKSCS) is in the Encoding Standard, http://encoding.spec.whatwg.org/#big5-encoder + // Unicode mapping (http://www.unicode.org/Public/MAPPINGS/OBSOLETE/EASTASIA/OTHER/BIG5.TXT) is said to be wrong. + + 'windows950': 'cp950', + '950': 'cp950', + 'cp950': { + type: '_dbcs', + table: function table() { + return require$$1; + } + }, + + // Big5 has many variations and is an extension of cp950. We use Encoding Standard's as a consensus. + 'big5': 'big5hkscs', + 'big5hkscs': { + type: '_dbcs', + table: function table() { + return require$$1.concat(require$$0$3); + }, + encodeSkipVals: [0xa2cc] + }, + + 'cnbig5': 'big5hkscs', + 'csbig5': 'big5hkscs', + 'xxbig5': 'big5hkscs' + + }; +}); + +var __moduleExports$73 = createCommonjsModule(function (module, exports) { + "use strict"; + + // Update this array if you add/rename/remove files in this directory. + // We support Browserify by skipping automatic module discovery and requiring modules directly. + + var modules = [__moduleExports$74, __moduleExports$75, __moduleExports$76, __moduleExports$77, __moduleExports$78, __moduleExports$79, __moduleExports$80, __moduleExports$81]; + + // Put all encoding/alias/codec definitions to single object and export it. + for (var i = 0; i < modules.length; i++) { + var module = modules[i]; + for (var enc in module) { + if (Object.prototype.hasOwnProperty.call(module, enc)) exports[enc] = module[enc]; + } + } +}); + +var __moduleExports$82 = createCommonjsModule(function (module) { + "use strict"; + + var Transform = stream.Transform; + + // == Exports ================================================================== + module.exports = function (iconv) { + + // Additional Public API. + iconv.encodeStream = function encodeStream(encoding, options) { + return new IconvLiteEncoderStream(iconv.getEncoder(encoding, options), options); + }; + + iconv.decodeStream = function decodeStream(encoding, options) { + return new IconvLiteDecoderStream(iconv.getDecoder(encoding, options), options); + }; + + iconv.supportsStreams = true; + + // Not published yet. + iconv.IconvLiteEncoderStream = IconvLiteEncoderStream; + iconv.IconvLiteDecoderStream = IconvLiteDecoderStream; + iconv._collect = IconvLiteDecoderStream.prototype.collect; + }; + + // == Encoder stream ======================================================= + function IconvLiteEncoderStream(conv, options) { + this.conv = conv; + options = options || {}; + options.decodeStrings = false; // We accept only strings, so we don't need to decode them. + Transform.call(this, options); + } + + IconvLiteEncoderStream.prototype = Object.create(Transform.prototype, { + constructor: { value: IconvLiteEncoderStream } + }); + + IconvLiteEncoderStream.prototype._transform = function (chunk, encoding, done) { + if (typeof chunk != 'string') return done(new Error("Iconv encoding stream needs strings as its input.")); + try { + var res = this.conv.write(chunk); + if (res && res.length) this.push(res); + done(); + } catch (e) { + done(e); + } + }; + + IconvLiteEncoderStream.prototype._flush = function (done) { + try { + var res = this.conv.end(); + if (res && res.length) this.push(res); + done(); + } catch (e) { + done(e); + } + }; + + IconvLiteEncoderStream.prototype.collect = function (cb) { + var chunks = []; + this.on('error', cb); + this.on('data', function (chunk) { + chunks.push(chunk); + }); + this.on('end', function () { + cb(null, Buffer.concat(chunks)); + }); + return this; + }; + + // == Decoder stream ======================================================= + function IconvLiteDecoderStream(conv, options) { + this.conv = conv; + options = options || {}; + options.encoding = this.encoding = 'utf8'; // We output strings. + Transform.call(this, options); + } + + IconvLiteDecoderStream.prototype = Object.create(Transform.prototype, { + constructor: { value: IconvLiteDecoderStream } + }); + + IconvLiteDecoderStream.prototype._transform = function (chunk, encoding, done) { + if (!Buffer.isBuffer(chunk)) return done(new Error("Iconv decoding stream needs buffers as its input.")); + try { + var res = this.conv.write(chunk); + if (res && res.length) this.push(res, this.encoding); + done(); + } catch (e) { + done(e); + } + }; + + IconvLiteDecoderStream.prototype._flush = function (done) { + try { + var res = this.conv.end(); + if (res && res.length) this.push(res, this.encoding); + done(); + } catch (e) { + done(e); + } + }; + + IconvLiteDecoderStream.prototype.collect = function (cb) { + var res = ''; + this.on('error', cb); + this.on('data', function (chunk) { + res += chunk; + }); + this.on('end', function () { + cb(null, res); + }); + return this; + }; +}); + +var __moduleExports$83 = createCommonjsModule(function (module) { + "use strict"; + + // == Extend Node primitives to use iconv-lite ================================= + + module.exports = function (iconv) { + var original = undefined; // Place to keep original methods. + + // Node authors rewrote Buffer internals to make it compatible with + // Uint8Array and we cannot patch key functions since then. + iconv.supportsNodeEncodingsExtension = !(new Buffer(0) instanceof Uint8Array); + + iconv.extendNodeEncodings = function extendNodeEncodings() { + if (original) return; + original = {}; + + if (!iconv.supportsNodeEncodingsExtension) { + console.error("ACTION NEEDED: require('iconv-lite').extendNodeEncodings() is not supported in your version of Node"); + console.error("See more info at https://github.com/ashtuchkin/iconv-lite/wiki/Node-v4-compatibility"); + return; + } + + var nodeNativeEncodings = { + 'hex': true, 'utf8': true, 'utf-8': true, 'ascii': true, 'binary': true, + 'base64': true, 'ucs2': true, 'ucs-2': true, 'utf16le': true, 'utf-16le': true + }; + + Buffer.isNativeEncoding = function (enc) { + return enc && nodeNativeEncodings[enc.toLowerCase()]; + }; + + // -- SlowBuffer ----------------------------------------------------------- + var SlowBuffer = buffer.SlowBuffer; + + original.SlowBufferToString = SlowBuffer.prototype.toString; + SlowBuffer.prototype.toString = function (encoding, start, end) { + encoding = String(encoding || 'utf8').toLowerCase(); + + // Use native conversion when possible + if (Buffer.isNativeEncoding(encoding)) return original.SlowBufferToString.call(this, encoding, start, end); + + // Otherwise, use our decoding method. + if (typeof start == 'undefined') start = 0; + if (typeof end == 'undefined') end = this.length; + return iconv.decode(this.slice(start, end), encoding); + }; + + original.SlowBufferWrite = SlowBuffer.prototype.write; + SlowBuffer.prototype.write = function (string, offset, length, encoding) { + // Support both (string, offset, length, encoding) + // and the legacy (string, encoding, offset, length) + if (isFinite(offset)) { + if (!isFinite(length)) { + encoding = length; + length = undefined; + } + } else { + // legacy + var swap = encoding; + encoding = offset; + offset = length; + length = swap; + } + + offset = +offset || 0; + var remaining = this.length - offset; + if (!length) { + length = remaining; + } else { + length = +length; + if (length > remaining) { + length = remaining; + } + } + encoding = String(encoding || 'utf8').toLowerCase(); + + // Use native conversion when possible + if (Buffer.isNativeEncoding(encoding)) return original.SlowBufferWrite.call(this, string, offset, length, encoding); + + if (string.length > 0 && (length < 0 || offset < 0)) throw new RangeError('attempt to write beyond buffer bounds'); + + // Otherwise, use our encoding method. + var buf = iconv.encode(string, encoding); + if (buf.length < length) length = buf.length; + buf.copy(this, offset, 0, length); + return length; + }; + + // -- Buffer --------------------------------------------------------------- + + original.BufferIsEncoding = Buffer.isEncoding; + Buffer.isEncoding = function (encoding) { + return Buffer.isNativeEncoding(encoding) || iconv.encodingExists(encoding); + }; + + original.BufferByteLength = Buffer.byteLength; + Buffer.byteLength = SlowBuffer.byteLength = function (str, encoding) { + encoding = String(encoding || 'utf8').toLowerCase(); + + // Use native conversion when possible + if (Buffer.isNativeEncoding(encoding)) return original.BufferByteLength.call(this, str, encoding); + + // Slow, I know, but we don't have a better way yet. + return iconv.encode(str, encoding).length; + }; + + original.BufferToString = Buffer.prototype.toString; + Buffer.prototype.toString = function (encoding, start, end) { + encoding = String(encoding || 'utf8').toLowerCase(); + + // Use native conversion when possible + if (Buffer.isNativeEncoding(encoding)) return original.BufferToString.call(this, encoding, start, end); + + // Otherwise, use our decoding method. + if (typeof start == 'undefined') start = 0; + if (typeof end == 'undefined') end = this.length; + return iconv.decode(this.slice(start, end), encoding); + }; + + original.BufferWrite = Buffer.prototype.write; + Buffer.prototype.write = function (string, offset, length, encoding) { + var _offset = offset, + _length = length, + _encoding = encoding; + // Support both (string, offset, length, encoding) + // and the legacy (string, encoding, offset, length) + if (isFinite(offset)) { + if (!isFinite(length)) { + encoding = length; + length = undefined; + } + } else { + // legacy + var swap = encoding; + encoding = offset; + offset = length; + length = swap; + } + + encoding = String(encoding || 'utf8').toLowerCase(); + + // Use native conversion when possible + if (Buffer.isNativeEncoding(encoding)) return original.BufferWrite.call(this, string, _offset, _length, _encoding); + + offset = +offset || 0; + var remaining = this.length - offset; + if (!length) { + length = remaining; + } else { + length = +length; + if (length > remaining) { + length = remaining; + } + } + + if (string.length > 0 && (length < 0 || offset < 0)) throw new RangeError('attempt to write beyond buffer bounds'); + + // Otherwise, use our encoding method. + var buf = iconv.encode(string, encoding); + if (buf.length < length) length = buf.length; + buf.copy(this, offset, 0, length); + return length; + + // TODO: Set _charsWritten. + }; + + // -- Readable ------------------------------------------------------------- + if (iconv.supportsStreams) { + var Readable = stream.Readable; + + original.ReadableSetEncoding = Readable.prototype.setEncoding; + Readable.prototype.setEncoding = function setEncoding(enc, options) { + // Use our own decoder, it has the same interface. + // We cannot use original function as it doesn't handle BOM-s. + this._readableState.decoder = iconv.getDecoder(enc, options); + this._readableState.encoding = enc; + }; + + Readable.prototype.collect = iconv._collect; + } + }; + + // Remove iconv-lite Node primitive extensions. + iconv.undoExtendNodeEncodings = function undoExtendNodeEncodings() { + if (!iconv.supportsNodeEncodingsExtension) return; + if (!original) throw new Error("require('iconv-lite').undoExtendNodeEncodings(): Nothing to undo; extendNodeEncodings() is not called."); + + delete Buffer.isNativeEncoding; + + var SlowBuffer = buffer.SlowBuffer; + + SlowBuffer.prototype.toString = original.SlowBufferToString; + SlowBuffer.prototype.write = original.SlowBufferWrite; + + Buffer.isEncoding = original.BufferIsEncoding; + Buffer.byteLength = original.BufferByteLength; + Buffer.prototype.toString = original.BufferToString; + Buffer.prototype.write = original.BufferWrite; + + if (iconv.supportsStreams) { + var Readable = stream.Readable; + + Readable.prototype.setEncoding = original.ReadableSetEncoding; + delete Readable.prototype.collect; + } + + original = undefined; + }; + }; +}); + +var __moduleExports$71 = createCommonjsModule(function (module) { + "use strict"; + + var bomHandling = __moduleExports$72, + iconv = module.exports; + + // All codecs and aliases are kept here, keyed by encoding name/alias. + // They are lazy loaded in `iconv.getCodec` from `encodings/index.js`. + iconv.encodings = null; + + // Characters emitted in case of error. + iconv.defaultCharUnicode = '�'; + iconv.defaultCharSingleByte = '?'; + + // Public API. + iconv.encode = function encode(str, encoding, options) { + str = "" + (str || ""); // Ensure string. + + var encoder = iconv.getEncoder(encoding, options); + + var res = encoder.write(str); + var trail = encoder.end(); + + return trail && trail.length > 0 ? Buffer.concat([res, trail]) : res; + }; + + iconv.decode = function decode(buf, encoding, options) { + if (typeof buf === 'string') { + if (!iconv.skipDecodeWarning) { + console.error('Iconv-lite warning: decode()-ing strings is deprecated. Refer to https://github.com/ashtuchkin/iconv-lite/wiki/Use-Buffers-when-decoding'); + iconv.skipDecodeWarning = true; + } + + buf = new Buffer("" + (buf || ""), "binary"); // Ensure buffer. + } + + var decoder = iconv.getDecoder(encoding, options); + + var res = decoder.write(buf); + var trail = decoder.end(); + + return trail ? res + trail : res; + }; + + iconv.encodingExists = function encodingExists(enc) { + try { + iconv.getCodec(enc); + return true; + } catch (e) { + return false; + } + }; + + // Legacy aliases to convert functions + iconv.toEncoding = iconv.encode; + iconv.fromEncoding = iconv.decode; + + // Search for a codec in iconv.encodings. Cache codec data in iconv._codecDataCache. + iconv._codecDataCache = {}; + iconv.getCodec = function getCodec(encoding) { + if (!iconv.encodings) iconv.encodings = __moduleExports$73; // Lazy load all encoding definitions. + + // Canonicalize encoding name: strip all non-alphanumeric chars and appended year. + var enc = ('' + encoding).toLowerCase().replace(/[^0-9a-z]|:\d{4}$/g, ""); + + // Traverse iconv.encodings to find actual codec. + var codecOptions = {}; + while (true) { + var codec = iconv._codecDataCache[enc]; + if (codec) return codec; + + var codecDef = iconv.encodings[enc]; + + switch (typeof codecDef === 'undefined' ? 'undefined' : _typeof$1(codecDef)) { + case "string": + // Direct alias to other encoding. + enc = codecDef; + break; + + case "object": + // Alias with options. Can be layered. + for (var key in codecDef) { + codecOptions[key] = codecDef[key]; + }if (!codecOptions.encodingName) codecOptions.encodingName = enc; + + enc = codecDef.type; + break; + + case "function": + // Codec itself. + if (!codecOptions.encodingName) codecOptions.encodingName = enc; + + // The codec function must load all tables and return object with .encoder and .decoder methods. + // It'll be called only once (for each different options object). + codec = new codecDef(codecOptions, iconv); + + iconv._codecDataCache[codecOptions.encodingName] = codec; // Save it to be reused later. + return codec; + + default: + throw new Error("Encoding not recognized: '" + encoding + "' (searched as: '" + enc + "')"); + } + } + }; + + iconv.getEncoder = function getEncoder(encoding, options) { + var codec = iconv.getCodec(encoding), + encoder = new codec.encoder(options, codec); + + if (codec.bomAware && options && options.addBOM) encoder = new bomHandling.PrependBOM(encoder, options); + + return encoder; + }; + + iconv.getDecoder = function getDecoder(encoding, options) { + var codec = iconv.getCodec(encoding), + decoder = new codec.decoder(options, codec); + + if (codec.bomAware && !(options && options.stripBOM === false)) decoder = new bomHandling.StripBOM(decoder, options); + + return decoder; + }; + + // Load extensions in Node. All of them are omitted in Browserify build via 'browser' field in package.json. + var nodeVer = typeof process !== 'undefined' && process.versions && process.versions.node; + if (nodeVer) { + + // Load streaming support in Node v0.10+ + var nodeVerArr = nodeVer.split(".").map(Number); + if (nodeVerArr[0] > 0 || nodeVerArr[1] >= 10) { + __moduleExports$82(iconv); + } + + // Load Node primitive extensions. + __moduleExports$83(iconv); + } +}); + +var __moduleExports$69 = createCommonjsModule(function (module) { + /*! + * raw-body + * Copyright(c) 2013-2014 Jonathan Ong + * Copyright(c) 2014-2015 Douglas Christopher Wilson + * MIT Licensed + */ + + 'use strict'; + + /** + * Module dependencies. + * @private + */ + + var bytes = __moduleExports$70; + var iconv = __moduleExports$71; + var unpipe = __moduleExports$12; + + /** + * Module exports. + * @public + */ + + module.exports = getRawBody; + + /** + * Module variables. + * @private + */ + + var iconvEncodingMessageRegExp = /^Encoding not recognized: /; + + /** + * Get the decoder for a given encoding. + * + * @param {string} encoding + * @private + */ + + function getDecoder(encoding) { + if (!encoding) return null; + + try { + return iconv.getDecoder(encoding); + } catch (e) { + // error getting decoder + if (!iconvEncodingMessageRegExp.test(e.message)) throw e; + + // the encoding was not found + throw createError(415, 'specified encoding unsupported', 'encoding.unsupported', { + encoding: encoding + }); + } + } + + /** + * Get the raw body of a stream (typically HTTP). + * + * @param {object} stream + * @param {object|string|function} [options] + * @param {function} [callback] + * @public + */ + + function getRawBody(stream, options, callback) { + var done = callback; + var opts = options || {}; + + if (options === true || typeof options === 'string') { + // short cut for encoding + opts = { + encoding: options + }; + } + + if (typeof options === 'function') { + done = options; + opts = {}; + } + + // validate callback is a function, if provided + if (done !== undefined && typeof done !== 'function') { + throw new TypeError('argument callback must be a function'); + } + + // require the callback without promises + if (!done && !commonjsGlobal.Promise) { + throw new TypeError('argument callback is required'); + } + + // get encoding + var encoding = opts.encoding !== true ? opts.encoding : 'utf-8'; + + // convert the limit to an integer + var limit = bytes.parse(opts.limit); + + // convert the expected length to an integer + var length = opts.length != null && !isNaN(opts.length) ? parseInt(opts.length, 10) : null; + + if (done) { + // classic callback style + return readStream(stream, encoding, length, limit, done); + } + + return new Promise(function executor(resolve, reject) { + readStream(stream, encoding, length, limit, function onRead(err, buf) { + if (err) return reject(err); + resolve(buf); + }); + }); + } + + /** + * Halt a stream. + * + * @param {Object} stream + * @private + */ + + function halt(stream) { + // unpipe everything from the stream + unpipe(stream); + + // pause stream + if (typeof stream.pause === 'function') { + stream.pause(); + } + } + + /** + * Make a serializable error object. + * + * To create serializable errors you must re-set message so + * that it is enumerable and you must re configure the type + * property so that is writable and enumerable. + * + * @param {number} status + * @param {string} message + * @param {string} type + * @param {object} props + * @private + */ + + function createError(status, message, type, props) { + var error = new Error(); + + // capture stack trace + Error.captureStackTrace(error, createError); + + // set free-form properties + for (var prop in props) { + error[prop] = props[prop]; + } + + // set message + error.message = message; + + // set status + error.status = status; + error.statusCode = status; + + // set type + Object.defineProperty(error, 'type', { + value: type, + enumerable: true, + writable: true, + configurable: true + }); + + return error; + } + + /** + * Read the data from the stream. + * + * @param {object} stream + * @param {string} encoding + * @param {number} length + * @param {number} limit + * @param {function} callback + * @public + */ + + function readStream(stream, encoding, length, limit, callback) { + var complete = false; + var sync = true; + + // check the length and limit options. + // note: we intentionally leave the stream paused, + // so users should handle the stream themselves. + if (limit !== null && length !== null && length > limit) { + return done(createError(413, 'request entity too large', 'entity.too.large', { + expected: length, + length: length, + limit: limit + })); + } + + // streams1: assert request encoding is buffer. + // streams2+: assert the stream encoding is buffer. + // stream._decoder: streams1 + // state.encoding: streams2 + // state.decoder: streams2, specifically < 0.10.6 + var state = stream._readableState; + if (stream._decoder || state && (state.encoding || state.decoder)) { + // developer error + return done(createError(500, 'stream encoding should not be set', 'stream.encoding.set')); + } + + var received = 0; + var decoder; + + try { + decoder = getDecoder(encoding); + } catch (err) { + return done(err); + } + + var buffer = decoder ? '' : []; + + // attach listeners + stream.on('aborted', onAborted); + stream.on('close', cleanup); + stream.on('data', onData); + stream.on('end', onEnd); + stream.on('error', onEnd); + + // mark sync section complete + sync = false; + + function done() { + var args = new Array(arguments.length); + + // copy arguments + for (var i = 0; i < args.length; i++) { + args[i] = arguments[i]; + } + + // mark complete + complete = true; + + if (sync) { + process.nextTick(invokeCallback); + } else { + invokeCallback(); + } + + function invokeCallback() { + cleanup(); + + if (args[0]) { + // halt the stream on error + halt(stream); + } + + callback.apply(null, args); + } + } + + function onAborted() { + if (complete) return; + + done(createError(400, 'request aborted', 'request.aborted', { + code: 'ECONNABORTED', + expected: length, + length: length, + received: received + })); + } + + function onData(chunk) { + if (complete) return; + + received += chunk.length; + decoder ? buffer += decoder.write(chunk) : buffer.push(chunk); + + if (limit !== null && received > limit) { + done(createError(413, 'request entity too large', 'entity.too.large', { + limit: limit, + received: received + })); + } + } + + function onEnd(err) { + if (complete) return; + if (err) return done(err); + + if (length !== null && received !== length) { + done(createError(400, 'request size did not match content length', 'request.size.invalid', { + expected: length, + length: length, + received: received + })); + } else { + var string = decoder ? buffer + (decoder.end() || '') : Buffer.concat(buffer); + done(null, string); + } + } + + function cleanup() { + buffer = null; + + stream.removeListener('aborted', onAborted); + stream.removeListener('data', onData); + stream.removeListener('end', onEnd); + stream.removeListener('error', onEnd); + stream.removeListener('close', cleanup); + } + } +}); + +var __moduleExports$68 = createCommonjsModule(function (module) { + /*! + * body-parser + * Copyright(c) 2014-2015 Douglas Christopher Wilson + * MIT Licensed + */ + + 'use strict'; + + /** + * Module dependencies. + * @private + */ + + var createError = __moduleExports$37; + var getBody = __moduleExports$69; + var iconv = __moduleExports$71; + var onFinished = __moduleExports$9; + var zlib$$ = zlib; + + /** + * Module exports. + */ + + module.exports = read; + + /** + * Read a request into a buffer and parse. + * + * @param {object} req + * @param {object} res + * @param {function} next + * @param {function} parse + * @param {function} debug + * @param {object} [options] + * @api private + */ + + function read(req, res, next, parse, debug, options) { + var length; + var opts = options || {}; + var stream; + + // flag as parsed + req._body = true; + + // read options + var encoding = opts.encoding !== null ? opts.encoding || 'utf-8' : null; + var verify = opts.verify; + + try { + // get the content stream + stream = contentstream(req, debug, opts.inflate); + length = stream.length; + stream.length = undefined; + } catch (err) { + return next(err); + } + + // set raw-body options + opts.length = length; + opts.encoding = verify ? null : encoding; + + // assert charset is supported + if (opts.encoding === null && encoding !== null && !iconv.encodingExists(encoding)) { + return next(createError(415, 'unsupported charset "' + encoding.toUpperCase() + '"', { + charset: encoding.toLowerCase() + })); + } + + // read body + debug('read body'); + getBody(stream, opts, function (err, body) { + if (err) { + // default to 400 + setErrorStatus(err, 400); + + // echo back charset + if (err.type === 'encoding.unsupported') { + err = createError(415, 'unsupported charset "' + encoding.toUpperCase() + '"', { + charset: encoding.toLowerCase() + }); + } + + // read off entire request + stream.resume(); + onFinished(req, function onfinished() { + next(err); + }); + return; + } + + // verify + if (verify) { + try { + debug('verify body'); + verify(req, res, body, encoding); + } catch (err) { + // default to 403 + setErrorStatus(err, 403); + next(err); + return; + } + } + + // parse + var str; + try { + debug('parse body'); + str = typeof body !== 'string' && encoding !== null ? iconv.decode(body, encoding) : body; + req.body = parse(str); + } catch (err) { + err.body = str === undefined ? body : str; + + // default to 400 + setErrorStatus(err, 400); + + next(err); + return; + } + + next(); + }); + } + + /** + * Get the content stream of the request. + * + * @param {object} req + * @param {function} debug + * @param {boolean} [inflate=true] + * @return {object} + * @api private + */ + + function contentstream(req, debug, inflate) { + var encoding = (req.headers['content-encoding'] || 'identity').toLowerCase(); + var length = req.headers['content-length']; + var stream; + + debug('content-encoding "%s"', encoding); + + if (inflate === false && encoding !== 'identity') { + throw createError(415, 'content encoding unsupported'); + } + + switch (encoding) { + case 'deflate': + stream = zlib$$.createInflate(); + debug('inflate body'); + req.pipe(stream); + break; + case 'gzip': + stream = zlib$$.createGunzip(); + debug('gunzip body'); + req.pipe(stream); + break; + case 'identity': + stream = req; + stream.length = length; + break; + default: + throw createError(415, 'unsupported content encoding "' + encoding + '"', { + encoding: encoding + }); + } + + return stream; + } + + /** + * Set a status on an error object, if ones does not exist + * @private + */ + + function setErrorStatus(error, status) { + if (!error.status && !error.statusCode) { + error.status = status; + error.statusCode = status; + } + } +}); + +var __moduleExports$66 = createCommonjsModule(function (module) { + /*! + * body-parser + * Copyright(c) 2014 Jonathan Ong + * Copyright(c) 2014-2015 Douglas Christopher Wilson + * MIT Licensed + */ + + 'use strict'; + + /** + * Module dependencies. + * @private + */ + + var bytes = __moduleExports$67; + var contentType = __moduleExports$35; + var createError = __moduleExports$37; + var debug = __moduleExports$5('body-parser:json'); + var read = __moduleExports$68; + var typeis = __moduleExports$58; + + /** + * Module exports. + */ + + module.exports = json; + + /** + * RegExp to match the first non-space in a string. + * + * Allowed whitespace is defined in RFC 7159: + * + * ws = *( + * %x20 / ; Space + * %x09 / ; Horizontal tab + * %x0A / ; Line feed or New line + * %x0D ) ; Carriage return + */ + + var FIRST_CHAR_REGEXP = /^[\x20\x09\x0a\x0d]*(.)/; // eslint-disable-line no-control-regex + + /** + * Create a middleware to parse JSON bodies. + * + * @param {object} [options] + * @return {function} + * @public + */ + + function json(options) { + var opts = options || {}; + + var limit = typeof opts.limit !== 'number' ? bytes.parse(opts.limit || '100kb') : opts.limit; + var inflate = opts.inflate !== false; + var reviver = opts.reviver; + var strict = opts.strict !== false; + var type = opts.type || 'application/json'; + var verify = opts.verify || false; + + if (verify !== false && typeof verify !== 'function') { + throw new TypeError('option verify must be function'); + } + + // create the appropriate type checking function + var shouldParse = typeof type !== 'function' ? typeChecker(type) : type; + + function parse(body) { + if (body.length === 0) { + // special-case empty json body, as it's a common client-side mistake + // TODO: maybe make this configurable or part of "strict" option + return {}; + } + + if (strict) { + var first = firstchar(body); + + if (first !== '{' && first !== '[') { + debug('strict violation'); + throw new SyntaxError('Unexpected token ' + first); + } + } + + debug('parse json'); + return JSON.parse(body, reviver); + } + + return function jsonParser(req, res, next) { + if (req._body) { + debug('body already parsed'); + next(); + return; + } + + req.body = req.body || {}; + + // skip requests without bodies + if (!typeis.hasBody(req)) { + debug('skip empty body'); + next(); + return; + } + + debug('content-type %j', req.headers['content-type']); + + // determine if request should be parsed + if (!shouldParse(req)) { + debug('skip parsing'); + next(); + return; + } + + // assert charset per RFC 7159 sec 8.1 + var charset = getCharset(req) || 'utf-8'; + if (charset.substr(0, 4) !== 'utf-') { + debug('invalid charset'); + next(createError(415, 'unsupported charset "' + charset.toUpperCase() + '"', { + charset: charset + })); + return; + } + + // read + read(req, res, next, parse, debug, { + encoding: charset, + inflate: inflate, + limit: limit, + verify: verify + }); + }; + } + + /** + * Get the first non-whitespace character in a string. + * + * @param {string} str + * @return {function} + * @api public + */ + + function firstchar(str) { + var match = FIRST_CHAR_REGEXP.exec(str); + return match ? match[1] : ''; + } + + /** + * Get the charset of a request. + * + * @param {object} req + * @api private + */ + + function getCharset(req) { + try { + return contentType.parse(req).parameters.charset.toLowerCase(); + } catch (e) { + return undefined; + } + } + + /** + * Get the simple type checker. + * + * @param {string} type + * @return {function} + */ + + function typeChecker(type) { + return function checkType(req) { + return Boolean(typeis(req, type)); + }; + } +}); + +var __moduleExports$84 = createCommonjsModule(function (module) { + /*! + * body-parser + * Copyright(c) 2014-2015 Douglas Christopher Wilson + * MIT Licensed + */ + + 'use strict'; + + /** + * Module dependencies. + */ + + var bytes = __moduleExports$67; + var debug = __moduleExports$5('body-parser:raw'); + var read = __moduleExports$68; + var typeis = __moduleExports$58; + + /** + * Module exports. + */ + + module.exports = raw; + + /** + * Create a middleware to parse raw bodies. + * + * @param {object} [options] + * @return {function} + * @api public + */ + + function raw(options) { + var opts = options || {}; + + var inflate = opts.inflate !== false; + var limit = typeof opts.limit !== 'number' ? bytes.parse(opts.limit || '100kb') : opts.limit; + var type = opts.type || 'application/octet-stream'; + var verify = opts.verify || false; + + if (verify !== false && typeof verify !== 'function') { + throw new TypeError('option verify must be function'); + } + + // create the appropriate type checking function + var shouldParse = typeof type !== 'function' ? typeChecker(type) : type; + + function parse(buf) { + return buf; + } + + return function rawParser(req, res, next) { + if (req._body) { + debug('body already parsed'); + next(); + return; + } + + req.body = req.body || {}; + + // skip requests without bodies + if (!typeis.hasBody(req)) { + debug('skip empty body'); + next(); + return; + } + + debug('content-type %j', req.headers['content-type']); + + // determine if request should be parsed + if (!shouldParse(req)) { + debug('skip parsing'); + next(); + return; + } + + // read + read(req, res, next, parse, debug, { + encoding: null, + inflate: inflate, + limit: limit, + verify: verify + }); + }; + } + + /** + * Get the simple type checker. + * + * @param {string} type + * @return {function} + */ + + function typeChecker(type) { + return function checkType(req) { + return Boolean(typeis(req, type)); + }; + } +}); + +var __moduleExports$85 = createCommonjsModule(function (module) { + /*! + * body-parser + * Copyright(c) 2014-2015 Douglas Christopher Wilson + * MIT Licensed + */ + + 'use strict'; + + /** + * Module dependencies. + */ + + var bytes = __moduleExports$67; + var contentType = __moduleExports$35; + var debug = __moduleExports$5('body-parser:text'); + var read = __moduleExports$68; + var typeis = __moduleExports$58; + + /** + * Module exports. + */ + + module.exports = text; + + /** + * Create a middleware to parse text bodies. + * + * @param {object} [options] + * @return {function} + * @api public + */ + + function text(options) { + var opts = options || {}; + + var defaultCharset = opts.defaultCharset || 'utf-8'; + var inflate = opts.inflate !== false; + var limit = typeof opts.limit !== 'number' ? bytes.parse(opts.limit || '100kb') : opts.limit; + var type = opts.type || 'text/plain'; + var verify = opts.verify || false; + + if (verify !== false && typeof verify !== 'function') { + throw new TypeError('option verify must be function'); + } + + // create the appropriate type checking function + var shouldParse = typeof type !== 'function' ? typeChecker(type) : type; + + function parse(buf) { + return buf; + } + + return function textParser(req, res, next) { + if (req._body) { + debug('body already parsed'); + next(); + return; + } + + req.body = req.body || {}; + + // skip requests without bodies + if (!typeis.hasBody(req)) { + debug('skip empty body'); + next(); + return; + } + + debug('content-type %j', req.headers['content-type']); + + // determine if request should be parsed + if (!shouldParse(req)) { + debug('skip parsing'); + next(); + return; + } + + // get charset + var charset = getCharset(req) || defaultCharset; + + // read + read(req, res, next, parse, debug, { + encoding: charset, + inflate: inflate, + limit: limit, + verify: verify + }); + }; + } + + /** + * Get the charset of a request. + * + * @param {object} req + * @api private + */ + + function getCharset(req) { + try { + return contentType.parse(req).parameters.charset.toLowerCase(); + } catch (e) { + return undefined; + } + } + + /** + * Get the simple type checker. + * + * @param {string} type + * @return {function} + */ + + function typeChecker(type) { + return function checkType(req) { + return Boolean(typeis(req, type)); + }; + } +}); + +var __moduleExports$89 = createCommonjsModule(function (module, exports) { + 'use strict'; + + var hexTable = function () { + var array = new Array(256); + for (var i = 0; i < 256; ++i) { + array[i] = '%' + ((i < 16 ? '0' : '') + i.toString(16)).toUpperCase(); + } + + return array; + }(); + + exports.arrayToObject = function (source, options) { + var obj = options.plainObjects ? Object.create(null) : {}; + for (var i = 0; i < source.length; ++i) { + if (typeof source[i] !== 'undefined') { + obj[i] = source[i]; + } + } + + return obj; + }; + + exports.merge = function (target, source, options) { + if (!source) { + return target; + } + + if ((typeof source === 'undefined' ? 'undefined' : _typeof$1(source)) !== 'object') { + if (Array.isArray(target)) { + target.push(source); + } else if ((typeof target === 'undefined' ? 'undefined' : _typeof$1(target)) === 'object') { + target[source] = true; + } else { + return [target, source]; + } + + return target; + } + + if ((typeof target === 'undefined' ? 'undefined' : _typeof$1(target)) !== 'object') { + return [target].concat(source); + } + + var mergeTarget = target; + if (Array.isArray(target) && !Array.isArray(source)) { + mergeTarget = exports.arrayToObject(target, options); + } + + return Object.keys(source).reduce(function (acc, key) { + var value = source[key]; + + if (Object.prototype.hasOwnProperty.call(acc, key)) { + acc[key] = exports.merge(acc[key], value, options); + } else { + acc[key] = value; + } + return acc; + }, mergeTarget); + }; + + exports.decode = function (str) { + try { + return decodeURIComponent(str.replace(/\+/g, ' ')); + } catch (e) { + return str; + } + }; + + exports.encode = function (str) { + // This code was originally written by Brian White (mscdex) for the io.js core querystring library. + // It has been adapted here for stricter adherence to RFC 3986 + if (str.length === 0) { + return str; + } + + var string = typeof str === 'string' ? str : String(str); + + var out = ''; + for (var i = 0; i < string.length; ++i) { + var c = string.charCodeAt(i); + + if (c === 0x2D || // - + c === 0x2E || // . + c === 0x5F || // _ + c === 0x7E || // ~ + c >= 0x30 && c <= 0x39 || // 0-9 + c >= 0x41 && c <= 0x5A || // a-z + c >= 0x61 && c <= 0x7A // A-Z + ) { + out += string.charAt(i); + continue; + } + + if (c < 0x80) { + out = out + hexTable[c]; + continue; + } + + if (c < 0x800) { + out = out + (hexTable[0xC0 | c >> 6] + hexTable[0x80 | c & 0x3F]); + continue; + } + + if (c < 0xD800 || c >= 0xE000) { + out = out + (hexTable[0xE0 | c >> 12] + hexTable[0x80 | c >> 6 & 0x3F] + hexTable[0x80 | c & 0x3F]); + continue; + } + + i += 1; + c = 0x10000 + ((c & 0x3FF) << 10 | string.charCodeAt(i) & 0x3FF); + out += hexTable[0xF0 | c >> 18] + hexTable[0x80 | c >> 12 & 0x3F] + hexTable[0x80 | c >> 6 & 0x3F] + hexTable[0x80 | c & 0x3F]; + } + + return out; + }; + + exports.compact = function (obj, references) { + if ((typeof obj === 'undefined' ? 'undefined' : _typeof$1(obj)) !== 'object' || obj === null) { + return obj; + } + + var refs = references || []; + var lookup = refs.indexOf(obj); + if (lookup !== -1) { + return refs[lookup]; + } + + refs.push(obj); + + if (Array.isArray(obj)) { + var compacted = []; + + for (var i = 0; i < obj.length; ++i) { + if (obj[i] && _typeof$1(obj[i]) === 'object') { + compacted.push(exports.compact(obj[i], refs)); + } else if (typeof obj[i] !== 'undefined') { + compacted.push(obj[i]); + } + } + + return compacted; + } + + var keys = Object.keys(obj); + for (var j = 0; j < keys.length; ++j) { + var key = keys[j]; + 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 (obj === null || typeof obj === 'undefined') { + return false; + } + + return !!(obj.constructor && obj.constructor.isBuffer && obj.constructor.isBuffer(obj)); + }; +}); + +var __moduleExports$88 = createCommonjsModule(function (module) { + 'use strict'; + + var Utils = __moduleExports$89; + + var arrayPrefixGenerators = { + brackets: function brackets(prefix) { + return prefix + '[]'; + }, + indices: function indices(prefix, key) { + return prefix + '[' + key + ']'; + }, + repeat: function repeat(prefix) { + return prefix; + } + }; + + var defaults = { + delimiter: '&', + strictNullHandling: false, + skipNulls: false, + encode: true, + encoder: Utils.encode + }; + + var stringify = function stringify(object, prefix, generateArrayPrefix, strictNullHandling, skipNulls, encoder, filter, sort, allowDots) { + var obj = object; + if (typeof filter === 'function') { + obj = filter(prefix, obj); + } else if (obj instanceof Date) { + obj = obj.toISOString(); + } else if (obj === null) { + if (strictNullHandling) { + return encoder ? encoder(prefix) : prefix; + } + + obj = ''; + } + + if (typeof obj === 'string' || typeof obj === 'number' || typeof obj === 'boolean' || Utils.isBuffer(obj)) { + if (encoder) { + return [encoder(prefix) + '=' + encoder(obj)]; + } + return [prefix + '=' + String(obj)]; + } + + var values = []; + + if (typeof obj === 'undefined') { + return values; + } + + var objKeys; + if (Array.isArray(filter)) { + objKeys = filter; + } else { + var keys = Object.keys(obj); + objKeys = sort ? keys.sort(sort) : keys; + } + + for (var i = 0; i < objKeys.length; ++i) { + var key = objKeys[i]; + + if (skipNulls && obj[key] === null) { + continue; + } + + if (Array.isArray(obj)) { + values = values.concat(stringify(obj[key], generateArrayPrefix(prefix, key), generateArrayPrefix, strictNullHandling, skipNulls, encoder, filter, sort, allowDots)); + } else { + values = values.concat(stringify(obj[key], prefix + (allowDots ? '.' + key : '[' + key + ']'), generateArrayPrefix, strictNullHandling, skipNulls, encoder, filter, sort, allowDots)); + } + } + + return values; + }; + + module.exports = function (object, opts) { + var obj = object; + var options = opts || {}; + var delimiter = typeof options.delimiter === 'undefined' ? defaults.delimiter : options.delimiter; + var strictNullHandling = typeof options.strictNullHandling === 'boolean' ? options.strictNullHandling : defaults.strictNullHandling; + var skipNulls = typeof options.skipNulls === 'boolean' ? options.skipNulls : defaults.skipNulls; + var encode = typeof options.encode === 'boolean' ? options.encode : defaults.encode; + var encoder = encode ? typeof options.encoder === 'function' ? options.encoder : defaults.encoder : null; + var sort = typeof options.sort === 'function' ? options.sort : null; + var allowDots = typeof options.allowDots === 'undefined' ? false : options.allowDots; + var objKeys; + var filter; + + if (options.encoder !== null && options.encoder !== undefined && typeof options.encoder !== 'function') { + throw new TypeError('Encoder has to be a function.'); + } + + if (typeof options.filter === 'function') { + filter = options.filter; + obj = filter('', obj); + } else if (Array.isArray(options.filter)) { + objKeys = filter = options.filter; + } + + var keys = []; + + if ((typeof obj === 'undefined' ? 'undefined' : _typeof$1(obj)) !== 'object' || obj === null) { + return ''; + } + + var arrayFormat; + if (options.arrayFormat in arrayPrefixGenerators) { + arrayFormat = options.arrayFormat; + } else if ('indices' in options) { + arrayFormat = options.indices ? 'indices' : 'repeat'; + } else { + arrayFormat = 'indices'; + } + + var generateArrayPrefix = arrayPrefixGenerators[arrayFormat]; + + if (!objKeys) { + objKeys = Object.keys(obj); + } + + if (sort) { + objKeys.sort(sort); + } + + for (var i = 0; i < objKeys.length; ++i) { + var key = objKeys[i]; + + if (skipNulls && obj[key] === null) { + continue; + } + + keys = keys.concat(stringify(obj[key], key, generateArrayPrefix, strictNullHandling, skipNulls, encoder, filter, sort, allowDots)); + } + + return keys.join(delimiter); + }; +}); + +var __moduleExports$90 = createCommonjsModule(function (module) { + 'use strict'; + + var Utils = __moduleExports$89; + + var defaults = { + delimiter: '&', + depth: 5, + arrayLimit: 20, + parameterLimit: 1000, + strictNullHandling: false, + plainObjects: false, + allowPrototypes: false, + allowDots: false, + decoder: Utils.decode + }; + + var parseValues = function parseValues(str, options) { + var obj = {}; + var parts = str.split(options.delimiter, options.parameterLimit === Infinity ? undefined : options.parameterLimit); + + for (var i = 0; i < parts.length; ++i) { + var part = parts[i]; + var pos = part.indexOf(']=') === -1 ? part.indexOf('=') : part.indexOf(']=') + 1; + + if (pos === -1) { + obj[options.decoder(part)] = ''; + + if (options.strictNullHandling) { + obj[options.decoder(part)] = null; + } + } else { + var key = options.decoder(part.slice(0, pos)); + var val = options.decoder(part.slice(pos + 1)); + + if (Object.prototype.hasOwnProperty.call(obj, key)) { + obj[key] = [].concat(obj[key]).concat(val); + } else { + obj[key] = val; + } + } + } + + return obj; + }; + + var parseObject = function parseObject(chain, val, options) { + if (!chain.length) { + return val; + } + + var root = chain.shift(); + + var obj; + if (root === '[]') { + obj = []; + obj = obj.concat(parseObject(chain, val, options)); + } else { + obj = options.plainObjects ? Object.create(null) : {}; + var cleanRoot = root[0] === '[' && root[root.length - 1] === ']' ? root.slice(1, root.length - 1) : root; + var index = parseInt(cleanRoot, 10); + if (!isNaN(index) && root !== cleanRoot && String(index) === cleanRoot && index >= 0 && options.parseArrays && index <= options.arrayLimit) { + obj = []; + obj[index] = parseObject(chain, val, options); + } else { + obj[cleanRoot] = parseObject(chain, val, options); + } + } + + return obj; + }; + + var parseKeys = function parseKeys(givenKey, val, options) { + if (!givenKey) { + return; + } + + // Transform dot notation to bracket notation + var key = options.allowDots ? givenKey.replace(/\.([^\.\[]+)/g, '[$1]') : givenKey; + + // The regex chunks + + var parent = /^([^\[\]]*)/; + var child = /(\[[^\[\]]*\])/g; + + // Get the parent + + var segment = parent.exec(key); + + // Stash the parent if it exists + + var keys = []; + if (segment[1]) { + // If we aren't using plain objects, optionally prefix keys + // that would overwrite object prototype properties + if (!options.plainObjects && Object.prototype.hasOwnProperty(segment[1])) { + if (!options.allowPrototypes) { + return; + } + } + + 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 += 1; + if (!options.plainObjects && Object.prototype.hasOwnProperty(segment[1].replace(/\[|\]/g, ''))) { + if (!options.allowPrototypes) { + continue; + } + } + keys.push(segment[1]); + } + + // If there's a remainder, just add whatever is left + + if (segment) { + keys.push('[' + key.slice(segment.index) + ']'); + } + + return parseObject(keys, val, options); + }; + + module.exports = function (str, opts) { + var options = opts || {}; + + if (options.decoder !== null && options.decoder !== undefined && typeof options.decoder !== 'function') { + throw new TypeError('Decoder has to be a function.'); + } + + options.delimiter = typeof options.delimiter === 'string' || Utils.isRegExp(options.delimiter) ? options.delimiter : defaults.delimiter; + options.depth = typeof options.depth === 'number' ? options.depth : defaults.depth; + options.arrayLimit = typeof options.arrayLimit === 'number' ? options.arrayLimit : defaults.arrayLimit; + options.parseArrays = options.parseArrays !== false; + options.decoder = typeof options.decoder === 'function' ? options.decoder : defaults.decoder; + options.allowDots = typeof options.allowDots === 'boolean' ? options.allowDots : defaults.allowDots; + options.plainObjects = typeof options.plainObjects === 'boolean' ? options.plainObjects : defaults.plainObjects; + options.allowPrototypes = typeof options.allowPrototypes === 'boolean' ? options.allowPrototypes : defaults.allowPrototypes; + options.parameterLimit = typeof options.parameterLimit === 'number' ? options.parameterLimit : defaults.parameterLimit; + options.strictNullHandling = typeof options.strictNullHandling === 'boolean' ? options.strictNullHandling : defaults.strictNullHandling; + + if (str === '' || str === null || typeof str === 'undefined') { + return options.plainObjects ? Object.create(null) : {}; + } + + var tempObj = typeof str === 'string' ? parseValues(str, options) : str; + var obj = options.plainObjects ? Object.create(null) : {}; + + // Iterate over the keys and setup the new object + + var keys = Object.keys(tempObj); + for (var i = 0; i < keys.length; ++i) { + var key = keys[i]; + var newObj = parseKeys(key, tempObj[key], options); + obj = Utils.merge(obj, newObj, options); + } + + return Utils.compact(obj); + }; +}); + +var __moduleExports$87 = createCommonjsModule(function (module) { + 'use strict'; + + var Stringify = __moduleExports$88; + var Parse = __moduleExports$90; + + module.exports = { + stringify: Stringify, + parse: Parse + }; +}); + +var __moduleExports$86 = createCommonjsModule(function (module) { + /*! + * body-parser + * Copyright(c) 2014 Jonathan Ong + * Copyright(c) 2014-2015 Douglas Christopher Wilson + * MIT Licensed + */ + + 'use strict'; + + /** + * Module dependencies. + * @private + */ + + var bytes = __moduleExports$67; + var contentType = __moduleExports$35; + var createError = __moduleExports$37; + var debug = __moduleExports$5('body-parser:urlencoded'); + var deprecate = __moduleExports$20('body-parser'); + var read = __moduleExports$68; + var typeis = __moduleExports$58; + + /** + * Module exports. + */ + + module.exports = urlencoded; + + /** + * Cache of parser modules. + */ + + var parsers = Object.create(null); + + /** + * Create a middleware to parse urlencoded bodies. + * + * @param {object} [options] + * @return {function} + * @public + */ + + function urlencoded(options) { + var opts = options || {}; + + // notice because option default will flip in next major + if (opts.extended === undefined) { + deprecate('undefined extended: provide extended option'); + } + + var extended = opts.extended !== false; + var inflate = opts.inflate !== false; + var limit = typeof opts.limit !== 'number' ? bytes.parse(opts.limit || '100kb') : opts.limit; + var type = opts.type || 'application/x-www-form-urlencoded'; + var verify = opts.verify || false; + + if (verify !== false && typeof verify !== 'function') { + throw new TypeError('option verify must be function'); + } + + // create the appropriate query parser + var queryparse = extended ? extendedparser(opts) : simpleparser(opts); + + // create the appropriate type checking function + var shouldParse = typeof type !== 'function' ? typeChecker(type) : type; + + function parse(body) { + return body.length ? queryparse(body) : {}; + } + + return function urlencodedParser(req, res, next) { + if (req._body) { + debug('body already parsed'); + next(); + return; + } + + req.body = req.body || {}; + + // skip requests without bodies + if (!typeis.hasBody(req)) { + debug('skip empty body'); + next(); + return; + } + + debug('content-type %j', req.headers['content-type']); + + // determine if request should be parsed + if (!shouldParse(req)) { + debug('skip parsing'); + next(); + return; + } + + // assert charset + var charset = getCharset(req) || 'utf-8'; + if (charset !== 'utf-8') { + debug('invalid charset'); + next(createError(415, 'unsupported charset "' + charset.toUpperCase() + '"', { + charset: charset + })); + return; + } + + // read + read(req, res, next, parse, debug, { + debug: debug, + encoding: charset, + inflate: inflate, + limit: limit, + verify: verify + }); + }; + } + + /** + * Get the extended query parser. + * + * @param {object} options + */ + + function extendedparser(options) { + var parameterLimit = options.parameterLimit !== undefined ? options.parameterLimit : 1000; + var parse = parser('qs'); + + if (isNaN(parameterLimit) || parameterLimit < 1) { + throw new TypeError('option parameterLimit must be a positive number'); + } + + if (isFinite(parameterLimit)) { + parameterLimit = parameterLimit | 0; + } + + return function queryparse(body) { + var paramCount = parameterCount(body, parameterLimit); + + if (paramCount === undefined) { + debug('too many parameters'); + throw createError(413, 'too many parameters'); + } + + var arrayLimit = Math.max(100, paramCount); + + debug('parse extended urlencoding'); + return parse(body, { + allowPrototypes: true, + arrayLimit: arrayLimit, + depth: Infinity, + parameterLimit: parameterLimit + }); + }; + } + + /** + * Get the charset of a request. + * + * @param {object} req + * @api private + */ + + function getCharset(req) { + try { + return contentType.parse(req).parameters.charset.toLowerCase(); + } catch (e) { + return undefined; + } + } + + /** + * Count the number of parameters, stopping once limit reached + * + * @param {string} body + * @param {number} limit + * @api private + */ + + function parameterCount(body, limit) { + var count = 0; + var index = 0; + + while ((index = body.indexOf('&', index)) !== -1) { + count++; + index++; + + if (count === limit) { + return undefined; + } + } + + return count; + } + + /** + * Get parser for module name dynamically. + * + * @param {string} name + * @return {function} + * @api private + */ + + function parser(name) { + var mod = parsers[name]; + + if (mod !== undefined) { + return mod.parse; + } + + // this uses a switch for static require analysis + switch (name) { + case 'qs': + mod = __moduleExports$87; + break; + case 'querystring': + mod = querystring; + break; + } + + // store to prevent invoking require() + parsers[name] = mod; + + return mod.parse; + } + + /** + * Get the simple query parser. + * + * @param {object} options + */ + + function simpleparser(options) { + var parameterLimit = options.parameterLimit !== undefined ? options.parameterLimit : 1000; + var parse = parser('querystring'); + + if (isNaN(parameterLimit) || parameterLimit < 1) { + throw new TypeError('option parameterLimit must be a positive number'); + } + + if (isFinite(parameterLimit)) { + parameterLimit = parameterLimit | 0; + } + + return function queryparse(body) { + var paramCount = parameterCount(body, parameterLimit); + + if (paramCount === undefined) { + debug('too many parameters'); + throw createError(413, 'too many parameters'); + } + + debug('parse urlencoding'); + return parse(body, undefined, undefined, { maxKeys: parameterLimit }); + }; + } + + /** + * Get the simple type checker. + * + * @param {string} type + * @return {function} + */ + + function typeChecker(type) { + return function checkType(req) { + return Boolean(typeis(req, type)); + }; + } +}); + +var __moduleExports$65 = createCommonjsModule(function (module, exports) { + /*! + * body-parser + * Copyright(c) 2014-2015 Douglas Christopher Wilson + * MIT Licensed + */ + + 'use strict'; + + /** + * Module dependencies. + * @private + */ + + var deprecate = __moduleExports$20('body-parser'); + + /** + * Cache of loaded parsers. + * @private + */ + + var parsers = Object.create(null); + + /** + * @typedef Parsers + * @type {function} + * @property {function} json + * @property {function} raw + * @property {function} text + * @property {function} urlencoded + */ + + /** + * Module exports. + * @type {Parsers} + */ + + exports = module.exports = deprecate.function(bodyParser, 'bodyParser: use individual json/urlencoded middlewares'); + + /** + * JSON parser. + * @public + */ + + Object.defineProperty(exports, 'json', { + configurable: true, + enumerable: true, + get: createParserGetter('json') + }); + + /** + * Raw parser. + * @public + */ + + Object.defineProperty(exports, 'raw', { + configurable: true, + enumerable: true, + get: createParserGetter('raw') + }); + + /** + * Text parser. + * @public + */ + + Object.defineProperty(exports, 'text', { + configurable: true, + enumerable: true, + get: createParserGetter('text') + }); + + /** + * URL-encoded parser. + * @public + */ + + Object.defineProperty(exports, 'urlencoded', { + configurable: true, + enumerable: true, + get: createParserGetter('urlencoded') + }); + + /** + * Create a middleware to parse json and urlencoded bodies. + * + * @param {object} [options] + * @return {function} + * @deprecated + * @public + */ + + function bodyParser(options) { + var opts = {}; + + // exclude type option + if (options) { + for (var prop in options) { + if (prop !== 'type') { + opts[prop] = options[prop]; + } + } + } + + var _urlencoded = exports.urlencoded(opts); + var _json = exports.json(opts); + + return function bodyParser(req, res, next) { + _json(req, res, function (err) { + if (err) return next(err); + _urlencoded(req, res, next); + }); + }; + } + + /** + * Create a getter for loading a parser. + * @private + */ + + function createParserGetter(name) { + return function get() { + return loadParser(name); + }; + } + + /** + * Load a parser module. + * @private + */ + + function loadParser(parserName) { + var parser = parsers[parserName]; + + if (parser !== undefined) { + return parser; + } + + // this uses a switch for static require analysis + switch (parserName) { + case 'json': + parser = __moduleExports$66; + break; + case 'raw': + parser = __moduleExports$84; + break; + case 'text': + parser = __moduleExports$85; + break; + case 'urlencoded': + parser = __moduleExports$86; + break; + } + + // store to prevent invoking require() + return parsers[parserName] = parser; + } +}); + +var require$$2$1 = ( jsData_es2015 && jsData_es2015['default'] ) || jsData_es2015; + +var jsDataExpress = createCommonjsModule(function (module, exports) { + 'use strict'; + + function _interopDefault(ex) { + return ex && (typeof ex === 'undefined' ? 'undefined' : _typeof$1(ex)) === 'object' && 'default' in ex ? ex['default'] : ex; + } + + var jsData = require$$2$1; + var express = _interopDefault(__moduleExports); + var bodyParser = _interopDefault(__moduleExports$65); + + function parseQuery(query) { + if (query.where) { + try { + query.where = JSON.parse(query.where); + } catch (err) {} + } + if (query.orderBy || query.sort) { + var orderBy = query.orderBy || query.sort; + if (orderBy.length) { + query.orderBy = orderBy.map(function (clause) { + if (typeof clause === 'string') { + return JSON.parse(clause); + } + return clause; + }); + query.sort = undefined; + } + } + } + + function queryParser(req, res, next) { + req.jsdataOpts || (req.jsdataOpts = {}); + if (req.query.with) { + req.jsdataOpts.with = req.query.with; + delete req.query.with; + } + try { + parseQuery(req.query); + next(); + } catch (err) { + next(err); + } + } + + function makeHandler(handler) { + return function (req, res, next) { + return jsData.utils.resolve().then(function () { + return handler(req); + }).then(function (result) { + res.status(200); + if (!jsData.utils.isUndefined(result)) { + res.send(result); + } + res.end(); + }).catch(next); + }; + } + + function Router(component) { + if (!(component instanceof jsData.Mapper) && !(component instanceof jsData.Container)) { + throw new Error('You must provide an instance of JSData.Container, JSData.DataStore, or JSData.Mapper!'); + } + + var router = this.router = express.Router(); + router.use(bodyParser.json()); + router.use(bodyParser.urlencoded({ + extended: true + })); + + if (component instanceof jsData.Container) { + jsData.utils.forOwn(component._mappers, function (mapper, name) { + router.use('/' + (mapper.endpoint || name), new Router(mapper).router); + }); + } else if (component instanceof jsData.Mapper) { + router.route('/') + // GET /:resource + .get(makeHandler(function (req) { + return component.findAll(req.query, req.jsdataOpts); + })) + // POST /:resource + .post(makeHandler(function (req) { + if (jsData.utils.isArray(req.body)) { + return component.createMany(req.body, req.jsdataOpts); + } + return component.create(req.body, req.jsdataOpts); + })) + // PUT /:resource + .put(makeHandler(function (req) { + if (jsData.utils.isArray(req.body)) { + return component.updateMany(req.body, req.jsdataOpts); + } + return component.updateAll(req.body, req.query, req.jsdataOpts); + })) + // DELETE /:resource + .delete(makeHandler(function (req) { + return component.destroyAll(req.query, req.jsdataOpts); + })); + + router.route('/:id') + // GET /:resource/:id + .get(makeHandler(function (req) { + return component.find(req.params.id, req.jsdataOpts); + })) + // PUT /:resource/:id + .put(makeHandler(function (req) { + return component.update(req.params.id, req.body, req.jsdataOpts); + })) + // DELETE /:resource/:id + .delete(makeHandler(function (req) { + return component.destroy(req.params.id, req.jsdataOpts); + })); + } + } + + jsData.Component.extend({ + constructor: Router + }); + + /** + * Convenience method that mounts {@link queryParser} and a store. + * + * @example Mount queryParser and store at "/" + * import express from 'express' + * import {mount, queryParser, Router} from 'js-data-express' + * import {Container} from 'js-data' + * + * const app = express() + * const store = new Container() + * const UserMapper = store.defineMapper('user') + * const CommentMapper = store.defineMapper('comment') + * mount(app, store) + * + * @example Mount queryParser and store at "/api" + * mount(app, store, '/api') + * + * @name module:js-data-express.mount + * @type {Function} + * @param {*} app + * @param {*} store + * @param {string} [path] + */ + function mount(app, store, path) { + if (!(store instanceof jsData.Container)) { + throw new Error('You must provide an instance of JSData.Container or JSData.DataStore!'); + } + path || (path = '/'); + app.use(path, queryParser); + app.use(path, new Router(store).router); + } + + /** + * Details of the current version of the `js-data-express` module. + * + * @example ES2015 modules import + * import {version} from 'js-data-express' + * console.log(version.full) + * + * @example CommonJS import + * var version = require('js-data-express').version + * console.log(version.full) + * + * @name module:js-data-express.version + * @type {Object} + * @property {string} version.full The full semver value. + * @property {number} version.major The major version number. + * @property {number} version.minor The minor version number. + * @property {number} version.patch The patch version number. + * @property {(string|boolean)} version.alpha The alpha version value, + * otherwise `false` if the current version is not alpha. + * @property {(string|boolean)} version.beta The beta version value, + * otherwise `false` if the current version is not beta. + */ + var version = { + alpha: 1, + full: '1.0.0-alpha.1', + major: 1, + minor: 0, + patch: 0 + }; + + /** + * {@link Router} class. + * + * @example ES2015 modules import + * import {Router} from 'js-data-express' + * const adapter = new Router() + * + * @example CommonJS import + * var Router = require('js-data-express').Router + * var adapter = new Router() + * + * @name module:js-data-express.Router + * @see Router + * @type {Constructor} + */ + + /** + * Registered as `js-data-express` in NPM. + * + * @example Install from NPM + * npm i --save js-data-express@beta js-data@beta + * + * @example ES2015 modules import + * import {Router} from 'js-data-express' + * const adapter = new Router() + * + * @example CommonJS import + * var Router = require('js-data-express').Router + * var adapter = new Router() + * + * @module js-data-express + */ + + exports.Router = Router; + exports.mount = mount; + exports.version = version; + exports.parseQuery = parseQuery; + exports.queryParser = queryParser; + }); + +var queryParser = jsDataExpress.queryParser; +var Router = jsDataExpress.Router; + +var JsDataServerSetup = function () { + function JsDataServerSetup() { + var config = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; + classCallCheck(this, JsDataServerSetup); + + this.baseRoute = config.baseRoute || '/'; + this.app = config.app || __moduleExports(); + this.container = config.container || new Container(); + this.adapter = config.adapter; + // a hashmap of resource mappers + this.resources = {}; + // flag if router has been mounted to this.app + this._isMounted = false; + if (!this.adapter) throw new Error('JsDataServerSetup requires an a Js-Data Adapter'); + this.container.registerAdapter('defaultAdapter', this.adapter, { default: true }); + + this.apiRoutes = __moduleExports.Router(); + // use js-data-express's queryParser + this.apiRoutes.use(queryParser); + + return this; + } + + /** + * Mount the router to the app after all resources have been setup. + */ + + + createClass(JsDataServerSetup, [{ + key: 'mount', + value: function mount() { + this.app.use(this.baseRoute || '/', this.apiRoutes); + } + + /** + * Helper method for an array or hashmap of resources. This will invoke mount() + * after all resources are iterated unless the false is passed as the 2nd arg + * @name setup + * @param {array|object} resources - An array of resource objects or a hashmap of { resourceName => resourceConfig } + */ + + }, { + key: 'setup', + value: function setup(resources) { + var _this = this; + + var mount = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true; + + if (Array.isArray(resources)) { + resources.forEach(this.setupResource, this); + } else if ((typeof resources === 'undefined' ? 'undefined' : _typeof$1(resources)) === 'object') { + Object.keys(resources).forEach(function (resourceName) { + // ensure the resource has a name if we're processing a hashmap + !resources[resourceName].name ? resources[resourceName].name = resourceName : null; + _this.setupResource(resources[resourceName]); + }, this); + } else { + throw new Error('JsDataServerSetup.setup() requires an array or an hashmap of resources'); + } + + if (mount) { + this.mount(); + } + } + + /** + * Setup a mapper resource on this.container + * @param {object} options - The resource options for setup + * @param {string} [options.name=mapperConfig.name] - Name of the resource + * @param {object} [options.endpointConfig] - Config obj: http://api.js-data.io/js-data-express/1.0.0-rc.1/global.html#Config + * @param {object} [options.mapperConfig] - The config to be used on .defineMapper() + * @param {object} [options.adapter] - An adapter to use on this resource + * @param {object} [options.adapter.name] - The name of the adapter + */ + + }, { + key: 'setupResource', + value: function setupResource(_ref) { + var name = _ref.name; + var endpointConfig = _ref.endpointConfig; + var mapperConfig = _ref.mapperConfig; + var adapter = _ref.adapter; + + if (!name && !mapperConfig && !mapperConfig.name) throw new Error('JsDataServerSetup.setupResource() requires a resource name'); + mapperConfig || (mapperConfig = {}); + name || (name = mapperConfig.name); + this.resources[name] = this.container.defineMapper(Object.assign({ name: name }, mapperConfig)); + + if (adapter) this.resources[name].registerAdapter(this.resources[name], adapter); + + // mount this resource + this.apiRoutes.use('/' + name, new Router(this.resources[name], endpointConfig).router); + } + }, { + key: 'registerAdapter', + value: function registerAdapter(component, adapter) { + var adapterName = adapter.name || 'noNameAdapter'; + try { + component.registerAdapter(adapterName, adapter, { default: true }); + } catch (e) { + console.log('JsDataServerSetup.setupResource() unable to registerAdapter ' + adapterName + ' on resource'); + throw new Error(e); + } + } + }]); + return JsDataServerSetup; +}(); + +module.exports = JsDataServerSetup; \ No newline at end of file diff --git a/package.json b/package.json index 8fe2f6f..c86c517 100644 --- a/package.json +++ b/package.json @@ -28,20 +28,18 @@ }, "devDependencies": { "babel-cli": "^6.14.0", - "babel-core": "^6.14.0", + "babel-core": "^6.17.0", "babel-loader": "^6.2.5", "babel-plugin-transform-react-jsx": "^6.8.0", - "babel-preset-es2015": "^6.14.0", + "babel-preset-es2015": "^6.16.0", "babel-preset-es2015-rollup": "^1.2.0", - "body-parser": "^1.15.2", - "js-data": "^3.0.0-rc.5", - "js-data-express": "^1.0.0-alpha.1", "mocha": "^3.0.2", "npm-watch": "^0.1.6", "nyc": "^8.1.0", "rollup": "^0.34.13", "rollup-plugin-babel": "^2.6.1", "rollup-plugin-commonjs": "^4.1.0", + "rollup-plugin-json": "^2.0.2", "rollup-plugin-node-resolve": "^2.0.0", "semantic-release": "^4.3.5", "standard": "^8.0.0", @@ -54,5 +52,10 @@ "it" ] }, - "homepage": "https://github.com/pizza-rolls/js-data-server-setup#readme" + "homepage": "https://github.com/pizza-rolls/js-data-server-setup#readme", + "dependencies": { + "body-parser": "^1.15.2", + "js-data": "^3.0.0-rc.5", + "js-data-express": "^1.0.0-alpha.1" + } } diff --git a/rollup.config.js b/rollup.config.js index 899b4ff..cd0b57d 100644 --- a/rollup.config.js +++ b/rollup.config.js @@ -3,6 +3,7 @@ import resolve from 'rollup-plugin-node-resolve' import commonjs from 'rollup-plugin-commonjs' import babel from 'rollup-plugin-babel' import es2015Rollup from 'babel-preset-es2015-rollup' +import json from 'rollup-plugin-json' export default { entry: 'src/index.js', @@ -15,14 +16,12 @@ export default { main: true // browser: true }), - // convert commonjs modules to es2015 module imports + json(), + // // convert commonjs modules to es2015 module imports commonjs(), // transform code with babel babel({ babelrc: false, - 'plugins': [ - ['transform-react-jsx'] - ], 'presets': [es2015Rollup] }) ] diff --git a/src/index.js b/src/index.js index 3251653..4c8e0d0 100644 --- a/src/index.js +++ b/src/index.js @@ -1,8 +1,8 @@ -import express from 'express' import { Router, queryParser } from 'js-data-express' import { Container } from 'js-data' +import express from 'express' -class JsDataServerSetup { +export default class JsDataServerSetup { constructor (config = {}) { this.baseRoute = config.baseRoute || '/' this.app = config.app || express() @@ -89,5 +89,3 @@ class JsDataServerSetup { } } } - -export default JsDataServerSetup