@itwin/core-quantity 5.9.0-dev.9 → 5.10.0-dev.3

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 (152) hide show
  1. package/CHANGELOG.md +16 -1
  2. package/lib/cjs/BasicUnitsProvider.d.ts +44 -0
  3. package/lib/cjs/BasicUnitsProvider.d.ts.map +1 -0
  4. package/lib/cjs/BasicUnitsProvider.js +241 -0
  5. package/lib/cjs/BasicUnitsProvider.js.map +1 -0
  6. package/lib/cjs/CompositeUnitsProvider.d.ts +45 -0
  7. package/lib/cjs/CompositeUnitsProvider.d.ts.map +1 -0
  8. package/lib/cjs/CompositeUnitsProvider.js +111 -0
  9. package/lib/cjs/CompositeUnitsProvider.js.map +1 -0
  10. package/lib/cjs/Constants.js.map +1 -1
  11. package/lib/cjs/Exception.js.map +1 -1
  12. package/lib/cjs/FormatSpecHandle.d.ts +56 -0
  13. package/lib/cjs/FormatSpecHandle.d.ts.map +1 -0
  14. package/lib/cjs/FormatSpecHandle.js +87 -0
  15. package/lib/cjs/FormatSpecHandle.js.map +1 -0
  16. package/lib/cjs/Formatter/Format.js.map +1 -1
  17. package/lib/cjs/Formatter/FormatEnums.js.map +1 -1
  18. package/lib/cjs/Formatter/Formatter.js.map +1 -1
  19. package/lib/cjs/Formatter/FormatterSpec.d.ts.map +1 -1
  20. package/lib/cjs/Formatter/FormatterSpec.js +14 -0
  21. package/lib/cjs/Formatter/FormatterSpec.js.map +1 -1
  22. package/lib/cjs/Formatter/FormattingReadyCollector.d.ts +16 -0
  23. package/lib/cjs/Formatter/FormattingReadyCollector.d.ts.map +1 -0
  24. package/lib/cjs/Formatter/FormattingReadyCollector.js +44 -0
  25. package/lib/cjs/Formatter/FormattingReadyCollector.js.map +1 -0
  26. package/lib/cjs/Formatter/Interfaces.d.ts +51 -3
  27. package/lib/cjs/Formatter/Interfaces.d.ts.map +1 -1
  28. package/lib/cjs/Formatter/Interfaces.js.map +1 -1
  29. package/lib/cjs/Interfaces.d.ts +31 -1
  30. package/lib/cjs/Interfaces.d.ts.map +1 -1
  31. package/lib/cjs/Interfaces.js.map +1 -1
  32. package/lib/cjs/Parser.d.ts.map +1 -1
  33. package/lib/cjs/Parser.js +16 -1
  34. package/lib/cjs/Parser.js.map +1 -1
  35. package/lib/cjs/ParserSpec.d.ts.map +1 -1
  36. package/lib/cjs/ParserSpec.js +15 -2
  37. package/lib/cjs/ParserSpec.js.map +1 -1
  38. package/lib/cjs/Quantity.js.map +1 -1
  39. package/lib/cjs/QuantityLoggerCategory.d.ts +16 -0
  40. package/lib/cjs/QuantityLoggerCategory.d.ts.map +1 -0
  41. package/lib/cjs/QuantityLoggerCategory.js +24 -0
  42. package/lib/cjs/QuantityLoggerCategory.js.map +1 -0
  43. package/lib/cjs/SerializedUnitSchema.d.ts +98 -0
  44. package/lib/cjs/SerializedUnitSchema.d.ts.map +1 -0
  45. package/lib/cjs/SerializedUnitSchema.js +25 -0
  46. package/lib/cjs/SerializedUnitSchema.js.map +1 -0
  47. package/lib/cjs/Unit.js.map +1 -1
  48. package/lib/cjs/UnitConversion/Graph.d.ts +35 -0
  49. package/lib/cjs/UnitConversion/Graph.d.ts.map +1 -0
  50. package/lib/cjs/UnitConversion/Graph.js +87 -0
  51. package/lib/cjs/UnitConversion/Graph.js.map +1 -0
  52. package/lib/cjs/UnitConversion/Parser.d.ts +9 -0
  53. package/lib/cjs/UnitConversion/Parser.d.ts.map +1 -0
  54. package/lib/cjs/UnitConversion/Parser.js +42 -0
  55. package/lib/cjs/UnitConversion/Parser.js.map +1 -0
  56. package/lib/cjs/UnitConversion/UnitConversion.d.ts +56 -0
  57. package/lib/cjs/UnitConversion/UnitConversion.d.ts.map +1 -0
  58. package/lib/cjs/UnitConversion/UnitConversion.js +80 -0
  59. package/lib/cjs/UnitConversion/UnitConversion.js.map +1 -0
  60. package/lib/cjs/UnitConversion/UnitDefinitionResolver.d.ts +29 -0
  61. package/lib/cjs/UnitConversion/UnitDefinitionResolver.d.ts.map +1 -0
  62. package/lib/cjs/UnitConversion/UnitDefinitionResolver.js +102 -0
  63. package/lib/cjs/UnitConversion/UnitDefinitionResolver.js.map +1 -0
  64. package/lib/cjs/UnitConversion/nameUtils.d.ts +11 -0
  65. package/lib/cjs/UnitConversion/nameUtils.d.ts.map +1 -0
  66. package/lib/cjs/UnitConversion/nameUtils.js +25 -0
  67. package/lib/cjs/UnitConversion/nameUtils.js.map +1 -0
  68. package/lib/cjs/assets/Units.json +4215 -0
  69. package/lib/cjs/core-quantity.d.ts +22 -1
  70. package/lib/cjs/core-quantity.d.ts.map +1 -1
  71. package/lib/cjs/core-quantity.js +24 -1
  72. package/lib/cjs/core-quantity.js.map +1 -1
  73. package/lib/cjs/internal/cross-package.d.ts +4 -0
  74. package/lib/cjs/internal/cross-package.d.ts.map +1 -0
  75. package/lib/cjs/internal/cross-package.js +13 -0
  76. package/lib/cjs/internal/cross-package.js.map +1 -0
  77. package/lib/esm/BasicUnitsProvider.d.ts +44 -0
  78. package/lib/esm/BasicUnitsProvider.d.ts.map +1 -0
  79. package/lib/esm/BasicUnitsProvider.js +213 -0
  80. package/lib/esm/BasicUnitsProvider.js.map +1 -0
  81. package/lib/esm/CompositeUnitsProvider.d.ts +45 -0
  82. package/lib/esm/CompositeUnitsProvider.d.ts.map +1 -0
  83. package/lib/esm/CompositeUnitsProvider.js +108 -0
  84. package/lib/esm/CompositeUnitsProvider.js.map +1 -0
  85. package/lib/esm/Constants.js.map +1 -1
  86. package/lib/esm/Exception.js.map +1 -1
  87. package/lib/esm/FormatSpecHandle.d.ts +56 -0
  88. package/lib/esm/FormatSpecHandle.d.ts.map +1 -0
  89. package/lib/esm/FormatSpecHandle.js +83 -0
  90. package/lib/esm/FormatSpecHandle.js.map +1 -0
  91. package/lib/esm/Formatter/Format.js.map +1 -1
  92. package/lib/esm/Formatter/FormatEnums.js.map +1 -1
  93. package/lib/esm/Formatter/Formatter.js.map +1 -1
  94. package/lib/esm/Formatter/FormatterSpec.d.ts.map +1 -1
  95. package/lib/esm/Formatter/FormatterSpec.js +14 -0
  96. package/lib/esm/Formatter/FormatterSpec.js.map +1 -1
  97. package/lib/esm/Formatter/FormattingReadyCollector.d.ts +16 -0
  98. package/lib/esm/Formatter/FormattingReadyCollector.d.ts.map +1 -0
  99. package/lib/esm/Formatter/FormattingReadyCollector.js +40 -0
  100. package/lib/esm/Formatter/FormattingReadyCollector.js.map +1 -0
  101. package/lib/esm/Formatter/Interfaces.d.ts +51 -3
  102. package/lib/esm/Formatter/Interfaces.d.ts.map +1 -1
  103. package/lib/esm/Formatter/Interfaces.js.map +1 -1
  104. package/lib/esm/Interfaces.d.ts +31 -1
  105. package/lib/esm/Interfaces.d.ts.map +1 -1
  106. package/lib/esm/Interfaces.js.map +1 -1
  107. package/lib/esm/Parser.d.ts.map +1 -1
  108. package/lib/esm/Parser.js +16 -1
  109. package/lib/esm/Parser.js.map +1 -1
  110. package/lib/esm/ParserSpec.d.ts.map +1 -1
  111. package/lib/esm/ParserSpec.js +15 -2
  112. package/lib/esm/ParserSpec.js.map +1 -1
  113. package/lib/esm/Quantity.js.map +1 -1
  114. package/lib/esm/QuantityLoggerCategory.d.ts +16 -0
  115. package/lib/esm/QuantityLoggerCategory.d.ts.map +1 -0
  116. package/lib/esm/QuantityLoggerCategory.js +21 -0
  117. package/lib/esm/QuantityLoggerCategory.js.map +1 -0
  118. package/lib/esm/SerializedUnitSchema.d.ts +98 -0
  119. package/lib/esm/SerializedUnitSchema.d.ts.map +1 -0
  120. package/lib/esm/SerializedUnitSchema.js +22 -0
  121. package/lib/esm/SerializedUnitSchema.js.map +1 -0
  122. package/lib/esm/Unit.js.map +1 -1
  123. package/lib/esm/UnitConversion/Graph.d.ts +35 -0
  124. package/lib/esm/UnitConversion/Graph.d.ts.map +1 -0
  125. package/lib/esm/UnitConversion/Graph.js +83 -0
  126. package/lib/esm/UnitConversion/Graph.js.map +1 -0
  127. package/lib/esm/UnitConversion/Parser.d.ts +9 -0
  128. package/lib/esm/UnitConversion/Parser.d.ts.map +1 -0
  129. package/lib/esm/UnitConversion/Parser.js +39 -0
  130. package/lib/esm/UnitConversion/Parser.js.map +1 -0
  131. package/lib/esm/UnitConversion/UnitConversion.d.ts +56 -0
  132. package/lib/esm/UnitConversion/UnitConversion.d.ts.map +1 -0
  133. package/lib/esm/UnitConversion/UnitConversion.js +76 -0
  134. package/lib/esm/UnitConversion/UnitConversion.js.map +1 -0
  135. package/lib/esm/UnitConversion/UnitDefinitionResolver.d.ts +29 -0
  136. package/lib/esm/UnitConversion/UnitDefinitionResolver.d.ts.map +1 -0
  137. package/lib/esm/UnitConversion/UnitDefinitionResolver.js +98 -0
  138. package/lib/esm/UnitConversion/UnitDefinitionResolver.js.map +1 -0
  139. package/lib/esm/UnitConversion/nameUtils.d.ts +11 -0
  140. package/lib/esm/UnitConversion/nameUtils.d.ts.map +1 -0
  141. package/lib/esm/UnitConversion/nameUtils.js +21 -0
  142. package/lib/esm/UnitConversion/nameUtils.js.map +1 -0
  143. package/lib/esm/assets/Units.json +4215 -0
  144. package/lib/esm/core-quantity.d.ts +22 -1
  145. package/lib/esm/core-quantity.d.ts.map +1 -1
  146. package/lib/esm/core-quantity.js +22 -1
  147. package/lib/esm/core-quantity.js.map +1 -1
  148. package/lib/esm/internal/cross-package.d.ts +4 -0
  149. package/lib/esm/internal/cross-package.d.ts.map +1 -0
  150. package/lib/esm/internal/cross-package.js +8 -0
  151. package/lib/esm/internal/cross-package.js.map +1 -0
  152. package/package.json +6 -5
