@hpcc-js/common 3.7.2 → 3.7.5

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.
Files changed (54) hide show
  1. package/LICENSE +43 -43
  2. package/README.md +59 -59
  3. package/dist/index.js +1 -1
  4. package/dist/index.js.map +1 -1
  5. package/dist/index.umd.cjs +1 -1
  6. package/dist/index.umd.cjs.map +1 -1
  7. package/package.json +5 -5
  8. package/src/CanvasWidget.ts +31 -31
  9. package/src/Class.ts +72 -72
  10. package/src/Database.ts +860 -860
  11. package/src/Entity.ts +235 -235
  12. package/src/EntityCard.ts +66 -66
  13. package/src/EntityPin.ts +103 -103
  14. package/src/EntityRect.css +15 -15
  15. package/src/EntityRect.ts +254 -254
  16. package/src/EntityVertex.ts +86 -86
  17. package/src/FAChar.css +2 -2
  18. package/src/FAChar.ts +89 -89
  19. package/src/HTMLWidget.ts +191 -191
  20. package/src/IList.ts +4 -4
  21. package/src/IMenu.ts +5 -5
  22. package/src/Icon.css +9 -9
  23. package/src/Icon.ts +176 -176
  24. package/src/Image.ts +104 -104
  25. package/src/List.css +12 -12
  26. package/src/List.ts +102 -102
  27. package/src/Menu.css +22 -22
  28. package/src/Menu.ts +139 -139
  29. package/src/Palette.ts +341 -341
  30. package/src/Platform.ts +125 -125
  31. package/src/ProgressBar.ts +115 -115
  32. package/src/PropertyExt.ts +770 -770
  33. package/src/ResizeSurface.css +38 -38
  34. package/src/ResizeSurface.ts +225 -225
  35. package/src/SVGWidget.ts +583 -583
  36. package/src/SVGZoomWidget.css +11 -11
  37. package/src/SVGZoomWidget.ts +427 -427
  38. package/src/Shape.css +3 -3
  39. package/src/Shape.ts +186 -186
  40. package/src/Surface.css +39 -39
  41. package/src/Surface.ts +364 -364
  42. package/src/Text.css +3 -3
  43. package/src/Text.ts +131 -131
  44. package/src/TextBox.css +3 -3
  45. package/src/TextBox.ts +183 -183
  46. package/src/TitleBar.css +114 -114
  47. package/src/TitleBar.ts +407 -407
  48. package/src/Transition.ts +45 -45
  49. package/src/Utility.ts +843 -843
  50. package/src/Widget.css +7 -7
  51. package/src/Widget.ts +731 -731
  52. package/src/WidgetArray.ts +15 -15
  53. package/src/__package__.ts +3 -3
  54. package/src/index.ts +55 -55
