@barchart/portfolio-api-common 1.0.34 → 1.0.39

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.
@@ -16,14 +16,16 @@ module.exports = (() => {
16
16
  * @param {String} code
17
17
  * @param {String} description
18
18
  * @param {Function} rangeCalculator
19
+ * @param {Function} startDateCalculator
19
20
  */
20
21
  class PositionSummaryFrame extends Enum {
21
- constructor(code, description, rangeCalculator) {
22
+ constructor(code, description, rangeCalculator, startDateCalculator) {
22
23
  super(code, description);
23
24
 
24
25
  assert.argumentIsRequired(rangeCalculator, 'rangeCalculator', Function);
25
26
 
26
27
  this._rangeCalculator = rangeCalculator;
28
+ this._startDateCalculator = startDateCalculator;
27
29
  }
28
30
 
29
31
  getRanges(transactions) {
@@ -32,6 +34,12 @@ module.exports = (() => {
32
34
  return this._rangeCalculator(getFilteredTransactions(transactions));
33
35
  }
34
36
 
37
+ getStartDate(periods) {
38
+ assert.argumentIsRequired(periods, 'periods', Number);
39
+
40
+ return this._startDateCalculator(periods);
41
+ }
42
+
35
43
  /**
36
44
  * A summary for a calendar year.
37
45
  *
@@ -77,10 +85,10 @@ module.exports = (() => {
77
85
  }
78
86
  }
79
87
 
80
- const yearly = new PositionSummaryFrame('YEARLY', 'year', getYearlyRanges);
81
- const quarterly = new PositionSummaryFrame('QUARTER', 'quarter', getQuarterlyRanges);
82
- const monthly = new PositionSummaryFrame('MONTH', 'month', getMonthlyRanges);
83
- const ytd = new PositionSummaryFrame('YTD', 'year-to-date', getYearToDateRanges);
88
+ const yearly = new PositionSummaryFrame('YEARLY', 'year', getYearlyRanges, getYearlyStartDate);
89
+ const quarterly = new PositionSummaryFrame('QUARTER', 'quarter', getQuarterlyRanges, getQuarterlyStartDate);
90
+ const monthly = new PositionSummaryFrame('MONTH', 'month', getMonthlyRanges, getMonthlyStartDate);
91
+ const ytd = new PositionSummaryFrame('YTD', 'year-to-date', getYearToDateRanges, getYearToDateStartDate);
84
92
 
85
93
  function getRange(start, end) {
86
94
  return {
@@ -143,6 +151,27 @@ module.exports = (() => {
143
151
  return ranges;
144
152
  }
145
153
 
154
+ function getYearlyStartDate(periods) {
155
+ const today = Day.getToday();
156
+
157
+ return Day.getToday()
158
+ .subtractMonths(today.month - 1)
159
+ .subtractDays(today.day)
160
+ .subtractYears(periods);
161
+ }
162
+
163
+ function getQuarterlyStartDate(periods) {
164
+ return null;
165
+ }
166
+
167
+ function getMonthlyStartDate(periods) {
168
+ return null;
169
+ }
170
+
171
+ function getYearToDateStartDate(periods) {
172
+ return null;
173
+ }
174
+
146
175
  function getFilteredTransactions(transactions) {
147
176
  return transactions.reduce((filtered, transaction) => {
148
177
  if (!transaction.snapshot.open.getIsZero() || transaction.type.closing) {
@@ -156,7 +185,7 @@ module.exports = (() => {
156
185
  return PositionSummaryFrame;
157
186
  })();
158
187
 
159
- },{"@barchart/common-js/lang/Day":5,"@barchart/common-js/lang/Enum":7,"@barchart/common-js/lang/array":8,"@barchart/common-js/lang/assert":9,"@barchart/common-js/lang/is":10}],2:[function(require,module,exports){
188
+ },{"@barchart/common-js/lang/Day":10,"@barchart/common-js/lang/Enum":13,"@barchart/common-js/lang/array":14,"@barchart/common-js/lang/assert":15,"@barchart/common-js/lang/is":16}],2:[function(require,module,exports){
160
189
  const assert = require('@barchart/common-js/lang/assert'),
161
190
  Enum = require('@barchart/common-js/lang/Enum');
162
191
 
@@ -483,7 +512,617 @@ module.exports = (() => {
483
512
  return TransactionType;
484
513
  })();
485
514
 
486
- },{"@barchart/common-js/lang/Enum":7,"@barchart/common-js/lang/assert":9}],3:[function(require,module,exports){
515
+ },{"@barchart/common-js/lang/Enum":13,"@barchart/common-js/lang/assert":15}],3:[function(require,module,exports){
516
+ const array = require('@barchart/common-js/lang/array'),
517
+ assert = require('@barchart/common-js/lang/assert'),
518
+ is = require('@barchart/common-js/lang/is'),
519
+ Tree = require('@barchart/common-js/collections/Tree');
520
+
521
+ const PositionGroup = require('./PositionGroup'),
522
+ PositionGroupDefinition = require('./PositionGroupDefinition'),
523
+ PositionItem = require('./PositionItem');
524
+
525
+ module.exports = (() => {
526
+ 'use strict';
527
+
528
+ /**
529
+ * @public
530
+ */
531
+ class PositionContainer {
532
+ constructor(portfolios, positions, summaries, definitions) {
533
+ this._portfolios = portfolios.reduce((map, portfolio) => {
534
+ map[portfolio.portfolio] = portfolio;
535
+
536
+ return map;
537
+ }, { });
538
+
539
+ this._summaries = summaries.reduce((map, summary) => {
540
+ const key = summary.position;
541
+
542
+ if (!map.hasOwnProperty(key)) {
543
+ map[key] = [ ];
544
+ }
545
+
546
+ map[key].push(summary);
547
+
548
+ return map;
549
+ }, { });
550
+
551
+ this._items = positions.reduce((items, position) => {
552
+ const portfolio = this._portfolios[position.portfolio];
553
+
554
+ if (position) {
555
+ const summaries = this._summaries[position.position] || [ ];
556
+
557
+ items.push(new PositionItem(portfolio, position, summaries));
558
+ }
559
+
560
+ return items;
561
+ }, [ ]);
562
+
563
+ this._symbols = this._items.reduce((map, item) => {
564
+ let position = item.position;
565
+ let symbol = null;
566
+
567
+ if (position.instrument && position.instrument.symbol && position.instrument.barchart) {
568
+ symbol = position.instrument.barchart;
569
+
570
+ if (!map.hasOwnProperty(symbol)) {
571
+ map[symbol] = [ ];
572
+ }
573
+
574
+ map[symbol].push(item);
575
+ }
576
+
577
+ return map;
578
+ }, { });
579
+
580
+ this._definitions = definitions || [ new PositionGroupDefinition('Totals', i => true, i => 'Totals', [ 'Totals' ]) ];
581
+
582
+ this._tree = new Tree();
583
+
584
+ const createGroups = (tree, items, definitions) => {
585
+ if (definitions.length === 0) {
586
+ return;
587
+ }
588
+
589
+ const currentDefinition = definitions[0];
590
+ const additionalDefinitions = array.dropLeft(definitions);
591
+
592
+ const populatedGroups = array.batchBy(items, currentDefinition.keySelector).map((items) => {
593
+ const first = items[0];
594
+
595
+ return new PositionGroup(items, currentDefinition.descriptionSelector(first), currentDefinition.single && items.length === 1);
596
+ });
597
+
598
+ const missingGroups = array.difference(currentDefinition.requiredGroups, populatedGroups.map(group => group.description));
599
+
600
+ const empty = missingGroups.map((description) => {
601
+ return new PositionGroup(description, [ ]);
602
+ });
603
+
604
+ const compositeGroups = populatedGroups.concat(empty);
605
+
606
+ compositeGroups.forEach((group) => {
607
+ const child = tree.addChild(group);
608
+
609
+ createGroups(child, group.items, additionalDefinitions);
610
+ });
611
+ };
612
+
613
+ createGroups(this._tree, this._items, this._definitions);
614
+ }
615
+
616
+ setPrice(symbol, price) {
617
+ if (this._symbols.hasOwnProperty(symbol)) {
618
+ this._symbols.forEach(item.setPrice(price));
619
+ }
620
+ }
621
+
622
+ getGroup(keys) {
623
+ const node = keys.reduce((tree, key) => {
624
+ tree = tree.findChild((group) => group.description === key);
625
+
626
+ return tree;
627
+ }, this._tree);
628
+
629
+ return node.getValue();
630
+ }
631
+
632
+ getGroups(keys) {
633
+ const node = keys.reduce((tree, key) => {
634
+ tree = tree.findChild((group) => group.description === key);
635
+
636
+ return tree;
637
+ }, this._tree);
638
+
639
+ return node.getChildren().map((node) => node.getValue());
640
+ }
641
+
642
+ toString() {
643
+ return '[PositionContainer]';
644
+ }
645
+ }
646
+
647
+ return PositionContainer;
648
+ })();
649
+
650
+ },{"./PositionGroup":4,"./PositionGroupDefinition":5,"./PositionItem":6,"@barchart/common-js/collections/Tree":7,"@barchart/common-js/lang/array":14,"@barchart/common-js/lang/assert":15,"@barchart/common-js/lang/is":16}],4:[function(require,module,exports){
651
+ const assert = require('@barchart/common-js/lang/assert'),
652
+ is = require('@barchart/common-js/lang/is');
653
+
654
+ module.exports = (() => {
655
+ 'use strict';
656
+
657
+ /**
658
+ * @public
659
+ */
660
+ class PositionGroup {
661
+ constructor(items, description, single) {
662
+ this._description = description;
663
+ this._items = items;
664
+
665
+ this._single = is.boolean(single) && single;
666
+
667
+ this._data = { };
668
+
669
+ this._data.description = this._description;
670
+
671
+ this._data.previous = null;
672
+ this._data.current = null;
673
+
674
+ this._items.forEach((item) => {
675
+ item.registerPriceChangeHandler((price, sender) => {
676
+ if (this._single) {
677
+ data.current = price;
678
+ } else {
679
+ data.current = null;
680
+ }
681
+ });
682
+ });
683
+
684
+ calculateStaticData(this);
685
+ }
686
+
687
+ get description() {
688
+ return this._description;
689
+ }
690
+
691
+ get data() {
692
+ return this._data;
693
+ }
694
+
695
+ get items() {
696
+ return this._items;
697
+ }
698
+
699
+ toString() {
700
+ return '[PositionGroup]';
701
+ }
702
+ }
703
+
704
+ function calculateStaticData(group) {
705
+ const items = group._items;
706
+ const data = group._data;
707
+
708
+ const updates = items.reduce(function(updates, item) {
709
+
710
+ }, { });
711
+
712
+
713
+ }
714
+
715
+ return PositionGroup;
716
+ })();
717
+
718
+ },{"@barchart/common-js/lang/assert":15,"@barchart/common-js/lang/is":16}],5:[function(require,module,exports){
719
+ const assert = require('@barchart/common-js/lang/assert'),
720
+ is = require('@barchart/common-js/lang/is');
721
+
722
+ module.exports = (() => {
723
+ 'use strict';
724
+
725
+ /**
726
+ * @public
727
+ */
728
+ class PositionGroupDefinition {
729
+ constructor(name, keySelector, descriptionSelector, requiredGroups, single) {
730
+ this._name = name;
731
+
732
+ this._keySelector = keySelector;
733
+ this._descriptionSelector = descriptionSelector;
734
+
735
+ this._requiredGroups = requiredGroups || [ ];
736
+ this._single = is.boolean(single) && single;
737
+ }
738
+
739
+ get name() {
740
+ return this._name;
741
+ }
742
+
743
+ get keySelector() {
744
+ return this._keySelector;
745
+ }
746
+
747
+ get descriptionSelector() {
748
+ return this._descriptionSelector;
749
+ }
750
+
751
+ get requiredGroups() {
752
+ return this._requiredGroups;
753
+ }
754
+
755
+ toString() {
756
+ return '[PositionGroupDefinition]';
757
+ }
758
+ }
759
+
760
+ return PositionGroupDefinition;
761
+ })();
762
+
763
+ },{"@barchart/common-js/lang/assert":15,"@barchart/common-js/lang/is":16}],6:[function(require,module,exports){
764
+ const assert = require('@barchart/common-js/lang/assert'),
765
+ Event = require('@barchart/common-js/messaging/Event'),
766
+ is = require('@barchart/common-js/lang/is');
767
+
768
+ module.exports = (() => {
769
+ 'use strict';
770
+
771
+ /**
772
+ * @public
773
+ */
774
+ class PositionItem {
775
+ constructor(portfolio, position, summaries) {
776
+ this._portfolio = portfolio;
777
+ this._position = position;
778
+ this._summaries = summaries || [ ];
779
+
780
+ this._price = null;
781
+ this._priceChangeEvent = new Event(this);
782
+ }
783
+
784
+ get portfolio() {
785
+ return this._portfolio;
786
+ }
787
+
788
+ get position() {
789
+ return this._position;
790
+ }
791
+
792
+ get summaries() {
793
+ return this._summaries;
794
+ }
795
+
796
+ setPrice(price) {
797
+ if (this._price !== price) {
798
+ this._priceChangeEvent.fire(this._price = price);
799
+ }
800
+ }
801
+
802
+ registerPriceChangeHandler(handler) {
803
+ assert.argumentIsRequired(handler, 'handler', Function);
804
+
805
+ this._priceChangeEvent.register(handler);
806
+ }
807
+
808
+ toString() {
809
+ return '[PositionItem]';
810
+ }
811
+ }
812
+
813
+ return PositionItem;
814
+ })();
815
+
816
+ },{"@barchart/common-js/lang/assert":15,"@barchart/common-js/lang/is":16,"@barchart/common-js/messaging/Event":17}],7:[function(require,module,exports){
817
+ 'use strict';
818
+
819
+ var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
820
+
821
+ function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
822
+
823
+ var is = require('./../lang/is');
824
+
825
+ module.exports = function () {
826
+ 'use strict';
827
+
828
+ /**
829
+ * A tree data structure. Each instance represents a node, holding
830
+ * an item, a reference to the parent node, and a reference to
831
+ * children nodes. Children are stored in insertion order.
832
+ *
833
+ * @public
834
+ * @param {*} value - The value of the node.
835
+ * @param {Tree} parent - The parent node. If not supplied, this will be the root node.
836
+ */
837
+
838
+ var Tree = function () {
839
+ function Tree(value, parent) {
840
+ _classCallCheck(this, Tree);
841
+
842
+ this._value = value;
843
+
844
+ this._parent = parent || null;
845
+ this._children = [];
846
+ }
847
+
848
+ /**
849
+ * Returns the parent node. If this is the root node, a null value is returned.
850
+ *
851
+ * @public
852
+ * @returns {Tree|null}
853
+ */
854
+
855
+
856
+ _createClass(Tree, [{
857
+ key: 'getParent',
858
+ value: function getParent() {
859
+ return this._parent;
860
+ }
861
+
862
+ /**
863
+ * Returns the collection of children nodes.
864
+ *
865
+ * @public
866
+ * @returns {Array<Tree>}
867
+ */
868
+
869
+ }, {
870
+ key: 'getChildren',
871
+ value: function getChildren() {
872
+ return this._children;
873
+ }
874
+
875
+ /**
876
+ * Returns the value associated with the current node.
877
+ *
878
+ * @public
879
+ * @returns {*}
880
+ */
881
+
882
+ }, {
883
+ key: 'getValue',
884
+ value: function getValue() {
885
+ return this._value;
886
+ }
887
+
888
+ /**
889
+ * Returns true if this node has no children; otherwise false.
890
+ *
891
+ * @public
892
+ * @returns {boolean}
893
+ */
894
+
895
+ }, {
896
+ key: 'getIsLeaf',
897
+ value: function getIsLeaf() {
898
+ return this._children.length === 0;
899
+ }
900
+
901
+ /**
902
+ * Returns true if this node has no parent; otherwise false.
903
+ *
904
+ * @public
905
+ * @returns {boolean}
906
+ */
907
+
908
+ }, {
909
+ key: 'getIsRoot',
910
+ value: function getIsRoot() {
911
+ return this._parent === null;
912
+ }
913
+
914
+ /**
915
+ * Adds a child node to the current node and returns a reference
916
+ * to the child node.
917
+ *
918
+ * @public
919
+ * @param {*} value - The value of the child.
920
+ * @returns {Tree}
921
+ */
922
+
923
+ }, {
924
+ key: 'addChild',
925
+ value: function addChild(value) {
926
+ var returnRef = new Tree(value, this);
927
+
928
+ this._children.push(returnRef);
929
+
930
+ return returnRef;
931
+ }
932
+
933
+ /**
934
+ * Removes a child node.
935
+ *
936
+ * @public
937
+ * @param {Tree} node - The child to remove.
938
+ */
939
+
940
+ }, {
941
+ key: 'removeChild',
942
+ value: function removeChild(node) {
943
+ for (var i = this._children.length - 1; !(i < 0); i--) {
944
+ var child = this._children[i];
945
+
946
+ if (child === node) {
947
+ this._children.splice(i, 1);
948
+
949
+ child._parent = null;
950
+ child._children = [];
951
+
952
+ break;
953
+ }
954
+ }
955
+ }
956
+
957
+ /**
958
+ * Searches the children nodes for the first child node that matches the
959
+ * predicate.
960
+ *
961
+ * @public
962
+ * @param {Tree~nodePredicate} predicate - A predicate that tests each child node. The predicate takes two arguments -- the node's value, and the node itself.
963
+ * @returns {Tree|null}
964
+ */
965
+
966
+ }, {
967
+ key: 'findChild',
968
+ value: function findChild(predicate) {
969
+ var returnRef = null;
970
+
971
+ for (var i = 0; i < this._children.length; i++) {
972
+ var child = this._children[i];
973
+
974
+ if (predicate(child.getValue(), child)) {
975
+ returnRef = child;
976
+
977
+ break;
978
+ }
979
+ }
980
+
981
+ return returnRef;
982
+ }
983
+
984
+ /**
985
+ * Searches the tree recursively, starting with the current node.
986
+ *
987
+ * @public
988
+ * @param {Tree~nodePredicate} predicate - A predicate that tests each child node. The predicate takes two arguments -- the node's value, and the node itself.
989
+ * @param {boolean=} childrenFirst - True, if the tree should be searched depth first.
990
+ * @param {boolean=} includeCurrentNode - True, if the current node should be checked against the predicate.
991
+ * @returns {Tree|null}
992
+ */
993
+
994
+ }, {
995
+ key: 'search',
996
+ value: function search(predicate, childrenFirst, includeCurrentNode) {
997
+ var returnRef = null;
998
+
999
+ if (returnRef === null && childrenFirst && includeCurrentNode && predicate(this.getValue(), this)) {
1000
+ returnRef = this;
1001
+ }
1002
+
1003
+ for (var i = 0; i < this._children.length; i++) {
1004
+ var child = this._children[i];
1005
+
1006
+ returnRef = child.search(predicate, childrenFirst, true);
1007
+
1008
+ if (returnRef !== null) {
1009
+ break;
1010
+ }
1011
+ }
1012
+
1013
+ if (returnRef === null && !childrenFirst && includeCurrentNode && predicate(this.getValue(), this)) {
1014
+ returnRef = this;
1015
+ }
1016
+
1017
+ return returnRef;
1018
+ }
1019
+
1020
+ /**
1021
+ * Walks the children of the current node, running an action on each node.
1022
+ *
1023
+ * @public
1024
+ * @param {Tree~nodeAction} walkAction - A action to apply to each node. The action takes two arguments -- the node's value, and the node itself.
1025
+ * @param {boolean=} childrenFirst - True if the tree should be walked depth first.
1026
+ * @param {boolean=} includeCurrentNode - True if the current node should be applied to the action.
1027
+ */
1028
+
1029
+ }, {
1030
+ key: 'walk',
1031
+ value: function walk(walkAction, childrenFirst, includeCurrentNode) {
1032
+ var predicate = function predicate(value, node) {
1033
+ walkAction(value, node);
1034
+
1035
+ return false;
1036
+ };
1037
+
1038
+ this.search(predicate, childrenFirst, includeCurrentNode);
1039
+ }
1040
+
1041
+ /**
1042
+ * Climbs the parents of the current node -- current node up to the root node, running an action on each node.
1043
+ *
1044
+ * @public
1045
+ * @param {Tree~nodeAction} climbAction - A action to apply to each node. The action takes two arguments -- the node's value, and the node itself.
1046
+ * @param {boolean=} includeCurrentNode - True if the current node should be applied to the action.
1047
+ */
1048
+
1049
+ }, {
1050
+ key: 'climb',
1051
+ value: function climb(climbAction, includeCurrentNode) {
1052
+ if (includeCurrentNode) {
1053
+ climbAction(this.getValue(), this);
1054
+ }
1055
+
1056
+ if (this._parent !== null) {
1057
+ this._parent.climb(climbAction, true);
1058
+ }
1059
+ }
1060
+
1061
+ /**
1062
+ * Creates a representation of the tree using JavaScript objects and arrays.
1063
+ *
1064
+ * @public
1065
+ * @param {Function=} valueConverter - An optional function for converting the value of each node.
1066
+ * @param {Boolean=} valueConverter - If true, empty children arrays will be excluded from output.
1067
+ * @returns {Object}
1068
+ */
1069
+
1070
+ }, {
1071
+ key: 'toJSObj',
1072
+ value: function toJSObj(valueConverter, omitEmptyChildren) {
1073
+ var valueConverterToUse = void 0;
1074
+
1075
+ if (is.fn(valueConverter)) {
1076
+ valueConverterToUse = valueConverter;
1077
+ } else {
1078
+ valueConverterToUse = function valueConverterToUse(x) {
1079
+ return x;
1080
+ };
1081
+ }
1082
+
1083
+ var converted = {
1084
+ value: valueConverterToUse(this._value)
1085
+ };
1086
+
1087
+ if (!(is.boolean(omitEmptyChildren) && omitEmptyChildren && this._children.length === 0)) {
1088
+ converted.children = this._children.map(function (child) {
1089
+ return child.toJSObj(valueConverter, omitEmptyChildren);
1090
+ });
1091
+ }
1092
+
1093
+ return converted;
1094
+ }
1095
+ }, {
1096
+ key: 'toString',
1097
+ value: function toString() {
1098
+ return '[Tree]';
1099
+ }
1100
+ }]);
1101
+
1102
+ return Tree;
1103
+ }();
1104
+
1105
+ /**
1106
+ * A predicate that is used to check a node (i.e. {@link Tree}).
1107
+ *
1108
+ * @callback Tree~nodePredicate
1109
+ * @param {*} item - The candidate node's item
1110
+ * @param {Tree} node - The candidate node.
1111
+ * @returns {Boolean}
1112
+ */
1113
+
1114
+ /**
1115
+ * An action that is run on a node (i.e. {@link Tree}).
1116
+ *
1117
+ * @callback Tree~nodeAction
1118
+ * @param {*} item - The candidate node's item
1119
+ * @param {Tree} node - The candidate node.
1120
+ */
1121
+
1122
+ return Tree;
1123
+ }();
1124
+
1125
+ },{"./../lang/is":16}],8:[function(require,module,exports){
487
1126
  'use strict';
488
1127
 
489
1128
  var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
@@ -627,7 +1266,7 @@ module.exports = function () {
627
1266
  return ComparatorBuilder;
628
1267
  }();
629
1268
 
630
- },{"./../../lang/assert":9,"./comparators":4}],4:[function(require,module,exports){
1269
+ },{"./../../lang/assert":15,"./comparators":9}],9:[function(require,module,exports){
631
1270
  'use strict';
632
1271
 
633
1272
  var assert = require('./../../lang/assert');
@@ -702,7 +1341,7 @@ module.exports = function () {
702
1341
  };
703
1342
  }();
704
1343
 
705
- },{"./../../lang/assert":9}],5:[function(require,module,exports){
1344
+ },{"./../../lang/assert":15}],10:[function(require,module,exports){
706
1345
  'use strict';
707
1346
 
708
1347
  var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
@@ -1255,7 +1894,7 @@ module.exports = function () {
1255
1894
  return Day;
1256
1895
  }();
1257
1896
 
1258
- },{"./../collections/sorting/ComparatorBuilder":3,"./../collections/sorting/comparators":4,"./assert":9,"./is":10}],6:[function(require,module,exports){
1897
+ },{"./../collections/sorting/ComparatorBuilder":8,"./../collections/sorting/comparators":9,"./assert":15,"./is":16}],11:[function(require,module,exports){
1259
1898
  'use strict';
1260
1899
 
1261
1900
  var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
@@ -1760,82 +2399,231 @@ module.exports = function () {
1760
2399
  function RoundingMode(value, description) {
1761
2400
  _classCallCheck(this, RoundingMode);
1762
2401
 
1763
- var _this = _possibleConstructorReturn(this, (RoundingMode.__proto__ || Object.getPrototypeOf(RoundingMode)).call(this, value.toString(), description));
2402
+ var _this = _possibleConstructorReturn(this, (RoundingMode.__proto__ || Object.getPrototypeOf(RoundingMode)).call(this, value.toString(), description));
2403
+
2404
+ _this._value = value;
2405
+ return _this;
2406
+ }
2407
+
2408
+ /**
2409
+ * The code used by the Big.js library.
2410
+ *
2411
+ * @ignore
2412
+ * @returns {Number}
2413
+ */
2414
+
2415
+
2416
+ _createClass(RoundingMode, [{
2417
+ key: 'toString',
2418
+ value: function toString() {
2419
+ return '[RoundingMode]';
2420
+ }
2421
+ }, {
2422
+ key: 'value',
2423
+ get: function get() {
2424
+ return this._value;
2425
+ }
2426
+
2427
+ /**
2428
+ * Rounds away from zero.
2429
+ *
2430
+ * @public
2431
+ * @returns {RoundingMode}
2432
+ */
2433
+
2434
+ }], [{
2435
+ key: 'UP',
2436
+ get: function get() {
2437
+ return up;
2438
+ }
2439
+
2440
+ /**
2441
+ * Rounds towards zero.
2442
+ *
2443
+ * @public
2444
+ * @returns {RoundingMode}
2445
+ */
2446
+
2447
+ }, {
2448
+ key: 'DOWN',
2449
+ get: function get() {
2450
+ return down;
2451
+ }
2452
+
2453
+ /**
2454
+ * Rounds towards nearest neighbor. If equidistant, rounds away from zero.
2455
+ *
2456
+ * @public
2457
+ * @returns {RoundingMode}
2458
+ */
2459
+
2460
+ }, {
2461
+ key: 'NORMAL',
2462
+ get: function get() {
2463
+ return normal;
2464
+ }
2465
+ }]);
2466
+
2467
+ return RoundingMode;
2468
+ }(Enum);
2469
+
2470
+ var up = new RoundingMode(3, 'up');
2471
+ var down = new RoundingMode(0, 'down');
2472
+ var normal = new RoundingMode(1, 'normal');
2473
+
2474
+ return Decimal;
2475
+ }();
2476
+
2477
+ },{"./Enum":13,"./assert":15,"./is":16,"big.js":18}],12:[function(require,module,exports){
2478
+ 'use strict';
2479
+
2480
+ var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
2481
+
2482
+ function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
2483
+
2484
+ function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
2485
+
2486
+ function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
2487
+
2488
+ var assert = require('./assert');
2489
+
2490
+ module.exports = function () {
2491
+ 'use strict';
2492
+
2493
+ /**
2494
+ * An object that has an end-of-life process.
2495
+ *
2496
+ * @public
2497
+ * @interface
2498
+ */
2499
+
2500
+ var Disposable = function () {
2501
+ function Disposable() {
2502
+ _classCallCheck(this, Disposable);
1764
2503
 
1765
- _this._value = value;
1766
- return _this;
2504
+ this._disposed = false;
1767
2505
  }
1768
2506
 
1769
2507
  /**
1770
- * The code used by the Big.js library.
2508
+ * Invokes end-of-life logic. Once this function has been
2509
+ * invoked, further interaction with the object is not
2510
+ * recommended.
1771
2511
  *
1772
- * @ignore
1773
- * @returns {Number}
2512
+ * @public
1774
2513
  */
1775
2514
 
1776
2515
 
1777
- _createClass(RoundingMode, [{
1778
- key: 'toString',
1779
- value: function toString() {
1780
- return '[RoundingMode]';
2516
+ _createClass(Disposable, [{
2517
+ key: 'dispose',
2518
+ value: function dispose() {
2519
+ if (this._disposed) {
2520
+ return;
2521
+ }
2522
+
2523
+ this._disposed = true;
2524
+
2525
+ this._onDispose();
1781
2526
  }
2527
+
2528
+ /**
2529
+ * @protected
2530
+ * @abstract
2531
+ * @ignore
2532
+ */
2533
+
1782
2534
  }, {
1783
- key: 'value',
1784
- get: function get() {
1785
- return this._value;
2535
+ key: '_onDispose',
2536
+ value: function _onDispose() {
2537
+ return;
1786
2538
  }
1787
2539
 
1788
2540
  /**
1789
- * Rounds away from zero.
2541
+ * Returns true if the {@link Disposable#dispose} function has been invoked.
1790
2542
  *
1791
2543
  * @public
1792
- * @returns {RoundingMode}
2544
+ * @returns {boolean}
1793
2545
  */
1794
2546
 
1795
- }], [{
1796
- key: 'UP',
1797
- get: function get() {
1798
- return up;
2547
+ }, {
2548
+ key: 'getIsDisposed',
2549
+ value: function getIsDisposed() {
2550
+ return this._disposed || false;
2551
+ }
2552
+ }, {
2553
+ key: 'toString',
2554
+ value: function toString() {
2555
+ return '[Disposable]';
1799
2556
  }
1800
2557
 
1801
2558
  /**
1802
- * Rounds towards zero.
2559
+ * Creates and returns a {@link Disposable} object with end-of-life logic
2560
+ * delegated to a function.
1803
2561
  *
1804
2562
  * @public
1805
- * @returns {RoundingMode}
2563
+ * @param disposeAction {Function}
2564
+ * @returns {Disposable}
1806
2565
  */
1807
2566
 
1808
- }, {
1809
- key: 'DOWN',
1810
- get: function get() {
1811
- return down;
2567
+ }], [{
2568
+ key: 'fromAction',
2569
+ value: function fromAction(disposeAction) {
2570
+ assert.argumentIsRequired(disposeAction, 'disposeAction', Function);
2571
+
2572
+ return new DisposableAction(disposeAction);
1812
2573
  }
1813
2574
 
1814
2575
  /**
1815
- * Rounds towards nearest neighbor. If equidistant, rounds away from zero.
2576
+ * Creates and returns a {@link Disposable} object whose end-of-life
2577
+ * logic does nothing.
1816
2578
  *
1817
2579
  * @public
1818
- * @returns {RoundingMode}
2580
+ * @returns {Disposable}
1819
2581
  */
1820
2582
 
1821
2583
  }, {
1822
- key: 'NORMAL',
1823
- get: function get() {
1824
- return normal;
2584
+ key: 'getEmpty',
2585
+ value: function getEmpty() {
2586
+ return Disposable.fromAction(function () {
2587
+ return;
2588
+ });
1825
2589
  }
1826
2590
  }]);
1827
2591
 
1828
- return RoundingMode;
1829
- }(Enum);
2592
+ return Disposable;
2593
+ }();
1830
2594
 
1831
- var up = new RoundingMode(3, 'up');
1832
- var down = new RoundingMode(0, 'down');
1833
- var normal = new RoundingMode(1, 'normal');
2595
+ var DisposableAction = function (_Disposable) {
2596
+ _inherits(DisposableAction, _Disposable);
1834
2597
 
1835
- return Decimal;
2598
+ function DisposableAction(disposeAction) {
2599
+ _classCallCheck(this, DisposableAction);
2600
+
2601
+ var _this = _possibleConstructorReturn(this, (DisposableAction.__proto__ || Object.getPrototypeOf(DisposableAction)).call(this, disposeAction));
2602
+
2603
+ _this._disposeAction = disposeAction;
2604
+ return _this;
2605
+ }
2606
+
2607
+ _createClass(DisposableAction, [{
2608
+ key: '_onDispose',
2609
+ value: function _onDispose() {
2610
+ this._disposeAction();
2611
+ this._disposeAction = null;
2612
+ }
2613
+ }, {
2614
+ key: 'toString',
2615
+ value: function toString() {
2616
+ return '[DisposableAction]';
2617
+ }
2618
+ }]);
2619
+
2620
+ return DisposableAction;
2621
+ }(Disposable);
2622
+
2623
+ return Disposable;
1836
2624
  }();
1837
2625
 
1838
- },{"./Enum":7,"./assert":9,"./is":10,"big.js":11}],7:[function(require,module,exports){
2626
+ },{"./assert":15}],13:[function(require,module,exports){
1839
2627
  'use strict';
1840
2628
 
1841
2629
  var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
@@ -1977,7 +2765,7 @@ module.exports = function () {
1977
2765
  return Enum;
1978
2766
  }();
1979
2767
 
1980
- },{"./assert":9}],8:[function(require,module,exports){
2768
+ },{"./assert":15}],14:[function(require,module,exports){
1981
2769
  'use strict';
1982
2770
 
1983
2771
  var assert = require('./assert'),
@@ -2122,6 +2910,26 @@ module.exports = function () {
2122
2910
  },
2123
2911
 
2124
2912
 
2913
+ /**
2914
+ * Returns a new array containing all but the first item.
2915
+ *
2916
+ * @static
2917
+ * @param {Array} a
2918
+ * @returns {Array}
2919
+ */
2920
+ dropLeft: function dropLeft(a) {
2921
+ assert.argumentIsArray(a, 'a');
2922
+
2923
+ var returnRef = Array.from(a);
2924
+
2925
+ if (returnRef.length !== 0) {
2926
+ returnRef.shift();
2927
+ }
2928
+
2929
+ return returnRef;
2930
+ },
2931
+
2932
+
2125
2933
  /**
2126
2934
  * Returns a new array containing all but the last item.
2127
2935
  *
@@ -2338,7 +3146,7 @@ module.exports = function () {
2338
3146
  };
2339
3147
  }();
2340
3148
 
2341
- },{"./assert":9,"./is":10}],9:[function(require,module,exports){
3149
+ },{"./assert":15,"./is":16}],15:[function(require,module,exports){
2342
3150
  'use strict';
2343
3151
 
2344
3152
  var is = require('./is');
@@ -2486,7 +3294,7 @@ module.exports = function () {
2486
3294
  };
2487
3295
  }();
2488
3296
 
2489
- },{"./is":10}],10:[function(require,module,exports){
3297
+ },{"./is":16}],16:[function(require,module,exports){
2490
3298
  'use strict';
2491
3299
 
2492
3300
  var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; };
@@ -2507,7 +3315,7 @@ module.exports = function () {
2507
3315
  *
2508
3316
  * @static
2509
3317
  * @public
2510
- * @param candidate {*}
3318
+ * @param {*} candidate {*}
2511
3319
  * @returns {boolean}
2512
3320
  */
2513
3321
  number: function number(candidate) {
@@ -2560,7 +3368,7 @@ module.exports = function () {
2560
3368
  *
2561
3369
  * @static
2562
3370
  * @public
2563
- * @param candidate
3371
+ * @param {*} candidate
2564
3372
  * @returns {boolean}
2565
3373
  */
2566
3374
  positive: function positive(candidate) {
@@ -2573,7 +3381,7 @@ module.exports = function () {
2573
3381
  *
2574
3382
  * @static
2575
3383
  * @public
2576
- * @param candidate
3384
+ * @param {*} candidate
2577
3385
  * @returns {*|boolean}
2578
3386
  */
2579
3387
  negative: function negative(candidate) {
@@ -2586,7 +3394,7 @@ module.exports = function () {
2586
3394
  *
2587
3395
  * @static
2588
3396
  * @public
2589
- * @param candidate
3397
+ * @param {*} candidate
2590
3398
  * @returns {boolean}
2591
3399
  */
2592
3400
  string: function string(candidate) {
@@ -2599,7 +3407,7 @@ module.exports = function () {
2599
3407
  *
2600
3408
  * @static
2601
3409
  * @public
2602
- * @param candidate
3410
+ * @param {*} candidate
2603
3411
  * @returns {boolean}
2604
3412
  */
2605
3413
  date: function date(candidate) {
@@ -2612,7 +3420,7 @@ module.exports = function () {
2612
3420
  *
2613
3421
  * @static
2614
3422
  * @public
2615
- * @param candidate
3423
+ * @param {*} candidate
2616
3424
  * @returns {boolean}
2617
3425
  */
2618
3426
  fn: function fn(candidate) {
@@ -2625,7 +3433,7 @@ module.exports = function () {
2625
3433
  *
2626
3434
  * @static
2627
3435
  * @public
2628
- * @param candidate
3436
+ * @param {*} candidate
2629
3437
  * @returns {boolean}
2630
3438
  */
2631
3439
  array: function array(candidate) {
@@ -2638,7 +3446,7 @@ module.exports = function () {
2638
3446
  *
2639
3447
  * @static
2640
3448
  * @public
2641
- * @param candidate
3449
+ * @param {*} candidate
2642
3450
  * @returns {boolean}
2643
3451
  */
2644
3452
  boolean: function boolean(candidate) {
@@ -2651,7 +3459,7 @@ module.exports = function () {
2651
3459
  *
2652
3460
  * @static
2653
3461
  * @public
2654
- * @param candidate
3462
+ * @param {*} candidate
2655
3463
  * @returns {boolean}
2656
3464
  */
2657
3465
  object: function object(candidate) {
@@ -2664,7 +3472,7 @@ module.exports = function () {
2664
3472
  *
2665
3473
  * @static
2666
3474
  * @public
2667
- * @param candidate
3475
+ * @param {*} candidate
2668
3476
  * @returns {boolean}
2669
3477
  */
2670
3478
  null: function _null(candidate) {
@@ -2677,7 +3485,7 @@ module.exports = function () {
2677
3485
  *
2678
3486
  * @static
2679
3487
  * @public
2680
- * @param candidate
3488
+ * @param {*} candidate
2681
3489
  * @returns {boolean}
2682
3490
  */
2683
3491
  undefined: function (_undefined) {
@@ -2709,7 +3517,179 @@ module.exports = function () {
2709
3517
  };
2710
3518
  }();
2711
3519
 
2712
- },{}],11:[function(require,module,exports){
3520
+ },{}],17:[function(require,module,exports){
3521
+ 'use strict';
3522
+
3523
+ var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
3524
+
3525
+ function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
3526
+
3527
+ function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
3528
+
3529
+ function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
3530
+
3531
+ var assert = require('./../lang/assert'),
3532
+ Disposable = require('./../lang/Disposable');
3533
+
3534
+ module.exports = function () {
3535
+ 'use strict';
3536
+
3537
+ /**
3538
+ * An implementation of the observer pattern.
3539
+ *
3540
+ * @param {*} sender - The object which owns the event.
3541
+ * @extends {Disposable}
3542
+ */
3543
+
3544
+ var Event = function (_Disposable) {
3545
+ _inherits(Event, _Disposable);
3546
+
3547
+ function Event(sender) {
3548
+ _classCallCheck(this, Event);
3549
+
3550
+ var _this = _possibleConstructorReturn(this, (Event.__proto__ || Object.getPrototypeOf(Event)).call(this));
3551
+
3552
+ _this._sender = sender || null;
3553
+
3554
+ _this._observers = [];
3555
+ return _this;
3556
+ }
3557
+
3558
+ /**
3559
+ * Registers an event handler which will receive a notification when
3560
+ * {@link Event#fire} is called.
3561
+ *
3562
+ * @public
3563
+ * @param {Function} handler - The function which will be called each time the event fires. The first argument will be the event data. The second argument will be the event owner (i.e. sender).
3564
+ * @returns {Disposable}
3565
+ */
3566
+
3567
+
3568
+ _createClass(Event, [{
3569
+ key: 'register',
3570
+ value: function register(handler) {
3571
+ var _this2 = this;
3572
+
3573
+ assert.argumentIsRequired(handler, 'handler', Function);
3574
+
3575
+ addRegistration.call(this, handler);
3576
+
3577
+ return Disposable.fromAction(function () {
3578
+ if (_this2.getIsDisposed()) {
3579
+ return;
3580
+ }
3581
+
3582
+ removeRegistration.call(_this2, handler);
3583
+ });
3584
+ }
3585
+
3586
+ /**
3587
+ * Removes registration for an event handler. That is, the handler will
3588
+ * no longer be called if the event fires.
3589
+ *
3590
+ * @public
3591
+ * @param {Function} handler
3592
+ */
3593
+
3594
+ }, {
3595
+ key: 'unregister',
3596
+ value: function unregister(handler) {
3597
+ assert.argumentIsRequired(handler, 'handler', Function);
3598
+
3599
+ removeRegistration.call(this, handler);
3600
+ }
3601
+
3602
+ /**
3603
+ * Removes all handlers from the event.
3604
+ *
3605
+ * @public
3606
+ */
3607
+
3608
+ }, {
3609
+ key: 'clear',
3610
+ value: function clear() {
3611
+ this._observers = [];
3612
+ }
3613
+
3614
+ /**
3615
+ * Triggers the event, calling all previously registered handlers.
3616
+ *
3617
+ * @public
3618
+ * @param {*) data - The data to pass each handler.
3619
+ */
3620
+
3621
+ }, {
3622
+ key: 'fire',
3623
+ value: function fire(data) {
3624
+ var observers = this._observers;
3625
+
3626
+ for (var i = 0; i < observers.length; i++) {
3627
+ var observer = observers[i];
3628
+
3629
+ observer(data, this._sender);
3630
+ }
3631
+ }
3632
+
3633
+ /**
3634
+ * Returns true, if no handlers are currently registered.
3635
+ *
3636
+ * @returns {boolean}
3637
+ */
3638
+
3639
+ }, {
3640
+ key: 'getIsEmpty',
3641
+ value: function getIsEmpty() {
3642
+ return this._observers.length === 0;
3643
+ }
3644
+ }, {
3645
+ key: '_onDispose',
3646
+ value: function _onDispose() {
3647
+ this._observers = null;
3648
+ }
3649
+ }, {
3650
+ key: 'toString',
3651
+ value: function toString() {
3652
+ return '[Event]';
3653
+ }
3654
+ }]);
3655
+
3656
+ return Event;
3657
+ }(Disposable);
3658
+
3659
+ function addRegistration(handler) {
3660
+ var copiedObservers = this._observers.slice();
3661
+
3662
+ copiedObservers.push(handler);
3663
+
3664
+ this._observers = copiedObservers;
3665
+ }
3666
+
3667
+ function removeRegistration(handler) {
3668
+ var indicesToRemove = [];
3669
+
3670
+ for (var i = 0; i < this._observers.length; i++) {
3671
+ var candidate = this._observers[i];
3672
+
3673
+ if (candidate === handler) {
3674
+ indicesToRemove.push(i);
3675
+ }
3676
+ }
3677
+
3678
+ if (indicesToRemove.length > 0) {
3679
+ var copiedObservers = this._observers.slice();
3680
+
3681
+ for (var j = indicesToRemove.length - 1; !(j < 0); j--) {
3682
+ copiedObservers.splice(indicesToRemove[j], 1);
3683
+ }
3684
+
3685
+ this._observers = copiedObservers;
3686
+ }
3687
+ }
3688
+
3689
+ return Event;
3690
+ }();
3691
+
3692
+ },{"./../lang/Disposable":12,"./../lang/assert":15}],18:[function(require,module,exports){
2713
3693
  /*
2714
3694
  * big.js v5.0.3
2715
3695
  * A small, fast, easy-to-use library for arbitrary-precision decimal arithmetic.
@@ -3650,7 +4630,7 @@ module.exports = function () {
3650
4630
  }
3651
4631
  })(this);
3652
4632
 
3653
- },{}],12:[function(require,module,exports){
4633
+ },{}],19:[function(require,module,exports){
3654
4634
  const Day = require('@barchart/common-js/lang/Day'),
3655
4635
  Decimal = require('@barchart/common-js/lang/Decimal');
3656
4636
 
@@ -3963,6 +4943,147 @@ describe('After the PositionSummaryFrame enumeration is initialized', () => {
3963
4943
  expect(ranges[0].end.format()).toEqual('2018-12-31');
3964
4944
  });
3965
4945
  });
4946
+
4947
+ describe('and getting the start date for yearly frames', () => {
4948
+ describe('for one year ago', function() {
4949
+ let start;
4950
+
4951
+ beforeEach(() => {
4952
+ start = PositionSummaryFrame.YEARLY.getStartDate(1);
4953
+ });
4954
+
4955
+ it('should be in December', () => {
4956
+ expect(start.month).toEqual(12);
4957
+ });
4958
+
4959
+ it('should be on the 31st', () => {
4960
+ expect(start.day).toEqual(31);
4961
+ });
4962
+
4963
+ it('should be two years ago', () => {
4964
+ expect(start.year).toEqual(Day.getToday().year - 2);
4965
+ });
4966
+ });
4967
+
4968
+ describe('for two years ago', function() {
4969
+ let start;
4970
+
4971
+ beforeEach(() => {
4972
+ start = PositionSummaryFrame.YEARLY.getStartDate(2);
4973
+ });
4974
+
4975
+ it('should be in December', () => {
4976
+ expect(start.month).toEqual(12);
4977
+ });
4978
+
4979
+ it('should be on the 31st', () => {
4980
+ expect(start.day).toEqual(31);
4981
+ });
4982
+
4983
+ it('should be two years ago', () => {
4984
+ expect(start.year).toEqual(Day.getToday().year - 3);
4985
+ });
4986
+ });
4987
+ });
4988
+ });
4989
+
4990
+ },{"./../../../lib/data/PositionSummaryFrame":1,"./../../../lib/data/TransactionType":2,"@barchart/common-js/lang/Day":10,"@barchart/common-js/lang/Decimal":11}],20:[function(require,module,exports){
4991
+ const PositionContainer = require('./../../../lib/processing/PositionContainer'),
4992
+ PositionGroupDefinition = require('./../../../lib/processing/PositionGroupDefinition');
4993
+
4994
+ describe('When a position container data is gathered', () => {
4995
+ 'use strict';
4996
+
4997
+ describe('for two portfolios, each with the same position, and the second portfolio with an additonal position', () => {
4998
+ let portfolios;
4999
+ let positions;
5000
+ let summaries;
5001
+
5002
+ beforeEach(() => {
5003
+ portfolios = [
5004
+ {
5005
+ portfolio: 'a',
5006
+ name: 'a'
5007
+ }, {
5008
+ portfolio: 'b',
5009
+ name: 'b'
5010
+ }
5011
+ ];
5012
+
5013
+ positions = [
5014
+ {
5015
+ portfolio: 'a',
5016
+ position: '1',
5017
+ instrument: {
5018
+ symbol: {
5019
+ barchart: 'AAPL'
5020
+ }
5021
+ },
5022
+ }, {
5023
+ portfolio: 'b',
5024
+ position: '2',
5025
+ instrument: {
5026
+ symbol: {
5027
+ barchart: 'AAPL'
5028
+ }
5029
+ }
5030
+ }, {
5031
+ portfolio: 'b',
5032
+ position: '3',
5033
+ instrument: {
5034
+ symbol: {
5035
+ barchart: 'TSLA'
5036
+ }
5037
+ }
5038
+ }
5039
+ ];
5040
+
5041
+ summaries = [ ];
5042
+ });
5043
+
5044
+ describe('and a container is created grouping by total, portfolio, and instrument', () => {
5045
+ let definitions;
5046
+ let container;
5047
+
5048
+ beforeEach(() => {
5049
+ definitions = [
5050
+ new PositionGroupDefinition('Total', x => true, x => 'Total'),
5051
+ new PositionGroupDefinition('Portfolio', x => x.portfolio.portfolio, x => x.portfolio.name),
5052
+ new PositionGroupDefinition('Position', x => x.position.position, x => x.position.instrument.symbol.barchart)
5053
+ ];
5054
+
5055
+ try {
5056
+ container = new PositionContainer(portfolios, positions, summaries, definitions);
5057
+ } catch (e) {
5058
+ console.log(e);
5059
+ }
5060
+ });
5061
+
5062
+ it('the "Total" group should have two children groups', () => {
5063
+ expect(container.getGroups([ 'Total' ]).length).toEqual(2);
5064
+ });
5065
+
5066
+ it('the "Total" group should have three items', () => {
5067
+ expect(container.getGroup([ 'Total' ]).items.length).toEqual(3);
5068
+ });
5069
+
5070
+ it('The "a" portfolio group should have one child group', () => {
5071
+ expect(container.getGroups([ 'Total', 'a' ]).length).toEqual(1);
5072
+ });
5073
+
5074
+ it('the "a" portfolio group should have one item', () => {
5075
+ expect(container.getGroup([ 'Total', 'a' ]).items.length).toEqual(1);
5076
+ });
5077
+
5078
+ it('The "b" portfolio group should have two child groups', () => {
5079
+ expect(container.getGroups([ 'Total', 'b' ]).length).toEqual(2);
5080
+ });
5081
+
5082
+ it('the "b" portfolio group should have two items', () => {
5083
+ expect(container.getGroup([ 'Total', 'b' ]).items.length).toEqual(2);
5084
+ });
5085
+ });
5086
+ });
3966
5087
  });
3967
5088
 
3968
- },{"./../../../lib/data/PositionSummaryFrame":1,"./../../../lib/data/TransactionType":2,"@barchart/common-js/lang/Day":5,"@barchart/common-js/lang/Decimal":6}]},{},[12]);
5089
+ },{"./../../../lib/processing/PositionContainer":3,"./../../../lib/processing/PositionGroupDefinition":5}]},{},[19,20]);