foxhound 1.0.41 → 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,3029 @@
1
+ (function (f) {
2
+ if (typeof exports === "object" && typeof module !== "undefined") {
3
+ module.exports = f();
4
+ } else if (typeof define === "function" && define.amd) {
5
+ define([], f);
6
+ } else {
7
+ var g;
8
+ if (typeof window !== "undefined") {
9
+ g = window;
10
+ } else if (typeof global !== "undefined") {
11
+ g = global;
12
+ } else if (typeof self !== "undefined") {
13
+ g = self;
14
+ } else {
15
+ g = this;
16
+ }
17
+ g.Foxhound = f();
18
+ }
19
+ })(function () {
20
+ var define, module, exports;
21
+ return function () {
22
+ function r(e, n, t) {
23
+ function o(i, f) {
24
+ if (!n[i]) {
25
+ if (!e[i]) {
26
+ var c = "function" == typeof require && require;
27
+ if (!f && c) return c(i, !0);
28
+ if (u) return u(i, !0);
29
+ var a = new Error("Cannot find module '" + i + "'");
30
+ throw a.code = "MODULE_NOT_FOUND", a;
31
+ }
32
+ var p = n[i] = {
33
+ exports: {}
34
+ };
35
+ e[i][0].call(p.exports, function (r) {
36
+ var n = e[i][1][r];
37
+ return o(n || r);
38
+ }, p, p.exports, r, e, n, t);
39
+ }
40
+ return n[i].exports;
41
+ }
42
+ for (var u = "function" == typeof require && require, i = 0; i < t.length; i++) o(t[i]);
43
+ return o;
44
+ }
45
+ return r;
46
+ }()({
47
+ 1: [function (require, module, exports) {
48
+ (function (global) {
49
+ (function () {
50
+ (function (global, factory) {
51
+ typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() : typeof define === 'function' && define.amd ? define('underscore', factory) : (global = typeof globalThis !== 'undefined' ? globalThis : global || self, function () {
52
+ var current = global._;
53
+ var exports = global._ = factory();
54
+ exports.noConflict = function () {
55
+ global._ = current;
56
+ return exports;
57
+ };
58
+ }());
59
+ })(this, function () {
60
+ // Underscore.js 1.13.6
61
+ // https://underscorejs.org
62
+ // (c) 2009-2022 Jeremy Ashkenas, Julian Gonggrijp, and DocumentCloud and Investigative Reporters & Editors
63
+ // Underscore may be freely distributed under the MIT license.
64
+
65
+ // Current version.
66
+ var VERSION = '1.13.6';
67
+
68
+ // Establish the root object, `window` (`self`) in the browser, `global`
69
+ // on the server, or `this` in some virtual machines. We use `self`
70
+ // instead of `window` for `WebWorker` support.
71
+ var root = typeof self == 'object' && self.self === self && self || typeof global == 'object' && global.global === global && global || Function('return this')() || {};
72
+
73
+ // Save bytes in the minified (but not gzipped) version:
74
+ var ArrayProto = Array.prototype,
75
+ ObjProto = Object.prototype;
76
+ var SymbolProto = typeof Symbol !== 'undefined' ? Symbol.prototype : null;
77
+
78
+ // Create quick reference variables for speed access to core prototypes.
79
+ var push = ArrayProto.push,
80
+ slice = ArrayProto.slice,
81
+ toString = ObjProto.toString,
82
+ hasOwnProperty = ObjProto.hasOwnProperty;
83
+
84
+ // Modern feature detection.
85
+ var supportsArrayBuffer = typeof ArrayBuffer !== 'undefined',
86
+ supportsDataView = typeof DataView !== 'undefined';
87
+
88
+ // All **ECMAScript 5+** native function implementations that we hope to use
89
+ // are declared here.
90
+ var nativeIsArray = Array.isArray,
91
+ nativeKeys = Object.keys,
92
+ nativeCreate = Object.create,
93
+ nativeIsView = supportsArrayBuffer && ArrayBuffer.isView;
94
+
95
+ // Create references to these builtin functions because we override them.
96
+ var _isNaN = isNaN,
97
+ _isFinite = isFinite;
98
+
99
+ // Keys in IE < 9 that won't be iterated by `for key in ...` and thus missed.
100
+ var hasEnumBug = !{
101
+ toString: null
102
+ }.propertyIsEnumerable('toString');
103
+ var nonEnumerableProps = ['valueOf', 'isPrototypeOf', 'toString', 'propertyIsEnumerable', 'hasOwnProperty', 'toLocaleString'];
104
+
105
+ // The largest integer that can be represented exactly.
106
+ var MAX_ARRAY_INDEX = Math.pow(2, 53) - 1;
107
+
108
+ // Some functions take a variable number of arguments, or a few expected
109
+ // arguments at the beginning and then a variable number of values to operate
110
+ // on. This helper accumulates all remaining arguments past the function’s
111
+ // argument length (or an explicit `startIndex`), into an array that becomes
112
+ // the last argument. Similar to ES6’s "rest parameter".
113
+ function restArguments(func, startIndex) {
114
+ startIndex = startIndex == null ? func.length - 1 : +startIndex;
115
+ return function () {
116
+ var length = Math.max(arguments.length - startIndex, 0),
117
+ rest = Array(length),
118
+ index = 0;
119
+ for (; index < length; index++) {
120
+ rest[index] = arguments[index + startIndex];
121
+ }
122
+ switch (startIndex) {
123
+ case 0:
124
+ return func.call(this, rest);
125
+ case 1:
126
+ return func.call(this, arguments[0], rest);
127
+ case 2:
128
+ return func.call(this, arguments[0], arguments[1], rest);
129
+ }
130
+ var args = Array(startIndex + 1);
131
+ for (index = 0; index < startIndex; index++) {
132
+ args[index] = arguments[index];
133
+ }
134
+ args[startIndex] = rest;
135
+ return func.apply(this, args);
136
+ };
137
+ }
138
+
139
+ // Is a given variable an object?
140
+ function isObject(obj) {
141
+ var type = typeof obj;
142
+ return type === 'function' || type === 'object' && !!obj;
143
+ }
144
+
145
+ // Is a given value equal to null?
146
+ function isNull(obj) {
147
+ return obj === null;
148
+ }
149
+
150
+ // Is a given variable undefined?
151
+ function isUndefined(obj) {
152
+ return obj === void 0;
153
+ }
154
+
155
+ // Is a given value a boolean?
156
+ function isBoolean(obj) {
157
+ return obj === true || obj === false || toString.call(obj) === '[object Boolean]';
158
+ }
159
+
160
+ // Is a given value a DOM element?
161
+ function isElement(obj) {
162
+ return !!(obj && obj.nodeType === 1);
163
+ }
164
+
165
+ // Internal function for creating a `toString`-based type tester.
166
+ function tagTester(name) {
167
+ var tag = '[object ' + name + ']';
168
+ return function (obj) {
169
+ return toString.call(obj) === tag;
170
+ };
171
+ }
172
+ var isString = tagTester('String');
173
+ var isNumber = tagTester('Number');
174
+ var isDate = tagTester('Date');
175
+ var isRegExp = tagTester('RegExp');
176
+ var isError = tagTester('Error');
177
+ var isSymbol = tagTester('Symbol');
178
+ var isArrayBuffer = tagTester('ArrayBuffer');
179
+ var isFunction = tagTester('Function');
180
+
181
+ // Optimize `isFunction` if appropriate. Work around some `typeof` bugs in old
182
+ // v8, IE 11 (#1621), Safari 8 (#1929), and PhantomJS (#2236).
183
+ var nodelist = root.document && root.document.childNodes;
184
+ if (typeof /./ != 'function' && typeof Int8Array != 'object' && typeof nodelist != 'function') {
185
+ isFunction = function (obj) {
186
+ return typeof obj == 'function' || false;
187
+ };
188
+ }
189
+ var isFunction$1 = isFunction;
190
+ var hasObjectTag = tagTester('Object');
191
+
192
+ // In IE 10 - Edge 13, `DataView` has string tag `'[object Object]'`.
193
+ // In IE 11, the most common among them, this problem also applies to
194
+ // `Map`, `WeakMap` and `Set`.
195
+ var hasStringTagBug = supportsDataView && hasObjectTag(new DataView(new ArrayBuffer(8))),
196
+ isIE11 = typeof Map !== 'undefined' && hasObjectTag(new Map());
197
+ var isDataView = tagTester('DataView');
198
+
199
+ // In IE 10 - Edge 13, we need a different heuristic
200
+ // to determine whether an object is a `DataView`.
201
+ function ie10IsDataView(obj) {
202
+ return obj != null && isFunction$1(obj.getInt8) && isArrayBuffer(obj.buffer);
203
+ }
204
+ var isDataView$1 = hasStringTagBug ? ie10IsDataView : isDataView;
205
+
206
+ // Is a given value an array?
207
+ // Delegates to ECMA5's native `Array.isArray`.
208
+ var isArray = nativeIsArray || tagTester('Array');
209
+
210
+ // Internal function to check whether `key` is an own property name of `obj`.
211
+ function has$1(obj, key) {
212
+ return obj != null && hasOwnProperty.call(obj, key);
213
+ }
214
+ var isArguments = tagTester('Arguments');
215
+
216
+ // Define a fallback version of the method in browsers (ahem, IE < 9), where
217
+ // there isn't any inspectable "Arguments" type.
218
+ (function () {
219
+ if (!isArguments(arguments)) {
220
+ isArguments = function (obj) {
221
+ return has$1(obj, 'callee');
222
+ };
223
+ }
224
+ })();
225
+ var isArguments$1 = isArguments;
226
+
227
+ // Is a given object a finite number?
228
+ function isFinite$1(obj) {
229
+ return !isSymbol(obj) && _isFinite(obj) && !isNaN(parseFloat(obj));
230
+ }
231
+
232
+ // Is the given value `NaN`?
233
+ function isNaN$1(obj) {
234
+ return isNumber(obj) && _isNaN(obj);
235
+ }
236
+
237
+ // Predicate-generating function. Often useful outside of Underscore.
238
+ function constant(value) {
239
+ return function () {
240
+ return value;
241
+ };
242
+ }
243
+
244
+ // Common internal logic for `isArrayLike` and `isBufferLike`.
245
+ function createSizePropertyCheck(getSizeProperty) {
246
+ return function (collection) {
247
+ var sizeProperty = getSizeProperty(collection);
248
+ return typeof sizeProperty == 'number' && sizeProperty >= 0 && sizeProperty <= MAX_ARRAY_INDEX;
249
+ };
250
+ }
251
+
252
+ // Internal helper to generate a function to obtain property `key` from `obj`.
253
+ function shallowProperty(key) {
254
+ return function (obj) {
255
+ return obj == null ? void 0 : obj[key];
256
+ };
257
+ }
258
+
259
+ // Internal helper to obtain the `byteLength` property of an object.
260
+ var getByteLength = shallowProperty('byteLength');
261
+
262
+ // Internal helper to determine whether we should spend extensive checks against
263
+ // `ArrayBuffer` et al.
264
+ var isBufferLike = createSizePropertyCheck(getByteLength);
265
+
266
+ // Is a given value a typed array?
267
+ var typedArrayPattern = /\[object ((I|Ui)nt(8|16|32)|Float(32|64)|Uint8Clamped|Big(I|Ui)nt64)Array\]/;
268
+ function isTypedArray(obj) {
269
+ // `ArrayBuffer.isView` is the most future-proof, so use it when available.
270
+ // Otherwise, fall back on the above regular expression.
271
+ return nativeIsView ? nativeIsView(obj) && !isDataView$1(obj) : isBufferLike(obj) && typedArrayPattern.test(toString.call(obj));
272
+ }
273
+ var isTypedArray$1 = supportsArrayBuffer ? isTypedArray : constant(false);
274
+
275
+ // Internal helper to obtain the `length` property of an object.
276
+ var getLength = shallowProperty('length');
277
+
278
+ // Internal helper to create a simple lookup structure.
279
+ // `collectNonEnumProps` used to depend on `_.contains`, but this led to
280
+ // circular imports. `emulatedSet` is a one-off solution that only works for
281
+ // arrays of strings.
282
+ function emulatedSet(keys) {
283
+ var hash = {};
284
+ for (var l = keys.length, i = 0; i < l; ++i) hash[keys[i]] = true;
285
+ return {
286
+ contains: function (key) {
287
+ return hash[key] === true;
288
+ },
289
+ push: function (key) {
290
+ hash[key] = true;
291
+ return keys.push(key);
292
+ }
293
+ };
294
+ }
295
+
296
+ // Internal helper. Checks `keys` for the presence of keys in IE < 9 that won't
297
+ // be iterated by `for key in ...` and thus missed. Extends `keys` in place if
298
+ // needed.
299
+ function collectNonEnumProps(obj, keys) {
300
+ keys = emulatedSet(keys);
301
+ var nonEnumIdx = nonEnumerableProps.length;
302
+ var constructor = obj.constructor;
303
+ var proto = isFunction$1(constructor) && constructor.prototype || ObjProto;
304
+
305
+ // Constructor is a special case.
306
+ var prop = 'constructor';
307
+ if (has$1(obj, prop) && !keys.contains(prop)) keys.push(prop);
308
+ while (nonEnumIdx--) {
309
+ prop = nonEnumerableProps[nonEnumIdx];
310
+ if (prop in obj && obj[prop] !== proto[prop] && !keys.contains(prop)) {
311
+ keys.push(prop);
312
+ }
313
+ }
314
+ }
315
+
316
+ // Retrieve the names of an object's own properties.
317
+ // Delegates to **ECMAScript 5**'s native `Object.keys`.
318
+ function keys(obj) {
319
+ if (!isObject(obj)) return [];
320
+ if (nativeKeys) return nativeKeys(obj);
321
+ var keys = [];
322
+ for (var key in obj) if (has$1(obj, key)) keys.push(key);
323
+ // Ahem, IE < 9.
324
+ if (hasEnumBug) collectNonEnumProps(obj, keys);
325
+ return keys;
326
+ }
327
+
328
+ // Is a given array, string, or object empty?
329
+ // An "empty" object has no enumerable own-properties.
330
+ function isEmpty(obj) {
331
+ if (obj == null) return true;
332
+ // Skip the more expensive `toString`-based type checks if `obj` has no
333
+ // `.length`.
334
+ var length = getLength(obj);
335
+ if (typeof length == 'number' && (isArray(obj) || isString(obj) || isArguments$1(obj))) return length === 0;
336
+ return getLength(keys(obj)) === 0;
337
+ }
338
+
339
+ // Returns whether an object has a given set of `key:value` pairs.
340
+ function isMatch(object, attrs) {
341
+ var _keys = keys(attrs),
342
+ length = _keys.length;
343
+ if (object == null) return !length;
344
+ var obj = Object(object);
345
+ for (var i = 0; i < length; i++) {
346
+ var key = _keys[i];
347
+ if (attrs[key] !== obj[key] || !(key in obj)) return false;
348
+ }
349
+ return true;
350
+ }
351
+
352
+ // If Underscore is called as a function, it returns a wrapped object that can
353
+ // be used OO-style. This wrapper holds altered versions of all functions added
354
+ // through `_.mixin`. Wrapped objects may be chained.
355
+ function _$1(obj) {
356
+ if (obj instanceof _$1) return obj;
357
+ if (!(this instanceof _$1)) return new _$1(obj);
358
+ this._wrapped = obj;
359
+ }
360
+ _$1.VERSION = VERSION;
361
+
362
+ // Extracts the result from a wrapped and chained object.
363
+ _$1.prototype.value = function () {
364
+ return this._wrapped;
365
+ };
366
+
367
+ // Provide unwrapping proxies for some methods used in engine operations
368
+ // such as arithmetic and JSON stringification.
369
+ _$1.prototype.valueOf = _$1.prototype.toJSON = _$1.prototype.value;
370
+ _$1.prototype.toString = function () {
371
+ return String(this._wrapped);
372
+ };
373
+
374
+ // Internal function to wrap or shallow-copy an ArrayBuffer,
375
+ // typed array or DataView to a new view, reusing the buffer.
376
+ function toBufferView(bufferSource) {
377
+ return new Uint8Array(bufferSource.buffer || bufferSource, bufferSource.byteOffset || 0, getByteLength(bufferSource));
378
+ }
379
+
380
+ // We use this string twice, so give it a name for minification.
381
+ var tagDataView = '[object DataView]';
382
+
383
+ // Internal recursive comparison function for `_.isEqual`.
384
+ function eq(a, b, aStack, bStack) {
385
+ // Identical objects are equal. `0 === -0`, but they aren't identical.
386
+ // See the [Harmony `egal` proposal](https://wiki.ecmascript.org/doku.php?id=harmony:egal).
387
+ if (a === b) return a !== 0 || 1 / a === 1 / b;
388
+ // `null` or `undefined` only equal to itself (strict comparison).
389
+ if (a == null || b == null) return false;
390
+ // `NaN`s are equivalent, but non-reflexive.
391
+ if (a !== a) return b !== b;
392
+ // Exhaust primitive checks
393
+ var type = typeof a;
394
+ if (type !== 'function' && type !== 'object' && typeof b != 'object') return false;
395
+ return deepEq(a, b, aStack, bStack);
396
+ }
397
+
398
+ // Internal recursive comparison function for `_.isEqual`.
399
+ function deepEq(a, b, aStack, bStack) {
400
+ // Unwrap any wrapped objects.
401
+ if (a instanceof _$1) a = a._wrapped;
402
+ if (b instanceof _$1) b = b._wrapped;
403
+ // Compare `[[Class]]` names.
404
+ var className = toString.call(a);
405
+ if (className !== toString.call(b)) return false;
406
+ // Work around a bug in IE 10 - Edge 13.
407
+ if (hasStringTagBug && className == '[object Object]' && isDataView$1(a)) {
408
+ if (!isDataView$1(b)) return false;
409
+ className = tagDataView;
410
+ }
411
+ switch (className) {
412
+ // These types are compared by value.
413
+ case '[object RegExp]':
414
+ // RegExps are coerced to strings for comparison (Note: '' + /a/i === '/a/i')
415
+ case '[object String]':
416
+ // Primitives and their corresponding object wrappers are equivalent; thus, `"5"` is
417
+ // equivalent to `new String("5")`.
418
+ return '' + a === '' + b;
419
+ case '[object Number]':
420
+ // `NaN`s are equivalent, but non-reflexive.
421
+ // Object(NaN) is equivalent to NaN.
422
+ if (+a !== +a) return +b !== +b;
423
+ // An `egal` comparison is performed for other numeric values.
424
+ return +a === 0 ? 1 / +a === 1 / b : +a === +b;
425
+ case '[object Date]':
426
+ case '[object Boolean]':
427
+ // Coerce dates and booleans to numeric primitive values. Dates are compared by their
428
+ // millisecond representations. Note that invalid dates with millisecond representations
429
+ // of `NaN` are not equivalent.
430
+ return +a === +b;
431
+ case '[object Symbol]':
432
+ return SymbolProto.valueOf.call(a) === SymbolProto.valueOf.call(b);
433
+ case '[object ArrayBuffer]':
434
+ case tagDataView:
435
+ // Coerce to typed array so we can fall through.
436
+ return deepEq(toBufferView(a), toBufferView(b), aStack, bStack);
437
+ }
438
+ var areArrays = className === '[object Array]';
439
+ if (!areArrays && isTypedArray$1(a)) {
440
+ var byteLength = getByteLength(a);
441
+ if (byteLength !== getByteLength(b)) return false;
442
+ if (a.buffer === b.buffer && a.byteOffset === b.byteOffset) return true;
443
+ areArrays = true;
444
+ }
445
+ if (!areArrays) {
446
+ if (typeof a != 'object' || typeof b != 'object') return false;
447
+
448
+ // Objects with different constructors are not equivalent, but `Object`s or `Array`s
449
+ // from different frames are.
450
+ var aCtor = a.constructor,
451
+ bCtor = b.constructor;
452
+ if (aCtor !== bCtor && !(isFunction$1(aCtor) && aCtor instanceof aCtor && isFunction$1(bCtor) && bCtor instanceof bCtor) && 'constructor' in a && 'constructor' in b) {
453
+ return false;
454
+ }
455
+ }
456
+ // Assume equality for cyclic structures. The algorithm for detecting cyclic
457
+ // structures is adapted from ES 5.1 section 15.12.3, abstract operation `JO`.
458
+
459
+ // Initializing stack of traversed objects.
460
+ // It's done here since we only need them for objects and arrays comparison.
461
+ aStack = aStack || [];
462
+ bStack = bStack || [];
463
+ var length = aStack.length;
464
+ while (length--) {
465
+ // Linear search. Performance is inversely proportional to the number of
466
+ // unique nested structures.
467
+ if (aStack[length] === a) return bStack[length] === b;
468
+ }
469
+
470
+ // Add the first object to the stack of traversed objects.
471
+ aStack.push(a);
472
+ bStack.push(b);
473
+
474
+ // Recursively compare objects and arrays.
475
+ if (areArrays) {
476
+ // Compare array lengths to determine if a deep comparison is necessary.
477
+ length = a.length;
478
+ if (length !== b.length) return false;
479
+ // Deep compare the contents, ignoring non-numeric properties.
480
+ while (length--) {
481
+ if (!eq(a[length], b[length], aStack, bStack)) return false;
482
+ }
483
+ } else {
484
+ // Deep compare objects.
485
+ var _keys = keys(a),
486
+ key;
487
+ length = _keys.length;
488
+ // Ensure that both objects contain the same number of properties before comparing deep equality.
489
+ if (keys(b).length !== length) return false;
490
+ while (length--) {
491
+ // Deep compare each member
492
+ key = _keys[length];
493
+ if (!(has$1(b, key) && eq(a[key], b[key], aStack, bStack))) return false;
494
+ }
495
+ }
496
+ // Remove the first object from the stack of traversed objects.
497
+ aStack.pop();
498
+ bStack.pop();
499
+ return true;
500
+ }
501
+
502
+ // Perform a deep comparison to check if two objects are equal.
503
+ function isEqual(a, b) {
504
+ return eq(a, b);
505
+ }
506
+
507
+ // Retrieve all the enumerable property names of an object.
508
+ function allKeys(obj) {
509
+ if (!isObject(obj)) return [];
510
+ var keys = [];
511
+ for (var key in obj) keys.push(key);
512
+ // Ahem, IE < 9.
513
+ if (hasEnumBug) collectNonEnumProps(obj, keys);
514
+ return keys;
515
+ }
516
+
517
+ // Since the regular `Object.prototype.toString` type tests don't work for
518
+ // some types in IE 11, we use a fingerprinting heuristic instead, based
519
+ // on the methods. It's not great, but it's the best we got.
520
+ // The fingerprint method lists are defined below.
521
+ function ie11fingerprint(methods) {
522
+ var length = getLength(methods);
523
+ return function (obj) {
524
+ if (obj == null) return false;
525
+ // `Map`, `WeakMap` and `Set` have no enumerable keys.
526
+ var keys = allKeys(obj);
527
+ if (getLength(keys)) return false;
528
+ for (var i = 0; i < length; i++) {
529
+ if (!isFunction$1(obj[methods[i]])) return false;
530
+ }
531
+ // If we are testing against `WeakMap`, we need to ensure that
532
+ // `obj` doesn't have a `forEach` method in order to distinguish
533
+ // it from a regular `Map`.
534
+ return methods !== weakMapMethods || !isFunction$1(obj[forEachName]);
535
+ };
536
+ }
537
+
538
+ // In the interest of compact minification, we write
539
+ // each string in the fingerprints only once.
540
+ var forEachName = 'forEach',
541
+ hasName = 'has',
542
+ commonInit = ['clear', 'delete'],
543
+ mapTail = ['get', hasName, 'set'];
544
+
545
+ // `Map`, `WeakMap` and `Set` each have slightly different
546
+ // combinations of the above sublists.
547
+ var mapMethods = commonInit.concat(forEachName, mapTail),
548
+ weakMapMethods = commonInit.concat(mapTail),
549
+ setMethods = ['add'].concat(commonInit, forEachName, hasName);
550
+ var isMap = isIE11 ? ie11fingerprint(mapMethods) : tagTester('Map');
551
+ var isWeakMap = isIE11 ? ie11fingerprint(weakMapMethods) : tagTester('WeakMap');
552
+ var isSet = isIE11 ? ie11fingerprint(setMethods) : tagTester('Set');
553
+ var isWeakSet = tagTester('WeakSet');
554
+
555
+ // Retrieve the values of an object's properties.
556
+ function values(obj) {
557
+ var _keys = keys(obj);
558
+ var length = _keys.length;
559
+ var values = Array(length);
560
+ for (var i = 0; i < length; i++) {
561
+ values[i] = obj[_keys[i]];
562
+ }
563
+ return values;
564
+ }
565
+
566
+ // Convert an object into a list of `[key, value]` pairs.
567
+ // The opposite of `_.object` with one argument.
568
+ function pairs(obj) {
569
+ var _keys = keys(obj);
570
+ var length = _keys.length;
571
+ var pairs = Array(length);
572
+ for (var i = 0; i < length; i++) {
573
+ pairs[i] = [_keys[i], obj[_keys[i]]];
574
+ }
575
+ return pairs;
576
+ }
577
+
578
+ // Invert the keys and values of an object. The values must be serializable.
579
+ function invert(obj) {
580
+ var result = {};
581
+ var _keys = keys(obj);
582
+ for (var i = 0, length = _keys.length; i < length; i++) {
583
+ result[obj[_keys[i]]] = _keys[i];
584
+ }
585
+ return result;
586
+ }
587
+
588
+ // Return a sorted list of the function names available on the object.
589
+ function functions(obj) {
590
+ var names = [];
591
+ for (var key in obj) {
592
+ if (isFunction$1(obj[key])) names.push(key);
593
+ }
594
+ return names.sort();
595
+ }
596
+
597
+ // An internal function for creating assigner functions.
598
+ function createAssigner(keysFunc, defaults) {
599
+ return function (obj) {
600
+ var length = arguments.length;
601
+ if (defaults) obj = Object(obj);
602
+ if (length < 2 || obj == null) return obj;
603
+ for (var index = 1; index < length; index++) {
604
+ var source = arguments[index],
605
+ keys = keysFunc(source),
606
+ l = keys.length;
607
+ for (var i = 0; i < l; i++) {
608
+ var key = keys[i];
609
+ if (!defaults || obj[key] === void 0) obj[key] = source[key];
610
+ }
611
+ }
612
+ return obj;
613
+ };
614
+ }
615
+
616
+ // Extend a given object with all the properties in passed-in object(s).
617
+ var extend = createAssigner(allKeys);
618
+
619
+ // Assigns a given object with all the own properties in the passed-in
620
+ // object(s).
621
+ // (https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object/assign)
622
+ var extendOwn = createAssigner(keys);
623
+
624
+ // Fill in a given object with default properties.
625
+ var defaults = createAssigner(allKeys, true);
626
+
627
+ // Create a naked function reference for surrogate-prototype-swapping.
628
+ function ctor() {
629
+ return function () {};
630
+ }
631
+
632
+ // An internal function for creating a new object that inherits from another.
633
+ function baseCreate(prototype) {
634
+ if (!isObject(prototype)) return {};
635
+ if (nativeCreate) return nativeCreate(prototype);
636
+ var Ctor = ctor();
637
+ Ctor.prototype = prototype;
638
+ var result = new Ctor();
639
+ Ctor.prototype = null;
640
+ return result;
641
+ }
642
+
643
+ // Creates an object that inherits from the given prototype object.
644
+ // If additional properties are provided then they will be added to the
645
+ // created object.
646
+ function create(prototype, props) {
647
+ var result = baseCreate(prototype);
648
+ if (props) extendOwn(result, props);
649
+ return result;
650
+ }
651
+
652
+ // Create a (shallow-cloned) duplicate of an object.
653
+ function clone(obj) {
654
+ if (!isObject(obj)) return obj;
655
+ return isArray(obj) ? obj.slice() : extend({}, obj);
656
+ }
657
+
658
+ // Invokes `interceptor` with the `obj` and then returns `obj`.
659
+ // The primary purpose of this method is to "tap into" a method chain, in
660
+ // order to perform operations on intermediate results within the chain.
661
+ function tap(obj, interceptor) {
662
+ interceptor(obj);
663
+ return obj;
664
+ }
665
+
666
+ // Normalize a (deep) property `path` to array.
667
+ // Like `_.iteratee`, this function can be customized.
668
+ function toPath$1(path) {
669
+ return isArray(path) ? path : [path];
670
+ }
671
+ _$1.toPath = toPath$1;
672
+
673
+ // Internal wrapper for `_.toPath` to enable minification.
674
+ // Similar to `cb` for `_.iteratee`.
675
+ function toPath(path) {
676
+ return _$1.toPath(path);
677
+ }
678
+
679
+ // Internal function to obtain a nested property in `obj` along `path`.
680
+ function deepGet(obj, path) {
681
+ var length = path.length;
682
+ for (var i = 0; i < length; i++) {
683
+ if (obj == null) return void 0;
684
+ obj = obj[path[i]];
685
+ }
686
+ return length ? obj : void 0;
687
+ }
688
+
689
+ // Get the value of the (deep) property on `path` from `object`.
690
+ // If any property in `path` does not exist or if the value is
691
+ // `undefined`, return `defaultValue` instead.
692
+ // The `path` is normalized through `_.toPath`.
693
+ function get(object, path, defaultValue) {
694
+ var value = deepGet(object, toPath(path));
695
+ return isUndefined(value) ? defaultValue : value;
696
+ }
697
+
698
+ // Shortcut function for checking if an object has a given property directly on
699
+ // itself (in other words, not on a prototype). Unlike the internal `has`
700
+ // function, this public version can also traverse nested properties.
701
+ function has(obj, path) {
702
+ path = toPath(path);
703
+ var length = path.length;
704
+ for (var i = 0; i < length; i++) {
705
+ var key = path[i];
706
+ if (!has$1(obj, key)) return false;
707
+ obj = obj[key];
708
+ }
709
+ return !!length;
710
+ }
711
+
712
+ // Keep the identity function around for default iteratees.
713
+ function identity(value) {
714
+ return value;
715
+ }
716
+
717
+ // Returns a predicate for checking whether an object has a given set of
718
+ // `key:value` pairs.
719
+ function matcher(attrs) {
720
+ attrs = extendOwn({}, attrs);
721
+ return function (obj) {
722
+ return isMatch(obj, attrs);
723
+ };
724
+ }
725
+
726
+ // Creates a function that, when passed an object, will traverse that object’s
727
+ // properties down the given `path`, specified as an array of keys or indices.
728
+ function property(path) {
729
+ path = toPath(path);
730
+ return function (obj) {
731
+ return deepGet(obj, path);
732
+ };
733
+ }
734
+
735
+ // Internal function that returns an efficient (for current engines) version
736
+ // of the passed-in callback, to be repeatedly applied in other Underscore
737
+ // functions.
738
+ function optimizeCb(func, context, argCount) {
739
+ if (context === void 0) return func;
740
+ switch (argCount == null ? 3 : argCount) {
741
+ case 1:
742
+ return function (value) {
743
+ return func.call(context, value);
744
+ };
745
+ // The 2-argument case is omitted because we’re not using it.
746
+ case 3:
747
+ return function (value, index, collection) {
748
+ return func.call(context, value, index, collection);
749
+ };
750
+ case 4:
751
+ return function (accumulator, value, index, collection) {
752
+ return func.call(context, accumulator, value, index, collection);
753
+ };
754
+ }
755
+ return function () {
756
+ return func.apply(context, arguments);
757
+ };
758
+ }
759
+
760
+ // An internal function to generate callbacks that can be applied to each
761
+ // element in a collection, returning the desired result — either `_.identity`,
762
+ // an arbitrary callback, a property matcher, or a property accessor.
763
+ function baseIteratee(value, context, argCount) {
764
+ if (value == null) return identity;
765
+ if (isFunction$1(value)) return optimizeCb(value, context, argCount);
766
+ if (isObject(value) && !isArray(value)) return matcher(value);
767
+ return property(value);
768
+ }
769
+
770
+ // External wrapper for our callback generator. Users may customize
771
+ // `_.iteratee` if they want additional predicate/iteratee shorthand styles.
772
+ // This abstraction hides the internal-only `argCount` argument.
773
+ function iteratee(value, context) {
774
+ return baseIteratee(value, context, Infinity);
775
+ }
776
+ _$1.iteratee = iteratee;
777
+
778
+ // The function we call internally to generate a callback. It invokes
779
+ // `_.iteratee` if overridden, otherwise `baseIteratee`.
780
+ function cb(value, context, argCount) {
781
+ if (_$1.iteratee !== iteratee) return _$1.iteratee(value, context);
782
+ return baseIteratee(value, context, argCount);
783
+ }
784
+
785
+ // Returns the results of applying the `iteratee` to each element of `obj`.
786
+ // In contrast to `_.map` it returns an object.
787
+ function mapObject(obj, iteratee, context) {
788
+ iteratee = cb(iteratee, context);
789
+ var _keys = keys(obj),
790
+ length = _keys.length,
791
+ results = {};
792
+ for (var index = 0; index < length; index++) {
793
+ var currentKey = _keys[index];
794
+ results[currentKey] = iteratee(obj[currentKey], currentKey, obj);
795
+ }
796
+ return results;
797
+ }
798
+
799
+ // Predicate-generating function. Often useful outside of Underscore.
800
+ function noop() {}
801
+
802
+ // Generates a function for a given object that returns a given property.
803
+ function propertyOf(obj) {
804
+ if (obj == null) return noop;
805
+ return function (path) {
806
+ return get(obj, path);
807
+ };
808
+ }
809
+
810
+ // Run a function **n** times.
811
+ function times(n, iteratee, context) {
812
+ var accum = Array(Math.max(0, n));
813
+ iteratee = optimizeCb(iteratee, context, 1);
814
+ for (var i = 0; i < n; i++) accum[i] = iteratee(i);
815
+ return accum;
816
+ }
817
+
818
+ // Return a random integer between `min` and `max` (inclusive).
819
+ function random(min, max) {
820
+ if (max == null) {
821
+ max = min;
822
+ min = 0;
823
+ }
824
+ return min + Math.floor(Math.random() * (max - min + 1));
825
+ }
826
+
827
+ // A (possibly faster) way to get the current timestamp as an integer.
828
+ var now = Date.now || function () {
829
+ return new Date().getTime();
830
+ };
831
+
832
+ // Internal helper to generate functions for escaping and unescaping strings
833
+ // to/from HTML interpolation.
834
+ function createEscaper(map) {
835
+ var escaper = function (match) {
836
+ return map[match];
837
+ };
838
+ // Regexes for identifying a key that needs to be escaped.
839
+ var source = '(?:' + keys(map).join('|') + ')';
840
+ var testRegexp = RegExp(source);
841
+ var replaceRegexp = RegExp(source, 'g');
842
+ return function (string) {
843
+ string = string == null ? '' : '' + string;
844
+ return testRegexp.test(string) ? string.replace(replaceRegexp, escaper) : string;
845
+ };
846
+ }
847
+
848
+ // Internal list of HTML entities for escaping.
849
+ var escapeMap = {
850
+ '&': '&amp;',
851
+ '<': '&lt;',
852
+ '>': '&gt;',
853
+ '"': '&quot;',
854
+ "'": '&#x27;',
855
+ '`': '&#x60;'
856
+ };
857
+
858
+ // Function for escaping strings to HTML interpolation.
859
+ var _escape = createEscaper(escapeMap);
860
+
861
+ // Internal list of HTML entities for unescaping.
862
+ var unescapeMap = invert(escapeMap);
863
+
864
+ // Function for unescaping strings from HTML interpolation.
865
+ var _unescape = createEscaper(unescapeMap);
866
+
867
+ // By default, Underscore uses ERB-style template delimiters. Change the
868
+ // following template settings to use alternative delimiters.
869
+ var templateSettings = _$1.templateSettings = {
870
+ evaluate: /<%([\s\S]+?)%>/g,
871
+ interpolate: /<%=([\s\S]+?)%>/g,
872
+ escape: /<%-([\s\S]+?)%>/g
873
+ };
874
+
875
+ // When customizing `_.templateSettings`, if you don't want to define an
876
+ // interpolation, evaluation or escaping regex, we need one that is
877
+ // guaranteed not to match.
878
+ var noMatch = /(.)^/;
879
+
880
+ // Certain characters need to be escaped so that they can be put into a
881
+ // string literal.
882
+ var escapes = {
883
+ "'": "'",
884
+ '\\': '\\',
885
+ '\r': 'r',
886
+ '\n': 'n',
887
+ '\u2028': 'u2028',
888
+ '\u2029': 'u2029'
889
+ };
890
+ var escapeRegExp = /\\|'|\r|\n|\u2028|\u2029/g;
891
+ function escapeChar(match) {
892
+ return '\\' + escapes[match];
893
+ }
894
+
895
+ // In order to prevent third-party code injection through
896
+ // `_.templateSettings.variable`, we test it against the following regular
897
+ // expression. It is intentionally a bit more liberal than just matching valid
898
+ // identifiers, but still prevents possible loopholes through defaults or
899
+ // destructuring assignment.
900
+ var bareIdentifier = /^\s*(\w|\$)+\s*$/;
901
+
902
+ // JavaScript micro-templating, similar to John Resig's implementation.
903
+ // Underscore templating handles arbitrary delimiters, preserves whitespace,
904
+ // and correctly escapes quotes within interpolated code.
905
+ // NB: `oldSettings` only exists for backwards compatibility.
906
+ function template(text, settings, oldSettings) {
907
+ if (!settings && oldSettings) settings = oldSettings;
908
+ settings = defaults({}, settings, _$1.templateSettings);
909
+
910
+ // Combine delimiters into one regular expression via alternation.
911
+ var matcher = RegExp([(settings.escape || noMatch).source, (settings.interpolate || noMatch).source, (settings.evaluate || noMatch).source].join('|') + '|$', 'g');
912
+
913
+ // Compile the template source, escaping string literals appropriately.
914
+ var index = 0;
915
+ var source = "__p+='";
916
+ text.replace(matcher, function (match, escape, interpolate, evaluate, offset) {
917
+ source += text.slice(index, offset).replace(escapeRegExp, escapeChar);
918
+ index = offset + match.length;
919
+ if (escape) {
920
+ source += "'+\n((__t=(" + escape + "))==null?'':_.escape(__t))+\n'";
921
+ } else if (interpolate) {
922
+ source += "'+\n((__t=(" + interpolate + "))==null?'':__t)+\n'";
923
+ } else if (evaluate) {
924
+ source += "';\n" + evaluate + "\n__p+='";
925
+ }
926
+
927
+ // Adobe VMs need the match returned to produce the correct offset.
928
+ return match;
929
+ });
930
+ source += "';\n";
931
+ var argument = settings.variable;
932
+ if (argument) {
933
+ // Insure against third-party code injection. (CVE-2021-23358)
934
+ if (!bareIdentifier.test(argument)) throw new Error('variable is not a bare identifier: ' + argument);
935
+ } else {
936
+ // If a variable is not specified, place data values in local scope.
937
+ source = 'with(obj||{}){\n' + source + '}\n';
938
+ argument = 'obj';
939
+ }
940
+ source = "var __t,__p='',__j=Array.prototype.join," + "print=function(){__p+=__j.call(arguments,'');};\n" + source + 'return __p;\n';
941
+ var render;
942
+ try {
943
+ render = new Function(argument, '_', source);
944
+ } catch (e) {
945
+ e.source = source;
946
+ throw e;
947
+ }
948
+ var template = function (data) {
949
+ return render.call(this, data, _$1);
950
+ };
951
+
952
+ // Provide the compiled source as a convenience for precompilation.
953
+ template.source = 'function(' + argument + '){\n' + source + '}';
954
+ return template;
955
+ }
956
+
957
+ // Traverses the children of `obj` along `path`. If a child is a function, it
958
+ // is invoked with its parent as context. Returns the value of the final
959
+ // child, or `fallback` if any child is undefined.
960
+ function result(obj, path, fallback) {
961
+ path = toPath(path);
962
+ var length = path.length;
963
+ if (!length) {
964
+ return isFunction$1(fallback) ? fallback.call(obj) : fallback;
965
+ }
966
+ for (var i = 0; i < length; i++) {
967
+ var prop = obj == null ? void 0 : obj[path[i]];
968
+ if (prop === void 0) {
969
+ prop = fallback;
970
+ i = length; // Ensure we don't continue iterating.
971
+ }
972
+
973
+ obj = isFunction$1(prop) ? prop.call(obj) : prop;
974
+ }
975
+ return obj;
976
+ }
977
+
978
+ // Generate a unique integer id (unique within the entire client session).
979
+ // Useful for temporary DOM ids.
980
+ var idCounter = 0;
981
+ function uniqueId(prefix) {
982
+ var id = ++idCounter + '';
983
+ return prefix ? prefix + id : id;
984
+ }
985
+
986
+ // Start chaining a wrapped Underscore object.
987
+ function chain(obj) {
988
+ var instance = _$1(obj);
989
+ instance._chain = true;
990
+ return instance;
991
+ }
992
+
993
+ // Internal function to execute `sourceFunc` bound to `context` with optional
994
+ // `args`. Determines whether to execute a function as a constructor or as a
995
+ // normal function.
996
+ function executeBound(sourceFunc, boundFunc, context, callingContext, args) {
997
+ if (!(callingContext instanceof boundFunc)) return sourceFunc.apply(context, args);
998
+ var self = baseCreate(sourceFunc.prototype);
999
+ var result = sourceFunc.apply(self, args);
1000
+ if (isObject(result)) return result;
1001
+ return self;
1002
+ }
1003
+
1004
+ // Partially apply a function by creating a version that has had some of its
1005
+ // arguments pre-filled, without changing its dynamic `this` context. `_` acts
1006
+ // as a placeholder by default, allowing any combination of arguments to be
1007
+ // pre-filled. Set `_.partial.placeholder` for a custom placeholder argument.
1008
+ var partial = restArguments(function (func, boundArgs) {
1009
+ var placeholder = partial.placeholder;
1010
+ var bound = function () {
1011
+ var position = 0,
1012
+ length = boundArgs.length;
1013
+ var args = Array(length);
1014
+ for (var i = 0; i < length; i++) {
1015
+ args[i] = boundArgs[i] === placeholder ? arguments[position++] : boundArgs[i];
1016
+ }
1017
+ while (position < arguments.length) args.push(arguments[position++]);
1018
+ return executeBound(func, bound, this, this, args);
1019
+ };
1020
+ return bound;
1021
+ });
1022
+ partial.placeholder = _$1;
1023
+
1024
+ // Create a function bound to a given object (assigning `this`, and arguments,
1025
+ // optionally).
1026
+ var bind = restArguments(function (func, context, args) {
1027
+ if (!isFunction$1(func)) throw new TypeError('Bind must be called on a function');
1028
+ var bound = restArguments(function (callArgs) {
1029
+ return executeBound(func, bound, context, this, args.concat(callArgs));
1030
+ });
1031
+ return bound;
1032
+ });
1033
+
1034
+ // Internal helper for collection methods to determine whether a collection
1035
+ // should be iterated as an array or as an object.
1036
+ // Related: https://people.mozilla.org/~jorendorff/es6-draft.html#sec-tolength
1037
+ // Avoids a very nasty iOS 8 JIT bug on ARM-64. #2094
1038
+ var isArrayLike = createSizePropertyCheck(getLength);
1039
+
1040
+ // Internal implementation of a recursive `flatten` function.
1041
+ function flatten$1(input, depth, strict, output) {
1042
+ output = output || [];
1043
+ if (!depth && depth !== 0) {
1044
+ depth = Infinity;
1045
+ } else if (depth <= 0) {
1046
+ return output.concat(input);
1047
+ }
1048
+ var idx = output.length;
1049
+ for (var i = 0, length = getLength(input); i < length; i++) {
1050
+ var value = input[i];
1051
+ if (isArrayLike(value) && (isArray(value) || isArguments$1(value))) {
1052
+ // Flatten current level of array or arguments object.
1053
+ if (depth > 1) {
1054
+ flatten$1(value, depth - 1, strict, output);
1055
+ idx = output.length;
1056
+ } else {
1057
+ var j = 0,
1058
+ len = value.length;
1059
+ while (j < len) output[idx++] = value[j++];
1060
+ }
1061
+ } else if (!strict) {
1062
+ output[idx++] = value;
1063
+ }
1064
+ }
1065
+ return output;
1066
+ }
1067
+
1068
+ // Bind a number of an object's methods to that object. Remaining arguments
1069
+ // are the method names to be bound. Useful for ensuring that all callbacks
1070
+ // defined on an object belong to it.
1071
+ var bindAll = restArguments(function (obj, keys) {
1072
+ keys = flatten$1(keys, false, false);
1073
+ var index = keys.length;
1074
+ if (index < 1) throw new Error('bindAll must be passed function names');
1075
+ while (index--) {
1076
+ var key = keys[index];
1077
+ obj[key] = bind(obj[key], obj);
1078
+ }
1079
+ return obj;
1080
+ });
1081
+
1082
+ // Memoize an expensive function by storing its results.
1083
+ function memoize(func, hasher) {
1084
+ var memoize = function (key) {
1085
+ var cache = memoize.cache;
1086
+ var address = '' + (hasher ? hasher.apply(this, arguments) : key);
1087
+ if (!has$1(cache, address)) cache[address] = func.apply(this, arguments);
1088
+ return cache[address];
1089
+ };
1090
+ memoize.cache = {};
1091
+ return memoize;
1092
+ }
1093
+
1094
+ // Delays a function for the given number of milliseconds, and then calls
1095
+ // it with the arguments supplied.
1096
+ var delay = restArguments(function (func, wait, args) {
1097
+ return setTimeout(function () {
1098
+ return func.apply(null, args);
1099
+ }, wait);
1100
+ });
1101
+
1102
+ // Defers a function, scheduling it to run after the current call stack has
1103
+ // cleared.
1104
+ var defer = partial(delay, _$1, 1);
1105
+
1106
+ // Returns a function, that, when invoked, will only be triggered at most once
1107
+ // during a given window of time. Normally, the throttled function will run
1108
+ // as much as it can, without ever going more than once per `wait` duration;
1109
+ // but if you'd like to disable the execution on the leading edge, pass
1110
+ // `{leading: false}`. To disable execution on the trailing edge, ditto.
1111
+ function throttle(func, wait, options) {
1112
+ var timeout, context, args, result;
1113
+ var previous = 0;
1114
+ if (!options) options = {};
1115
+ var later = function () {
1116
+ previous = options.leading === false ? 0 : now();
1117
+ timeout = null;
1118
+ result = func.apply(context, args);
1119
+ if (!timeout) context = args = null;
1120
+ };
1121
+ var throttled = function () {
1122
+ var _now = now();
1123
+ if (!previous && options.leading === false) previous = _now;
1124
+ var remaining = wait - (_now - previous);
1125
+ context = this;
1126
+ args = arguments;
1127
+ if (remaining <= 0 || remaining > wait) {
1128
+ if (timeout) {
1129
+ clearTimeout(timeout);
1130
+ timeout = null;
1131
+ }
1132
+ previous = _now;
1133
+ result = func.apply(context, args);
1134
+ if (!timeout) context = args = null;
1135
+ } else if (!timeout && options.trailing !== false) {
1136
+ timeout = setTimeout(later, remaining);
1137
+ }
1138
+ return result;
1139
+ };
1140
+ throttled.cancel = function () {
1141
+ clearTimeout(timeout);
1142
+ previous = 0;
1143
+ timeout = context = args = null;
1144
+ };
1145
+ return throttled;
1146
+ }
1147
+
1148
+ // When a sequence of calls of the returned function ends, the argument
1149
+ // function is triggered. The end of a sequence is defined by the `wait`
1150
+ // parameter. If `immediate` is passed, the argument function will be
1151
+ // triggered at the beginning of the sequence instead of at the end.
1152
+ function debounce(func, wait, immediate) {
1153
+ var timeout, previous, args, result, context;
1154
+ var later = function () {
1155
+ var passed = now() - previous;
1156
+ if (wait > passed) {
1157
+ timeout = setTimeout(later, wait - passed);
1158
+ } else {
1159
+ timeout = null;
1160
+ if (!immediate) result = func.apply(context, args);
1161
+ // This check is needed because `func` can recursively invoke `debounced`.
1162
+ if (!timeout) args = context = null;
1163
+ }
1164
+ };
1165
+ var debounced = restArguments(function (_args) {
1166
+ context = this;
1167
+ args = _args;
1168
+ previous = now();
1169
+ if (!timeout) {
1170
+ timeout = setTimeout(later, wait);
1171
+ if (immediate) result = func.apply(context, args);
1172
+ }
1173
+ return result;
1174
+ });
1175
+ debounced.cancel = function () {
1176
+ clearTimeout(timeout);
1177
+ timeout = args = context = null;
1178
+ };
1179
+ return debounced;
1180
+ }
1181
+
1182
+ // Returns the first function passed as an argument to the second,
1183
+ // allowing you to adjust arguments, run code before and after, and
1184
+ // conditionally execute the original function.
1185
+ function wrap(func, wrapper) {
1186
+ return partial(wrapper, func);
1187
+ }
1188
+
1189
+ // Returns a negated version of the passed-in predicate.
1190
+ function negate(predicate) {
1191
+ return function () {
1192
+ return !predicate.apply(this, arguments);
1193
+ };
1194
+ }
1195
+
1196
+ // Returns a function that is the composition of a list of functions, each
1197
+ // consuming the return value of the function that follows.
1198
+ function compose() {
1199
+ var args = arguments;
1200
+ var start = args.length - 1;
1201
+ return function () {
1202
+ var i = start;
1203
+ var result = args[start].apply(this, arguments);
1204
+ while (i--) result = args[i].call(this, result);
1205
+ return result;
1206
+ };
1207
+ }
1208
+
1209
+ // Returns a function that will only be executed on and after the Nth call.
1210
+ function after(times, func) {
1211
+ return function () {
1212
+ if (--times < 1) {
1213
+ return func.apply(this, arguments);
1214
+ }
1215
+ };
1216
+ }
1217
+
1218
+ // Returns a function that will only be executed up to (but not including) the
1219
+ // Nth call.
1220
+ function before(times, func) {
1221
+ var memo;
1222
+ return function () {
1223
+ if (--times > 0) {
1224
+ memo = func.apply(this, arguments);
1225
+ }
1226
+ if (times <= 1) func = null;
1227
+ return memo;
1228
+ };
1229
+ }
1230
+
1231
+ // Returns a function that will be executed at most one time, no matter how
1232
+ // often you call it. Useful for lazy initialization.
1233
+ var once = partial(before, 2);
1234
+
1235
+ // Returns the first key on an object that passes a truth test.
1236
+ function findKey(obj, predicate, context) {
1237
+ predicate = cb(predicate, context);
1238
+ var _keys = keys(obj),
1239
+ key;
1240
+ for (var i = 0, length = _keys.length; i < length; i++) {
1241
+ key = _keys[i];
1242
+ if (predicate(obj[key], key, obj)) return key;
1243
+ }
1244
+ }
1245
+
1246
+ // Internal function to generate `_.findIndex` and `_.findLastIndex`.
1247
+ function createPredicateIndexFinder(dir) {
1248
+ return function (array, predicate, context) {
1249
+ predicate = cb(predicate, context);
1250
+ var length = getLength(array);
1251
+ var index = dir > 0 ? 0 : length - 1;
1252
+ for (; index >= 0 && index < length; index += dir) {
1253
+ if (predicate(array[index], index, array)) return index;
1254
+ }
1255
+ return -1;
1256
+ };
1257
+ }
1258
+
1259
+ // Returns the first index on an array-like that passes a truth test.
1260
+ var findIndex = createPredicateIndexFinder(1);
1261
+
1262
+ // Returns the last index on an array-like that passes a truth test.
1263
+ var findLastIndex = createPredicateIndexFinder(-1);
1264
+
1265
+ // Use a comparator function to figure out the smallest index at which
1266
+ // an object should be inserted so as to maintain order. Uses binary search.
1267
+ function sortedIndex(array, obj, iteratee, context) {
1268
+ iteratee = cb(iteratee, context, 1);
1269
+ var value = iteratee(obj);
1270
+ var low = 0,
1271
+ high = getLength(array);
1272
+ while (low < high) {
1273
+ var mid = Math.floor((low + high) / 2);
1274
+ if (iteratee(array[mid]) < value) low = mid + 1;else high = mid;
1275
+ }
1276
+ return low;
1277
+ }
1278
+
1279
+ // Internal function to generate the `_.indexOf` and `_.lastIndexOf` functions.
1280
+ function createIndexFinder(dir, predicateFind, sortedIndex) {
1281
+ return function (array, item, idx) {
1282
+ var i = 0,
1283
+ length = getLength(array);
1284
+ if (typeof idx == 'number') {
1285
+ if (dir > 0) {
1286
+ i = idx >= 0 ? idx : Math.max(idx + length, i);
1287
+ } else {
1288
+ length = idx >= 0 ? Math.min(idx + 1, length) : idx + length + 1;
1289
+ }
1290
+ } else if (sortedIndex && idx && length) {
1291
+ idx = sortedIndex(array, item);
1292
+ return array[idx] === item ? idx : -1;
1293
+ }
1294
+ if (item !== item) {
1295
+ idx = predicateFind(slice.call(array, i, length), isNaN$1);
1296
+ return idx >= 0 ? idx + i : -1;
1297
+ }
1298
+ for (idx = dir > 0 ? i : length - 1; idx >= 0 && idx < length; idx += dir) {
1299
+ if (array[idx] === item) return idx;
1300
+ }
1301
+ return -1;
1302
+ };
1303
+ }
1304
+
1305
+ // Return the position of the first occurrence of an item in an array,
1306
+ // or -1 if the item is not included in the array.
1307
+ // If the array is large and already in sort order, pass `true`
1308
+ // for **isSorted** to use binary search.
1309
+ var indexOf = createIndexFinder(1, findIndex, sortedIndex);
1310
+
1311
+ // Return the position of the last occurrence of an item in an array,
1312
+ // or -1 if the item is not included in the array.
1313
+ var lastIndexOf = createIndexFinder(-1, findLastIndex);
1314
+
1315
+ // Return the first value which passes a truth test.
1316
+ function find(obj, predicate, context) {
1317
+ var keyFinder = isArrayLike(obj) ? findIndex : findKey;
1318
+ var key = keyFinder(obj, predicate, context);
1319
+ if (key !== void 0 && key !== -1) return obj[key];
1320
+ }
1321
+
1322
+ // Convenience version of a common use case of `_.find`: getting the first
1323
+ // object containing specific `key:value` pairs.
1324
+ function findWhere(obj, attrs) {
1325
+ return find(obj, matcher(attrs));
1326
+ }
1327
+
1328
+ // The cornerstone for collection functions, an `each`
1329
+ // implementation, aka `forEach`.
1330
+ // Handles raw objects in addition to array-likes. Treats all
1331
+ // sparse array-likes as if they were dense.
1332
+ function each(obj, iteratee, context) {
1333
+ iteratee = optimizeCb(iteratee, context);
1334
+ var i, length;
1335
+ if (isArrayLike(obj)) {
1336
+ for (i = 0, length = obj.length; i < length; i++) {
1337
+ iteratee(obj[i], i, obj);
1338
+ }
1339
+ } else {
1340
+ var _keys = keys(obj);
1341
+ for (i = 0, length = _keys.length; i < length; i++) {
1342
+ iteratee(obj[_keys[i]], _keys[i], obj);
1343
+ }
1344
+ }
1345
+ return obj;
1346
+ }
1347
+
1348
+ // Return the results of applying the iteratee to each element.
1349
+ function map(obj, iteratee, context) {
1350
+ iteratee = cb(iteratee, context);
1351
+ var _keys = !isArrayLike(obj) && keys(obj),
1352
+ length = (_keys || obj).length,
1353
+ results = Array(length);
1354
+ for (var index = 0; index < length; index++) {
1355
+ var currentKey = _keys ? _keys[index] : index;
1356
+ results[index] = iteratee(obj[currentKey], currentKey, obj);
1357
+ }
1358
+ return results;
1359
+ }
1360
+
1361
+ // Internal helper to create a reducing function, iterating left or right.
1362
+ function createReduce(dir) {
1363
+ // Wrap code that reassigns argument variables in a separate function than
1364
+ // the one that accesses `arguments.length` to avoid a perf hit. (#1991)
1365
+ var reducer = function (obj, iteratee, memo, initial) {
1366
+ var _keys = !isArrayLike(obj) && keys(obj),
1367
+ length = (_keys || obj).length,
1368
+ index = dir > 0 ? 0 : length - 1;
1369
+ if (!initial) {
1370
+ memo = obj[_keys ? _keys[index] : index];
1371
+ index += dir;
1372
+ }
1373
+ for (; index >= 0 && index < length; index += dir) {
1374
+ var currentKey = _keys ? _keys[index] : index;
1375
+ memo = iteratee(memo, obj[currentKey], currentKey, obj);
1376
+ }
1377
+ return memo;
1378
+ };
1379
+ return function (obj, iteratee, memo, context) {
1380
+ var initial = arguments.length >= 3;
1381
+ return reducer(obj, optimizeCb(iteratee, context, 4), memo, initial);
1382
+ };
1383
+ }
1384
+
1385
+ // **Reduce** builds up a single result from a list of values, aka `inject`,
1386
+ // or `foldl`.
1387
+ var reduce = createReduce(1);
1388
+
1389
+ // The right-associative version of reduce, also known as `foldr`.
1390
+ var reduceRight = createReduce(-1);
1391
+
1392
+ // Return all the elements that pass a truth test.
1393
+ function filter(obj, predicate, context) {
1394
+ var results = [];
1395
+ predicate = cb(predicate, context);
1396
+ each(obj, function (value, index, list) {
1397
+ if (predicate(value, index, list)) results.push(value);
1398
+ });
1399
+ return results;
1400
+ }
1401
+
1402
+ // Return all the elements for which a truth test fails.
1403
+ function reject(obj, predicate, context) {
1404
+ return filter(obj, negate(cb(predicate)), context);
1405
+ }
1406
+
1407
+ // Determine whether all of the elements pass a truth test.
1408
+ function every(obj, predicate, context) {
1409
+ predicate = cb(predicate, context);
1410
+ var _keys = !isArrayLike(obj) && keys(obj),
1411
+ length = (_keys || obj).length;
1412
+ for (var index = 0; index < length; index++) {
1413
+ var currentKey = _keys ? _keys[index] : index;
1414
+ if (!predicate(obj[currentKey], currentKey, obj)) return false;
1415
+ }
1416
+ return true;
1417
+ }
1418
+
1419
+ // Determine if at least one element in the object passes a truth test.
1420
+ function some(obj, predicate, context) {
1421
+ predicate = cb(predicate, context);
1422
+ var _keys = !isArrayLike(obj) && keys(obj),
1423
+ length = (_keys || obj).length;
1424
+ for (var index = 0; index < length; index++) {
1425
+ var currentKey = _keys ? _keys[index] : index;
1426
+ if (predicate(obj[currentKey], currentKey, obj)) return true;
1427
+ }
1428
+ return false;
1429
+ }
1430
+
1431
+ // Determine if the array or object contains a given item (using `===`).
1432
+ function contains(obj, item, fromIndex, guard) {
1433
+ if (!isArrayLike(obj)) obj = values(obj);
1434
+ if (typeof fromIndex != 'number' || guard) fromIndex = 0;
1435
+ return indexOf(obj, item, fromIndex) >= 0;
1436
+ }
1437
+
1438
+ // Invoke a method (with arguments) on every item in a collection.
1439
+ var invoke = restArguments(function (obj, path, args) {
1440
+ var contextPath, func;
1441
+ if (isFunction$1(path)) {
1442
+ func = path;
1443
+ } else {
1444
+ path = toPath(path);
1445
+ contextPath = path.slice(0, -1);
1446
+ path = path[path.length - 1];
1447
+ }
1448
+ return map(obj, function (context) {
1449
+ var method = func;
1450
+ if (!method) {
1451
+ if (contextPath && contextPath.length) {
1452
+ context = deepGet(context, contextPath);
1453
+ }
1454
+ if (context == null) return void 0;
1455
+ method = context[path];
1456
+ }
1457
+ return method == null ? method : method.apply(context, args);
1458
+ });
1459
+ });
1460
+
1461
+ // Convenience version of a common use case of `_.map`: fetching a property.
1462
+ function pluck(obj, key) {
1463
+ return map(obj, property(key));
1464
+ }
1465
+
1466
+ // Convenience version of a common use case of `_.filter`: selecting only
1467
+ // objects containing specific `key:value` pairs.
1468
+ function where(obj, attrs) {
1469
+ return filter(obj, matcher(attrs));
1470
+ }
1471
+
1472
+ // Return the maximum element (or element-based computation).
1473
+ function max(obj, iteratee, context) {
1474
+ var result = -Infinity,
1475
+ lastComputed = -Infinity,
1476
+ value,
1477
+ computed;
1478
+ if (iteratee == null || typeof iteratee == 'number' && typeof obj[0] != 'object' && obj != null) {
1479
+ obj = isArrayLike(obj) ? obj : values(obj);
1480
+ for (var i = 0, length = obj.length; i < length; i++) {
1481
+ value = obj[i];
1482
+ if (value != null && value > result) {
1483
+ result = value;
1484
+ }
1485
+ }
1486
+ } else {
1487
+ iteratee = cb(iteratee, context);
1488
+ each(obj, function (v, index, list) {
1489
+ computed = iteratee(v, index, list);
1490
+ if (computed > lastComputed || computed === -Infinity && result === -Infinity) {
1491
+ result = v;
1492
+ lastComputed = computed;
1493
+ }
1494
+ });
1495
+ }
1496
+ return result;
1497
+ }
1498
+
1499
+ // Return the minimum element (or element-based computation).
1500
+ function min(obj, iteratee, context) {
1501
+ var result = Infinity,
1502
+ lastComputed = Infinity,
1503
+ value,
1504
+ computed;
1505
+ if (iteratee == null || typeof iteratee == 'number' && typeof obj[0] != 'object' && obj != null) {
1506
+ obj = isArrayLike(obj) ? obj : values(obj);
1507
+ for (var i = 0, length = obj.length; i < length; i++) {
1508
+ value = obj[i];
1509
+ if (value != null && value < result) {
1510
+ result = value;
1511
+ }
1512
+ }
1513
+ } else {
1514
+ iteratee = cb(iteratee, context);
1515
+ each(obj, function (v, index, list) {
1516
+ computed = iteratee(v, index, list);
1517
+ if (computed < lastComputed || computed === Infinity && result === Infinity) {
1518
+ result = v;
1519
+ lastComputed = computed;
1520
+ }
1521
+ });
1522
+ }
1523
+ return result;
1524
+ }
1525
+
1526
+ // Safely create a real, live array from anything iterable.
1527
+ var reStrSymbol = /[^\ud800-\udfff]|[\ud800-\udbff][\udc00-\udfff]|[\ud800-\udfff]/g;
1528
+ function toArray(obj) {
1529
+ if (!obj) return [];
1530
+ if (isArray(obj)) return slice.call(obj);
1531
+ if (isString(obj)) {
1532
+ // Keep surrogate pair characters together.
1533
+ return obj.match(reStrSymbol);
1534
+ }
1535
+ if (isArrayLike(obj)) return map(obj, identity);
1536
+ return values(obj);
1537
+ }
1538
+
1539
+ // Sample **n** random values from a collection using the modern version of the
1540
+ // [Fisher-Yates shuffle](https://en.wikipedia.org/wiki/Fisher–Yates_shuffle).
1541
+ // If **n** is not specified, returns a single random element.
1542
+ // The internal `guard` argument allows it to work with `_.map`.
1543
+ function sample(obj, n, guard) {
1544
+ if (n == null || guard) {
1545
+ if (!isArrayLike(obj)) obj = values(obj);
1546
+ return obj[random(obj.length - 1)];
1547
+ }
1548
+ var sample = toArray(obj);
1549
+ var length = getLength(sample);
1550
+ n = Math.max(Math.min(n, length), 0);
1551
+ var last = length - 1;
1552
+ for (var index = 0; index < n; index++) {
1553
+ var rand = random(index, last);
1554
+ var temp = sample[index];
1555
+ sample[index] = sample[rand];
1556
+ sample[rand] = temp;
1557
+ }
1558
+ return sample.slice(0, n);
1559
+ }
1560
+
1561
+ // Shuffle a collection.
1562
+ function shuffle(obj) {
1563
+ return sample(obj, Infinity);
1564
+ }
1565
+
1566
+ // Sort the object's values by a criterion produced by an iteratee.
1567
+ function sortBy(obj, iteratee, context) {
1568
+ var index = 0;
1569
+ iteratee = cb(iteratee, context);
1570
+ return pluck(map(obj, function (value, key, list) {
1571
+ return {
1572
+ value: value,
1573
+ index: index++,
1574
+ criteria: iteratee(value, key, list)
1575
+ };
1576
+ }).sort(function (left, right) {
1577
+ var a = left.criteria;
1578
+ var b = right.criteria;
1579
+ if (a !== b) {
1580
+ if (a > b || a === void 0) return 1;
1581
+ if (a < b || b === void 0) return -1;
1582
+ }
1583
+ return left.index - right.index;
1584
+ }), 'value');
1585
+ }
1586
+
1587
+ // An internal function used for aggregate "group by" operations.
1588
+ function group(behavior, partition) {
1589
+ return function (obj, iteratee, context) {
1590
+ var result = partition ? [[], []] : {};
1591
+ iteratee = cb(iteratee, context);
1592
+ each(obj, function (value, index) {
1593
+ var key = iteratee(value, index, obj);
1594
+ behavior(result, value, key);
1595
+ });
1596
+ return result;
1597
+ };
1598
+ }
1599
+
1600
+ // Groups the object's values by a criterion. Pass either a string attribute
1601
+ // to group by, or a function that returns the criterion.
1602
+ var groupBy = group(function (result, value, key) {
1603
+ if (has$1(result, key)) result[key].push(value);else result[key] = [value];
1604
+ });
1605
+
1606
+ // Indexes the object's values by a criterion, similar to `_.groupBy`, but for
1607
+ // when you know that your index values will be unique.
1608
+ var indexBy = group(function (result, value, key) {
1609
+ result[key] = value;
1610
+ });
1611
+
1612
+ // Counts instances of an object that group by a certain criterion. Pass
1613
+ // either a string attribute to count by, or a function that returns the
1614
+ // criterion.
1615
+ var countBy = group(function (result, value, key) {
1616
+ if (has$1(result, key)) result[key]++;else result[key] = 1;
1617
+ });
1618
+
1619
+ // Split a collection into two arrays: one whose elements all pass the given
1620
+ // truth test, and one whose elements all do not pass the truth test.
1621
+ var partition = group(function (result, value, pass) {
1622
+ result[pass ? 0 : 1].push(value);
1623
+ }, true);
1624
+
1625
+ // Return the number of elements in a collection.
1626
+ function size(obj) {
1627
+ if (obj == null) return 0;
1628
+ return isArrayLike(obj) ? obj.length : keys(obj).length;
1629
+ }
1630
+
1631
+ // Internal `_.pick` helper function to determine whether `key` is an enumerable
1632
+ // property name of `obj`.
1633
+ function keyInObj(value, key, obj) {
1634
+ return key in obj;
1635
+ }
1636
+
1637
+ // Return a copy of the object only containing the allowed properties.
1638
+ var pick = restArguments(function (obj, keys) {
1639
+ var result = {},
1640
+ iteratee = keys[0];
1641
+ if (obj == null) return result;
1642
+ if (isFunction$1(iteratee)) {
1643
+ if (keys.length > 1) iteratee = optimizeCb(iteratee, keys[1]);
1644
+ keys = allKeys(obj);
1645
+ } else {
1646
+ iteratee = keyInObj;
1647
+ keys = flatten$1(keys, false, false);
1648
+ obj = Object(obj);
1649
+ }
1650
+ for (var i = 0, length = keys.length; i < length; i++) {
1651
+ var key = keys[i];
1652
+ var value = obj[key];
1653
+ if (iteratee(value, key, obj)) result[key] = value;
1654
+ }
1655
+ return result;
1656
+ });
1657
+
1658
+ // Return a copy of the object without the disallowed properties.
1659
+ var omit = restArguments(function (obj, keys) {
1660
+ var iteratee = keys[0],
1661
+ context;
1662
+ if (isFunction$1(iteratee)) {
1663
+ iteratee = negate(iteratee);
1664
+ if (keys.length > 1) context = keys[1];
1665
+ } else {
1666
+ keys = map(flatten$1(keys, false, false), String);
1667
+ iteratee = function (value, key) {
1668
+ return !contains(keys, key);
1669
+ };
1670
+ }
1671
+ return pick(obj, iteratee, context);
1672
+ });
1673
+
1674
+ // Returns everything but the last entry of the array. Especially useful on
1675
+ // the arguments object. Passing **n** will return all the values in
1676
+ // the array, excluding the last N.
1677
+ function initial(array, n, guard) {
1678
+ return slice.call(array, 0, Math.max(0, array.length - (n == null || guard ? 1 : n)));
1679
+ }
1680
+
1681
+ // Get the first element of an array. Passing **n** will return the first N
1682
+ // values in the array. The **guard** check allows it to work with `_.map`.
1683
+ function first(array, n, guard) {
1684
+ if (array == null || array.length < 1) return n == null || guard ? void 0 : [];
1685
+ if (n == null || guard) return array[0];
1686
+ return initial(array, array.length - n);
1687
+ }
1688
+
1689
+ // Returns everything but the first entry of the `array`. Especially useful on
1690
+ // the `arguments` object. Passing an **n** will return the rest N values in the
1691
+ // `array`.
1692
+ function rest(array, n, guard) {
1693
+ return slice.call(array, n == null || guard ? 1 : n);
1694
+ }
1695
+
1696
+ // Get the last element of an array. Passing **n** will return the last N
1697
+ // values in the array.
1698
+ function last(array, n, guard) {
1699
+ if (array == null || array.length < 1) return n == null || guard ? void 0 : [];
1700
+ if (n == null || guard) return array[array.length - 1];
1701
+ return rest(array, Math.max(0, array.length - n));
1702
+ }
1703
+
1704
+ // Trim out all falsy values from an array.
1705
+ function compact(array) {
1706
+ return filter(array, Boolean);
1707
+ }
1708
+
1709
+ // Flatten out an array, either recursively (by default), or up to `depth`.
1710
+ // Passing `true` or `false` as `depth` means `1` or `Infinity`, respectively.
1711
+ function flatten(array, depth) {
1712
+ return flatten$1(array, depth, false);
1713
+ }
1714
+
1715
+ // Take the difference between one array and a number of other arrays.
1716
+ // Only the elements present in just the first array will remain.
1717
+ var difference = restArguments(function (array, rest) {
1718
+ rest = flatten$1(rest, true, true);
1719
+ return filter(array, function (value) {
1720
+ return !contains(rest, value);
1721
+ });
1722
+ });
1723
+
1724
+ // Return a version of the array that does not contain the specified value(s).
1725
+ var without = restArguments(function (array, otherArrays) {
1726
+ return difference(array, otherArrays);
1727
+ });
1728
+
1729
+ // Produce a duplicate-free version of the array. If the array has already
1730
+ // been sorted, you have the option of using a faster algorithm.
1731
+ // The faster algorithm will not work with an iteratee if the iteratee
1732
+ // is not a one-to-one function, so providing an iteratee will disable
1733
+ // the faster algorithm.
1734
+ function uniq(array, isSorted, iteratee, context) {
1735
+ if (!isBoolean(isSorted)) {
1736
+ context = iteratee;
1737
+ iteratee = isSorted;
1738
+ isSorted = false;
1739
+ }
1740
+ if (iteratee != null) iteratee = cb(iteratee, context);
1741
+ var result = [];
1742
+ var seen = [];
1743
+ for (var i = 0, length = getLength(array); i < length; i++) {
1744
+ var value = array[i],
1745
+ computed = iteratee ? iteratee(value, i, array) : value;
1746
+ if (isSorted && !iteratee) {
1747
+ if (!i || seen !== computed) result.push(value);
1748
+ seen = computed;
1749
+ } else if (iteratee) {
1750
+ if (!contains(seen, computed)) {
1751
+ seen.push(computed);
1752
+ result.push(value);
1753
+ }
1754
+ } else if (!contains(result, value)) {
1755
+ result.push(value);
1756
+ }
1757
+ }
1758
+ return result;
1759
+ }
1760
+
1761
+ // Produce an array that contains the union: each distinct element from all of
1762
+ // the passed-in arrays.
1763
+ var union = restArguments(function (arrays) {
1764
+ return uniq(flatten$1(arrays, true, true));
1765
+ });
1766
+
1767
+ // Produce an array that contains every item shared between all the
1768
+ // passed-in arrays.
1769
+ function intersection(array) {
1770
+ var result = [];
1771
+ var argsLength = arguments.length;
1772
+ for (var i = 0, length = getLength(array); i < length; i++) {
1773
+ var item = array[i];
1774
+ if (contains(result, item)) continue;
1775
+ var j;
1776
+ for (j = 1; j < argsLength; j++) {
1777
+ if (!contains(arguments[j], item)) break;
1778
+ }
1779
+ if (j === argsLength) result.push(item);
1780
+ }
1781
+ return result;
1782
+ }
1783
+
1784
+ // Complement of zip. Unzip accepts an array of arrays and groups
1785
+ // each array's elements on shared indices.
1786
+ function unzip(array) {
1787
+ var length = array && max(array, getLength).length || 0;
1788
+ var result = Array(length);
1789
+ for (var index = 0; index < length; index++) {
1790
+ result[index] = pluck(array, index);
1791
+ }
1792
+ return result;
1793
+ }
1794
+
1795
+ // Zip together multiple lists into a single array -- elements that share
1796
+ // an index go together.
1797
+ var zip = restArguments(unzip);
1798
+
1799
+ // Converts lists into objects. Pass either a single array of `[key, value]`
1800
+ // pairs, or two parallel arrays of the same length -- one of keys, and one of
1801
+ // the corresponding values. Passing by pairs is the reverse of `_.pairs`.
1802
+ function object(list, values) {
1803
+ var result = {};
1804
+ for (var i = 0, length = getLength(list); i < length; i++) {
1805
+ if (values) {
1806
+ result[list[i]] = values[i];
1807
+ } else {
1808
+ result[list[i][0]] = list[i][1];
1809
+ }
1810
+ }
1811
+ return result;
1812
+ }
1813
+
1814
+ // Generate an integer Array containing an arithmetic progression. A port of
1815
+ // the native Python `range()` function. See
1816
+ // [the Python documentation](https://docs.python.org/library/functions.html#range).
1817
+ function range(start, stop, step) {
1818
+ if (stop == null) {
1819
+ stop = start || 0;
1820
+ start = 0;
1821
+ }
1822
+ if (!step) {
1823
+ step = stop < start ? -1 : 1;
1824
+ }
1825
+ var length = Math.max(Math.ceil((stop - start) / step), 0);
1826
+ var range = Array(length);
1827
+ for (var idx = 0; idx < length; idx++, start += step) {
1828
+ range[idx] = start;
1829
+ }
1830
+ return range;
1831
+ }
1832
+
1833
+ // Chunk a single array into multiple arrays, each containing `count` or fewer
1834
+ // items.
1835
+ function chunk(array, count) {
1836
+ if (count == null || count < 1) return [];
1837
+ var result = [];
1838
+ var i = 0,
1839
+ length = array.length;
1840
+ while (i < length) {
1841
+ result.push(slice.call(array, i, i += count));
1842
+ }
1843
+ return result;
1844
+ }
1845
+
1846
+ // Helper function to continue chaining intermediate results.
1847
+ function chainResult(instance, obj) {
1848
+ return instance._chain ? _$1(obj).chain() : obj;
1849
+ }
1850
+
1851
+ // Add your own custom functions to the Underscore object.
1852
+ function mixin(obj) {
1853
+ each(functions(obj), function (name) {
1854
+ var func = _$1[name] = obj[name];
1855
+ _$1.prototype[name] = function () {
1856
+ var args = [this._wrapped];
1857
+ push.apply(args, arguments);
1858
+ return chainResult(this, func.apply(_$1, args));
1859
+ };
1860
+ });
1861
+ return _$1;
1862
+ }
1863
+
1864
+ // Add all mutator `Array` functions to the wrapper.
1865
+ each(['pop', 'push', 'reverse', 'shift', 'sort', 'splice', 'unshift'], function (name) {
1866
+ var method = ArrayProto[name];
1867
+ _$1.prototype[name] = function () {
1868
+ var obj = this._wrapped;
1869
+ if (obj != null) {
1870
+ method.apply(obj, arguments);
1871
+ if ((name === 'shift' || name === 'splice') && obj.length === 0) {
1872
+ delete obj[0];
1873
+ }
1874
+ }
1875
+ return chainResult(this, obj);
1876
+ };
1877
+ });
1878
+
1879
+ // Add all accessor `Array` functions to the wrapper.
1880
+ each(['concat', 'join', 'slice'], function (name) {
1881
+ var method = ArrayProto[name];
1882
+ _$1.prototype[name] = function () {
1883
+ var obj = this._wrapped;
1884
+ if (obj != null) obj = method.apply(obj, arguments);
1885
+ return chainResult(this, obj);
1886
+ };
1887
+ });
1888
+
1889
+ // Named Exports
1890
+
1891
+ var allExports = {
1892
+ __proto__: null,
1893
+ VERSION: VERSION,
1894
+ restArguments: restArguments,
1895
+ isObject: isObject,
1896
+ isNull: isNull,
1897
+ isUndefined: isUndefined,
1898
+ isBoolean: isBoolean,
1899
+ isElement: isElement,
1900
+ isString: isString,
1901
+ isNumber: isNumber,
1902
+ isDate: isDate,
1903
+ isRegExp: isRegExp,
1904
+ isError: isError,
1905
+ isSymbol: isSymbol,
1906
+ isArrayBuffer: isArrayBuffer,
1907
+ isDataView: isDataView$1,
1908
+ isArray: isArray,
1909
+ isFunction: isFunction$1,
1910
+ isArguments: isArguments$1,
1911
+ isFinite: isFinite$1,
1912
+ isNaN: isNaN$1,
1913
+ isTypedArray: isTypedArray$1,
1914
+ isEmpty: isEmpty,
1915
+ isMatch: isMatch,
1916
+ isEqual: isEqual,
1917
+ isMap: isMap,
1918
+ isWeakMap: isWeakMap,
1919
+ isSet: isSet,
1920
+ isWeakSet: isWeakSet,
1921
+ keys: keys,
1922
+ allKeys: allKeys,
1923
+ values: values,
1924
+ pairs: pairs,
1925
+ invert: invert,
1926
+ functions: functions,
1927
+ methods: functions,
1928
+ extend: extend,
1929
+ extendOwn: extendOwn,
1930
+ assign: extendOwn,
1931
+ defaults: defaults,
1932
+ create: create,
1933
+ clone: clone,
1934
+ tap: tap,
1935
+ get: get,
1936
+ has: has,
1937
+ mapObject: mapObject,
1938
+ identity: identity,
1939
+ constant: constant,
1940
+ noop: noop,
1941
+ toPath: toPath$1,
1942
+ property: property,
1943
+ propertyOf: propertyOf,
1944
+ matcher: matcher,
1945
+ matches: matcher,
1946
+ times: times,
1947
+ random: random,
1948
+ now: now,
1949
+ escape: _escape,
1950
+ unescape: _unescape,
1951
+ templateSettings: templateSettings,
1952
+ template: template,
1953
+ result: result,
1954
+ uniqueId: uniqueId,
1955
+ chain: chain,
1956
+ iteratee: iteratee,
1957
+ partial: partial,
1958
+ bind: bind,
1959
+ bindAll: bindAll,
1960
+ memoize: memoize,
1961
+ delay: delay,
1962
+ defer: defer,
1963
+ throttle: throttle,
1964
+ debounce: debounce,
1965
+ wrap: wrap,
1966
+ negate: negate,
1967
+ compose: compose,
1968
+ after: after,
1969
+ before: before,
1970
+ once: once,
1971
+ findKey: findKey,
1972
+ findIndex: findIndex,
1973
+ findLastIndex: findLastIndex,
1974
+ sortedIndex: sortedIndex,
1975
+ indexOf: indexOf,
1976
+ lastIndexOf: lastIndexOf,
1977
+ find: find,
1978
+ detect: find,
1979
+ findWhere: findWhere,
1980
+ each: each,
1981
+ forEach: each,
1982
+ map: map,
1983
+ collect: map,
1984
+ reduce: reduce,
1985
+ foldl: reduce,
1986
+ inject: reduce,
1987
+ reduceRight: reduceRight,
1988
+ foldr: reduceRight,
1989
+ filter: filter,
1990
+ select: filter,
1991
+ reject: reject,
1992
+ every: every,
1993
+ all: every,
1994
+ some: some,
1995
+ any: some,
1996
+ contains: contains,
1997
+ includes: contains,
1998
+ include: contains,
1999
+ invoke: invoke,
2000
+ pluck: pluck,
2001
+ where: where,
2002
+ max: max,
2003
+ min: min,
2004
+ shuffle: shuffle,
2005
+ sample: sample,
2006
+ sortBy: sortBy,
2007
+ groupBy: groupBy,
2008
+ indexBy: indexBy,
2009
+ countBy: countBy,
2010
+ partition: partition,
2011
+ toArray: toArray,
2012
+ size: size,
2013
+ pick: pick,
2014
+ omit: omit,
2015
+ first: first,
2016
+ head: first,
2017
+ take: first,
2018
+ initial: initial,
2019
+ last: last,
2020
+ rest: rest,
2021
+ tail: rest,
2022
+ drop: rest,
2023
+ compact: compact,
2024
+ flatten: flatten,
2025
+ without: without,
2026
+ uniq: uniq,
2027
+ unique: uniq,
2028
+ union: union,
2029
+ intersection: intersection,
2030
+ difference: difference,
2031
+ unzip: unzip,
2032
+ transpose: unzip,
2033
+ zip: zip,
2034
+ object: object,
2035
+ range: range,
2036
+ chunk: chunk,
2037
+ mixin: mixin,
2038
+ 'default': _$1
2039
+ };
2040
+
2041
+ // Default Export
2042
+
2043
+ // Add all of the Underscore functions to the wrapper object.
2044
+ var _ = mixin(allExports);
2045
+ // Legacy Node.js API.
2046
+ _._ = _;
2047
+ return _;
2048
+ });
2049
+ }).call(this);
2050
+ }).call(this, typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {});
2051
+ }, {}],
2052
+ 2: [function (require, module, exports) {
2053
+ /**
2054
+ * Simple browser shim loader - assign the npm module to a window global automatically
2055
+ *
2056
+ * @license MIT
2057
+ * @author <steven@velozo.com>
2058
+ */
2059
+ var libNPMModuleWrapper = require('./Foxhound.js');
2060
+ if (typeof window === 'object' && !window.hasOwnProperty('Foxhound')) {
2061
+ window.Foxhound = libNPMModuleWrapper;
2062
+ }
2063
+ module.exports = libNPMModuleWrapper;
2064
+ }, {
2065
+ "./Foxhound.js": 3
2066
+ }],
2067
+ 3: [function (require, module, exports) {
2068
+ /**
2069
+ * FoxHound Query Generation Library
2070
+ *
2071
+ * @license MIT
2072
+ *
2073
+ * @author Steven Velozo <steven@velozo.com>
2074
+ * @module FoxHound
2075
+ */
2076
+
2077
+ // We use Underscore.js for utility
2078
+ var libUnderscore = require('underscore');
2079
+
2080
+ // Load our base parameters skeleton object
2081
+ var baseParameters = require('./Parameters.js');
2082
+
2083
+ /**
2084
+ * FoxHound Query Generation Library Main Class
2085
+ *
2086
+ * @class FoxHound
2087
+ * @constructor
2088
+ */
2089
+ var FoxHound = function () {
2090
+ function createNew(pFable, pFromParameters) {
2091
+ // If a valid Fable object isn't passed in, return a constructor
2092
+ if (typeof pFable !== 'object' || !('fable' in pFable)) {
2093
+ return {
2094
+ new: createNew
2095
+ };
2096
+ }
2097
+ var _Fable = pFable;
2098
+
2099
+ // The default parameters config object, used as a template for all new
2100
+ // queries created from this query.
2101
+ var _DefaultParameters = typeof pFromParameters === 'undefined' ? {} : pFromParameters;
2102
+
2103
+ // The parameters config object for the current query. This is the only
2104
+ // piece of internal state that is important to operation.
2105
+ var _Parameters = false;
2106
+
2107
+ // The unique identifier for a query
2108
+ var _UUID = _Fable.getUUID();
2109
+
2110
+ // The log level, for debugging chattiness.
2111
+ var _LogLevel = 0;
2112
+
2113
+ // The dialect to use when generating queries
2114
+ var _Dialect = false;
2115
+
2116
+ /**
2117
+ * Clone the current FoxHound Query into a new Query object, copying all
2118
+ * parameters as the new default. Clone also copies the log level.
2119
+ *
2120
+ * @method clone
2121
+ * @return {Object} Returns a cloned Query. This is still chainable.
2122
+ */
2123
+ var clone = function () {
2124
+ var tmpFoxHound = createNew(_Fable, baseParameters).setScope(_Parameters.scope).setBegin(_Parameters.begin).setCap(_Parameters.cap);
2125
+
2126
+ // Schema is the only part of a query that carries forward.
2127
+ tmpFoxHound.query.schema = _Parameters.query.schema;
2128
+ if (_Parameters.dataElements) {
2129
+ tmpFoxHound.parameters.dataElements = _Parameters.dataElements.slice(); // Copy the array of dataElements
2130
+ }
2131
+
2132
+ if (_Parameters.sort) {
2133
+ tmpFoxHound.parameters.sort = _Parameters.sort.slice(); // Copy the sort array.
2134
+ // TODO: Fix the side affect nature of these being objects in the array .. they are technically clones of the previous.
2135
+ }
2136
+
2137
+ if (_Parameters.filter) {
2138
+ tmpFoxHound.parameters.filter = _Parameters.filter.slice(); // Copy the filter array.
2139
+ // TODO: Fix the side affect nature of these being objects in the array .. they are technically clones of the previous.
2140
+ }
2141
+
2142
+ return tmpFoxHound;
2143
+ };
2144
+
2145
+ /**
2146
+ * Reset the parameters of the FoxHound Query to the Default. Default
2147
+ * parameters were set during object construction.
2148
+ *
2149
+ * @method resetParameters
2150
+ * @return {Object} Returns the current Query for chaining.
2151
+ */
2152
+ var resetParameters = function () {
2153
+ _Parameters = libUnderscore.extend({}, baseParameters, _DefaultParameters);
2154
+ _Parameters.query = {
2155
+ disableAutoIdentity: false,
2156
+ disableAutoDateStamp: false,
2157
+ disableAutoUserStamp: false,
2158
+ disableDeleteTracking: false,
2159
+ body: false,
2160
+ schema: false,
2161
+ // The schema to intersect with our records
2162
+ IDUser: 0,
2163
+ // The user to stamp into records
2164
+ UUID: _Fable.getUUID(),
2165
+ // A UUID for this record
2166
+ records: false,
2167
+ // The records to be created or changed
2168
+ parameters: {}
2169
+ };
2170
+ _Parameters.result = {
2171
+ executed: false,
2172
+ // True once we've run a query.
2173
+ value: false,
2174
+ // The return value of the last query run
2175
+ error: false // The error message of the last run query
2176
+ };
2177
+
2178
+ return this;
2179
+ };
2180
+ resetParameters();
2181
+
2182
+ /**
2183
+ * Reset the parameters of the FoxHound Query to the Default. Default
2184
+ * parameters were set during object construction.
2185
+ *
2186
+ * @method mergeParameters
2187
+ * @param {Object} pFromParameters A Parameters Object to merge from
2188
+ * @return {Object} Returns the current Query for chaining.
2189
+ */
2190
+ var mergeParameters = function (pFromParameters) {
2191
+ _Parameters = libUnderscore.extend({}, _Parameters, pFromParameters);
2192
+ return this;
2193
+ };
2194
+
2195
+ /**
2196
+ * Set the the Logging level.
2197
+ *
2198
+ * The log levels are:
2199
+ * 0 - Don't log anything
2200
+ * 1 - Log queries
2201
+ * 2 - Log queries and non-parameterized queries
2202
+ * 3 - Log everything
2203
+ *
2204
+ * @method setLogLevel
2205
+ * @param {Number} pLogLevel The log level for our object
2206
+ * @return {Object} Returns the current Query for chaining.
2207
+ */
2208
+ var setLogLevel = function (pLogLevel) {
2209
+ var tmpLogLevel = 0;
2210
+ if (typeof pLogLevel === 'number' && pLogLevel % 1 === 0) {
2211
+ tmpLogLevel = pLogLevel;
2212
+ }
2213
+ _LogLevel = tmpLogLevel;
2214
+ return this;
2215
+ };
2216
+
2217
+ /**
2218
+ * Set the Scope for the Query. *Scope* is the source for the data being
2219
+ * pulled. In TSQL this would be the _table_, whereas in MongoDB this
2220
+ * would be the _collection_.
2221
+ *
2222
+ * A scope can be either a string, or an array (for JOINs and such).
2223
+ *
2224
+ * @method setScope
2225
+ * @param {String} pScope A Scope for the Query.
2226
+ * @return {Object} Returns the current Query for chaining.
2227
+ */
2228
+ var setScope = function (pScope) {
2229
+ var tmpScope = false;
2230
+ if (typeof pScope === 'string') {
2231
+ tmpScope = pScope;
2232
+ } else if (pScope !== false) {
2233
+ _Fable.log.error('Scope set failed. You must pass in a string or array.', {
2234
+ queryUUID: _UUID,
2235
+ parameters: _Parameters,
2236
+ invalidScope: pScope
2237
+ });
2238
+ }
2239
+ _Parameters.scope = tmpScope;
2240
+ if (_LogLevel > 2) {
2241
+ _Fable.log.info('Scope set: ' + tmpScope, {
2242
+ queryUUID: _UUID,
2243
+ parameters: _Parameters
2244
+ });
2245
+ }
2246
+ return this;
2247
+ };
2248
+
2249
+ /**
2250
+ * Set whether the query returns DISTINCT results.
2251
+ * For count queries, returns the distinct for the selected fields, or all fields in the base table by default.
2252
+ *
2253
+ * @method setDistinct
2254
+ * @param {Boolean} pDistinct True if the query should be distinct.
2255
+ * @return {Object} Returns the current Query for chaining.
2256
+ */
2257
+ var setDistinct = function (pDistinct) {
2258
+ _Parameters.distinct = !!pDistinct;
2259
+ if (_LogLevel > 2) {
2260
+ _Fable.log.info('Distinct set: ' + _Parameters.distinct, {
2261
+ queryUUID: _UUID,
2262
+ parameters: _Parameters
2263
+ });
2264
+ }
2265
+ return this;
2266
+ };
2267
+
2268
+ /**
2269
+ * Set the Data Elements for the Query. *Data Elements* are the fields
2270
+ * being pulled by the query. In TSQL this would be the _columns_,
2271
+ * whereas in MongoDB this would be the _fields_.
2272
+ *
2273
+ * The passed values can be either a string, or an array.
2274
+ *
2275
+ * @method setDataElements
2276
+ * @param {String} pDataElements The Data Element(s) for the Query.
2277
+ * @return {Object} Returns the current Query for chaining.
2278
+ */
2279
+ var setDataElements = function (pDataElements) {
2280
+ var tmpDataElements = false;
2281
+ if (Array.isArray(pDataElements)) {
2282
+ // TODO: Check each entry of the array are all strings
2283
+ tmpDataElements = pDataElements;
2284
+ }
2285
+ if (typeof pDataElements === 'string') {
2286
+ tmpDataElements = [pDataElements];
2287
+ }
2288
+ _Parameters.dataElements = tmpDataElements;
2289
+ if (_LogLevel > 2) {
2290
+ _Fable.log.info('Data Elements set', {
2291
+ queryUUID: _UUID,
2292
+ parameters: _Parameters
2293
+ });
2294
+ }
2295
+ return this;
2296
+ };
2297
+
2298
+ /**
2299
+ * Set the sort data element
2300
+ *
2301
+ * The passed values can be either a string, an object or an array of objects.
2302
+ *
2303
+ * The Sort object has two values:
2304
+ * {Column:'Birthday', Direction:'Ascending'}
2305
+ *
2306
+ * @method setSort
2307
+ * @param {String} pSort The sort criteria(s) for the Query.
2308
+ * @return {Object} Returns the current Query for chaining.
2309
+ */
2310
+ var setSort = function (pSort) {
2311
+ var tmpSort = false;
2312
+ if (Array.isArray(pSort)) {
2313
+ // TODO: Check each entry of the array are all conformant sort objects
2314
+ tmpSort = pSort;
2315
+ } else if (typeof pSort === 'string') {
2316
+ // Default to ascending
2317
+ tmpSort = [{
2318
+ Column: pSort,
2319
+ Direction: 'Ascending'
2320
+ }];
2321
+ } else if (typeof pSort === 'object') {
2322
+ // TODO: Check that this sort entry conforms to a sort entry
2323
+ tmpSort = [pSort];
2324
+ }
2325
+ _Parameters.sort = tmpSort;
2326
+ if (_LogLevel > 2) {
2327
+ _Fable.log.info('Sort set', {
2328
+ queryUUID: _UUID,
2329
+ parameters: _Parameters
2330
+ });
2331
+ }
2332
+ return this;
2333
+ };
2334
+
2335
+ /**
2336
+ * Set the join data element
2337
+ *
2338
+ * The passed values can be either an object or an array of objects.
2339
+ *
2340
+ * The join object has four values:
2341
+ * {Type:'INNER JOIN', Table:'Test', From:'Test.ID', To:'Scope.IDItem'}
2342
+ *
2343
+ * @method setJoin
2344
+ * @param {Object} pJoin The join criteria(s) for the Query.
2345
+ * @return {Object} Returns the current Query for chaining.
2346
+ */
2347
+ var setJoin = function (pJoin) {
2348
+ _Parameters.join = [];
2349
+ if (Array.isArray(pJoin)) {
2350
+ pJoin.forEach(function (join) {
2351
+ addJoin(join.Table, join.From, join.To, join.Type);
2352
+ });
2353
+ } else if (typeof pJoin === 'object') {
2354
+ addJoin(pJoin.Table, pJoin.From, pJoin.To, pJoin.Type);
2355
+ }
2356
+ return this;
2357
+ };
2358
+
2359
+ /**
2360
+ * Add a sort data element
2361
+ *
2362
+ * The passed values can be either a string, an object or an array of objects.
2363
+ *
2364
+ * The Sort object has two values:
2365
+ * {Column:'Birthday', Direction:'Ascending'}
2366
+ *
2367
+ * @method setSort
2368
+ * @param {String} pSort The sort criteria to add to the Query.
2369
+ * @return {Object} Returns the current Query for chaining.
2370
+ */
2371
+ var addSort = function (pSort) {
2372
+ var tmpSort = false;
2373
+ if (typeof pSort === 'string') {
2374
+ // Default to ascending
2375
+ tmpSort = {
2376
+ Column: pSort,
2377
+ Direction: 'Ascending'
2378
+ };
2379
+ }
2380
+ if (typeof pSort === 'object') {
2381
+ // TODO: Check that this sort entry conforms to a sort entry
2382
+ tmpSort = pSort;
2383
+ }
2384
+ if (!_Parameters.sort) {
2385
+ _Parameters.sort = [];
2386
+ }
2387
+ _Parameters.sort.push(tmpSort);
2388
+ if (_LogLevel > 2) {
2389
+ _Fable.log.info('Sort set', {
2390
+ queryUUID: _UUID,
2391
+ parameters: _Parameters
2392
+ });
2393
+ }
2394
+ return this;
2395
+ };
2396
+
2397
+ /**
2398
+ * Set the the Begin index for the Query. *Begin* is the index at which
2399
+ * a query should start returning rows. In TSQL this would be the n
2400
+ * parameter of ```LIMIT 1,n```, whereas in MongoDB this would be the
2401
+ * n in ```skip(n)```.
2402
+ *
2403
+ * The passed value must be an Integer >= 0.
2404
+ *
2405
+ * @method setBegin
2406
+ * @param {Number} pBeginAmount The index to begin returning Query data.
2407
+ * @return {Object} Returns the current Query for chaining.
2408
+ */
2409
+ var setBegin = function (pBeginAmount) {
2410
+ var tmpBegin = false;
2411
+
2412
+ // Test if it is an integer > -1
2413
+ // http://jsperf.com/numbers-and-integers
2414
+ if (typeof pBeginAmount === 'number' && pBeginAmount % 1 === 0 && pBeginAmount >= 0) {
2415
+ tmpBegin = pBeginAmount;
2416
+ } else if (pBeginAmount !== false) {
2417
+ _Fable.log.error('Begin set failed; non-positive or non-numeric argument.', {
2418
+ queryUUID: _UUID,
2419
+ parameters: _Parameters,
2420
+ invalidBeginAmount: pBeginAmount
2421
+ });
2422
+ }
2423
+ _Parameters.begin = tmpBegin;
2424
+ if (_LogLevel > 2) {
2425
+ _Fable.log.info('Begin set: ' + pBeginAmount, {
2426
+ queryUUID: _UUID,
2427
+ parameters: _Parameters
2428
+ });
2429
+ }
2430
+ return this;
2431
+ };
2432
+
2433
+ /**
2434
+ * Set the the Cap for the Query. *Cap* is the maximum number of records
2435
+ * a Query should return in a set. In TSQL this would be the n
2436
+ * parameter of ```LIMIT n```, whereas in MongoDB this would be the
2437
+ * n in ```limit(n)```.
2438
+ *
2439
+ * The passed value must be an Integer >= 0.
2440
+ *
2441
+ * @method setCap
2442
+ * @param {Number} pCapAmount The maximum records for the Query set.
2443
+ * @return {Object} Returns the current Query for chaining.
2444
+ */
2445
+ var setCap = function (pCapAmount) {
2446
+ var tmpCapAmount = false;
2447
+ if (typeof pCapAmount === 'number' && pCapAmount % 1 === 0 && pCapAmount >= 0) {
2448
+ tmpCapAmount = pCapAmount;
2449
+ } else if (pCapAmount !== false) {
2450
+ _Fable.log.error('Cap set failed; non-positive or non-numeric argument.', {
2451
+ queryUUID: _UUID,
2452
+ parameters: _Parameters,
2453
+ invalidCapAmount: pCapAmount
2454
+ });
2455
+ }
2456
+ _Parameters.cap = tmpCapAmount;
2457
+ if (_LogLevel > 2) {
2458
+ _Fable.log.info('Cap set to: ' + tmpCapAmount, {
2459
+ queryUUID: _UUID,
2460
+ parameters: _Parameters
2461
+ });
2462
+ }
2463
+ return this;
2464
+ };
2465
+
2466
+ /**
2467
+ * Set the filter expression
2468
+ *
2469
+ * The passed values can be either an object or an array of objects.
2470
+ *
2471
+ * The Filter object has a minimum of two values (which expands to the following):
2472
+ * {Column:'Name', Value:'John'}
2473
+ * {Column:'Name', Operator:'EQ', Value:'John', Connector:'And', Parameter:'Name'}
2474
+ *
2475
+ * @method setFilter
2476
+ * @param {String} pFilter The filter(s) for the Query.
2477
+ * @return {Object} Returns the current Query for chaining.
2478
+ */
2479
+ var setFilter = function (pFilter) {
2480
+ var tmpFilter = false;
2481
+ if (Array.isArray(pFilter)) {
2482
+ // TODO: Check each entry of the array are all conformant Filter objects
2483
+ tmpFilter = pFilter;
2484
+ } else if (typeof pFilter === 'object') {
2485
+ // TODO: Check that this Filter entry conforms to a Filter entry
2486
+ tmpFilter = [pFilter];
2487
+ }
2488
+ _Parameters.filter = tmpFilter;
2489
+ if (_LogLevel > 2) {
2490
+ _Fable.log.info('Filter set', {
2491
+ queryUUID: _UUID,
2492
+ parameters: _Parameters
2493
+ });
2494
+ }
2495
+ return this;
2496
+ };
2497
+
2498
+ /**
2499
+ * Add a filter expression
2500
+ *
2501
+ * {Column:'Name', Operator:'EQ', Value:'John', Connector:'And', Parameter:'Name'}
2502
+ *
2503
+ * @method addFilter
2504
+ * @return {Object} Returns the current Query for chaining.
2505
+ */
2506
+ var addFilter = function (pColumn, pValue, pOperator, pConnector, pParameter) {
2507
+ if (typeof pColumn !== 'string') {
2508
+ _Fable.log.warn('Tried to add an invalid query filter column', {
2509
+ queryUUID: _UUID,
2510
+ parameters: _Parameters
2511
+ });
2512
+ return this;
2513
+ }
2514
+ if (typeof pValue === 'undefined') {
2515
+ _Fable.log.warn('Tried to add an invalid query filter value', {
2516
+ queryUUID: _UUID,
2517
+ parameters: _Parameters,
2518
+ invalidColumn: pColumn
2519
+ });
2520
+ return this;
2521
+ }
2522
+ var tmpOperator = typeof pOperator === 'undefined' ? '=' : pOperator;
2523
+ var tmpConnector = typeof pConnector === 'undefined' ? 'AND' : pConnector;
2524
+ var tmpParameter = typeof pParameter === 'undefined' ? pColumn : pParameter;
2525
+
2526
+ //support table.field notation (mysql2 requires this)
2527
+ tmpParameter = tmpParameter.replace('.', '_');
2528
+ var tmpFilter = {
2529
+ Column: pColumn,
2530
+ Operator: tmpOperator,
2531
+ Value: pValue,
2532
+ Connector: tmpConnector,
2533
+ Parameter: tmpParameter
2534
+ };
2535
+ if (!Array.isArray(_Parameters.filter)) {
2536
+ _Parameters.filter = [tmpFilter];
2537
+ } else {
2538
+ _Parameters.filter.push(tmpFilter);
2539
+ }
2540
+ if (_LogLevel > 2) {
2541
+ _Fable.log.info('Added a filter', {
2542
+ queryUUID: _UUID,
2543
+ parameters: _Parameters,
2544
+ newFilter: tmpFilter
2545
+ });
2546
+ }
2547
+ return this;
2548
+ };
2549
+
2550
+ /**
2551
+ * Add a join expression
2552
+ *
2553
+ * {Type:'INNER JOIN', Table:'Test', From:'Test.ID', To:'Scope.IDItem'}
2554
+ *
2555
+ * @method addJoin
2556
+ * @return {Object} Returns the current Query for chaining.
2557
+ */
2558
+ var addJoin = function (pTable, pFrom, pTo, pType) {
2559
+ if (typeof pTable !== 'string') {
2560
+ _Fable.log.warn('Tried to add an invalid query join table', {
2561
+ queryUUID: _UUID,
2562
+ parameters: _Parameters
2563
+ });
2564
+ return this;
2565
+ }
2566
+ if (typeof pFrom === 'undefined' || typeof pTo === 'undefined') {
2567
+ _Fable.log.warn('Tried to add an invalid query join field', {
2568
+ queryUUID: _UUID,
2569
+ parameters: _Parameters
2570
+ });
2571
+ return this;
2572
+ }
2573
+ //sanity check the join fields
2574
+ if (pFrom.indexOf(pTable) != 0) {
2575
+ _Fable.log.warn('Tried to add an invalid query join field, join must come FROM the join table!', {
2576
+ queryUUID: _UUID,
2577
+ parameters: _Parameters,
2578
+ invalidField: pFrom
2579
+ });
2580
+ return this;
2581
+ }
2582
+ if (pTo.indexOf('.') <= 0) {
2583
+ _Fable.log.warn('Tried to add an invalid query join field, join must go TO a field on another table ([table].[field])!', {
2584
+ queryUUID: _UUID,
2585
+ parameters: _Parameters,
2586
+ invalidField: pTo
2587
+ });
2588
+ return this;
2589
+ }
2590
+ var tmpType = typeof pType === 'undefined' ? 'INNER JOIN' : pType;
2591
+ var tmpJoin = {
2592
+ Type: tmpType,
2593
+ Table: pTable,
2594
+ From: pFrom,
2595
+ To: pTo
2596
+ };
2597
+ if (!Array.isArray(_Parameters.join)) {
2598
+ _Parameters.join = [tmpJoin];
2599
+ } else {
2600
+ _Parameters.join.push(tmpJoin);
2601
+ }
2602
+ if (_LogLevel > 2) {
2603
+ _Fable.log.info('Added a join', {
2604
+ queryUUID: _UUID,
2605
+ parameters: _Parameters
2606
+ });
2607
+ }
2608
+ return this;
2609
+ };
2610
+
2611
+ /**
2612
+ * Add a record (for UPDATE and INSERT)
2613
+ *
2614
+ *
2615
+ * @method addRecord
2616
+ * @param {Object} pRecord The record to add.
2617
+ * @return {Object} Returns the current Query for chaining.
2618
+ */
2619
+ var addRecord = function (pRecord) {
2620
+ if (typeof pRecord !== 'object') {
2621
+ _Fable.log.warn('Tried to add an invalid record to the query -- records must be an object', {
2622
+ queryUUID: _UUID,
2623
+ parameters: _Parameters
2624
+ });
2625
+ return this;
2626
+ }
2627
+ if (!Array.isArray(_Parameters.query.records)) {
2628
+ _Parameters.query.records = [pRecord];
2629
+ } else {
2630
+ _Parameters.query.records.push(pRecord);
2631
+ }
2632
+ if (_LogLevel > 2) {
2633
+ _Fable.log.info('Added a record to the query', {
2634
+ queryUUID: _UUID,
2635
+ parameters: _Parameters,
2636
+ newRecord: pRecord
2637
+ });
2638
+ }
2639
+ return this;
2640
+ };
2641
+
2642
+ /**
2643
+ * Set the Dialect for Query generation.
2644
+ *
2645
+ * This function expects a string, case sensitive, which matches both the
2646
+ * folder and filename
2647
+ *
2648
+ * @method setDialect
2649
+ * @param {String} pDialectName The dialect for query generation.
2650
+ * @return {Object} Returns the current Query for chaining.
2651
+ */
2652
+ var setDialect = function (pDialectName) {
2653
+ if (typeof pDialectName !== 'string') {
2654
+ _Fable.log.warn('Dialect set to English - invalid name', {
2655
+ queryUUID: _UUID,
2656
+ parameters: _Parameters,
2657
+ invalidDialect: pDialectName
2658
+ });
2659
+ return setDialect('English');
2660
+ }
2661
+ var tmpDialectModuleFile = './dialects/' + pDialectName + '/FoxHound-Dialect-' + pDialectName + '.js';
2662
+ try {
2663
+ var tmpDialectModule = require(tmpDialectModuleFile);
2664
+ _Dialect = tmpDialectModule;
2665
+ if (_LogLevel > 2) {
2666
+ _Fable.log.info('Dialog set to: ' + pDialectName, {
2667
+ queryUUID: _UUID,
2668
+ parameters: _Parameters,
2669
+ dialectModuleFile: tmpDialectModuleFile
2670
+ });
2671
+ }
2672
+ } catch (pError) {
2673
+ _Fable.log.error('Dialect not set - require load problem', {
2674
+ queryUUID: _UUID,
2675
+ parameters: _Parameters,
2676
+ dialectModuleFile: tmpDialectModuleFile,
2677
+ invalidDialect: pDialectName,
2678
+ error: pError
2679
+ });
2680
+ setDialect('English');
2681
+ }
2682
+ return this;
2683
+ };
2684
+
2685
+ /**
2686
+ * User to use for this query
2687
+ *
2688
+ * @method setIDUser
2689
+ */
2690
+ var setIDUser = function (pIDUser) {
2691
+ var tmpUserID = 0;
2692
+ if (typeof pIDUser === 'number' && pIDUser % 1 === 0 && pIDUser >= 0) {
2693
+ tmpUserID = pIDUser;
2694
+ } else if (pIDUser !== false) {
2695
+ _Fable.log.error('User set failed; non-positive or non-numeric argument.', {
2696
+ queryUUID: _UUID,
2697
+ parameters: _Parameters,
2698
+ invalidIDUser: pIDUser
2699
+ });
2700
+ }
2701
+ _Parameters.userID = tmpUserID;
2702
+ _Parameters.query.IDUser = tmpUserID;
2703
+ if (_LogLevel > 2) {
2704
+ _Fable.log.info('IDUser set to: ' + tmpUserID, {
2705
+ queryUUID: _UUID,
2706
+ parameters: _Parameters
2707
+ });
2708
+ }
2709
+ return this;
2710
+ };
2711
+
2712
+ /**
2713
+ * Flag to disable auto identity
2714
+ *
2715
+ * @method setDisableAutoIdentity
2716
+ */
2717
+ var setDisableAutoIdentity = function (pFlag) {
2718
+ _Parameters.query.disableAutoIdentity = pFlag;
2719
+ return this; //chainable
2720
+ };
2721
+
2722
+ /**
2723
+ * Flag to disable auto datestamp
2724
+ *
2725
+ * @method setDisableAutoDateStamp
2726
+ */
2727
+ var setDisableAutoDateStamp = function (pFlag) {
2728
+ _Parameters.query.disableAutoDateStamp = pFlag;
2729
+ return this; //chainable
2730
+ };
2731
+
2732
+ /**
2733
+ * Flag to disable auto userstamp
2734
+ *
2735
+ * @method setDisableAutoUserStamp
2736
+ */
2737
+ var setDisableAutoUserStamp = function (pFlag) {
2738
+ _Parameters.query.disableAutoUserStamp = pFlag;
2739
+ return this; //chainable
2740
+ };
2741
+
2742
+ /**
2743
+ * Flag to disable delete tracking
2744
+ *
2745
+ * @method setDisableDeleteTracking
2746
+ */
2747
+ var setDisableDeleteTracking = function (pFlag) {
2748
+ _Parameters.query.disableDeleteTracking = pFlag;
2749
+ return this; //chainable
2750
+ };
2751
+
2752
+ /**
2753
+ * Check that a valid Dialect has been set
2754
+ *
2755
+ * If there has not been a dialect set, it defaults to English.
2756
+ * TODO: Have the json configuration define a "default" dialect.
2757
+ *
2758
+ * @method checkDialect
2759
+ */
2760
+ var checkDialect = function () {
2761
+ if (_Dialect === false) {
2762
+ setDialect('English');
2763
+ }
2764
+ };
2765
+ var buildCreateQuery = function () {
2766
+ checkDialect();
2767
+ _Parameters.query.body = _Dialect.Create(_Parameters);
2768
+ return this;
2769
+ };
2770
+ var buildReadQuery = function () {
2771
+ checkDialect();
2772
+ _Parameters.query.body = _Dialect.Read(_Parameters);
2773
+ return this;
2774
+ };
2775
+ var buildUpdateQuery = function () {
2776
+ checkDialect();
2777
+ _Parameters.query.body = _Dialect.Update(_Parameters);
2778
+ return this;
2779
+ };
2780
+ var buildDeleteQuery = function () {
2781
+ checkDialect();
2782
+ _Parameters.query.body = _Dialect.Delete(_Parameters);
2783
+ return this;
2784
+ };
2785
+ var buildUndeleteQuery = function () {
2786
+ checkDialect();
2787
+ _Parameters.query.body = _Dialect.Undelete(_Parameters);
2788
+ return this;
2789
+ };
2790
+ var buildCountQuery = function () {
2791
+ checkDialect();
2792
+ _Parameters.query.body = _Dialect.Count(_Parameters);
2793
+ return this;
2794
+ };
2795
+
2796
+ /**
2797
+ * Container Object for our Factory Pattern
2798
+ */
2799
+ var tmpNewFoxHoundObject = {
2800
+ resetParameters: resetParameters,
2801
+ mergeParameters: mergeParameters,
2802
+ setLogLevel: setLogLevel,
2803
+ setScope: setScope,
2804
+ setDistinct: setDistinct,
2805
+ setIDUser: setIDUser,
2806
+ setDataElements: setDataElements,
2807
+ setBegin: setBegin,
2808
+ setCap: setCap,
2809
+ setFilter: setFilter,
2810
+ addFilter: addFilter,
2811
+ setSort: setSort,
2812
+ addSort: addSort,
2813
+ setJoin: setJoin,
2814
+ addJoin: addJoin,
2815
+ addRecord: addRecord,
2816
+ setDisableAutoIdentity: setDisableAutoIdentity,
2817
+ setDisableAutoDateStamp: setDisableAutoDateStamp,
2818
+ setDisableAutoUserStamp: setDisableAutoUserStamp,
2819
+ setDisableDeleteTracking: setDisableDeleteTracking,
2820
+ setDialect: setDialect,
2821
+ buildCreateQuery: buildCreateQuery,
2822
+ buildReadQuery: buildReadQuery,
2823
+ buildUpdateQuery: buildUpdateQuery,
2824
+ buildDeleteQuery: buildDeleteQuery,
2825
+ buildUndeleteQuery: buildUndeleteQuery,
2826
+ buildCountQuery: buildCountQuery,
2827
+ clone: clone,
2828
+ new: createNew
2829
+ };
2830
+
2831
+ /**
2832
+ * Query
2833
+ *
2834
+ * @property query
2835
+ * @type Object
2836
+ */
2837
+ Object.defineProperty(tmpNewFoxHoundObject, 'query', {
2838
+ get: function () {
2839
+ return _Parameters.query;
2840
+ },
2841
+ set: function (pQuery) {
2842
+ _Parameters.query = pQuery;
2843
+ },
2844
+ enumerable: true
2845
+ });
2846
+
2847
+ /**
2848
+ * Result
2849
+ *
2850
+ * @property result
2851
+ * @type Object
2852
+ */
2853
+ Object.defineProperty(tmpNewFoxHoundObject, 'result', {
2854
+ get: function () {
2855
+ return _Parameters.result;
2856
+ },
2857
+ set: function (pResult) {
2858
+ _Parameters.result = pResult;
2859
+ },
2860
+ enumerable: true
2861
+ });
2862
+
2863
+ /**
2864
+ * Query Parameters
2865
+ *
2866
+ * @property parameters
2867
+ * @type Object
2868
+ */
2869
+ Object.defineProperty(tmpNewFoxHoundObject, 'parameters', {
2870
+ get: function () {
2871
+ return _Parameters;
2872
+ },
2873
+ set: function (pParameters) {
2874
+ _Parameters = pParameters;
2875
+ },
2876
+ enumerable: true
2877
+ });
2878
+
2879
+ /**
2880
+ * Dialect
2881
+ *
2882
+ * @property dialect
2883
+ * @type Object
2884
+ */
2885
+ Object.defineProperty(tmpNewFoxHoundObject, 'dialect', {
2886
+ get: function () {
2887
+ return _Dialect;
2888
+ },
2889
+ enumerable: true
2890
+ });
2891
+
2892
+ /**
2893
+ * Universally Unique Identifier
2894
+ *
2895
+ * @property uuid
2896
+ * @type String
2897
+ */
2898
+ Object.defineProperty(tmpNewFoxHoundObject, 'uuid', {
2899
+ get: function () {
2900
+ return _UUID;
2901
+ },
2902
+ enumerable: true
2903
+ });
2904
+
2905
+ /**
2906
+ * Log Level
2907
+ *
2908
+ * @property logLevel
2909
+ * @type Integer
2910
+ */
2911
+ Object.defineProperty(tmpNewFoxHoundObject, 'logLevel', {
2912
+ get: function () {
2913
+ return _LogLevel;
2914
+ },
2915
+ enumerable: true
2916
+ });
2917
+ return tmpNewFoxHoundObject;
2918
+ }
2919
+ return createNew();
2920
+ };
2921
+ module.exports = new FoxHound();
2922
+ }, {
2923
+ "./Parameters.js": 4,
2924
+ "underscore": 1
2925
+ }],
2926
+ 4: [function (require, module, exports) {
2927
+ /**
2928
+ * Query Parameters Object
2929
+ *
2930
+ * @class FoxHoundQueryParameters
2931
+ * @constructor
2932
+ */
2933
+ var FoxHoundQueryParameters = {
2934
+ scope: false,
2935
+ // STR: The scope of the data
2936
+ // TSQL: the "Table" or "View"
2937
+ // MongoDB: the "Collection"
2938
+
2939
+ dataElements: false,
2940
+ // ARR of STR: The data elements to return
2941
+ // TSQL: the "Columns"
2942
+ // MongoDB: the "Fields"
2943
+
2944
+ begin: false,
2945
+ // INT: Record index to start at
2946
+ // TSQL: n in LIMIT 1,n
2947
+ // MongoDB: n in Skip(n)
2948
+
2949
+ cap: false,
2950
+ // INT: Maximum number of records to return
2951
+ // TSQL: n in LIMIT n
2952
+ // MongoDB: n in limit(n)
2953
+
2954
+ // Serialization example for a query:
2955
+ // Take the filter and return an array of filter instructions
2956
+ // Basic instruction anatomy:
2957
+ // INSTRUCTION~FIELD~OPERATOR~VALUE
2958
+ // FOP - Filter Open Paren
2959
+ // FOP~~(~
2960
+ // FCP - Filter Close Paren
2961
+ // FCP~~)~
2962
+ // FBV - Filter By Value
2963
+ // FBV~Category~EQ~Books
2964
+ // Possible comparisons:
2965
+ // * EQ - Equals To (=)
2966
+ // * NE - Not Equals To (!=)
2967
+ // * GT - Greater Than (>)
2968
+ // * GE - Greater Than or Equals To (>=)
2969
+ // * LT - Less Than (<)
2970
+ // * LE - Less Than or Equals To (<=)
2971
+ // * LK - Like (Like)
2972
+ // FBL - Filter By List (value list, separated by commas)
2973
+ // FBL~Category~EQ~Books,Movies
2974
+ // FSF - Filter Sort Field
2975
+ // FSF~Category~ASC~0
2976
+ // FSF~Category~DESC~0
2977
+ // FCC - Filter Constraint Cap (the limit of what is returned)
2978
+ // FCC~~10~
2979
+ // FCB - Filter Constraint Begin (the zero-based start index of what is returned)
2980
+ // FCB~~10~
2981
+ //
2982
+ // This means: FBV~Category~EQ~Books~FBV~PublishedYear~GT~2000~FSF~PublishedYear~DESC~0
2983
+ // Filters down to ALL BOOKS PUBLISHED AFTER 2000 IN DESCENDING ORDER
2984
+ filter: false,
2985
+ // ARR of OBJ: Data filter expression list {Column:'Name', Operator:'EQ', Value:'John', Connector:'And', Parameter:'Name'}
2986
+ // TSQL: the WHERE clause
2987
+ // MongoDB: a find() expression
2988
+
2989
+ sort: false,
2990
+ // ARR of OBJ: The sort order {Column:'Birthday', Direction:'Ascending'}
2991
+ // TSQL: ORDER BY
2992
+ // MongoDB: sort()
2993
+
2994
+ join: false,
2995
+ // ARR of OBJ: The join tables {Type:'INNER JOIN', Table:'test', From: 'Test.ID', To: 'Scope.IDItem' }
2996
+ // TSQL: JOIN
2997
+
2998
+ // Force a specific query to run regardless of above ... this is used to override the query generator.
2999
+ queryOverride: false,
3000
+ // Where the generated query goes
3001
+ query: false,
3002
+ /*
3003
+ {
3004
+ body: false,
3005
+ schema: false, // The schema to intersect with our records
3006
+ IDUser: 0, // The User ID to stamp into records
3007
+ UUID: A_UUID, // Some globally unique record id, different per cloned query.
3008
+ records: false, // The records to be created or changed
3009
+ parameters: {}
3010
+ }
3011
+ */
3012
+
3013
+ // Who is making the query
3014
+ userID: 0,
3015
+ // Where the query results are stuck
3016
+ result: false
3017
+ /*
3018
+ {
3019
+ executed: false, // True once we've run a query.
3020
+ value: false, // The return value of the last query run
3021
+ error: false // The error message of the last run query
3022
+ }
3023
+ */
3024
+ };
3025
+
3026
+ module.exports = FoxHoundQueryParameters;
3027
+ }, {}]
3028
+ }, {}, [2])(2);
3029
+ });