bruce-models 7.1.54 → 7.1.55

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.
@@ -77,12 +77,234 @@ var Calculator;
77
77
  EValueType[EValueType["RandomColor"] = 5] = "RandomColor";
78
78
  })(EValueType = Calculator.EValueType || (Calculator.EValueType = {}));
79
79
  /**
80
- * Calculates a value-type 'T' based on given set of fields.
81
- * The supplied data + tags are fed into the calculation.
82
- * When a value fails to be calculated, the 'defaultValue' is returned.
83
- * If no 'defaultValue' is provided, then 'null' is returned.
80
+ * Decodes an effective string produced by TraceCalculate back into a structured object.
81
+ * Returns null if the string is null, empty, or does not match the expected format.
84
82
  */
85
- function Calculate(params) {
83
+ function DecodeEffective(effective) {
84
+ if (!effective) {
85
+ return null;
86
+ }
87
+ // Format: f{index}:{type}[:{part1}[:{part2}]]
88
+ const match = effective.match(/^f(\d+):([^:]+)(?::([^:]+)(?::([^:]+))?)?$/);
89
+ if (!match) {
90
+ return null;
91
+ }
92
+ const fieldIndex = parseInt(match[1], 10);
93
+ const type = match[2];
94
+ const part1 = match[3] != null ? decodeEffective(match[3]) : null;
95
+ const part2 = match[4] != null ? decodeEffective(match[4]) : null;
96
+ const base = { type, fieldIndex };
97
+ switch (type) {
98
+ case "color":
99
+ if (part1 == null) {
100
+ return null;
101
+ }
102
+ return Object.assign(Object.assign({}, base), { colorStr: part1 });
103
+ case "gradient":
104
+ case "mapping":
105
+ return Object.assign(Object.assign(Object.assign({}, base), (part1 != null && { path: part1 })), (part2 != null && { entityValue: part2 }));
106
+ case "input":
107
+ if (part1 == null || part2 == null) {
108
+ return null;
109
+ }
110
+ return Object.assign(Object.assign({}, base), { template: part1, resolvedValue: part2 });
111
+ case "tag":
112
+ if (part1 == null) {
113
+ return null;
114
+ }
115
+ return Object.assign(Object.assign({}, base), { tagColor: part1 });
116
+ case "random":
117
+ case "fn":
118
+ return base;
119
+ default:
120
+ return null;
121
+ }
122
+ }
123
+ Calculator.DecodeEffective = DecodeEffective;
124
+ function encodeEffective(str) {
125
+ const s = String(str == null ? "" : str);
126
+ try {
127
+ if (typeof Buffer !== "undefined") {
128
+ return Buffer.from(s).toString("base64").replace(/=+$/, "");
129
+ }
130
+ // Browser fallback
131
+ return btoa(s).replace(/=+$/, "");
132
+ }
133
+ catch (e) {
134
+ return encodeURIComponent(s);
135
+ }
136
+ }
137
+ function decodeEffective(encoded) {
138
+ try {
139
+ if (typeof Buffer !== "undefined") {
140
+ return Buffer.from(encoded, "base64").toString("utf8");
141
+ }
142
+ return atob(encoded);
143
+ }
144
+ catch (e) {
145
+ return decodeURIComponent(encoded);
146
+ }
147
+ }
148
+ function _getMappingTrace(value, entity) {
149
+ const attrPaths = parseLegacyPath(value.field);
150
+ for (let i = 0; i < attrPaths.length; i++) {
151
+ const attrPath = attrPaths[i];
152
+ let eValue = entity_1.Entity.GetValue({
153
+ entity: entity,
154
+ path: attrPath
155
+ });
156
+ let isValueNum = !isNaN(+eValue);
157
+ if (eValue == null) {
158
+ isValueNum = false;
159
+ }
160
+ for (let j = 0; j < value.values.length; j++) {
161
+ const option = value.values[j];
162
+ const fieldValues = Array.isArray(option.fieldValue) ? option.fieldValue : [option.fieldValue];
163
+ for (let k = 0; k < fieldValues.length; k++) {
164
+ let mapValue = fieldValues[k];
165
+ // If mapValue is prefixed with "JS:", we evaluate it as JavaScript.
166
+ // This lets us do things like JS:Boolean("${}") as a quick way to map 'existence' to a target value.
167
+ if (typeof mapValue === "string" && mapValue.startsWith("JS:")) {
168
+ try {
169
+ let jsEval = mapValue.replace("JS:", "").trim();
170
+ const attrPathStr = path_utils_1.PathUtils.Wrap(attrPath);
171
+ jsEval = jsEval.replace("${}", "${" + attrPathStr + "}");
172
+ jsEval = bruce_variable_1.BruceVariable.SwapValues({
173
+ str: jsEval,
174
+ entity: entity
175
+ });
176
+ // https://rollupjs.org/guide/en/#avoiding-eval
177
+ // This stops eval warning.
178
+ const eval2 = eval;
179
+ mapValue = eval2(jsEval);
180
+ if (mapValue) {
181
+ return { result: option.appliedValue, attrPath, eValue };
182
+ }
183
+ else {
184
+ continue;
185
+ }
186
+ }
187
+ catch (exception) {
188
+ const e = exception;
189
+ let suppress = false;
190
+ if (e && typeof e == "object") {
191
+ const msg = e.message;
192
+ suppress = !!msg && (msg.includes("Unexpected end") || msg.includes("got end of script"));
193
+ }
194
+ if (!suppress) {
195
+ console.error(e);
196
+ }
197
+ // Eval failed, therefor not a valid mapping-row.
198
+ continue;
199
+ }
200
+ }
201
+ let isMapValueNum = !isNaN(+mapValue);
202
+ if (isMapValueNum == null) {
203
+ isMapValueNum = false;
204
+ }
205
+ if (isValueNum && (isMapValueNum || (typeof mapValue === "string" && mapValue.includes("-")))) {
206
+ if (+mapValue == +eValue) {
207
+ return { result: option.appliedValue, attrPath, eValue };
208
+ }
209
+ const mapSplit = mapValue.split("-");
210
+ if (mapSplit.length == 2) {
211
+ const min = mapSplit[0];
212
+ const max = mapSplit[1];
213
+ if (min != "") {
214
+ if (+eValue < +min) {
215
+ continue;
216
+ }
217
+ }
218
+ if (max != "") {
219
+ if (+eValue > +max) {
220
+ continue;
221
+ }
222
+ }
223
+ if (min == "" && max == "") {
224
+ continue;
225
+ }
226
+ return { result: option.appliedValue, attrPath, eValue };
227
+ }
228
+ }
229
+ else {
230
+ if (mapValue == eValue) {
231
+ return { result: option.appliedValue, attrPath, eValue };
232
+ }
233
+ // Case where Entity value is a boolean but the mapping value is a string.
234
+ // Common as mapping value is typically a user-entered string.
235
+ else if (typeof eValue === "boolean" && typeof mapValue === "string") {
236
+ const eValueStr = eValue ? "true" : "false";
237
+ if (mapValue.toLowerCase() == eValueStr) {
238
+ return { result: option.appliedValue, attrPath, eValue };
239
+ }
240
+ }
241
+ // Handling possible case where the opposite is true.
242
+ // Have not seen this happen yet, but preparing for any future cases.
243
+ else if (typeof mapValue === "boolean" && typeof eValue === "string") {
244
+ const mapValueStr = mapValue ? "true" : "false";
245
+ if (mapValueStr == eValue.toLowerCase()) {
246
+ return { result: option.appliedValue, attrPath, eValue };
247
+ }
248
+ }
249
+ }
250
+ }
251
+ }
252
+ }
253
+ return { result: null, attrPath: null, eValue: null };
254
+ }
255
+ function _getGradientTrace(value, entity, defaultToMin) {
256
+ const min = +value.points[0].position;
257
+ const max = +value.points[value.points.length - 1].position;
258
+ const attrPaths = parseLegacyPath(value.field);
259
+ for (let i = 0; i < attrPaths.length; i++) {
260
+ const attrPath = attrPaths[i];
261
+ let eValue = entity_1.Entity.GetValue({
262
+ entity: entity,
263
+ path: attrPath
264
+ });
265
+ if (typeof eValue == "string") {
266
+ eValue = Number(eValue);
267
+ }
268
+ if ((!eValue && eValue != 0) || isNaN(eValue)) {
269
+ continue;
270
+ }
271
+ if (eValue >= max) {
272
+ return { result: color_1.Color.ColorFromStr(value.points[value.points.length - 1].color), attrPath, eValue };
273
+ }
274
+ else if (eValue <= min) {
275
+ return { result: color_1.Color.ColorFromStr(value.points[0].color), attrPath, eValue };
276
+ }
277
+ for (let j = 0; j < value.points.length - 1; j++) {
278
+ const pointA = value.points[j];
279
+ const pointB = value.points[j + 1];
280
+ if (eValue >= pointA.position && eValue <= pointB.position) {
281
+ if (pointA.position == pointB.position) {
282
+ return { result: color_1.Color.ColorFromStr(pointA.color), attrPath, eValue };
283
+ }
284
+ const distance = (eValue - pointA.position) / (pointB.position - pointA.position);
285
+ const colorA = color_1.Color.ColorFromStr(pointA.color);
286
+ const colorB = color_1.Color.ColorFromStr(pointB.color);
287
+ return {
288
+ result: {
289
+ red: colorA.red + (colorB.red - colorA.red) * distance,
290
+ green: colorA.green + (colorB.green - colorA.green) * distance,
291
+ blue: colorA.blue + (colorB.blue - colorA.blue) * distance,
292
+ alpha: colorA.alpha + (colorB.alpha - colorA.alpha) * distance
293
+ },
294
+ attrPath,
295
+ eValue
296
+ };
297
+ }
298
+ }
299
+ }
300
+ // Fallback to min (static, no data path resolved).
301
+ return { result: color_1.Color.ColorFromStr(value.points[0].color), attrPath: null, eValue: null };
302
+ }
303
+ /**
304
+ * Like Calculate, but also returns an 'effective' key describing how the value
305
+ * was derived. See ITraceResult for the key format.
306
+ */
307
+ function TraceCalculate(params) {
86
308
  let { fields, tags, data, defaultValue, type } = params;
87
309
  // If params doesn't include a defaultValue, use null.
88
310
  // Though passing in undefined is valid!
@@ -90,7 +312,7 @@ var Calculator;
90
312
  defaultValue = null;
91
313
  }
92
314
  if (fields == null) {
93
- return defaultValue;
315
+ return { value: defaultValue, effective: null };
94
316
  }
95
317
  if (data == null || typeof data != "object") {
96
318
  data = {};
@@ -135,22 +357,21 @@ var Calculator;
135
357
  }
136
358
  return false;
137
359
  };
