@linkurious/ogma-linkurious-parser 4.1.6 → 4.1.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (46) hide show
  1. package/dist/index.cjs +4 -0
  2. package/dist/index.cjs.map +1 -0
  3. package/dist/index.d.ts +5 -5
  4. package/dist/index.mjs +4082 -0
  5. package/dist/index.mjs.map +1 -0
  6. package/dist/ogma/features/nodeGrouping.d.ts +15 -1
  7. package/dist/tools/ogmaTool.d.ts +3 -1
  8. package/package.json +23 -21
  9. package/dist/captions/captions.js +0 -115
  10. package/dist/captions/captions.js.map +0 -1
  11. package/dist/filters/filters.js +0 -167
  12. package/dist/filters/filters.js.map +0 -1
  13. package/dist/index.js +0 -56
  14. package/dist/index.js.map +0 -1
  15. package/dist/ogma/features/OgmaStore.js +0 -37
  16. package/dist/ogma/features/OgmaStore.js.map +0 -1
  17. package/dist/ogma/features/captions.js +0 -117
  18. package/dist/ogma/features/captions.js.map +0 -1
  19. package/dist/ogma/features/nodeGrouping.js +0 -283
  20. package/dist/ogma/features/nodeGrouping.js.map +0 -1
  21. package/dist/ogma/features/reactive.js +0 -132
  22. package/dist/ogma/features/reactive.js.map +0 -1
  23. package/dist/ogma/features/selectors.js +0 -97
  24. package/dist/ogma/features/selectors.js.map +0 -1
  25. package/dist/ogma/features/styles.js +0 -689
  26. package/dist/ogma/features/styles.js.map +0 -1
  27. package/dist/ogma/features/transformations.js +0 -86
  28. package/dist/ogma/features/transformations.js.map +0 -1
  29. package/dist/ogma/index.js +0 -326
  30. package/dist/ogma/index.js.map +0 -1
  31. package/dist/styles/edgeAttributes.js +0 -115
  32. package/dist/styles/edgeAttributes.js.map +0 -1
  33. package/dist/styles/itemAttributes.js +0 -133
  34. package/dist/styles/itemAttributes.js.map +0 -1
  35. package/dist/styles/nodeAttributes.js +0 -228
  36. package/dist/styles/nodeAttributes.js.map +0 -1
  37. package/dist/styles/styleRule.js +0 -194
  38. package/dist/styles/styleRule.js.map +0 -1
  39. package/dist/styles/styleRules.js +0 -292
  40. package/dist/styles/styleRules.js.map +0 -1
  41. package/dist/tools/colorPalette.js +0 -145
  42. package/dist/tools/colorPalette.js.map +0 -1
  43. package/dist/tools/ogmaTool.js +0 -86
  44. package/dist/tools/ogmaTool.js.map +0 -1
  45. package/dist/tools/tools.js +0 -409
  46. package/dist/tools/tools.js.map +0 -1
