@oicl/openbridge-webcomponents 2.0.0-next.121 → 2.0.0-next.123

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 (38) hide show
  1. package/bundle/openbridge-webcomponents.bundle.js +252 -53
  2. package/bundle/openbridge-webcomponents.bundle.js.map +1 -1
  3. package/custom-elements.json +66 -17
  4. package/dist/automation/automation-tank/automation-tank.css.js +94 -14
  5. package/dist/automation/automation-tank/automation-tank.css.js.map +1 -1
  6. package/dist/automation/automation-tank/automation-tank.d.ts +53 -5
  7. package/dist/automation/automation-tank/automation-tank.d.ts.map +1 -1
  8. package/dist/automation/automation-tank/automation-tank.js +39 -20
  9. package/dist/automation/automation-tank/automation-tank.js.map +1 -1
  10. package/dist/building-blocks/readout-block/readout-block.d.ts +27 -1
  11. package/dist/building-blocks/readout-block/readout-block.d.ts.map +1 -1
  12. package/dist/building-blocks/readout-block/readout-block.js +31 -10
  13. package/dist/building-blocks/readout-block/readout-block.js.map +1 -1
  14. package/dist/navigation-instruments/compass-sector/compass-sector.css.js +10 -0
  15. package/dist/navigation-instruments/compass-sector/compass-sector.css.js.map +1 -1
  16. package/dist/navigation-instruments/readout/readout-formatters.d.ts +61 -0
  17. package/dist/navigation-instruments/readout/readout-formatters.d.ts.map +1 -1
  18. package/dist/navigation-instruments/readout/readout-formatters.js +35 -2
  19. package/dist/navigation-instruments/readout/readout-formatters.js.map +1 -1
  20. package/dist/navigation-instruments/readout/readout.d.ts +19 -2
  21. package/dist/navigation-instruments/readout/readout.d.ts.map +1 -1
  22. package/dist/navigation-instruments/readout/readout.js +18 -4
  23. package/dist/navigation-instruments/readout/readout.js.map +1 -1
  24. package/dist/navigation-instruments/readout-list/readout-list.d.ts.map +1 -1
  25. package/dist/navigation-instruments/readout-list/readout-list.js +6 -3
  26. package/dist/navigation-instruments/readout-list/readout-list.js.map +1 -1
  27. package/dist/navigation-instruments/readout-list-item/readout-list-item.d.ts +19 -2
  28. package/dist/navigation-instruments/readout-list-item/readout-list-item.d.ts.map +1 -1
  29. package/dist/navigation-instruments/readout-list-item/readout-list-item.js +18 -4
  30. package/dist/navigation-instruments/readout-list-item/readout-list-item.js.map +1 -1
  31. package/dist/navigation-instruments/thruster/thruster.d.ts.map +1 -1
  32. package/dist/navigation-instruments/thruster/thruster.js +1 -0
  33. package/dist/navigation-instruments/thruster/thruster.js.map +1 -1
  34. package/dist/navigation-instruments/watch/watch.css.js +4 -0
  35. package/dist/navigation-instruments/watch/watch.css.js.map +1 -1
  36. package/dist/navigation-instruments/watch-flat/watch-flat.css.js +4 -0
  37. package/dist/navigation-instruments/watch-flat/watch-flat.css.js.map +1 -1
  38. package/package.json +1 -1
@@ -14,6 +14,67 @@ export declare enum ReadoutValueType {
14
14
  }
15
15
  /** Whether `value` is one of the supported {@link ReadoutValueType} values. */
16
16
  export declare function isReadoutValueType(value: unknown): value is ReadoutValueType;