138
- // Calculate the value.
139
360
  let value = null;
361
+ let computedEffective = null;
140
362
  for (let i = 0; i < fieldsArr.length; i++) {
141
363
  let field = fieldsArr[i];
142
- if (field) {
143
- // Dereference.
144
- // We do this because we'll be modifying the field to fix bad data.
145
- // EDIT: commented out because the risk is low.
146
- // field = JSON.parse(JSON.stringify(field));
147
- }
364
+ // Intermediate trace parts — assembled into effective only if value resolves.
365
+ let traceType = null;
366
+ let tracePart1 = null;
367
+ let tracePart2 = null;
148
368
  // Bad data has it set to 'color' but expects the input to be a number.
149
369
  if (type == "number" && field.type == EValueType.Color) {
150
370
  field.type = EValueType.Input;
151
371
  }
152
372
  // Custom resolution.
153
373
  if (field.value instanceof Function) {
374
+ traceType = "fn";
154
375
  value = field.value(data, tags);
155
376
  if (type == "number") {
156
377
  if (typeof value == "string" && value != "" && value != null && value != undefined) {
@@ -184,6 +405,8 @@ var Calculator;
184
405
  break;
185
406
  }
186
407
  value = field.value;
408
+ traceType = "color";
409
+ tracePart1 = encodeEffective(value);
187
410
  value = assertColor(value);
188
411
  if (value && type == "string") {
189
412
  value = `rgba(${value.red},${value.green},${value.blue},${value.alpha})`;
@@ -193,10 +416,17 @@ var Calculator;
193
416
  if (type === "number") {
194
417
  break;
195
418
  }
196
- value = GetGradientValue(field.value, data, shouldRangesDefaultToMin);
197
- value = assertColor(value);
198
- if (value && type == "string") {
199
- value = `rgba(${value.red},${value.green},${value.blue},${value.alpha})`;
419
+ {
420
+ const gradTrace = _getGradientTrace(field.value, data, shouldRangesDefaultToMin);
421
+ value = assertColor(gradTrace.result);
422
+ traceType = "gradient";
423
+ if (gradTrace.attrPath != null) {
424
+ tracePart1 = encodeEffective(path_utils_1.PathUtils.Wrap(gradTrace.attrPath));
425
+ tracePart2 = encodeEffective(String(gradTrace.eValue));
426
+ }
427
+ if (value && type == "string") {
428
+ value = `rgba(${value.red},${value.green},${value.blue},${value.alpha})`;
429
+ }
200
430
  }
201
431
  break;
202
432
  case EValueType.RandomColor:
@@ -205,6 +435,7 @@ var Calculator;
205
435
  }
206
436
  value = color_1.Color.RandomColor();
207
437
  value = assertColor(value);
438
+ traceType = "random";
208
439
  if (value && type == "string") {
209
440
  value = `rgba(${value.red},${value.green},${value.blue},${value.alpha})`;
210
441
  }
@@ -213,12 +444,14 @@ var Calculator;
213
444
  if (type === "number") {
214
445
  break;
215
446
  }
216
- for (let i = 0; i < tags.length; i++) {
217
- const tag = tags[i];
447
+ for (let ti = 0; ti < tags.length; ti++) {
448
+ const tag = tags[ti];
218
449
  if (tag.Color) {
219
450
  value = color_1.Color.ColorFromStr(tag.Color);
220
451
  value = assertColor(value);
221
452
  if (value) {
453
+ traceType = "tag";
454
+ tracePart1 = encodeEffective(tag.Color);
222
455
  break;
223
456
  }
224
457
  }
@@ -232,31 +465,37 @@ var Calculator;
232
465
  // Eg: Result is a colour, a number, a string.
233
466
  // This means we first calculate the value, then validate it in the context of the desired type.
234
467
  case EValueType.Input:
235
- value = GetInputValue(field.value, data);
236
- if (value != null) {
237
- if (type == "number") {
238
- if (typeof value == "string" && value != "" && value != null && value != undefined) {
239
- value = Number(value);
240
- }
241
- else if (typeof value != "number") {
242
- value = null;
243
- }
244
- }
245
- else if (type == "string") {
246
- if (typeof value == "number") {
247
- value = String(value);
248
- }
249
- else if (typeof value == "object") {
250
- if (isColor(value)) {
251
- value = `rgba(${value.red},${value.green},${value.blue},${value.alpha})`;
468
+ {
469
+ const inputTemplate = String(field.value);
470
+ value = GetInputValue(field.value, data);
471
+ if (value != null) {
472
+ traceType = "input";
473
+ tracePart1 = encodeEffective(inputTemplate);
474
+ tracePart2 = encodeEffective(String(value));
475
+ if (type == "number") {
476
+ if (typeof value == "string" && value != "" && value != null && value != undefined) {
477
+ value = Number(value);
252
478
  }
253
- else {
479
+ else if (typeof value != "number") {
254
480
  value = null;
255
481
  }
256
482
  }
257
- }
258
- else if (type == "color") {
259
- value = assertColor(value);
483
+ else if (type == "string") {
484
+ if (typeof value == "number") {
485
+ value = String(value);
486
+ }
487
+ else if (typeof value == "object") {
488
+ if (isColor(value)) {
489
+ value = `rgba(${value.red},${value.green},${value.blue},${value.alpha})`;
490
+ }
491
+ else {
492
+ value = null;
493
+ }
494
+ }
495
+ }
496
+ else if (type == "color") {
497
+ value = assertColor(value);
498
+ }
260
499
  }
261
500
  }
262
501
  break;
@@ -264,31 +503,39 @@ var Calculator;
264
503
  // Eg: mapping a value to a Client File ID, or a colour, or a number.
265
504
  // This means we first calculate the value, then validate it in the context of the desired type.
266
505
  case EValueType.Mapping:
267
- value = GetMappingValue(field.value, data);
268
- if (value != null) {
269
- if (type == "number") {
270
- if (typeof value == "string" && value != "" && value != null && value != undefined) {
271
- value = Number(value);
272
- }
273
- else if (typeof value != "number") {
274
- value = null;
275
- }
276
- }
277
- else if (type == "string") {
278
- if (typeof value == "number") {
279
- value = String(value);
506
+ {
507
+ const mapTrace = _getMappingTrace(field.value, data);
508
+ value = mapTrace.result;
509
+ if (value != null) {
510
+ traceType = "mapping";
511
+ if (mapTrace.attrPath != null) {
512
+ tracePart1 = encodeEffective(path_utils_1.PathUtils.Wrap(mapTrace.attrPath));
513
+ tracePart2 = encodeEffective(String(mapTrace.eValue));
280
514
  }
281
- else if (typeof value == "object") {
282
- if (isColor(value)) {
283
- value = `rgba(${value.red},${value.green},${value.blue},${value.alpha})`;
515
+ if (type == "number") {
516
+ if (typeof value == "string" && value != "" && value != null && value != undefined) {
517
+ value = Number(value);
284
518
  }
285
- else {
519
+ else if (typeof value != "number") {
286
520
  value = null;
287
521
  }
288
522
  }
289
- }
290
- else if (type == "color") {
291
- value = assertColor(typeof value === "number" ? String(value) : value);
523
+ else if (type == "string") {
524
+ if (typeof value == "number") {
525
+ value = String(value);
526
+ }
527
+ else if (typeof value == "object") {
528
+ if (isColor(value)) {
529
+ value = `rgba(${value.red},${value.green},${value.blue},${value.alpha})`;
530
+ }
531
+ else {
532
+ value = null;
533
+ }
534
+ }
535
+ }
536
+ else if (type == "color") {
537
+ value = assertColor(typeof value === "number" ? String(value) : value);
538
+ }
292
539
  }
293
540
  }
294
541
  break;
@@ -312,11 +559,34 @@ var Calculator;
312
559
  }
313
560
  }
314
561
  if (value != null) {
562
+ if (traceType != null) {
563
+ if (tracePart1 != null && tracePart2 != null) {
564
+ computedEffective = `f${i}:${traceType}:${tracePart1}:${tracePart2}`;
565
+ }
566
+ else if (tracePart1 != null) {
567
+ computedEffective = `f${i}:${traceType}:${tracePart1}`;
568
+ }
569
+ else {
570
+ computedEffective = `f${i}:${traceType}`;
571
+ }
572
+ }
315
573
  break;
316
574
  }
317
575
  }
318
- // Return the value or default.
319
- return value != null ? value : defaultValue;
576
+ return {
577
+ value: value != null ? value : defaultValue,
578
+ effective: value != null ? computedEffective : null
579
+ };
580
+ }
581
+ Calculator.TraceCalculate = TraceCalculate;
582
+ /**
583
+ * Calculates a value-type 'T' based on given set of fields.
584
+ * The supplied data + tags are fed into the calculation.
585
+ * When a value fails to be calculated, the 'defaultValue' is returned.
586
+ * If no 'defaultValue' is provided, then 'null' is returned.
587
+ */
588
+ function Calculate(params) {
589
+ return TraceCalculate(params).value;
320
590
  }
321
591
  Calculator.Calculate = Calculate;
322
592
  /**
@@ -328,13 +598,7 @@ var Calculator;
328
598
  * @returns
329
599
  */
330
600
  function GetValue(fields, entity = {}, tags = []) {
331
- return Calculate({
332
- fields: fields,
333
- data: entity,
334
- defaultValue: null,
335
- tags: tags,
336
- type: "any"
337
- });
601
+ return TraceGetValue(fields, entity, tags).value;
338
602
  }
339
603
  Calculator.GetValue = GetValue;
340
604
  /**
@@ -345,13 +609,7 @@ var Calculator;
345
609
  * @param tags
346
610
  */
347
611
  function GetColor(fields, entity = {}, tags = []) {
348
- return Calculate({
349
- fields: fields,
350
- data: entity,
351
- defaultValue: null,
352
- tags: tags,
353
- type: "color"
354
- });
612
+ return TraceGetColor(fields, entity, tags).value;
355
613
  }
356
614
  Calculator.GetColor = GetColor;
357
615
  /**
@@ -363,13 +621,7 @@ var Calculator;
363
621
  * @returns
364
622
  */
365
623
  function GetNumber(fields, entity = {}, tags = []) {
366
- return Calculate({
367
- fields: fields,
368
- data: entity,
369
- defaultValue: null,
370
- tags: tags,
371
- type: "number"
372
- });
624
+ return TraceGetNumber(fields, entity, tags).value;
373
625
  }
374
626
  Calculator.GetNumber = GetNumber;
375
627
  /**
@@ -381,15 +633,61 @@ var Calculator;
381
633
  * @returns
382
634
  */
383
635
  function GetString(fields, entity = {}, tags = []) {
384
- return Calculate({
385
- fields: fields,
636
+ return TraceGetString(fields, entity, tags).value;
637
+ }
638
+ Calculator.GetString = GetString;
639
+ /**
640
+ * Like GetValue, but also returns 'effective' describing how the value was derived.
641
+ */
642
+ function TraceGetValue(fields, entity = {}, tags = []) {
643
+ return TraceCalculate({
644
+ fields,
645
+ data: entity,
646
+ defaultValue: null,
647
+ tags,
648
+ type: "any"
649
+ });
650
+ }
651
+ Calculator.TraceGetValue = TraceGetValue;
652
+ /**
653
+ * Like GetColor, but also returns 'effective' describing how the color was derived.
654
+ */
655
+ function TraceGetColor(fields, entity = {}, tags = []) {
656
+ return TraceCalculate({
657
+ fields,
658
+ data: entity,
659
+ defaultValue: null,
660
+ tags,
661
+ type: "color"
662
+ });
663
+ }
664
+ Calculator.TraceGetColor = TraceGetColor;
665
+ /**
666
+ * Like GetNumber, but also returns 'effective' describing how the number was derived.
667
+ */
668
+ function TraceGetNumber(fields, entity = {}, tags = []) {
669
+ return TraceCalculate({
670
+ fields,
386
671
  data: entity,
387
672
  defaultValue: null,
388
- tags: tags,
673
+ tags,
674
+ type: "number"
675
+ });
676
+ }
677
+ Calculator.TraceGetNumber = TraceGetNumber;
678
+ /**
679
+ * Like GetString, but also returns 'effective' describing how the string was derived.
680
+ */
681
+ function TraceGetString(fields, entity = {}, tags = []) {
682
+ return TraceCalculate({
683
+ fields,
684
+ data: entity,
685
+ defaultValue: null,
686
+ tags,
389
687
  type: "string"
390
688
  });
391
689
  }
392
- Calculator.GetString = GetString;
690
+ Calculator.TraceGetString = TraceGetString;
393
691
  /**
394
692
  * Calculates a mapping value. This can return any value type.
395
693
  * It is intended to be parsed and validated within a value-type context. Eg: GetColor, GetNumber, GetString.
@@ -398,114 +696,7 @@ var Calculator;
398
696
  * @returns
399
697
  */
400
698
  function GetMappingValue(value, entity) {
401
- const attrPaths = parseLegacyPath(value.field);
402
- for (let i = 0; i < attrPaths.length; i++) {
403
- const attrPath = attrPaths[i];
404
- let eValue = entity_1.Entity.GetValue({
405
- entity: entity,
406
- path: attrPath
407
- });
408
- let isValueNum = !isNaN(+eValue);
409
- if (eValue == null) {
410
- isValueNum = false;
411
- }
412
- for (let i = 0; i < value.values.length; i++) {
413
- const option = value.values[i];
414
- const fieldValues = Array.isArray(option.fieldValue) ? option.fieldValue : [option.fieldValue];
415
- // Check each field value in the array.
416
- for (let j = 0; j < fieldValues.length; j++) {
417
- let mapValue = fieldValues[j];
418
- // If mapValue is prefixed with "JS:", we evaluate it as JavaScript.
419
- // This lets us do things like JS:Boolean("${}") as a quick way to map 'existence' to a target value.
420
- if (typeof mapValue === "string" && mapValue.startsWith("JS:")) {
421
- try {
422
- let jsEval = mapValue.replace("JS:", "").trim();
423
- const attrPathStr = path_utils_1.PathUtils.Wrap(attrPath);
424
- jsEval = jsEval.replace("${}", "${" + attrPathStr + "}");
425
- jsEval = bruce_variable_1.BruceVariable.SwapValues({
426
- str: jsEval,
427
- entity: entity
428
- });
429
- // https://rollupjs.org/guide/en/#avoiding-eval
430
- // This stops eval warning.
431
- const eval2 = eval;
432
- mapValue = eval2(jsEval);
433
- // We currently expect eval to return a validity bool.
434
- // So it either matches and we return it, or it doesn't and we continue.
435
- if (mapValue) {
436
- return option.appliedValue;
437
- }
438
- else {
439
- continue;
440
- }
441
- }
442
- catch (exception) {
443
- const e = exception;
444
- let suppress = false;
445
- if (e && typeof e == "object") {
446
- const msg = e.message;
447
- suppress = !!msg && (msg.includes("Unexpected end") || msg.includes("got end of script"));
448
- }
449
- if (!suppress) {
450
- console.error(e);
451
- }
452
- // Eval failed, therefor not a valid mapping-row.
453
- continue;
454
- }
455
- }
456
- let isMapValueNum = !isNaN(+mapValue);
457
- if (isMapValueNum == null) {
458
- isMapValueNum = false;
459
- }
460
- if (isValueNum && (isMapValueNum || (typeof mapValue === "string" && mapValue.includes("-")))) {
461
- if (+mapValue == +eValue) {
462
- return option.appliedValue;
463
- }
464
- const mapSplit = mapValue.split("-");
465
- if (mapSplit.length == 2) {
466
- const min = mapSplit[0];
467
- const max = mapSplit[1];
468
- if (min != "") {
469
- if (+eValue < +min) {
470
- continue;
471
- }
472
- }
473
- if (max != "") {
474
- if (+eValue > +max) {
475
- continue;
476
- }
477
- }
478
- if (min == "" && max == "") {
479
- continue;
480
- }
481
- return option.appliedValue;
482
- }
483
- }
484
- else {
485
- if (mapValue == eValue) {
486
- return option.appliedValue;
487
- }
488
- // Case where Entity value is a boolean but the mapping value is a string.
489
- // Common as mapping value is typically a user-entered string.
490
- else if (typeof eValue === "boolean" && typeof mapValue === "string") {
491
- const eValueStr = eValue ? "true" : "false";
492
- if (mapValue.toLowerCase() == eValueStr) {
493
- return option.appliedValue;
494
- }
495
- }
496
- // Handling possible case where the opposite is true.
497
- // Have not seen this happen yet, but preparing for any future cases.
498
- else if (typeof mapValue === "boolean" && typeof eValue === "string") {
499
- const mapValueStr = mapValue ? "true" : "false";
500
- if (mapValueStr == eValue.toLowerCase()) {
501
- return option.appliedValue;
502
- }
503
- }
504
- }
505
- }
506
- }
507
- }
508
- return null;
699
+ return _getMappingTrace(value, entity).result;
509
700
  }
510
701
  Calculator.GetMappingValue = GetMappingValue;
511
702
  /**
@@ -518,47 +709,7 @@ var Calculator;
518
709
  * @returns
519
710
  */
520
711
  function GetGradientValue(value, entity, defaultToMin) {
521
- const min = +value.points[0].position;
522
- const max = +value.points[value.points.length - 1].position;
523
- const attrPaths = parseLegacyPath(value.field);
524
- for (let i = 0; i < attrPaths.length; i++) {
525
- const attrPath = attrPaths[i];
526
- let eValue = entity_1.Entity.GetValue({
527
- entity: entity,
528
- path: attrPath
529
- });
530
- if (typeof eValue == "string") {
531
- eValue = Number(eValue);
532
- }
533
- if ((!eValue && eValue != 0) || isNaN(eValue)) {
534
- continue;
535
- }
536
- if (eValue >= max) {
537
- return color_1.Color.ColorFromStr(value.points[value.points.length - 1].color);
538
- }
539
- else if (eValue <= min) {
540
- return color_1.Color.ColorFromStr(value.points[0].color);
541
- }
542
- for (let i = 0; i < value.points.length - 1; i++) {
543
- const pointA = value.points[i];
544
- const pointB = value.points[i + 1];
545
- if (eValue >= pointA.position && eValue <= pointB.position) {
546
- if (pointA.position == pointB.position) {
547
- return color_1.Color.ColorFromStr(pointA.color);
548
- }
549
- const distance = (eValue - pointA.position) / (pointB.position - pointA.position);
550
- const colorA = color_1.Color.ColorFromStr(pointA.color);
551
- const colorB = color_1.Color.ColorFromStr(pointB.color);
552
- return {
553
- red: colorA.red + (colorB.red - colorA.red) * distance,
554
- green: colorA.green + (colorB.green - colorA.green) * distance,
555
- blue: colorA.blue + (colorB.blue - colorA.blue) * distance,
556
- alpha: colorA.alpha + (colorB.alpha - colorA.alpha) * distance
557
- };
558
- }
559
- }
560
- }
561
- return color_1.Color.ColorFromStr(value.points[0].color);
712
+ return _getGradientTrace(value, entity, defaultToMin).result;
562
713
  }
563
714
  Calculator.GetGradientValue = GetGradientValue;
564
715
  /**