@@ -1,409 +0,0 @@
1
- 'use strict';
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
5
- Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.Tools = exports.CAPTION_HEURISTIC = exports.sortBy = void 0;
7
- const isEqual_1 = __importDefault(require("lodash/isEqual"));
8
- const sortBy_1 = __importDefault(require("lodash/sortBy"));
9
- exports.sortBy = sortBy_1.default;
10
- const rest_client_1 = require("@linkurious/rest-client");
11
- const IMAGE_PATTERN = /\S+\.(gif|jpe?g|tiff|png|bmp|svg)$/i;
12
- exports.CAPTION_HEURISTIC = [
13
- 'label',
14
- 'Label',
15
- 'name',
16
- 'Name',
17
- 'title',
18
- 'Title',
19
- 'rdfs:label'
20
- ];
21
- class Tools {
22
- static isEqual(v1, v2) {
23
- return (0, isEqual_1.default)(v1, v2);
24
- }
25
- /**
26
- * Check that a value is defined : not null and not undefined
27
- *
28
- * @param {any} value
29
- * @return {boolean}
30
- */
31
- static isDefined(value) {
32
- return value !== undefined && value !== null;
33
- }
34
- /**
35
- * Truncate a text
36
- */
37
- static truncate(value, position, limit = 0) {
38
- const suffix = '\u2026';
39
- if (!Tools.isDefined(value)) {
40
- return ``;
41
- }
42
- const valueToTruncate = `${value}`;
43
- if (valueToTruncate.length <= limit + 1) {
44
- return valueToTruncate;
45
- }
46
- const fixedLimit = limit - 1;
47
- switch (position) {
48
- case 'middle':
49
- return (valueToTruncate.substring(0, Math.ceil(fixedLimit / 2)) +
50
- suffix +
51
- valueToTruncate.substring(valueToTruncate.length - Math.floor(fixedLimit / 2)));
52
- case 'end':
53
- return valueToTruncate.substring(0, fixedLimit) + suffix;
54
- }
55
- }
56
- /**
57
- * Return a value from a nested object depending on a keyPath
58
- */
59
- static getIn(ref, path) {
60
- return path.reduce((p, c) => (p && p[c] !== undefined ? p[c] : undefined), ref);
61
- }
62
- /**
63
- * Return a clone of an object
64
- */
65
- static clone(o) {
66
- return typeof o === 'object'
67
- ? JSON.parse(JSON.stringify(o, (k, v) => {
68
- return v instanceof Set ? {} : v;
69
- }))
70
- : o;
71
- }
72
- /**
73
- * Get the amount of hidden neighbors from a list of nodes
74
- *
75
- * @param nodes
76
- */
77
- static getHiddenNeighbors(nodes) {
78
- return nodes.reduce((result, node) => {
79
- const statistics = node.getData('statistics');
80
- if (statistics !== undefined) {
81
- const hiddenNeighbors = statistics.degree !== undefined && !statistics.supernode
82
- ? statistics.degree - Tools.getDegreeWithoutSelfConnection(node)
83
- : statistics.supernodeDegree;
84
- if (hiddenNeighbors !== undefined && hiddenNeighbors > 0) {
85
- return (result += hiddenNeighbors);
86
- }
87
- }
88
- return result;
89
- }, 0);
90
- }
91
- /**
92
- * Return the visible degree of a node without self connection (self edge)
93
- *
94
- * @param {Node} node
95
- * @return {number}
96
- */
97
- static getDegreeWithoutSelfConnection(node) {
98
- return node.getAdjacentNodes({ policy: 'exclude-sources', filter: 'raw' }).size;
99
- }
100
- /**
101
- * Return a formatted version of a number
102
- */
103
- static formatNumber(number) {
104
- let div = 1;
105
- let suffix = '';
106
- const sign = number < 0 ? '-' : '';
107
- number = Math.abs(number);
108
- if (number >= 1000000) {
109
- div = 1000000;
110
- suffix = 'M';
111
- }
112
- else if (number >= 1000) {
113
- div = 1000;
114
- suffix = 'k';
115
- }
116
- const nn = number / div;
117
- // if there is a decimal value and nn < 10
118
- if (nn < 10 && nn % 1 !== 0) {
119
- return sign + nn.toFixed(1) + suffix;
120
- }
121
- else {
122
- return sign + Math.floor(nn) + suffix;
123
- }
124
- }
125
- /**
126
- * Return true if a string is not composed only by invisible char
127
- *
128
- * @param {string} value
129
- * @return {boolean}
130
- */
131
- static isStringFilled(value) {
132
- return value.trim() !== '';
133
- }
134
- static getValueFromLkProperty(property) {
135
- if (typeof property === 'object' && 'type' in property) {
136
- if (!('original' in property) && !('value' in property)) {
137
- return null;
138
- }
139
- if ('original' in property) {
140
- return `${property.original}`;
141
- }
142
- if ('value' in property) {
143
- return Tools.formatDate(new Date(new Date(property.value).getTime() + Tools.timezoneToMilliseconds(property.timezone)).toISOString());
144
- }
145
- }
146
- return property;
147
- }
148
- /**
149
- * Return a formatted date as a string
150
- */
151
- static formatDate(isoString, isDatetime, timezone) {
152
- // The date received from the server will be always in seconds
153
- let offsetDate = isoString;
154
- if (timezone !== undefined) {
155
- offsetDate = new Date(isoString).getTime() + timezone * 1000;
156
- }
157
- const dateObject = new Date(offsetDate);
158
- if (isNaN(dateObject.getUTCFullYear())) {
159
- return null;
160
- }
161
- let formattedDate = dateObject.getFullYear() +
162
- '-' +
163
- ((dateObject.getUTCMonth() + 1).toString().length === 1
164
- ? '0' + (dateObject.getUTCMonth() + 1)
165
- : dateObject.getUTCMonth() + 1) +
166
- '-' +
167
- (dateObject.getUTCDate().toString().length === 1
168
- ? '0' + dateObject.getUTCDate()
169
- : dateObject.getUTCDate());
170
- if (isDatetime) {
171
- formattedDate +=
172
- ' ' +
173
- (dateObject.getUTCHours().toString().length === 1
174
- ? '0' + dateObject.getUTCHours()
175
- : dateObject.getUTCHours()) +
176
- ':' +
177
- (dateObject.getUTCMinutes().toString().length === 1
178
- ? '0' + dateObject.getUTCMinutes()
179
- : dateObject.getUTCMinutes()) +
180
- ':' +
181
- (dateObject.getUTCSeconds().toString().length === 1
182
- ? '0' + dateObject.getUTCSeconds()
183
- : dateObject.getUTCSeconds());
184
- }
185
- return formattedDate;
186
- }
187
- /**
188
- * From "+03:00" return the offset in milliseconds
189
- * @param timezone
190
- */
191
- static timezoneToMilliseconds(timezone) {
192
- if (timezone === undefined) {
193
- return 0;
194
- }
195
- if (timezone === 'Z') {
196
- return 0;
197
- }
198
- const sign = timezone[0];
199
- const [hours, minutes] = timezone.slice(1).split(':');
200
- return sign === '+'
201
- ? this.sanitizeFormattedNumber(hours) * 3.6e6 + this.sanitizeFormattedNumber(minutes) * 60000
202
- : (this.sanitizeFormattedNumber(hours) * 3.6e6 +
203
- this.sanitizeFormattedNumber(minutes) * 60000) *
204
- -1;
205
- }
206
- static sanitizeFormattedNumber(str) {
207
- if (str.length === 2 && str.startsWith('0')) {
208
- return Tools.parseNumber(str[1]);
209
- }
210
- return Tools.parseNumber(str);
211
- }
212
- /**
213
- * Return true if `n` is (or can be parsed as) a float, but is NOT an integer
214
- *
215
- * @param {any} n
216
- * @return {number} a number (NaN is `n` cannot be parsed as a number)
217
- */
218
- static parseNumber(n) {
219
- // string: try to parse as number (allow ',' as decimal separator)
220
- if (typeof n === 'string') {
221
- // prevent the empty string to be parsed as 0
222
- if (n.trim() === '') {
223
- return Number.NaN;
224
- }
225
- n = +n.replace(',', '.').replace(' ', '');
226
- }
227
- // (the string could not be parsed) OR (it was neither string nor number)
228
- if (typeof n !== 'number') {
229
- return Number.NaN;
230
- }
231
- // false for NaN, +Infinity, -Infinity
232
- if (!isFinite(n)) {
233
- return Number.NaN;
234
- }
235
- return n;
236
- }
237
- /**
238
- * Return an Array without duplicated keys
239
- *
240
- * @param {Array<any>} arr
241
- * @param {string} key
242
- * @return {Array<any>}
243
- */
244
- static uniqBy(arr, key) {
245
- const seen = new Set();
246
- if (key) {
247
- const result = [];
248
- for (let i = 0; i < arr.length; ++i) {
249
- if (arr[i] && arr[i][key] && !seen.has(arr[i][key])) {
250
- seen.add(arr[i][key]);
251
- result.push(arr[i]);
252
- }
253
- else if (!arr[i][key]) {
254
- result.push(arr[i]);
255
- }
256
- }
257
- return result;
258
- }
259
- return typeof arr[0] === 'object'
260
- ? Array.from(new Set(arr.map((v) => JSON.stringify(v)))).map((v) => JSON.parse(v))
261
- : Array.from(new Set(arr));
262
- }
263
- /**
264
- * Return 'image' or 'url' depending on the given string
265
- *
266
- * @param {string} value
267
- * @return {"image" | "url"}
268
- */
269
- static getType(value) {
270
- if (Tools.isURLImage(value)) {
271
- return 'imageUrl';
272
- }
273
- if (Tools.isImage(value)) {
274
- return 'image';
275
- }
276
- if (Tools.isUrl(value)) {
277
- return 'url';
278
- }
279
- return undefined;
280
- }
281
- /**
282
- * Return true if the given string is an url that match the schema handled by LKE
283
- *
284
- * @param {string} value
285
- * @return {boolean}
286
- */
287
- static isUrl(value) {
288
- try {
289
- new URL(value);
290
- return true;
291
- }
292
- catch (e) {
293
- return false;
294
- }
295
- }
296
- /**
297
- * Return true if the given string is an image extension
298
- *
299
- * @param {string} value
300
- * @return {boolean}
301
- */
302
- static isImage(value) {
303
- return IMAGE_PATTERN.test(value);
304
- }
305
- /**
306
- * Return true if the given string is an url with an image extension
307
- *
308
- * @param {string} value
309
- * @return {boolean}
310
- */
311
- static isURLImage(value) {
312
- if (Tools.isUrl(value)) {
313
- const url = new URL(value);
314
- return Tools.isImage(url.pathname);
315
- }
316
- return false;
317
- }
318
- /**
319
- * Return true if a value is not undefined, not null and not an empty string
320
- */
321
- static valueExists(value) {
322
- return Tools.isDefined(value) && (typeof value !== 'string' || Tools.isStringFilled(value));
323
- }
324
- /**
325
- * Return true if `n` is (or can be parsed as) a number
326
- */
327
- static isNumber(n) {
328
- n = Tools.parseNumber(n);
329
- return Tools.isDefined(n) && n === n;
330
- }
331
- /**
332
- * return the correct property value
333
- */
334
- static getPropertyValue(property, invalidAsString, formattedDates) {
335
- if (typeof property === 'object' && !Array.isArray(property)) {
336
- if (!('status' in property)) {
337
- if ((property.type === 'date' || property.type === 'datetime') && formattedDates) {
338
- return Tools.formatDate(property.value, property.type === 'datetime');
339
- }
340
- else if (property.type === 'date' || property.type === 'datetime') {
341
- return new Date(property.value).getTime();
342
- }
343
- }
344
- else if (invalidAsString) {
345
- return 'original' in property ? property.original : undefined;
346
- }
347
- else {
348
- return undefined;
349
- }
350
- }
351
- return property;
352
- }
353
- /**
354
- * Parse the given value and return a float number or NaN
355
- *
356
- * @param {any} n
357
- * @return {number}
358
- */
359
- static parseFloat(n) {
360
- return Tools.parseNumber(n);
361
- }
362
- /**
363
- * Format a currency value to string.
364
- *
365
- * eg: 4123 -> 4.123,00 $
366
- */
367
- static formatCurrencyValue(value, options) {
368
- const sign = value < 0 ? '- ' : '';
369
- switch (options.format) {
370
- case rest_client_1.CurrencyFormat.SYMBOL_COMMAS_DOT:
371
- return `${sign}${options.symbol !== undefined ? options.symbol + ' ' : ''}${Tools.formatNumberToCurrency(value, ',', '.')}`;
372
- case rest_client_1.CurrencyFormat.SYMBOL_COMMAS:
373
- return `${sign}${options.symbol !== undefined ? options.symbol + ' ' : ''}${Tools.formatNumberToCurrency(value, ',')}`;
374
- case rest_client_1.CurrencyFormat.DOTS_COMMA_SYMBOL:
375
- return `${sign}${Tools.formatNumberToCurrency(value, '.', ',')}${options.symbol !== undefined ? ' ' + options.symbol : ''}`;
376
- case rest_client_1.CurrencyFormat.DOTS_SYMBOL:
377
- return `${sign}${Tools.formatNumberToCurrency(value, '.')}${options.symbol !== undefined ? ' ' + options.symbol : ''}`;
378
- case rest_client_1.CurrencyFormat.SPACES_COMMA_SYMBOL:
379
- return `${sign}${Tools.formatNumberToCurrency(value, ' ', ',')}${options.symbol !== undefined ? ' ' + options.symbol : ''}`;
380
- case rest_client_1.CurrencyFormat.SPACES_SYMBOL:
381
- return `${sign}${Tools.formatNumberToCurrency(value, ' ')}${options.symbol !== undefined ? ' ' + options.symbol : ''}`;
382
- default:
383
- throw Error(`Cannot format property value ${value}, unknown format ${options.format}.`);
384
- }
385
- }
386
- static formatNumberToCurrency(value, thousandSeparator, decimalSeparator) {
387
- if (!Number.isFinite(value)) {
388
- return value.toString();
389
- }
390
- const [integerPart, fractionalPart] = decimalSeparator
391
- ? Math.abs(value).toFixed(2).split('.')
392
- : [Math.abs(value).toFixed(0), undefined];
393
- let i = -1;
394
- const formattedIntegerPart = integerPart
395
- .split('')
396
- .reverse()
397
- .map((digit) => {
398
- i++;
399
- return i > 0 && i % 3 === 0 ? digit + thousandSeparator : digit;
400
- })
401
- .reverse()
402
- .join('');
403
- return decimalSeparator
404
- ? formattedIntegerPart + decimalSeparator + fractionalPart
405
- : formattedIntegerPart;
406
- }
407
- }
408
- exports.Tools = Tools;
409
- //# sourceMappingURL=tools.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"tools.js","sourceRoot":"","sources":["../../src/tools/tools.ts"],"names":[],"mappings":"AAAA,YAAY,CAAC;;;;;;AAEb,6DAAqC;AACrC,2DAAmC;AAI3B,iBAJD,gBAAM,CAIC;AAFd,yDAAiG;AAGjG,MAAM,aAAa,GAAG,qCAAqC,CAAC;AAC/C,QAAA,iBAAiB,GAAa;IACzC,OAAO;IACP,OAAO;IACP,MAAM;IACN,MAAM;IACN,OAAO;IACP,OAAO;IACP,YAAY;CACb,CAAC;AAEF,MAAa,KAAK;IACT,MAAM,CAAC,OAAO,CAAC,EAAW,EAAE,EAAW;QAC5C,OAAO,IAAA,iBAAO,EAAC,EAAE,EAAE,EAAE,CAAC,CAAC;IACzB,CAAC;IAED;;;;;OAKG;IACI,MAAM,CAAC,SAAS,CAAI,KAAQ;QACjC,OAAO,KAAK,KAAK,SAAS,IAAI,KAAK,KAAK,IAAI,CAAC;IAC/C,CAAC;IAED;;OAEG;IACI,MAAM,CAAC,QAAQ,CAAC,KAAc,EAAE,QAA0B,EAAE,KAAK,GAAG,CAAC;QAC1E,MAAM,MAAM,GAAG,QAAQ,CAAC;QACxB,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC,KAAK,CAAC,EAAE,CAAC;YAC5B,OAAO,EAAE,CAAC;QACZ,CAAC;QACD,MAAM,eAAe,GAAG,GAAG,KAAK,EAAE,CAAC;QACnC,IAAI,eAAe,CAAC,MAAM,IAAI,KAAK,GAAG,CAAC,EAAE,CAAC;YACxC,OAAO,eAAe,CAAC;QACzB,CAAC;QACD,MAAM,UAAU,GAAG,KAAK,GAAG,CAAC,CAAC;QAC7B,QAAQ,QAAQ,EAAE,CAAC;YACjB,KAAK,QAAQ;gBACX,OAAO,CACL,eAAe,CAAC,SAAS,CAAC,CAAC,EAAE,IAAI,CAAC,IAAI,CAAC,UAAU,GAAG,CAAC,CAAC,CAAC;oBACvD,MAAM;oBACN,eAAe,CAAC,SAAS,CAAC,eAAe,CAAC,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,UAAU,GAAG,CAAC,CAAC,CAAC,CAC/E,CAAC;YAEJ,KAAK,KAAK;gBACR,OAAO,eAAe,CAAC,SAAS,CAAC,CAAC,EAAE,UAAU,CAAC,GAAG,MAAM,CAAC;QAC7D,CAAC;IACH,CAAC;IAED;;OAEG;IACI,MAAM,CAAC,KAAK,CAAC,GAAQ,EAAE,IAA4B;QACxD,OAAO,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,KAAK,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,EAAE,GAAG,CAAC,CAAC;IAClF,CAAC;IAED;;OAEG;IACI,MAAM,CAAC,KAAK,CAAC,CAAM;QACxB,OAAO,OAAO,CAAC,KAAK,QAAQ;YAC1B,CAAC,CAAC,IAAI,CAAC,KAAK,CACR,IAAI,CAAC,SAAS,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE;gBACzB,OAAO,CAAC,YAAY,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;YACnC,CAAC,CAAC,CACH;YACH,CAAC,CAAC,CAAC,CAAC;IACR,CAAC;IAED;;;;OAIG;IACI,MAAM,CAAC,kBAAkB,CAAC,KAA2B;QAC1D,OAAO,KAAK,CAAC,MAAM,CAAC,CAAC,MAAc,EAAE,IAAsB,EAAE,EAAE;YAC7D,MAAM,UAAU,GAAG,IAAI,CAAC,OAAO,CAAC,YAAY,CAAC,CAAC;YAC9C,IAAI,UAAU,KAAK,SAAS,EAAE,CAAC;gBAC7B,MAAM,eAAe,GACnB,UAAU,CAAC,MAAM,KAAK,SAAS,IAAI,CAAC,UAAU,CAAC,SAAS;oBACtD,CAAC,CAAC,UAAU,CAAC,MAAM,GAAG,KAAK,CAAC,8BAA8B,CAAC,IAAI,CAAC;oBAChE,CAAC,CAAC,UAAU,CAAC,eAAe,CAAC;gBACjC,IAAI,eAAe,KAAK,SAAS,IAAI,eAAe,GAAG,CAAC,EAAE,CAAC;oBACzD,OAAO,CAAC,MAAM,IAAI,eAAe,CAAC,CAAC;gBACrC,CAAC;YACH,CAAC;YACD,OAAO,MAAM,CAAC;QAChB,CAAC,EAAE,CAAC,CAAC,CAAC;IACR,CAAC;IAED;;;;;OAKG;IACI,MAAM,CAAC,8BAA8B,CAAC,IAAsB;QACjE,OAAO,IAAI,CAAC,gBAAgB,CAAC,EAAC,MAAM,EAAE,iBAAiB,EAAE,MAAM,EAAE,KAAK,EAAC,CAAC,CAAC,IAAI,CAAC;IAChF,CAAC;IAED;;OAEG;IACI,MAAM,CAAC,YAAY,CAAC,MAAc;QACvC,IAAI,GAAG,GAAG,CAAC,CAAC;QACZ,IAAI,MAAM,GAAG,EAAE,CAAC;QAChB,MAAM,IAAI,GAAG,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC;QACnC,MAAM,GAAG,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;QAE1B,IAAI,MAAM,IAAI,OAAO,EAAE,CAAC;YACtB,GAAG,GAAG,OAAO,CAAC;YACd,MAAM,GAAG,GAAG,CAAC;QACf,CAAC;aAAM,IAAI,MAAM,IAAI,IAAI,EAAE,CAAC;YAC1B,GAAG,GAAG,IAAI,CAAC;YACX,MAAM,GAAG,GAAG,CAAC;QACf,CAAC;QACD,MAAM,EAAE,GAAG,MAAM,GAAG,GAAG,CAAC;QACxB,0CAA0C;QAC1C,IAAI,EAAE,GAAG,EAAE,IAAI,EAAE,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC;YAC5B,OAAO,IAAI,GAAG,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,MAAM,CAAC;QACvC,CAAC;aAAM,CAAC;YACN,OAAO,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,GAAG,MAAM,CAAC;QACxC,CAAC;IACH,CAAC;IAED;;;;;OAKG;IACI,MAAM,CAAC,cAAc,CAAC,KAAa;QACxC,OAAO,KAAK,CAAC,IAAI,EAAE,KAAK,EAAE,CAAC;IAC7B,CAAC;IAEM,MAAM,CAAC,sBAAsB,CAAC,QAAoB;QACvD,IAAI,OAAO,QAAQ,KAAK,QAAQ,IAAI,MAAM,IAAI,QAAQ,EAAE,CAAC;YACvD,IAAI,CAAC,CAAC,UAAU,IAAI,QAAQ,CAAC,IAAI,CAAC,CAAC,OAAO,IAAI,QAAQ,CAAC,EAAE,CAAC;gBACxD,OAAO,IAAI,CAAC;YACd,CAAC;YACD,IAAI,UAAU,IAAI,QAAQ,EAAE,CAAC;gBAC3B,OAAO,GAAG,QAAQ,CAAC,QAAQ,EAAE,CAAC;YAChC,CAAC;YACD,IAAI,OAAO,IAAI,QAAQ,EAAE,CAAC;gBACxB,OAAO,KAAK,CAAC,UAAU,CACrB,IAAI,IAAI,CACN,IAAI,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,OAAO,EAAE,GAAG,KAAK,CAAC,sBAAsB,CAAC,QAAQ,CAAC,QAAQ,CAAC,CACrF,CAAC,WAAW,EAAE,CAChB,CAAC;YACJ,CAAC;QACH,CAAC;QACD,OAAO,QAAQ,CAAC;IAClB,CAAC;IAED;;OAEG;IACI,MAAM,CAAC,UAAU,CACtB,SAAiB,EACjB,UAAoB,EACpB,QAAiB;QAEjB,8DAA8D;QAC9D,IAAI,UAAU,GAAoB,SAAS,CAAC;QAC5C,IAAI,QAAQ,KAAK,SAAS,EAAE,CAAC;YAC3B,UAAU,GAAG,IAAI,IAAI,CAAC,SAAS,CAAC,CAAC,OAAO,EAAE,GAAG,QAAQ,GAAG,IAAI,CAAC;QAC/D,CAAC;QACD,MAAM,UAAU,GAAG,IAAI,IAAI,CAAC,UAAU,CAAC,CAAC;QAExC,IAAI,KAAK,CAAC,UAAU,CAAC,cAAc,EAAE,CAAC,EAAE,CAAC;YACvC,OAAO,IAAI,CAAC;QACd,CAAC;QACD,IAAI,aAAa,GACf,UAAU,CAAC,WAAW,EAAE;YACxB,GAAG;YACH,CAAC,CAAC,UAAU,CAAC,WAAW,EAAE,GAAG,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAC,MAAM,KAAK,CAAC;gBACrD,CAAC,CAAC,GAAG,GAAG,CAAC,UAAU,CAAC,WAAW,EAAE,GAAG,CAAC,CAAC;gBACtC,CAAC,CAAC,UAAU,CAAC,WAAW,EAAE,GAAG,CAAC,CAAC;YACjC,GAAG;YACH,CAAC,UAAU,CAAC,UAAU,EAAE,CAAC,QAAQ,EAAE,CAAC,MAAM,KAAK,CAAC;gBAC9C,CAAC,CAAC,GAAG,GAAG,UAAU,CAAC,UAAU,EAAE;gBAC/B,CAAC,CAAC,UAAU,CAAC,UAAU,EAAE,CAAC,CAAC;QAE/B,IAAI,UAAU,EAAE,CAAC;YACf,aAAa;gBACX,GAAG;oBACH,CAAC,UAAU,CAAC,WAAW,EAAE,CAAC,QAAQ,EAAE,CAAC,MAAM,KAAK,CAAC;wBAC/C,CAAC,CAAC,GAAG,GAAG,UAAU,CAAC,WAAW,EAAE;wBAChC,CAAC,CAAC,UAAU,CAAC,WAAW,EAAE,CAAC;oBAC7B,GAAG;oBACH,CAAC,UAAU,CAAC,aAAa,EAAE,CAAC,QAAQ,EAAE,CAAC,MAAM,KAAK,CAAC;wBACjD,CAAC,CAAC,GAAG,GAAG,UAAU,CAAC,aAAa,EAAE;wBAClC,CAAC,CAAC,UAAU,CAAC,aAAa,EAAE,CAAC;oBAC/B,GAAG;oBACH,CAAC,UAAU,CAAC,aAAa,EAAE,CAAC,QAAQ,EAAE,CAAC,MAAM,KAAK,CAAC;wBACjD,CAAC,CAAC,GAAG,GAAG,UAAU,CAAC,aAAa,EAAE;wBAClC,CAAC,CAAC,UAAU,CAAC,aAAa,EAAE,CAAC,CAAC;QACpC,CAAC;QACD,OAAO,aAAa,CAAC;IACvB,CAAC;IAED;;;OAGG;IACI,MAAM,CAAC,sBAAsB,CAAC,QAA4B;QAC/D,IAAI,QAAQ,KAAK,SAAS,EAAE,CAAC;YAC3B,OAAO,CAAC,CAAC;QACX,CAAC;QACD,IAAI,QAAQ,KAAK,GAAG,EAAE,CAAC;YACrB,OAAO,CAAC,CAAC;QACX,CAAC;QACD,MAAM,IAAI,GAAG,QAAQ,CAAC,CAAC,CAAC,CAAC;QACzB,MAAM,CAAC,KAAK,EAAE,OAAO,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QACtD,OAAO,IAAI,KAAK,GAAG;YACjB,CAAC,CAAC,IAAI,CAAC,uBAAuB,CAAC,KAAK,CAAC,GAAG,KAAK,GAAG,IAAI,CAAC,uBAAuB,CAAC,OAAO,CAAC,GAAG,KAAK;YAC7F,CAAC,CAAC,CAAC,IAAI,CAAC,uBAAuB,CAAC,KAAK,CAAC,GAAG,KAAK;gBAC1C,IAAI,CAAC,uBAAuB,CAAC,OAAO,CAAC,GAAG,KAAK,CAAC;gBAC9C,CAAC,CAAC,CAAC;IACX,CAAC;IAEM,MAAM,CAAC,uBAAuB,CAAC,GAAW;QAC/C,IAAI,GAAG,CAAC,MAAM,KAAK,CAAC,IAAI,GAAG,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;YAC5C,OAAO,KAAK,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;QACnC,CAAC;QACD,OAAO,KAAK,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC;IAChC,CAAC;IAED;;;;;OAKG;IACI,MAAM,CAAC,WAAW,CAAC,CAAU;QAClC,kEAAkE;QAClE,IAAI,OAAO,CAAC,KAAK,QAAQ,EAAE,CAAC;YAC1B,6CAA6C;YAC7C,IAAI,CAAC,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC;gBACpB,OAAO,MAAM,CAAC,GAAG,CAAC;YACpB,CAAC;YAED,CAAC,GAAG,CAAC,CAAC,CAAC,OAAO,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC;QAC5C,CAAC;QAED,yEAAyE;QACzE,IAAI,OAAO,CAAC,KAAK,QAAQ,EAAE,CAAC;YAC1B,OAAO,MAAM,CAAC,GAAG,CAAC;QACpB,CAAC;QAED,sCAAsC;QACtC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC;YACjB,OAAO,MAAM,CAAC,GAAG,CAAC;QACpB,CAAC;QAED,OAAO,CAAC,CAAC;IACX,CAAC;IAED;;;;;;OAMG;IACI,MAAM,CAAC,MAAM,CAAC,GAAe,EAAE,GAAY;QAChD,MAAM,IAAI,GAAG,IAAI,GAAG,EAAE,CAAC;QACvB,IAAI,GAAG,EAAE,CAAC;YACR,MAAM,MAAM,GAAG,EAAE,CAAC;YAClB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,GAAG,CAAC,MAAM,EAAE,EAAE,CAAC,EAAE,CAAC;gBACpC,IAAI,GAAG,CAAC,CAAC,CAAC,IAAI,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC;oBACpD,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;oBACtB,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;gBACtB,CAAC;qBAAM,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC;oBACxB,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;gBACtB,CAAC;YACH,CAAC;YACD,OAAO,MAAM,CAAC;QAChB,CAAC;QACD,OAAO,OAAO,GAAG,CAAC,CAAC,CAAC,KAAK,QAAQ;YAC/B,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;YAClF,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC;IAC/B,CAAC;IAED;;;;;OAKG;IACI,MAAM,CAAC,OAAO,CAAC,KAAa;QACjC,IAAI,KAAK,CAAC,UAAU,CAAC,KAAK,CAAC,EAAE,CAAC;YAC5B,OAAO,UAAU,CAAC;QACpB,CAAC;QAED,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;YACzB,OAAO,OAAO,CAAC;QACjB,CAAC;QAED,IAAI,KAAK,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE,CAAC;YACvB,OAAO,KAAK,CAAC;QACf,CAAC;QAED,OAAO,SAAS,CAAC;IACnB,CAAC;IAED;;;;;OAKG;IACK,MAAM,CAAC,KAAK,CAAC,KAAa;QAChC,IAAI,CAAC;YACH,IAAI,GAAG,CAAC,KAAK,CAAC,CAAC;YACf,OAAO,IAAI,CAAC;QACd,CAAC;QAAC,OAAO,CAAC,EAAE,CAAC;YACX,OAAO,KAAK,CAAC;QACf,CAAC;IACH,CAAC;IAED;;;;;OAKG;IACK,MAAM,CAAC,OAAO,CAAC,KAAa;QAClC,OAAO,aAAa,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IACnC,CAAC;IAED;;;;;OAKG;IACK,MAAM,CAAC,UAAU,CAAC,KAAa;QACrC,IAAI,KAAK,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE,CAAC;YACvB,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,KAAK,CAAC,CAAC;YAC3B,OAAO,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;QACrC,CAAC;QACD,OAAO,KAAK,CAAC;IACf,CAAC;IAED;;OAEG;IACI,MAAM,CAAC,WAAW,CAAC,KAAiB;QACzC,OAAO,KAAK,CAAC,SAAS,CAAC,KAAK,CAAC,IAAI,CAAC,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,CAAC,cAAc,CAAC,KAAK,CAAC,CAAC,CAAC;IAC9F,CAAC;IAED;;OAEG;IACI,MAAM,CAAC,QAAQ,CAAC,CAAU;QAC/B,CAAC,GAAG,KAAK,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC;QACzB,OAAO,KAAK,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IACvC,CAAC;IAED;;OAEG;IACI,MAAM,CAAC,gBAAgB,CAC5B,QAAoB,EACpB,eAAyB,EACzB,cAAwB;QAExB,IAAI,OAAO,QAAQ,KAAK,QAAQ,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE,CAAC;YAC7D,IAAI,CAAC,CAAC,QAAQ,IAAI,QAAQ,CAAC,EAAE,CAAC;gBAC5B,IAAI,CAAC,QAAQ,CAAC,IAAI,KAAK,MAAM,IAAI,QAAQ,CAAC,IAAI,KAAK,UAAU,CAAC,IAAI,cAAc,EAAE,CAAC;oBACjF,OAAO,KAAK,CAAC,UAAU,CAAC,QAAQ,CAAC,KAAK,EAAE,QAAQ,CAAC,IAAI,KAAK,UAAU,CAAC,CAAC;gBACxE,CAAC;qBAAM,IAAI,QAAQ,CAAC,IAAI,KAAK,MAAM,IAAI,QAAQ,CAAC,IAAI,KAAK,UAAU,EAAE,CAAC;oBACpE,OAAO,IAAI,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,OAAO,EAAE,CAAC;gBAC5C,CAAC;YACH,CAAC;iBAAM,IAAI,eAAe,EAAE,CAAC;gBAC3B,OAAO,UAAU,IAAI,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC,CAAC,SAAS,CAAC;YAChE,CAAC;iBAAM,CAAC;gBACN,OAAO,SAAS,CAAC;YACnB,CAAC;QACH,CAAC;QACD,OAAO,QAAQ,CAAC;IAClB,CAAC;IAED;;;;;OAKG;IACI,MAAM,CAAC,UAAU,CAAC,CAAU;QACjC,OAAO,KAAK,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC;IAC9B,CAAC;IAED;;;;OAIG;IACI,MAAM,CAAC,mBAAmB,CAAC,KAAa,EAAE,OAAyB;QACxE,MAAM,IAAI,GAAG,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC;QACnC,QAAQ,OAAO,CAAC,MAAM,EAAE,CAAC;YACvB,KAAK,4BAAc,CAAC,iBAAiB;gBACnC,OAAO,GAAG,IAAI,GACZ,OAAO,CAAC,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,OAAO,CAAC,MAAM,GAAG,GAAG,CAAC,CAAC,CAAC,EACxD,GAAG,KAAK,CAAC,sBAAsB,CAAC,KAAK,EAAE,GAAG,EAAE,GAAG,CAAC,EAAE,CAAC;YAErD,KAAK,4BAAc,CAAC,aAAa;gBAC/B,OAAO,GAAG,IAAI,GACZ,OAAO,CAAC,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,OAAO,CAAC,MAAM,GAAG,GAAG,CAAC,CAAC,CAAC,EACxD,GAAG,KAAK,CAAC,sBAAsB,CAAC,KAAK,EAAE,GAAG,CAAC,EAAE,CAAC;YAEhD,KAAK,4BAAc,CAAC,iBAAiB;gBACnC,OAAO,GAAG,IAAI,GAAG,KAAK,CAAC,sBAAsB,CAAC,KAAK,EAAE,GAAG,EAAE,GAAG,CAAC,GAC5D,OAAO,CAAC,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,GAAG,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EACxD,EAAE,CAAC;YAEL,KAAK,4BAAc,CAAC,WAAW;gBAC7B,OAAO,GAAG,IAAI,GAAG,KAAK,CAAC,sBAAsB,CAAC,KAAK,EAAE,GAAG,CAAC,GACvD,OAAO,CAAC,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,GAAG,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EACxD,EAAE,CAAC;YAEL,KAAK,4BAAc,CAAC,mBAAmB;gBACrC,OAAO,GAAG,IAAI,GAAG,KAAK,CAAC,sBAAsB,CAAC,KAAK,EAAE,GAAG,EAAE,GAAG,CAAC,GAC5D,OAAO,CAAC,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,GAAG,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EACxD,EAAE,CAAC;YAEL,KAAK,4BAAc,CAAC,aAAa;gBAC/B,OAAO,GAAG,IAAI,GAAG,KAAK,CAAC,sBAAsB,CAAC,KAAK,EAAE,GAAG,CAAC,GACvD,OAAO,CAAC,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,GAAG,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EACxD,EAAE,CAAC;YAEL;gBACE,MAAM,KAAK,CAAC,gCAAgC,KAAK,oBAAoB,OAAO,CAAC,MAAM,GAAG,CAAC,CAAC;QAC5F,CAAC;IACH,CAAC;IAEO,MAAM,CAAC,sBAAsB,CACnC,KAAa,EACb,iBAAyB,EACzB,gBAAyB;QAEzB,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC;YAC5B,OAAO,KAAK,CAAC,QAAQ,EAAE,CAAC;QAC1B,CAAC;QAED,MAAM,CAAC,WAAW,EAAE,cAAc,CAAC,GAAG,gBAAgB;YACpD,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC;YACvC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,SAAS,CAAC,CAAC;QAE5C,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;QACX,MAAM,oBAAoB,GAAG,WAAW;aACrC,KAAK,CAAC,EAAE,CAAC;aACT,OAAO,EAAE;aACT,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE;YACb,CAAC,EAAE,CAAC;YACJ,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,GAAG,iBAAiB,CAAC,CAAC,CAAC,KAAK,CAAC;QAClE,CAAC,CAAC;aACD,OAAO,EAAE;aACT,IAAI,CAAC,EAAE,CAAC,CAAC;QAEZ,OAAO,gBAAgB;YACrB,CAAC,CAAC,oBAAoB,GAAG,gBAAgB,GAAG,cAAc;YAC1D,CAAC,CAAC,oBAAoB,CAAC;IAC3B,CAAC;CACF;AAzcD,sBAycC","sourcesContent":["'use strict';\n\nimport isEqual from 'lodash/isEqual';\nimport sortBy from 'lodash/sortBy';\nimport {Node, NodeList} from '@linkurious/ogma';\nimport {CurrencyFormat, ICurrencyOptions, LkNodeData, LkProperty} from '@linkurious/rest-client';\n\nexport {sortBy};\nconst IMAGE_PATTERN = /\\S+\\.(gif|jpe?g|tiff|png|bmp|svg)$/i;\nexport const CAPTION_HEURISTIC: string[] = [\n 'label',\n 'Label',\n 'name',\n 'Name',\n 'title',\n 'Title',\n 'rdfs:label'\n];\n\nexport class Tools {\n public static isEqual(v1: unknown, v2: unknown): boolean {\n return isEqual(v1, v2);\n }\n\n /**\n * Check that a value is defined : not null and not undefined\n *\n * @param {any} value\n * @return {boolean}\n */\n public static isDefined<T>(value: T): value is NonNullable<T> {\n return value !== undefined && value !== null;\n }\n\n /**\n * Truncate a text\n */\n public static truncate(value: unknown, position: 'middle' | 'end', limit = 0): string {\n const suffix = '\\u2026';\n if (!Tools.isDefined(value)) {\n return ``;\n }\n const valueToTruncate = `${value}`;\n if (valueToTruncate.length <= limit + 1) {\n return valueToTruncate;\n }\n const fixedLimit = limit - 1;\n switch (position) {\n case 'middle':\n return (\n valueToTruncate.substring(0, Math.ceil(fixedLimit / 2)) +\n suffix +\n valueToTruncate.substring(valueToTruncate.length - Math.floor(fixedLimit / 2))\n );\n\n case 'end':\n return valueToTruncate.substring(0, fixedLimit) + suffix;\n }\n }\n\n /**\n * Return a value from a nested object depending on a keyPath\n */\n public static getIn(ref: any, path: Array<string | number>): any {\n return path.reduce((p, c) => (p && p[c] !== undefined ? p[c] : undefined), ref);\n }\n\n /**\n * Return a clone of an object\n */\n public static clone(o: any) {\n return typeof o === 'object'\n ? JSON.parse(\n JSON.stringify(o, (k, v) => {\n return v instanceof Set ? {} : v;\n })\n )\n : o;\n }\n\n /**\n * Get the amount of hidden neighbors from a list of nodes\n *\n * @param nodes\n */\n public static getHiddenNeighbors(nodes: NodeList<LkNodeData>): number {\n return nodes.reduce((result: number, node: Node<LkNodeData>) => {\n const statistics = node.getData('statistics');\n if (statistics !== undefined) {\n const hiddenNeighbors =\n statistics.degree !== undefined && !statistics.supernode\n ? statistics.degree - Tools.getDegreeWithoutSelfConnection(node)\n : statistics.supernodeDegree;\n if (hiddenNeighbors !== undefined && hiddenNeighbors > 0) {\n return (result += hiddenNeighbors);\n }\n }\n return result;\n }, 0);\n }\n\n /**\n * Return the visible degree of a node without self connection (self edge)\n *\n * @param {Node} node\n * @return {number}\n */\n public static getDegreeWithoutSelfConnection(node: Node<LkNodeData>): number {\n return node.getAdjacentNodes({policy: 'exclude-sources', filter: 'raw'}).size;\n }\n\n /**\n * Return a formatted version of a number\n */\n public static formatNumber(number: number): string {\n let div = 1;\n let suffix = '';\n const sign = number < 0 ? '-' : '';\n number = Math.abs(number);\n\n if (number >= 1000000) {\n div = 1000000;\n suffix = 'M';\n } else if (number >= 1000) {\n div = 1000;\n suffix = 'k';\n }\n const nn = number / div;\n // if there is a decimal value and nn < 10\n if (nn < 10 && nn % 1 !== 0) {\n return sign + nn.toFixed(1) + suffix;\n } else {\n return sign + Math.floor(nn) + suffix;\n }\n }\n\n /**\n * Return true if a string is not composed only by invisible char\n *\n * @param {string} value\n * @return {boolean}\n */\n public static isStringFilled(value: string): boolean {\n return value.trim() !== '';\n }\n\n public static getValueFromLkProperty(property: LkProperty): null | string | number | boolean {\n if (typeof property === 'object' && 'type' in property) {\n if (!('original' in property) && !('value' in property)) {\n return null;\n }\n if ('original' in property) {\n return `${property.original}`;\n }\n if ('value' in property) {\n return Tools.formatDate(\n new Date(\n new Date(property.value).getTime() + Tools.timezoneToMilliseconds(property.timezone)\n ).toISOString()\n );\n }\n }\n return property;\n }\n\n /**\n * Return a formatted date as a string\n */\n public static formatDate(\n isoString: string,\n isDatetime?: boolean,\n timezone?: number\n ): string | null {\n // The date received from the server will be always in seconds\n let offsetDate: string | number = isoString;\n if (timezone !== undefined) {\n offsetDate = new Date(isoString).getTime() + timezone * 1000;\n }\n const dateObject = new Date(offsetDate);\n\n if (isNaN(dateObject.getUTCFullYear())) {\n return null;\n }\n let formattedDate =\n dateObject.getFullYear() +\n '-' +\n ((dateObject.getUTCMonth() + 1).toString().length === 1\n ? '0' + (dateObject.getUTCMonth() + 1)\n : dateObject.getUTCMonth() + 1) +\n '-' +\n (dateObject.getUTCDate().toString().length === 1\n ? '0' + dateObject.getUTCDate()\n : dateObject.getUTCDate());\n\n if (isDatetime) {\n formattedDate +=\n ' ' +\n (dateObject.getUTCHours().toString().length === 1\n ? '0' + dateObject.getUTCHours()\n : dateObject.getUTCHours()) +\n ':' +\n (dateObject.getUTCMinutes().toString().length === 1\n ? '0' + dateObject.getUTCMinutes()\n : dateObject.getUTCMinutes()) +\n ':' +\n (dateObject.getUTCSeconds().toString().length === 1\n ? '0' + dateObject.getUTCSeconds()\n : dateObject.getUTCSeconds());\n }\n return formattedDate;\n }\n\n /**\n * From \"+03:00\" return the offset in milliseconds\n * @param timezone\n */\n public static timezoneToMilliseconds(timezone: string | undefined): number {\n if (timezone === undefined) {\n return 0;\n }\n if (timezone === 'Z') {\n return 0;\n }\n const sign = timezone[0];\n const [hours, minutes] = timezone.slice(1).split(':');\n return sign === '+'\n ? this.sanitizeFormattedNumber(hours) * 3.6e6 + this.sanitizeFormattedNumber(minutes) * 60000\n : (this.sanitizeFormattedNumber(hours) * 3.6e6 +\n this.sanitizeFormattedNumber(minutes) * 60000) *\n -1;\n }\n\n public static sanitizeFormattedNumber(str: string): number {\n if (str.length === 2 && str.startsWith('0')) {\n return Tools.parseNumber(str[1]);\n }\n return Tools.parseNumber(str);\n }\n\n /**\n * Return true if `n` is (or can be parsed as) a float, but is NOT an integer\n *\n * @param {any} n\n * @return {number} a number (NaN is `n` cannot be parsed as a number)\n */\n public static parseNumber(n: unknown): number {\n // string: try to parse as number (allow ',' as decimal separator)\n if (typeof n === 'string') {\n // prevent the empty string to be parsed as 0\n if (n.trim() === '') {\n return Number.NaN;\n }\n\n n = +n.replace(',', '.').replace(' ', '');\n }\n\n // (the string could not be parsed) OR (it was neither string nor number)\n if (typeof n !== 'number') {\n return Number.NaN;\n }\n\n // false for NaN, +Infinity, -Infinity\n if (!isFinite(n)) {\n return Number.NaN;\n }\n\n return n;\n }\n\n /**\n * Return an Array without duplicated keys\n *\n * @param {Array<any>} arr\n * @param {string} key\n * @return {Array<any>}\n */\n public static uniqBy(arr: Array<any>, key?: string): Array<any> {\n const seen = new Set();\n if (key) {\n const result = [];\n for (let i = 0; i < arr.length; ++i) {\n if (arr[i] && arr[i][key] && !seen.has(arr[i][key])) {\n seen.add(arr[i][key]);\n result.push(arr[i]);\n } else if (!arr[i][key]) {\n result.push(arr[i]);\n }\n }\n return result;\n }\n return typeof arr[0] === 'object'\n ? Array.from(new Set(arr.map((v) => JSON.stringify(v)))).map((v) => JSON.parse(v))\n : Array.from(new Set(arr));\n }\n\n /**\n * Return 'image' or 'url' depending on the given string\n *\n * @param {string} value\n * @return {\"image\" | \"url\"}\n */\n public static getType(value: string): 'image' | 'url' | 'imageUrl' | undefined {\n if (Tools.isURLImage(value)) {\n return 'imageUrl';\n }\n\n if (Tools.isImage(value)) {\n return 'image';\n }\n\n if (Tools.isUrl(value)) {\n return 'url';\n }\n\n return undefined;\n }\n\n /**\n * Return true if the given string is an url that match the schema handled by LKE\n *\n * @param {string} value\n * @return {boolean}\n */\n private static isUrl(value: string): boolean {\n try {\n new URL(value);\n return true;\n } catch (e) {\n return false;\n }\n }\n\n /**\n * Return true if the given string is an image extension\n *\n * @param {string} value\n * @return {boolean}\n */\n private static isImage(value: string): boolean {\n return IMAGE_PATTERN.test(value);\n }\n\n /**\n * Return true if the given string is an url with an image extension\n *\n * @param {string} value\n * @return {boolean}\n */\n private static isURLImage(value: string): boolean {\n if (Tools.isUrl(value)) {\n const url = new URL(value);\n return Tools.isImage(url.pathname);\n }\n return false;\n }\n\n /**\n * Return true if a value is not undefined, not null and not an empty string\n */\n public static valueExists(value: LkProperty): boolean {\n return Tools.isDefined(value) && (typeof value !== 'string' || Tools.isStringFilled(value));\n }\n\n /**\n * Return true if `n` is (or can be parsed as) a number\n */\n public static isNumber(n: unknown): boolean {\n n = Tools.parseNumber(n);\n return Tools.isDefined(n) && n === n;\n }\n\n /**\n * return the correct property value\n */\n public static getPropertyValue(\n property: LkProperty,\n invalidAsString?: boolean,\n formattedDates?: boolean\n ): undefined | null | string | number | boolean | Array<string> {\n if (typeof property === 'object' && !Array.isArray(property)) {\n if (!('status' in property)) {\n if ((property.type === 'date' || property.type === 'datetime') && formattedDates) {\n return Tools.formatDate(property.value, property.type === 'datetime');\n } else if (property.type === 'date' || property.type === 'datetime') {\n return new Date(property.value).getTime();\n }\n } else if (invalidAsString) {\n return 'original' in property ? property.original : undefined;\n } else {\n return undefined;\n }\n }\n return property;\n }\n\n /**\n * Parse the given value and return a float number or NaN\n *\n * @param {any} n\n * @return {number}\n */\n public static parseFloat(n: unknown): number {\n return Tools.parseNumber(n);\n }\n\n /**\n * Format a currency value to string.\n *\n * eg: 4123 -> 4.123,00 $\n */\n public static formatCurrencyValue(value: number, options: ICurrencyOptions): string {\n const sign = value < 0 ? '- ' : '';\n switch (options.format) {\n case CurrencyFormat.SYMBOL_COMMAS_DOT:\n return `${sign}${\n options.symbol !== undefined ? options.symbol + ' ' : ''\n }${Tools.formatNumberToCurrency(value, ',', '.')}`;\n\n case CurrencyFormat.SYMBOL_COMMAS:\n return `${sign}${\n options.symbol !== undefined ? options.symbol + ' ' : ''\n }${Tools.formatNumberToCurrency(value, ',')}`;\n\n case CurrencyFormat.DOTS_COMMA_SYMBOL:\n return `${sign}${Tools.formatNumberToCurrency(value, '.', ',')}${\n options.symbol !== undefined ? ' ' + options.symbol : ''\n }`;\n\n case CurrencyFormat.DOTS_SYMBOL:\n return `${sign}${Tools.formatNumberToCurrency(value, '.')}${\n options.symbol !== undefined ? ' ' + options.symbol : ''\n }`;\n\n case CurrencyFormat.SPACES_COMMA_SYMBOL:\n return `${sign}${Tools.formatNumberToCurrency(value, ' ', ',')}${\n options.symbol !== undefined ? ' ' + options.symbol : ''\n }`;\n\n case CurrencyFormat.SPACES_SYMBOL:\n return `${sign}${Tools.formatNumberToCurrency(value, ' ')}${\n options.symbol !== undefined ? ' ' + options.symbol : ''\n }`;\n\n default:\n throw Error(`Cannot format property value ${value}, unknown format ${options.format}.`);\n }\n }\n\n private static formatNumberToCurrency(\n value: number,\n thousandSeparator: string,\n decimalSeparator?: string\n ): string {\n if (!Number.isFinite(value)) {\n return value.toString();\n }\n\n const [integerPart, fractionalPart] = decimalSeparator\n ? Math.abs(value).toFixed(2).split('.')\n : [Math.abs(value).toFixed(0), undefined];\n\n let i = -1;\n const formattedIntegerPart = integerPart\n .split('')\n .reverse()\n .map((digit) => {\n i++;\n return i > 0 && i % 3 === 0 ? digit + thousandSeparator : digit;\n })\n .reverse()\n .join('');\n\n return decimalSeparator\n ? formattedIntegerPart + decimalSeparator + fractionalPart\n : formattedIntegerPart;\n }\n}\n"]}