package/src/Utility.ts CHANGED
@@ -1,843 +1,843 @@
1
- import { isArray } from "@hpcc-js/util";
2
- import { ascending as d3Ascending, descending as d3Descending } from "d3-array";
3
- import { select as d3Select, Selection as d3SelectionT } from "d3-selection";
4
- import { timeFormat as d3TimeFormat } from "d3-time-format";
5
-
6
- function _naturalSort(a, b, order, idx, sortCaseSensitive) {
7
- const re = /(^([+\-]?(?:0|[1-9]\d*)(?:\.\d*)?(?:[eE][+\-]?\d+)?)?$|^0x[0-9a-f]+$|\d+)/gi;
8
- const sre = /(^[ ]*|[ ]*$)/g;
9
- const dre = /(^([\w ]+,?[\w ]+)?[\w ]+,?[\w ]+\d+:\d+(:\d+)?[\w ]?|^\d{1,4}[\/\-]\d{1,4}[\/\-]\d{1,4}|^\w+, \w+ \d+, \d{4})/;
10
- const ore = /^0/;
11
- const i = function (s) { return !sortCaseSensitive && ("" + s).toLowerCase() || "" + s; };
12
- // convert all to strings strip whitespace
13
- const x = i(idx ? a[idx] : a).replace(sre, "") || "";
14
- const y = i(idx ? b[idx] : b).replace(sre, "") || "";
15
- // chunk/tokenize
16
- const xN = x.replace(re, "\0$1\0").replace(/\0$/, "").replace(/^\0/, "").split("\0");
17
- const yN = y.replace(re, "\0$1\0").replace(/\0$/, "").replace(/^\0/, "").split("\0");
18
- // numeric or date detection
19
- const xD = (xN.length !== 1 && x.match(dre) && Date.parse(x));
20
- const yD = xD && y.match(dre) && Date.parse(y) || null;
21
- let oFxNcL;
22
- let oFyNcL;
23
- // first try and sort Hex codes or Dates
24
- if (yD) {
25
- if (xD < yD) {
26
- return order === "ascending" ? -1 : 1;
27
- } else if (xD > yD) {
28
- return order === "ascending" ? 1 : -1;
29
- }
30
- }
31
- // natural sorting through split numeric strings and default strings
32
- for (let cLoc = 0, numS = Math.max(xN.length, yN.length); cLoc < numS; cLoc++) {
33
- // find floats not starting with "0", string or 0 if not defined (Clint Priest)
34
- oFxNcL = !(xN[cLoc] || "").match(ore) && parseFloat(xN[cLoc]) || xN[cLoc] || 0;
35
- oFyNcL = !(yN[cLoc] || "").match(ore) && parseFloat(yN[cLoc]) || yN[cLoc] || 0;
36
- // handle numeric vs string comparison - number < string - (Kyle Adams)
37
- if (isNaN(oFxNcL) !== isNaN(oFyNcL)) {
38
- return (isNaN(oFxNcL)) ? 1 : -1;
39
- } else if (typeof oFxNcL !== typeof oFyNcL) {
40
- // rely on string comparison if different types - i.e. "02" < 2 != "02" < "2"
41
- oFxNcL += "";
42
- oFyNcL += "";
43
- }
44
- if (oFxNcL < oFyNcL) { return order === "ascending" ? -1 : 1; }
45
- if (oFxNcL > oFyNcL) { return order === "ascending" ? 1 : -1; }
46
- }
47
- return 0;
48
- }
49
-
50
- // Selection Bag(s) ---
51
- export class SelectionBase {
52
- protected __widget;
53
- private __svgGlowID: string;
54
-
55
- constructor(widget) {
56
- // Can't import Widget or SVGWidget as it breaks AMD loading...
57
- this.__widget = widget;
58
- }
59
-
60
- svgGlowID(): string {
61
- if (this.__svgGlowID === undefined) {
62
- this.__svgGlowID = this.__widget.svgGlowID && this.__widget.svgGlowID() || "";
63
- }
64
- return this.__svgGlowID;
65
- }
66
- }
67
-
68
- export interface ISelectionItem {
69
- _id: string;
70
- element(): d3SelectionT<Element, any, Element, any>;
71
- }
72
-
73
- export class SelectionBag extends SelectionBase {
74
- items: { [key: string]: ISelectionItem };
75
- constructor(widget) {
76
- super(widget);
77
- this.items = {};
78
- }
79
-
80
- clear() {
81
- for (const key in this.items) {
82
- this.items[key].element()
83
- .classed("selected", false)
84
- .attr("filter", null)
85
- ;
86
- }
87
- this.items = {};
88
- }
89
-
90
- isEmpty() {
91
- for (const _key in this.items) { // jshint ignore:line
92
- return false;
93
- }
94
- return true;
95
- }
96
-
97
- append(item: ISelectionItem) {
98
- this.items[item._id] = item;
99
- item.element()
100
- .classed("selected", true)
101
- .attr("filter", this.svgGlowID() ? `url(#${this.svgGlowID()})` : null)
102
- ;
103
- }
104
-
105
- remove(item: ISelectionItem) {
106
- this.items[item._id].element()
107
- .classed("selected", false)
108
- .attr("filter", null)
109
- ;
110
- delete this.items[item._id];
111
- }
112
-
113
- isSelected(item: ISelectionItem) {
114
- return this.items[item._id] !== undefined;
115
- }
116
-
117
- get() {
118
- const retVal = [];
119
- for (const key in this.items) {
120
- retVal.push(this.items[key]);
121
- }
122
- return retVal;
123
- }
124
-
125
- set(itemArray: ISelectionItem[]) {
126
- this.clear();
127
- itemArray.forEach(function (item) {
128
- this.append(item);
129
- }, this);
130
- }
131
-
132
- click = function (item: ISelectionItem, evt) {
133
- if (evt.ctrlKey) {
134
- if (this.items[item._id]) {
135
- this.remove(item);
136
- } else {
137
- this.append(item);
138
- }
139
- } else {
140
- this.clear();
141
- this.append(item);
142
- }
143
- };
144
- }
145
-
146
- export class SimpleSelection extends SelectionBase {
147
- constructor(widget, widgetElement, skipBringToTop?) {
148
- super(widget);
149
- this.widgetElement(widgetElement);
150
- this.skipBringToTop(skipBringToTop);
151
- }
152
-
153
- _widgetElement;
154
- widgetElement(_?) {
155
- if (!arguments.length) return this._widgetElement;
156
- this._widgetElement = _;
157
- return this;
158
- }
159
-
160
- _skipBringToTop;
161
- skipBringToTop(_?) {
162
- if (!arguments.length) return this._skipBringToTop;
163
- this._skipBringToTop = _;
164
- return this;
165
- }
166
-
167
- _initialSelection: (d) => boolean;
168
- enter(elements) {
169
- const context = this;
170
- elements
171
- .each(function (d) {
172
- const selected: boolean = context._initialSelection ? context._initialSelection(d.data) : false;
173
- d3Select(this)
174
- .classed("selected", selected)
175
- .classed("deselected", !selected)
176
- .attr("filter", context.svgGlowID() && selected ? `url(#${context.svgGlowID()})` : null)
177
- ;
178
- })
179
- .on("click.SimpleSelection", function () {
180
- context.click(this);
181
- })
182
- .on("mouseover.SimpleSelection", function () {
183
- context.mouseOver(this);
184
- })
185
- .on("mouseout.SimpleSelection", function () {
186
- context.mouseOut(this);
187
- })
188
- ;
189
- }
190
- click(domNode): boolean {
191
- if (!this._skipBringToTop) {
192
- domNode.parentNode.appendChild(domNode);
193
- }
194
- const element = d3Select(domNode);
195
- const wasSelected = element.classed("selected");
196
- this._widgetElement.selectAll(".selected")
197
- .classed("selected", false)
198
- .classed("deselected", true)
199
- .attr("filter", null)
200
- ;
201
- if (!wasSelected) {
202
- element
203
- .classed("selected", true)
204
- .classed("deselected", false)
205
- .attr("filter", this.svgGlowID() ? `url(#${this.svgGlowID()})` : null)
206
- ;
207
- }
208
- return !wasSelected;
209
- }
210
- mouseOver(domNode) {
211
- d3Select(domNode)
212
- .classed("over", true)
213
- ;
214
- }
215
- mouseOut(domNode) {
216
- d3Select(domNode)
217
- .classed("over", null)
218
- ;
219
- }
220
- selected(domNode) {
221
- return d3Select(domNode).classed("selected");
222
- }
223
- selection(_?) {
224
- if (!arguments.length) {
225
- return this.selection2().map(row => JSON.stringify(row));
226
- }
227
- this.selection2(d => _.indexOf(JSON.stringify(d)) >= 0);
228
- return this;
229
- }
230
- selection2(): any[];
231
- selection2(isSelected: (d) => boolean): this;
232
- selection2(isSelected?: (d) => boolean): any[] | this {
233
- if (!arguments.length) {
234
- const retVal: any[] = [];
235
- if (this._widgetElement) {
236
- this._widgetElement.selectAll(".selected")
237
- .each(d => retVal.push(d))
238
- ;
239
- }
240
- return retVal;
241
- }
242
- if (this._widgetElement) {
243
- const context = this;
244
- this._widgetElement.selectAll(".selected,.deselected")
245
- .each(function (d) {
246
- const selected = isSelected(d);
247
- d3Select(this)
248
- .classed("selected", selected)
249
- .classed("deselected", !selected)
250
- .attr("filter", (selected && context.svgGlowID()) ? `url(#${context.svgGlowID()})` : null)
251
- ;
252
- if (selected && !context._skipBringToTop) {
253
- safeRaise(this);
254
- }
255
- })
256
- ;
257
- } else {
258
- this._initialSelection = isSelected;
259
- }
260
- return this;
261
- }
262
- }
263
-
264
- export function SimpleSelectionMixin(skipBringToTop) {
265
- this._selection = new SimpleSelection(this, null, skipBringToTop);
266
- }
267
-
268
- SimpleSelectionMixin.prototype.serializeState = function () {
269
- return {
270
- selection: this._selection.selection(),
271
- data: this.data()
272
- };
273
- };
274
-
275
- SimpleSelectionMixin.prototype.deserializeState = function (state) {
276
- if (state) {
277
- this._selection.selection(state.selection);
278
- if (state.data) {
279
- this.data(state.data);
280
- }
281
- }
282
- return this;
283
- };
284
-
285
- const perf: any = window.performance;
286
- const now = perf && (perf.now || perf.mozNow || perf.msNow || perf.oNow || perf.webkitNow);
287
-
288
- const faCharMap = { "fa-500px": "", "fa-address-book": "", "fa-address-book-o": "", "fa-address-card": "", "fa-address-card-o": "", "fa-adjust": "", "fa-adn": "", "fa-align-center": "", "fa-align-justify": "", "fa-align-left": "", "fa-align-right": "", "fa-amazon": "", "fa-ambulance": "", "fa-american-sign-language-interpreting": "", "fa-anchor": "", "fa-android": "", "fa-angellist": "", "fa-angle-double-down": "", "fa-angle-double-left": "", "fa-angle-double-right": "", "fa-angle-double-up": "", "fa-angle-down": "", "fa-angle-left": "", "fa-angle-right": "", "fa-angle-up": "", "fa-apple": "", "fa-archive": "", "fa-area-chart": "", "fa-arrow-circle-down": "", "fa-arrow-circle-left": "", "fa-arrow-circle-o-down": "", "fa-arrow-circle-o-left": "", "fa-arrow-circle-o-right": "", "fa-arrow-circle-o-up": "", "fa-arrow-circle-right": "", "fa-arrow-circle-up": "", "fa-arrow-down": "", "fa-arrow-left": "", "fa-arrow-right": "", "fa-arrow-up": "", "fa-arrows": "", "fa-arrows-alt": "", "fa-arrows-h": "", "fa-arrows-v": "", "fa-asl-interpreting": "", "fa-assistive-listening-systems": "", "fa-asterisk": "", "fa-at": "", "fa-audio-description": "", "fa-automobile": "", "fa-backward": "", "fa-balance-scale": "", "fa-ban": "", "fa-bandcamp": "", "fa-bank": "", "fa-bar-chart": "", "fa-bar-chart-o": "", "fa-barcode": "", "fa-bars": "", "fa-bath": "", "fa-bathtub": "", "fa-battery": "", "fa-battery-0": "", "fa-battery-1": "", "fa-battery-2": "", "fa-battery-3": "", "fa-battery-4": "", "fa-battery-empty": "", "fa-battery-full": "", "fa-battery-half": "", "fa-battery-quarter": "", "fa-battery-three-quarters": "", "fa-bed": "", "fa-beer": "", "fa-behance": "", "fa-behance-square": "", "fa-bell": "", "fa-bell-o": "", "fa-bell-slash": "", "fa-bell-slash-o": "", "fa-bicycle": "", "fa-binoculars": "", "fa-birthday-cake": "", "fa-bitbucket": "", "fa-bitbucket-square": "", "fa-bitcoin": "", "fa-black-tie": "", "fa-blind": "", "fa-bluetooth": "", "fa-bluetooth-b": "", "fa-bold": "", "fa-bolt": "", "fa-bomb": "", "fa-book": "", "fa-bookmark": "", "fa-bookmark-o": "", "fa-braille": "", "fa-briefcase": "", "fa-btc": "", "fa-bug": "", "fa-building": "", "fa-building-o": "", "fa-bullhorn": "", "fa-bullseye": "", "fa-bus": "", "fa-buysellads": "", "fa-cab": "", "fa-calculator": "", "fa-calendar": "", "fa-calendar-check-o": "", "fa-calendar-minus-o": "", "fa-calendar-o": "", "fa-calendar-plus-o": "", "fa-calendar-times-o": "", "fa-camera": "", "fa-camera-retro": "", "fa-car": "", "fa-caret-down": "", "fa-caret-left": "", "fa-caret-right": "", "fa-caret-square-o-down": "", "fa-caret-square-o-left": "", "fa-caret-square-o-right": "", "fa-caret-square-o-up": "", "fa-caret-up": "", "fa-cart-arrow-down": "", "fa-cart-plus": "", "fa-cc": "", "fa-cc-amex": "", "fa-cc-diners-club": "", "fa-cc-discover": "", "fa-cc-jcb": "", "fa-cc-mastercard": "", "fa-cc-paypal": "", "fa-cc-stripe": "", "fa-cc-visa": "", "fa-certificate": "", "fa-chain": "", "fa-chain-broken": "", "fa-check": "", "fa-check-circle": "", "fa-check-circle-o": "", "fa-check-square": "", "fa-check-square-o": "", "fa-chevron-circle-down": "", "fa-chevron-circle-left": "", "fa-chevron-circle-right": "", "fa-chevron-circle-up": "", "fa-chevron-down": "", "fa-chevron-left": "", "fa-chevron-right": "", "fa-chevron-up": "", "fa-child": "", "fa-chrome": "", "fa-circle": "", "fa-circle-o": "", "fa-circle-o-notch": "", "fa-circle-thin": "", "fa-clipboard": "", "fa-clock-o": "", "fa-clone": "", "fa-close": "", "fa-cloud": "", "fa-cloud-download": "", "fa-cloud-upload": "", "fa-cny": "", "fa-code": "", "fa-code-fork": "", "fa-codepen": "", "fa-codiepie": "", "fa-coffee": "", "fa-cog": "", "fa-cogs": "", "fa-columns": "", "fa-comment": "", "fa-comment-o": "", "fa-commenting": "", "fa-commenting-o": "", "fa-comments": "", "fa-comments-o": "", "fa-compass": "", "fa-compress": "", "fa-connectdevelop": "", "fa-contao": "", "fa-copy": "", "fa-copyright": "", "fa-creative-commons": "", "fa-credit-card": "", "fa-credit-card-alt": "", "fa-crop": "", "fa-crosshairs": "", "fa-css3": "", "fa-cube": "", "fa-cubes": "", "fa-cut": "", "fa-cutlery": "", "fa-dashboard": "", "fa-dashcube": "", "fa-database": "", "fa-deaf": "", "fa-deafness": "", "fa-dedent": "", "fa-delicious": "", "fa-desktop": "", "fa-deviantart": "", "fa-diamond": "", "fa-digg": "", "fa-dollar": "", "fa-dot-circle-o": "", "fa-download": "", "fa-dribbble": "", "fa-drivers-license": "", "fa-drivers-license-o": "", "fa-dropbox": "", "fa-drupal": "", "fa-edge": "", "fa-edit": "", "fa-eercast": "", "fa-eject": "", "fa-ellipsis-h": "", "fa-ellipsis-v": "", "fa-empire": "", "fa-envelope": "", "fa-envelope-o": "", "fa-envelope-open": "", "fa-envelope-open-o": "", "fa-envelope-square": "", "fa-envira": "", "fa-eraser": "", "fa-etsy": "", "fa-eur": "", "fa-euro": "", "fa-exchange": "", "fa-exclamation": "", "fa-exclamation-circle": "", "fa-exclamation-triangle": "", "fa-expand": "", "fa-expeditedssl": "", "fa-external-link": "", "fa-external-link-square": "", "fa-eye": "", "fa-eye-slash": "", "fa-eyedropper": "", "fa-fa": "", "fa-facebook": "", "fa-facebook-f": "", "fa-facebook-official": "", "fa-facebook-square": "", "fa-fast-backward": "", "fa-fast-forward": "", "fa-fax": "", "fa-feed": "", "fa-female": "", "fa-fighter-jet": "", "fa-file": "", "fa-file-archive-o": "", "fa-file-audio-o": "", "fa-file-code-o": "", "fa-file-excel-o": "", "fa-file-image-o": "", "fa-file-movie-o": "", "fa-file-o": "", "fa-file-pdf-o": "", "fa-file-photo-o": "", "fa-file-picture-o": "", "fa-file-powerpoint-o": "", "fa-file-sound-o": "", "fa-file-text": "", "fa-file-text-o": "", "fa-file-video-o": "", "fa-file-word-o": "", "fa-file-zip-o": "", "fa-files-o": "", "fa-film": "", "fa-filter": "", "fa-fire": "", "fa-fire-extinguisher": "", "fa-firefox": "", "fa-first-order": "", "fa-flag": "", "fa-flag-checkered": "", "fa-flag-o": "", "fa-flash": "", "fa-flask": "", "fa-flickr": "", "fa-floppy-o": "", "fa-folder": "", "fa-folder-o": "", "fa-folder-open": "", "fa-folder-open-o": "", "fa-font": "", "fa-font-awesome": "", "fa-fonticons": "", "fa-fort-awesome": "", "fa-forumbee": "", "fa-forward": "", "fa-foursquare": "", "fa-free-code-camp": "", "fa-frown-o": "", "fa-futbol-o": "", "fa-gamepad": "", "fa-gavel": "", "fa-gbp": "", "fa-ge": "", "fa-gear": "", "fa-gears": "", "fa-genderless": "", "fa-get-pocket": "", "fa-gg": "", "fa-gg-circle": "", "fa-gift": "", "fa-git": "", "fa-git-square": "", "fa-github": "", "fa-github-alt": "", "fa-github-square": "", "fa-gitlab": "", "fa-gittip": "", "fa-glass": "", "fa-glide": "", "fa-glide-g": "", "fa-globe": "", "fa-google": "", "fa-google-plus": "", "fa-google-plus-circle": "", "fa-google-plus-official": "", "fa-google-plus-square": "", "fa-google-wallet": "", "fa-graduation-cap": "", "fa-gratipay": "", "fa-grav": "", "fa-group": "", "fa-h-square": "", "fa-hacker-news": "", "fa-hand-grab-o": "", "fa-hand-lizard-o": "", "fa-hand-o-down": "", "fa-hand-o-left": "", "fa-hand-o-right": "", "fa-hand-o-up": "", "fa-hand-paper-o": "", "fa-hand-peace-o": "", "fa-hand-pointer-o": "", "fa-hand-rock-o": "", "fa-hand-scissors-o": "", "fa-hand-spock-o": "", "fa-hand-stop-o": "", "fa-handshake-o": "", "fa-hard-of-hearing": "", "fa-hashtag": "", "fa-hdd-o": "", "fa-header": "", "fa-headphones": "", "fa-heart": "", "fa-heart-o": "", "fa-heartbeat": "", "fa-history": "", "fa-home": "", "fa-hospital-o": "", "fa-hotel": "", "fa-hourglass": "", "fa-hourglass-1": "", "fa-hourglass-2": "", "fa-hourglass-3": "", "fa-hourglass-end": "", "fa-hourglass-half": "", "fa-hourglass-o": "", "fa-hourglass-start": "", "fa-houzz": "", "fa-html5": "", "fa-i-cursor": "", "fa-id-badge": "", "fa-id-card": "", "fa-id-card-o": "", "fa-ils": "", "fa-image": "", "fa-imdb": "", "fa-inbox": "", "fa-indent": "", "fa-industry": "", "fa-info": "", "fa-info-circle": "", "fa-inr": "", "fa-instagram": "", "fa-institution": "", "fa-internet-explorer": "", "fa-intersex": "", "fa-ioxhost": "", "fa-italic": "", "fa-joomla": "", "fa-jpy": "", "fa-jsfiddle": "", "fa-key": "", "fa-keyboard-o": "", "fa-krw": "", "fa-language": "", "fa-laptop": "", "fa-lastfm": "", "fa-lastfm-square": "", "fa-leaf": "", "fa-leanpub": "", "fa-legal": "", "fa-lemon-o": "", "fa-level-down": "", "fa-level-up": "", "fa-life-bouy": "", "fa-life-buoy": "", "fa-life-ring": "", "fa-life-saver": "", "fa-lightbulb-o": "", "fa-line-chart": "", "fa-link": "", "fa-linkedin": "", "fa-linkedin-square": "", "fa-linode": "", "fa-linux": "", "fa-list": "", "fa-list-alt": "", "fa-list-ol": "", "fa-list-ul": "", "fa-location-arrow": "", "fa-lock": "", "fa-long-arrow-down": "", "fa-long-arrow-left": "", "fa-long-arrow-right": "", "fa-long-arrow-up": "", "fa-low-vision": "", "fa-magic": "", "fa-magnet": "", "fa-mail-forward": "", "fa-mail-reply": "", "fa-mail-reply-all": "", "fa-male": "", "fa-map": "", "fa-map-marker": "", "fa-map-o": "", "fa-map-pin": "", "fa-map-signs": "", "fa-mars": "", "fa-mars-double": "", "fa-mars-stroke": "", "fa-mars-stroke-h": "", "fa-mars-stroke-v": "", "fa-maxcdn": "", "fa-meanpath": "", "fa-medium": "", "fa-medkit": "", "fa-meetup": "", "fa-meh-o": "", "fa-mercury": "", "fa-microchip": "", "fa-microphone": "", "fa-microphone-slash": "", "fa-minus": "", "fa-minus-circle": "", "fa-minus-square": "", "fa-minus-square-o": "", "fa-mixcloud": "", "fa-mobile": "", "fa-mobile-phone": "", "fa-modx": "", "fa-money": "", "fa-moon-o": "", "fa-mortar-board": "", "fa-motorcycle": "", "fa-mouse-pointer": "", "fa-music": "", "fa-navicon": "", "fa-neuter": "", "fa-newspaper-o": "", "fa-object-group": "", "fa-object-ungroup": "", "fa-odnoklassniki": "", "fa-odnoklassniki-square": "", "fa-opencart": "", "fa-openid": "", "fa-opera": "", "fa-optin-monster": "", "fa-outdent": "", "fa-pagelines": "", "fa-paint-brush": "", "fa-paper-plane": "", "fa-paper-plane-o": "", "fa-paperclip": "", "fa-paragraph": "", "fa-paste": "", "fa-pause": "", "fa-pause-circle": "", "fa-pause-circle-o": "", "fa-paw": "", "fa-paypal": "", "fa-pencil": "", "fa-pencil-square": "", "fa-pencil-square-o": "", "fa-percent": "", "fa-phone": "", "fa-phone-square": "", "fa-photo": "", "fa-picture-o": "", "fa-pie-chart": "", "fa-pied-piper": "", "fa-pied-piper-alt": "", "fa-pied-piper-pp": "", "fa-pinterest": "", "fa-pinterest-p": "", "fa-pinterest-square": "", "fa-plane": "", "fa-play": "", "fa-play-circle": "", "fa-play-circle-o": "", "fa-plug": "", "fa-plus": "", "fa-plus-circle": "", "fa-plus-square": "", "fa-plus-square-o": "", "fa-podcast": "", "fa-power-off": "", "fa-print": "", "fa-product-hunt": "", "fa-puzzle-piece": "", "fa-qq": "", "fa-qrcode": "", "fa-question": "", "fa-question-circle": "", "fa-question-circle-o": "", "fa-quora": "", "fa-quote-left": "", "fa-quote-right": "", "fa-ra": "", "fa-random": "", "fa-ravelry": "", "fa-rebel": "", "fa-recycle": "", "fa-reddit": "", "fa-reddit-alien": "", "fa-reddit-square": "", "fa-refresh": "", "fa-registered": "", "fa-remove": "", "fa-renren": "", "fa-reorder": "", "fa-repeat": "", "fa-reply": "", "fa-reply-all": "", "fa-resistance": "", "fa-retweet": "", "fa-rmb": "", "fa-road": "", "fa-rocket": "", "fa-rotate-left": "", "fa-rotate-right": "", "fa-rouble": "", "fa-rss": "", "fa-rss-square": "", "fa-rub": "", "fa-ruble": "", "fa-rupee": "", "fa-s15": "", "fa-safari": "", "fa-save": "", "fa-scissors": "", "fa-scribd": "", "fa-search": "", "fa-search-minus": "", "fa-search-plus": "", "fa-sellsy": "", "fa-send": "", "fa-send-o": "", "fa-server": "", "fa-share": "", "fa-share-alt": "", "fa-share-alt-square": "", "fa-share-square": "", "fa-share-square-o": "", "fa-shekel": "", "fa-sheqel": "", "fa-shield": "", "fa-ship": "", "fa-shirtsinbulk": "", "fa-shopping-bag": "", "fa-shopping-basket": "", "fa-shopping-cart": "", "fa-shower": "", "fa-sign-in": "", "fa-sign-language": "", "fa-sign-out": "", "fa-signal": "", "fa-signing": "", "fa-simplybuilt": "", "fa-sitemap": "", "fa-skyatlas": "", "fa-skype": "", "fa-slack": "", "fa-sliders": "", "fa-slideshare": "", "fa-smile-o": "", "fa-snapchat": "", "fa-snapchat-ghost": "", "fa-snapchat-square": "", "fa-snowflake-o": "", "fa-soccer-ball-o": "", "fa-sort": "", "fa-sort-alpha-asc": "", "fa-sort-alpha-desc": "", "fa-sort-amount-asc": "", "fa-sort-amount-desc": "", "fa-sort-asc": "", "fa-sort-desc": "", "fa-sort-down": "", "fa-sort-numeric-asc": "", "fa-sort-numeric-desc": "", "fa-sort-up": "", "fa-soundcloud": "", "fa-space-shuttle": "", "fa-spinner": "", "fa-spoon": "", "fa-spotify": "", "fa-square": "", "fa-square-o": "", "fa-stack-exchange": "", "fa-stack-overflow": "", "fa-star": "", "fa-star-half": "", "fa-star-half-empty": "", "fa-star-half-full": "", "fa-star-half-o": "", "fa-star-o": "", "fa-steam": "", "fa-steam-square": "", "fa-step-backward": "", "fa-step-forward": "", "fa-stethoscope": "", "fa-sticky-note": "", "fa-sticky-note-o": "", "fa-stop": "", "fa-stop-circle": "", "fa-stop-circle-o": "", "fa-street-view": "", "fa-strikethrough": "", "fa-stumbleupon": "", "fa-stumbleupon-circle": "", "fa-subscript": "", "fa-subway": "", "fa-suitcase": "", "fa-sun-o": "", "fa-superpowers": "", "fa-superscript": "", "fa-support": "", "fa-table": "", "fa-tablet": "", "fa-tachometer": "", "fa-tag": "", "fa-tags": "", "fa-tasks": "", "fa-taxi": "", "fa-telegram": "", "fa-television": "", "fa-tencent-weibo": "", "fa-terminal": "", "fa-text-height": "", "fa-text-width": "", "fa-th": "", "fa-th-large": "", "fa-th-list": "", "fa-themeisle": "", "fa-thermometer": "", "fa-thermometer-0": "", "fa-thermometer-1": "", "fa-thermometer-2": "", "fa-thermometer-3": "", "fa-thermometer-4": "", "fa-thermometer-empty": "", "fa-thermometer-full": "", "fa-thermometer-half": "", "fa-thermometer-quarter": "", "fa-thermometer-three-quarters": "", "fa-thumb-tack": "", "fa-thumbs-down": "", "fa-thumbs-o-down": "", "fa-thumbs-o-up": "", "fa-thumbs-up": "", "fa-ticket": "", "fa-times": "", "fa-times-circle": "", "fa-times-circle-o": "", "fa-times-rectangle": "", "fa-times-rectangle-o": "", "fa-tint": "", "fa-toggle-down": "", "fa-toggle-left": "", "fa-toggle-off": "", "fa-toggle-on": "", "fa-toggle-right": "", "fa-toggle-up": "", "fa-trademark": "", "fa-train": "", "fa-transgender": "", "fa-transgender-alt": "", "fa-trash": "", "fa-trash-o": "", "fa-tree": "", "fa-trello": "", "fa-tripadvisor": "", "fa-trophy": "", "fa-truck": "", "fa-try": "", "fa-tty": "", "fa-tumblr": "", "fa-tumblr-square": "", "fa-turkish-lira": "", "fa-tv": "", "fa-twitch": "", "fa-twitter": "", "fa-twitter-square": "", "fa-umbrella": "", "fa-underline": "", "fa-undo": "", "fa-universal-access": "", "fa-university": "", "fa-unlink": "", "fa-unlock": "", "fa-unlock-alt": "", "fa-unsorted": "", "fa-upload": "", "fa-usb": "", "fa-usd": "", "fa-user": "", "fa-user-circle": "", "fa-user-circle-o": "", "fa-user-md": "", "fa-user-o": "", "fa-user-plus": "", "fa-user-secret": "", "fa-user-times": "", "fa-users": "", "fa-vcard": "", "fa-vcard-o": "", "fa-venus": "", "fa-venus-double": "", "fa-venus-mars": "", "fa-viacoin": "", "fa-viadeo": "", "fa-viadeo-square": "", "fa-video-camera": "", "fa-vimeo": "", "fa-vimeo-square": "", "fa-vine": "", "fa-vk": "", "fa-volume-control-phone": "", "fa-volume-down": "", "fa-volume-off": "", "fa-volume-up": "", "fa-warning": "", "fa-wechat": "", "fa-weibo": "", "fa-weixin": "", "fa-whatsapp": "", "fa-wheelchair": "", "fa-wheelchair-alt": "", "fa-wifi": "", "fa-wikipedia-w": "", "fa-window-close": "", "fa-window-close-o": "", "fa-window-maximize": "", "fa-window-minimize": "", "fa-window-restore": "", "fa-windows": "", "fa-won": "", "fa-wordpress": "", "fa-wpbeginner": "", "fa-wpexplorer": "", "fa-wpforms": "", "fa-wrench": "", "fa-xing": "", "fa-xing-square": "", "fa-y-combinator": "", "fa-y-combinator-square": "", "fa-yahoo": "", "fa-yc": "", "fa-yc-square": "", "fa-yelp": "", "fa-yen": "", "fa-yoast": "", "fa-youtube": "", "fa-youtube-play": "", "fa-youtube-square": "" };
289
- const faClassMap = {
290
- "fa-arrows": "fas fa-arrows-alt",
291
- "fa-address-book-o": "fa fa-address-book",
292
- "fa-address-card-o": "fa fa-address-card",
293
- "fa-arrow-circle-o-down": "fa fa-arrow-alt-circle-down",
294
- "fa-arrow-circle-o-left": "fa fa-arrow-alt-circle-left",
295
- "fa-arrow-circle-o-right": "fa fa-arrow-alt-circle-right",
296
- "fa-arrow-circle-o-up": "fa fa-arrow-alt-circle-up",
297
- "fa-arrows-h": "fas fa-arrows-alt-h",
298
- "fa-arrows-v": "fas fa-arrows-alt-v",
299
- "fa-bell-o": "fa fa-bell",
300
- "fa-bell-slash-o": "fa fa-bell-slash",
301
- "fa-bitbucket-square": "fab fa-bitbucket",
302
- "fa-bookmark-o": "fa fa-bookmark",
303
- "fa-building-o": "fa fa-building",
304
- "fa-check-circle-o": "fa fa-check-circle",
305
- "fa-check-square-o": "fa fa-check-square",
306
- "fa-circle-o": "fa fa-circle",
307
- "fa-circle-thin": "fa fa-circle",
308
- "fa-cloud-download": "fas fa-cloud-download-alt",
309
- "fa-cloud-upload": "fas fa-cloud-upload-alt",
310
- "fa-comment-o": "fa fa-comment",
311
- "fa-commenting-o": "fa fa-comment-dots",
312
- "fa-comments-o": "fa fa-comments",
313
- "fa-credit-card-alt": "fas fa-credit-card",
314
- "fa-cutlery": "fas fa-utensils",
315
- "fa-dashboard": "fas fa-tachometer-alt",
316
- "fa-diamond": "fa fa-gem",
317
- "fa-drivers-license-o": "fa fa-address-card",
318
- "fa-envelope-o": "fa fa-envelope",
319
- "fa-envelope-open-o": "fa fa-envelope-open",
320
- "fa-exchange": "fas fa-exchange-alt",
321
- "fa-external-link": "fas fa-external-link-alt",
322
- "fa-external-link-square": "fas fa-external-link-square-alt",
323
- "fa-facebook-official": "fab fa-facebook-square",
324
- "fa-file-o": "fa fa-file",
325
- "fa-file-text-o": "fa fa-file-alt",
326
- "fa-flag-o": "fa fa-flag",
327
- "fa-folder-o": "fa fa-folder",
328
- "fa-folder-open-o": "fa fa-folder-open",
329
- "fa-heart-o": "fa fa-heart",
330
- "fa-hourglass-o": "fa fa-hourglass",
331
- "fa-id-card-o": "fa fa-id-card",
332
- "fa-level-down": "fas fa-level-down-alt",
333
- "fa-level-up": "fas fa-level-up-alt",
334
- "fa-long-arrow-down": "fas fa-long-arrow-alt-down",
335
- "fa-long-arrow-left": "fas fa-long-arrow-alt-left",
336
- "fa-long-arrow-right": "fas fa-long-arrow-alt-right",
337
- "fa-long-arrow-up": "fas fa-long-arrow-alt-up",
338
- "fa-mail-reply": "fas fa-reply",
339
- "fa-map-o": "fa fa-map",
340
- "fa-meanpath": "fas fa-square",
341
- "fa-minus-square-o": "fa fa-minus-square",
342
- "fa-paper-plane-o": "fa fa-paper-plane",
343
- "fa-pause-circle-o": "fa fa-pause-circle",
344
- "fa-pencil": "fas fa-pencil-alt",
345
- "fa-play-circle-o": "fa fa-play-circle",
346
- "fa-plus-square-o": "fa fa-plus-square",
347
- "fa-question-circle-o": "fa fa-question-circle",
348
- "fa-reply": "fas fa-reply",
349
- "fa-send-o": "fa fa-paper-plane",
350
- "fa-share-square-o": "fa fa-share-square",
351
- "fa-shield": "fas fa-shield-alt",
352
- "fa-sign-in": "fas fa-sign-in-alt",
353
- "fa-sign-out": "fas fa-sign-out-alt",
354
- "fa-spoon": "fas fa-utensil-spoon",
355
- "fa-square-o": "fa fa-square",
356
- "fa-star-half-empty": "fa fa-star-half",
357
- "fa-star-half-full": "fas fa-star-half-alt",
358
- "fa-star-half-o": "fa fa-star-half",
359
- "fa-star-o": "fa fa-star",
360
- "fa-sticky-note-o": "fa fa-sticky-note",
361
- "fa-stop-circle-o": "fa fa-stop-circle",
362
- "fa-tachometer": "fas fa-tachometer-alt",
363
- "fa-thumbs-o-down": "fa fa-thumbs-down",
364
- "fa-thumbs-o-up": "fa fa-thumbs-up",
365
- "fa-ticket": "fas fa-ticket-alt",
366
- "fa-times-circle-o": "fa fa-times-circle",
367
- "fa-times-rectangle": "fas fa-window-close",
368
- "fa-times-rectangle-o": "fa fa-window-close",
369
- "fa-trash-o": "fa fa-trash-alt",
370
- "fa-user-circle-o": "fa fa-user-circle",
371
- "fa-user-o": "fa fa-user",
372
- "fa-vcard-o": "fa fa-address-card",
373
- "fa-wheelchair-alt": "fas fa-wheelchair",
374
- "fa-window-close": "fas fa-window-close",
375
- "fa-window-close-o": "fa fa-window-close",
376
- "fa-youtube-play": "fab fa-youtube",
377
- "fa-youtube-square": "fab fa-youtube-square"
378
- };
379
- export function faKeys(): string[] {
380
- return Object.keys(faCharMap);
381
- }
382
-
383
- export function fa5Class(key: string): string {
384
- return faClassMap[key] ? faClassMap[key] : key;
385
- }
386
-
387
- export function faChar(key: string, defChar: string = "fa-question"): string {
388
- if (key.indexOf("fa-") === 0) {
389
- return faCharMap[key] || faCharMap[defChar];
390
- }
391
- return key;
392
- }
393
-
394
- export function faCode(key: string): number {
395
- return faChar(key).charCodeAt(0);
396
- }
397
-
398
- let _removeHTMLFromStringDiv: HTMLDivElement;
399
- export function removeHTMLFromString(str: string, div?: HTMLDivElement) {
400
- if (div === undefined && _removeHTMLFromStringDiv === undefined) {
401
- _removeHTMLFromStringDiv = document.createElement("div");
402
- }
403
- div = div ?? _removeHTMLFromStringDiv;
404
- div.innerHTML = str;
405
- return div.textContent ?? div.innerText ?? "";
406
- }
407
-
408
- // Template ---
409
- // https://github.com/Matt-Esch/string-template (MIT)
410
- const nargs = /\{([0-9a-zA-Z_\s\[\]]+)\}/g;
411
- const nargs2 = /\{\{([0-9a-zA-Z_\s\[\]]+)\}\}/g;
412
-
413
- export function templateFields(tpl: string): string[] {
414
- if (!tpl) return [];
415
- const retVal: string[] = [];
416
- const matches = tpl.match(nargs);
417
- if (matches && matches.length) {
418
- for (const tplField of matches) {
419
- retVal.push(tplField.substring(1, tplField.length - 1));
420
- }
421
- }
422
- return retVal;
423
- }
424
-
425
- export function template(tpl?: string, _args?) {
426
- if (!tpl) return "";
427
- let args;
428
-
429
- if (arguments.length === 2 && typeof arguments[1] === "object") {
430
- args = arguments[1];
431
- } else {
432
- args = new Array(arguments.length - 1);
433
- for (let i = 1; i < arguments.length; ++i) {
434
- args[i - 1] = arguments[i];
435
- }
436
- }
437
-
438
- if (!args || !args.hasOwnProperty) {
439
- args = {};
440
- }
441
-
442
- // Array handling
443
- for (const key in args) {
444
- if (isArray(args[key])) {
445
- args[key].forEach(function (row, idx) {
446
- args[key + "[" + idx + "]"] = row;
447
- });
448
- }
449
- }
450
-
451
- return tpl
452
- .replace(nargs2, function replaceArg(match, i) {
453
- const result = args.hasOwnProperty(i) ? args[i] : null;
454
- if (result === null || result === undefined) {
455
- return match;
456
- }
457
- return removeHTMLFromString(result);
458
- })
459
- .replace(nargs, function replaceArg(match, i, index) {
460
- const result = args.hasOwnProperty(i) ? args[i] : null;
461
- if (result === null || result === undefined) {
462
- return "";
463
- }
464
- return result;
465
- })
466
- ;
467
- }
468
-
469
- export function naturalSort(data, order, idx, sortCaseSensitive) {
470
- return data.slice(0).sort(function (a, b) {
471
- return _naturalSort(a, b, order, idx, sortCaseSensitive);
472
- });
473
- }
474
-
475
- export function multiSort(data, sortBy) {
476
- if (sortBy && sortBy.length) {
477
- data.sort(function (l, r) {
478
- for (let i = 0; i < sortBy.length; ++i) {
479
- const lVal = l[sortBy[i].idx];
480
- const rVal = r[sortBy[i].idx];
481
- if (lVal !== rVal) {
482
- return sortBy[i].reverse ? d3Descending(lVal, rVal) : d3Ascending(lVal, rVal);
483
- }
484
- }
485
- return 0;
486
- });
487
- }
488
- return data;
489
- }
490
-
491
- export const Selection = SelectionBag;
492
-
493
- export function urlParams() {
494
- const retVal = {};
495
- const url = window.location.href;
496
- const idx = url.indexOf("?");
497
- if (idx >= 0) {
498
- url.substring(idx + 1).split("&").forEach(function (param) {
499
- const paramParts = param.split("=");
500
- switch (paramParts.length) {
501
- case 1:
502
- retVal[decodeURIComponent(paramParts[0])] = undefined;
503
- break;
504
- case 2:
505
- retVal[decodeURIComponent(paramParts[0])] = decodeURIComponent(paramParts[1]);
506
- break;
507
- default:
508
- throw new Error("Invalid URL Param: " + param);
509
- }
510
- });
511
- }
512
- return retVal;
513
- }
514
-
515
- export function endsWith(str: string, searchStr: string, pos?: number) {
516
- const subjectString = str.toString();
517
- if (typeof pos !== "number" || !isFinite(pos) || Math.floor(pos) !== pos || pos > subjectString.length) {
518
- pos = subjectString.length;
519
- }
520
- pos -= searchStr.length;
521
- const lastIndex = subjectString.indexOf(searchStr, pos);
522
- return lastIndex !== -1 && lastIndex === pos;
523
- }
524
-
525
- export function d3ArrayAdapter(array) {
526
- return {
527
- ownerDocument: {
528
- createElement(_tagName) {
529
- return {
530
- get __data__() { return this.row; },
531
- set __data__(_) { this.row = array[this.index] = _; }
532
- };
533
- },
534
-
535
- createElementNS(_ns, tagName) {
536
- return this.createElement(tagName);
537
- }
538
- },
539
-
540
- querySelectorAll(selectors) {
541
- if (selectors) throw new Error("unsupported");
542
- const context = this;
543
- return array.map(function (row, idx) {
544
- return {
545
- ownerDocument: context.ownerDocument,
546
- parentNode: context,
547
- get __data__() { return row; },
548
- set __data__(_) { array[idx] = _; }
549
- };
550
- });
551
- },
552
-
553
- appendChild(node) {
554
- node.parentNode = this;
555
- node.index = array.length;
556
- array.push(null);
557
- return node;
558
- },
559
-
560
- insertBefore(node, referenceNode) {
561
- const idx = array.indexOf(node.__data__);
562
- const refIdx = array.indexOf(referenceNode.__data__);
563
- if (idx > refIdx) {
564
- array.splice(refIdx, 0, array.splice(idx, 1)[0]);
565
- } else if (idx < refIdx - 1) {
566
- array.splice(refIdx - 1, 0, array.splice(idx, 1)[0]);
567
- }
568
- return node;
569
- },
570
-
571
- removeChild(node) {
572
- array.splice(array.indexOf(node.__data__), 1);
573
- return node;
574
- }
575
- };
576
- }
577
-
578
- export function downloadBlob(blob: Blob, filename: string) {
579
- let a = document.createElement("a");
580
- if (navigator["msSaveBlob"]) { // IE10+
581
- a = null;
582
- return navigator["msSaveBlob"](blob, filename);
583
- } else if ("download" in a) { // html 5
584
- a.href = URL.createObjectURL(blob);
585
- a.setAttribute("download", filename);
586
- document.body.appendChild(a);
587
- setTimeout(function () {
588
- a.click();
589
- document.body.removeChild(a);
590
- }, 10);
591
- return true;
592
- }
593
- }
594
-
595
- export function timestamp() {
596
- const currentdate = new Date();
597
- const timeFormat = d3TimeFormat("%Y-%m-%dT%H_%M_%S");
598
- return timeFormat(currentdate);
599
- }
600
-
601
- export function downloadString(format: "CSV" | "TSV" | "JSON" | "TEXT" | "SVG", blob: string, id?: string) {
602
- const filename = id || ("data_" + timestamp()) + "." + format.toLowerCase();
603
-
604
- let mimeType = "";
605
- switch (format) {
606
- case "TSV":
607
- mimeType = "text/tab-seperated-values";
608
- break;
609
- case "JSON":
610
- mimeType = "application/json";
611
- break;
612
- case "SVG":
613
- mimeType = "image/svg+xml";
614
- break;
615
- case "CSV":
616
- case "TEXT":
617
- default:
618
- mimeType = "text/csv";
619
- }
620
- downloadBlob(new Blob([blob], { type: mimeType }), filename);
621
- }
622
-
623
- export function widgetPath(classID) {
624
- return "../" + classID.split("_").join("/");
625
- }
626
-
627
- export function parseClassID(classID, prefix = "..") {
628
- const parts = classID.split(".");
629
- const classParts = parts[0].split("_");
630
- return {
631
- package: `@hpcc-js/${classParts[0]}`,
632
- path: prefix + "/" + parts[0].split("_").join("/"),
633
- widgetID: classParts.length > 1 ? classParts[1] : null,
634
- memberWidgetID: parts.length > 1 ? parts[1] : null
635
- };
636
- }
637
-
638
- export function checksum(s) {
639
- if (s instanceof Array) {
640
- s = s.join("") + s.length;
641
- }
642
- switch (typeof s) {
643
- case "string":
644
- break;
645
- default:
646
- s = "" + s;
647
- }
648
- let chk = 0x12345678;
649
- for (let i = 0, l = s.length; i < l; ++i) {
650
- chk += (s.charCodeAt(i) * (i + 1));
651
- }
652
- return (chk & 0xffffffff).toString(16);
653
- }
654
- export function getTime() {
655
- return (now && now.call(perf)) || (new Date().getTime());
656
- }
657
- export function mixin(dest, _sources) {
658
- dest = dest || {};
659
- for (let i = 1, l = arguments.length; i < l; i++) {
660
- _mixin(dest, arguments[i]);
661
- }
662
- return dest;
663
- }
664
-
665
- function _mixin(dest, source) {
666
- let s;
667
- const empty = {};
668
- for (const key in source) {
669
- s = source[key];
670
- if (!(key in dest) || (dest[key] !== s && (!(key in empty) || empty[key] !== s))) {
671
- dest[key] = s;
672
- }
673
- }
674
- return dest;
675
- }
676
-
677
- export function exists(prop, scope) {
678
- if (!prop || !scope) {
679
- return false;
680
- }
681
- const propParts = prop.split(".");
682
- let testScope = scope;
683
- for (let i = 0; i < propParts.length; ++i) {
684
- const item = propParts[i];
685
- if (testScope[item] === undefined) {
686
- return false;
687
- }
688
- testScope = testScope[item];
689
- }
690
- return true;
691
- }
692
-
693
- export function logStringify(obj) {
694
- const cache = [];
695
- return JSON.stringify(obj, function (_key, value) {
696
- if (typeof value === "object" && value !== null) {
697
- if (cache.indexOf(value) !== -1) {
698
- return;
699
- }
700
-
701
- cache.push(value);
702
- }
703
- return value;
704
- });
705
- }
706
-
707
- export function debounce(func, threshold = 100, execAsap = false) {
708
- return function debounced(..._dummyArgs) {
709
- const obj = this || {};
710
- const args = arguments;
711
- function delayed() {
712
- if (!execAsap)
713
- func.apply(obj, args);
714
- obj.__hpcc_debounce_timeout = null;
715
- }
716
- if (obj.__hpcc_debounce_timeout)
717
- clearTimeout(obj.__hpcc_debounce_timeout);
718
- else if (execAsap)
719
- func.apply(obj, args);
720
- obj.__hpcc_debounce_timeout = setTimeout(delayed, threshold);
721
- };
722
- }
723
-
724
- export function parseVersionString(versionString) {
725
- const _sp = versionString.split(".");
726
- return {
727
- major: parseInt(_sp[0].replace("v", "")),
728
- minor: parseInt(_sp[1]),
729
- patch: parseInt(_sp[2].split("-")[0])
730
- };
731
- }
732
-
733
- export type TextSize = { width: number; height: number; };
734
- let g_fontSizeContext: CanvasRenderingContext2D;
735
- const g_fontSizeContextCache: { [key: string]: TextSize } = {};
736
-
737
- export function textSize(_text: string | string[], fontName: string = "Verdana", fontSize: number = 12, bold: boolean = false): Readonly<TextSize> {
738
- g_fontSizeContext = globalCanvasContext();
739
- const text = _text instanceof Array ? _text : [_text];
740
- const hash = `${bold}::${fontSize}::${fontName}::${text.join("::")}`;
741
- let retVal = g_fontSizeContextCache[hash];
742
- if (!retVal) {
743
- retVal = { width: 0, height: 0 };
744
- g_fontSizeContext.font = `${bold ? "bold " : ""}${fontSize}px ${fontName}`;
745
- text.forEach(line => {
746
- const textMeasurement = g_fontSizeContext.measureText("" + line);
747
- const width = textMeasurement.width;
748
- const height = (textMeasurement.fontBoundingBoxDescent + textMeasurement.fontBoundingBoxAscent) * text.length;
749
- g_fontSizeContextCache[hash] = retVal = {
750
- width: width > retVal.width ? width : retVal.width,
751
- height: height > retVal.height ? height : retVal.height
752
- };
753
- });
754
- }
755
- return retVal;
756
- }
757
-
758
- export type TextRect = { width: number; height: number; top: number; right: number; bottom: number; left: number; };
759
- let g_fontCanvas;
760
- const g_fontRectContextCache: { [key: string]: TextRect } = {};
761
- export function textRect(text: string, fontName: string = "Verdana", fontSize: number = 12, bold: boolean = false): Readonly<TextRect> {
762
- // This function is relatively expensive and should be used conservatively
763
- g_fontCanvas = globalCanvasElement();
764
- g_fontSizeContext = globalCanvasContext();
765
- const hash = `${bold}::${fontSize}::${fontName}::${text}`;
766
- let retVal = g_fontRectContextCache[hash];
767
- if (!retVal) {
768
- const font = `${bold ? "bold " : ""}${fontSize}px '${fontName}'`;
769
- g_fontSizeContext.font = font;
770
- const m = g_fontSizeContext.measureText(text);
771
- const w = g_fontCanvas.width = Math.ceil(m.width);
772
- const h = g_fontCanvas.height = fontSize * 1.5;
773
- const canvas = document.createElement("canvas");
774
- canvas.width = w;
775
- canvas.height = h;
776
- g_fontSizeContext.font = font;
777
- g_fontSizeContext.fillStyle = "black";
778
- g_fontSizeContext.textAlign = "start";
779
- g_fontSizeContext.textBaseline = "top";
780
- g_fontSizeContext.fillText(text, 0, 0);
781
-
782
- let top, right, bottom, left = 0;
783
- if (w > 0) {
784
- const data = g_fontSizeContext.getImageData(0, 0, w, h).data;
785
- for (let y = 0; y < h; y++) {
786
- for (let x = 0; x < w; x++) {
787
- const i = (x + y * w) * 4;
788
- if (data[i + 3] !== 0) {
789
- if (top === undefined) {
790
- top = y;
791
- }
792
- if (left === undefined || left > x) {
793
- left = x;
794
- }
795
- if (right === undefined || right < x) {
796
- right = x;
797
- }
798
- bottom = y;
799
- }
800
- }
801
- }
802
- }
803
- retVal = {
804
- width: right - left + 1,
805
- height: bottom - top + 1,
806
- top,
807
- right,
808
- bottom,
809
- left
810
- };
811
- g_fontRectContextCache[hash] = retVal;
812
- }
813
- return retVal;
814
- }
815
-
816
- function globalCanvasElement() {
817
- if (!g_fontCanvas) {
818
- g_fontCanvas = document.getElementById("hpcc_js_font_size");
819
- if (!g_fontCanvas) {
820
- g_fontCanvas = document.createElement("canvas");
821
- g_fontCanvas.id = "hpcc_js_font_size";
822
- document.body.appendChild(g_fontCanvas);
823
- }
824
- }
825
- return g_fontCanvas;
826
- }
827
-
828
- function globalCanvasContext() {
829
- if (!g_fontSizeContext) {
830
- g_fontCanvas = globalCanvasElement();
831
- g_fontSizeContext = (g_fontCanvas as HTMLCanvasElement).getContext("2d");
832
- }
833
- return g_fontSizeContext;
834
- }
835
-
836
- export function safeRaise(domNode: Element) {
837
- const target = domNode;
838
- let nextSibling = target.nextSibling;
839
- while (nextSibling) {
840
- target.parentNode.insertBefore(nextSibling, target);
841
- nextSibling = target.nextSibling;
842
- }
843
- }
1
+ import { isArray } from "@hpcc-js/util";
2
+ import { ascending as d3Ascending, descending as d3Descending } from "d3-array";
3
+ import { select as d3Select, Selection as d3SelectionT } from "d3-selection";
4
+ import { timeFormat as d3TimeFormat } from "d3-time-format";
5
+
6
+ function _naturalSort(a, b, order, idx, sortCaseSensitive) {
7
+ const re = /(^([+\-]?(?:0|[1-9]\d*)(?:\.\d*)?(?:[eE][+\-]?\d+)?)?$|^0x[0-9a-f]+$|\d+)/gi;
8
+ const sre = /(^[ ]*|[ ]*$)/g;
9
+ const dre = /(^([\w ]+,?[\w ]+)?[\w ]+,?[\w ]+\d+:\d+(:\d+)?[\w ]?|^\d{1,4}[\/\-]\d{1,4}[\/\-]\d{1,4}|^\w+, \w+ \d+, \d{4})/;
10
+ const ore = /^0/;
11
+ const i = function (s) { return !sortCaseSensitive && ("" + s).toLowerCase() || "" + s; };
12
+ // convert all to strings strip whitespace
13
+ const x = i(idx ? a[idx] : a).replace(sre, "") || "";
14
+ const y = i(idx ? b[idx] : b).replace(sre, "") || "";
15
+ // chunk/tokenize
16
+ const xN = x.replace(re, "\0$1\0").replace(/\0$/, "").replace(/^\0/, "").split("\0");
17
+ const yN = y.replace(re, "\0$1\0").replace(/\0$/, "").replace(/^\0/, "").split("\0");
18
+ // numeric or date detection
19
+ const xD = (xN.length !== 1 && x.match(dre) && Date.parse(x));
20
+ const yD = xD && y.match(dre) && Date.parse(y) || null;
21
+ let oFxNcL;
22
+ let oFyNcL;
23
+ // first try and sort Hex codes or Dates
24
+ if (yD) {
25
+ if (xD < yD) {
26
+ return order === "ascending" ? -1 : 1;
27
+ } else if (xD > yD) {
28
+ return order === "ascending" ? 1 : -1;
29
+ }
30
+ }
31
+ // natural sorting through split numeric strings and default strings
32
+ for (let cLoc = 0, numS = Math.max(xN.length, yN.length); cLoc < numS; cLoc++) {
33
+ // find floats not starting with "0", string or 0 if not defined (Clint Priest)
34
+ oFxNcL = !(xN[cLoc] || "").match(ore) && parseFloat(xN[cLoc]) || xN[cLoc] || 0;
35
+ oFyNcL = !(yN[cLoc] || "").match(ore) && parseFloat(yN[cLoc]) || yN[cLoc] || 0;
36
+ // handle numeric vs string comparison - number < string - (Kyle Adams)
37
+ if (isNaN(oFxNcL) !== isNaN(oFyNcL)) {
38
+ return (isNaN(oFxNcL)) ? 1 : -1;
39
+ } else if (typeof oFxNcL !== typeof oFyNcL) {
40
+ // rely on string comparison if different types - i.e. "02" < 2 != "02" < "2"
41
+ oFxNcL += "";
42
+ oFyNcL += "";
43
+ }
44
+ if (oFxNcL < oFyNcL) { return order === "ascending" ? -1 : 1; }
45
+ if (oFxNcL > oFyNcL) { return order === "ascending" ? 1 : -1; }
46
+ }
47
+ return 0;
48
+ }
49
+
50
+ // Selection Bag(s) ---
51
+ export class SelectionBase {
52
+ protected __widget;
53
+ private __svgGlowID: string;
54
+
55
+ constructor(widget) {
56
+ // Can't import Widget or SVGWidget as it breaks AMD loading...
57
+ this.__widget = widget;
58
+ }
59
+
60
+ svgGlowID(): string {
61
+ if (this.__svgGlowID === undefined) {
62
+ this.__svgGlowID = this.__widget.svgGlowID && this.__widget.svgGlowID() || "";
63
+ }
64
+ return this.__svgGlowID;
65
+ }
66
+ }
67
+
68
+ export interface ISelectionItem {
69
+ _id: string;
70
+ element(): d3SelectionT<Element, any, Element, any>;
71
+ }
72
+
73
+ export class SelectionBag extends SelectionBase {
74
+ items: { [key: string]: ISelectionItem };
75
+ constructor(widget) {
76
+ super(widget);
77
+ this.items = {};
78
+ }
79
+
80
+ clear() {
81
+ for (const key in this.items) {
82
+ this.items[key].element()
83
+ .classed("selected", false)
84
+ .attr("filter", null)
85
+ ;
86
+ }
87
+ this.items = {};
88
+ }
89
+
90
+ isEmpty() {
91
+ for (const _key in this.items) { // jshint ignore:line
92
+ return false;
93
+ }
94
+ return true;
95
+ }
96
+
97
+ append(item: ISelectionItem) {
98
+ this.items[item._id] = item;
99
+ item.element()
100
+ .classed("selected", true)
101
+ .attr("filter", this.svgGlowID() ? `url(#${this.svgGlowID()})` : null)
102
+ ;
103
+ }
104
+
105
+ remove(item: ISelectionItem) {
106
+ this.items[item._id].element()
107
+ .classed("selected", false)
108
+ .attr("filter", null)
109
+ ;
110
+ delete this.items[item._id];
111
+ }
112
+
113
+ isSelected(item: ISelectionItem) {
114
+ return this.items[item._id] !== undefined;
115
+ }
116
+
117
+ get() {
118
+ const retVal = [];
119
+ for (const key in this.items) {
120
+ retVal.push(this.items[key]);
121
+ }
122
+ return retVal;
123
+ }
124
+
125
+ set(itemArray: ISelectionItem[]) {
126
+ this.clear();
127
+ itemArray.forEach(function (item) {
128
+ this.append(item);
129
+ }, this);
130
+ }
131
+
132
+ click = function (item: ISelectionItem, evt) {
133
+ if (evt.ctrlKey) {
134
+ if (this.items[item._id]) {
135
+ this.remove(item);
136
+ } else {
137
+ this.append(item);
138
+ }
139
+ } else {
140
+ this.clear();
141
+ this.append(item);
142
+ }
143
+ };
144
+ }
145
+
146
+ export class SimpleSelection extends SelectionBase {
147
+ constructor(widget, widgetElement, skipBringToTop?) {
148
+ super(widget);
149
+ this.widgetElement(widgetElement);
150
+ this.skipBringToTop(skipBringToTop);
151
+ }
152
+
153
+ _widgetElement;
154
+ widgetElement(_?) {
155
+ if (!arguments.length) return this._widgetElement;
156
+ this._widgetElement = _;
157
+ return this;
158
+ }
159
+
160
+ _skipBringToTop;
161
+ skipBringToTop(_?) {
162
+ if (!arguments.length) return this._skipBringToTop;
163
+ this._skipBringToTop = _;
164
+ return this;
165
+ }
166
+
167
+ _initialSelection: (d) => boolean;
168
+ enter(elements) {
169
+ const context = this;
170
+ elements
171
+ .each(function (d) {
172
+ const selected: boolean = context._initialSelection ? context._initialSelection(d.data) : false;
173
+ d3Select(this)
174
+ .classed("selected", selected)
175
+ .classed("deselected", !selected)
176
+ .attr("filter", context.svgGlowID() && selected ? `url(#${context.svgGlowID()})` : null)
177
+ ;
178
+ })
179
+ .on("click.SimpleSelection", function () {
180
+ context.click(this);
181
+ })
182
+ .on("mouseover.SimpleSelection", function () {
183
+ context.mouseOver(this);
184
+ })
185
+ .on("mouseout.SimpleSelection", function () {
186
+ context.mouseOut(this);
187
+ })
188
+ ;
189
+ }
190
+ click(domNode): boolean {
191
+ if (!this._skipBringToTop) {
192
+ domNode.parentNode.appendChild(domNode);
193
+ }
194
+ const element = d3Select(domNode);
195
+ const wasSelected = element.classed("selected");
196
+ this._widgetElement.selectAll(".selected")
197
+ .classed("selected", false)
198
+ .classed("deselected", true)
199
+ .attr("filter", null)
200
+ ;
201
+ if (!wasSelected) {
202
+ element
203
+ .classed("selected", true)
204
+ .classed("deselected", false)
205
+ .attr("filter", this.svgGlowID() ? `url(#${this.svgGlowID()})` : null)
206
+ ;
207
+ }
208
+ return !wasSelected;
209
+ }
210
+ mouseOver(domNode) {
211
+ d3Select(domNode)
212
+ .classed("over", true)
213
+ ;
214
+ }
215
+ mouseOut(domNode) {
216
+ d3Select(domNode)
217
+ .classed("over", null)
218
+ ;
219
+ }
220
+ selected(domNode) {
221
+ return d3Select(domNode).classed("selected");
222
+ }
223
+ selection(_?) {
224
+ if (!arguments.length) {
225
+ return this.selection2().map(row => JSON.stringify(row));
226
+ }
227
+ this.selection2(d => _.indexOf(JSON.stringify(d)) >= 0);
228
+ return this;
229
+ }
230
+ selection2(): any[];
231
+ selection2(isSelected: (d) => boolean): this;
232
+ selection2(isSelected?: (d) => boolean): any[] | this {
233
+ if (!arguments.length) {
234
+ const retVal: any[] = [];
235
+ if (this._widgetElement) {
236
+ this._widgetElement.selectAll(".selected")
237
+ .each(d => retVal.push(d))
238
+ ;
239
+ }
240
+ return retVal;
241
+ }
242
+ if (this._widgetElement) {
243
+ const context = this;
244
+ this._widgetElement.selectAll(".selected,.deselected")
245
+ .each(function (d) {
246
+ const selected = isSelected(d);
247
+ d3Select(this)
248
+ .classed("selected", selected)
249
+ .classed("deselected", !selected)
250
+ .attr("filter", (selected && context.svgGlowID()) ? `url(#${context.svgGlowID()})` : null)
251
+ ;
252
+ if (selected && !context._skipBringToTop) {
253
+ safeRaise(this);
254
+ }
255
+ })
256
+ ;
257
+ } else {
258
+ this._initialSelection = isSelected;
259
+ }
260
+ return this;
261
+ }
262
+ }
263
+
264
+ export function SimpleSelectionMixin(skipBringToTop) {
265
+ this._selection = new SimpleSelection(this, null, skipBringToTop);
266
+ }
267
+
268
+ SimpleSelectionMixin.prototype.serializeState = function () {
269
+ return {
270
+ selection: this._selection.selection(),
271
+ data: this.data()
272
+ };
273
+ };
274
+
275
+ SimpleSelectionMixin.prototype.deserializeState = function (state) {
276
+ if (state) {
277
+ this._selection.selection(state.selection);
278
+ if (state.data) {
279
+ this.data(state.data);
280
+ }
281
+ }
282
+ return this;
283
+ };
284
+
285
+ const perf: any = window.performance;
286
+ const now = perf && (perf.now || perf.mozNow || perf.msNow || perf.oNow || perf.webkitNow);
287
+
288
+ const faCharMap = { "fa-500px": "", "fa-address-book": "", "fa-address-book-o": "", "fa-address-card": "", "fa-address-card-o": "", "fa-adjust": "", "fa-adn": "", "fa-align-center": "", "fa-align-justify": "", "fa-align-left": "", "fa-align-right": "", "fa-amazon": "", "fa-ambulance": "", "fa-american-sign-language-interpreting": "", "fa-anchor": "", "fa-android": "", "fa-angellist": "", "fa-angle-double-down": "", "fa-angle-double-left": "", "fa-angle-double-right": "", "fa-angle-double-up": "", "fa-angle-down": "", "fa-angle-left": "", "fa-angle-right": "", "fa-angle-up": "", "fa-apple": "", "fa-archive": "", "fa-area-chart": "", "fa-arrow-circle-down": "", "fa-arrow-circle-left": "", "fa-arrow-circle-o-down": "", "fa-arrow-circle-o-left": "", "fa-arrow-circle-o-right": "", "fa-arrow-circle-o-up": "", "fa-arrow-circle-right": "", "fa-arrow-circle-up": "", "fa-arrow-down": "", "fa-arrow-left": "", "fa-arrow-right": "", "fa-arrow-up": "", "fa-arrows": "", "fa-arrows-alt": "", "fa-arrows-h": "", "fa-arrows-v": "", "fa-asl-interpreting": "", "fa-assistive-listening-systems": "", "fa-asterisk": "", "fa-at": "", "fa-audio-description": "", "fa-automobile": "", "fa-backward": "", "fa-balance-scale": "", "fa-ban": "", "fa-bandcamp": "", "fa-bank": "", "fa-bar-chart": "", "fa-bar-chart-o": "", "fa-barcode": "", "fa-bars": "", "fa-bath": "", "fa-bathtub": "", "fa-battery": "", "fa-battery-0": "", "fa-battery-1": "", "fa-battery-2": "", "fa-battery-3": "", "fa-battery-4": "", "fa-battery-empty": "", "fa-battery-full": "", "fa-battery-half": "", "fa-battery-quarter": "", "fa-battery-three-quarters": "", "fa-bed": "", "fa-beer": "", "fa-behance": "", "fa-behance-square": "", "fa-bell": "", "fa-bell-o": "", "fa-bell-slash": "", "fa-bell-slash-o": "", "fa-bicycle": "", "fa-binoculars": "", "fa-birthday-cake": "", "fa-bitbucket": "", "fa-bitbucket-square": "", "fa-bitcoin": "", "fa-black-tie": "", "fa-blind": "", "fa-bluetooth": "", "fa-bluetooth-b": "", "fa-bold": "", "fa-bolt": "", "fa-bomb": "", "fa-book": "", "fa-bookmark": "", "fa-bookmark-o": "", "fa-braille": "", "fa-briefcase": "", "fa-btc": "", "fa-bug": "", "fa-building": "", "fa-building-o": "", "fa-bullhorn": "", "fa-bullseye": "", "fa-bus": "", "fa-buysellads": "", "fa-cab": "", "fa-calculator": "", "fa-calendar": "", "fa-calendar-check-o": "", "fa-calendar-minus-o": "", "fa-calendar-o": "", "fa-calendar-plus-o": "", "fa-calendar-times-o": "", "fa-camera": "", "fa-camera-retro": "", "fa-car": "", "fa-caret-down": "", "fa-caret-left": "", "fa-caret-right": "", "fa-caret-square-o-down": "", "fa-caret-square-o-left": "", "fa-caret-square-o-right": "", "fa-caret-square-o-up": "", "fa-caret-up": "", "fa-cart-arrow-down": "", "fa-cart-plus": "", "fa-cc": "", "fa-cc-amex": "", "fa-cc-diners-club": "", "fa-cc-discover": "", "fa-cc-jcb": "", "fa-cc-mastercard": "", "fa-cc-paypal": "", "fa-cc-stripe": "", "fa-cc-visa": "", "fa-certificate": "", "fa-chain": "", "fa-chain-broken": "", "fa-check": "", "fa-check-circle": "", "fa-check-circle-o": "", "fa-check-square": "", "fa-check-square-o": "", "fa-chevron-circle-down": "", "fa-chevron-circle-left": "", "fa-chevron-circle-right": "", "fa-chevron-circle-up": "", "fa-chevron-down": "", "fa-chevron-left": "", "fa-chevron-right": "", "fa-chevron-up": "", "fa-child": "", "fa-chrome": "", "fa-circle": "", "fa-circle-o": "", "fa-circle-o-notch": "", "fa-circle-thin": "", "fa-clipboard": "", "fa-clock-o": "", "fa-clone": "", "fa-close": "", "fa-cloud": "", "fa-cloud-download": "", "fa-cloud-upload": "", "fa-cny": "", "fa-code": "", "fa-code-fork": "", "fa-codepen": "", "fa-codiepie": "", "fa-coffee": "", "fa-cog": "", "fa-cogs": "", "fa-columns": "", "fa-comment": "", "fa-comment-o": "", "fa-commenting": "", "fa-commenting-o": "", "fa-comments": "", "fa-comments-o": "", "fa-compass": "", "fa-compress": "", "fa-connectdevelop": "", "fa-contao": "", "fa-copy": "", "fa-copyright": "", "fa-creative-commons": "", "fa-credit-card": "", "fa-credit-card-alt": "", "fa-crop": "", "fa-crosshairs": "", "fa-css3": "", "fa-cube": "", "fa-cubes": "", "fa-cut": "", "fa-cutlery": "", "fa-dashboard": "", "fa-dashcube": "", "fa-database": "", "fa-deaf": "", "fa-deafness": "", "fa-dedent": "", "fa-delicious": "", "fa-desktop": "", "fa-deviantart": "", "fa-diamond": "", "fa-digg": "", "fa-dollar": "", "fa-dot-circle-o": "", "fa-download": "", "fa-dribbble": "", "fa-drivers-license": "", "fa-drivers-license-o": "", "fa-dropbox": "", "fa-drupal": "", "fa-edge": "", "fa-edit": "", "fa-eercast": "", "fa-eject": "", "fa-ellipsis-h": "", "fa-ellipsis-v": "", "fa-empire": "", "fa-envelope": "", "fa-envelope-o": "", "fa-envelope-open": "", "fa-envelope-open-o": "", "fa-envelope-square": "", "fa-envira": "", "fa-eraser": "", "fa-etsy": "", "fa-eur": "", "fa-euro": "", "fa-exchange": "", "fa-exclamation": "", "fa-exclamation-circle": "", "fa-exclamation-triangle": "", "fa-expand": "", "fa-expeditedssl": "", "fa-external-link": "", "fa-external-link-square": "", "fa-eye": "", "fa-eye-slash": "", "fa-eyedropper": "", "fa-fa": "", "fa-facebook": "", "fa-facebook-f": "", "fa-facebook-official": "", "fa-facebook-square": "", "fa-fast-backward": "", "fa-fast-forward": "", "fa-fax": "", "fa-feed": "", "fa-female": "", "fa-fighter-jet": "", "fa-file": "", "fa-file-archive-o": "", "fa-file-audio-o": "", "fa-file-code-o": "", "fa-file-excel-o": "", "fa-file-image-o": "", "fa-file-movie-o": "", "fa-file-o": "", "fa-file-pdf-o": "", "fa-file-photo-o": "", "fa-file-picture-o": "", "fa-file-powerpoint-o": "", "fa-file-sound-o": "", "fa-file-text": "", "fa-file-text-o": "", "fa-file-video-o": "", "fa-file-word-o": "", "fa-file-zip-o": "", "fa-files-o": "", "fa-film": "", "fa-filter": "", "fa-fire": "", "fa-fire-extinguisher": "", "fa-firefox": "", "fa-first-order": "", "fa-flag": "", "fa-flag-checkered": "", "fa-flag-o": "", "fa-flash": "", "fa-flask": "", "fa-flickr": "", "fa-floppy-o": "", "fa-folder": "", "fa-folder-o": "", "fa-folder-open": "", "fa-folder-open-o": "", "fa-font": "", "fa-font-awesome": "", "fa-fonticons": "", "fa-fort-awesome": "", "fa-forumbee": "", "fa-forward": "", "fa-foursquare": "", "fa-free-code-camp": "", "fa-frown-o": "", "fa-futbol-o": "", "fa-gamepad": "", "fa-gavel": "", "fa-gbp": "", "fa-ge": "", "fa-gear": "", "fa-gears": "", "fa-genderless": "", "fa-get-pocket": "", "fa-gg": "", "fa-gg-circle": "", "fa-gift": "", "fa-git": "", "fa-git-square": "", "fa-github": "", "fa-github-alt": "", "fa-github-square": "", "fa-gitlab": "", "fa-gittip": "", "fa-glass": "", "fa-glide": "", "fa-glide-g": "", "fa-globe": "", "fa-google": "", "fa-google-plus": "", "fa-google-plus-circle": "", "fa-google-plus-official": "", "fa-google-plus-square": "", "fa-google-wallet": "", "fa-graduation-cap": "", "fa-gratipay": "", "fa-grav": "", "fa-group": "", "fa-h-square": "", "fa-hacker-news": "", "fa-hand-grab-o": "", "fa-hand-lizard-o": "", "fa-hand-o-down": "", "fa-hand-o-left": "", "fa-hand-o-right": "", "fa-hand-o-up": "", "fa-hand-paper-o": "", "fa-hand-peace-o": "", "fa-hand-pointer-o": "", "fa-hand-rock-o": "", "fa-hand-scissors-o": "", "fa-hand-spock-o": "", "fa-hand-stop-o": "", "fa-handshake-o": "", "fa-hard-of-hearing": "", "fa-hashtag": "", "fa-hdd-o": "", "fa-header": "", "fa-headphones": "", "fa-heart": "", "fa-heart-o": "", "fa-heartbeat": "", "fa-history": "", "fa-home": "", "fa-hospital-o": "", "fa-hotel": "", "fa-hourglass": "", "fa-hourglass-1": "", "fa-hourglass-2": "", "fa-hourglass-3": "", "fa-hourglass-end": "", "fa-hourglass-half": "", "fa-hourglass-o": "", "fa-hourglass-start": "", "fa-houzz": "", "fa-html5": "", "fa-i-cursor": "", "fa-id-badge": "", "fa-id-card": "", "fa-id-card-o": "", "fa-ils": "", "fa-image": "", "fa-imdb": "", "fa-inbox": "", "fa-indent": "", "fa-industry": "", "fa-info": "", "fa-info-circle": "", "fa-inr": "", "fa-instagram": "", "fa-institution": "", "fa-internet-explorer": "", "fa-intersex": "", "fa-ioxhost": "", "fa-italic": "", "fa-joomla": "", "fa-jpy": "", "fa-jsfiddle": "", "fa-key": "", "fa-keyboard-o": "", "fa-krw": "", "fa-language": "", "fa-laptop": "", "fa-lastfm": "", "fa-lastfm-square": "", "fa-leaf": "", "fa-leanpub": "", "fa-legal": "", "fa-lemon-o": "", "fa-level-down": "", "fa-level-up": "", "fa-life-bouy": "", "fa-life-buoy": "", "fa-life-ring": "", "fa-life-saver": "", "fa-lightbulb-o": "", "fa-line-chart": "", "fa-link": "", "fa-linkedin": "", "fa-linkedin-square": "", "fa-linode": "", "fa-linux": "", "fa-list": "", "fa-list-alt": "", "fa-list-ol": "", "fa-list-ul": "", "fa-location-arrow": "", "fa-lock": "", "fa-long-arrow-down": "", "fa-long-arrow-left": "", "fa-long-arrow-right": "", "fa-long-arrow-up": "", "fa-low-vision": "", "fa-magic": "", "fa-magnet": "", "fa-mail-forward": "", "fa-mail-reply": "", "fa-mail-reply-all": "", "fa-male": "", "fa-map": "", "fa-map-marker": "", "fa-map-o": "", "fa-map-pin": "", "fa-map-signs": "", "fa-mars": "", "fa-mars-double": "", "fa-mars-stroke": "", "fa-mars-stroke-h": "", "fa-mars-stroke-v": "", "fa-maxcdn": "", "fa-meanpath": "", "fa-medium": "", "fa-medkit": "", "fa-meetup": "", "fa-meh-o": "", "fa-mercury": "", "fa-microchip": "", "fa-microphone": "", "fa-microphone-slash": "", "fa-minus": "", "fa-minus-circle": "", "fa-minus-square": "", "fa-minus-square-o": "", "fa-mixcloud": "", "fa-mobile": "", "fa-mobile-phone": "", "fa-modx": "", "fa-money": "", "fa-moon-o": "", "fa-mortar-board": "", "fa-motorcycle": "", "fa-mouse-pointer": "", "fa-music": "", "fa-navicon": "", "fa-neuter": "", "fa-newspaper-o": "", "fa-object-group": "", "fa-object-ungroup": "", "fa-odnoklassniki": "", "fa-odnoklassniki-square": "", "fa-opencart": "", "fa-openid": "", "fa-opera": "", "fa-optin-monster": "", "fa-outdent": "", "fa-pagelines": "", "fa-paint-brush": "", "fa-paper-plane": "", "fa-paper-plane-o": "", "fa-paperclip": "", "fa-paragraph": "", "fa-paste": "", "fa-pause": "", "fa-pause-circle": "", "fa-pause-circle-o": "", "fa-paw": "", "fa-paypal": "", "fa-pencil": "", "fa-pencil-square": "", "fa-pencil-square-o": "", "fa-percent": "", "fa-phone": "", "fa-phone-square": "", "fa-photo": "", "fa-picture-o": "", "fa-pie-chart": "", "fa-pied-piper": "", "fa-pied-piper-alt": "", "fa-pied-piper-pp": "", "fa-pinterest": "", "fa-pinterest-p": "", "fa-pinterest-square": "", "fa-plane": "", "fa-play": "", "fa-play-circle": "", "fa-play-circle-o": "", "fa-plug": "", "fa-plus": "", "fa-plus-circle": "", "fa-plus-square": "", "fa-plus-square-o": "", "fa-podcast": "", "fa-power-off": "", "fa-print": "", "fa-product-hunt": "", "fa-puzzle-piece": "", "fa-qq": "", "fa-qrcode": "", "fa-question": "", "fa-question-circle": "", "fa-question-circle-o": "", "fa-quora": "", "fa-quote-left": "", "fa-quote-right": "", "fa-ra": "", "fa-random": "", "fa-ravelry": "", "fa-rebel": "", "fa-recycle": "", "fa-reddit": "", "fa-reddit-alien": "", "fa-reddit-square": "", "fa-refresh": "", "fa-registered": "", "fa-remove": "", "fa-renren": "", "fa-reorder": "", "fa-repeat": "", "fa-reply": "", "fa-reply-all": "", "fa-resistance": "", "fa-retweet": "", "fa-rmb": "", "fa-road": "", "fa-rocket": "", "fa-rotate-left": "", "fa-rotate-right": "", "fa-rouble": "", "fa-rss": "", "fa-rss-square": "", "fa-rub": "", "fa-ruble": "", "fa-rupee": "", "fa-s15": "", "fa-safari": "", "fa-save": "", "fa-scissors": "", "fa-scribd": "", "fa-search": "", "fa-search-minus": "", "fa-search-plus": "", "fa-sellsy": "", "fa-send": "", "fa-send-o": "", "fa-server": "", "fa-share": "", "fa-share-alt": "", "fa-share-alt-square": "", "fa-share-square": "", "fa-share-square-o": "", "fa-shekel": "", "fa-sheqel": "", "fa-shield": "", "fa-ship": "", "fa-shirtsinbulk": "", "fa-shopping-bag": "", "fa-shopping-basket": "", "fa-shopping-cart": "", "fa-shower": "", "fa-sign-in": "", "fa-sign-language": "", "fa-sign-out": "", "fa-signal": "", "fa-signing": "", "fa-simplybuilt": "", "fa-sitemap": "", "fa-skyatlas": "", "fa-skype": "", "fa-slack": "", "fa-sliders": "", "fa-slideshare": "", "fa-smile-o": "", "fa-snapchat": "", "fa-snapchat-ghost": "", "fa-snapchat-square": "", "fa-snowflake-o": "", "fa-soccer-ball-o": "", "fa-sort": "", "fa-sort-alpha-asc": "", "fa-sort-alpha-desc": "", "fa-sort-amount-asc": "", "fa-sort-amount-desc": "", "fa-sort-asc": "", "fa-sort-desc": "", "fa-sort-down": "", "fa-sort-numeric-asc": "", "fa-sort-numeric-desc": "", "fa-sort-up": "", "fa-soundcloud": "", "fa-space-shuttle": "", "fa-spinner": "", "fa-spoon": "", "fa-spotify": "", "fa-square": "", "fa-square-o": "", "fa-stack-exchange": "", "fa-stack-overflow": "", "fa-star": "", "fa-star-half": "", "fa-star-half-empty": "", "fa-star-half-full": "", "fa-star-half-o": "", "fa-star-o": "", "fa-steam": "", "fa-steam-square": "", "fa-step-backward": "", "fa-step-forward": "", "fa-stethoscope": "", "fa-sticky-note": "", "fa-sticky-note-o": "", "fa-stop": "", "fa-stop-circle": "", "fa-stop-circle-o": "", "fa-street-view": "", "fa-strikethrough": "", "fa-stumbleupon": "", "fa-stumbleupon-circle": "", "fa-subscript": "", "fa-subway": "", "fa-suitcase": "", "fa-sun-o": "", "fa-superpowers": "", "fa-superscript": "", "fa-support": "", "fa-table": "", "fa-tablet": "", "fa-tachometer": "", "fa-tag": "", "fa-tags": "", "fa-tasks": "", "fa-taxi": "", "fa-telegram": "", "fa-television": "", "fa-tencent-weibo": "", "fa-terminal": "", "fa-text-height": "", "fa-text-width": "", "fa-th": "", "fa-th-large": "", "fa-th-list": "", "fa-themeisle": "", "fa-thermometer": "", "fa-thermometer-0": "", "fa-thermometer-1": "", "fa-thermometer-2": "", "fa-thermometer-3": "", "fa-thermometer-4": "", "fa-thermometer-empty": "", "fa-thermometer-full": "", "fa-thermometer-half": "", "fa-thermometer-quarter": "", "fa-thermometer-three-quarters": "", "fa-thumb-tack": "", "fa-thumbs-down": "", "fa-thumbs-o-down": "", "fa-thumbs-o-up": "", "fa-thumbs-up": "", "fa-ticket": "", "fa-times": "", "fa-times-circle": "", "fa-times-circle-o": "", "fa-times-rectangle": "", "fa-times-rectangle-o": "", "fa-tint": "", "fa-toggle-down": "", "fa-toggle-left": "", "fa-toggle-off": "", "fa-toggle-on": "", "fa-toggle-right": "", "fa-toggle-up": "", "fa-trademark": "", "fa-train": "", "fa-transgender": "", "fa-transgender-alt": "", "fa-trash": "", "fa-trash-o": "", "fa-tree": "", "fa-trello": "", "fa-tripadvisor": "", "fa-trophy": "", "fa-truck": "", "fa-try": "", "fa-tty": "", "fa-tumblr": "", "fa-tumblr-square": "", "fa-turkish-lira": "", "fa-tv": "", "fa-twitch": "", "fa-twitter": "", "fa-twitter-square": "", "fa-umbrella": "", "fa-underline": "", "fa-undo": "", "fa-universal-access": "", "fa-university": "", "fa-unlink": "", "fa-unlock": "", "fa-unlock-alt": "", "fa-unsorted": "", "fa-upload": "", "fa-usb": "", "fa-usd": "", "fa-user": "", "fa-user-circle": "", "fa-user-circle-o": "", "fa-user-md": "", "fa-user-o": "", "fa-user-plus": "", "fa-user-secret": "", "fa-user-times": "", "fa-users": "", "fa-vcard": "", "fa-vcard-o": "", "fa-venus": "", "fa-venus-double": "", "fa-venus-mars": "", "fa-viacoin": "", "fa-viadeo": "", "fa-viadeo-square": "", "fa-video-camera": "", "fa-vimeo": "", "fa-vimeo-square": "", "fa-vine": "", "fa-vk": "", "fa-volume-control-phone": "", "fa-volume-down": "", "fa-volume-off": "", "fa-volume-up": "", "fa-warning": "", "fa-wechat": "", "fa-weibo": "", "fa-weixin": "", "fa-whatsapp": "", "fa-wheelchair": "", "fa-wheelchair-alt": "", "fa-wifi": "", "fa-wikipedia-w": "", "fa-window-close": "", "fa-window-close-o": "", "fa-window-maximize": "", "fa-window-minimize": "", "fa-window-restore": "", "fa-windows": "", "fa-won": "", "fa-wordpress": "", "fa-wpbeginner": "", "fa-wpexplorer": "", "fa-wpforms": "", "fa-wrench": "", "fa-xing": "", "fa-xing-square": "", "fa-y-combinator": "", "fa-y-combinator-square": "", "fa-yahoo": "", "fa-yc": "", "fa-yc-square": "", "fa-yelp": "", "fa-yen": "", "fa-yoast": "", "fa-youtube": "", "fa-youtube-play": "", "fa-youtube-square": "" };
289
+ const faClassMap = {
290
+ "fa-arrows": "fas fa-arrows-alt",
291
+ "fa-address-book-o": "fa fa-address-book",
292
+ "fa-address-card-o": "fa fa-address-card",
293
+ "fa-arrow-circle-o-down": "fa fa-arrow-alt-circle-down",
294
+ "fa-arrow-circle-o-left": "fa fa-arrow-alt-circle-left",
295
+ "fa-arrow-circle-o-right": "fa fa-arrow-alt-circle-right",
296
+ "fa-arrow-circle-o-up": "fa fa-arrow-alt-circle-up",
297
+ "fa-arrows-h": "fas fa-arrows-alt-h",
298
+ "fa-arrows-v": "fas fa-arrows-alt-v",
299
+ "fa-bell-o": "fa fa-bell",
300
+ "fa-bell-slash-o": "fa fa-bell-slash",
301
+ "fa-bitbucket-square": "fab fa-bitbucket",
302
+ "fa-bookmark-o": "fa fa-bookmark",
303
+ "fa-building-o": "fa fa-building",
304
+ "fa-check-circle-o": "fa fa-check-circle",
305
+ "fa-check-square-o": "fa fa-check-square",
306
+ "fa-circle-o": "fa fa-circle",
307
+ "fa-circle-thin": "fa fa-circle",
308
+ "fa-cloud-download": "fas fa-cloud-download-alt",
309
+ "fa-cloud-upload": "fas fa-cloud-upload-alt",
310
+ "fa-comment-o": "fa fa-comment",
311
+ "fa-commenting-o": "fa fa-comment-dots",
312
+ "fa-comments-o": "fa fa-comments",
313
+ "fa-credit-card-alt": "fas fa-credit-card",
314
+ "fa-cutlery": "fas fa-utensils",
315
+ "fa-dashboard": "fas fa-tachometer-alt",
316
+ "fa-diamond": "fa fa-gem",
317
+ "fa-drivers-license-o": "fa fa-address-card",
318
+ "fa-envelope-o": "fa fa-envelope",
319
+ "fa-envelope-open-o": "fa fa-envelope-open",
320
+ "fa-exchange": "fas fa-exchange-alt",
321
+ "fa-external-link": "fas fa-external-link-alt",
322
+ "fa-external-link-square": "fas fa-external-link-square-alt",
323
+ "fa-facebook-official": "fab fa-facebook-square",
324
+ "fa-file-o": "fa fa-file",
325
+ "fa-file-text-o": "fa fa-file-alt",
326
+ "fa-flag-o": "fa fa-flag",
327
+ "fa-folder-o": "fa fa-folder",
328
+ "fa-folder-open-o": "fa fa-folder-open",
329
+ "fa-heart-o": "fa fa-heart",
330
+ "fa-hourglass-o": "fa fa-hourglass",
331
+ "fa-id-card-o": "fa fa-id-card",
332
+ "fa-level-down": "fas fa-level-down-alt",
333
+ "fa-level-up": "fas fa-level-up-alt",
334
+ "fa-long-arrow-down": "fas fa-long-arrow-alt-down",
335
+ "fa-long-arrow-left": "fas fa-long-arrow-alt-left",
336
+ "fa-long-arrow-right": "fas fa-long-arrow-alt-right",
337
+ "fa-long-arrow-up": "fas fa-long-arrow-alt-up",
338
+ "fa-mail-reply": "fas fa-reply",
339
+ "fa-map-o": "fa fa-map",
340
+ "fa-meanpath": "fas fa-square",
341
+ "fa-minus-square-o": "fa fa-minus-square",
342
+ "fa-paper-plane-o": "fa fa-paper-plane",
343
+ "fa-pause-circle-o": "fa fa-pause-circle",
344
+ "fa-pencil": "fas fa-pencil-alt",
345
+ "fa-play-circle-o": "fa fa-play-circle",
346
+ "fa-plus-square-o": "fa fa-plus-square",
347
+ "fa-question-circle-o": "fa fa-question-circle",
348
+ "fa-reply": "fas fa-reply",
349
+ "fa-send-o": "fa fa-paper-plane",
350
+ "fa-share-square-o": "fa fa-share-square",
351
+ "fa-shield": "fas fa-shield-alt",
352
+ "fa-sign-in": "fas fa-sign-in-alt",
353
+ "fa-sign-out": "fas fa-sign-out-alt",
354
+ "fa-spoon": "fas fa-utensil-spoon",
355
+ "fa-square-o": "fa fa-square",
356
+ "fa-star-half-empty": "fa fa-star-half",
357
+ "fa-star-half-full": "fas fa-star-half-alt",
358
+ "fa-star-half-o": "fa fa-star-half",
359
+ "fa-star-o": "fa fa-star",
360
+ "fa-sticky-note-o": "fa fa-sticky-note",
361
+ "fa-stop-circle-o": "fa fa-stop-circle",
362
+ "fa-tachometer": "fas fa-tachometer-alt",
363
+ "fa-thumbs-o-down": "fa fa-thumbs-down",
364
+ "fa-thumbs-o-up": "fa fa-thumbs-up",
365
+ "fa-ticket": "fas fa-ticket-alt",
366
+ "fa-times-circle-o": "fa fa-times-circle",
367
+ "fa-times-rectangle": "fas fa-window-close",
368
+ "fa-times-rectangle-o": "fa fa-window-close",
369
+ "fa-trash-o": "fa fa-trash-alt",
370
+ "fa-user-circle-o": "fa fa-user-circle",
371
+ "fa-user-o": "fa fa-user",
372
+ "fa-vcard-o": "fa fa-address-card",
373
+ "fa-wheelchair-alt": "fas fa-wheelchair",
374
+ "fa-window-close": "fas fa-window-close",
375
+ "fa-window-close-o": "fa fa-window-close",
376
+ "fa-youtube-play": "fab fa-youtube",
377
+ "fa-youtube-square": "fab fa-youtube-square"
378
+ };
379
+ export function faKeys(): string[] {
380
+ return Object.keys(faCharMap);
381
+ }
382
+
383
+ export function fa5Class(key: string): string {
384
+ return faClassMap[key] ? faClassMap[key] : key;
385
+ }
386
+
387
+ export function faChar(key: string, defChar: string = "fa-question"): string {
388
+ if (key.indexOf("fa-") === 0) {
389
+ return faCharMap[key] || faCharMap[defChar];
390
+ }
391
+ return key;
392
+ }
393
+
394
+ export function faCode(key: string): number {
395
+ return faChar(key).charCodeAt(0);
396
+ }
397
+
398
+ let _removeHTMLFromStringDiv: HTMLDivElement;
399
+ export function removeHTMLFromString(str: string, div?: HTMLDivElement) {
400
+ if (div === undefined && _removeHTMLFromStringDiv === undefined) {
401
+ _removeHTMLFromStringDiv = document.createElement("div");
402
+ }
403
+ div = div ?? _removeHTMLFromStringDiv;
404
+ div.innerHTML = str;
405
+ return div.textContent ?? div.innerText ?? "";
406
+ }
407
+
408
+ // Template ---
409
+ // https://github.com/Matt-Esch/string-template (MIT)
410
+ const nargs = /\{([0-9a-zA-Z_\s\[\]]+)\}/g;
411
+ const nargs2 = /\{\{([0-9a-zA-Z_\s\[\]]+)\}\}/g;
412
+
413
+ export function templateFields(tpl: string): string[] {
414
+ if (!tpl) return [];
415
+ const retVal: string[] = [];
416
+ const matches = tpl.match(nargs);
417
+ if (matches && matches.length) {
418
+ for (const tplField of matches) {
419
+ retVal.push(tplField.substring(1, tplField.length - 1));
420
+ }
421
+ }
422
+ return retVal;
423
+ }
424
+
425
+ export function template(tpl?: string, _args?) {
426
+ if (!tpl) return "";
427
+ let args;
428
+
429
+ if (arguments.length === 2 && typeof arguments[1] === "object") {
430
+ args = arguments[1];
431
+ } else {
432
+ args = new Array(arguments.length - 1);
433
+ for (let i = 1; i < arguments.length; ++i) {
434
+ args[i - 1] = arguments[i];
435
+ }
436
+ }
437
+
438
+ if (!args || !args.hasOwnProperty) {
439
+ args = {};
440
+ }
441
+
442
+ // Array handling
443
+ for (const key in args) {
444
+ if (isArray(args[key])) {
445
+ args[key].forEach(function (row, idx) {
446
+ args[key + "[" + idx + "]"] = row;
447
+ });
448
+ }
449
+ }
450
+
451
+ return tpl
452
+ .replace(nargs2, function replaceArg(match, i) {
453
+ const result = args.hasOwnProperty(i) ? args[i] : null;
454
+ if (result === null || result === undefined) {
455
+ return match;
456
+ }
457
+ return removeHTMLFromString(result);
458
+ })
459
+ .replace(nargs, function replaceArg(match, i, index) {
460
+ const result = args.hasOwnProperty(i) ? args[i] : null;
461
+ if (result === null || result === undefined) {
462
+ return "";
463
+ }
464
+ return result;
465
+ })
466
+ ;
467
+ }
468
+
469
+ export function naturalSort(data, order, idx, sortCaseSensitive) {
470
+ return data.slice(0).sort(function (a, b) {
471
+ return _naturalSort(a, b, order, idx, sortCaseSensitive);
472
+ });
473
+ }
474
+
475
+ export function multiSort(data, sortBy) {
476
+ if (sortBy && sortBy.length) {
477
+ data.sort(function (l, r) {
478
+ for (let i = 0; i < sortBy.length; ++i) {
479
+ const lVal = l[sortBy[i].idx];
480
+ const rVal = r[sortBy[i].idx];
481
+ if (lVal !== rVal) {
482
+ return sortBy[i].reverse ? d3Descending(lVal, rVal) : d3Ascending(lVal, rVal);
483
+ }
484
+ }
485
+ return 0;
486
+ });
487
+ }
488
+ return data;
489
+ }
490
+
491
+ export const Selection = SelectionBag;
492
+
493
+ export function urlParams() {
494
+ const retVal = {};
495
+ const url = window.location.href;
496
+ const idx = url.indexOf("?");
497
+ if (idx >= 0) {
498
+ url.substring(idx + 1).split("&").forEach(function (param) {
499
+ const paramParts = param.split("=");
500
+ switch (paramParts.length) {
501
+ case 1:
502
+ retVal[decodeURIComponent(paramParts[0])] = undefined;
503
+ break;
504
+ case 2:
505
+ retVal[decodeURIComponent(paramParts[0])] = decodeURIComponent(paramParts[1]);
506
+ break;
507
+ default:
508
+ throw new Error("Invalid URL Param: " + param);
509
+ }
510
+ });
511
+ }
512
+ return retVal;
513
+ }
514
+
515
+ export function endsWith(str: string, searchStr: string, pos?: number) {
516
+ const subjectString = str.toString();
517
+ if (typeof pos !== "number" || !isFinite(pos) || Math.floor(pos) !== pos || pos > subjectString.length) {
518
+ pos = subjectString.length;
519
+ }
520
+ pos -= searchStr.length;
521
+ const lastIndex = subjectString.indexOf(searchStr, pos);
522
+ return lastIndex !== -1 && lastIndex === pos;
523
+ }
524
+
525
+ export function d3ArrayAdapter(array) {
526
+ return {
527
+ ownerDocument: {
528
+ createElement(_tagName) {
529
+ return {
530
+ get __data__() { return this.row; },
531
+ set __data__(_) { this.row = array[this.index] = _; }
532
+ };
533
+ },
534
+
535
+ createElementNS(_ns, tagName) {
536
+ return this.createElement(tagName);
537
+ }
538
+ },
539
+
540
+ querySelectorAll(selectors) {
541
+ if (selectors) throw new Error("unsupported");
542
+ const context = this;
543
+ return array.map(function (row, idx) {
544
+ return {
545
+ ownerDocument: context.ownerDocument,
546
+ parentNode: context,
547
+ get __data__() { return row; },
548
+ set __data__(_) { array[idx] = _; }
549
+ };
550
+ });
551
+ },
552
+
553
+ appendChild(node) {
554
+ node.parentNode = this;
555
+ node.index = array.length;
556
+ array.push(null);
557
+ return node;
558
+ },
559
+
560
+ insertBefore(node, referenceNode) {
561
+ const idx = array.indexOf(node.__data__);
562
+ const refIdx = array.indexOf(referenceNode.__data__);
563
+ if (idx > refIdx) {
564
+ array.splice(refIdx, 0, array.splice(idx, 1)[0]);
565
+ } else if (idx < refIdx - 1) {
566
+ array.splice(refIdx - 1, 0, array.splice(idx, 1)[0]);
567
+ }
568
+ return node;
569
+ },
570
+
571
+ removeChild(node) {
572
+ array.splice(array.indexOf(node.__data__), 1);
573
+ return node;
574
+ }
575
+ };
576
+ }
577
+
578
+ export function downloadBlob(blob: Blob, filename: string) {
579
+ let a = document.createElement("a");
580
+ if (navigator["msSaveBlob"]) { // IE10+
581
+ a = null;
582
+ return navigator["msSaveBlob"](blob, filename);
583
+ } else if ("download" in a) { // html 5
584
+ a.href = URL.createObjectURL(blob);
585
+ a.setAttribute("download", filename);
586
+ document.body.appendChild(a);
587
+ setTimeout(function () {
588
+ a.click();
589
+ document.body.removeChild(a);
590
+ }, 10);
591
+ return true;
592
+ }
593
+ }
594
+
595
+ export function timestamp() {
596
+ const currentdate = new Date();
597
+ const timeFormat = d3TimeFormat("%Y-%m-%dT%H_%M_%S");
598
+ return timeFormat(currentdate);
599
+ }
600
+
601
+ export function downloadString(format: "CSV" | "TSV" | "JSON" | "TEXT" | "SVG", blob: string, id?: string) {
602
+ const filename = id || ("data_" + timestamp()) + "." + format.toLowerCase();
603
+
604
+ let mimeType = "";
605
+ switch (format) {
606
+ case "TSV":
607
+ mimeType = "text/tab-seperated-values";
608
+ break;
609
+ case "JSON":
610
+ mimeType = "application/json";
611
+ break;
612
+ case "SVG":
613
+ mimeType = "image/svg+xml";
614
+ break;
615
+ case "CSV":
616
+ case "TEXT":
617
+ default:
618
+ mimeType = "text/csv";
619
+ }
620
+ downloadBlob(new Blob([blob], { type: mimeType }), filename);
621
+ }
622
+
623
+ export function widgetPath(classID) {
624
+ return "../" + classID.split("_").join("/");
625
+ }
626
+
627
+ export function parseClassID(classID, prefix = "..") {
628
+ const parts = classID.split(".");
629
+ const classParts = parts[0].split("_");
630
+ return {
631
+ package: `@hpcc-js/${classParts[0]}`,
632
+ path: prefix + "/" + parts[0].split("_").join("/"),
633
+ widgetID: classParts.length > 1 ? classParts[1] : null,
634
+ memberWidgetID: parts.length > 1 ? parts[1] : null
635
+ };
636
+ }
637
+
638
+ export function checksum(s) {
639
+ if (s instanceof Array) {
640
+ s = s.join("") + s.length;
641
+ }
642
+ switch (typeof s) {
643
+ case "string":
644
+ break;
645
+ default:
646
+ s = "" + s;
647
+ }
648
+ let chk = 0x12345678;
649
+ for (let i = 0, l = s.length; i < l; ++i) {
650
+ chk += (s.charCodeAt(i) * (i + 1));
651
+ }
652
+ return (chk & 0xffffffff).toString(16);
653
+ }
654
+ export function getTime() {
655
+ return (now && now.call(perf)) || (new Date().getTime());
656
+ }
657
+ export function mixin(dest, _sources) {
658
+ dest = dest || {};
659
+ for (let i = 1, l = arguments.length; i < l; i++) {
660
+ _mixin(dest, arguments[i]);
661
+ }
662
+ return dest;
663
+ }
664
+
665
+ function _mixin(dest, source) {
666
+ let s;
667
+ const empty = {};
668
+ for (const key in source) {
669
+ s = source[key];
670
+ if (!(key in dest) || (dest[key] !== s && (!(key in empty) || empty[key] !== s))) {
671
+ dest[key] = s;
672
+ }
673
+ }
674
+ return dest;
675
+ }
676
+
677
+ export function exists(prop, scope) {
678
+ if (!prop || !scope) {
679
+ return false;
680
+ }
681
+ const propParts = prop.split(".");
682
+ let testScope = scope;
683
+ for (let i = 0; i < propParts.length; ++i) {
684
+ const item = propParts[i];
685
+ if (testScope[item] === undefined) {
686
+ return false;
687
+ }
688
+ testScope = testScope[item];
689
+ }
690
+ return true;
691
+ }
692
+
693
+ export function logStringify(obj) {
694
+ const cache = [];
695
+ return JSON.stringify(obj, function (_key, value) {
696
+ if (typeof value === "object" && value !== null) {
697
+ if (cache.indexOf(value) !== -1) {
698
+ return;
699
+ }
700
+
701
+ cache.push(value);
702
+ }
703
+ return value;
704
+ });
705
+ }
706
+
707
+ export function debounce(func, threshold = 100, execAsap = false) {
708
+ return function debounced(..._dummyArgs) {
709
+ const obj = this || {};
710
+ const args = arguments;
711
+ function delayed() {
712
+ if (!execAsap)
713
+ func.apply(obj, args);
714
+ obj.__hpcc_debounce_timeout = null;
715
+ }
716
+ if (obj.__hpcc_debounce_timeout)
717
+ clearTimeout(obj.__hpcc_debounce_timeout);
718
+ else if (execAsap)
719
+ func.apply(obj, args);
720
+ obj.__hpcc_debounce_timeout = setTimeout(delayed, threshold);
721
+ };
722
+ }
723
+
724
+ export function parseVersionString(versionString) {
725
+ const _sp = versionString.split(".");
726
+ return {
727
+ major: parseInt(_sp[0].replace("v", "")),
728
+ minor: parseInt(_sp[1]),
729
+ patch: parseInt(_sp[2].split("-")[0])
730
+ };
731
+ }
732
+
733
+ export type TextSize = { width: number; height: number; };
734
+ let g_fontSizeContext: CanvasRenderingContext2D;
735
+ const g_fontSizeContextCache: { [key: string]: TextSize } = {};
736
+
737
+ export function textSize(_text: string | string[], fontName: string = "Verdana", fontSize: number = 12, bold: boolean = false): Readonly<TextSize> {
738
+ g_fontSizeContext = globalCanvasContext();
739
+ const text = _text instanceof Array ? _text : [_text];
740
+ const hash = `${bold}::${fontSize}::${fontName}::${text.join("::")}`;
741
+ let retVal = g_fontSizeContextCache[hash];
742
+ if (!retVal) {
743
+ retVal = { width: 0, height: 0 };
744
+ g_fontSizeContext.font = `${bold ? "bold " : ""}${fontSize}px ${fontName}`;
745
+ text.forEach(line => {
746
+ const textMeasurement = g_fontSizeContext.measureText("" + line);
747
+ const width = textMeasurement.width;
748
+ const height = (textMeasurement.fontBoundingBoxDescent + textMeasurement.fontBoundingBoxAscent) * text.length;
749
+ g_fontSizeContextCache[hash] = retVal = {
750
+ width: width > retVal.width ? width : retVal.width,
751
+ height: height > retVal.height ? height : retVal.height
752
+ };
753
+ });
754
+ }
755
+ return retVal;
756
+ }
757
+
758
+ export type TextRect = { width: number; height: number; top: number; right: number; bottom: number; left: number; };
759
+ let g_fontCanvas;
760
+ const g_fontRectContextCache: { [key: string]: TextRect } = {};
761
+ export function textRect(text: string, fontName: string = "Verdana", fontSize: number = 12, bold: boolean = false): Readonly<TextRect> {
762
+ // This function is relatively expensive and should be used conservatively
763
+ g_fontCanvas = globalCanvasElement();
764
+ g_fontSizeContext = globalCanvasContext();
765
+ const hash = `${bold}::${fontSize}::${fontName}::${text}`;
766
+ let retVal = g_fontRectContextCache[hash];
767
+ if (!retVal) {
768
+ const font = `${bold ? "bold " : ""}${fontSize}px '${fontName}'`;
769
+ g_fontSizeContext.font = font;
770
+ const m = g_fontSizeContext.measureText(text);
771
+ const w = g_fontCanvas.width = Math.ceil(m.width);
772
+ const h = g_fontCanvas.height = fontSize * 1.5;
773
+ const canvas = document.createElement("canvas");
774
+ canvas.width = w;
775
+ canvas.height = h;
776
+ g_fontSizeContext.font = font;
777
+ g_fontSizeContext.fillStyle = "black";
778
+ g_fontSizeContext.textAlign = "start";
779
+ g_fontSizeContext.textBaseline = "top";
780
+ g_fontSizeContext.fillText(text, 0, 0);
781
+
782
+ let top, right, bottom, left = 0;
783
+ if (w > 0) {
784
+ const data = g_fontSizeContext.getImageData(0, 0, w, h).data;
785
+ for (let y = 0; y < h; y++) {
786
+ for (let x = 0; x < w; x++) {
787
+ const i = (x + y * w) * 4;
788
+ if (data[i + 3] !== 0) {
789
+ if (top === undefined) {
790
+ top = y;
791
+ }
792
+ if (left === undefined || left > x) {
793
+ left = x;
794
+ }
795
+ if (right === undefined || right < x) {
796
+ right = x;
797
+ }
798
+ bottom = y;
799
+ }
800
+ }
801
+ }
802
+ }
803
+ retVal = {
804
+ width: right - left + 1,
805
+ height: bottom - top + 1,
806
+ top,
807
+ right,
808
+ bottom,
809
+ left
810
+ };
811
+ g_fontRectContextCache[hash] = retVal;
812
+ }
813
+ return retVal;
814
+ }
815
+
816
+ function globalCanvasElement() {
817
+ if (!g_fontCanvas) {
818
+ g_fontCanvas = document.getElementById("hpcc_js_font_size");
819
+ if (!g_fontCanvas) {
820
+ g_fontCanvas = document.createElement("canvas");
821
+ g_fontCanvas.id = "hpcc_js_font_size";
822
+ document.body.appendChild(g_fontCanvas);
823
+ }
824
+ }
825
+ return g_fontCanvas;
826
+ }
827
+
828
+ function globalCanvasContext() {
829
+ if (!g_fontSizeContext) {
830
+ g_fontCanvas = globalCanvasElement();
831
+ g_fontSizeContext = (g_fontCanvas as HTMLCanvasElement).getContext("2d");
832
+ }
833
+ return g_fontSizeContext;
834
+ }
835
+
836
+ export function safeRaise(domNode: Element) {
837
+ const target = domNode;
838
+ let nextSibling = target.nextSibling;
839
+ while (nextSibling) {
840
+ target.parentNode.insertBefore(nextSibling, target);
841
+ nextSibling = target.nextSibling;
842
+ }
843
+ }