@@ -1 +1 @@
1
- {"version":3,"file":"Formatter.js","sourceRoot":"","sources":["../../../src/Formatter/Formatter.ts"],"names":[],"mappings":"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","sourcesContent":["/*---------------------------------------------------------------------------------------------\n* Copyright (c) Bentley Systems, Incorporated. All rights reserved.\n* See LICENSE.md in the project root for license terms and full copyright notice.\n*--------------------------------------------------------------------------------------------*/\n/** @packageDocumentation\n * @module Quantity\n */\n\nimport { QuantityConstants } from \"../Constants\";\nimport { QuantityError, QuantityStatus } from \"../Exception\";\nimport { FormatterSpec } from \"./FormatterSpec\";\nimport { DecimalPrecision, FormatTraits, FormatType, FractionalPrecision, RatioType, ScientificType, ShowSignOption } from \"./FormatEnums\";\nimport { applyConversion, Quantity } from \"../Quantity\";\n\n/** rounding additive\n * @internal\n */\nconst FPV_ROUNDFACTOR = 0.50000000001;\n\n/** A private helper class used to format fraction part of value into a numerator and denominator.\n * @internal\n */\nclass FractionalNumeric {\n private _integral: number = 0;\n private _numerator: number = 0;\n private _denominator: number = 1;\n private _greatestCommonFactor: number = 1;\n private _textParts: string[] = [];\n\n constructor(value: number, precision: FractionalPrecision, reduce: boolean) {\n this.calculate(value, precision as number);\n this.formTextParts(reduce);\n }\n\n private calculate(value: number, denominator: number) {\n const positiveValue = Math.abs(value);\n this._denominator = denominator;\n this._integral = Math.floor(positiveValue);\n const fractionPart = positiveValue - this._integral;\n this._numerator = Math.floor(fractionPart * this._denominator + FPV_ROUNDFACTOR);\n\n if (0 !== denominator && (this._numerator / this._denominator) === 1) {\n this._numerator = 0;\n this._integral += 1;\n } else {\n this._greatestCommonFactor = FractionalNumeric.getGreatestCommonFactor(this._numerator, this._denominator);\n }\n }\n\n /** Determine the GCD given two values. This value can be used to reduce a fraction.\n * See algorithm description http://en.wikipedia.org/wiki/Euclidean_algorithm\n */\n public static getGreatestCommonFactor(numerator: number, denominator: number): number {\n let r;\n while (denominator !== 0) {\n r = numerator % denominator;\n numerator = denominator;\n denominator = r;\n }\n return (numerator < 0) ? -numerator : numerator;\n }\n\n public get greatestCommonFactor(): number { return this._greatestCommonFactor; }\n public get hasFractionPart(): boolean { return this._textParts.length > 0; }\n public get isZero(): boolean { return 0 === this._numerator; }\n\n public getIntegralString(): string {\n if (this._textParts.length > 0)\n return this._textParts[0];\n\n return \"\";\n }\n\n public getNumeratorString(): string {\n if (this._textParts.length >= 3)\n return this._textParts[1];\n\n return \"\";\n }\n\n public getDenominatorString(): string {\n if (this._textParts.length >= 3)\n return this._textParts[2];\n\n return \"\";\n }\n\n private formTextParts(reduce: boolean): void {\n let numerator = this._numerator;\n let denominator = this._denominator;\n\n if (reduce && this._greatestCommonFactor > 1) {\n numerator /= this.greatestCommonFactor;\n denominator /= this.greatestCommonFactor;\n }\n\n this._textParts.push(this._integral.toFixed(0));\n if (numerator > 0) {\n this._textParts.push(numerator.toFixed(0));\n this._textParts.push(denominator.toFixed(0));\n }\n }\n}\n\n/** A helper class that contains methods used to format quantity values based on a format that are defined via the Format class.\n * @beta\n */\nexport class Formatter {\n private static FPV_MINTHRESHOLD = 1.0e-14;\n\n private static isNegligible(value: number): boolean { return (Math.abs(value) < Formatter.FPV_MINTHRESHOLD); }\n\n /** Return floating point value rounded by specific rounding factor.\n * @param value Value to be rounded.\n * @param roundTo Rounding factor.\n */\n private static roundDouble(value: number, roundTo: number): number {\n if (Formatter.isNegligible(roundTo))\n return value;\n\n roundTo = Math.abs(roundTo);\n let rnd = FPV_ROUNDFACTOR + (value / roundTo);\n const iVal = Math.floor(rnd);\n rnd = iVal * roundTo;\n return (value < 0.0) ? -rnd : rnd;\n }\n\n /** Generate a formatted text string integer value insert 1000 separators if appropriate.\n * @param wholePart Integer value to be formatted.\n */\n private static integerPartToText(wholePart: number, spec: FormatterSpec): string {\n // build invariant string represent wholePart\n let formattedValue = wholePart.toFixed(0);\n\n if ((formattedValue.length > 3) && (spec.format.hasFormatTraitSet(FormatTraits.Use1000Separator) && (spec.format.thousandSeparator.length > 0))) {\n let numSeparators = Math.floor(formattedValue.length / 3);\n let groupLength = formattedValue.length % 3;\n\n if (groupLength === 0) {\n numSeparators = numSeparators - 1;\n groupLength = groupLength + 3;\n }\n\n let outString = formattedValue.substring(0, groupLength);\n\n for (let i = 1; i <= numSeparators; i += 1) {\n outString = outString + spec.format.thousandSeparator + formattedValue.substring(groupLength, groupLength + 3);\n groupLength = groupLength + 3;\n }\n\n formattedValue = outString;\n }\n\n return formattedValue;\n }\n\n /** Trim trailing \"0\" from the text that represent the fractional part of a floating point value.\n * @param strVal The value string.\n */\n private static trimTrailingZeroes(strVal: string): string {\n let lastNonZeroCharIndex = -1;\n for (let i = strVal.length - 1; i >= 0; i--) {\n if (strVal.charCodeAt(i) !== QuantityConstants.CHAR_DIGIT_ZERO) {\n lastNonZeroCharIndex = i;\n break;\n }\n }\n if (lastNonZeroCharIndex >= 0)\n return strVal.substring(0, lastNonZeroCharIndex + 1);\n return \"\";\n }\n\n /** Format a quantity value into a composite format such as ft-in or deg-min-sec.\n * @param compositeValue The value for this part of the composite\n * @param isLastPart If false the composite value should be a whole value, if true then the value should be formatted as a floating point value.\n * @param label Label for this part of the composite. This will be either the default unit label or a custom label specified the format specification.\n */\n private static formatCompositePart(compositeValue: number, isLastPart: boolean, label: string, spec: FormatterSpec): string {\n let componentText = \"\";\n if (!isLastPart) {\n componentText = Formatter.integerPartToText(compositeValue, spec);\n if(spec.format.minWidth) { // integerPartToText does not do this padding\n componentText = this.countAndPad(componentText, spec.format.minWidth);\n }\n } else {\n componentText = Formatter.formatMagnitude(compositeValue, spec);\n }\n\n\n if (spec.format.hasFormatTraitSet(FormatTraits.ShowUnitLabel)) {\n componentText = componentText + spec.format.uomSeparator + label;\n }\n\n return componentText;\n }\n\n /** Format a quantity value into a composite format such as ft-in or deg-min-sec.\n * @param magnitude quantity value\n * @param fromUnit quantity unit\n */\n private static formatComposite(magnitude: number, spec: FormatterSpec): { componentText: string, isNegative: boolean } {\n const compositeStrings: string[] = [];\n let isNegative = false;\n let remainingMagnitude = magnitude;\n\n for (let i = 0; i < spec.unitConversions.length; i++) {\n const currentLabel = spec.unitConversions[i].label;\n const unitConversion = spec.unitConversions[i].conversion;\n\n if (i > 0 && unitConversion.factor < 1.0)\n throw new QuantityError(QuantityStatus.InvalidCompositeFormat, `The Format ${spec.format.name} has a invalid unit specification.`);\n if (i > 0 && unitConversion.offset !== 0) // offset should only ever be defined for major unit\n throw new QuantityError(QuantityStatus.InvalidCompositeFormat, `The Format ${spec.format.name} has a invalid unit specification.`);\n\n // Handle ratio format with composite units\n if (spec.format.type === FormatType.Ratio) {\n let ratioUnitValue = 0.0;\n try {\n ratioUnitValue = applyConversion(remainingMagnitude, unitConversion) + this.FPV_MINTHRESHOLD;\n } catch (e) {\n // The \"InvertingZero\" error is thrown when the value is zero and the conversion factor is inverted.\n // For ratio, we actually want to support this corner case and return \"1:0\" as the formatted value.\n if (e instanceof QuantityError && e.errorNumber === QuantityStatus.InvertingZero) {\n return { componentText: \"1:0\", isNegative: false };\n }\n throw e;\n }\n\n compositeStrings.push(this.formatRatio(ratioUnitValue, spec));\n isNegative = ratioUnitValue < 0;\n continue;\n }\n\n let unitValue = applyConversion(remainingMagnitude, unitConversion) + this.FPV_MINTHRESHOLD;\n if (0 === i) {\n // Only set isNegative from the first (major) unit conversion\n isNegative = unitValue < 0;\n\n // Use a minimum precision of 8 for intermediate rounding to avoid loss of precision in composite formats,\n // but use higher precision if the format specifies it\n const precisionScale = Math.pow(10, Math.max(8, spec.format.precision));\n unitValue = Math.floor(unitValue * precisionScale + FPV_ROUNDFACTOR) / precisionScale;\n if ((Math.abs(unitValue) < 0.0001) && spec.format.hasFormatTraitSet(FormatTraits.ZeroEmpty))\n return { componentText: \"\", isNegative: false };\n }\n\n if (i < (spec.format.units?.length ?? 0) - 1) {\n let wholePart = Math.trunc(unitValue);\n\n // Check if the remaining fractional part will round up to a full unit in the next (smaller) component\n if (spec.format.type === FormatType.Fractional && i === spec.unitConversions.length - 2) {\n // For the second-to-last unit with fractional formatting, check if rounding causes carry-over\n const fractionalPart = unitValue - wholePart;\n const nextUnitValue = applyConversion(fractionalPart, spec.unitConversions[i + 1].conversion);\n\n // Create a FractionalNumeric to determine what the rounded value would be\n const fn = new FractionalNumeric(Math.abs(nextUnitValue), spec.format.precision as FractionalPrecision, true);\n\n // If the fractional numeric rounds to a whole unit (integral part increased due to rounding)\n // and the next unit value would round to equal the conversion factor, we need to carry it over\n const roundedNextValue = parseFloat(fn.getIntegralString());\n const expectedNextValue = Math.floor(Math.abs(nextUnitValue));\n\n // Check if rounding caused the value to reach the conversion factor (1 full unit of the parent)\n const conversionFactor = spec.unitConversions[i + 1].conversion.factor;\n if (roundedNextValue > expectedNextValue && Math.abs(roundedNextValue - conversionFactor) < this.FPV_MINTHRESHOLD) {\n // The rounding caused a carry-over to a full parent unit, add 1 to the current unit's whole part\n wholePart += (unitValue >= 0 ? 1 : -1);\n }\n }\n\n const componentText = Formatter.formatCompositePart(Math.abs(wholePart), false, currentLabel, spec);\n remainingMagnitude = unitValue - wholePart;\n compositeStrings.push(componentText);\n } else {\n const componentText = Formatter.formatCompositePart(Math.abs(unitValue), true, currentLabel, spec);\n compositeStrings.push(componentText);\n }\n }\n\n return { componentText: compositeStrings.join(spec.format.spacerOrDefault), isNegative };\n }\n\n /** Format a quantity value into a single text string. Imitate how formatting done by server method NumericFormatSpec::FormatDouble.\n * @param magnitude quantity value\n */\n private static formatMagnitude(magnitude: number, spec: FormatterSpec): string {\n let posMagnitude = Math.abs(magnitude);\n if ((Math.abs(posMagnitude) < 0.0001) && spec.format.hasFormatTraitSet(FormatTraits.ZeroEmpty))\n return \"\";\n\n if (spec.format.hasFormatTraitSet(FormatTraits.ApplyRounding))\n posMagnitude = Math.abs(Formatter.roundDouble(magnitude, spec.format.roundFactor));\n\n const isSci = ((posMagnitude > 1.0e12) || spec.format.type === FormatType.Scientific);\n const isDecimal = (isSci || spec.format.type === FormatType.Decimal || spec.format.type === FormatType.Bearing || spec.format.type === FormatType.Azimuth) || spec.format.type === FormatType.Ratio;\n const isFractional = (!isDecimal && spec.format.type === FormatType.Fractional);\n /* const usesStops = spec.format.type === FormatType.Station; */\n const isPrecisionZero = spec.format.precision === DecimalPrecision.Zero;\n const isKeepSingleZero = spec.format.hasFormatTraitSet(FormatTraits.KeepSingleZero);\n const precisionScale = Math.pow(10.0, spec.format.precision);\n const isKeepTrailingZeroes = spec.format.hasFormatTraitSet(FormatTraits.TrailZeroes);\n let expInt = 0.0;\n\n if (isSci && (posMagnitude !== 0.0)) {\n let exp = Math.log10(posMagnitude);\n let negativeExp = false;\n if (exp < 0.0) {\n exp = -exp;\n negativeExp = true;\n }\n\n expInt = Math.floor(exp);\n if (spec.format.type === FormatType.Scientific) {\n if (spec.format.scientificType === ScientificType.ZeroNormalized && posMagnitude > 1.0)\n expInt += 1.0;\n else if (spec.format.scientificType === ScientificType.Normalized && posMagnitude < 1.0)\n expInt += 1.0;\n\n if (negativeExp)\n expInt = -expInt;\n }\n\n const factor = Math.pow(10.0, -expInt);\n posMagnitude *= factor;\n }\n\n let formattedValue = \"\";\n if (isDecimal) {\n const actualVal = isPrecisionZero ? posMagnitude + FPV_ROUNDFACTOR : posMagnitude + Formatter.FPV_MINTHRESHOLD;\n let wholePart = Math.floor(actualVal);\n let fractionPart = actualVal - wholePart;\n if (!isPrecisionZero) {\n fractionPart = Math.abs(fractionPart) * precisionScale + FPV_ROUNDFACTOR;\n if (fractionPart >= precisionScale) {\n wholePart += 1;\n fractionPart -= precisionScale;\n }\n }\n\n formattedValue = Formatter.integerPartToText(wholePart, spec);\n if (isPrecisionZero) {\n if (spec.format.hasFormatTraitSet(FormatTraits.KeepDecimalPoint) && !isKeepSingleZero)\n formattedValue = formattedValue + spec.format.decimalSeparator;\n else if (isKeepSingleZero)\n formattedValue = `${formattedValue + spec.format.decimalSeparator}0`;\n } else {\n fractionPart = Math.floor(fractionPart) / precisionScale;\n let fractionString = fractionPart.toFixed(spec.format.precision);\n // remove leading \"0.\"\n fractionString = fractionString.substring(2).padEnd(spec.format.precision, \"0\");\n if (!isKeepTrailingZeroes)\n fractionString = Formatter.trimTrailingZeroes(fractionString);\n\n if (fractionString.length > 0)\n formattedValue = formattedValue + spec.format.decimalSeparator + fractionString;\n else {\n if (spec.format.hasFormatTraitSet(FormatTraits.KeepDecimalPoint))\n formattedValue = formattedValue + spec.format.decimalSeparator + (isKeepSingleZero ? \"0\" : \"\");\n }\n }\n\n if (isSci) {\n const expString = `e${expInt.toFixed(0)}`;\n formattedValue = formattedValue + expString;\n }\n } else if (isFractional) {\n const fn = new FractionalNumeric(posMagnitude, spec.format.precision as FractionalPrecision, true);\n formattedValue = fn.getIntegralString();\n\n if (!fn.isZero && fn.hasFractionPart) {\n const wholeFractionSeparator = spec.format.hasFormatTraitSet(FormatTraits.FractionDash) ? \"-\" : \" \";\n const fractionString = `${fn.getNumeratorString()}/${fn.getDenominatorString()}`;\n formattedValue = formattedValue + wholeFractionSeparator + fractionString;\n }\n } else /* if (usesStops)*/ {\n // we assume that stopping value is always positive\n posMagnitude = Math.floor(posMagnitude * precisionScale + FPV_ROUNDFACTOR) / precisionScale;\n\n const baseFactor = spec.format.stationBaseFactor ?? 1;\n const stationOffsetSize = spec.format.stationOffsetSize || 0; // Provide default if undefined\n const denominator = baseFactor * Math.pow(10, stationOffsetSize);\n const tVal = Math.floor(posMagnitude); // this is the integer part only\n const hiPart = Math.floor(tVal / denominator);\n const lowPart = tVal - hiPart * denominator;\n const fract = posMagnitude - tVal;\n const fractionPart = Math.floor(fract * precisionScale + FPV_ROUNDFACTOR);\n const stationString = hiPart.toFixed(0) + spec.format.stationSeparator + lowPart.toFixed(0).padStart(stationOffsetSize, \"0\");\n let fractionString = \"\";\n if (fractionPart > 0) {\n fractionString = (fractionPart/precisionScale).toFixed(spec.format.precision);\n // remove leading \"0.\"\n fractionString = fractionString.substring(2).padEnd(spec.format.precision, \"0\");\n if (!isKeepTrailingZeroes)\n fractionString = Formatter.trimTrailingZeroes(fractionString);\n\n formattedValue = stationString + spec.format.decimalSeparator + fractionString;\n } else {\n if (isKeepTrailingZeroes)\n fractionString = spec.format.decimalSeparator + \"\".padEnd(spec.format.precision, \"0\");\n else if (spec.format.hasFormatTraitSet(FormatTraits.KeepDecimalPoint))\n fractionString = spec.format.decimalSeparator;\n formattedValue = stationString + fractionString;\n }\n }\n\n if(spec.format.minWidth) {\n formattedValue = this.countAndPad(formattedValue, spec.format.minWidth);\n }\n\n return formattedValue;\n }\n\n private static countAndPad(value: string, minWidth: number): string {\n const regex = /[\\d,.]/g;\n const matches = value.match(regex);\n const count = matches ? matches.length : 0;\n if (count < minWidth) {\n value = value.padStart(minWidth, \"0\");\n }\n return value;\n }\n\n /** Helper function to apply sign formatting based on showSignOption\n * @param isNegative whether the value should be treated as negative\n * @param showSignOption the sign display option\n * @param formatType the format type (to handle bearing/azimuth exceptions)\n * @returns object containing prefix and suffix strings\n */\n private static applySignFormatting(isNegative: boolean, showSignOption: ShowSignOption, formatType: FormatType): { prefix: string, suffix: string } {\n let prefix = \"\";\n let suffix = \"\";\n\n switch (showSignOption) {\n case ShowSignOption.NegativeParentheses:\n if (isNegative) {\n prefix = \"(\";\n suffix = \")\";\n }\n break;\n\n case ShowSignOption.OnlyNegative:\n if (isNegative && formatType !== FormatType.Bearing && formatType !== FormatType.Azimuth) {\n prefix = \"-\";\n }\n break;\n\n case ShowSignOption.SignAlways:\n prefix = isNegative ? \"-\" : \"+\";\n break;\n\n case ShowSignOption.NoSign:\n default:\n break;\n }\n\n return { prefix, suffix };\n }\n\n /** Format a quantity value into a single text string based on the current format specification of this class.\n * @param magnitude defines the value to spec.format.\n * @param spec A FormatterSpec object the defines specification for the magnitude and unit conversions for the formatter.\n */\n public static formatQuantity(magnitude: number, spec: FormatterSpec): string {\n let valueIsNegative = magnitude < 0.0;\n let prefix = \"\";\n let suffix = \"\";\n let formattedValue = \"\";\n\n // Handle bearing/azimuth special formatting\n if (spec.format.type === FormatType.Bearing || spec.format.type === FormatType.Azimuth) {\n const result = this.processBearingAndAzimuth(magnitude, spec);\n magnitude = result.magnitude;\n prefix = result.prefix ?? \"\";\n suffix = result.suffix ?? \"\";\n }\n\n let formattedMagnitude = \"\";\n\n if (spec.format.type === FormatType.Ratio && spec.unitConversions.length >= 3) {\n // Handle ratio formatting separately when 2-unit composite provides 3 conversion specs\n const ratioResult = this.formatRatioQuantity(magnitude, spec);\n formattedMagnitude = ratioResult.componentText;\n valueIsNegative = ratioResult.isNegative;\n } else if (spec.format.hasUnits) {\n const compositeResult = Formatter.formatComposite(magnitude, spec);\n formattedMagnitude = compositeResult.componentText;\n // Override the sign detection with the composite conversion result\n valueIsNegative = compositeResult.isNegative;\n } else {\n // unitless quantity\n formattedMagnitude = Formatter.formatMagnitude(magnitude, spec);\n if (formattedMagnitude.length > 0 && spec.unitConversions.length > 0 && spec.format.hasFormatTraitSet(FormatTraits.ShowUnitLabel)) {\n if (spec.format.hasFormatTraitSet(FormatTraits.PrependUnitLabel))\n formattedMagnitude = spec.unitConversions[0].label + spec.format.uomSeparator + formattedMagnitude;\n else\n formattedMagnitude = formattedMagnitude + spec.format.uomSeparator + spec.unitConversions[0].label;\n }\n // For unitless quantities, keep original sign detection\n }\n\n // Apply sign formatting based on the final determined sign\n const signFormatting = this.applySignFormatting(valueIsNegative, spec.format.showSignOption, spec.format.type);\n prefix += signFormatting.prefix;\n suffix = signFormatting.suffix + suffix;\n\n // add Sign prefix and suffix as necessary\n if ((prefix.length > 0 || suffix.length > 0) && formattedMagnitude.length > 0)\n formattedValue = prefix + formattedMagnitude + suffix;\n else\n formattedValue = formattedMagnitude;\n\n return formattedValue;\n }\n\n private static processBearingAndAzimuth(magnitude: number, spec: FormatterSpec): {magnitude: number, prefix?: string, suffix?: string} {\n const type = spec.format.type;\n if (type !== FormatType.Bearing && type !== FormatType.Azimuth)\n return {magnitude};\n\n const revolution = this.getRevolution(spec);\n magnitude = this.normalizeAngle(magnitude, revolution);\n const quarterRevolution = revolution / 4;\n\n if (type === FormatType.Bearing) {\n let quadrant = 0;\n while (magnitude > quarterRevolution) {\n magnitude -= quarterRevolution;\n quadrant++;\n }\n let prefix: string = \"\";\n let suffix: string = \"\";\n\n // Quadrants are\n // 3 0\n // 2 1\n // For quadrants 1 and 3 we have to subtract the angle from quarterRevolution degrees because they go counter-clockwise\n if (quadrant === 1 || quadrant === 3)\n magnitude = quarterRevolution - magnitude;\n\n // TODO: at some point we will want to open this for localization, in the first release it's going to be hard coded\n if (quadrant === 0 || quadrant === 3)\n prefix = \"N\";\n\n if (quadrant === 2 || quadrant === 1)\n prefix = \"S\";\n\n if (quadrant === 0 || quadrant === 1)\n suffix = \"E\";\n\n if (quadrant === 3 || quadrant === 2)\n suffix = \"W\";\n\n // special case, if in quadrant 2 and value is very close to quarter revolution (90°), turn prefix to N because N90:00:00W is preferred over S90:00:00W\n if (quadrant === 2 && spec.unitConversions.length > 0) {\n // To determine if value is small, we need to convert it to the smallest unit presented and use the provided precision on it\n const unitConversion = spec.unitConversions[spec.unitConversions.length - 1].conversion;\n const smallestFormattedDelta = applyConversion((quarterRevolution - magnitude), unitConversion) + this.FPV_MINTHRESHOLD;\n\n const precisionScale = Math.pow(10.0, spec.format.precision);\n const floor = Math.floor((smallestFormattedDelta) * precisionScale + FPV_ROUNDFACTOR) / precisionScale;\n if(floor === 0) {\n prefix = \"N\";\n }\n }\n\n return {magnitude, prefix, suffix};\n }\n\n if (type === FormatType.Azimuth) {\n let azimuthBase = 0; // default base is North\n if (spec.format.azimuthBase !== undefined) {\n if (spec.azimuthBaseConversion === undefined) {\n throw new QuantityError(QuantityStatus.MissingRequiredProperty, `Missing azimuth base conversion for interpreting ${spec.name}'s azimuth base.`);\n }\n const azBaseQuantity: Quantity = new Quantity(spec.format.azimuthBaseUnit, spec.format.azimuthBase);\n const azBaseConverted = azBaseQuantity.convertTo(spec.persistenceUnit, spec.azimuthBaseConversion);\n if (!azBaseConverted.isValid) {\n throw new QuantityError(QuantityStatus.UnsupportedUnit, `Failed to convert azimuth base unit to ${spec.persistenceUnit.name}.`);\n }\n azimuthBase = this.normalizeAngle(azBaseConverted.magnitude, revolution);\n }\n\n if (azimuthBase === 0.0 && spec.format.azimuthClockwiseOrDefault)\n return {magnitude}; // no conversion necessary, the input is already using the result parameters (north base and clockwise)\n\n // subtract the base from the actual value\n magnitude -= azimuthBase;\n if (spec.format.azimuthClockwiseOrDefault)\n return {magnitude: this.normalizeAngle(magnitude, revolution)};\n\n // turn it into a counter-clockwise angle\n magnitude = revolution - magnitude;\n // normalize the result as it may have become negative or exceed the revolution\n magnitude = this.normalizeAngle(magnitude, revolution);\n }\n\n return {magnitude};\n }\n\n private static normalizeAngle(magnitude: number, revolution: number): number {\n magnitude = magnitude % revolution; // Strip anything that goes around more than once\n\n if (magnitude < 0) // If the value is negative, we want to normalize it to a positive angle\n magnitude += revolution;\n\n return magnitude;\n }\n\n private static getRevolution(spec: FormatterSpec): number {\n if (spec.revolutionConversion === undefined) {\n throw new QuantityError(QuantityStatus.MissingRequiredProperty, `Missing revolution unit conversion for calculating ${spec.name}'s revolution.`);\n }\n\n const revolution: Quantity = new Quantity(spec.format.revolutionUnit, 1.0);\n const converted = revolution.convertTo(spec.persistenceUnit, spec.revolutionConversion);\n if (!converted.isValid) {\n throw new QuantityError(QuantityStatus.UnsupportedUnit, `Failed to convert revolution unit to ${spec.persistenceUnit.name}.`);\n }\n\n return converted.magnitude;\n }\n\n private static formatRatioPart(value: number, spec: FormatterSpec, side: \"numerator\" | \"denominator\"): string {\n const formatType = spec.format.ratioFormatType === \"Fractional\" ? FormatType.Fractional : FormatType.Decimal;\n const tempFormat = spec.format.clone({ type: formatType });\n const tempSpec = new FormatterSpec(spec.name, tempFormat, spec.unitConversions, spec.persistenceUnit);\n let formattedValue = this.formatMagnitude(value, tempSpec);\n\n // For fractional ratio formatting, suppress leading \"0\" if the value is purely fractional\n if (formatType === FormatType.Fractional && formattedValue.startsWith(\"0 \")) {\n formattedValue = formattedValue.substring(2); // Remove \"0 \" prefix\n }\n\n // Add unit label if ShowUnitLabel trait is set\n // unitConversions[0] = ratio scale factor, [1] = numerator unit, [2] = denominator unit\n if (spec.format.hasFormatTraitSet(FormatTraits.ShowUnitLabel) && spec.unitConversions.length >= 3) {\n const labelToAdd = side === \"numerator\" ? spec.unitConversions[1].label : spec.unitConversions[2].label;\n formattedValue = formattedValue + labelToAdd;\n }\n\n return formattedValue;\n }\n\n /** Format a ratio quantity value (separate from composite formatting) */\n private static formatRatioQuantity(magnitude: number, spec: FormatterSpec): { componentText: string, isNegative: boolean } {\n const unitConversion = spec.unitConversions[0].conversion;\n let unitValue = 0.0;\n\n try {\n unitValue = applyConversion(magnitude, unitConversion) + this.FPV_MINTHRESHOLD;\n } catch (e) {\n // The \"InvertingZero\" error is thrown when the value is zero and the conversion factor is inverted.\n // For ratio, we return \"1:0\" as the formatted value.\n if (e instanceof QuantityError && e.errorNumber === QuantityStatus.InvertingZero) {\n return { componentText: \"1:0\", isNegative: false };\n }\n throw e;\n }\n\n const componentText = this.formatRatio(unitValue, spec);\n const isNegative = unitValue < 0;\n return { componentText, isNegative };\n }\n\n private static formatRatio(magnitude: number, spec: FormatterSpec): string {\n if (null === spec.format.ratioType)\n throw new QuantityError(QuantityStatus.InvalidCompositeFormat, `The Format ${spec.format.name} must have a ratio type specified.`);\n\n const precisionScale = Math.pow(10.0, spec.format.precision);\n const separator = spec.format.ratioSeparator;\n let reciprocal = 0;\n\n // Helper to get unit labels if ShowUnitLabel is set\n const getUnitLabels = (): { numeratorLabel: string, denominatorLabel: string } => {\n if (spec.format.hasFormatTraitSet(FormatTraits.ShowUnitLabel) && spec.unitConversions.length >= 3) {\n return { numeratorLabel: spec.unitConversions[1].label, denominatorLabel: spec.unitConversions[2].label };\n }\n return { numeratorLabel: \"\", denominatorLabel: \"\" };\n };\n\n const { numeratorLabel, denominatorLabel } = getUnitLabels();\n\n if (magnitude === 0.0)\n return `0${separator}1`;\n else\n reciprocal = 1.0/magnitude;\n switch (spec.format.ratioType) {\n case RatioType.OneToN:\n return `1${numeratorLabel}${separator}${this.formatRatioPart(reciprocal, spec, \"denominator\")}`;\n case RatioType.NToOne:\n return `${this.formatRatioPart(magnitude, spec, \"numerator\")}${separator}1${denominatorLabel}`;\n case RatioType.ValueBased:\n if (magnitude > 1.0) {\n return `${this.formatRatioPart(magnitude, spec, \"numerator\")}${separator}1${denominatorLabel}`;\n } else {\n return `1${numeratorLabel}${separator}${this.formatRatioPart(reciprocal, spec, \"denominator\")}`;\n }\n case RatioType.UseGreatestCommonDivisor:\n magnitude = Math.round(magnitude * precisionScale)/precisionScale;\n let numerator = magnitude * precisionScale;\n let denominator = precisionScale;\n\n const gcd = FractionalNumeric.getGreatestCommonFactor(numerator, denominator);\n numerator /= gcd;\n denominator /= gcd;\n\n return `${this.formatRatioPart(numerator, spec, \"numerator\")}${separator}${this.formatRatioPart(denominator, spec, \"denominator\")}`;\n default:\n throw new QuantityError(QuantityStatus.InvalidCompositeFormat, `The Format ${spec.format.name} has an invalid ratio type specified.`);\n }\n }\n}\n"]}
1
+ {"version":3,"file":"Formatter.js","sourceRoot":"","sources":["../../../src/Formatter/Formatter.ts"],"names":[],"mappings":"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","sourcesContent":["/*---------------------------------------------------------------------------------------------\r\n* Copyright (c) Bentley Systems, Incorporated. All rights reserved.\r\n* See LICENSE.md in the project root for license terms and full copyright notice.\r\n*--------------------------------------------------------------------------------------------*/\r\n/** @packageDocumentation\r\n * @module Quantity\r\n */\r\n\r\nimport { QuantityConstants } from \"../Constants\";\r\nimport { QuantityError, QuantityStatus } from \"../Exception\";\r\nimport { FormatterSpec } from \"./FormatterSpec\";\r\nimport { DecimalPrecision, FormatTraits, FormatType, FractionalPrecision, RatioType, ScientificType, ShowSignOption } from \"./FormatEnums\";\r\nimport { applyConversion, Quantity } from \"../Quantity\";\r\n\r\n/** rounding additive\r\n * @internal\r\n */\r\nconst FPV_ROUNDFACTOR = 0.50000000001;\r\n\r\n/** A private helper class used to format fraction part of value into a numerator and denominator.\r\n * @internal\r\n */\r\nclass FractionalNumeric {\r\n private _integral: number = 0;\r\n private _numerator: number = 0;\r\n private _denominator: number = 1;\r\n private _greatestCommonFactor: number = 1;\r\n private _textParts: string[] = [];\r\n\r\n constructor(value: number, precision: FractionalPrecision, reduce: boolean) {\r\n this.calculate(value, precision);\r\n this.formTextParts(reduce);\r\n }\r\n\r\n private calculate(value: number, denominator: number) {\r\n const positiveValue = Math.abs(value);\r\n this._denominator = denominator;\r\n this._integral = Math.floor(positiveValue);\r\n const fractionPart = positiveValue - this._integral;\r\n this._numerator = Math.floor(fractionPart * this._denominator + FPV_ROUNDFACTOR);\r\n\r\n if (0 !== denominator && (this._numerator / this._denominator) === 1) {\r\n this._numerator = 0;\r\n this._integral += 1;\r\n } else {\r\n this._greatestCommonFactor = FractionalNumeric.getGreatestCommonFactor(this._numerator, this._denominator);\r\n }\r\n }\r\n\r\n /** Determine the GCD given two values. This value can be used to reduce a fraction.\r\n * See algorithm description http://en.wikipedia.org/wiki/Euclidean_algorithm\r\n */\r\n public static getGreatestCommonFactor(numerator: number, denominator: number): number {\r\n let r;\r\n while (denominator !== 0) {\r\n r = numerator % denominator;\r\n numerator = denominator;\r\n denominator = r;\r\n }\r\n return (numerator < 0) ? -numerator : numerator;\r\n }\r\n\r\n public get greatestCommonFactor(): number { return this._greatestCommonFactor; }\r\n public get hasFractionPart(): boolean { return this._textParts.length > 0; }\r\n public get isZero(): boolean { return 0 === this._numerator; }\r\n\r\n public getIntegralString(): string {\r\n if (this._textParts.length > 0)\r\n return this._textParts[0];\r\n\r\n return \"\";\r\n }\r\n\r\n public getNumeratorString(): string {\r\n if (this._textParts.length >= 3)\r\n return this._textParts[1];\r\n\r\n return \"\";\r\n }\r\n\r\n public getDenominatorString(): string {\r\n if (this._textParts.length >= 3)\r\n return this._textParts[2];\r\n\r\n return \"\";\r\n }\r\n\r\n private formTextParts(reduce: boolean): void {\r\n let numerator = this._numerator;\r\n let denominator = this._denominator;\r\n\r\n if (reduce && this._greatestCommonFactor > 1) {\r\n numerator /= this.greatestCommonFactor;\r\n denominator /= this.greatestCommonFactor;\r\n }\r\n\r\n this._textParts.push(this._integral.toFixed(0));\r\n if (numerator > 0) {\r\n this._textParts.push(numerator.toFixed(0));\r\n this._textParts.push(denominator.toFixed(0));\r\n }\r\n }\r\n}\r\n\r\n/** A helper class that contains methods used to format quantity values based on a format that are defined via the Format class.\r\n * @beta\r\n */\r\nexport class Formatter {\r\n private static FPV_MINTHRESHOLD = 1.0e-14;\r\n\r\n private static isNegligible(value: number): boolean { return (Math.abs(value) < Formatter.FPV_MINTHRESHOLD); }\r\n\r\n /** Return floating point value rounded by specific rounding factor.\r\n * @param value Value to be rounded.\r\n * @param roundTo Rounding factor.\r\n */\r\n private static roundDouble(value: number, roundTo: number): number {\r\n if (Formatter.isNegligible(roundTo))\r\n return value;\r\n\r\n roundTo = Math.abs(roundTo);\r\n let rnd = FPV_ROUNDFACTOR + (value / roundTo);\r\n const iVal = Math.floor(rnd);\r\n rnd = iVal * roundTo;\r\n return (value < 0.0) ? -rnd : rnd;\r\n }\r\n\r\n /** Generate a formatted text string integer value insert 1000 separators if appropriate.\r\n * @param wholePart Integer value to be formatted.\r\n */\r\n private static integerPartToText(wholePart: number, spec: FormatterSpec): string {\r\n // build invariant string represent wholePart\r\n let formattedValue = wholePart.toFixed(0);\r\n\r\n if ((formattedValue.length > 3) && (spec.format.hasFormatTraitSet(FormatTraits.Use1000Separator) && (spec.format.thousandSeparator.length > 0))) {\r\n let numSeparators = Math.floor(formattedValue.length / 3);\r\n let groupLength = formattedValue.length % 3;\r\n\r\n if (groupLength === 0) {\r\n numSeparators = numSeparators - 1;\r\n groupLength = groupLength + 3;\r\n }\r\n\r\n let outString = formattedValue.substring(0, groupLength);\r\n\r\n for (let i = 1; i <= numSeparators; i += 1) {\r\n outString = outString + spec.format.thousandSeparator + formattedValue.substring(groupLength, groupLength + 3);\r\n groupLength = groupLength + 3;\r\n }\r\n\r\n formattedValue = outString;\r\n }\r\n\r\n return formattedValue;\r\n }\r\n\r\n /** Trim trailing \"0\" from the text that represent the fractional part of a floating point value.\r\n * @param strVal The value string.\r\n */\r\n private static trimTrailingZeroes(strVal: string): string {\r\n let lastNonZeroCharIndex = -1;\r\n for (let i = strVal.length - 1; i >= 0; i--) {\r\n if (strVal.charCodeAt(i) !== QuantityConstants.CHAR_DIGIT_ZERO) {\r\n lastNonZeroCharIndex = i;\r\n break;\r\n }\r\n }\r\n if (lastNonZeroCharIndex >= 0)\r\n return strVal.substring(0, lastNonZeroCharIndex + 1);\r\n return \"\";\r\n }\r\n\r\n /** Format a quantity value into a composite format such as ft-in or deg-min-sec.\r\n * @param compositeValue The value for this part of the composite\r\n * @param isLastPart If false the composite value should be a whole value, if true then the value should be formatted as a floating point value.\r\n * @param label Label for this part of the composite. This will be either the default unit label or a custom label specified the format specification.\r\n */\r\n private static formatCompositePart(compositeValue: number, isLastPart: boolean, label: string, spec: FormatterSpec): string {\r\n let componentText = \"\";\r\n if (!isLastPart) {\r\n componentText = Formatter.integerPartToText(compositeValue, spec);\r\n if(spec.format.minWidth) { // integerPartToText does not do this padding\r\n componentText = this.countAndPad(componentText, spec.format.minWidth);\r\n }\r\n } else {\r\n componentText = Formatter.formatMagnitude(compositeValue, spec);\r\n }\r\n\r\n\r\n if (spec.format.hasFormatTraitSet(FormatTraits.ShowUnitLabel)) {\r\n componentText = componentText + spec.format.uomSeparator + label;\r\n }\r\n\r\n return componentText;\r\n }\r\n\r\n /** Format a quantity value into a composite format such as ft-in or deg-min-sec.\r\n * @param magnitude quantity value\r\n * @param fromUnit quantity unit\r\n */\r\n private static formatComposite(magnitude: number, spec: FormatterSpec): { componentText: string, isNegative: boolean } {\r\n const compositeStrings: string[] = [];\r\n let isNegative = false;\r\n let remainingMagnitude = magnitude;\r\n\r\n for (let i = 0; i < spec.unitConversions.length; i++) {\r\n const currentLabel = spec.unitConversions[i].label;\r\n const unitConversion = spec.unitConversions[i].conversion;\r\n\r\n if (i > 0 && unitConversion.factor < 1.0)\r\n throw new QuantityError(QuantityStatus.InvalidCompositeFormat, `The Format ${spec.format.name} has a invalid unit specification.`);\r\n if (i > 0 && unitConversion.offset !== 0) // offset should only ever be defined for major unit\r\n throw new QuantityError(QuantityStatus.InvalidCompositeFormat, `The Format ${spec.format.name} has a invalid unit specification.`);\r\n\r\n // Handle ratio format with composite units\r\n if (spec.format.type === FormatType.Ratio) {\r\n let ratioUnitValue = 0.0;\r\n try {\r\n ratioUnitValue = applyConversion(remainingMagnitude, unitConversion) + this.FPV_MINTHRESHOLD;\r\n } catch (e) {\r\n // The \"InvertingZero\" error is thrown when the value is zero and the conversion factor is inverted.\r\n // For ratio, we actually want to support this corner case and return \"1:0\" as the formatted value.\r\n if (e instanceof QuantityError && e.errorNumber === QuantityStatus.InvertingZero) {\r\n return { componentText: \"1:0\", isNegative: false };\r\n }\r\n throw e;\r\n }\r\n\r\n compositeStrings.push(this.formatRatio(ratioUnitValue, spec));\r\n isNegative = ratioUnitValue < 0;\r\n continue;\r\n }\r\n\r\n let unitValue = applyConversion(remainingMagnitude, unitConversion) + this.FPV_MINTHRESHOLD;\r\n if (0 === i) {\r\n // Only set isNegative from the first (major) unit conversion\r\n isNegative = unitValue < 0;\r\n\r\n // Use a minimum precision of 8 for intermediate rounding to avoid loss of precision in composite formats,\r\n // but use higher precision if the format specifies it\r\n const precisionScale = Math.pow(10, Math.max(8, spec.format.precision));\r\n unitValue = Math.floor(unitValue * precisionScale + FPV_ROUNDFACTOR) / precisionScale;\r\n if ((Math.abs(unitValue) < 0.0001) && spec.format.hasFormatTraitSet(FormatTraits.ZeroEmpty))\r\n return { componentText: \"\", isNegative: false };\r\n }\r\n\r\n if (i < (spec.format.units?.length ?? 0) - 1) {\r\n let wholePart = Math.trunc(unitValue);\r\n\r\n // Check if the remaining fractional part will round up to a full unit in the next (smaller) component\r\n if (spec.format.type === FormatType.Fractional && i === spec.unitConversions.length - 2) {\r\n // For the second-to-last unit with fractional formatting, check if rounding causes carry-over\r\n const fractionalPart = unitValue - wholePart;\r\n const nextUnitValue = applyConversion(fractionalPart, spec.unitConversions[i + 1].conversion);\r\n\r\n // Create a FractionalNumeric to determine what the rounded value would be\r\n const fn = new FractionalNumeric(Math.abs(nextUnitValue), spec.format.precision as FractionalPrecision, true);\r\n\r\n // If the fractional numeric rounds to a whole unit (integral part increased due to rounding)\r\n // and the next unit value would round to equal the conversion factor, we need to carry it over\r\n const roundedNextValue = parseFloat(fn.getIntegralString());\r\n const expectedNextValue = Math.floor(Math.abs(nextUnitValue));\r\n\r\n // Check if rounding caused the value to reach the conversion factor (1 full unit of the parent)\r\n const conversionFactor = spec.unitConversions[i + 1].conversion.factor;\r\n if (roundedNextValue > expectedNextValue && Math.abs(roundedNextValue - conversionFactor) < this.FPV_MINTHRESHOLD) {\r\n // The rounding caused a carry-over to a full parent unit, add 1 to the current unit's whole part\r\n wholePart += (unitValue >= 0 ? 1 : -1);\r\n }\r\n }\r\n\r\n const componentText = Formatter.formatCompositePart(Math.abs(wholePart), false, currentLabel, spec);\r\n remainingMagnitude = unitValue - wholePart;\r\n compositeStrings.push(componentText);\r\n } else {\r\n const componentText = Formatter.formatCompositePart(Math.abs(unitValue), true, currentLabel, spec);\r\n compositeStrings.push(componentText);\r\n }\r\n }\r\n\r\n return { componentText: compositeStrings.join(spec.format.spacerOrDefault), isNegative };\r\n }\r\n\r\n /** Format a quantity value into a single text string. Imitate how formatting done by server method NumericFormatSpec::FormatDouble.\r\n * @param magnitude quantity value\r\n */\r\n private static formatMagnitude(magnitude: number, spec: FormatterSpec): string {\r\n let posMagnitude = Math.abs(magnitude);\r\n if ((Math.abs(posMagnitude) < 0.0001) && spec.format.hasFormatTraitSet(FormatTraits.ZeroEmpty))\r\n return \"\";\r\n\r\n if (spec.format.hasFormatTraitSet(FormatTraits.ApplyRounding))\r\n posMagnitude = Math.abs(Formatter.roundDouble(magnitude, spec.format.roundFactor));\r\n\r\n const isSci = ((posMagnitude > 1.0e12) || spec.format.type === FormatType.Scientific);\r\n const isDecimal = (isSci || spec.format.type === FormatType.Decimal || spec.format.type === FormatType.Bearing || spec.format.type === FormatType.Azimuth) || spec.format.type === FormatType.Ratio;\r\n const isFractional = (!isDecimal && spec.format.type === FormatType.Fractional);\r\n /* const usesStops = spec.format.type === FormatType.Station; */\r\n const isPrecisionZero = spec.format.precision === DecimalPrecision.Zero;\r\n const isKeepSingleZero = spec.format.hasFormatTraitSet(FormatTraits.KeepSingleZero);\r\n const precisionScale = Math.pow(10.0, spec.format.precision);\r\n const isKeepTrailingZeroes = spec.format.hasFormatTraitSet(FormatTraits.TrailZeroes);\r\n let expInt = 0.0;\r\n\r\n if (isSci && (posMagnitude !== 0.0)) {\r\n let exp = Math.log10(posMagnitude);\r\n let negativeExp = false;\r\n if (exp < 0.0) {\r\n exp = -exp;\r\n negativeExp = true;\r\n }\r\n\r\n expInt = Math.floor(exp);\r\n if (spec.format.type === FormatType.Scientific) {\r\n if (spec.format.scientificType === ScientificType.ZeroNormalized && posMagnitude > 1.0)\r\n expInt += 1.0;\r\n else if (spec.format.scientificType === ScientificType.Normalized && posMagnitude < 1.0)\r\n expInt += 1.0;\r\n\r\n if (negativeExp)\r\n expInt = -expInt;\r\n }\r\n\r\n const factor = Math.pow(10.0, -expInt);\r\n posMagnitude *= factor;\r\n }\r\n\r\n let formattedValue = \"\";\r\n if (isDecimal) {\r\n const actualVal = isPrecisionZero ? posMagnitude + FPV_ROUNDFACTOR : posMagnitude + Formatter.FPV_MINTHRESHOLD;\r\n let wholePart = Math.floor(actualVal);\r\n let fractionPart = actualVal - wholePart;\r\n if (!isPrecisionZero) {\r\n fractionPart = Math.abs(fractionPart) * precisionScale + FPV_ROUNDFACTOR;\r\n if (fractionPart >= precisionScale) {\r\n wholePart += 1;\r\n fractionPart -= precisionScale;\r\n }\r\n }\r\n\r\n formattedValue = Formatter.integerPartToText(wholePart, spec);\r\n if (isPrecisionZero) {\r\n if (spec.format.hasFormatTraitSet(FormatTraits.KeepDecimalPoint) && !isKeepSingleZero)\r\n formattedValue = formattedValue + spec.format.decimalSeparator;\r\n else if (isKeepSingleZero)\r\n formattedValue = `${formattedValue + spec.format.decimalSeparator}0`;\r\n } else {\r\n fractionPart = Math.floor(fractionPart) / precisionScale;\r\n let fractionString = fractionPart.toFixed(spec.format.precision);\r\n // remove leading \"0.\"\r\n fractionString = fractionString.substring(2).padEnd(spec.format.precision, \"0\");\r\n if (!isKeepTrailingZeroes)\r\n fractionString = Formatter.trimTrailingZeroes(fractionString);\r\n\r\n if (fractionString.length > 0)\r\n formattedValue = formattedValue + spec.format.decimalSeparator + fractionString;\r\n else {\r\n if (spec.format.hasFormatTraitSet(FormatTraits.KeepDecimalPoint))\r\n formattedValue = formattedValue + spec.format.decimalSeparator + (isKeepSingleZero ? \"0\" : \"\");\r\n }\r\n }\r\n\r\n if (isSci) {\r\n const expString = `e${expInt.toFixed(0)}`;\r\n formattedValue = formattedValue + expString;\r\n }\r\n } else if (isFractional) {\r\n const fn = new FractionalNumeric(posMagnitude, spec.format.precision as FractionalPrecision, true);\r\n formattedValue = fn.getIntegralString();\r\n\r\n if (!fn.isZero && fn.hasFractionPart) {\r\n const wholeFractionSeparator = spec.format.hasFormatTraitSet(FormatTraits.FractionDash) ? \"-\" : \" \";\r\n const fractionString = `${fn.getNumeratorString()}/${fn.getDenominatorString()}`;\r\n formattedValue = formattedValue + wholeFractionSeparator + fractionString;\r\n }\r\n } else /* if (usesStops)*/ {\r\n // we assume that stopping value is always positive\r\n posMagnitude = Math.floor(posMagnitude * precisionScale + FPV_ROUNDFACTOR) / precisionScale;\r\n\r\n const baseFactor = spec.format.stationBaseFactor ?? 1;\r\n const stationOffsetSize = spec.format.stationOffsetSize || 0; // Provide default if undefined\r\n const denominator = baseFactor * Math.pow(10, stationOffsetSize);\r\n const tVal = Math.floor(posMagnitude); // this is the integer part only\r\n const hiPart = Math.floor(tVal / denominator);\r\n const lowPart = tVal - hiPart * denominator;\r\n const fract = posMagnitude - tVal;\r\n const fractionPart = Math.floor(fract * precisionScale + FPV_ROUNDFACTOR);\r\n const stationString = hiPart.toFixed(0) + spec.format.stationSeparator + lowPart.toFixed(0).padStart(stationOffsetSize, \"0\");\r\n let fractionString = \"\";\r\n if (fractionPart > 0) {\r\n fractionString = (fractionPart/precisionScale).toFixed(spec.format.precision);\r\n // remove leading \"0.\"\r\n fractionString = fractionString.substring(2).padEnd(spec.format.precision, \"0\");\r\n if (!isKeepTrailingZeroes)\r\n fractionString = Formatter.trimTrailingZeroes(fractionString);\r\n\r\n formattedValue = stationString + spec.format.decimalSeparator + fractionString;\r\n } else {\r\n if (isKeepTrailingZeroes)\r\n fractionString = spec.format.decimalSeparator + \"\".padEnd(spec.format.precision, \"0\");\r\n else if (spec.format.hasFormatTraitSet(FormatTraits.KeepDecimalPoint))\r\n fractionString = spec.format.decimalSeparator;\r\n formattedValue = stationString + fractionString;\r\n }\r\n }\r\n\r\n if(spec.format.minWidth) {\r\n formattedValue = this.countAndPad(formattedValue, spec.format.minWidth);\r\n }\r\n\r\n return formattedValue;\r\n }\r\n\r\n private static countAndPad(value: string, minWidth: number): string {\r\n const regex = /[\\d,.]/g;\r\n const matches = value.match(regex);\r\n const count = matches ? matches.length : 0;\r\n if (count < minWidth) {\r\n value = value.padStart(minWidth, \"0\");\r\n }\r\n return value;\r\n }\r\n\r\n /** Helper function to apply sign formatting based on showSignOption\r\n * @param isNegative whether the value should be treated as negative\r\n * @param showSignOption the sign display option\r\n * @param formatType the format type (to handle bearing/azimuth exceptions)\r\n * @returns object containing prefix and suffix strings\r\n */\r\n private static applySignFormatting(isNegative: boolean, showSignOption: ShowSignOption, formatType: FormatType): { prefix: string, suffix: string } {\r\n let prefix = \"\";\r\n let suffix = \"\";\r\n\r\n switch (showSignOption) {\r\n case ShowSignOption.NegativeParentheses:\r\n if (isNegative) {\r\n prefix = \"(\";\r\n suffix = \")\";\r\n }\r\n break;\r\n\r\n case ShowSignOption.OnlyNegative:\r\n if (isNegative && formatType !== FormatType.Bearing && formatType !== FormatType.Azimuth) {\r\n prefix = \"-\";\r\n }\r\n break;\r\n\r\n case ShowSignOption.SignAlways:\r\n prefix = isNegative ? \"-\" : \"+\";\r\n break;\r\n\r\n case ShowSignOption.NoSign:\r\n default:\r\n break;\r\n }\r\n\r\n return { prefix, suffix };\r\n }\r\n\r\n /** Format a quantity value into a single text string based on the current format specification of this class.\r\n * @param magnitude defines the value to spec.format.\r\n * @param spec A FormatterSpec object the defines specification for the magnitude and unit conversions for the formatter.\r\n */\r\n public static formatQuantity(magnitude: number, spec: FormatterSpec): string {\r\n let valueIsNegative = magnitude < 0.0;\r\n let prefix = \"\";\r\n let suffix = \"\";\r\n let formattedValue = \"\";\r\n\r\n // Handle bearing/azimuth special formatting\r\n if (spec.format.type === FormatType.Bearing || spec.format.type === FormatType.Azimuth) {\r\n const result = this.processBearingAndAzimuth(magnitude, spec);\r\n magnitude = result.magnitude;\r\n prefix = result.prefix ?? \"\";\r\n suffix = result.suffix ?? \"\";\r\n }\r\n\r\n let formattedMagnitude = \"\";\r\n\r\n if (spec.format.type === FormatType.Ratio && spec.unitConversions.length >= 3) {\r\n // Handle ratio formatting separately when 2-unit composite provides 3 conversion specs\r\n const ratioResult = this.formatRatioQuantity(magnitude, spec);\r\n formattedMagnitude = ratioResult.componentText;\r\n valueIsNegative = ratioResult.isNegative;\r\n } else if (spec.format.hasUnits) {\r\n const compositeResult = Formatter.formatComposite(magnitude, spec);\r\n formattedMagnitude = compositeResult.componentText;\r\n // Override the sign detection with the composite conversion result\r\n valueIsNegative = compositeResult.isNegative;\r\n } else {\r\n // unitless quantity\r\n formattedMagnitude = Formatter.formatMagnitude(magnitude, spec);\r\n if (formattedMagnitude.length > 0 && spec.unitConversions.length > 0 && spec.format.hasFormatTraitSet(FormatTraits.ShowUnitLabel)) {\r\n if (spec.format.hasFormatTraitSet(FormatTraits.PrependUnitLabel))\r\n formattedMagnitude = spec.unitConversions[0].label + spec.format.uomSeparator + formattedMagnitude;\r\n else\r\n formattedMagnitude = formattedMagnitude + spec.format.uomSeparator + spec.unitConversions[0].label;\r\n }\r\n // For unitless quantities, keep original sign detection\r\n }\r\n\r\n // Apply sign formatting based on the final determined sign\r\n const signFormatting = this.applySignFormatting(valueIsNegative, spec.format.showSignOption, spec.format.type);\r\n prefix += signFormatting.prefix;\r\n suffix = signFormatting.suffix + suffix;\r\n\r\n // add Sign prefix and suffix as necessary\r\n if ((prefix.length > 0 || suffix.length > 0) && formattedMagnitude.length > 0)\r\n formattedValue = prefix + formattedMagnitude + suffix;\r\n else\r\n formattedValue = formattedMagnitude;\r\n\r\n return formattedValue;\r\n }\r\n\r\n private static processBearingAndAzimuth(magnitude: number, spec: FormatterSpec): {magnitude: number, prefix?: string, suffix?: string} {\r\n const type = spec.format.type;\r\n if (type !== FormatType.Bearing && type !== FormatType.Azimuth)\r\n return {magnitude};\r\n\r\n const revolution = this.getRevolution(spec);\r\n magnitude = this.normalizeAngle(magnitude, revolution);\r\n const quarterRevolution = revolution / 4;\r\n\r\n if (type === FormatType.Bearing) {\r\n let quadrant = 0;\r\n while (magnitude > quarterRevolution) {\r\n magnitude -= quarterRevolution;\r\n quadrant++;\r\n }\r\n let prefix: string = \"\";\r\n let suffix: string = \"\";\r\n\r\n // Quadrants are\r\n // 3 0\r\n // 2 1\r\n // For quadrants 1 and 3 we have to subtract the angle from quarterRevolution degrees because they go counter-clockwise\r\n if (quadrant === 1 || quadrant === 3)\r\n magnitude = quarterRevolution - magnitude;\r\n\r\n // TODO: at some point we will want to open this for localization, in the first release it's going to be hard coded\r\n if (quadrant === 0 || quadrant === 3)\r\n prefix = \"N\";\r\n\r\n if (quadrant === 2 || quadrant === 1)\r\n prefix = \"S\";\r\n\r\n if (quadrant === 0 || quadrant === 1)\r\n suffix = \"E\";\r\n\r\n if (quadrant === 3 || quadrant === 2)\r\n suffix = \"W\";\r\n\r\n // special case, if in quadrant 2 and value is very close to quarter revolution (90°), turn prefix to N because N90:00:00W is preferred over S90:00:00W\r\n if (quadrant === 2 && spec.unitConversions.length > 0) {\r\n // To determine if value is small, we need to convert it to the smallest unit presented and use the provided precision on it\r\n const unitConversion = spec.unitConversions[spec.unitConversions.length - 1].conversion;\r\n const smallestFormattedDelta = applyConversion((quarterRevolution - magnitude), unitConversion) + this.FPV_MINTHRESHOLD;\r\n\r\n const precisionScale = Math.pow(10.0, spec.format.precision);\r\n const floor = Math.floor((smallestFormattedDelta) * precisionScale + FPV_ROUNDFACTOR) / precisionScale;\r\n if(floor === 0) {\r\n prefix = \"N\";\r\n }\r\n }\r\n\r\n return {magnitude, prefix, suffix};\r\n }\r\n\r\n if (type === FormatType.Azimuth) {\r\n let azimuthBase = 0; // default base is North\r\n if (spec.format.azimuthBase !== undefined) {\r\n if (spec.azimuthBaseConversion === undefined) {\r\n throw new QuantityError(QuantityStatus.MissingRequiredProperty, `Missing azimuth base conversion for interpreting ${spec.name}'s azimuth base.`);\r\n }\r\n const azBaseQuantity: Quantity = new Quantity(spec.format.azimuthBaseUnit, spec.format.azimuthBase);\r\n const azBaseConverted = azBaseQuantity.convertTo(spec.persistenceUnit, spec.azimuthBaseConversion);\r\n if (!azBaseConverted.isValid) {\r\n throw new QuantityError(QuantityStatus.UnsupportedUnit, `Failed to convert azimuth base unit to ${spec.persistenceUnit.name}.`);\r\n }\r\n azimuthBase = this.normalizeAngle(azBaseConverted.magnitude, revolution);\r\n }\r\n\r\n if (azimuthBase === 0.0 && spec.format.azimuthClockwiseOrDefault)\r\n return {magnitude}; // no conversion necessary, the input is already using the result parameters (north base and clockwise)\r\n\r\n // subtract the base from the actual value\r\n magnitude -= azimuthBase;\r\n if (spec.format.azimuthClockwiseOrDefault)\r\n return {magnitude: this.normalizeAngle(magnitude, revolution)};\r\n\r\n // turn it into a counter-clockwise angle\r\n magnitude = revolution - magnitude;\r\n // normalize the result as it may have become negative or exceed the revolution\r\n magnitude = this.normalizeAngle(magnitude, revolution);\r\n }\r\n\r\n return {magnitude};\r\n }\r\n\r\n private static normalizeAngle(magnitude: number, revolution: number): number {\r\n magnitude = magnitude % revolution; // Strip anything that goes around more than once\r\n\r\n if (magnitude < 0) // If the value is negative, we want to normalize it to a positive angle\r\n magnitude += revolution;\r\n\r\n return magnitude;\r\n }\r\n\r\n private static getRevolution(spec: FormatterSpec): number {\r\n if (spec.revolutionConversion === undefined) {\r\n throw new QuantityError(QuantityStatus.MissingRequiredProperty, `Missing revolution unit conversion for calculating ${spec.name}'s revolution.`);\r\n }\r\n\r\n const revolution: Quantity = new Quantity(spec.format.revolutionUnit, 1.0);\r\n const converted = revolution.convertTo(spec.persistenceUnit, spec.revolutionConversion);\r\n if (!converted.isValid) {\r\n throw new QuantityError(QuantityStatus.UnsupportedUnit, `Failed to convert revolution unit to ${spec.persistenceUnit.name}.`);\r\n }\r\n\r\n return converted.magnitude;\r\n }\r\n\r\n private static formatRatioPart(value: number, spec: FormatterSpec, side: \"numerator\" | \"denominator\"): string {\r\n const formatType = spec.format.ratioFormatType === \"Fractional\" ? FormatType.Fractional : FormatType.Decimal;\r\n const tempFormat = spec.format.clone({ type: formatType });\r\n const tempSpec = new FormatterSpec(spec.name, tempFormat, spec.unitConversions, spec.persistenceUnit);\r\n let formattedValue = this.formatMagnitude(value, tempSpec);\r\n\r\n // For fractional ratio formatting, suppress leading \"0\" if the value is purely fractional\r\n if (formatType === FormatType.Fractional && formattedValue.startsWith(\"0 \")) {\r\n formattedValue = formattedValue.substring(2); // Remove \"0 \" prefix\r\n }\r\n\r\n // Add unit label if ShowUnitLabel trait is set\r\n // unitConversions[0] = ratio scale factor, [1] = numerator unit, [2] = denominator unit\r\n if (spec.format.hasFormatTraitSet(FormatTraits.ShowUnitLabel) && spec.unitConversions.length >= 3) {\r\n const labelToAdd = side === \"numerator\" ? spec.unitConversions[1].label : spec.unitConversions[2].label;\r\n formattedValue = formattedValue + labelToAdd;\r\n }\r\n\r\n return formattedValue;\r\n }\r\n\r\n /** Format a ratio quantity value (separate from composite formatting) */\r\n private static formatRatioQuantity(magnitude: number, spec: FormatterSpec): { componentText: string, isNegative: boolean } {\r\n const unitConversion = spec.unitConversions[0].conversion;\r\n let unitValue = 0.0;\r\n\r\n try {\r\n unitValue = applyConversion(magnitude, unitConversion) + this.FPV_MINTHRESHOLD;\r\n } catch (e) {\r\n // The \"InvertingZero\" error is thrown when the value is zero and the conversion factor is inverted.\r\n // For ratio, we return \"1:0\" as the formatted value.\r\n if (e instanceof QuantityError && e.errorNumber === QuantityStatus.InvertingZero) {\r\n return { componentText: \"1:0\", isNegative: false };\r\n }\r\n throw e;\r\n }\r\n\r\n const componentText = this.formatRatio(unitValue, spec);\r\n const isNegative = unitValue < 0;\r\n return { componentText, isNegative };\r\n }\r\n\r\n private static formatRatio(magnitude: number, spec: FormatterSpec): string {\r\n if (null === spec.format.ratioType)\r\n throw new QuantityError(QuantityStatus.InvalidCompositeFormat, `The Format ${spec.format.name} must have a ratio type specified.`);\r\n\r\n const precisionScale = Math.pow(10.0, spec.format.precision);\r\n const separator = spec.format.ratioSeparator;\r\n let reciprocal = 0;\r\n\r\n // Helper to get unit labels if ShowUnitLabel is set\r\n const getUnitLabels = (): { numeratorLabel: string, denominatorLabel: string } => {\r\n if (spec.format.hasFormatTraitSet(FormatTraits.ShowUnitLabel) && spec.unitConversions.length >= 3) {\r\n return { numeratorLabel: spec.unitConversions[1].label, denominatorLabel: spec.unitConversions[2].label };\r\n }\r\n return { numeratorLabel: \"\", denominatorLabel: \"\" };\r\n };\r\n\r\n const { numeratorLabel, denominatorLabel } = getUnitLabels();\r\n\r\n if (magnitude === 0.0)\r\n return `0${separator}1`;\r\n else\r\n reciprocal = 1.0/magnitude;\r\n switch (spec.format.ratioType) {\r\n case RatioType.OneToN:\r\n return `1${numeratorLabel}${separator}${this.formatRatioPart(reciprocal, spec, \"denominator\")}`;\r\n case RatioType.NToOne:\r\n return `${this.formatRatioPart(magnitude, spec, \"numerator\")}${separator}1${denominatorLabel}`;\r\n case RatioType.ValueBased:\r\n if (magnitude > 1.0) {\r\n return `${this.formatRatioPart(magnitude, spec, \"numerator\")}${separator}1${denominatorLabel}`;\r\n } else {\r\n return `1${numeratorLabel}${separator}${this.formatRatioPart(reciprocal, spec, \"denominator\")}`;\r\n }\r\n case RatioType.UseGreatestCommonDivisor:\r\n magnitude = Math.round(magnitude * precisionScale)/precisionScale;\r\n let numerator = magnitude * precisionScale;\r\n let denominator = precisionScale;\r\n\r\n const gcd = FractionalNumeric.getGreatestCommonFactor(numerator, denominator);\r\n numerator /= gcd;\r\n denominator /= gcd;\r\n\r\n return `${this.formatRatioPart(numerator, spec, \"numerator\")}${separator}${this.formatRatioPart(denominator, spec, \"denominator\")}`;\r\n default:\r\n throw new QuantityError(QuantityStatus.InvalidCompositeFormat, `The Format ${spec.format.name} has an invalid ratio type specified.`);\r\n }\r\n }\r\n}\r\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"FormatterSpec.d.ts","sourceRoot":"","sources":["../../../src/Formatter/FormatterSpec.ts"],"names":[],"mappings":"AAIA;;GAEG;AAEH,OAAO,EAAE,mBAAmB,EAAE,kBAAkB,EAAE,SAAS,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAClG,OAAO,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAOlC;;;GAGG;AACH,qBAAa,aAAa;IACxB,SAAS,CAAC,KAAK,EAAE,MAAM,CAAC;IACxB,SAAS,CAAC,YAAY,EAAE,kBAAkB,EAAE,CAAM;IAClD,SAAS,CAAC,OAAO,EAAE,MAAM,CAAC;IAC1B,SAAS,CAAC,gBAAgB,EAAE,SAAS,CAAC;IACtC,SAAS,CAAC,sBAAsB,CAAC,EAAE,mBAAmB,CAAC;IACvD,SAAS,CAAC,qBAAqB,CAAC,EAAE,mBAAmB,CAAC;IAEtD;;;;;;;OAOG;gBACS,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,WAAW,CAAC,EAAE,kBAAkB,EAAE,EAAE,eAAe,CAAC,EAAE,SAAS,EAAE,qBAAqB,CAAC,EAAE,mBAAmB,EAAE,oBAAoB,CAAC,EAAE,mBAAmB;IAmBlM,IAAW,IAAI,IAAI,MAAM,CAAuB;IAChD,uHAAuH;IACvH,IAAW,eAAe,IAAI,kBAAkB,EAAE,CAA8B;IAChF,IAAW,MAAM,IAAI,MAAM,CAAyB;IACpD,IAAW,eAAe,IAAI,SAAS,CAAkC;IACzE,IAAW,qBAAqB,IAAI,mBAAmB,GAAG,SAAS,CAAwC;IAC3G,IAAW,oBAAoB,IAAI,mBAAmB,GAAG,SAAS,CAAuC;IAEzG,8FAA8F;mBACzE,uBAAuB;IAkD5C,mHAAmH;WAC/F,kBAAkB,CAAC,MAAM,EAAE,MAAM,EAAE,aAAa,EAAE,aAAa,EAAE,SAAS,CAAC,EAAE,SAAS,GAAG,OAAO,CAAC,kBAAkB,EAAE,CAAC;IA2C1I;;;;;;OAMG;WACiB,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,aAAa,EAAE,aAAa,EAAE,SAAS,CAAC,EAAE,SAAS,GAAG,OAAO,CAAC,aAAa,CAAC;IAsBrI,+BAA+B;IACxB,eAAe,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM;CAGlD"}
1
+ {"version":3,"file":"FormatterSpec.d.ts","sourceRoot":"","sources":["../../../src/Formatter/FormatterSpec.ts"],"names":[],"mappings":"AAIA;;GAEG;AAGH,OAAO,EAAE,mBAAmB,EAAE,kBAAkB,EAAE,SAAS,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAElG,OAAO,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAOlC;;;GAGG;AACH,qBAAa,aAAa;IACxB,SAAS,CAAC,KAAK,EAAE,MAAM,CAAC;IACxB,SAAS,CAAC,YAAY,EAAE,kBAAkB,EAAE,CAAM;IAClD,SAAS,CAAC,OAAO,EAAE,MAAM,CAAC;IAC1B,SAAS,CAAC,gBAAgB,EAAE,SAAS,CAAC;IACtC,SAAS,CAAC,sBAAsB,CAAC,EAAE,mBAAmB,CAAC;IACvD,SAAS,CAAC,qBAAqB,CAAC,EAAE,mBAAmB,CAAC;IAEtD;;;;;;;OAOG;gBACS,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,WAAW,CAAC,EAAE,kBAAkB,EAAE,EAAE,eAAe,CAAC,EAAE,SAAS,EAAE,qBAAqB,CAAC,EAAE,mBAAmB,EAAE,oBAAoB,CAAC,EAAE,mBAAmB;IAmBlM,IAAW,IAAI,IAAI,MAAM,CAAuB;IAChD,uHAAuH;IACvH,IAAW,eAAe,IAAI,kBAAkB,EAAE,CAA8B;IAChF,IAAW,MAAM,IAAI,MAAM,CAAyB;IACpD,IAAW,eAAe,IAAI,SAAS,CAAkC;IACzE,IAAW,qBAAqB,IAAI,mBAAmB,GAAG,SAAS,CAAwC;IAC3G,IAAW,oBAAoB,IAAI,mBAAmB,GAAG,SAAS,CAAuC;IAEzG,8FAA8F;mBACzE,uBAAuB;IAqD5C,mHAAmH;WAC/F,kBAAkB,CAAC,MAAM,EAAE,MAAM,EAAE,aAAa,EAAE,aAAa,EAAE,SAAS,CAAC,EAAE,SAAS,GAAG,OAAO,CAAC,kBAAkB,EAAE,CAAC;IA8C1I;;;;;;OAMG;WACiB,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,aAAa,EAAE,aAAa,EAAE,SAAS,CAAC,EAAE,SAAS,GAAG,OAAO,CAAC,aAAa,CAAC;IA4BrI,+BAA+B;IACxB,eAAe,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM;CAGlD"}
@@ -8,6 +8,8 @@
8
8
  */
9
9
  Object.defineProperty(exports, "__esModule", { value: true });
10
10
  exports.FormatterSpec = void 0;
11
+ const core_bentley_1 = require("@itwin/core-bentley");
12
+ const QuantityLoggerCategory_1 = require("../QuantityLoggerCategory");
11
13
  const FormatEnums_1 = require("./FormatEnums");
12
14
  const Formatter_1 = require("./Formatter");
13
15
  // cSpell:ignore ZERONORMALIZED, nosign, onlynegative, signalways, negativeparentheses
@@ -63,6 +65,9 @@ class FormatterSpec {
63
65
  const [denominatorUnit, denominatorLabel] = units[1];
64
66
  // Compute ratio scale: how many numerator units per denominator unit (e.g., IN:FT = 12)
65
67
  const denominatorToNumerator = await unitsProvider.getConversion(denominatorUnit, numeratorUnit);
68
+ if (denominatorToNumerator.error) {
69
+ core_bentley_1.Logger.logWarning(QuantityLoggerCategory_1.QuantityLoggerCategory.Formatting, `Unit conversion from "${denominatorUnit.name}" to "${numeratorUnit.name}" could not be resolved.`);
70
+ }
66
71
  const displayRatioScale = denominatorToNumerator.factor;
67
72
  // Avoid double-scaling: if persistence unit already encodes the display ratio, use factor 1.
68
73
  // Check by name heuristic (e.g., IN_PER_FT with ratioUnits [IN, FT] → no scaling needed)
@@ -122,6 +127,9 @@ class FormatterSpec {
122
127
  let unitConversion;
123
128
  if (convertFromUnit) {
124
129
  unitConversion = await unitsProvider.getConversion(convertFromUnit, unit[0]);
130
+ if (unitConversion.error) {
131
+ core_bentley_1.Logger.logWarning(QuantityLoggerCategory_1.QuantityLoggerCategory.Formatting, `Unit conversion from "${convertFromUnit.name}" to "${unit[0].name}" could not be resolved.`);
132
+ }
125
133
  }
126
134
  else {
127
135
  unitConversion = { factor: 1.0, offset: 0.0 };
@@ -154,6 +162,9 @@ class FormatterSpec {
154
162
  if (format.azimuthBaseUnit !== undefined) {
155
163
  if (inputUnit !== undefined) {
156
164
  azimuthBaseConversion = await unitsProvider.getConversion(format.azimuthBaseUnit, inputUnit);
165
+ if (azimuthBaseConversion.error) {
166
+ core_bentley_1.Logger.logWarning(QuantityLoggerCategory_1.QuantityLoggerCategory.Formatting, `Unit conversion from "${format.azimuthBaseUnit.name}" to "${inputUnit.name}" could not be resolved.`);
167
+ }
157
168
  }
158
169
  else {
159
170
  azimuthBaseConversion = { factor: 1.0, offset: 0.0 };
@@ -163,6 +174,9 @@ class FormatterSpec {
163
174
  if (format.revolutionUnit !== undefined) {
164
175
  if (inputUnit !== undefined) {
165
176
  revolutionConversion = await unitsProvider.getConversion(format.revolutionUnit, inputUnit);
177
+ if (revolutionConversion.error) {
178
+ core_bentley_1.Logger.logWarning(QuantityLoggerCategory_1.QuantityLoggerCategory.Formatting, `Unit conversion from "${format.revolutionUnit.name}" to "${inputUnit.name}" could not be resolved.`);
179
+ }
166
180
  }
167
181
  else {
168
182
  revolutionConversion = { factor: 1.0, offset: 0.0 };
@@ -1 +1 @@
1
- {"version":3,"file":"FormatterSpec.js","sourceRoot":"","sources":["../../../src/Formatter/FormatterSpec.ts"],"names":[],"mappings":"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","sourcesContent":["/*---------------------------------------------------------------------------------------------\n* Copyright (c) Bentley Systems, Incorporated. All rights reserved.\n* See LICENSE.md in the project root for license terms and full copyright notice.\n*--------------------------------------------------------------------------------------------*/\n/** @packageDocumentation\n * @module Quantity\n */\n\nimport { UnitConversionProps, UnitConversionSpec, UnitProps, UnitsProvider } from \"../Interfaces\";\nimport { Format } from \"./Format\";\nimport { FormatType } from \"./FormatEnums\";\nimport { Formatter } from \"./Formatter\";\n\n// cSpell:ignore ZERONORMALIZED, nosign, onlynegative, signalways, negativeparentheses\n// cSpell:ignore trailzeroes, keepsinglezero, zeroempty, keepdecimalpoint, applyrounding, fractiondash, showunitlabel, prependunitlabel, exponentonlynegative\n\n/** A class that contains both formatting information and the conversion factors necessary to convert from an input unit to the units specified in the format.\n * Once created the FormatterSpec will be able to format quantity values with synchronous calls.\n * @beta\n */\nexport class FormatterSpec {\n protected _name: string;\n protected _conversions: UnitConversionSpec[] = []; // max four entries\n protected _format: Format;\n protected _persistenceUnit: UnitProps;\n protected _azimuthBaseConversion?: UnitConversionProps; // converts azimuth base unit to persistence unit\n protected _revolutionConversion?: UnitConversionProps; // converts revolution unit to persistence unit\n\n /** Constructor\n * @param name The name of a format specification.\n * @param format Defines the output format for the quantity value.\n * @param conversions An array of conversion factors necessary to convert from an input unit to the units specified in the format.\n * @param persistenceUnit The unit the magnitude value is input.\n * @param azimuthBaseConversion The conversion used to interpret azimuth base values.\n * @param revolutionConversion The conversion used to determine a revolution value (used for bearing and azimuth).\n */\n constructor(name: string, format: Format, conversions?: UnitConversionSpec[], persistenceUnit?: UnitProps, azimuthBaseConversion?: UnitConversionProps, revolutionConversion?: UnitConversionProps) {\n if (!persistenceUnit) {\n if (format.units) {\n const [props] = format.units[0];\n persistenceUnit = props;\n } else {\n throw new Error(\"Formatter Spec needs persistence unit to be specified\");\n }\n }\n\n this._name = name;\n this._format = format;\n this._persistenceUnit = persistenceUnit;\n if (conversions)\n this._conversions = conversions;\n this._azimuthBaseConversion = azimuthBaseConversion;\n this._revolutionConversion = revolutionConversion;\n }\n\n public get name(): string { return this._name; }\n /** Returns an array of UnitConversionSpecs, one for each unit that is to be shown in the formatted quantity string. */\n public get unitConversions(): UnitConversionSpec[] { return this._conversions; }\n public get format(): Format { return this._format; }\n public get persistenceUnit(): UnitProps { return this._persistenceUnit; }\n public get azimuthBaseConversion(): UnitConversionProps | undefined { return this._azimuthBaseConversion; }\n public get revolutionConversion(): UnitConversionProps | undefined { return this._revolutionConversion; }\n\n /** Build conversion specs for ratio format with 2 composite units (numerator/denominator). */\n private static async getRatioUnitConversions(units: ReadonlyArray<[UnitProps, string | undefined]>, unitsProvider: UnitsProvider, persistenceUnit: UnitProps): Promise<UnitConversionSpec[]> {\n const conversions: UnitConversionSpec[] = [];\n\n const [numeratorUnit, numeratorLabel] = units[0];\n const [denominatorUnit, denominatorLabel] = units[1];\n\n // Compute ratio scale: how many numerator units per denominator unit (e.g., IN:FT = 12)\n const denominatorToNumerator = await unitsProvider.getConversion(denominatorUnit, numeratorUnit);\n const displayRatioScale = denominatorToNumerator.factor;\n\n // Avoid double-scaling: if persistence unit already encodes the display ratio, use factor 1.\n // Check by name heuristic (e.g., IN_PER_FT with ratioUnits [IN, FT] → no scaling needed)\n const persistenceName = persistenceUnit.name.toUpperCase();\n const numName = numeratorUnit.name.toUpperCase().split(\".\").pop() ?? \"\";\n const denName = denominatorUnit.name.toUpperCase().split(\".\").pop() ?? \"\";\n // Split by word boundaries (underscores, dots) and check for exact token matches\n const persistenceTokens = persistenceName.split(/[._]/);\n const isPersistenceMatchingRatio = persistenceTokens.includes(numName) && persistenceTokens.includes(denName);\n const ratioScaleFactor = isPersistenceMatchingRatio ? 1.0 : displayRatioScale;\n\n // First conversion spec: effective ratio unit conversion\n const ratioConversionSpec: UnitConversionSpec = {\n name: `${numeratorUnit.name}_per_${denominatorUnit.name}`,\n label: \"\",\n system: numeratorUnit.system,\n conversion: { factor: ratioScaleFactor, offset: 0.0 },\n };\n conversions.push(ratioConversionSpec);\n\n // Numerator unit for label lookup\n const numeratorSpec: UnitConversionSpec = {\n name: numeratorUnit.name,\n label: numeratorLabel?.length ? numeratorLabel : numeratorUnit.label,\n system: numeratorUnit.system,\n conversion: { factor: 1.0, offset: 0.0 },\n };\n conversions.push(numeratorSpec);\n\n // Denominator unit for label lookup\n const denominatorSpec: UnitConversionSpec = {\n name: denominatorUnit.name,\n label: denominatorLabel?.length ? denominatorLabel : denominatorUnit.label,\n system: denominatorUnit.system,\n conversion: { factor: 1.0, offset: 0.0 },\n };\n conversions.push(denominatorSpec);\n\n return conversions;\n }\n\n /** Get an array of UnitConversionSpecs, one for each unit that is to be shown in the formatted quantity string. */\n public static async getUnitConversions(format: Format, unitsProvider: UnitsProvider, inputUnit?: UnitProps): Promise<UnitConversionSpec[]> {\n const conversions: UnitConversionSpec[] = [];\n let persistenceUnit = inputUnit;\n if (!persistenceUnit) {\n if (format.units) {\n const [props] = format.units[0];\n persistenceUnit = props;\n } else {\n throw new Error(\"Formatter Spec needs persistence unit to be specified\");\n }\n }\n\n // Handle 2-unit composite for ratio formats (scale factors)\n if (format.type === FormatType.Ratio && format.units && format.units.length === 2) {\n return FormatterSpec.getRatioUnitConversions(format.units, unitsProvider, persistenceUnit);\n }\n\n if (format.units) {\n let convertFromUnit = inputUnit;\n for (const unit of format.units) {\n let unitConversion: UnitConversionProps;\n if (convertFromUnit) {\n unitConversion = await unitsProvider.getConversion(convertFromUnit, unit[0]);\n } else {\n unitConversion = { factor: 1.0, offset: 0.0 };\n }\n const unitLabel = (unit[1] && unit[1].length > 0) ? unit[1] : unit[0].label;\n const spec = ({ name: unit[0].name, label: unitLabel, conversion: unitConversion, system: unit[0].system }) as UnitConversionSpec;\n\n conversions.push(spec);\n convertFromUnit = unit[0];\n }\n } else {\n // if format is only numeric and a input unit is defined set spec to use the input unit as the format unit\n if (inputUnit) {\n const spec: UnitConversionSpec = { name: inputUnit.name, label: inputUnit.label, system: inputUnit.system, conversion: { factor: 1.0, offset: 0.0 } };\n conversions.push(spec);\n }\n }\n\n return conversions;\n }\n\n /** Static async method to create a FormatSpec given the format and unit of the quantity that will be passed to the Formatter. The input unit will\n * be used to generate conversion information for each unit specified in the Format. This method is async due to the fact that the units provider must make\n * async calls to lookup unit definitions.\n * @param name The name of a format specification.\n * @param unitsProvider The units provider is used to look up unit definitions and provide conversion information for converting between units.\n * @param inputUnit The unit the value to be formatted. This unit is often referred to as persistence unit.\n */\n public static async create(name: string, format: Format, unitsProvider: UnitsProvider, inputUnit?: UnitProps): Promise<FormatterSpec> {\n const conversions: UnitConversionSpec[] = await FormatterSpec.getUnitConversions(format, unitsProvider, inputUnit);\n let azimuthBaseConversion: UnitConversionProps | undefined;\n if (format.azimuthBaseUnit !== undefined) {\n if (inputUnit !== undefined) {\n azimuthBaseConversion = await unitsProvider.getConversion(format.azimuthBaseUnit, inputUnit);\n } else {\n azimuthBaseConversion = { factor: 1.0, offset: 0.0 };\n }\n }\n let revolutionConversion: UnitConversionProps | undefined;\n if (format.revolutionUnit !== undefined) {\n if (inputUnit !== undefined) {\n revolutionConversion = await unitsProvider.getConversion(format.revolutionUnit, inputUnit);\n } else {\n revolutionConversion = { factor: 1.0, offset: 0.0 };\n }\n }\n\n return new FormatterSpec(name, format, conversions, inputUnit, azimuthBaseConversion, revolutionConversion);\n }\n\n /** Format a quantity value. */\n public applyFormatting(magnitude: number): string {\n return Formatter.formatQuantity(magnitude, this);\n }\n}\n"]}
1
+ {"version":3,"file":"FormatterSpec.js","sourceRoot":"","sources":["../../../src/Formatter/FormatterSpec.ts"],"names":[],"mappings":"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","sourcesContent":["/*---------------------------------------------------------------------------------------------\r\n* Copyright (c) Bentley Systems, Incorporated. All rights reserved.\r\n* See LICENSE.md in the project root for license terms and full copyright notice.\r\n*--------------------------------------------------------------------------------------------*/\r\n/** @packageDocumentation\r\n * @module Quantity\r\n */\r\n\r\nimport { Logger } from \"@itwin/core-bentley\";\r\nimport { UnitConversionProps, UnitConversionSpec, UnitProps, UnitsProvider } from \"../Interfaces\";\r\nimport { QuantityLoggerCategory } from \"../QuantityLoggerCategory\";\r\nimport { Format } from \"./Format\";\r\nimport { FormatType } from \"./FormatEnums\";\r\nimport { Formatter } from \"./Formatter\";\r\n\r\n// cSpell:ignore ZERONORMALIZED, nosign, onlynegative, signalways, negativeparentheses\r\n// cSpell:ignore trailzeroes, keepsinglezero, zeroempty, keepdecimalpoint, applyrounding, fractiondash, showunitlabel, prependunitlabel, exponentonlynegative\r\n\r\n/** A class that contains both formatting information and the conversion factors necessary to convert from an input unit to the units specified in the format.\r\n * Once created the FormatterSpec will be able to format quantity values with synchronous calls.\r\n * @beta\r\n */\r\nexport class FormatterSpec {\r\n protected _name: string;\r\n protected _conversions: UnitConversionSpec[] = []; // max four entries\r\n protected _format: Format;\r\n protected _persistenceUnit: UnitProps;\r\n protected _azimuthBaseConversion?: UnitConversionProps; // converts azimuth base unit to persistence unit\r\n protected _revolutionConversion?: UnitConversionProps; // converts revolution unit to persistence unit\r\n\r\n /** Constructor\r\n * @param name The name of a format specification.\r\n * @param format Defines the output format for the quantity value.\r\n * @param conversions An array of conversion factors necessary to convert from an input unit to the units specified in the format.\r\n * @param persistenceUnit The unit the magnitude value is input.\r\n * @param azimuthBaseConversion The conversion used to interpret azimuth base values.\r\n * @param revolutionConversion The conversion used to determine a revolution value (used for bearing and azimuth).\r\n */\r\n constructor(name: string, format: Format, conversions?: UnitConversionSpec[], persistenceUnit?: UnitProps, azimuthBaseConversion?: UnitConversionProps, revolutionConversion?: UnitConversionProps) {\r\n if (!persistenceUnit) {\r\n if (format.units) {\r\n const [props] = format.units[0];\r\n persistenceUnit = props;\r\n } else {\r\n throw new Error(\"Formatter Spec needs persistence unit to be specified\");\r\n }\r\n }\r\n\r\n this._name = name;\r\n this._format = format;\r\n this._persistenceUnit = persistenceUnit;\r\n if (conversions)\r\n this._conversions = conversions;\r\n this._azimuthBaseConversion = azimuthBaseConversion;\r\n this._revolutionConversion = revolutionConversion;\r\n }\r\n\r\n public get name(): string { return this._name; }\r\n /** Returns an array of UnitConversionSpecs, one for each unit that is to be shown in the formatted quantity string. */\r\n public get unitConversions(): UnitConversionSpec[] { return this._conversions; }\r\n public get format(): Format { return this._format; }\r\n public get persistenceUnit(): UnitProps { return this._persistenceUnit; }\r\n public get azimuthBaseConversion(): UnitConversionProps | undefined { return this._azimuthBaseConversion; }\r\n public get revolutionConversion(): UnitConversionProps | undefined { return this._revolutionConversion; }\r\n\r\n /** Build conversion specs for ratio format with 2 composite units (numerator/denominator). */\r\n private static async getRatioUnitConversions(units: ReadonlyArray<[UnitProps, string | undefined]>, unitsProvider: UnitsProvider, persistenceUnit: UnitProps): Promise<UnitConversionSpec[]> {\r\n const conversions: UnitConversionSpec[] = [];\r\n\r\n const [numeratorUnit, numeratorLabel] = units[0];\r\n const [denominatorUnit, denominatorLabel] = units[1];\r\n\r\n // Compute ratio scale: how many numerator units per denominator unit (e.g., IN:FT = 12)\r\n const denominatorToNumerator = await unitsProvider.getConversion(denominatorUnit, numeratorUnit);\r\n if (denominatorToNumerator.error) {\r\n Logger.logWarning(QuantityLoggerCategory.Formatting, `Unit conversion from \"${denominatorUnit.name}\" to \"${numeratorUnit.name}\" could not be resolved.`);\r\n }\r\n const displayRatioScale = denominatorToNumerator.factor;\r\n\r\n // Avoid double-scaling: if persistence unit already encodes the display ratio, use factor 1.\r\n // Check by name heuristic (e.g., IN_PER_FT with ratioUnits [IN, FT] → no scaling needed)\r\n const persistenceName = persistenceUnit.name.toUpperCase();\r\n const numName = numeratorUnit.name.toUpperCase().split(\".\").pop() ?? \"\";\r\n const denName = denominatorUnit.name.toUpperCase().split(\".\").pop() ?? \"\";\r\n // Split by word boundaries (underscores, dots) and check for exact token matches\r\n const persistenceTokens = persistenceName.split(/[._]/);\r\n const isPersistenceMatchingRatio = persistenceTokens.includes(numName) && persistenceTokens.includes(denName);\r\n const ratioScaleFactor = isPersistenceMatchingRatio ? 1.0 : displayRatioScale;\r\n\r\n // First conversion spec: effective ratio unit conversion\r\n const ratioConversionSpec: UnitConversionSpec = {\r\n name: `${numeratorUnit.name}_per_${denominatorUnit.name}`,\r\n label: \"\",\r\n system: numeratorUnit.system,\r\n conversion: { factor: ratioScaleFactor, offset: 0.0 },\r\n };\r\n conversions.push(ratioConversionSpec);\r\n\r\n // Numerator unit for label lookup\r\n const numeratorSpec: UnitConversionSpec = {\r\n name: numeratorUnit.name,\r\n label: numeratorLabel?.length ? numeratorLabel : numeratorUnit.label,\r\n system: numeratorUnit.system,\r\n conversion: { factor: 1.0, offset: 0.0 },\r\n };\r\n conversions.push(numeratorSpec);\r\n\r\n // Denominator unit for label lookup\r\n const denominatorSpec: UnitConversionSpec = {\r\n name: denominatorUnit.name,\r\n label: denominatorLabel?.length ? denominatorLabel : denominatorUnit.label,\r\n system: denominatorUnit.system,\r\n conversion: { factor: 1.0, offset: 0.0 },\r\n };\r\n conversions.push(denominatorSpec);\r\n\r\n return conversions;\r\n }\r\n\r\n /** Get an array of UnitConversionSpecs, one for each unit that is to be shown in the formatted quantity string. */\r\n public static async getUnitConversions(format: Format, unitsProvider: UnitsProvider, inputUnit?: UnitProps): Promise<UnitConversionSpec[]> {\r\n const conversions: UnitConversionSpec[] = [];\r\n let persistenceUnit = inputUnit;\r\n if (!persistenceUnit) {\r\n if (format.units) {\r\n const [props] = format.units[0];\r\n persistenceUnit = props;\r\n } else {\r\n throw new Error(\"Formatter Spec needs persistence unit to be specified\");\r\n }\r\n }\r\n\r\n // Handle 2-unit composite for ratio formats (scale factors)\r\n if (format.type === FormatType.Ratio && format.units && format.units.length === 2) {\r\n return FormatterSpec.getRatioUnitConversions(format.units, unitsProvider, persistenceUnit);\r\n }\r\n\r\n if (format.units) {\r\n let convertFromUnit = inputUnit;\r\n for (const unit of format.units) {\r\n let unitConversion: UnitConversionProps;\r\n if (convertFromUnit) {\r\n unitConversion = await unitsProvider.getConversion(convertFromUnit, unit[0]);\r\n if (unitConversion.error) {\r\n Logger.logWarning(QuantityLoggerCategory.Formatting, `Unit conversion from \"${convertFromUnit.name}\" to \"${unit[0].name}\" could not be resolved.`);\r\n }\r\n } else {\r\n unitConversion = { factor: 1.0, offset: 0.0 };\r\n }\r\n const unitLabel = (unit[1] && unit[1].length > 0) ? unit[1] : unit[0].label;\r\n const spec = ({ name: unit[0].name, label: unitLabel, conversion: unitConversion, system: unit[0].system }) as UnitConversionSpec;\r\n\r\n conversions.push(spec);\r\n convertFromUnit = unit[0];\r\n }\r\n } else {\r\n // if format is only numeric and a input unit is defined set spec to use the input unit as the format unit\r\n if (inputUnit) {\r\n const spec: UnitConversionSpec = { name: inputUnit.name, label: inputUnit.label, system: inputUnit.system, conversion: { factor: 1.0, offset: 0.0 } };\r\n conversions.push(spec);\r\n }\r\n }\r\n\r\n return conversions;\r\n }\r\n\r\n /** Static async method to create a FormatSpec given the format and unit of the quantity that will be passed to the Formatter. The input unit will\r\n * be used to generate conversion information for each unit specified in the Format. This method is async due to the fact that the units provider must make\r\n * async calls to lookup unit definitions.\r\n * @param name The name of a format specification.\r\n * @param unitsProvider The units provider is used to look up unit definitions and provide conversion information for converting between units.\r\n * @param inputUnit The unit the value to be formatted. This unit is often referred to as persistence unit.\r\n */\r\n public static async create(name: string, format: Format, unitsProvider: UnitsProvider, inputUnit?: UnitProps): Promise<FormatterSpec> {\r\n const conversions: UnitConversionSpec[] = await FormatterSpec.getUnitConversions(format, unitsProvider, inputUnit);\r\n let azimuthBaseConversion: UnitConversionProps | undefined;\r\n if (format.azimuthBaseUnit !== undefined) {\r\n if (inputUnit !== undefined) {\r\n azimuthBaseConversion = await unitsProvider.getConversion(format.azimuthBaseUnit, inputUnit);\r\n if (azimuthBaseConversion.error) {\r\n Logger.logWarning(QuantityLoggerCategory.Formatting, `Unit conversion from \"${format.azimuthBaseUnit.name}\" to \"${inputUnit.name}\" could not be resolved.`);\r\n }\r\n } else {\r\n azimuthBaseConversion = { factor: 1.0, offset: 0.0 };\r\n }\r\n }\r\n let revolutionConversion: UnitConversionProps | undefined;\r\n if (format.revolutionUnit !== undefined) {\r\n if (inputUnit !== undefined) {\r\n revolutionConversion = await unitsProvider.getConversion(format.revolutionUnit, inputUnit);\r\n if (revolutionConversion.error) {\r\n Logger.logWarning(QuantityLoggerCategory.Formatting, `Unit conversion from \"${format.revolutionUnit.name}\" to \"${inputUnit.name}\" could not be resolved.`);\r\n }\r\n } else {\r\n revolutionConversion = { factor: 1.0, offset: 0.0 };\r\n }\r\n }\r\n\r\n return new FormatterSpec(name, format, conversions, inputUnit, azimuthBaseConversion, revolutionConversion);\r\n }\r\n\r\n /** Format a quantity value. */\r\n public applyFormatting(magnitude: number): string {\r\n return Formatter.formatQuantity(magnitude, this);\r\n }\r\n}\r\n"]}
@@ -0,0 +1,16 @@
1
+ /** @module Quantity */
2
+ /** Collects async work from formatting providers during the pre-ready phase.
3
+ * Providers call [[addPendingWork]] to register promises that the formatter
4
+ * will await before signaling [[QuantityFormatter.onFormattingReady]].
5
+ * @beta
6
+ */
7
+ export declare class FormattingReadyCollector {
8
+ private _promises;
9
+ /** Register async work that must complete before the formatter signals ready.
10
+ * Call this from an `onBeforeFormattingReady` listener.
11
+ */
12
+ addPendingWork(work: Promise<void>): void;
13
+ /** @internal Await all registered work with a timeout. Logs warnings for rejections and timeouts. */
14
+ awaitAll(timeoutMs?: number): Promise<void>;
15
+ }
16
+ //# sourceMappingURL=FormattingReadyCollector.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"FormattingReadyCollector.d.ts","sourceRoot":"","sources":["../../../src/Formatter/FormattingReadyCollector.ts"],"names":[],"mappings":"AAIA,uBAAuB;AAKvB;;;;GAIG;AACH,qBAAa,wBAAwB;IACnC,OAAO,CAAC,SAAS,CAAuB;IAExC;;OAEG;IACI,cAAc,CAAC,IAAI,EAAE,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI;IAIhD,qGAAqG;IACxF,QAAQ,CAAC,SAAS,GAAE,MAAe,GAAG,OAAO,CAAC,IAAI,CAAC;CAmBjE"}
@@ -0,0 +1,44 @@
1
+ "use strict";
2
+ /*---------------------------------------------------------------------------------------------
3
+ * Copyright (c) Bentley Systems, Incorporated. All rights reserved.
4
+ * See LICENSE.md in the project root for license terms and full copyright notice.
5
+ *--------------------------------------------------------------------------------------------*/
6
+ /** @module Quantity */
7
+ Object.defineProperty(exports, "__esModule", { value: true });
8
+ exports.FormattingReadyCollector = void 0;
9
+ const core_bentley_1 = require("@itwin/core-bentley");
10
+ const QuantityLoggerCategory_1 = require("../QuantityLoggerCategory");
11
+ /** Collects async work from formatting providers during the pre-ready phase.
12
+ * Providers call [[addPendingWork]] to register promises that the formatter
13
+ * will await before signaling [[QuantityFormatter.onFormattingReady]].
14
+ * @beta
15
+ */
16
+ class FormattingReadyCollector {
17
+ _promises = [];
18
+ /** Register async work that must complete before the formatter signals ready.
19
+ * Call this from an `onBeforeFormattingReady` listener.
20
+ */
21
+ addPendingWork(work) {
22
+ this._promises.push(work);
23
+ }
24
+ /** @internal Await all registered work with a timeout. Logs warnings for rejections and timeouts. */
25
+ async awaitAll(timeoutMs = 20_000) {
26
+ if (this._promises.length === 0)
27
+ return;
28
+ const timeout = new Promise((resolve) => setTimeout(() => resolve("timeout"), timeoutMs));
29
+ const work = Promise.allSettled(this._promises).then((results) => {
30
+ for (const result of results) {
31
+ if (result.status === "rejected") {
32
+ core_bentley_1.Logger.logWarning(QuantityLoggerCategory_1.QuantityLoggerCategory.Formatting, "FormattingReadyCollector: a provider's async work rejected", () => ({ reason: result.reason }));
33
+ }
34
+ }
35
+ return "done";
36
+ });
37
+ const outcome = await Promise.race([work, timeout]);
38
+ if (outcome === "timeout") {
39
+ core_bentley_1.Logger.logWarning(QuantityLoggerCategory_1.QuantityLoggerCategory.Formatting, `FormattingReadyCollector: timed out after ${timeoutMs}ms waiting for ${this._promises.length} provider(s). Proceeding with ready signal.`);
40
+ }
41
+ }
42
+ }
43
+ exports.FormattingReadyCollector = FormattingReadyCollector;
44
+ //# sourceMappingURL=FormattingReadyCollector.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"FormattingReadyCollector.js","sourceRoot":"","sources":["../../../src/Formatter/FormattingReadyCollector.ts"],"names":[],"mappings":";AAAA;;;+FAG+F;AAC/F,uBAAuB;;;AAEvB,sDAA6C;AAC7C,sEAAmE;AAEnE;;;;GAIG;AACH,MAAa,wBAAwB;IAC3B,SAAS,GAAoB,EAAE,CAAC;IAExC;;OAEG;IACI,cAAc,CAAC,IAAmB;QACvC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAC5B,CAAC;IAED,qGAAqG;IAC9F,KAAK,CAAC,QAAQ,CAAC,YAAoB,MAAM;QAC9C,IAAI,IAAI,CAAC,SAAS,CAAC,MAAM,KAAK,CAAC;YAC7B,OAAO;QAET,MAAM,OAAO,GAAG,IAAI,OAAO,CAAY,CAAC,OAAO,EAAE,EAAE,CAAC,UAAU,CAAC,GAAG,EAAE,CAAC,OAAO,CAAC,SAAS,CAAC,EAAE,SAAS,CAAC,CAAC,CAAC;QACrG,MAAM,IAAI,GAAG,OAAO,CAAC,UAAU,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,EAAE;YAC/D,KAAK,MAAM,MAAM,IAAI,OAAO,EAAE,CAAC;gBAC7B,IAAI,MAAM,CAAC,MAAM,KAAK,UAAU,EAAE,CAAC;oBACjC,qBAAM,CAAC,UAAU,CAAC,+CAAsB,CAAC,UAAU,EAAE,4DAA4D,EAAE,GAAG,EAAE,CAAC,CAAC,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;gBACxJ,CAAC;YACH,CAAC;YACD,OAAO,MAAe,CAAC;QACzB,CAAC,CAAC,CAAC;QAEH,MAAM,OAAO,GAAG,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC,CAAC;QACpD,IAAI,OAAO,KAAK,SAAS,EAAE,CAAC;YAC1B,qBAAM,CAAC,UAAU,CAAC,+CAAsB,CAAC,UAAU,EAAE,6CAA6C,SAAS,kBAAkB,IAAI,CAAC,SAAS,CAAC,MAAM,6CAA6C,CAAC,CAAC;QACnM,CAAC;IACH,CAAC;CACF;AA9BD,4DA8BC","sourcesContent":["/*---------------------------------------------------------------------------------------------\r\n* Copyright (c) Bentley Systems, Incorporated. All rights reserved.\r\n* See LICENSE.md in the project root for license terms and full copyright notice.\r\n*--------------------------------------------------------------------------------------------*/\r\n/** @module Quantity */\r\n\r\nimport { Logger } from \"@itwin/core-bentley\";\r\nimport { QuantityLoggerCategory } from \"../QuantityLoggerCategory\";\r\n\r\n/** Collects async work from formatting providers during the pre-ready phase.\r\n * Providers call [[addPendingWork]] to register promises that the formatter\r\n * will await before signaling [[QuantityFormatter.onFormattingReady]].\r\n * @beta\r\n */\r\nexport class FormattingReadyCollector {\r\n private _promises: Promise<void>[] = [];\r\n\r\n /** Register async work that must complete before the formatter signals ready.\r\n * Call this from an `onBeforeFormattingReady` listener.\r\n */\r\n public addPendingWork(work: Promise<void>): void {\r\n this._promises.push(work);\r\n }\r\n\r\n /** @internal Await all registered work with a timeout. Logs warnings for rejections and timeouts. */\r\n public async awaitAll(timeoutMs: number = 20_000): Promise<void> {\r\n if (this._promises.length === 0)\r\n return;\r\n\r\n const timeout = new Promise<\"timeout\">((resolve) => setTimeout(() => resolve(\"timeout\"), timeoutMs));\r\n const work = Promise.allSettled(this._promises).then((results) => {\r\n for (const result of results) {\r\n if (result.status === \"rejected\") {\r\n Logger.logWarning(QuantityLoggerCategory.Formatting, \"FormattingReadyCollector: a provider's async work rejected\", () => ({ reason: result.reason }));\r\n }\r\n }\r\n return \"done\" as const;\r\n });\r\n\r\n const outcome = await Promise.race([work, timeout]);\r\n if (outcome === \"timeout\") {\r\n Logger.logWarning(QuantityLoggerCategory.Formatting, `FormattingReadyCollector: timed out after ${timeoutMs}ms waiting for ${this._promises.length} provider(s). Proceeding with ready signal.`);\r\n }\r\n }\r\n}\r\n"]}
@@ -1,9 +1,11 @@
1
1
  /** @packageDocumentation
2
2
  * @module Quantity
3
3
  */
4
- import { BeEvent } from "@itwin/core-bentley";
5
- import { UnitProps } from "../Interfaces";
4
+ import { BeEvent, BeUnorderedUiEvent } from "@itwin/core-bentley";
5
+ import { UnitProps, UnitSystemKey } from "../Interfaces";
6
6
  import { DecimalPrecision, FormatTraits, FormatType, FractionalPrecision } from "./FormatEnums";
7
+ import type { FormatterSpec } from "./FormatterSpec";
8
+ import type { ParserSpec } from "../ParserSpec";
7
9
  /** Defines a unit specification with a name and optional label override.
8
10
  * Used in composite formats and ratio unit specifications.
9
11
  * @beta
@@ -150,6 +152,13 @@ export interface FormatsChangedArgs {
150
152
  * If array, the array items list the names of formats that were changed or removed.
151
153
  */
152
154
  formatsChanged: "all" | string[];
155
+ /** If set, indicates that the format set implies a particular unit system. The consumer
156
+ * (e.g., QuantityFormatter) will synchronize the active unit system to match.
157
+ * If `undefined`, the format change does not imply a unit system switch — the active
158
+ * unit system remains unchanged.
159
+ * @beta
160
+ */
161
+ impliedUnitSystem?: UnitSystemKey;
153
162
  }
154
163
  /** This interface is implemented by a class that would provide formats for use in formatting quantities.
155
164
  * @beta
@@ -158,7 +167,7 @@ export interface FormatsProvider {
158
167
  /**
159
168
  * @param name The full name of the Format or KindOfQuantity.
160
169
  */
161
- getFormat(name: string): Promise<FormatDefinition | undefined>;
170
+ getFormat(name: string, system?: UnitSystemKey): Promise<FormatDefinition | undefined>;
162
171
  /**
163
172
  * Fired when formats are added, removed, or changed.
164
173
  * If all formats are changed, a single string "all" is emitted. Else, an array of changed format names is emitted.
@@ -179,4 +188,43 @@ export interface MutableFormatsProvider extends FormatsProvider {
179
188
  */
180
189
  removeFormat(name: string): Promise<void>;
181
190
  }
191
+ /** Entries returned when looking up specs from the format registry.
192
+ * @beta
193
+ */
194
+ export interface FormattingSpecEntry {
195
+ formatterSpec: FormatterSpec;
196
+ parserSpec: ParserSpec;
197
+ }
198
+ /** Arguments for looking up a formatting spec entry.
199
+ * @beta
200
+ */
201
+ export interface FormattingSpecArgs {
202
+ /** The KoQ name to look up. */
203
+ name: string;
204
+ /** The persistence unit name (e.g., `"Units.M"`). */
205
+ persistenceUnitName: string;
206
+ /** Optional unit system override. When omitted, the active system is used. */
207
+ system?: UnitSystemKey;
208
+ }
209
+ /** Arguments for registering a formatting spec entry.
210
+ * @beta
211
+ */
212
+ export interface AddFormattingSpecArgs extends FormattingSpecArgs {
213
+ /** Format properties to use. When omitted, the provider resolves them from the KoQ schema. */
214
+ formatProps?: FormatProps;
215
+ }
216
+ /** Minimal contract required by [[FormatSpecHandle]] to look up specs and subscribe to reloads.
217
+ * Implemented by [[QuantityFormatter]] in `@itwin/core-frontend`.
218
+ * @beta
219
+ */
220
+ export interface FormattingSpecProvider {
221
+ /** Look up a formatting spec entry by KoQ name and persistence unit. */
222
+ getSpecsByNameAndUnit(args: FormattingSpecArgs): FormattingSpecEntry | undefined;
223
+ /** Format a numeric value using the given formatter spec. */
224
+ formatQuantity(magnitude: number, formatSpec: FormatterSpec): string;
225
+ /** Event raised after the provider has finished reloading its caches.
226
+ * Uses Set-backed event for safe concurrent add/remove during emit.
227
+ */
228
+ readonly onFormattingReady: BeUnorderedUiEvent<void>;
229
+ }
182
230
  //# sourceMappingURL=Interfaces.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"Interfaces.d.ts","sourceRoot":"","sources":["../../../src/Formatter/Interfaces.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"Interfaces.d.ts","sourceRoot":"","sources":["../../../src/Formatter/Interfaces.ts"],"names":[],"mappings":"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"}