fable 3.0.20 → 3.0.21

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.
package/dist/fable.js CHANGED
@@ -276,7 +276,7 @@
276
276
  }).call(this);
277
277
  }).call(this, require("timers").setImmediate);
278
278
  }, {
279
- "timers": 33
279
+ "timers": 34
280
280
  }],
281
281
  14: [function (require, module, exports) {
282
282
  'use strict';
@@ -327,6 +327,424 @@
327
327
  }],
328
328
  16: [function (require, module, exports) {}, {}],
329
329
  17: [function (require, module, exports) {
330
+ /**
331
+ * @license MIT
332
+ * @author <steven@velozo.com>
333
+ */
334
+
335
+ /**
336
+ * Data Arithmatic
337
+ *
338
+ * @class DataArithmatic
339
+ */
340
+ class DataArithmatic {
341
+ constructor() {
342
+ // Regular Expressions (so they don't have to be recompiled every time)
343
+ // These could be defined as static, but I'm not sure if that will work with browserify ... and specifically the QT browser.
344
+ this._Regex_formatterInsertCommas = /.{1,3}/g;
345
+ // Match Function:
346
+ // function(pMatch, pSign, pZeros, pBefore, pDecimal, pAfter)
347
+ // Thoughts about below: /^([+-]?)(0*)(\d+)(\.(\d+))?$/;
348
+ this._Regex_formatterAddCommasToNumber = /^([-+]?)(0?)(\d+)(.?)(\d+)$/g;
349
+ this._Regex_formatterDollarsRemoveCommas = /,/gi;
350
+ this._Regex_formatterCleanNonAlpha = /[^a-z0-9]/gi;
351
+
352
+ // TODO: Potentially pull these in from a configuration.
353
+ // TODO: Use locale data for this if it's defaults all the way down.
354
+ this._Value_MoneySign_Currency = '$';
355
+ this._Value_NaN_Currency = '--';
356
+ this._Value_GroupSeparator_Number = ',';
357
+ this._Value_Prefix_StringHash = 'HSH';
358
+ this._Value_Clean_formatterCleanNonAlpha = '_';
359
+ this._UseEngineStringStartsWith = typeof String.prototype.startsWith === 'function';
360
+ this._UseEngineStringEndsWith = typeof String.prototype.endsWith === 'function';
361
+ }
362
+
363
+ /*************************************************************************
364
+ * String Manipulation and Comparison Functions
365
+ *-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/
366
+
367
+ /**
368
+ * Reverse a string
369
+ *
370
+ * @param {string} pString - The string to reverse
371
+ * @returns {string}
372
+ */
373
+ stringReverse(pString) {
374
+ // TODO: Benchmark if there are faster ways we want to do this with all the newer JS stuff
375
+ // ... and if it will work with browserify in a clean way.
376
+ return pString.split('').reverse().join('');
377
+ }
378
+
379
+ /**
380
+ * Test if a string starts with a given substring.
381
+ *
382
+ * @param {*} pString
383
+ * @param {*} pSearchString
384
+ * @param {*} pStartIndex
385
+ * @returns {*}
386
+ */
387
+ stringStartsWith(pString, pSearchString, pStartIndex) {
388
+ if (this._UseEngineStringStartsWith) {
389
+ return pString.startsWith(pSearchString, pStartIndex);
390
+ } else {
391
+ return this.stringStartsWith_Polyfill.call(pString, pSearchString, pStartIndex);
392
+ }
393
+ }
394
+
395
+ /**
396
+ * Check if a string starts with a given substring. This is a safe polyfill for the ES6 string.startsWith() function.
397
+ *
398
+ * @param {*} pSearchString - The string to search for
399
+ * @param {*} pStartIndex - The index to start the search at
400
+ * @returns {boolean}
401
+ */
402
+ stringStartsWith_Polyfill(pSearchString, pStartIndex) {
403
+ return this.slice(pStartIndex || 0, pSearchString.length) === pSearchString;
404
+ }
405
+
406
+ /**
407
+ * Test if a string starts with a given substring.
408
+ *
409
+ * @param {*} pString
410
+ * @param {*} pSearchString
411
+ * @param {*} pEndIndex
412
+ * @returns {*}
413
+ */
414
+ stringEndsWith(pString, pSearchString, pEndIndex) {
415
+ if (this._UseEngineStringEndsWith) {
416
+ return pString.endsWith(pSearchString, pEndIndex);
417
+ } else {
418
+ return this.stringEndsWith_Polyfill.call(pString, pSearchString, pEndIndex);
419
+ }
420
+ }
421
+
422
+ /**
423
+ * Check if a string starts with a given substring. This is a safe polyfill for the ES6 string.startsWith() function.
424
+ *
425
+ * @param {*} pSearchString - The string to search for
426
+ * @param {*} pEndIndex - The index to end the search at
427
+ * @returns {boolean}
428
+ */
429
+ stringEndsWith_Polyfill(pSearchString, pEndIndex) {
430
+ // This works much better than >= because
431
+ // it compensates for NaN:
432
+ if (!(pEndIndex < this.length)) {
433
+ pEndIndex = this.length;
434
+ } else {
435
+ pEndIndex |= 0; // round position
436
+ }
437
+
438
+ return this.substr(pEndIndex - pSearchString.length, pSearchString.length) === pSearchString;
439
+ }
440
+
441
+ /**
442
+ * Generate an insecure string hash. Not meant to be secure, just a quick way to generate a hash for a string. This is not a cryptographic hash. Additional warranty and disclaimer ... this is not for passwords!
443
+ *
444
+ * @param {string} pString
445
+ * @returns {string}
446
+ */
447
+ insecureStringHash(pString) {
448
+ let tmpHash = 0;
449
+ let tmpStringLength = pString.length;
450
+ let tmpCharacterIndex = 0;
451
+ while (tmpCharacterIndex < tmpStringLength) {
452
+ tmpHash = (tmpHash << 5) - tmpHash + pString.charCodeAt(tmpCharacterIndex++) | 0;
453
+ }
454
+ return "".concat(this._Value_Prefix_StringHash).concat(tmpHash);
455
+ }
456
+
457
+ /**
458
+ * Clean wrapping characters if they exist consistently around the string. If they do not, the string is returned unchanged.
459
+ *
460
+ * @param {string} pWrapCharacter - The character expected as the wrapping character
461
+ * @param {string} pString - the string to clean
462
+ * @returns {string}
463
+ */
464
+ cleanEnclosureWrapCharacters(pWrapCharacter, pString) {
465
+ // # Use case from ManyFest DSL:
466
+ //
467
+ // When a boxed property is passed in, it should have quotes of some
468
+ // kind around it.
469
+ //
470
+ // For instance:
471
+ // MyValues['Name']
472
+ // MyValues["Age"]
473
+ // MyValues[`Cost`]
474
+ //
475
+ // This function is necessary to remove the wrapping quotes before object
476
+ // resolution can occur.
477
+ if (pString.startsWith(pWrapCharacter) && pString.endsWith(pWrapCharacter)) {
478
+ return pString.substring(1, pString.length - 1);
479
+ } else {
480
+ return pString;
481
+ }
482
+ }
483
+
484
+ /**
485
+ *
486
+ * @param {*} pString
487
+ * @returns
488
+ */
489
+ cleanNonAlphaCharacters(pString) {
490
+ if (typeof pString == 'string' && pString != '') {
491
+ return pString.replace(this._Regex_formatterCleanNonAlpha, this._Value_Clean_formatterCleanNonAlpha);
492
+ }
493
+ }
494
+
495
+ /*************************************************************************
496
+ * Number Formatting Functions
497
+ *-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/
498
+
499
+ /**
500
+ * Insert commas every 3 characters from the right. Used by formatterAddCommasToNumber().
501
+ *
502
+ * @param {*} pString
503
+ * @returns {*}
504
+ */
505
+ formatterInsertCommas(pString) {
506
+ // Reverse, because it's easier to do things from the left, given arbitrary digit counts
507
+ let tmpReversed = this.stringReverse(pString);
508
+ // Add commas every three characters
509
+ let tmpReversedWithCommas = tmpReversed.match(this._Regex_formatterInsertCommas).join(',');
510
+ // Reverse again (back to normal direction)
511
+ return this.stringReverse(tmpReversedWithCommas);
512
+ }
513
+ processAddCommasToNumberRegex(pMatch, pSign, pZeros, pBefore, pDecimal, pAfter) {
514
+ // If there was no decimal, the last capture grabs the final digit, so
515
+ // we have to put it back together with the 'before' substring
516
+ return pSign + (pDecimal ? this.formatterInsertCommas(pBefore) + pDecimal + pAfter : this.formatterInsertCommas(pBefore + pAfter));
517
+ }
518
+
519
+ /**
520
+ * Add Commas to a Number for readability.
521
+ *
522
+ * @param {*} pNumber
523
+ * @returns {string}
524
+ */
525
+ formatterAddCommasToNumber(pNumber) {
526
+ // If the regex doesn't match, `replace` returns the string unmodified
527
+ return pNumber.toString().replace(this._Regex_formatterAddCommasToNumber, this.processAddCommasToNumberRegex.bind(this));
528
+ }
529
+
530
+ /**
531
+ * This will take a number and format it as a dollar string. It will also add commas to the number. If the number is not a number, it will return '--'.
532
+ *
533
+ * @param {*} pValue
534
+ * @returns {string}
535
+ */
536
+ formatterDollars(pValue) {
537
+ let tmpDollarAmount = parseFloat(pValue).toFixed(2);
538
+ if (isNaN(tmpDollarAmount)) {
539
+ // Try again and see if what was passed in was a dollars string.
540
+ if (typeof pValue == 'string') {
541
+ // TODO: Better rounding function? This is a hack to get rid of the currency symbol and commas.
542
+ tmpDollarAmount = parseFloat(pValue.replace(this._Value_MoneySign_Currency, '').replace(this._Regex_formatterDollarsRemoveCommas, '')).toFixed(2);
543
+ }
544
+ // If we didn't get a number, return the "not a number" string.
545
+ if (isNaN(tmpDollarAmount)) {
546
+ return this._Value_NaN_Currency;
547
+ }
548
+ }
549
+
550
+ // TODO: Get locale data and use that for this stuff.
551
+ return "$".concat(this.formatterAddCommasToNumber(tmpDollarAmount));
552
+ }
553
+
554
+ /**
555
+ * Round a number to a certain number of digits. If the number is not a number, it will return 0. If no digits are specified, it will default to 2 significant digits.
556
+ *
557
+ * @param {*} pValue
558
+ * @param {number} pDigits
559
+ * @returns {string}
560
+ */
561
+ formatterRoundNumber(pValue, pDigits) {
562
+ let tmpDigits = typeof pDigits == 'undefined' ? 2 : pDigits;
563
+ let tmpValue = Number.parseFloat(pValue).toFixed(tmpDigits);
564
+ if (isNaN(tmpValue)) {
565
+ let tmpZed = 0;
566
+ return tmpZed.toFixed(tmpDigits);
567
+ } else {
568
+ return tmpValue;
569
+ }
570
+ }
571
+
572
+ /*************************************************************************
573
+ * String Tokenization Functions
574
+ *-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/
575
+
576
+ /**
577
+ * Return the string before the matched substring.
578
+ *
579
+ * If the substring is not found, the entire string is returned. This only deals with the *first* match.
580
+ *
581
+ * @param {string} pString
582
+ * @param {string} pMatch
583
+ * @returns {string}
584
+ */
585
+ stringBeforeMatch(pString, pMatch) {
586
+ return pString.split(pMatch)[0];
587
+ }
588
+
589
+ /**
590
+ * Return the string after the matched substring.
591
+ *
592
+ * If the substring is not found, an empty string is returned. This only deals with the *first* match.
593
+ *
594
+ * @param {string} pString
595
+ * @param {string} pMatch
596
+ * @returns {string}
597
+ */
598
+ stringAfterMatch(pString, pMatch) {
599
+ let tmpStringSplitLocation = pString.indexOf(pMatch);
600
+ if (tmpStringSplitLocation < 0 || tmpStringSplitLocation + pMatch.length >= pString.length) {
601
+ return '';
602
+ }
603
+ return pString.substring(tmpStringSplitLocation + pMatch.length);
604
+ }
605
+
606
+ /**
607
+ * Count the number of enclosures in a string based on the start and end characters.
608
+ *
609
+ * If no start or end characters are specified, it will default to parentheses. If the string is not a string, it will return 0.
610
+ *
611
+ * @param {string} pString
612
+ * @param {string} pEnclosureStart
613
+ * @param {string} pEnclosureEnd
614
+ * @returns the count of full in the string
615
+ */
616
+ stringCountEnclosures(pString, pEnclosureStart, pEnclosureEnd) {
617
+ let tmpString = typeof pString == 'string' ? pString : '';
618
+ let tmpEnclosureStart = typeof pEnclosureStart == 'string' ? pEnclosureStart : '(';
619
+ let tmpEnclosureEnd = typeof pEnclosureEnd == 'string' ? pEnclosureEnd : ')';
620
+ let tmpEnclosureCount = 0;
621
+ let tmpEnclosureDepth = 0;
622
+ for (let i = 0; i < tmpString.length; i++) {
623
+ // This is the start of an enclosure
624
+ if (tmpString[i] == tmpEnclosureStart) {
625
+ if (tmpEnclosureDepth == 0) {
626
+ tmpEnclosureCount++;
627
+ }
628
+ tmpEnclosureDepth++;
629
+ } else if (tmpString[i] == tmpEnclosureEnd) {
630
+ tmpEnclosureDepth--;
631
+ }
632
+ }
633
+ return tmpEnclosureCount;
634
+ }
635
+
636
+ /**
637
+ * Get the value of the enclosure at the specified index.
638
+ *
639
+ * If the index is not a number, it will default to 0. If the string is not a string, it will return an empty string. If the enclosure is not found, it will return an empty string. If the enclosure
640
+ *
641
+ * @param {string} pString
642
+ * @param {number} pEnclosureIndexToGet
643
+ * @param {string} pEnclosureStart
644
+ * @param {string}} pEnclosureEnd
645
+ * @returns {string}
646
+ */
647
+ stringGetEnclosureValueByIndex(pString, pEnclosureIndexToGet, pEnclosureStart, pEnclosureEnd) {
648
+ let tmpString = typeof pString == 'string' ? pString : '';
649
+ let tmpEnclosureIndexToGet = typeof pEnclosureIndexToGet == 'number' ? pEnclosureIndexToGet : 0;
650
+ let tmpEnclosureStart = typeof pEnclosureStart == 'string' ? pEnclosureStart : '(';
651
+ let tmpEnclosureEnd = typeof pEnclosureEnd == 'string' ? pEnclosureEnd : ')';
652
+ let tmpEnclosureCount = 0;
653
+ let tmpEnclosureDepth = 0;
654
+ let tmpMatchedEnclosureIndex = false;
655
+ let tmpEnclosedValueStartIndex = 0;
656
+ let tmpEnclosedValueEndIndex = 0;
657
+ for (let i = 0; i < tmpString.length; i++) {
658
+ // This is the start of an enclosure
659
+ if (tmpString[i] == tmpEnclosureStart) {
660
+ tmpEnclosureDepth++;
661
+
662
+ // Only count enclosures at depth 1, but still this parses both pairs of all of them.
663
+ if (tmpEnclosureDepth == 1) {
664
+ tmpEnclosureCount++;
665
+ if (tmpEnclosureIndexToGet == tmpEnclosureCount - 1) {
666
+ // This is the start of *the* enclosure
667
+ tmpMatchedEnclosureIndex = true;
668
+ tmpEnclosedValueStartIndex = i;
669
+ }
670
+ }
671
+ }
672
+ // This is the end of an enclosure
673
+ else if (tmpString[i] == tmpEnclosureEnd) {
674
+ tmpEnclosureDepth--;
675
+
676
+ // Again, only count enclosures at depth 1, but still this parses both pairs of all of them.
677
+ if (tmpEnclosureDepth == 0 && tmpMatchedEnclosureIndex && tmpEnclosedValueEndIndex <= tmpEnclosedValueStartIndex) {
678
+ tmpEnclosedValueEndIndex = i;
679
+ tmpMatchedEnclosureIndex = false;
680
+ }
681
+ }
682
+ }
683
+ if (tmpEnclosureCount <= tmpEnclosureIndexToGet) {
684
+ // Return an empty string if the enclosure is not found
685
+ return '';
686
+ }
687
+ if (tmpEnclosedValueEndIndex > 0 && tmpEnclosedValueEndIndex > tmpEnclosedValueStartIndex) {
688
+ return tmpString.substring(tmpEnclosedValueStartIndex + 1, tmpEnclosedValueEndIndex);
689
+ } else {
690
+ return tmpString.substring(tmpEnclosedValueStartIndex + 1);
691
+ }
692
+ }
693
+
694
+ /**
695
+ * Remove an enclosure from a string based on the index of the enclosure.
696
+ *
697
+ * @param {string} pString
698
+ * @param {number} pEnclosureIndexToRemove
699
+ * @param {number} pEnclosureStart
700
+ * @param {number} pEnclosureEnd
701
+ * @returns {string}
702
+ */
703
+ stringRemoveEnclosureByIndex(pString, pEnclosureIndexToRemove, pEnclosureStart, pEnclosureEnd) {
704
+ let tmpString = typeof pString == 'string' ? pString : '';
705
+ let tmpEnclosureIndexToRemove = typeof pEnclosureIndexToRemove == 'number' ? pEnclosureIndexToRemove : 0;
706
+ let tmpEnclosureStart = typeof pEnclosureStart == 'string' ? pEnclosureStart : '(';
707
+ let tmpEnclosureEnd = typeof pEnclosureEnd == 'string' ? pEnclosureEnd : ')';
708
+ let tmpEnclosureCount = 0;
709
+ let tmpEnclosureDepth = 0;
710
+ let tmpMatchedEnclosureIndex = false;
711
+ let tmpEnclosureStartIndex = 0;
712
+ let tmpEnclosureEndIndex = 0;
713
+ for (let i = 0; i < tmpString.length; i++) {
714
+ // This is the start of an enclosure
715
+ if (tmpString[i] == tmpEnclosureStart) {
716
+ tmpEnclosureDepth++;
717
+ if (tmpEnclosureDepth == 1) {
718
+ tmpEnclosureCount++;
719
+ if (tmpEnclosureIndexToRemove == tmpEnclosureCount - 1) {
720
+ tmpMatchedEnclosureIndex = true;
721
+ tmpEnclosureStartIndex = i;
722
+ }
723
+ }
724
+ } else if (tmpString[i] == tmpEnclosureEnd) {
725
+ tmpEnclosureDepth--;
726
+ if (tmpEnclosureDepth == 0 && tmpMatchedEnclosureIndex && tmpEnclosureEndIndex <= tmpEnclosureStartIndex) {
727
+ tmpEnclosureEndIndex = i;
728
+ tmpMatchedEnclosureIndex = false;
729
+ }
730
+ }
731
+ }
732
+ if (tmpEnclosureCount <= tmpEnclosureIndexToRemove) {
733
+ return tmpString;
734
+ }
735
+ let tmpReturnString = '';
736
+ if (tmpEnclosureStartIndex > 1) {
737
+ tmpReturnString = tmpString.substring(0, tmpEnclosureStartIndex);
738
+ }
739
+ if (tmpString.length > tmpEnclosureEndIndex + 1 && tmpEnclosureEndIndex > tmpEnclosureStartIndex) {
740
+ tmpReturnString += tmpString.substring(tmpEnclosureEndIndex + 1);
741
+ }
742
+ return tmpReturnString;
743
+ }
744
+ }
745
+ module.exports = DataArithmatic;
746
+ }, {}],
747
+ 18: [function (require, module, exports) {
330
748
  /**
331
749
  * Base Logger Class
332
750
  *
@@ -390,7 +808,7 @@
390
808
  }
391
809
  module.exports = BaseLogger;
392
810
  }, {}],
393
- 18: [function (require, module, exports) {
811
+ 19: [function (require, module, exports) {
394
812
  /**
395
813
  * Default Logger Provider Function
396
814
  *
@@ -408,16 +826,16 @@
408
826
  };
409
827
  module.exports = getDefaultProviders();
410
828
  }, {
411
- "./Fable-Log-Logger-Console.js": 20
829
+ "./Fable-Log-Logger-Console.js": 21
412
830
  }],
413
- 19: [function (require, module, exports) {
831
+ 20: [function (require, module, exports) {
414
832
  module.exports = [{
415
833
  "loggertype": "console",
416
834
  "streamtype": "console",
417
835
  "level": "trace"
418
836
  }];
419
837
  }, {}],
420
- 20: [function (require, module, exports) {
838
+ 21: [function (require, module, exports) {
421
839
  let libBaseLogger = require('./Fable-Log-BaseLogger.js');
422
840
  class ConsoleLogger extends libBaseLogger {
423
841
  constructor(pLogStreamSettings, pFableLog) {
@@ -463,9 +881,9 @@
463
881
  }
464
882
  module.exports = ConsoleLogger;
465
883
  }, {
466
- "./Fable-Log-BaseLogger.js": 17
884
+ "./Fable-Log-BaseLogger.js": 18
467
885
  }],
468
- 21: [function (require, module, exports) {
886
+ 22: [function (require, module, exports) {
469
887
  const libConsoleLog = require('./Fable-Log-Logger-Console.js');
470
888
  const libFS = require('fs');
471
889
  const libPath = require('path');
@@ -551,11 +969,11 @@
551
969
  }
552
970
  module.exports = SimpleFlatFileLogger;
553
971
  }, {
554
- "./Fable-Log-Logger-Console.js": 20,
972
+ "./Fable-Log-Logger-Console.js": 21,
555
973
  "fs": 16,
556
- "path": 28
974
+ "path": 29
557
975
  }],
558
- 22: [function (require, module, exports) {
976
+ 23: [function (require, module, exports) {
559
977
  /**
560
978
  * Fable Logging Add-on
561
979
  *
@@ -738,13 +1156,13 @@
738
1156
  module.exports.LogProviderConsole = require('./Fable-Log-Logger-Console.js');
739
1157
  module.exports.LogProviderConsole = require('./Fable-Log-Logger-SimpleFlatFile.js');
740
1158
  }, {
741
- "./Fable-Log-BaseLogger.js": 17,
742
- "./Fable-Log-DefaultProviders-Node.js": 18,
743
- "./Fable-Log-DefaultStreams.json": 19,
744
- "./Fable-Log-Logger-Console.js": 20,
745
- "./Fable-Log-Logger-SimpleFlatFile.js": 21
1159
+ "./Fable-Log-BaseLogger.js": 18,
1160
+ "./Fable-Log-DefaultProviders-Node.js": 19,
1161
+ "./Fable-Log-DefaultStreams.json": 20,
1162
+ "./Fable-Log-Logger-Console.js": 21,
1163
+ "./Fable-Log-Logger-SimpleFlatFile.js": 22
746
1164
  }],
747
- 23: [function (require, module, exports) {
1165
+ 24: [function (require, module, exports) {
748
1166
  module.exports = {
749
1167
  "Product": "ApplicationNameHere",
750
1168
  "ProductVersion": "0.0.0",
@@ -754,7 +1172,7 @@
754
1172
  }]
755
1173
  };
756
1174
  }, {}],
757
- 24: [function (require, module, exports) {
1175
+ 25: [function (require, module, exports) {
758
1176
  (function (process) {
759
1177
  (function () {
760
1178
  /**
@@ -796,9 +1214,9 @@
796
1214
  }).call(this);
797
1215
  }).call(this, require('_process'));
798
1216
  }, {
799
- "_process": 32
1217
+ "_process": 33
800
1218
  }],
801
- 25: [function (require, module, exports) {
1219
+ 26: [function (require, module, exports) {
802
1220
  /**
803
1221
  * Fable Settings Add-on
804
1222
  *
@@ -944,11 +1362,11 @@
944
1362
  module.exports.new = autoConstruct;
945
1363
  module.exports.precedent = libPrecedent;
946
1364
  }, {
947
- "./Fable-Settings-Default": 23,
948
- "./Fable-Settings-TemplateProcessor.js": 24,
949
- "precedent": 29
1365
+ "./Fable-Settings-Default": 24,
1366
+ "./Fable-Settings-TemplateProcessor.js": 25,
1367
+ "precedent": 30
950
1368
  }],
951
- 26: [function (require, module, exports) {
1369
+ 27: [function (require, module, exports) {
952
1370
  /**
953
1371
  * Random Byte Generator - Browser version
954
1372
  *
@@ -1001,7 +1419,7 @@
1001
1419
  }
1002
1420
  module.exports = RandomBytes;
1003
1421
  }, {}],
1004
- 27: [function (require, module, exports) {
1422
+ 28: [function (require, module, exports) {
1005
1423
  /**
1006
1424
  * Fable UUID Generator
1007
1425
  *
@@ -1082,9 +1500,9 @@
1082
1500
  module.exports = FableUUID;
1083
1501
  module.exports.new = autoConstruct;
1084
1502
  }, {
1085
- "./Fable-UUID-Random.js": 26
1503
+ "./Fable-UUID-Random.js": 27
1086
1504
  }],
1087
- 28: [function (require, module, exports) {
1505
+ 29: [function (require, module, exports) {
1088
1506
  (function (process) {
1089
1507
  (function () {
1090
1508
  // 'path' module extracted from Node.js v8.11.1 (only the posix part)
@@ -1553,9 +1971,9 @@
1553
1971
  }).call(this);
1554
1972
  }).call(this, require('_process'));
1555
1973
  }, {
1556
- "_process": 32
1974
+ "_process": 33
1557
1975
  }],
1558
- 29: [function (require, module, exports) {
1976
+ 30: [function (require, module, exports) {
1559
1977
  /**
1560
1978
  * Precedent Meta-Templating
1561
1979
  *
@@ -1601,10 +2019,10 @@
1601
2019
  }
1602
2020
  module.exports = Precedent;
1603
2021
  }, {
1604
- "./StringParser.js": 30,
1605
- "./WordTree.js": 31
2022
+ "./StringParser.js": 31,
2023
+ "./WordTree.js": 32
1606
2024
  }],
1607
- 30: [function (require, module, exports) {
2025
+ 31: [function (require, module, exports) {
1608
2026
  /**
1609
2027
  * String Parser
1610
2028
  *
@@ -1750,7 +2168,7 @@
1750
2168
  }
1751
2169
  module.exports = StringParser;
1752
2170
  }, {}],
1753
- 31: [function (require, module, exports) {
2171
+ 32: [function (require, module, exports) {
1754
2172
  /**
1755
2173
  * Word Tree
1756
2174
  *
@@ -1809,7 +2227,7 @@
1809
2227
  }
1810
2228
  module.exports = WordTree;
1811
2229
  }, {}],
1812
- 32: [function (require, module, exports) {
2230
+ 33: [function (require, module, exports) {
1813
2231
  // shim for using process in browser
1814
2232
  var process = module.exports = {};
1815
2233
 
@@ -1986,7 +2404,7 @@
1986
2404
  return 0;
1987
2405
  };
1988
2406
  }, {}],
1989
- 33: [function (require, module, exports) {
2407
+ 34: [function (require, module, exports) {
1990
2408
  (function (setImmediate, clearImmediate) {
1991
2409
  (function () {
1992
2410
  var nextTick = require('process/browser.js').nextTick;
@@ -2060,19 +2478,19 @@
2060
2478
  }).call(this);
2061
2479
  }).call(this, require("timers").setImmediate, require("timers").clearImmediate);
2062
2480
  }, {
2063
- "process/browser.js": 32,
2064
- "timers": 33
2481
+ "process/browser.js": 33,
2482
+ "timers": 34
2065
2483
  }],
2066
- 34: [function (require, module, exports) {
2484
+ 35: [function (require, module, exports) {
2067
2485
  var libNPMModuleWrapper = require('./Fable.js');
2068
2486
  if (typeof window === 'object' && !window.hasOwnProperty('Fable')) {
2069
2487
  window.Fable = libNPMModuleWrapper;
2070
2488
  }
2071
2489
  module.exports = libNPMModuleWrapper;
2072
2490
  }, {
2073
- "./Fable.js": 40
2491
+ "./Fable.js": 42
2074
2492
  }],
2075
- 35: [function (require, module, exports) {
2493
+ 36: [function (require, module, exports) {
2076
2494
  const _OperationStatePrototype = JSON.stringify({
2077
2495
  "Metadata": {
2078
2496
  "GUID": false,
@@ -2154,7 +2572,22 @@
2154
2572
  }
2155
2573
  module.exports = FableOperation;
2156
2574
  }, {}],
2157
- 36: [function (require, module, exports) {
2575
+ 37: [function (require, module, exports) {
2576
+ const libFableServiceBase = require('./Fable-ServiceProviderBase.js');
2577
+ const libDataArithmatic = require('data-arithmatic');
2578
+ class FableServiceDataArithmatic extends libFableServiceBase {
2579
+ constructor(pFable, pOptions, pServiceHash) {
2580
+ super(pFable, pOptions, pServiceHash);
2581
+ this.serviceType = 'DataArithmatic';
2582
+ this._DataArithmaticLibrary = new libDataArithmatic();
2583
+ }
2584
+ }
2585
+ module.exports = FableServiceDataArithmatic;
2586
+ }, {
2587
+ "./Fable-ServiceProviderBase.js": 41,
2588
+ "data-arithmatic": 17
2589
+ }],
2590
+ 38: [function (require, module, exports) {
2158
2591
  const libFableServiceBase = require('./Fable-ServiceProviderBase.js');
2159
2592
  class FableServiceTemplate extends libFableServiceBase {
2160
2593
  // Underscore and lodash have a behavior, _.template, which compiles a
@@ -2235,9 +2668,83 @@
2235
2668
  }
2236
2669
  module.exports = FableServiceTemplate;
2237
2670
  }, {
2238
- "./Fable-ServiceProviderBase.js": 38
2671
+ "./Fable-ServiceProviderBase.js": 41
2239
2672
  }],
2240
- 37: [function (require, module, exports) {
2673
+ 39: [function (require, module, exports) {
2674
+ const libFableServiceBase = require('./Fable-ServiceProviderBase.js');
2675
+
2676
+ // TODO: These are still pretty big -- consider the smaller polyfills
2677
+ const libAsyncWaterfall = require('async.waterfall');
2678
+ const libAsyncEachLimit = require('async.eachlimit');
2679
+ class FableServiceUtility extends libFableServiceBase {
2680
+ // Underscore and lodash have a behavior, _.template, which compiles a
2681
+ // string-based template with code snippets into simple executable pieces,
2682
+ // with the added twist of returning a precompiled function ready to go.
2683
+ //
2684
+ // NOTE: This does not implement underscore escape expressions
2685
+ // NOTE: This does not implement underscore magic browser variable assignment
2686
+ //
2687
+ // This is an implementation of that.
2688
+ // TODO: Make this use precedent, add configuration, add debugging.
2689
+ constructor(pFable, pOptions, pServiceHash) {
2690
+ super(pFable, pOptions, pServiceHash);
2691
+ this.templates = {};
2692
+
2693
+ // These two functions are used extensively throughout
2694
+ this.waterfall = libAsyncWaterfall;
2695
+ this.eachLimit = libAsyncEachLimit;
2696
+ }
2697
+
2698
+ // Underscore and lodash have a behavior, _.extend, which merges objects.
2699
+ // Now that es6 gives us this, use the native thingy.
2700
+ extend(pDestinationObject) {
2701
+ for (var _len = arguments.length, pSourceObjects = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
2702
+ pSourceObjects[_key - 1] = arguments[_key];
2703
+ }
2704
+ return Object.assign(pDestinationObject, ...pSourceObjects);
2705
+ }
2706
+
2707
+ // Underscore and lodash have a behavior, _.template, which compiles a
2708
+ // string-based template with code snippets into simple executable pieces,
2709
+ // with the added twist of returning a precompiled function ready to go.
2710
+ template(pTemplateText, pData) {
2711
+ let tmpTemplate = this.fable.serviceManager.instantiateServiceProviderWithoutRegistration('Template');
2712
+ return tmpTemplate.buildTemplateFunction(pTemplateText, pData);
2713
+ }
2714
+
2715
+ // Build a template function from a template hash, and, register it with the service provider
2716
+ buildHashedTemplate(pTemplateHash, pTemplateText, pData) {
2717
+ let tmpTemplate = this.fable.serviceManager.instantiateServiceProvider('Template', {}, pTemplateHash);
2718
+ this.templates[pTemplateHash] = tmpTemplate.buildTemplateFunction(pTemplateText, pData);
2719
+ return this.templates[pTemplateHash];
2720
+ }
2721
+
2722
+ // This is a safe, modern version of chunk from underscore
2723
+ // Algorithm pulled from a mix of these two polyfills:
2724
+ // https://github.com/you-dont-need/You-Dont-Need-Lodash-Underscore#_chunk
2725
+ // https://youmightnotneed.com/lodash
2726
+ // This implementation was most tolerant in browsers. Uglify can fix the rest.
2727
+ chunk(pInput, pChunkSize, pChunkCache) {
2728
+ let tmpInputArray = [...pInput];
2729
+ // Note lodash defaults to 1, underscore defaults to 0
2730
+ let tmpChunkSize = typeof pChunkSize == 'number' ? pChunkSize : 0;
2731
+ let tmpChunkCache = typeof pChunkCache != 'undefined' ? pChunkCache : [];
2732
+ if (tmpChunkSize <= 0) {
2733
+ return tmpChunkCache;
2734
+ }
2735
+ while (tmpInputArray.length) {
2736
+ tmpChunkCache.push(tmpInputArray.splice(0, tmpChunkSize));
2737
+ }
2738
+ return tmpChunkCache;
2739
+ }
2740
+ }
2741
+ module.exports = FableServiceUtility;
2742
+ }, {
2743
+ "./Fable-ServiceProviderBase.js": 41,
2744
+ "async.eachlimit": 1,
2745
+ "async.waterfall": 15
2746
+ }],
2747
+ 40: [function (require, module, exports) {
2241
2748
  /**
2242
2749
  * Fable Application Services Management
2243
2750
  * @license MIT
@@ -2304,9 +2811,9 @@
2304
2811
  module.exports = FableService;
2305
2812
  module.exports.ServiceProviderBase = libFableServiceBase;
2306
2813
  }, {
2307
- "./Fable-ServiceProviderBase.js": 38
2814
+ "./Fable-ServiceProviderBase.js": 41
2308
2815
  }],
2309
- 38: [function (require, module, exports) {
2816
+ 41: [function (require, module, exports) {
2310
2817
  /**
2311
2818
  * Fable Service Base
2312
2819
  * @license MIT
@@ -2324,69 +2831,7 @@
2324
2831
  }
2325
2832
  module.exports = FableServiceProviderBase;
2326
2833
  }, {}],
2327
- 39: [function (require, module, exports) {
2328
- // TODO: These are still pretty big -- consider the smaller polyfills
2329
- const libAsyncWaterfall = require('async.waterfall');
2330
- const libAsyncEachLimit = require('async.eachlimit');
2331
- class FableUtility {
2332
- constructor(pFable) {
2333
- this.fable = pFable;
2334
- this.templates = {};
2335
-
2336
- // These two functions are used extensively throughout
2337
- this.waterfall = libAsyncWaterfall;
2338
- this.eachLimit = libAsyncEachLimit;
2339
- }
2340
-
2341
- // Underscore and lodash have a behavior, _.extend, which merges objects.
2342
- // Now that es6 gives us this, use the native thingy.
2343
- extend(pDestinationObject) {
2344
- for (var _len = arguments.length, pSourceObjects = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
2345
- pSourceObjects[_key - 1] = arguments[_key];
2346
- }
2347
- return Object.assign(pDestinationObject, ...pSourceObjects);
2348
- }
2349
-
2350
- // Underscore and lodash have a behavior, _.template, which compiles a
2351
- // string-based template with code snippets into simple executable pieces,
2352
- // with the added twist of returning a precompiled function ready to go.
2353
- template(pTemplateText, pData) {
2354
- let tmpTemplate = this.fable.serviceManager.instantiateServiceProviderWithoutRegistration('Template');
2355
- return tmpTemplate.buildTemplateFunction(pTemplateText, pData);
2356
- }
2357
-
2358
- // Build a template function from a template hash, and, register it with the service provider
2359
- buildHashedTemplate(pTemplateHash, pTemplateText, pData) {
2360
- let tmpTemplate = this.fable.serviceManager.instantiateServiceProvider('Template', {}, pTemplateHash);
2361
- this.templates[pTemplateHash] = tmpTemplate.buildTemplateFunction(pTemplateText, pData);
2362
- return this.templates[pTemplateHash];
2363
- }
2364
-
2365
- // This is a safe, modern version of chunk from underscore
2366
- // Algorithm pulled from a mix of these two polyfills:
2367
- // https://github.com/you-dont-need/You-Dont-Need-Lodash-Underscore#_chunk
2368
- // https://youmightnotneed.com/lodash
2369
- // This implementation was most tolerant in browsers. Uglify can fix the rest.
2370
- chunk(pInput, pChunkSize, pChunkCache) {
2371
- let tmpInputArray = [...pInput];
2372
- // Note lodash defaults to 1, underscore defaults to 0
2373
- let tmpChunkSize = typeof pChunkSize == 'number' ? pChunkSize : 0;
2374
- let tmpChunkCache = typeof pChunkCache != 'undefined' ? pChunkCache : [];
2375
- if (tmpChunkSize <= 0) {
2376
- return tmpChunkCache;
2377
- }
2378
- while (tmpInputArray.length) {
2379
- tmpChunkCache.push(tmpInputArray.splice(0, tmpChunkSize));
2380
- }
2381
- return tmpChunkCache;
2382
- }
2383
- }
2384
- module.exports = FableUtility;
2385
- }, {
2386
- "async.eachlimit": 1,
2387
- "async.waterfall": 15
2388
- }],
2389
- 40: [function (require, module, exports) {
2834
+ 42: [function (require, module, exports) {
2390
2835
  /**
2391
2836
  * Fable Application Services Support Library
2392
2837
  * @license MIT
@@ -2395,9 +2840,10 @@
2395
2840
  const libFableSettings = require('fable-settings');
2396
2841
  const libFableUUID = require('fable-uuid');
2397
2842
  const libFableLog = require('fable-log');
2398
- const libFableUtility = require('./Fable-Utility.js');
2399
2843
  const libFableServiceManager = require('./Fable-ServiceManager.js');
2844
+ const libFableServiceDataArithmatic = require('./Fable-Service-DataArithmatic.js');
2400
2845
  const libFableServiceTemplate = require('./Fable-Service-Template.js');
2846
+ const libFableServiceUtility = require('./Fable-Service-Utility.js');
2401
2847
  const libFableOperation = require('./Fable-Operation.js');
2402
2848
  class Fable {
2403
2849
  constructor(pSettings) {
@@ -2409,9 +2855,6 @@
2409
2855
  this.log = new libFableLog(this.settingsManager.settings);
2410
2856
  this.log.initialize();
2411
2857
 
2412
- // Built-in utility belt functions
2413
- this.Utility = new libFableUtility(this);
2414
-
2415
2858
  // Built-in dependencies
2416
2859
  this.Dependencies = {
2417
2860
  precedent: libFableSettings.precedent
@@ -2420,7 +2863,20 @@
2420
2863
  // Location for Operation state
2421
2864
  this.Operations = {};
2422
2865
  this.serviceManager = new libFableServiceManager(this);
2866
+
2867
+ // Initialize and instantiate the default baked-in Data Arithmatic service
2868
+ this.serviceManager.addServiceType('DataArithmatic', libFableServiceDataArithmatic);
2869
+ this.fable.serviceManager.instantiateServiceProvider('DataArithmatic', {}, 'Default-Service-DataArithmatic');
2870
+ // This service is passing through the data arithmatic library
2871
+ this.DataArithmatic = this.serviceManager.defaultServices.DataArithmatic._DataArithmaticLibrary;
2872
+
2873
+ // Initialize the template service
2423
2874
  this.serviceManager.addServiceType('Template', libFableServiceTemplate);
2875
+
2876
+ // Initialize and instantiate the default baked-in Utility service
2877
+ this.serviceManager.addServiceType('Utility', libFableServiceUtility);
2878
+ this.fable.serviceManager.instantiateServiceProvider('Utility', {}, 'Default-Service-Utility');
2879
+ this.Utility = this.serviceManager.defaultServices.Utility;
2424
2880
  this.services = this.serviceManager.services;
2425
2881
  this.defaultServices = this.serviceManager.defaultServices;
2426
2882
  }
@@ -2462,13 +2918,14 @@
2462
2918
  module.exports.ServiceProviderBase = libFableServiceManager.ServiceProviderBase;
2463
2919
  module.exports.precedent = libFableSettings.precedent;
2464
2920
  }, {
2465
- "./Fable-Operation.js": 35,
2466
- "./Fable-Service-Template.js": 36,
2467
- "./Fable-ServiceManager.js": 37,
2468
- "./Fable-Utility.js": 39,
2469
- "fable-log": 22,
2470
- "fable-settings": 25,
2471
- "fable-uuid": 27
2921
+ "./Fable-Operation.js": 36,
2922
+ "./Fable-Service-DataArithmatic.js": 37,
2923
+ "./Fable-Service-Template.js": 38,
2924
+ "./Fable-Service-Utility.js": 39,
2925
+ "./Fable-ServiceManager.js": 40,
2926
+ "fable-log": 23,
2927
+ "fable-settings": 26,
2928
+ "fable-uuid": 28
2472
2929
  }]
2473
- }, {}, [34])(34);
2930
+ }, {}, [35])(35);
2474
2931
  });