17
+ /**
18
+ * The largest `fractionDigits` `Number.prototype.toFixed` accepts. Reused as the
19
+ * `maxDigits` ceiling so the two bounds stay symmetric — a wider reserve than
20
+ * this is meaningless anyway, and an unbounded one builds a huge string.
21
+ */
22
+ export declare const READOUT_MAX_DIGITS = 100;
23
+ /**
24
+ * Throws when `fractionDigits` is outside the range `toFixed` accepts.
25
+ *
26
+ * It is a public property that reaches `Number.prototype.toFixed` unchanged, so
27
+ * `-1`, `101` or `Infinity` already throw a bare
28
+ * `RangeError: toFixed() digits argument must be between 0 and 100` from inside
29
+ * the update cycle. This replaces that with an error naming the component and
30
+ * the offending value.
31
+ *
32
+ * Deliberately not clamped: `fractionDigits` sets the PRECISION of a reading, so
33
+ * quietly turning `-1` into `0` would drop decimals from a displayed value
34
+ * without telling anyone. It is a configuration mistake, fixable only in code —
35
+ * the same class as a bad `valueType`, and treated the same way.
36
+ *
37
+ * Values `toFixed` itself tolerates are left alone: `NaN` reads as `0`, and a
38
+ * fractional count truncates (`2.7` → `2`).
39
+ */
40
+ export declare function assertReadoutFractionDigits(tagName: string, fractionDigits: number | null | undefined): void;
41
+ /**
42
+ * A digit count used for WIDTH RESERVATION, normalised to a non-negative integer
43
+ * no greater than {@link READOUT_MAX_DIGITS}.
44
+ *
45
+ * Deliberately named for the role rather than for `maxDigits`: both `maxDigits`
46
+ * and the fraction count `obc-readout-list` reserves with are the same kind of
47
+ * input — a count handed to `String.prototype.repeat` — and must be bounded the
48
+ * same way. `fractionDigits` as a FORMAT input is a different contract and is
49
+ * rejected instead; see {@link assertReadoutFractionDigits}.
50
+ *
51
+ * Clamped rather than rejected because it only reserves width, so bounding it
52
+ * changes no reading's meaning, and the surrounding code already absorbs bad
53
+ * values silently (`Math.max(count, 1)`, `NaN` repeating to `''`). What is not
54
+ * absorbed is `Infinity`, which throws out of `String.prototype.repeat`, and a
55
+ * large finite count, which builds a reserver string long enough to matter —
56
+ * both are capped here.
57
+ */
58
+ export declare function resolveReadoutDigitCount(count: number | null | undefined): number;
59
+ /**
60
+ * Whether a digit-count knob failed to arrive as a number: `null`, `undefined`
61
+ * or `NaN`.
62
+ *
63
+ * A missing knob renders the READING unavailable (the dash) rather than
64
+ * silently formatting with a default the author never chose. `fractionDigits`
65
+ * is typically written by the consuming system, and a runtime failure there
66
+ * produces exactly these values — formatting with `0` instead would print a
67
+ * critical `0.4` as a plausible-looking `0`, which an operator cannot tell
68
+ * apart from a healthy reading. The dash makes the failure visible.
69
+ *
70
+ * This is a third contract besides throw and clamp: a finite out-of-range
71
+ * `fractionDigits` is a programmer error and throws
72
+ * ({@link assertReadoutFractionDigits}); a finite out-of-range `maxDigits` is
73
+ * width-only and clamps ({@link resolveReadoutDigitCount}); a knob that never
74
+ * arrived is a runtime data condition and dashes the reading, the same class
75
+ * as a `NaN` value.
76
+ */
77
+ export declare function isReadoutDigitCountMissing(count: number | null | undefined): boolean;
17
78
  /**
18
79
  * Throws when `valueType` is not a supported value, or when `value` is text but
19
80
  * `valueType` is `number`.
@@ -1 +1 @@
1
- {"version":3,"file":"readout-formatters.d.ts","sourceRoot":"","sources":["../../../src/navigation-instruments/readout/readout-formatters.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,2BAA2B,GAAG;IACxC,eAAe,EAAE,OAAO,CAAC;IACzB,cAAc,EAAE,MAAM,CAAC;IACvB,cAAc,EAAE,MAAM,CAAC;CACxB,CAAC;AAEF;;;;GAIG;AACH,oBAAY,gBAAgB;IAC1B,MAAM,WAAW;IACjB,IAAI,SAAS;CACd;AAID,+EAA+E;AAC/E,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,gBAAgB,CAE5E;AAMD;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,sBAAsB,CACpC,OAAO,EAAE,MAAM,EACf,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,GAAG,SAAS,EACzC,SAAS,EAAE,gBAAgB,GAC1B,IAAI,CAyBN;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,0BAA0B,CACxC,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,GAAG,SAAS,EACzC,SAAS,EAAE,gBAAgB,GAC1B,MAAM,GAAG,SAAS,CAgBpB;AAED,+EAA+E;AAC/E,wBAAgB,uBAAuB,CACrC,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,GAAG,SAAS,EACzC,SAAS,EAAE,gBAAgB,GAC1B,MAAM,GAAG,SAAS,CAUpB;AAED;;;;;;;;;GASG;AACH,eAAO,MAAM,wBAAwB,WAAW,CAAC;AA+BjD,wBAAgB,kBAAkB,CAChC,KAAK,EAAE,MAAM,GAAG,SAAS,EACzB,OAAO,EAAE,2BAA2B,GACnC,MAAM,CAUR;AAED,wBAAgB,uBAAuB,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CASjE;AAED,wBAAgB,YAAY,CAC1B,KAAK,EAAE,MAAM,GAAG,SAAS,EACzB,EAAC,eAAe,EAAE,cAAc,EAAE,cAAc,EAAC,EAAE,2BAA2B,GAC7E,MAAM,CAeR"}
1
+ {"version":3,"file":"readout-formatters.d.ts","sourceRoot":"","sources":["../../../src/navigation-instruments/readout/readout-formatters.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,2BAA2B,GAAG;IACxC,eAAe,EAAE,OAAO,CAAC;IACzB,cAAc,EAAE,MAAM,CAAC;IACvB,cAAc,EAAE,MAAM,CAAC;CACxB,CAAC;AAEF;;;;GAIG;AACH,oBAAY,gBAAgB;IAC1B,MAAM,WAAW;IACjB,IAAI,SAAS;CACd;AAID,+EAA+E;AAC/E,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,gBAAgB,CAE5E;AAED;;;;GAIG;AACH,eAAO,MAAM,kBAAkB,MAAM,CAAC;AAkBtC;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,2BAA2B,CACzC,OAAO,EAAE,MAAM,EACf,cAAc,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GACxC,IAAI,CAWN;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,wBAAwB,CACtC,KAAK,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GAC/B,MAAM,CAQR;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,0BAA0B,CACxC,KAAK,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GAC/B,OAAO,CAET;AAMD;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,sBAAsB,CACpC,OAAO,EAAE,MAAM,EACf,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,GAAG,SAAS,EACzC,SAAS,EAAE,gBAAgB,GAC1B,IAAI,CAyBN;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,0BAA0B,CACxC,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,GAAG,SAAS,EACzC,SAAS,EAAE,gBAAgB,GAC1B,MAAM,GAAG,SAAS,CAgBpB;AAED,+EAA+E;AAC/E,wBAAgB,uBAAuB,CACrC,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,GAAG,SAAS,EACzC,SAAS,EAAE,gBAAgB,GAC1B,MAAM,GAAG,SAAS,CAUpB;AAED;;;;;;;;;GASG;AACH,eAAO,MAAM,wBAAwB,WAAW,CAAC;AAuCjD,wBAAgB,kBAAkB,CAChC,KAAK,EAAE,MAAM,GAAG,SAAS,EACzB,OAAO,EAAE,2BAA2B,GACnC,MAAM,CAmBR;AAED,wBAAgB,uBAAuB,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CASjE;AAED,wBAAgB,YAAY,CAC1B,KAAK,EAAE,MAAM,GAAG,SAAS,EACzB,EAAC,eAAe,EAAE,cAAc,EAAE,cAAc,EAAC,EAAE,2BAA2B,GAC7E,MAAM,CAeR"}
@@ -7,6 +7,34 @@ const READOUT_VALUE_TYPES = Object.values(ReadoutValueType);
7
7
  function isReadoutValueType(value) {
8
8
  return typeof value === "string" && READOUT_VALUE_TYPES.includes(value);
9
9
  }
10
+ const READOUT_MAX_DIGITS = 100;
11
+ function effectiveFractionDigits(fractionDigits) {
12
+ if (fractionDigits === null || fractionDigits === void 0) {
13
+ return 0;
14
+ }
15
+ return Number.isNaN(fractionDigits) ? 0 : Math.trunc(fractionDigits);
16
+ }
17
+ function assertReadoutFractionDigits(tagName, fractionDigits) {
18
+ const digits = effectiveFractionDigits(fractionDigits);
19
+ if (Number.isFinite(digits) && digits >= 0 && digits <= READOUT_MAX_DIGITS) {
20
+ return;
21
+ }
22
+ throw new RangeError(
23
+ // `String`, not `JSON.stringify`: the latter serialises `Infinity` and
24
+ // `NaN` to `null`, hiding the very value being rejected.
25
+ `<${tagName}>: fractionDigits must be between 0 and ${READOUT_MAX_DIGITS} (got ${String(fractionDigits)}).`
26
+ );
27
+ }
28
+ function resolveReadoutDigitCount(count) {
29
+ const digits = Math.trunc(count ?? 0);
30
+ if (Number.isNaN(digits) || digits <= 0) {
31
+ return 0;
32
+ }
33
+ return Math.min(digits, READOUT_MAX_DIGITS);
34
+ }
35
+ function isReadoutDigitCountMissing(count) {
36
+ return count === null || count === void 0 || Number.isNaN(count);
37
+ }
10
38
  function isBlank(value) {
11
39
  return value.trim() === "";
12
40
  }
@@ -51,9 +79,10 @@ const READOUT_UNAVAILABLE_DASH = "‒";
51
79
  function dashedGenerator({
52
80
  showZeroPadding,
53
81
  minValueLength,
54
- fractionDigits
82
+ fractionDigits: rawFractionDigits
55
83
  }) {
56
84
  const visibleDigits = showZeroPadding ? Math.max(minValueLength, 1) : 1;
85
+ const fractionDigits = Number.isNaN(rawFractionDigits) ? 0 : rawFractionDigits;
57
86
  if (fractionDigits < 1) {
58
87
  return READOUT_UNAVAILABLE_DASH.repeat(visibleDigits);
59
88
  }
@@ -61,7 +90,7 @@ function dashedGenerator({
61
90
  return READOUT_UNAVAILABLE_DASH.repeat(Math.max(integerDigits, 1)) + "." + READOUT_UNAVAILABLE_DASH.repeat(fractionDigits);
62
91
  }
63
92
  function formatNumericValue(value, options) {
64
- if (value === void 0 || !Number.isFinite(value)) {
93
+ if (value === void 0 || !Number.isFinite(value) || Number.isNaN(options.fractionDigits)) {
65
94
  return dashedGenerator(options);
66
95
  }
67
96
  return value.toFixed(options.fractionDigits);
@@ -90,13 +119,17 @@ function getHintZeros(value, { showZeroPadding, minValueLength, fractionDigits }
90
119
  return "";
91
120
  }
92
121
  export {
122
+ READOUT_MAX_DIGITS,
93
123
  READOUT_UNAVAILABLE_DASH,
94
124
  ReadoutValueType,
125
+ assertReadoutFractionDigits,
95
126
  assertReadoutValueType,
96
127
  formatNumericValue,
97
128
  getHintZeros,
129
+ isReadoutDigitCountMissing,
98
130
  isReadoutValueType,
99
131
  readoutFormattedInteger,
132
+ resolveReadoutDigitCount,
100
133
  resolveReadoutNumericValue,
101
134
  resolveReadoutTextValue
102
135
  };
@@ -1 +1 @@
1
- {"version":3,"file":"readout-formatters.js","sources":["../../../src/navigation-instruments/readout/readout-formatters.ts"],"sourcesContent":["export type ReadoutNumericFormatOptions = {\n showZeroPadding: boolean;\n minValueLength: number;\n fractionDigits: number;\n};\n\n/**\n * How a readout's `value` is interpreted.\n * - `number`: formatted via `fractionDigits` / `maxDigits`.\n * - `text`: rendered verbatim, with the numeric format options ignored.\n */\nexport enum ReadoutValueType {\n number = 'number',\n text = 'text',\n}\n\nconst READOUT_VALUE_TYPES: readonly string[] = Object.values(ReadoutValueType);\n\n/** Whether `value` is one of the supported {@link ReadoutValueType} values. */\nexport function isReadoutValueType(value: unknown): value is ReadoutValueType {\n return typeof value === 'string' && READOUT_VALUE_TYPES.includes(value);\n}\n\nfunction isBlank(value: string): boolean {\n return value.trim() === '';\n}\n\n/**\n * Throws when `valueType` is not a supported value, or when `value` is text but\n * `valueType` is `number`.\n *\n * `valueType` is validated first because an attribute carries an unchecked\n * string: a typo such as `valuetype=\"strng\"` matches neither mode, so every\n * mode check falls through and the readout silently renders the unavailable\n * dash — the opposite of the loud failure this contract exists to give.\n * `undefined`/`null` are allowed and mean \"use the default\".\n *\n * Attributes are always strings, so a numeric-looking string (`value=\"10.12\"`)\n * is accepted and parsed. Blank strings resolve to the unavailable dash rather\n * than throwing — `value=\"${maybeUndefined}\"` is a common template shape, and\n * `Number('')` is `0`, a silently wrong reading.\n */\nexport function assertReadoutValueType(\n tagName: string,\n value: number | string | null | undefined,\n valueType: ReadoutValueType\n): void {\n // `undefined`/`null` mean \"use the default\", matching how the components and\n // the resolvers treat an unset `valueType`.\n const resolved = valueType ?? ReadoutValueType.number;\n if (!isReadoutValueType(resolved)) {\n throw new TypeError(\n `<${tagName}>: valueType must be ` +\n `${READOUT_VALUE_TYPES.map((t) => `\"${t}\"`).join(' or ')} ` +\n `(got ${JSON.stringify(valueType)}).`\n );\n }\n if (\n resolved !== ReadoutValueType.number ||\n typeof value !== 'string' ||\n isBlank(value)\n ) {\n return;\n }\n if (Number.isFinite(Number(value))) {\n return;\n }\n throw new TypeError(\n `<${tagName}>: value must be a number when valueType is \"number\" ` +\n `(got ${JSON.stringify(value)}). Set valueType=\"text\" to render text.`\n );\n}\n\n/**\n * The value as a number, or `undefined` when it is text / unavailable.\n *\n * A non-finite number (`NaN`, `±Infinity`) counts as unavailable and renders the\n * dash, the same as `null`. `NaN` is a runtime data condition — a sensor\n * dropout, a `0/0`, a bad parse — not a programmer error, so it must not throw;\n * and `value.toFixed()` would otherwise render the literal text `\"NaN\"` /\n * `\"Infinity\"` in place of a reading. This also makes the number path agree with\n * the string path below, which has always resolved a non-finite string to\n * `undefined` — before this, `<obc-readout value=\"NaN\">` rendered a dash while\n * `.value=${NaN}` rendered `\"NaN\"`.\n */\nexport function resolveReadoutNumericValue(\n value: number | string | null | undefined,\n valueType: ReadoutValueType\n): number | undefined {\n if (\n valueType === ReadoutValueType.text ||\n value === null ||\n value === undefined\n ) {\n return undefined;\n }\n if (typeof value === 'number') {\n return Number.isFinite(value) ? value : undefined;\n }\n if (isBlank(value)) {\n return undefined;\n }\n const parsed = Number(value);\n return Number.isFinite(parsed) ? parsed : undefined;\n}\n\n/** The value as display text, or `undefined` when not in text mode / blank. */\nexport function resolveReadoutTextValue(\n value: number | string | null | undefined,\n valueType: ReadoutValueType\n): string | undefined {\n if (\n valueType !== ReadoutValueType.text ||\n value === null ||\n value === undefined\n ) {\n return undefined;\n }\n const text = typeof value === 'number' ? String(value) : value;\n return isBlank(text) ? undefined : text;\n}\n\n/**\n * The character used for an unavailable (\"no reading\") value.\n *\n * U+2012 FIGURE DASH, not the ASCII hyphen-minus: it is defined to be the same\n * width as a digit, so the placeholder lines up with the reading it stands in\n * for. Measured in Noto Sans with tabular figures at `size=\"m\"` — digit 13.02px,\n * U+2012 13.02px, U+002D 7.02px, en dash 11.02px, em dash 22.02px. With a\n * hyphen, `-.--` sat 46% narrow per character and its decimal point missed the\n * reading's; with U+2012 the point and every fraction position align exactly.\n */\nexport const READOUT_UNAVAILABLE_DASH = '\\u2012';\n\n/**\n * The unavailable (\"no reading\") text: a single integer dash plus one dash per\n * fraction digit — `\\u2012` at `fractionDigits` 0, `\\u2012.\\u2012\\u2012` at 2.\n *\n * Deliberately NOT filled out to `maxDigits`: the placeholder stays short and\n * sits at the right edge of the reserved width, rather than spelling out every\n * reserved digit position. `maxDigits` still reserves the width, so nothing\n * shifts when a reading arrives.\n */\nfunction dashedGenerator({\n showZeroPadding,\n minValueLength,\n fractionDigits,\n}: ReadoutNumericFormatOptions): string {\n const visibleDigits = showZeroPadding ? Math.max(minValueLength, 1) : 1;\n\n if (fractionDigits < 1) {\n return READOUT_UNAVAILABLE_DASH.repeat(visibleDigits);\n }\n\n const integerDigits = visibleDigits - fractionDigits;\n\n return (\n READOUT_UNAVAILABLE_DASH.repeat(Math.max(integerDigits, 1)) +\n '.' +\n READOUT_UNAVAILABLE_DASH.repeat(fractionDigits)\n );\n}\n\nexport function formatNumericValue(\n value: number | undefined,\n options: ReadoutNumericFormatOptions\n): string {\n // Non-finite counts as unavailable here too, not only in\n // `resolveReadoutNumericValue`. Every caller normalises today, but this\n // function is exported, and `NaN.toFixed()` would put the literal text\n // \"NaN\" where a reading belongs — the exact failure this change removes.\n if (value === undefined || !Number.isFinite(value)) {\n return dashedGenerator(options);\n }\n\n return value.toFixed(options.fractionDigits);\n}\n\nexport function readoutFormattedInteger(valueText: string): number {\n const t = valueText.trim();\n if (!t) {\n return 0;\n }\n\n const rest = t.startsWith('-') ? t.slice(1) : t;\n const dot = rest.indexOf('.');\n return dot === -1 ? rest.length : dot;\n}\n\nexport function getHintZeros(\n value: number | undefined,\n {showZeroPadding, minValueLength, fractionDigits}: ReadoutNumericFormatOptions\n): string {\n const formattedValue = formatNumericValue(value, {\n showZeroPadding,\n minValueLength,\n fractionDigits,\n });\n const dotLength = fractionDigits > 0 ? 1 : 0;\n const integerLength = formattedValue.length - dotLength;\n const hintedDigits = Math.max(minValueLength - integerLength, 0);\n\n if (hintedDigits > 0) {\n return '0'.repeat(hintedDigits);\n }\n\n return '';\n}\n"],"names":["ReadoutValueType"],"mappings":"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"}
1
+ {"version":3,"file":"readout-formatters.js","sources":["../../../src/navigation-instruments/readout/readout-formatters.ts"],"sourcesContent":["export type ReadoutNumericFormatOptions = {\n showZeroPadding: boolean;\n minValueLength: number;\n fractionDigits: number;\n};\n\n/**\n * How a readout's `value` is interpreted.\n * - `number`: formatted via `fractionDigits` / `maxDigits`.\n * - `text`: rendered verbatim, with the numeric format options ignored.\n */\nexport enum ReadoutValueType {\n number = 'number',\n text = 'text',\n}\n\nconst READOUT_VALUE_TYPES: readonly string[] = Object.values(ReadoutValueType);\n\n/** Whether `value` is one of the supported {@link ReadoutValueType} values. */\nexport function isReadoutValueType(value: unknown): value is ReadoutValueType {\n return typeof value === 'string' && READOUT_VALUE_TYPES.includes(value);\n}\n\n/**\n * The largest `fractionDigits` `Number.prototype.toFixed` accepts. Reused as the\n * `maxDigits` ceiling so the two bounds stay symmetric — a wider reserve than\n * this is meaningless anyway, and an unbounded one builds a huge string.\n */\nexport const READOUT_MAX_DIGITS = 100;\n\n/**\n * `fractionDigits` as `toFixed` will actually read it: `NaN` and an unset value\n * count as 0, and a fractional count truncates.\n */\nfunction effectiveFractionDigits(\n fractionDigits: number | null | undefined\n): number {\n // `toFixed(undefined)` behaves as `toFixed(0)`, and the components read\n // `fractionDigits ?? 0`, so an unset value must not be rejected here — the\n // assertion has to accept exactly what the runtime accepts.\n if (fractionDigits === null || fractionDigits === undefined) {\n return 0;\n }\n return Number.isNaN(fractionDigits) ? 0 : Math.trunc(fractionDigits);\n}\n\n/**\n * Throws when `fractionDigits` is outside the range `toFixed` accepts.\n *\n * It is a public property that reaches `Number.prototype.toFixed` unchanged, so\n * `-1`, `101` or `Infinity` already throw a bare\n * `RangeError: toFixed() digits argument must be between 0 and 100` from inside\n * the update cycle. This replaces that with an error naming the component and\n * the offending value.\n *\n * Deliberately not clamped: `fractionDigits` sets the PRECISION of a reading, so\n * quietly turning `-1` into `0` would drop decimals from a displayed value\n * without telling anyone. It is a configuration mistake, fixable only in code —\n * the same class as a bad `valueType`, and treated the same way.\n *\n * Values `toFixed` itself tolerates are left alone: `NaN` reads as `0`, and a\n * fractional count truncates (`2.7` → `2`).\n */\nexport function assertReadoutFractionDigits(\n tagName: string,\n fractionDigits: number | null | undefined\n): void {\n const digits = effectiveFractionDigits(fractionDigits);\n if (Number.isFinite(digits) && digits >= 0 && digits <= READOUT_MAX_DIGITS) {\n return;\n }\n throw new RangeError(\n // `String`, not `JSON.stringify`: the latter serialises `Infinity` and\n // `NaN` to `null`, hiding the very value being rejected.\n `<${tagName}>: fractionDigits must be between 0 and ${READOUT_MAX_DIGITS} ` +\n `(got ${String(fractionDigits)}).`\n );\n}\n\n/**\n * A digit count used for WIDTH RESERVATION, normalised to a non-negative integer\n * no greater than {@link READOUT_MAX_DIGITS}.\n *\n * Deliberately named for the role rather than for `maxDigits`: both `maxDigits`\n * and the fraction count `obc-readout-list` reserves with are the same kind of\n * input — a count handed to `String.prototype.repeat` — and must be bounded the\n * same way. `fractionDigits` as a FORMAT input is a different contract and is\n * rejected instead; see {@link assertReadoutFractionDigits}.\n *\n * Clamped rather than rejected because it only reserves width, so bounding it\n * changes no reading's meaning, and the surrounding code already absorbs bad\n * values silently (`Math.max(count, 1)`, `NaN` repeating to `''`). What is not\n * absorbed is `Infinity`, which throws out of `String.prototype.repeat`, and a\n * large finite count, which builds a reserver string long enough to matter —\n * both are capped here.\n */\nexport function resolveReadoutDigitCount(\n count: number | null | undefined\n): number {\n const digits = Math.trunc(count ?? 0);\n if (Number.isNaN(digits) || digits <= 0) {\n // Matches what the existing guards already do with these: reserve nothing.\n return 0;\n }\n // `Infinity` lands on the cap — \"as wide as possible\" — rather than throwing.\n return Math.min(digits, READOUT_MAX_DIGITS);\n}\n\n/**\n * Whether a digit-count knob failed to arrive as a number: `null`, `undefined`\n * or `NaN`.\n *\n * A missing knob renders the READING unavailable (the dash) rather than\n * silently formatting with a default the author never chose. `fractionDigits`\n * is typically written by the consuming system, and a runtime failure there\n * produces exactly these values — formatting with `0` instead would print a\n * critical `0.4` as a plausible-looking `0`, which an operator cannot tell\n * apart from a healthy reading. The dash makes the failure visible.\n *\n * This is a third contract besides throw and clamp: a finite out-of-range\n * `fractionDigits` is a programmer error and throws\n * ({@link assertReadoutFractionDigits}); a finite out-of-range `maxDigits` is\n * width-only and clamps ({@link resolveReadoutDigitCount}); a knob that never\n * arrived is a runtime data condition and dashes the reading, the same class\n * as a `NaN` value.\n */\nexport function isReadoutDigitCountMissing(\n count: number | null | undefined\n): boolean {\n return count === null || count === undefined || Number.isNaN(count);\n}\n\nfunction isBlank(value: string): boolean {\n return value.trim() === '';\n}\n\n/**\n * Throws when `valueType` is not a supported value, or when `value` is text but\n * `valueType` is `number`.\n *\n * `valueType` is validated first because an attribute carries an unchecked\n * string: a typo such as `valuetype=\"strng\"` matches neither mode, so every\n * mode check falls through and the readout silently renders the unavailable\n * dash — the opposite of the loud failure this contract exists to give.\n * `undefined`/`null` are allowed and mean \"use the default\".\n *\n * Attributes are always strings, so a numeric-looking string (`value=\"10.12\"`)\n * is accepted and parsed. Blank strings resolve to the unavailable dash rather\n * than throwing — `value=\"${maybeUndefined}\"` is a common template shape, and\n * `Number('')` is `0`, a silently wrong reading.\n */\nexport function assertReadoutValueType(\n tagName: string,\n value: number | string | null | undefined,\n valueType: ReadoutValueType\n): void {\n // `undefined`/`null` mean \"use the default\", matching how the components and\n // the resolvers treat an unset `valueType`.\n const resolved = valueType ?? ReadoutValueType.number;\n if (!isReadoutValueType(resolved)) {\n throw new TypeError(\n `<${tagName}>: valueType must be ` +\n `${READOUT_VALUE_TYPES.map((t) => `\"${t}\"`).join(' or ')} ` +\n `(got ${JSON.stringify(valueType)}).`\n );\n }\n if (\n resolved !== ReadoutValueType.number ||\n typeof value !== 'string' ||\n isBlank(value)\n ) {\n return;\n }\n if (Number.isFinite(Number(value))) {\n return;\n }\n throw new TypeError(\n `<${tagName}>: value must be a number when valueType is \"number\" ` +\n `(got ${JSON.stringify(value)}). Set valueType=\"text\" to render text.`\n );\n}\n\n/**\n * The value as a number, or `undefined` when it is text / unavailable.\n *\n * A non-finite number (`NaN`, `±Infinity`) counts as unavailable and renders the\n * dash, the same as `null`. `NaN` is a runtime data condition — a sensor\n * dropout, a `0/0`, a bad parse — not a programmer error, so it must not throw;\n * and `value.toFixed()` would otherwise render the literal text `\"NaN\"` /\n * `\"Infinity\"` in place of a reading. This also makes the number path agree with\n * the string path below, which has always resolved a non-finite string to\n * `undefined` — before this, `<obc-readout value=\"NaN\">` rendered a dash while\n * `.value=${NaN}` rendered `\"NaN\"`.\n */\nexport function resolveReadoutNumericValue(\n value: number | string | null | undefined,\n valueType: ReadoutValueType\n): number | undefined {\n if (\n valueType === ReadoutValueType.text ||\n value === null ||\n value === undefined\n ) {\n return undefined;\n }\n if (typeof value === 'number') {\n return Number.isFinite(value) ? value : undefined;\n }\n if (isBlank(value)) {\n return undefined;\n }\n const parsed = Number(value);\n return Number.isFinite(parsed) ? parsed : undefined;\n}\n\n/** The value as display text, or `undefined` when not in text mode / blank. */\nexport function resolveReadoutTextValue(\n value: number | string | null | undefined,\n valueType: ReadoutValueType\n): string | undefined {\n if (\n valueType !== ReadoutValueType.text ||\n value === null ||\n value === undefined\n ) {\n return undefined;\n }\n const text = typeof value === 'number' ? String(value) : value;\n return isBlank(text) ? undefined : text;\n}\n\n/**\n * The character used for an unavailable (\"no reading\") value.\n *\n * U+2012 FIGURE DASH, not the ASCII hyphen-minus: it is defined to be the same\n * width as a digit, so the placeholder lines up with the reading it stands in\n * for. Measured in Noto Sans with tabular figures at `size=\"m\"` — digit 13.02px,\n * U+2012 13.02px, U+002D 7.02px, en dash 11.02px, em dash 22.02px. With a\n * hyphen, `-.--` sat 46% narrow per character and its decimal point missed the\n * reading's; with U+2012 the point and every fraction position align exactly.\n */\nexport const READOUT_UNAVAILABLE_DASH = '\\u2012';\n\n/**\n * The unavailable (\"no reading\") text: a single integer dash plus one dash per\n * fraction digit — `\\u2012` at `fractionDigits` 0, `\\u2012.\\u2012\\u2012` at 2.\n *\n * Deliberately NOT filled out to `maxDigits`: the placeholder stays short and\n * sits at the right edge of the reserved width, rather than spelling out every\n * reserved digit position. `maxDigits` still reserves the width, so nothing\n * shifts when a reading arrives.\n */\nfunction dashedGenerator({\n showZeroPadding,\n minValueLength,\n fractionDigits: rawFractionDigits,\n}: ReadoutNumericFormatOptions): string {\n const visibleDigits = showZeroPadding ? Math.max(minValueLength, 1) : 1;\n\n // A missing precision shapes the placeholder as zero fraction digits — a\n // single dash. Without this, `NaN < 1` is false, both `repeat(NaN)` calls\n // below produce the empty string, and the placeholder degenerates to a\n // lone `\".\"`.\n const fractionDigits = Number.isNaN(rawFractionDigits)\n ? 0\n : rawFractionDigits;\n\n if (fractionDigits < 1) {\n return READOUT_UNAVAILABLE_DASH.repeat(visibleDigits);\n }\n\n const integerDigits = visibleDigits - fractionDigits;\n\n return (\n READOUT_UNAVAILABLE_DASH.repeat(Math.max(integerDigits, 1)) +\n '.' +\n READOUT_UNAVAILABLE_DASH.repeat(fractionDigits)\n );\n}\n\nexport function formatNumericValue(\n value: number | undefined,\n options: ReadoutNumericFormatOptions\n): string {\n // Non-finite counts as unavailable here too, not only in\n // `resolveReadoutNumericValue`. Every caller normalises today, but this\n // function is exported, and `NaN.toFixed()` would put the literal text\n // \"NaN\" where a reading belongs — the exact failure this change removes.\n //\n // A missing precision (`NaN` fractionDigits) is the same class of failure\n // from the other operand: `value.toFixed(NaN)` silently formats with zero\n // decimals, printing a critical `0.4` as a plausible-looking `0`. The\n // reading is untrustworthy without its precision, so it dashes too.\n if (\n value === undefined ||\n !Number.isFinite(value) ||\n Number.isNaN(options.fractionDigits)\n ) {\n return dashedGenerator(options);\n }\n\n return value.toFixed(options.fractionDigits);\n}\n\nexport function readoutFormattedInteger(valueText: string): number {\n const t = valueText.trim();\n if (!t) {\n return 0;\n }\n\n const rest = t.startsWith('-') ? t.slice(1) : t;\n const dot = rest.indexOf('.');\n return dot === -1 ? rest.length : dot;\n}\n\nexport function getHintZeros(\n value: number | undefined,\n {showZeroPadding, minValueLength, fractionDigits}: ReadoutNumericFormatOptions\n): string {\n const formattedValue = formatNumericValue(value, {\n showZeroPadding,\n minValueLength,\n fractionDigits,\n });\n const dotLength = fractionDigits > 0 ? 1 : 0;\n const integerLength = formattedValue.length - dotLength;\n const hintedDigits = Math.max(minValueLength - integerLength, 0);\n\n if (hintedDigits > 0) {\n return '0'.repeat(hintedDigits);\n }\n\n return '';\n}\n"],"names":["ReadoutValueType"],"mappings":"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"}
@@ -211,13 +211,22 @@ export declare class ObcReadout extends LitElement {
211
211
  hasDegreeSpacer: boolean;
212
212
  /**
213
213
  * Also formats the numeric setpoint / advice blocks, which stay numeric
214
- * even when the value is text.
214
+ * even when the value is text. Must be between 0 and 100 — the range
215
+ * `Number.prototype.toFixed` accepts; outside it throws a `RangeError`.
216
+ * A fractional count truncates (`2.7` → `2`). A count that never arrived
217
+ * (`NaN`, `null` or unset) renders the reading as the unavailable dash —
218
+ * formatting with a precision the author never chose would let a critical
219
+ * `0.4` pass for a healthy `0`.
215
220
  * @availableWhen valueType==number || hasSetpoint==true || hasAdvice==true
216
221
  */
217
222
  fractionDigits: number;
218
223
  /**
219
224
  * Also formats the numeric setpoint / advice blocks, which stay numeric
220
- * even when the value is text.
225
+ * even when the value is text. Bounded before use: a fractional count
226
+ * truncates (`2.7` → `2`), anything above 100 — including `Infinity` —
227
+ * caps at 100, and a negative count reserves nothing. A count that never
228
+ * arrived (`NaN`, `null` or unset) renders the reading as the unavailable
229
+ * dash, consistent with `fractionDigits`.
221
230
  * @availableWhen valueType==number || hasSetpoint==true || hasAdvice==true
222
231
  */
223
232
  maxDigits: number;
@@ -255,6 +264,14 @@ export declare class ObcReadout extends LitElement {
255
264
  private get isHorizontal();
256
265
  private get resolvedFractionDigits();
257
266
  private get resolvedMaxDigits();
267
+ /**
268
+ * Whether a digit knob failed to arrive (`NaN` / `null` / `undefined`).
269
+ * The raw knobs are forwarded to the blocks, which render the reading as
270
+ * the unavailable dash (see `obc-readout-block.digitCountsMissing`); this
271
+ * getter only keeps the setpoint comparison in agreement with what is
272
+ * displayed.
273
+ */
274
+ private get digitCountsMissing();
258
275
  private get hasSrc();
259
276
  private get resolvedSourceInteraction();
260
277
  private get isAtSetpoint();
@@ -1 +1 @@
1
- {"version":3,"file":"readout.d.ts","sourceRoot":"","sources":["../../../src/navigation-instruments/readout/readout.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,UAAU,EAAgD,MAAM,KAAK,CAAC;AAK9E,OAAO,qCAAqC,CAAC;AAK7C,OAAO,sDAAsD,CAAC;AAC9D,OAAO,EAEL,gBAAgB,EAChB,uBAAuB,EAExB,MAAM,sDAAsD,CAAC;AAC9D,OAAO,EACL,kCAAkC,EAElC,KAAK,mBAAmB,EACxB,KAAK,sBAAsB,EAC3B,KAAK,oBAAoB,EACzB,KAAK,sBAAsB,EAC3B,KAAK,iBAAiB,EACvB,MAAM,2CAA2C,CAAC;AACnD,OAAO,EAAC,QAAQ,EAAC,MAAM,aAAa,CAAC;AACrC,OAAO,EAGL,gBAAgB,EAEjB,MAAM,yBAAyB,CAAC;AAUjC,OAAO,EACL,KAAK,gBAAgB,EAKtB,MAAM,6CAA6C,CAAC;AAErD,OAAO,mCAAmC,CAAC;AAC3C,OAAO,2DAA2D,CAAC;AAMnE,OAAO,0CAA0C,CAAC;AAClD,OAAO,sCAAsC,CAAC;AAM9C,OAAO,EAAC,oBAAoB,EAAC,MAAM,qCAAqC,CAAC;AACzE,OAAO,EAAC,gBAAgB,EAAC,MAAM,yBAAyB,CAAC;AACzD,YAAY,EACV,iBAAiB,EACjB,mBAAmB,EACnB,sBAAsB,EACtB,oBAAoB,EACpB,sBAAsB,EACtB,iBAAiB,GAClB,MAAM,2CAA2C,CAAC;AAEnD;;;;;GAKG;AACH,eAAO,MAAM,WAAW,yBAAmB,CAAC;AAC5C,MAAM,MAAM,WAAW,GAAG,gBAAgB,CAAC;AAE3C;;;;;GAKG;AACH,eAAO,MAAM,eAAe,iBAAW,CAAC;AACxC,MAAM,MAAM,eAAe,GAAG,QAAQ,CAAC;AAEvC;;;;GAIG;AACH,eAAO,MAAM,kBAAkB,gCAA0B,CAAC;AAC1D,MAAM,MAAM,kBAAkB,GAAG,uBAAuB,CAAC;AAEzD;;;;;;;;GAQG;AACH,eAAO,MAAM,0BAA0B,2CAAqC,CAAC;AAC7E,MAAM,MAAM,0BAA0B,GAAG,kCAAkC,CAAC;AAE5E;;;;;;;;GAQG;AACH,oBAAY,gBAAgB;IAC1B,QAAQ,aAAa;IACrB,UAAU,eAAe;CAC1B;AAED;;;;;;GAMG;AACH,oBAAY,eAAe;IACzB,MAAM,WAAW;IACjB,OAAO,YAAY;CACpB;AAED;;;;;;GAMG;AACH,oBAAY,gBAAgB;IAC1B,QAAQ,aAAa;IACrB,IAAI,SAAS;IACb,MAAM,WAAW;CAClB;AAED;;;;;;;;;GASG;AACH,oBAAY,wBAAwB;IAClC,IAAI,SAAS;IACb,MAAM,WAAW;IACjB,MAAM,WAAW;CAClB;AAED;;;GAGG;AACH,MAAM,WAAW,oBAAqB,SAAQ,iBAAiB;IAC7D,wDAAwD;IACxD,WAAW,CAAC,EAAE,wBAAwB,CAAC;CACxC;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4DG;AACH,qBACa,UAAW,SAAQ,UAAU;IAEd,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,GAAG,CAAC,EAAE,MAAM,CAAC;IAEvC;;;;;OAKG;IAC0C,QAAQ,UAAQ;IAC7D;;;OAGG;IACuB,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAAQ;IAC/D;;;;OAIG;IACuB,SAAS,EAAE,gBAAgB,CAC3B;IAC1B,2FAA2F;IAChE,GAAG,UAAS;IACvC,oFAAoF;IAC1D,OAAO,SAAS;IAEf,WAAW,UAAS;IAC/C,uCAAuC;IACb,QAAQ,CAAC,EAAE,MAAM,CAAC;IAEjB,SAAS,UAAS;IAC7C,qCAAqC;IACX,MAAM,CAAC,EAAE,MAAM,CAAC;IAGhB,IAAI,CAAC,EAAE,WAAW,CAAC;IACnB,QAAQ,CAAC,EAAE,eAAe,CAAC;IAC3B,SAAS,CAAC,EAAE,gBAAgB,CAAC;IACvD,yCAAyC;IACf,QAAQ,CAAC,EAAE,eAAe,CAAC;IACrD,8DAA8D;IACpC,SAAS,CAAC,EAAE,gBAAgB,CAAC;IAC5B,SAAS,UAAS;IAC7C,sCAAsC;IACX,eAAe,UAAS;IACnD;;;;OAIG;IACuB,cAAc,SAAK;IAC7C;;;;OAIG;IACuB,SAAS,SAAK;IACd,WAAW,CAAC,EAAE,kBAAkB,CAAC;IAKjC,KAAK,EAAE,OAAO,GAAG,gBAAgB,CAAS;IAGpE,oCAAoC;IACV,YAAY,CAAC,EAAE,mBAAmB,CAAC;IAC7D,uCAAuC;IACb,eAAe,CAAC,EAAE,sBAAsB,CAAC;IACnE,qCAAqC;IACX,aAAa,CAAC,EAAE,oBAAoB,CAAC;IAC/D,8BAA8B;IACJ,WAAW,CAAC,EAAE,sBAAsB,CAAC;IAC/D,6BAA6B;IACH,UAAU,CAAC,EAAE,oBAAoB,CAAC;IAE5D;;;;OAIG;IACuC,gBAAgB,UAAS;IAEnE,yEAAyE;IAChE,OAAO,CAAC,yBAAyB,CACb;IAC7B,OAAO,CAAC,yBAAyB,CAAC,CAAS;IAC3C,OAAO,CAAC,uBAAuB,CAAS;IAE/B,OAAO,CAAC,0BAA0B,CAAS;IAC3C,OAAO,CAAC,mBAAmB,CAA2B;IAG/D,OAAO,CAAC,gBAAgB,CAAC,CAAkB;IAE3C,OAAO,CAAC,QAAQ,CAAC,mBAAmB,CAQlC;IAEF,OAAO,KAAK,YAAY,GAEvB;IAED,OAAO,KAAK,gBAAgB,GAE3B;IAED,OAAO,KAAK,iBAAiB,GAE5B;IAED,OAAO,KAAK,gBAAgB,GAE3B;IAED,OAAO,KAAK,iBAAiB,GAE5B;IAED,OAAO,KAAK,YAAY,GAEvB;IAED,OAAO,KAAK,sBAAsB,GAEjC;IAED,OAAO,KAAK,iBAAiB,GAE5B;IAED,OAAO,KAAK,MAAM,GAEjB;IAED,OAAO,KAAK,yBAAyB,GAEpC;IAED,OAAO,KAAK,YAAY,GAWvB;IAED,OAAO,KAAK,2BAA2B,GAKtC;IAED,OAAO,KAAK,UAAU,GAIrB;IAED,OAAO,KAAK,OAAO,GAIlB;IAED,OAAO,KAAK,gBAAgB,GAE3B;IAED;;;;;OAKG;IACH,OAAO,KAAK,kBAAkB,GAE7B;IAED;;;;;OAKG;IACH,OAAO,KAAK,oBAAoB,GAQ/B;IAED;;;;;OAKG;IACH,OAAO,KAAK,WAAW,GAEtB;IAED,kEAAkE;IAClE,OAAO,KAAK,WAAW,GAEtB;IAED,oFAAoF;IACpF,OAAO,KAAK,aAAa,GAExB;IAED,OAAO,KAAK,SAAS,GAQpB;IAED,OAAO,KAAK,YAAY,GAEvB;IAED,gGAAgG;IAChG,OAAO,KAAK,WAAW,GAEtB;IAED,4EAA4E;IAC5E,OAAO,KAAK,cAAc,GAEzB;IAED,OAAO,CAAC,oBAAoB;IAI5B,8EAA8E;IAC9E,OAAO,CAAC,kBAAkB;IAM1B;;;;OAIG;IACH,OAAO,CAAC,mBAAmB;IAU3B,OAAO,CAAC,WAAW;IAwDnB;;;;OAIG;IACH,OAAO,CAAC,iBAAiB;IAiBzB;;;;;;;OAOG;IACH,OAAO,CAAC,kBAAkB;IAgB1B,OAAO,CAAC,aAAa;IA4BrB,OAAO,KAAK,iBAAiB,GAO5B;IAED,OAAO,CAAC,iBAAiB;IAezB,OAAO,CAAC,mBAAmB;IAmB3B;;;;;;OAMG;IACH,OAAO,CAAC,kBAAkB;IA0B1B;;;;;;;OAOG;IACH,OAAO,CAAC,uBAAuB;IA+B/B,oFAAoF;IACpF,OAAO,CAAC,cAAc;IA8BtB,OAAO,CAAC,mBAAmB;IAgE3B,+EAA+E;IAC/E,OAAO,CAAC,YAAY;IAsBpB,OAAO,CAAC,8BAA8B;IAiBtC,OAAO,CAAC,4BAA4B;IAQpC,OAAO,CAAC,uBAAuB;IAgB/B,OAAO,CAAC,6BAA6B;IAWrC,OAAO,CAAC,uBAAuB,CAc7B;IAEF,OAAO,CAAC,2BAA2B;IAiBnC;;;;;;OAMG;IACH,OAAO,KAAK,oBAAoB,GAQ/B;IAED,OAAO,CAAC,yBAAyB;IAqBjC,OAAO,CAAC,sBAAsB;IAY9B;;;;;;;;;;;OAWG;IACH,OAAO,CAAC,0BAA0B;IAuClC;;;;OAIG;IACH,OAAO,CAAC,oBAAoB;IAyB5B;;;;OAIG;IACH,OAAO,CAAC,sBAAsB;cAuBX,UAAU,CAAC,OAAO,EAAE,GAAG,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI;IAYzD,OAAO,CAAC,OAAO,EAAE,GAAG,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI;IAoDrD,OAAO,CAAC,yBAAyB;IAQxB,oBAAoB,IAAI,IAAI;IAa5B,MAAM;IAkCf,OAAgB,MAAM,0BAA6B;CACpD;AAED,OAAO,CAAC,MAAM,CAAC;IACb,UAAU,qBAAqB;QAC7B,aAAa,EAAE,UAAU,CAAC;KAC3B;CACF"}
1
+ {"version":3,"file":"readout.d.ts","sourceRoot":"","sources":["../../../src/navigation-instruments/readout/readout.ts"],"names":[],"mappings":"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"}
@@ -7,7 +7,7 @@ import { ObcTextboxFontWeight, ObcTextboxSize } from "../../components/textbox/t
7
7
  import { ReadoutBlockHidePhase, ReadoutBlockSize, ReadoutBlockVariant, ReadoutBlockDataQuality } from "../../building-blocks/readout-block/readout-block.js";
8
8
  import { ReadoutListItemSetpointInteraction } from "../readout-list-item/readout-list-item.js";
9
9
  import { Priority } from "../types.js";
10
- import { ReadoutValueType, resolveReadoutNumericValue, assertReadoutValueType } from "./readout-formatters.js";
10
+ import { ReadoutValueType, resolveReadoutDigitCount, isReadoutDigitCountMissing, resolveReadoutNumericValue, assertReadoutValueType, assertReadoutFractionDigits } from "./readout-formatters.js";
11
11
  import { isDisplayedAtSetpoint, readoutPrimarySize, readoutSecondarySize, readoutSetpointWeight, readoutNumericFormatOptions, readoutDataQualityClasses, resolveSetpointHidePhase } from "./readout-shared.js";
12
12
  import { wrapWithAlertFrame, ObcAlertFrameThickness, ObcAlertFrameType, ObcAlertFrameMode } from "../../components/alert-frame/alert-frame.js";
13
13
  import { AlertType } from "../../types.js";
@@ -118,7 +118,17 @@ let ObcReadout = class extends LitElement {
118
118
  return this.fractionDigits ?? 0;
119
119
  }
120
120
  get resolvedMaxDigits() {
121
- return this.maxDigits ?? 0;
121
+ return resolveReadoutDigitCount(this.maxDigits);
122
+ }
123
+ /**
124
+ * Whether a digit knob failed to arrive (`NaN` / `null` / `undefined`).
125
+ * The raw knobs are forwarded to the blocks, which render the reading as
126
+ * the unavailable dash (see `obc-readout-block.digitCountsMissing`); this
127
+ * getter only keeps the setpoint comparison in agreement with what is
128
+ * displayed.
129
+ */
130
+ get digitCountsMissing() {
131
+ return isReadoutDigitCountMissing(this.fractionDigits) || isReadoutDigitCountMissing(this.maxDigits);
122
132
  }
123
133
  get hasSrc() {
124
134
  return this.src !== void 0 && this.src.trim() !== "";
@@ -130,6 +140,9 @@ let ObcReadout = class extends LitElement {
130
140
  if (!this.hasSetpoint) {
131
141
  return false;
132
142
  }
143
+ if (this.digitCountsMissing) {
144
+ return false;
145
+ }
133
146
  return isDisplayedAtSetpoint(
134
147
  resolveReadoutNumericValue(this.value, this.valueType) ?? null,
135
148
  this.setpoint,
@@ -240,8 +253,8 @@ let ObcReadout = class extends LitElement {
240
253
  .weight=${config.weight}
241
254
  .hasDegree=${config.hasDegree ?? false}
242
255
  .hasIcon=${config.hasIcon ?? false}
243
- .fractionDigits=${this.resolvedFractionDigits}
244
- .maxDigits=${this.resolvedMaxDigits}
256
+ .fractionDigits=${this.fractionDigits}
257
+ .maxDigits=${this.maxDigits}
245
258
  .hintedZeros=${config.hintedZeros}
246
259
  .spaceReserver=${config.spaceReserver}
247
260
  .off=${config.off ?? false}
@@ -714,6 +727,7 @@ let ObcReadout = class extends LitElement {
714
727
  willUpdate(changed) {
715
728
  super.willUpdate(changed);
716
729
  assertReadoutValueType("obc-readout", this.value, this.valueType);
730
+ assertReadoutFractionDigits("obc-readout", this.fractionDigits);
717
731
  }
718
732
  updated(changed) {
719
733
  super.updated(changed);