@hpcc-js/common 3.7.3 → 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.
- package/LICENSE +43 -43
- package/README.md +59 -59
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/index.umd.cjs +1 -1
- package/dist/index.umd.cjs.map +1 -1
- package/package.json +5 -5
- package/src/CanvasWidget.ts +31 -31
- package/src/Class.ts +72 -72
- package/src/Database.ts +860 -860
- package/src/Entity.ts +235 -235
- package/src/EntityCard.ts +66 -66
- package/src/EntityPin.ts +103 -103
- package/src/EntityRect.css +15 -15
- package/src/EntityRect.ts +254 -254
- package/src/EntityVertex.ts +86 -86
- package/src/FAChar.css +2 -2
- package/src/FAChar.ts +89 -89
- package/src/HTMLWidget.ts +191 -191
- package/src/IList.ts +4 -4
- package/src/IMenu.ts +5 -5
- package/src/Icon.css +9 -9
- package/src/Icon.ts +176 -176
- package/src/Image.ts +104 -104
- package/src/List.css +12 -12
- package/src/List.ts +102 -102
- package/src/Menu.css +22 -22
- package/src/Menu.ts +139 -139
- package/src/Palette.ts +341 -341
- package/src/Platform.ts +125 -125
- package/src/ProgressBar.ts +115 -115
- package/src/PropertyExt.ts +770 -770
- package/src/ResizeSurface.css +38 -38
- package/src/ResizeSurface.ts +225 -225
- package/src/SVGWidget.ts +583 -583
- package/src/SVGZoomWidget.css +11 -11
- package/src/SVGZoomWidget.ts +427 -427
- package/src/Shape.css +3 -3
- package/src/Shape.ts +186 -186
- package/src/Surface.css +39 -39
- package/src/Surface.ts +364 -364
- package/src/Text.css +3 -3
- package/src/Text.ts +131 -131
- package/src/TextBox.css +3 -3
- package/src/TextBox.ts +183 -183
- package/src/TitleBar.css +114 -114
- package/src/TitleBar.ts +407 -407
- package/src/Transition.ts +45 -45
- package/src/Utility.ts +843 -843
- package/src/Widget.css +7 -7
- package/src/Widget.ts +731 -731
- package/src/WidgetArray.ts +15 -15
- package/src/__package__.ts +3 -3
- 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
|
+
}
|