@bentley/imodeljs-quantity
Advanced tools
Comparing version 0.191.0 to 1.0.0
@@ -5,2 +5,17 @@ { | ||
{ | ||
"version": "1.0.0", | ||
"tag": "@bentley/imodeljs-quantity_v1.0.0", | ||
"date": "Mon, 03 Jun 2019 18:09:39 GMT", | ||
"comments": { | ||
"none": [ | ||
{ | ||
"comment": "Allow ^ to be used to define angle degrees." | ||
}, | ||
{ | ||
"comment": "Add ParserSec to support synchronous quantity parsing." | ||
} | ||
] | ||
} | ||
}, | ||
{ | ||
"version": "0.191.0", | ||
@@ -7,0 +22,0 @@ "tag": "@bentley/imodeljs-quantity_v0.191.0", |
# Change Log - @bentley/imodeljs-quantity | ||
This log was last generated on Mon, 13 May 2019 15:52:05 GMT and should not be manually modified. | ||
This log was last generated on Mon, 03 Jun 2019 18:09:39 GMT and should not be manually modified. | ||
## 1.0.0 | ||
Mon, 03 Jun 2019 18:09:39 GMT | ||
### Updates | ||
- Allow ^ to be used to define angle degrees. | ||
- Add ParserSec to support synchronous quantity parsing. | ||
## 0.191.0 | ||
@@ -6,0 +14,0 @@ Mon, 13 May 2019 15:52:05 GMT |
@@ -10,3 +10,8 @@ import { BentleyError } from "@bentley/bentleyjs-core"; | ||
InvalidJson = 35040, | ||
InvalidCompositeFormat = 35041 | ||
InvalidCompositeFormat = 35041, | ||
UnableToGenerateParseTokens = 35042, | ||
NoValueOrUnitFoundInString = 35043, | ||
UnitLabelSuppliedButNotMatched = 35044, | ||
UnknownUnit = 35045, | ||
UnableToConvertParseTokensToQuantity = 35046 | ||
} | ||
@@ -13,0 +18,0 @@ /** The error type thrown by this module. See [[QuantityStatus]] for `errorNumber` values. |
@@ -18,2 +18,7 @@ "use strict"; | ||
QuantityStatus[QuantityStatus["InvalidCompositeFormat"] = 35041] = "InvalidCompositeFormat"; | ||
QuantityStatus[QuantityStatus["UnableToGenerateParseTokens"] = 35042] = "UnableToGenerateParseTokens"; | ||
QuantityStatus[QuantityStatus["NoValueOrUnitFoundInString"] = 35043] = "NoValueOrUnitFoundInString"; | ||
QuantityStatus[QuantityStatus["UnitLabelSuppliedButNotMatched"] = 35044] = "UnitLabelSuppliedButNotMatched"; | ||
QuantityStatus[QuantityStatus["UnknownUnit"] = 35045] = "UnknownUnit"; | ||
QuantityStatus[QuantityStatus["UnableToConvertParseTokensToQuantity"] = 35046] = "UnableToConvertParseTokensToQuantity"; | ||
})(QuantityStatus = exports.QuantityStatus || (exports.QuantityStatus = {})); | ||
@@ -20,0 +25,0 @@ /** The error type thrown by this module. See [[QuantityStatus]] for `errorNumber` values. |
import { FormatProps } from "./Interfaces"; | ||
import { UnitProps, UnitsProvider, UnitConversion } from "../Interfaces"; | ||
import { UnitProps, UnitsProvider, UnitConversionSpec } from "../Interfaces"; | ||
import { FormatType, ScientificType, ShowSignOption, DecimalPrecision, FractionalPrecision, FormatTraits } from "./FormatEnums"; | ||
@@ -82,10 +82,2 @@ /** A class used to both define the specifications for formatting a quantity values and the methods to do the formatting. | ||
} | ||
/** Interface the defines the format of the data needed to convert a quantity from one unit to another. | ||
* @alpha | ||
*/ | ||
export interface UnitConversionSpec { | ||
name: string; | ||
label: string; | ||
conversion: UnitConversion; | ||
} | ||
/** 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. | ||
@@ -92,0 +84,0 @@ * @alpha |
@@ -180,3 +180,3 @@ "use strict"; | ||
throw new Exception_1.QuantityError(Exception_1.QuantityStatus.InvalidCompositeFormat, `The Format ${spec.format.name} has a invalid unit specification..`); | ||
const unitValue = (posMagnitude * unitConversion.factor) + unitConversion.offset; // offset should only ever be defined for major unit | ||
const unitValue = (posMagnitude * unitConversion.factor) + unitConversion.offset + Formatter.FPV_MINTHRESHOLD; // offset should only ever be defined for major unit | ||
if (i < spec.format.units.length - 1) { | ||
@@ -183,0 +183,0 @@ const wholePart = Math.floor(unitValue); |
@@ -6,2 +6,3 @@ export * from "./Constants"; | ||
export * from "./Quantity"; | ||
export * from "./Unit"; | ||
export * from "./Formatter/Format"; | ||
@@ -8,0 +9,0 @@ export * from "./Formatter/FormatEnums"; |
@@ -12,5 +12,5 @@ "use strict"; | ||
__export(require("./Exception")); | ||
__export(require("./Interfaces")); | ||
__export(require("./Parser")); | ||
__export(require("./Quantity")); | ||
__export(require("./Unit")); | ||
__export(require("./Formatter/Format")); | ||
@@ -17,0 +17,0 @@ __export(require("./Formatter/FormatEnums")); |
@@ -14,2 +14,4 @@ /** This interface provides basic information about a Unit that is return from a UnitProvider. This info | ||
readonly isValid: boolean; | ||
/** Optionally defined set of unit labels that can be used to represent the unit. This is helpful when parsing quantity value strings */ | ||
readonly alternateLabels?: string[]; | ||
} | ||
@@ -24,2 +26,15 @@ /** This interface defines the required properties of a Quantity. | ||
} | ||
/** Interface that defines how to convert between a specific unit an another in synchronous formatting or parsing processing. | ||
* @alpha | ||
*/ | ||
export interface UnitConversionSpec { | ||
/** Unit name that was used to locate the unit by the Unit Provider */ | ||
name: string; | ||
/** The default label that is used to display unit */ | ||
label: string; | ||
/** the information necessary to convert the unit to a specific display unit */ | ||
conversion: UnitConversion; | ||
/** Labels that may be used to represent the unit in a string that is to be parsed. */ | ||
parseLabels?: string[]; | ||
} | ||
/** This interface defines the properties required to convert a quantity value from one unit to another such as from meters to feet | ||
@@ -33,2 +48,9 @@ * or from Celsius to Fahrenheit. | ||
} | ||
/** Interface that defines potential parse units that may be found in user's string input of a quantity value. | ||
* @alpha | ||
*/ | ||
export interface PotentialParseUnit { | ||
unitName: string; | ||
altLabels?: string[]; | ||
} | ||
/** This interface is implemented by the class that is responsible for locating units by name or label and providing conversion values between units. | ||
@@ -40,14 +62,6 @@ * The methods to be implemented are async allowing the UnitsProvider to query the backend when necessary to look up unit definition and conversion rules. | ||
findUnit(unitLabel: string, unitFamily?: string): Promise<UnitProps>; | ||
getUnitsByFamily(unitFamily: string): Promise<UnitProps[]>; | ||
findUnitByName(unitName: string): Promise<UnitProps>; | ||
getConversion(fromUnit: UnitProps, toUnit: UnitProps): Promise<UnitConversion>; | ||
} | ||
/** This class is a convenience class that can be returned when a valid Unit cannot be determined. | ||
* @alpha | ||
*/ | ||
export declare class BadUnit implements UnitProps { | ||
name: string; | ||
label: string; | ||
unitFamily: string; | ||
isValid: boolean; | ||
} | ||
//# sourceMappingURL=Interfaces.d.ts.map |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
/** This class is a convenience class that can be returned when a valid Unit cannot be determined. | ||
* @alpha | ||
*/ | ||
class BadUnit { | ||
constructor() { | ||
this.name = ""; | ||
this.label = ""; | ||
this.unitFamily = ""; | ||
this.isValid = false; | ||
} | ||
} | ||
exports.BadUnit = BadUnit; | ||
//# sourceMappingURL=Interfaces.js.map |
@@ -49,2 +49,3 @@ /******/ (function(modules) { // webpackBootstrap | ||
/******/ } | ||
/******/ | ||
/******/ return result; | ||
@@ -51,0 +52,0 @@ /******/ } |
@@ -1,2 +0,2 @@ | ||
!function(t,e){"object"===typeof exports&&"object"===typeof module?module.exports=e(require("bentleyjs_core")):"function"===typeof define&&define.amd?define("imodeljs_quantity",["bentleyjs_core"],e):"object"===typeof exports?exports.imodeljs_quantity=e(require("bentleyjs_core")):t.imodeljs_quantity=e(t.bentleyjs_core)}(this,function(t){return(this.webpackJsonp=this.webpackJsonp||[]).push([[0],{"./lib/Constants.js":function(t,e,i){"use strict";Object.defineProperty(e,"__esModule",{value:!0});class QuantityConstants{static get LocaleSpecificDecimalSeparator(){if(QuantityConstants._LOCALE_DECIMAL_SEPARATOR.length>0)return QuantityConstants._LOCALE_DECIMAL_SEPARATOR;QuantityConstants._LOCALE_DECIMAL_SEPARATOR=".";const t=12345.6789.toLocaleString().match(/345(.*)67/);return t&&t.length>1&&(QuantityConstants._LOCALE_DECIMAL_SEPARATOR=t[1]),QuantityConstants._LOCALE_DECIMAL_SEPARATOR}static get LocaleSpecificThousandSeparator(){if(QuantityConstants._LOCALE_THOUSAND_SEPARATOR.length>0)return QuantityConstants._LOCALE_THOUSAND_SEPARATOR;QuantityConstants._LOCALE_THOUSAND_SEPARATOR=",";const t=12345.6789.toLocaleString().match(/12(.*)345/);return t&&t.length>0&&(QuantityConstants._LOCALE_THOUSAND_SEPARATOR=t[1]),QuantityConstants._LOCALE_THOUSAND_SEPARATOR}}QuantityConstants.CHAR_COMMA=44,QuantityConstants.CHAR_SPACE=32,QuantityConstants.CHAR_NUMBER=35,QuantityConstants.CHAR_PLUS=43,QuantityConstants.CHAR_MINUS=45,QuantityConstants.CHAR_PERIOD=46,QuantityConstants.CHAR_SLASH=47,QuantityConstants.CHAR_DIVISION_SLASH=8725,QuantityConstants.CHAR_FRACTION_SLASH=8260,QuantityConstants.CHAR_ONE_QUARTER=188,QuantityConstants.CHAR_ONE_HALF=189,QuantityConstants.CHAR_THREE_QUARTER=190,QuantityConstants.CHAR_DIGIT_ZERO=48,QuantityConstants.CHAR_DIGIT_NINE=57,QuantityConstants.CHAR_UPPER_E=69,QuantityConstants.CHAR_LOWER_E=101,QuantityConstants._LOCALE_DECIMAL_SEPARATOR="",QuantityConstants._LOCALE_THOUSAND_SEPARATOR="",e.QuantityConstants=QuantityConstants},"./lib/Exception.js":function(t,e,i){"use strict";Object.defineProperty(e,"__esModule",{value:!0});const a=i("@bentley/bentleyjs-core");!function(t){t[t.QUANTITY_ERROR_BASE=35039]="QUANTITY_ERROR_BASE",t[t.Success=0]="Success",t[t.InvalidJson=35040]="InvalidJson",t[t.InvalidCompositeFormat=35041]="InvalidCompositeFormat"}(e.QuantityStatus||(e.QuantityStatus={}));e.QuantityError=class QuantityError extends a.BentleyError{constructor(t,e){super(t,e),this.errorNumber=t}}},"./lib/Formatter/Format.js":function(t,e,i){"use strict";Object.defineProperty(e,"__esModule",{value:!0});const a=i("./lib/Exception.js"),r=i("./lib/Constants.js"),n=i("./lib/Formatter/FormatEnums.js");class Format{constructor(t){this._name="",this._roundFactor=0,this._type=n.FormatType.Decimal,this._precision=n.DecimalPrecision.Six,this._showSignOption=n.ShowSignOption.OnlyNegative,this._decimalSeparator=r.QuantityConstants.LocaleSpecificDecimalSeparator,this._thousandSeparator=r.QuantityConstants.LocaleSpecificThousandSeparator,this._uomSeparator=" ",this._stationSeparator="+",this._formatTraits=0,this._spacer=" ",this._includeZero=!0,this._name=t}get name(){return this._name}get roundFactor(){return this._roundFactor}get type(){return this._type}get precision(){return this._precision}get minWidth(){return this._minWidth}get scientificType(){return this._scientificType}get showSignOption(){return this._showSignOption}get decimalSeparator(){return this._decimalSeparator}get thousandSeparator(){return this._thousandSeparator}get uomSeparator(){return this._uomSeparator}get stationSeparator(){return this._stationSeparator}get stationOffsetSize(){return this._stationOffsetSize}get formatTraits(){return this._formatTraits}get spacer(){return this._spacer}get includeZero(){return this._includeZero}get units(){return this._units}get hasUnits(){return void 0!==this._units&&this._units.length>0}static scientificTypeToString(t){return t===n.ScientificType.Normalized?"Normalized":"ZeroNormalized"}static parseScientificType(t,e){switch(t){case"normalized":return n.ScientificType.Normalized;case"zeronormalized":return n.ScientificType.ZeroNormalized;default:throw new a.QuantityError(a.QuantityStatus.InvalidJson,`The Format ${e} has an invalid 'SCIENTIFIC_TYPE' attribute.`)}}static showSignOptionToString(t){switch(t){case n.ShowSignOption.NegativeParentheses:return"NegativeParentheses";case n.ShowSignOption.NoSign:return"NoSign";case n.ShowSignOption.OnlyNegative:return"OnlyNegative";case n.ShowSignOption.SignAlways:return"SignAlways"}}static parseShowSignOption(t,e){switch(t.toLowerCase()){case"nosign":return n.ShowSignOption.NoSign;case"onlynegative":return n.ShowSignOption.OnlyNegative;case"signalways":return n.ShowSignOption.SignAlways;case"negativeparentheses":return n.ShowSignOption.NegativeParentheses;default:throw new a.QuantityError(a.QuantityStatus.InvalidJson,`The Format ${e} has an invalid 'showSignOption' attribute.`)}}static formatTraitsToArray(t){const e=Array();return(t&n.FormatTraits.TrailZeroes)===n.FormatTraits.TrailZeroes&&e.push("trailZeroes"),(t&n.FormatTraits.KeepSingleZero)===n.FormatTraits.KeepSingleZero&&e.push("keepSingleZero"),(t&n.FormatTraits.ZeroEmpty)===n.FormatTraits.ZeroEmpty&&e.push("zeroEmpty"),(t&n.FormatTraits.KeepDecimalPoint)===n.FormatTraits.KeepDecimalPoint&&e.push("keepDecimalPoint"),(t&n.FormatTraits.ApplyRounding)===n.FormatTraits.ApplyRounding&&e.push("applyRounding"),(t&n.FormatTraits.FractionDash)===n.FormatTraits.FractionDash&&e.push("fractionDash"),(t&n.FormatTraits.ShowUnitLabel)===n.FormatTraits.ShowUnitLabel&&e.push("showUnitLabel"),(t&n.FormatTraits.PrependUnitLabel)===n.FormatTraits.PrependUnitLabel&&e.push("prependUnitLabel"),(t&n.FormatTraits.Use1000Separator)===n.FormatTraits.Use1000Separator&&e.push("use1000Separator"),(t&n.FormatTraits.ExponentOnlyNegative)===n.FormatTraits.ExponentOnlyNegative&&e.push("exponentOnlyNegative"),e}static parseFormatTrait(t,e){let i=e;switch(t.toLowerCase()){case"trailzeroes":i=e|n.FormatTraits.TrailZeroes;break;case"keepsinglezero":i=e|n.FormatTraits.KeepSingleZero;break;case"zeroempty":i=e|n.FormatTraits.ZeroEmpty;break;case"keepdecimalpoint":i=e|n.FormatTraits.KeepDecimalPoint;break;case"applyrounding":i=e|n.FormatTraits.ApplyRounding;break;case"fractiondash":i=e|n.FormatTraits.FractionDash;break;case"showunitlabel":i=e|n.FormatTraits.ShowUnitLabel;break;case"prependunitlabel":i=e|n.FormatTraits.PrependUnitLabel;break;case"use1000separator":i=e|n.FormatTraits.Use1000Separator;break;case"exponentonlynegative":i=e|n.FormatTraits.ExponentOnlyNegative;break;default:throw new a.QuantityError(a.QuantityStatus.InvalidJson,"Format has an invalid 'formatTraits' option.")}return i}static formatTypeToString(t){switch(t){case n.FormatType.Decimal:return"Decimal";case n.FormatType.Scientific:return"Scientific";case n.FormatType.Station:return"Station";case n.FormatType.Fractional:return"Fractional"}}static parseFormatType(t,e){switch(t.toLowerCase()){case"decimal":return n.FormatType.Decimal;case"scientific":return n.FormatType.Scientific;case"station":return n.FormatType.Station;case"fractional":return n.FormatType.Fractional;default:throw new a.QuantityError(a.QuantityStatus.InvalidJson,`The Format ${e} has an invalid 'type' attribute.`)}}static parseDecimalPrecision(t){switch(t){case 0:return n.DecimalPrecision.Zero;case 1:return n.DecimalPrecision.One;case 2:return n.DecimalPrecision.Two;case 3:return n.DecimalPrecision.Three;case 4:return n.DecimalPrecision.Four;case 5:return n.DecimalPrecision.Five;case 6:return n.DecimalPrecision.Six;case 7:return n.DecimalPrecision.Seven;case 8:return n.DecimalPrecision.Eight;case 9:return n.DecimalPrecision.Nine;case 10:return n.DecimalPrecision.Ten;case 11:return n.DecimalPrecision.Eleven;case 12:return n.DecimalPrecision.Twelve;default:throw new a.QuantityError(a.QuantityStatus.InvalidJson,"The 'precision' attribute must be an integer in the range 0-12.")}}static parseFractionalPrecision(t,e){switch(t){case 1:return n.FractionalPrecision.One;case 2:return n.FractionalPrecision.Two;case 4:return n.FractionalPrecision.Four;case 8:return n.FractionalPrecision.Eight;case 16:return n.FractionalPrecision.Sixteen;case 32:return n.FractionalPrecision.ThirtyTwo;case 64:return n.FractionalPrecision.SixtyFour;case 128:return n.FractionalPrecision.OneHundredTwentyEight;case 256:return n.FractionalPrecision.TwoHundredFiftySix;default:throw new a.QuantityError(a.QuantityStatus.InvalidJson,`The Format ${e} has an invalid 'precision' attribute.`)}}static parsePrecision(t,e,i){switch(i){case n.FormatType.Decimal:case n.FormatType.Scientific:case n.FormatType.Station:return Format.parseDecimalPrecision(t);case n.FormatType.Fractional:return Format.parseFractionalPrecision(t,e)}}verifyFormatTraitsOptions(t){(Array.isArray(t)?t:t.split(/,|;|\|/)).forEach(t=>{this._formatTraits=Format.parseFormatTrait(t,this.formatTraits)})}hasFormatTraitSet(t){return(this._formatTraits&t)===t}async createUnit(t,e,i){let r;if(void 0===e||"string"!==typeof e||void 0!==i&&"string"!==typeof i)return Promise.reject(new a.QuantityError(a.QuantityStatus.InvalidJson,"This Composite has a unit with an invalid 'name' or 'label' attribute."));for(const n of this.units){const t=n[0].name;if(t.toLowerCase()===e.toLowerCase())return Promise.reject(new a.QuantityError(a.QuantityStatus.InvalidJson,`The unit ${t} has a duplicate name.`))}if(!(r=await t.findUnit(e))||!r.isValid)return Promise.reject(new a.QuantityError(a.QuantityStatus.InvalidJson,`Invalid unit name '${e}'.`));this.units.push([r,i])}loadFormatProperties(t){if(void 0===t.type)throw new a.QuantityError(a.QuantityStatus.InvalidJson,`The Format ${this.name} does not have the required 'type' attribute.`);if("string"!==typeof t.type)throw new a.QuantityError(a.QuantityStatus.InvalidJson,`The Format ${this.name} has an invalid 'type' attribute. It should be of type 'string'.`);if(this._type=Format.parseFormatType(t.type,this.name),void 0===t.precision)throw new a.QuantityError(a.QuantityStatus.InvalidJson,`The Format ${this.name} does not have the required 'precision' attribute.`);if("number"!==typeof t.precision)throw new a.QuantityError(a.QuantityStatus.InvalidJson,`The Format ${this.name} has an invalid 'precision' attribute. It should be of type 'number'.`);if(!Number.isInteger(t.precision))throw new a.QuantityError(a.QuantityStatus.InvalidJson,`The Format ${this.name} has an invalid 'precision' attribute. It should be an integer.`);if(this._precision=Format.parsePrecision(t.precision,this.name,this._type),this.type===n.FormatType.Scientific){if(void 0===t.scientificType)throw new a.QuantityError(a.QuantityStatus.InvalidJson,`The Format ${this.name} has type 'Scientific' therefore attribute 'scientificType' is required.`);if("string"!==typeof t.scientificType)throw new a.QuantityError(a.QuantityStatus.InvalidJson,`The Format ${this.name} has an invalid 'scientificType' attribute. It should be of type 'string'.`);this._scientificType=Format.parseScientificType(t.scientificType.toLowerCase(),this.name)}if(this.type===n.FormatType.Station){if(void 0===t.stationOffsetSize)throw new a.QuantityError(a.QuantityStatus.InvalidJson,`The Format ${this.name} has type 'Station' therefore attribute 'stationOffsetSize' is required.`);if("number"!==typeof t.stationOffsetSize)throw new a.QuantityError(a.QuantityStatus.InvalidJson,`The Format ${this.name} has an invalid 'stationOffsetSize' attribute. It should be of type 'number'.`);if(!Number.isInteger(t.stationOffsetSize)||t.stationOffsetSize<=0)throw new a.QuantityError(a.QuantityStatus.InvalidJson,`The Format ${this.name} has an invalid 'stationOffsetSize' attribute. It should be a positive integer.`);this._stationOffsetSize=t.stationOffsetSize}if(void 0!==t.roundFactor){if("number"!==typeof t.roundFactor)throw new a.QuantityError(a.QuantityStatus.InvalidJson,`The Format ${this.name} has an invalid 'roundFactor' attribute. It should be of type 'number'.`);t.roundFactor!==this.roundFactor&&(this._roundFactor=t.roundFactor)}if(void 0!==t.minWidth){if("number"!==typeof t.minWidth)throw new a.QuantityError(a.QuantityStatus.InvalidJson,`The Format ${this.name} has an invalid 'minWidth' attribute. It should be of type 'number'.`);if(!Number.isInteger(t.minWidth)||t.minWidth<0)throw new a.QuantityError(a.QuantityStatus.InvalidJson,`The Format ${this.name} has an invalid 'minWidth' attribute. It should be a positive integer.`);this._minWidth=t.minWidth}if(void 0!==t.showSignOption){if("string"!==typeof t.showSignOption)throw new a.QuantityError(a.QuantityStatus.InvalidJson,`The Format ${this.name} has an invalid 'showSignOption' attribute. It should be of type 'string'.`);this._showSignOption=Format.parseShowSignOption(t.showSignOption,this.name)}if(void 0!==t.formatTraits&&0!==t.formatTraits.length){if(!Array.isArray(t.formatTraits)&&"string"!==typeof t.formatTraits)throw new a.QuantityError(a.QuantityStatus.InvalidJson,`The Format ${this.name} has an invalid 'formatTraits' attribute. It should be of type 'string' or 'string[]'.`);this.verifyFormatTraitsOptions(t.formatTraits)}if(void 0!==t.decimalSeparator){if("string"!==typeof t.decimalSeparator)throw new a.QuantityError(a.QuantityStatus.InvalidJson,`The Format ${this.name} has an invalid 'decimalSeparator' attribute. It should be of type 'string'.`);if(1!==t.decimalSeparator.length)throw new a.QuantityError(a.QuantityStatus.InvalidJson,`The Format ${this.name} has an invalid 'decimalSeparator' attribute. It must be a one character string.`);this._decimalSeparator=t.decimalSeparator}if(void 0!==t.thousandSeparator){if("string"!==typeof t.thousandSeparator)throw new a.QuantityError(a.QuantityStatus.InvalidJson,`The Format ${this.name} has an invalid 'thousandSeparator' attribute. It should be of type 'string'.`);if(1!==t.thousandSeparator.length)throw new a.QuantityError(a.QuantityStatus.InvalidJson,`The Format ${this.name} has an invalid 'thousandSeparator' attribute. It must be a one character string.`);this._thousandSeparator=t.thousandSeparator}if(void 0!==t.uomSeparator){if("string"!==typeof t.uomSeparator)throw new a.QuantityError(a.QuantityStatus.InvalidJson,`The Format ${this.name} has an invalid 'uomSeparator' attribute. It should be of type 'string'.`);if(t.uomSeparator.length<0||t.uomSeparator.length>1)throw new a.QuantityError(a.QuantityStatus.InvalidJson,`The Format ${this.name} has an invalid 'uomSeparator' attribute. It must be empty or a string with a single character.`);this._uomSeparator=t.uomSeparator}if(void 0!==t.stationSeparator){if("string"!==typeof t.stationSeparator)throw new a.QuantityError(a.QuantityStatus.InvalidJson,`The Format ${this.name} has an invalid 'stationSeparator' attribute. It should be of type 'string'.`);if(1!==t.stationSeparator.length)throw new a.QuantityError(a.QuantityStatus.InvalidJson,`The Format ${this.name} has an invalid 'stationSeparator' attribute. It must be a one character string.`);this._stationSeparator=t.stationSeparator}}async fromJson(t,e){if(this.loadFormatProperties(e),void 0!==e.composite){if(this._units=new Array,void 0!==e.composite.includeZero){if("boolean"!==typeof e.composite.includeZero)return Promise.reject(new a.QuantityError(a.QuantityStatus.InvalidJson,`The Format ${this.name} has a Composite with an invalid 'includeZero' attribute. It should be of type 'boolean'.`));this._includeZero=e.composite.includeZero}if(void 0!==e.composite.spacer){if("string"!==typeof e.composite.spacer)return Promise.reject(new a.QuantityError(a.QuantityStatus.InvalidJson,`The Format ${this.name} has a Composite with an invalid 'spacer' attribute. It must be of type 'string'.`));if(e.composite.spacer.length<0||e.composite.spacer.length>1)return Promise.reject(new a.QuantityError(a.QuantityStatus.InvalidJson,`The Format ${this.name} has a Composite with an invalid 'spacer' attribute. It must be empty or a string with a single character.`));this._spacer=e.composite.spacer}if(void 0!==e.composite.units){if(!Array.isArray(e.composite.units))return Promise.reject(new a.QuantityError(a.QuantityStatus.InvalidJson,`The Format ${this.name} has a Composite with an invalid 'units' attribute. It must be of type 'array'`));if(e.composite.units.length>0&&e.composite.units.length<=4)try{const i=[];for(const a of e.composite.units)i.push(this.createUnit(t,a.name,a.label));await Promise.all(i)}catch(t){return Promise.reject(t)}}if(void 0===this.units||0===this.units.length)return Promise.reject(new a.QuantityError(a.QuantityStatus.InvalidJson,`The Format ${this.name} has a Composite with no valid 'units'`))}}toJson(){const t={};if(t.type=Format.formatTypeToString(this.type),t.precision=this.precision,t.roundFactor=this.roundFactor,void 0!==this.minWidth&&(t.minWidth=this.minWidth),t.showSignOption=Format.showSignOptionToString(this.showSignOption),t.formatTraits=Format.formatTraitsToArray(this.formatTraits),t.decimalSeparator=this.decimalSeparator,t.thousandSeparator=this.thousandSeparator,t.uomSeparator=this.uomSeparator,void 0!==this.scientificType&&(t.scientificType=Format.scientificTypeToString(this.scientificType)),void 0!==this.stationOffsetSize&&(t.stationOffsetSize=this.stationOffsetSize),t.stationSeparator=this.stationSeparator,void 0!==this.units){const e={};e.spacer=this.spacer,e.includeZero=this.includeZero,e.units=[],this.units.forEach(t=>{void 0!==t[1]?e.units.push({name:t[0].name,label:t[1]}):e.units.push({name:t[0].name})}),t.composite=e}return t}}e.Format=Format;class FormatterSpec{constructor(t,e,i){this._name="",this._conversions=[],this._name=t,this._format=e,i&&(this._conversions=i)}get name(){return this._name}get unitConversions(){return this._conversions}get format(){return this._format}static async create(t,e,i,a){const r=[];if(e.units){let t=a;for(const a of e.units){let e;e=t?await i.getConversion(t,a[0]):{factor:1,offset:0};const n=a[1]&&a[1].length>0?a[1]:a[0].label,o={name:a[0].name,label:n,conversion:e};r.push(o),t=a[0]}}else if(a){const t={name:a.name,label:a.label,conversion:{factor:1,offset:0}};r.push(t)}return Promise.resolve(new FormatterSpec(t,e,r))}}e.FormatterSpec=FormatterSpec},"./lib/Formatter/FormatEnums.js":function(t,e,i){"use strict";Object.defineProperty(e,"__esModule",{value:!0}),function(t){t[t.TrailZeroes=1]="TrailZeroes",t[t.KeepSingleZero=2]="KeepSingleZero",t[t.ZeroEmpty=4]="ZeroEmpty",t[t.KeepDecimalPoint=8]="KeepDecimalPoint",t[t.ApplyRounding=16]="ApplyRounding",t[t.FractionDash=32]="FractionDash",t[t.ShowUnitLabel=64]="ShowUnitLabel",t[t.PrependUnitLabel=128]="PrependUnitLabel",t[t.Use1000Separator=256]="Use1000Separator",t[t.ExponentOnlyNegative=512]="ExponentOnlyNegative"}(e.FormatTraits||(e.FormatTraits={})),function(t){t[t.One=1]="One",t[t.Two=2]="Two",t[t.Four=4]="Four",t[t.Eight=8]="Eight",t[t.Sixteen=16]="Sixteen",t[t.ThirtyTwo=32]="ThirtyTwo",t[t.SixtyFour=64]="SixtyFour",t[t.OneHundredTwentyEight=128]="OneHundredTwentyEight",t[t.TwoHundredFiftySix=256]="TwoHundredFiftySix"}(e.FractionalPrecision||(e.FractionalPrecision={})),function(t){t[t.Zero=0]="Zero",t[t.One=1]="One",t[t.Two=2]="Two",t[t.Three=3]="Three",t[t.Four=4]="Four",t[t.Five=5]="Five",t[t.Six=6]="Six",t[t.Seven=7]="Seven",t[t.Eight=8]="Eight",t[t.Nine=9]="Nine",t[t.Ten=10]="Ten",t[t.Eleven=11]="Eleven",t[t.Twelve=12]="Twelve"}(e.DecimalPrecision||(e.DecimalPrecision={})),function(t){t[t.Decimal=0]="Decimal",t[t.Fractional=1]="Fractional",t[t.Scientific=2]="Scientific",t[t.Station=3]="Station"}(e.FormatType||(e.FormatType={})),function(t){t[t.Normalized=0]="Normalized",t[t.ZeroNormalized=1]="ZeroNormalized"}(e.ScientificType||(e.ScientificType={})),function(t){t[t.NoSign=0]="NoSign",t[t.OnlyNegative=1]="OnlyNegative",t[t.SignAlways=2]="SignAlways",t[t.NegativeParentheses=3]="NegativeParentheses"}(e.ShowSignOption||(e.ShowSignOption={}))},"./lib/Formatter/Formatter.js":function(t,e,i){"use strict";Object.defineProperty(e,"__esModule",{value:!0});const a=i("./lib/Constants.js"),r=i("./lib/Exception.js"),n=i("./lib/Formatter/FormatEnums.js"),o=.50000000001;class FractionalNumeric{constructor(t,e,i){this._integral=0,this._numerator=0,this._denominator=1,this._greatestCommonFactor=1,this._textParts=[],this.calculate(t,e),this.formTextParts(i)}calculate(t,e){const i=Math.abs(t);this._denominator=e,this._integral=Math.floor(i);const a=i-this._integral;this._numerator=Math.floor(a*this._denominator+o),0!==e&&this._numerator/this._denominator===1?(this._numerator=0,this._integral+=1):this._greatestCommonFactor=this.getGreatestCommonFactor(this._numerator,this._denominator)}getGreatestCommonFactor(t,e){let i;for(;0!==e;)i=t%e,t=e,e=i;return t<0?-t:t}get greatestCommonFactor(){return this._greatestCommonFactor}get hasFractionPart(){return this._textParts.length>0}get isZero(){return 0===this._numerator}getIntegralString(){return this._textParts.length>0?this._textParts[0]:""}getNumeratorString(){return this._textParts.length>=3?this._textParts[1]:""}getDenominatorString(){return this._textParts.length>=3?this._textParts[2]:""}formTextParts(t){let e=this._numerator,i=this._denominator;t&&this._greatestCommonFactor>1&&(e/=this.greatestCommonFactor,i/=this.greatestCommonFactor),this._textParts.push(this._integral.toFixed(0)),e>0&&(this._textParts.push(e.toFixed(0)),this._textParts.push(i.toFixed(0)))}}class Formatter{static isNegligible(t){return Math.abs(t)<Formatter.FPV_MINTHRESHOLD}static roundDouble(t,e){if(Formatter.isNegligible(e))return t;e=Math.abs(e);let i=o+t/e;return i=Math.floor(i)*e,t<0?-i:i}static integerPartToText(t,e){let i=t.toFixed(0);if(i.length>3&&e.format.hasFormatTraitSet(n.FormatTraits.Use1000Separator)&&e.format.thousandSeparator.length>0){let t=Math.floor(i.length/3),a=i.length%3;0===a&&(t-=1,a+=3);let r=i.substr(0,a);for(let n=1;n<=t;n+=1)r=r+e.format.thousandSeparator+i.substr(a,3),a+=3;i=r}return i}static trimTrailingZeroes(t){let e=-1;for(let i=t.length-1;i>=0;i--)if(t.charCodeAt(i)!==a.QuantityConstants.CHAR_DIGIT_ZERO){e=i;break}return e>=0?t.substr(0,e+1):""}static formatCompositePart(t,e,i,a){let r="";return r=e?Formatter.formatMagnitude(t,a):Formatter.integerPartToText(t,a),a.format.hasFormatTraitSet(n.FormatTraits.ShowUnitLabel)?r=r+a.format.uomSeparator+i:e||(r+=":"),r}static formatComposite(t,e){const i=[];let a=Math.abs(t);if(Math.abs(a)<1e-4&&e.format.hasFormatTraitSet(n.FormatTraits.ZeroEmpty))return"";for(let n=0;n<e.unitConversions.length;n++){const t=e.unitConversions[n].label,o=e.unitConversions[n].conversion;if(o.factor<1)throw new r.QuantityError(r.QuantityStatus.InvalidCompositeFormat,`The Format ${e.format.name} has a invalid unit specification..`);if(n>0&&0!==o.offset)throw new r.QuantityError(r.QuantityStatus.InvalidCompositeFormat,`The Format ${e.format.name} has a invalid unit specification..`);const s=a*o.factor+o.offset;if(n<e.format.units.length-1){const r=Math.floor(s),n=Formatter.formatCompositePart(r,!1,t,e);a=s-r,i.push(n)}else{const a=Formatter.formatCompositePart(s,!0,t,e);i.push(a)}}return i.join(e.format.spacer?e.format.spacer:"")}static formatMagnitude(t,e){let i=Math.abs(t);if(Math.abs(i)<1e-4&&e.format.hasFormatTraitSet(n.FormatTraits.ZeroEmpty))return"";e.format.hasFormatTraitSet(n.FormatTraits.ApplyRounding)&&(i=Math.abs(Formatter.roundDouble(t,e.format.roundFactor)));const a=i>1e12||e.format.type===n.FormatType.Scientific,r=a||e.format.type===n.FormatType.Decimal,s=!r&&e.format.type===n.FormatType.Fractional,u=e.format.precision===n.DecimalPrecision.Zero,c=e.format.hasFormatTraitSet(n.FormatTraits.KeepSingleZero),h=Math.pow(10,e.format.precision),m=e.format.hasFormatTraitSet(n.FormatTraits.TrailZeroes);let l=0;if(a&&0!==i){let t=Math.log10(i),a=!1;t<0&&(t=-t,a=!0),l=Math.floor(t),e.format.type===n.FormatType.Scientific&&(e.format.scientificType===n.ScientificType.ZeroNormalized&&i>1?l+=1:e.format.scientificType===n.ScientificType.Normalized&&i<1&&(l+=1),a&&(l=-l)),i*=Math.pow(10,-l)}let p="";if(r){const t=u?i+o:i+Formatter.FPV_MINTHRESHOLD;let r=Math.floor(t),s=t-r;if(u||(s=Math.abs(s)*h+o)>=h&&(r+=1,s-=h),p=Formatter.integerPartToText(r,e),u)c&&(p=p+e.format.decimalSeparator+"0");else{let t=(s=Math.floor(s)/h).toFixed(e.format.precision);t=t.substr(2).padEnd(e.format.precision,"0"),m||(t=Formatter.trimTrailingZeroes(t)),t.length>0?p=p+e.format.decimalSeparator+t:e.format.hasFormatTraitSet(n.FormatTraits.KeepDecimalPoint)&&(p+=e.format.decimalSeparator)}if(a){p+="e"+l.toFixed(0)}}else if(s){const t=new FractionalNumeric(i,e.format.precision,!0);if(p=t.getIntegralString(),!t.isZero&&t.hasFractionPart){p=p+(e.format.hasFormatTraitSet(n.FormatTraits.FractionDash)?"-":" ")+(t.getNumeratorString()+"/"+t.getDenominatorString())}}else{const t=Math.pow(10,e.format.stationOffsetSize),a=Math.floor(i),r=Math.floor(a/t),o=a-r*t,s=i-a,u=Math.floor(.5+s*h),c=r.toFixed(0)+e.format.stationSeparator+o.toFixed(0).padStart(e.format.stationOffsetSize,"0");let l="";u>0?(l=u.toFixed(0).padEnd(e.format.precision,"0"),m||(l=Formatter.trimTrailingZeroes(l)),p=c+e.format.decimalSeparator+l):(m?l=e.format.decimalSeparator+"".padEnd(e.format.precision,"0"):e.format.hasFormatTraitSet(n.FormatTraits.KeepDecimalPoint)&&(l=e.format.decimalSeparator),p=c+l)}return p}static formatQuantity(t,e){const i=t<0;let a="",r="",o="";switch(e.format.showSignOption){case n.ShowSignOption.NegativeParentheses:i&&(a="(",r=")");break;case n.ShowSignOption.OnlyNegative:i&&(a="-");break;case n.ShowSignOption.SignAlways:a=i?"-":"+";break;case n.ShowSignOption.NoSign:}let s="";return e.format.hasUnits?s=Formatter.formatComposite(t,e):(s=Formatter.formatMagnitude(t,e)).length>0&&e.unitConversions.length>0&&e.format.hasFormatTraitSet(n.FormatTraits.ShowUnitLabel)&&(s=e.format.hasFormatTraitSet(n.FormatTraits.PrependUnitLabel)?e.unitConversions[0].label+e.format.uomSeparator+s:s+e.format.uomSeparator+e.unitConversions[0].label),o=(a.length>0||r.length>0)&&s.length>0?a+s+r:s,e.format.minWidth&&e.format.minWidth<o.length&&o.padStart(e.format.minWidth," "),o}}Formatter.FPV_MINTHRESHOLD=1e-14,e.Formatter=Formatter},"./lib/Interfaces.js":function(t,e,i){"use strict";Object.defineProperty(e,"__esModule",{value:!0});e.BadUnit=class BadUnit{constructor(){this.name="",this.label="",this.unitFamily="",this.isValid=!1}}},"./lib/Parser.js":function(t,e,i){"use strict";Object.defineProperty(e,"__esModule",{value:!0});const a=i("./lib/Constants.js"),r=i("./lib/Quantity.js"),n=i("./lib/Formatter/FormatEnums.js");class ParseToken{constructor(t){this.value="string"===typeof t?t.trim():t}get isString(){return"string"===typeof this.value}get isNumber(){return"number"===typeof this.value}}class ScientificToken{constructor(t,e){this.exponent="",this.index=t,e&&(this.exponent=e)}}class FractionToken{constructor(t,e){this.fraction=0,this.exponent="",this.index=t,e&&(this.fraction=e)}}class Parser{static checkForScientificNotation(t,e,i){let r="",n=t+1;for(;n<e.length;n++){const o=e.charCodeAt(n);if(!Parser.isDigit(o)&&(o!==a.QuantityConstants.CHAR_MINUS&&o!==a.QuantityConstants.CHAR_PLUS||n!==t+1)){n=i===o?n:n-1;break}r=r.concat(e[n])}return r.length>1||1===r.length&&r.charCodeAt(0)!==a.QuantityConstants.CHAR_MINUS&&r.charCodeAt(0)!==a.QuantityConstants.CHAR_PLUS?new ScientificToken(n,r):new ScientificToken(t)}static checkForFractions(t,e,i,r){let n="",o="",s=!0,u=t;for(r&&r.length>0&&(n=r,s=!1);u<e.length;u++){const t=e.charCodeAt(u);if(Parser.isDigit(t))s?n=n.concat(e[u]):o=o.concat(e[u]);else{if(!s||t!==a.QuantityConstants.CHAR_SLASH&&t!==a.QuantityConstants.CHAR_DIVISION_SLASH&&t!==a.QuantityConstants.CHAR_DIVISION_SLASH){i!==t&&(u-=1);break}s=!1}}if(n.length>0&&o.length>0){const t=parseInt(n,10),e=parseInt(o,10);return e>0?new FractionToken(u,t/e):new FractionToken(u)}return new FractionToken(t+1)}static isDigit(t){return t>=a.QuantityConstants.CHAR_DIGIT_ZERO&&t<=a.QuantityConstants.CHAR_DIGIT_NINE}static isDigitOrDecimalSeparator(t,e){return t===e.decimalSeparator.charCodeAt(0)||Parser.isDigit(t)}static parseQuantitySpecification(t,e){const i=[],r=t.trim();let o=!1,s="",u="",c=0,h=0;const m=[e.thousandSeparator.charCodeAt(0)];e.type===n.FormatType.Station&&e.stationSeparator&&1===e.stationSeparator.length&&m.push(e.stationSeparator.charCodeAt(0)),e.type===n.FormatType.Fractional&&e.hasFormatTraitSet(n.FormatTraits.FractionDash)&&(h=a.QuantityConstants.CHAR_MINUS),e.uomSeparator&&" "!==e.uomSeparator&&1===e.uomSeparator.length&&(c=e.uomSeparator.charCodeAt(0),m.push(c));for(let n=0;n<r.length;n++){const t=r.charCodeAt(n);if(Parser.isDigitOrDecimalSeparator(t,e))o||(s.length>0&&(i.push(new ParseToken(s)),s=""),o=!0),s=s.concat(r[n]);else if(o){if(t===a.QuantityConstants.CHAR_SLASH||t===a.QuantityConstants.CHAR_FRACTION_SLASH||t===a.QuantityConstants.CHAR_DIVISION_SLASH){const t=Parser.checkForFractions(n+1,r,c,s);let e=t.fraction;if(n=t.index,0!==t.fraction){s="",u.length>0&&("-"===u&&(e=0-e),u=""),i.push(new ParseToken(e)),o=!1;continue}}else if(t===a.QuantityConstants.CHAR_SPACE||t===h){const t=Parser.checkForFractions(n+1,r,c);let e=t.fraction;if(n=t.index,0!==t.fraction){u.length>0&&(s=u+s,"-"===u&&(e=0-e),u="");const t=parseFloat(s)+e;i.push(new ParseToken(t)),o=!1,s="";continue}}else if(t===a.QuantityConstants.CHAR_UPPER_E||t===a.QuantityConstants.CHAR_LOWER_E){const t=Parser.checkForScientificNotation(n,r,c);if(n=t.index,t.exponent&&t.exponent.length>0){u.length>0&&(s=u+s,u=""),s=s+"e"+t.exponent;const e=Number(s);i.push(new ParseToken(e)),o=!1,s="";continue}}if(-1!==m.findIndex(e=>e===t))continue;u.length>0&&(s=u+s,u=""),i.push(new ParseToken(parseFloat(s))),s=n<r.length?r[n]:"",o=!1}else{if(t===a.QuantityConstants.CHAR_PLUS||t===a.QuantityConstants.CHAR_MINUS){u=r[n];continue}s=s.concat(r[n])}}return s.length>0&&(o?(u.length>0&&(s=u+s,u=""),i.push(new ParseToken(parseFloat(s))),o=!1):i.push(new ParseToken(s))),i}static async createQuantityFromParseTokens(t,e,i){const a=e.units&&e.units.length>0?e.units[0][0]:void 0;if(1===t.length){if(t[0].isNumber)return Promise.resolve(new r.Quantity(a,t[0].value));try{const e=await i.findUnit(t[0].value,a?a.unitFamily:void 0);return Promise.resolve(new r.Quantity(e))}catch(t){}}if(2===t.length){if(t[0].isNumber&&t[1].isString){const e=await i.findUnit(t[1].value,a?a.unitFamily:void 0);return Promise.resolve(new r.Quantity(e,t[0].value))}if(t[1].isNumber&&t[0].isString){const e=await i.findUnit(t[0].value,a?a.unitFamily:void 0);return Promise.resolve(new r.Quantity(e,t[1].value))}}if(t.length%2===0){let e=0,n=a;for(let r=0;r<t.length;r+=2)if(t[r].isNumber&&t[r+1].isString){const o=t[r].value,s=await i.findUnit(t[r+1].value,a?a.unitFamily:void 0);if(0===r)n=s,e+=o;else if(n){const t=await i.getConversion(s,n);e=e<0?e-o*t.factor+t.offset:e+o*t.factor+t.offset}}return Promise.resolve(new r.Quantity(n,e))}return Promise.resolve(new r.Quantity(a))}static async parseIntoQuantity(t,e,i){const a=Parser.parseQuantitySpecification(t,e);return 0===a.length?Promise.resolve(new r.Quantity):Parser.createQuantityFromParseTokens(a,e,i)}}e.Parser=Parser},"./lib/Quantity.js":function(t,e,i){"use strict";Object.defineProperty(e,"__esModule",{value:!0});class Quantity{constructor(t,e){this._magnitude=0,this._isValid=!1,void 0!==t?(this._unit=t,this._isValid=!0):this._unit={name:"unknown",label:"unknown",unitFamily:"unknown",isValid:!1},void 0!==e&&(this._magnitude=e)}get unit(){return this._unit}get magnitude(){return this._magnitude}get isValid(){return this._isValid}convertTo(t,e){const i=this.magnitude*e.factor+e.offset;return new Quantity(t,i)}}e.Quantity=Quantity},"./lib/imodeljs-quantity.js":function(t,e,i){"use strict";function a(t){for(var i in t)e.hasOwnProperty(i)||(e[i]=t[i])}Object.defineProperty(e,"__esModule",{value:!0}),a(i("./lib/Constants.js")),a(i("./lib/Exception.js")),a(i("./lib/Interfaces.js")),a(i("./lib/Parser.js")),a(i("./lib/Quantity.js")),a(i("./lib/Formatter/Format.js")),a(i("./lib/Formatter/FormatEnums.js")),a(i("./lib/Formatter/Formatter.js")),"undefined"!==typeof window&&window&&(window.iModelJsVersions||(window.iModelJsVersions=new Map),window.iModelJsVersions.set("imodeljs-quantity","0.191.0"))},"@bentley/bentleyjs-core":function(e,i){e.exports=t}},[["./lib/imodeljs-quantity.js",1]]])}); | ||
!function(t,e){"object"===typeof exports&&"object"===typeof module?module.exports=e(require("bentleyjs_core")):"function"===typeof define&&define.amd?define("imodeljs_quantity",["bentleyjs_core"],e):"object"===typeof exports?exports.imodeljs_quantity=e(require("bentleyjs_core")):t.imodeljs_quantity=e(t.bentleyjs_core)}(this,function(t){return(this.webpackJsonp=this.webpackJsonp||[]).push([[0],{"./lib/Constants.js":function(t,e,a){"use strict";Object.defineProperty(e,"__esModule",{value:!0});class QuantityConstants{static get LocaleSpecificDecimalSeparator(){if(QuantityConstants._LOCALE_DECIMAL_SEPARATOR.length>0)return QuantityConstants._LOCALE_DECIMAL_SEPARATOR;QuantityConstants._LOCALE_DECIMAL_SEPARATOR=".";const t=12345.6789.toLocaleString().match(/345(.*)67/);return t&&t.length>1&&(QuantityConstants._LOCALE_DECIMAL_SEPARATOR=t[1]),QuantityConstants._LOCALE_DECIMAL_SEPARATOR}static get LocaleSpecificThousandSeparator(){if(QuantityConstants._LOCALE_THOUSAND_SEPARATOR.length>0)return QuantityConstants._LOCALE_THOUSAND_SEPARATOR;QuantityConstants._LOCALE_THOUSAND_SEPARATOR=",";const t=12345.6789.toLocaleString().match(/12(.*)345/);return t&&t.length>0&&(QuantityConstants._LOCALE_THOUSAND_SEPARATOR=t[1]),QuantityConstants._LOCALE_THOUSAND_SEPARATOR}}QuantityConstants.CHAR_COMMA=44,QuantityConstants.CHAR_SPACE=32,QuantityConstants.CHAR_NUMBER=35,QuantityConstants.CHAR_PLUS=43,QuantityConstants.CHAR_MINUS=45,QuantityConstants.CHAR_PERIOD=46,QuantityConstants.CHAR_SLASH=47,QuantityConstants.CHAR_DIVISION_SLASH=8725,QuantityConstants.CHAR_FRACTION_SLASH=8260,QuantityConstants.CHAR_ONE_QUARTER=188,QuantityConstants.CHAR_ONE_HALF=189,QuantityConstants.CHAR_THREE_QUARTER=190,QuantityConstants.CHAR_DIGIT_ZERO=48,QuantityConstants.CHAR_DIGIT_NINE=57,QuantityConstants.CHAR_UPPER_E=69,QuantityConstants.CHAR_LOWER_E=101,QuantityConstants._LOCALE_DECIMAL_SEPARATOR="",QuantityConstants._LOCALE_THOUSAND_SEPARATOR="",e.QuantityConstants=QuantityConstants},"./lib/Exception.js":function(t,e,a){"use strict";Object.defineProperty(e,"__esModule",{value:!0});const i=a("@bentley/bentleyjs-core");!function(t){t[t.QUANTITY_ERROR_BASE=35039]="QUANTITY_ERROR_BASE",t[t.Success=0]="Success",t[t.InvalidJson=35040]="InvalidJson",t[t.InvalidCompositeFormat=35041]="InvalidCompositeFormat",t[t.UnableToGenerateParseTokens=35042]="UnableToGenerateParseTokens",t[t.NoValueOrUnitFoundInString=35043]="NoValueOrUnitFoundInString",t[t.UnitLabelSuppliedButNotMatched=35044]="UnitLabelSuppliedButNotMatched",t[t.UnknownUnit=35045]="UnknownUnit",t[t.UnableToConvertParseTokensToQuantity=35046]="UnableToConvertParseTokensToQuantity"}(e.QuantityStatus||(e.QuantityStatus={}));e.QuantityError=class QuantityError extends i.BentleyError{constructor(t,e){super(t,e),this.errorNumber=t}}},"./lib/Formatter/Format.js":function(t,e,a){"use strict";Object.defineProperty(e,"__esModule",{value:!0});const i=a("./lib/Exception.js"),r=a("./lib/Constants.js"),n=a("./lib/Formatter/FormatEnums.js");class Format{constructor(t){this._name="",this._roundFactor=0,this._type=n.FormatType.Decimal,this._precision=n.DecimalPrecision.Six,this._showSignOption=n.ShowSignOption.OnlyNegative,this._decimalSeparator=r.QuantityConstants.LocaleSpecificDecimalSeparator,this._thousandSeparator=r.QuantityConstants.LocaleSpecificThousandSeparator,this._uomSeparator=" ",this._stationSeparator="+",this._formatTraits=0,this._spacer=" ",this._includeZero=!0,this._name=t}get name(){return this._name}get roundFactor(){return this._roundFactor}get type(){return this._type}get precision(){return this._precision}get minWidth(){return this._minWidth}get scientificType(){return this._scientificType}get showSignOption(){return this._showSignOption}get decimalSeparator(){return this._decimalSeparator}get thousandSeparator(){return this._thousandSeparator}get uomSeparator(){return this._uomSeparator}get stationSeparator(){return this._stationSeparator}get stationOffsetSize(){return this._stationOffsetSize}get formatTraits(){return this._formatTraits}get spacer(){return this._spacer}get includeZero(){return this._includeZero}get units(){return this._units}get hasUnits(){return void 0!==this._units&&this._units.length>0}static scientificTypeToString(t){return t===n.ScientificType.Normalized?"Normalized":"ZeroNormalized"}static parseScientificType(t,e){switch(t){case"normalized":return n.ScientificType.Normalized;case"zeronormalized":return n.ScientificType.ZeroNormalized;default:throw new i.QuantityError(i.QuantityStatus.InvalidJson,`The Format ${e} has an invalid 'SCIENTIFIC_TYPE' attribute.`)}}static showSignOptionToString(t){switch(t){case n.ShowSignOption.NegativeParentheses:return"NegativeParentheses";case n.ShowSignOption.NoSign:return"NoSign";case n.ShowSignOption.OnlyNegative:return"OnlyNegative";case n.ShowSignOption.SignAlways:return"SignAlways"}}static parseShowSignOption(t,e){switch(t.toLowerCase()){case"nosign":return n.ShowSignOption.NoSign;case"onlynegative":return n.ShowSignOption.OnlyNegative;case"signalways":return n.ShowSignOption.SignAlways;case"negativeparentheses":return n.ShowSignOption.NegativeParentheses;default:throw new i.QuantityError(i.QuantityStatus.InvalidJson,`The Format ${e} has an invalid 'showSignOption' attribute.`)}}static formatTraitsToArray(t){const e=Array();return(t&n.FormatTraits.TrailZeroes)===n.FormatTraits.TrailZeroes&&e.push("trailZeroes"),(t&n.FormatTraits.KeepSingleZero)===n.FormatTraits.KeepSingleZero&&e.push("keepSingleZero"),(t&n.FormatTraits.ZeroEmpty)===n.FormatTraits.ZeroEmpty&&e.push("zeroEmpty"),(t&n.FormatTraits.KeepDecimalPoint)===n.FormatTraits.KeepDecimalPoint&&e.push("keepDecimalPoint"),(t&n.FormatTraits.ApplyRounding)===n.FormatTraits.ApplyRounding&&e.push("applyRounding"),(t&n.FormatTraits.FractionDash)===n.FormatTraits.FractionDash&&e.push("fractionDash"),(t&n.FormatTraits.ShowUnitLabel)===n.FormatTraits.ShowUnitLabel&&e.push("showUnitLabel"),(t&n.FormatTraits.PrependUnitLabel)===n.FormatTraits.PrependUnitLabel&&e.push("prependUnitLabel"),(t&n.FormatTraits.Use1000Separator)===n.FormatTraits.Use1000Separator&&e.push("use1000Separator"),(t&n.FormatTraits.ExponentOnlyNegative)===n.FormatTraits.ExponentOnlyNegative&&e.push("exponentOnlyNegative"),e}static parseFormatTrait(t,e){let a=e;switch(t.toLowerCase()){case"trailzeroes":a=e|n.FormatTraits.TrailZeroes;break;case"keepsinglezero":a=e|n.FormatTraits.KeepSingleZero;break;case"zeroempty":a=e|n.FormatTraits.ZeroEmpty;break;case"keepdecimalpoint":a=e|n.FormatTraits.KeepDecimalPoint;break;case"applyrounding":a=e|n.FormatTraits.ApplyRounding;break;case"fractiondash":a=e|n.FormatTraits.FractionDash;break;case"showunitlabel":a=e|n.FormatTraits.ShowUnitLabel;break;case"prependunitlabel":a=e|n.FormatTraits.PrependUnitLabel;break;case"use1000separator":a=e|n.FormatTraits.Use1000Separator;break;case"exponentonlynegative":a=e|n.FormatTraits.ExponentOnlyNegative;break;default:throw new i.QuantityError(i.QuantityStatus.InvalidJson,"Format has an invalid 'formatTraits' option.")}return a}static formatTypeToString(t){switch(t){case n.FormatType.Decimal:return"Decimal";case n.FormatType.Scientific:return"Scientific";case n.FormatType.Station:return"Station";case n.FormatType.Fractional:return"Fractional"}}static parseFormatType(t,e){switch(t.toLowerCase()){case"decimal":return n.FormatType.Decimal;case"scientific":return n.FormatType.Scientific;case"station":return n.FormatType.Station;case"fractional":return n.FormatType.Fractional;default:throw new i.QuantityError(i.QuantityStatus.InvalidJson,`The Format ${e} has an invalid 'type' attribute.`)}}static parseDecimalPrecision(t){switch(t){case 0:return n.DecimalPrecision.Zero;case 1:return n.DecimalPrecision.One;case 2:return n.DecimalPrecision.Two;case 3:return n.DecimalPrecision.Three;case 4:return n.DecimalPrecision.Four;case 5:return n.DecimalPrecision.Five;case 6:return n.DecimalPrecision.Six;case 7:return n.DecimalPrecision.Seven;case 8:return n.DecimalPrecision.Eight;case 9:return n.DecimalPrecision.Nine;case 10:return n.DecimalPrecision.Ten;case 11:return n.DecimalPrecision.Eleven;case 12:return n.DecimalPrecision.Twelve;default:throw new i.QuantityError(i.QuantityStatus.InvalidJson,"The 'precision' attribute must be an integer in the range 0-12.")}}static parseFractionalPrecision(t,e){switch(t){case 1:return n.FractionalPrecision.One;case 2:return n.FractionalPrecision.Two;case 4:return n.FractionalPrecision.Four;case 8:return n.FractionalPrecision.Eight;case 16:return n.FractionalPrecision.Sixteen;case 32:return n.FractionalPrecision.ThirtyTwo;case 64:return n.FractionalPrecision.SixtyFour;case 128:return n.FractionalPrecision.OneHundredTwentyEight;case 256:return n.FractionalPrecision.TwoHundredFiftySix;default:throw new i.QuantityError(i.QuantityStatus.InvalidJson,`The Format ${e} has an invalid 'precision' attribute.`)}}static parsePrecision(t,e,a){switch(a){case n.FormatType.Decimal:case n.FormatType.Scientific:case n.FormatType.Station:return Format.parseDecimalPrecision(t);case n.FormatType.Fractional:return Format.parseFractionalPrecision(t,e)}}verifyFormatTraitsOptions(t){(Array.isArray(t)?t:t.split(/,|;|\|/)).forEach(t=>{this._formatTraits=Format.parseFormatTrait(t,this.formatTraits)})}hasFormatTraitSet(t){return(this._formatTraits&t)===t}async createUnit(t,e,a){let r;if(void 0===e||"string"!==typeof e||void 0!==a&&"string"!==typeof a)return Promise.reject(new i.QuantityError(i.QuantityStatus.InvalidJson,"This Composite has a unit with an invalid 'name' or 'label' attribute."));for(const n of this.units){const t=n[0].name;if(t.toLowerCase()===e.toLowerCase())return Promise.reject(new i.QuantityError(i.QuantityStatus.InvalidJson,`The unit ${t} has a duplicate name.`))}if(!(r=await t.findUnit(e))||!r.isValid)return Promise.reject(new i.QuantityError(i.QuantityStatus.InvalidJson,`Invalid unit name '${e}'.`));this.units.push([r,a])}loadFormatProperties(t){if(void 0===t.type)throw new i.QuantityError(i.QuantityStatus.InvalidJson,`The Format ${this.name} does not have the required 'type' attribute.`);if("string"!==typeof t.type)throw new i.QuantityError(i.QuantityStatus.InvalidJson,`The Format ${this.name} has an invalid 'type' attribute. It should be of type 'string'.`);if(this._type=Format.parseFormatType(t.type,this.name),void 0===t.precision)throw new i.QuantityError(i.QuantityStatus.InvalidJson,`The Format ${this.name} does not have the required 'precision' attribute.`);if("number"!==typeof t.precision)throw new i.QuantityError(i.QuantityStatus.InvalidJson,`The Format ${this.name} has an invalid 'precision' attribute. It should be of type 'number'.`);if(!Number.isInteger(t.precision))throw new i.QuantityError(i.QuantityStatus.InvalidJson,`The Format ${this.name} has an invalid 'precision' attribute. It should be an integer.`);if(this._precision=Format.parsePrecision(t.precision,this.name,this._type),this.type===n.FormatType.Scientific){if(void 0===t.scientificType)throw new i.QuantityError(i.QuantityStatus.InvalidJson,`The Format ${this.name} has type 'Scientific' therefore attribute 'scientificType' is required.`);if("string"!==typeof t.scientificType)throw new i.QuantityError(i.QuantityStatus.InvalidJson,`The Format ${this.name} has an invalid 'scientificType' attribute. It should be of type 'string'.`);this._scientificType=Format.parseScientificType(t.scientificType.toLowerCase(),this.name)}if(this.type===n.FormatType.Station){if(void 0===t.stationOffsetSize)throw new i.QuantityError(i.QuantityStatus.InvalidJson,`The Format ${this.name} has type 'Station' therefore attribute 'stationOffsetSize' is required.`);if("number"!==typeof t.stationOffsetSize)throw new i.QuantityError(i.QuantityStatus.InvalidJson,`The Format ${this.name} has an invalid 'stationOffsetSize' attribute. It should be of type 'number'.`);if(!Number.isInteger(t.stationOffsetSize)||t.stationOffsetSize<=0)throw new i.QuantityError(i.QuantityStatus.InvalidJson,`The Format ${this.name} has an invalid 'stationOffsetSize' attribute. It should be a positive integer.`);this._stationOffsetSize=t.stationOffsetSize}if(void 0!==t.roundFactor){if("number"!==typeof t.roundFactor)throw new i.QuantityError(i.QuantityStatus.InvalidJson,`The Format ${this.name} has an invalid 'roundFactor' attribute. It should be of type 'number'.`);t.roundFactor!==this.roundFactor&&(this._roundFactor=t.roundFactor)}if(void 0!==t.minWidth){if("number"!==typeof t.minWidth)throw new i.QuantityError(i.QuantityStatus.InvalidJson,`The Format ${this.name} has an invalid 'minWidth' attribute. It should be of type 'number'.`);if(!Number.isInteger(t.minWidth)||t.minWidth<0)throw new i.QuantityError(i.QuantityStatus.InvalidJson,`The Format ${this.name} has an invalid 'minWidth' attribute. It should be a positive integer.`);this._minWidth=t.minWidth}if(void 0!==t.showSignOption){if("string"!==typeof t.showSignOption)throw new i.QuantityError(i.QuantityStatus.InvalidJson,`The Format ${this.name} has an invalid 'showSignOption' attribute. It should be of type 'string'.`);this._showSignOption=Format.parseShowSignOption(t.showSignOption,this.name)}if(void 0!==t.formatTraits&&0!==t.formatTraits.length){if(!Array.isArray(t.formatTraits)&&"string"!==typeof t.formatTraits)throw new i.QuantityError(i.QuantityStatus.InvalidJson,`The Format ${this.name} has an invalid 'formatTraits' attribute. It should be of type 'string' or 'string[]'.`);this.verifyFormatTraitsOptions(t.formatTraits)}if(void 0!==t.decimalSeparator){if("string"!==typeof t.decimalSeparator)throw new i.QuantityError(i.QuantityStatus.InvalidJson,`The Format ${this.name} has an invalid 'decimalSeparator' attribute. It should be of type 'string'.`);if(1!==t.decimalSeparator.length)throw new i.QuantityError(i.QuantityStatus.InvalidJson,`The Format ${this.name} has an invalid 'decimalSeparator' attribute. It must be a one character string.`);this._decimalSeparator=t.decimalSeparator}if(void 0!==t.thousandSeparator){if("string"!==typeof t.thousandSeparator)throw new i.QuantityError(i.QuantityStatus.InvalidJson,`The Format ${this.name} has an invalid 'thousandSeparator' attribute. It should be of type 'string'.`);if(1!==t.thousandSeparator.length)throw new i.QuantityError(i.QuantityStatus.InvalidJson,`The Format ${this.name} has an invalid 'thousandSeparator' attribute. It must be a one character string.`);this._thousandSeparator=t.thousandSeparator}if(void 0!==t.uomSeparator){if("string"!==typeof t.uomSeparator)throw new i.QuantityError(i.QuantityStatus.InvalidJson,`The Format ${this.name} has an invalid 'uomSeparator' attribute. It should be of type 'string'.`);if(t.uomSeparator.length<0||t.uomSeparator.length>1)throw new i.QuantityError(i.QuantityStatus.InvalidJson,`The Format ${this.name} has an invalid 'uomSeparator' attribute. It must be empty or a string with a single character.`);this._uomSeparator=t.uomSeparator}if(void 0!==t.stationSeparator){if("string"!==typeof t.stationSeparator)throw new i.QuantityError(i.QuantityStatus.InvalidJson,`The Format ${this.name} has an invalid 'stationSeparator' attribute. It should be of type 'string'.`);if(1!==t.stationSeparator.length)throw new i.QuantityError(i.QuantityStatus.InvalidJson,`The Format ${this.name} has an invalid 'stationSeparator' attribute. It must be a one character string.`);this._stationSeparator=t.stationSeparator}}async fromJson(t,e){if(this.loadFormatProperties(e),void 0!==e.composite){if(this._units=new Array,void 0!==e.composite.includeZero){if("boolean"!==typeof e.composite.includeZero)return Promise.reject(new i.QuantityError(i.QuantityStatus.InvalidJson,`The Format ${this.name} has a Composite with an invalid 'includeZero' attribute. It should be of type 'boolean'.`));this._includeZero=e.composite.includeZero}if(void 0!==e.composite.spacer){if("string"!==typeof e.composite.spacer)return Promise.reject(new i.QuantityError(i.QuantityStatus.InvalidJson,`The Format ${this.name} has a Composite with an invalid 'spacer' attribute. It must be of type 'string'.`));if(e.composite.spacer.length<0||e.composite.spacer.length>1)return Promise.reject(new i.QuantityError(i.QuantityStatus.InvalidJson,`The Format ${this.name} has a Composite with an invalid 'spacer' attribute. It must be empty or a string with a single character.`));this._spacer=e.composite.spacer}if(void 0!==e.composite.units){if(!Array.isArray(e.composite.units))return Promise.reject(new i.QuantityError(i.QuantityStatus.InvalidJson,`The Format ${this.name} has a Composite with an invalid 'units' attribute. It must be of type 'array'`));if(e.composite.units.length>0&&e.composite.units.length<=4)try{const a=[];for(const i of e.composite.units)a.push(this.createUnit(t,i.name,i.label));await Promise.all(a)}catch(t){return Promise.reject(t)}}if(void 0===this.units||0===this.units.length)return Promise.reject(new i.QuantityError(i.QuantityStatus.InvalidJson,`The Format ${this.name} has a Composite with no valid 'units'`))}}toJson(){const t={};if(t.type=Format.formatTypeToString(this.type),t.precision=this.precision,t.roundFactor=this.roundFactor,void 0!==this.minWidth&&(t.minWidth=this.minWidth),t.showSignOption=Format.showSignOptionToString(this.showSignOption),t.formatTraits=Format.formatTraitsToArray(this.formatTraits),t.decimalSeparator=this.decimalSeparator,t.thousandSeparator=this.thousandSeparator,t.uomSeparator=this.uomSeparator,void 0!==this.scientificType&&(t.scientificType=Format.scientificTypeToString(this.scientificType)),void 0!==this.stationOffsetSize&&(t.stationOffsetSize=this.stationOffsetSize),t.stationSeparator=this.stationSeparator,void 0!==this.units){const e={};e.spacer=this.spacer,e.includeZero=this.includeZero,e.units=[],this.units.forEach(t=>{void 0!==t[1]?e.units.push({name:t[0].name,label:t[1]}):e.units.push({name:t[0].name})}),t.composite=e}return t}}e.Format=Format;class FormatterSpec{constructor(t,e,a){this._name="",this._conversions=[],this._name=t,this._format=e,a&&(this._conversions=a)}get name(){return this._name}get unitConversions(){return this._conversions}get format(){return this._format}static async create(t,e,a,i){const r=[];if(e.units){let t=i;for(const i of e.units){let e;e=t?await a.getConversion(t,i[0]):{factor:1,offset:0};const n=i[1]&&i[1].length>0?i[1]:i[0].label,o={name:i[0].name,label:n,conversion:e};r.push(o),t=i[0]}}else if(i){const t={name:i.name,label:i.label,conversion:{factor:1,offset:0}};r.push(t)}return Promise.resolve(new FormatterSpec(t,e,r))}}e.FormatterSpec=FormatterSpec},"./lib/Formatter/FormatEnums.js":function(t,e,a){"use strict";Object.defineProperty(e,"__esModule",{value:!0}),function(t){t[t.TrailZeroes=1]="TrailZeroes",t[t.KeepSingleZero=2]="KeepSingleZero",t[t.ZeroEmpty=4]="ZeroEmpty",t[t.KeepDecimalPoint=8]="KeepDecimalPoint",t[t.ApplyRounding=16]="ApplyRounding",t[t.FractionDash=32]="FractionDash",t[t.ShowUnitLabel=64]="ShowUnitLabel",t[t.PrependUnitLabel=128]="PrependUnitLabel",t[t.Use1000Separator=256]="Use1000Separator",t[t.ExponentOnlyNegative=512]="ExponentOnlyNegative"}(e.FormatTraits||(e.FormatTraits={})),function(t){t[t.One=1]="One",t[t.Two=2]="Two",t[t.Four=4]="Four",t[t.Eight=8]="Eight",t[t.Sixteen=16]="Sixteen",t[t.ThirtyTwo=32]="ThirtyTwo",t[t.SixtyFour=64]="SixtyFour",t[t.OneHundredTwentyEight=128]="OneHundredTwentyEight",t[t.TwoHundredFiftySix=256]="TwoHundredFiftySix"}(e.FractionalPrecision||(e.FractionalPrecision={})),function(t){t[t.Zero=0]="Zero",t[t.One=1]="One",t[t.Two=2]="Two",t[t.Three=3]="Three",t[t.Four=4]="Four",t[t.Five=5]="Five",t[t.Six=6]="Six",t[t.Seven=7]="Seven",t[t.Eight=8]="Eight",t[t.Nine=9]="Nine",t[t.Ten=10]="Ten",t[t.Eleven=11]="Eleven",t[t.Twelve=12]="Twelve"}(e.DecimalPrecision||(e.DecimalPrecision={})),function(t){t[t.Decimal=0]="Decimal",t[t.Fractional=1]="Fractional",t[t.Scientific=2]="Scientific",t[t.Station=3]="Station"}(e.FormatType||(e.FormatType={})),function(t){t[t.Normalized=0]="Normalized",t[t.ZeroNormalized=1]="ZeroNormalized"}(e.ScientificType||(e.ScientificType={})),function(t){t[t.NoSign=0]="NoSign",t[t.OnlyNegative=1]="OnlyNegative",t[t.SignAlways=2]="SignAlways",t[t.NegativeParentheses=3]="NegativeParentheses"}(e.ShowSignOption||(e.ShowSignOption={}))},"./lib/Formatter/Formatter.js":function(t,e,a){"use strict";Object.defineProperty(e,"__esModule",{value:!0});const i=a("./lib/Constants.js"),r=a("./lib/Exception.js"),n=a("./lib/Formatter/FormatEnums.js"),o=.50000000001;class FractionalNumeric{constructor(t,e,a){this._integral=0,this._numerator=0,this._denominator=1,this._greatestCommonFactor=1,this._textParts=[],this.calculate(t,e),this.formTextParts(a)}calculate(t,e){const a=Math.abs(t);this._denominator=e,this._integral=Math.floor(a);const i=a-this._integral;this._numerator=Math.floor(i*this._denominator+o),0!==e&&this._numerator/this._denominator===1?(this._numerator=0,this._integral+=1):this._greatestCommonFactor=this.getGreatestCommonFactor(this._numerator,this._denominator)}getGreatestCommonFactor(t,e){let a;for(;0!==e;)a=t%e,t=e,e=a;return t<0?-t:t}get greatestCommonFactor(){return this._greatestCommonFactor}get hasFractionPart(){return this._textParts.length>0}get isZero(){return 0===this._numerator}getIntegralString(){return this._textParts.length>0?this._textParts[0]:""}getNumeratorString(){return this._textParts.length>=3?this._textParts[1]:""}getDenominatorString(){return this._textParts.length>=3?this._textParts[2]:""}formTextParts(t){let e=this._numerator,a=this._denominator;t&&this._greatestCommonFactor>1&&(e/=this.greatestCommonFactor,a/=this.greatestCommonFactor),this._textParts.push(this._integral.toFixed(0)),e>0&&(this._textParts.push(e.toFixed(0)),this._textParts.push(a.toFixed(0)))}}class Formatter{static isNegligible(t){return Math.abs(t)<Formatter.FPV_MINTHRESHOLD}static roundDouble(t,e){if(Formatter.isNegligible(e))return t;e=Math.abs(e);let a=o+t/e;return a=Math.floor(a)*e,t<0?-a:a}static integerPartToText(t,e){let a=t.toFixed(0);if(a.length>3&&e.format.hasFormatTraitSet(n.FormatTraits.Use1000Separator)&&e.format.thousandSeparator.length>0){let t=Math.floor(a.length/3),i=a.length%3;0===i&&(t-=1,i+=3);let r=a.substr(0,i);for(let n=1;n<=t;n+=1)r=r+e.format.thousandSeparator+a.substr(i,3),i+=3;a=r}return a}static trimTrailingZeroes(t){let e=-1;for(let a=t.length-1;a>=0;a--)if(t.charCodeAt(a)!==i.QuantityConstants.CHAR_DIGIT_ZERO){e=a;break}return e>=0?t.substr(0,e+1):""}static formatCompositePart(t,e,a,i){let r="";return r=e?Formatter.formatMagnitude(t,i):Formatter.integerPartToText(t,i),i.format.hasFormatTraitSet(n.FormatTraits.ShowUnitLabel)?r=r+i.format.uomSeparator+a:e||(r+=":"),r}static formatComposite(t,e){const a=[];let i=Math.abs(t);if(Math.abs(i)<1e-4&&e.format.hasFormatTraitSet(n.FormatTraits.ZeroEmpty))return"";for(let n=0;n<e.unitConversions.length;n++){const t=e.unitConversions[n].label,o=e.unitConversions[n].conversion;if(o.factor<1)throw new r.QuantityError(r.QuantityStatus.InvalidCompositeFormat,`The Format ${e.format.name} has a invalid unit specification..`);if(n>0&&0!==o.offset)throw new r.QuantityError(r.QuantityStatus.InvalidCompositeFormat,`The Format ${e.format.name} has a invalid unit specification..`);const s=i*o.factor+o.offset+Formatter.FPV_MINTHRESHOLD;if(n<e.format.units.length-1){const r=Math.floor(s),n=Formatter.formatCompositePart(r,!1,t,e);i=s-r,a.push(n)}else{const i=Formatter.formatCompositePart(s,!0,t,e);a.push(i)}}return a.join(e.format.spacer?e.format.spacer:"")}static formatMagnitude(t,e){let a=Math.abs(t);if(Math.abs(a)<1e-4&&e.format.hasFormatTraitSet(n.FormatTraits.ZeroEmpty))return"";e.format.hasFormatTraitSet(n.FormatTraits.ApplyRounding)&&(a=Math.abs(Formatter.roundDouble(t,e.format.roundFactor)));const i=a>1e12||e.format.type===n.FormatType.Scientific,r=i||e.format.type===n.FormatType.Decimal,s=!r&&e.format.type===n.FormatType.Fractional,u=e.format.precision===n.DecimalPrecision.Zero,c=e.format.hasFormatTraitSet(n.FormatTraits.KeepSingleZero),l=Math.pow(10,e.format.precision),h=e.format.hasFormatTraitSet(n.FormatTraits.TrailZeroes);let m=0;if(i&&0!==a){let t=Math.log10(a),i=!1;t<0&&(t=-t,i=!0),m=Math.floor(t),e.format.type===n.FormatType.Scientific&&(e.format.scientificType===n.ScientificType.ZeroNormalized&&a>1?m+=1:e.format.scientificType===n.ScientificType.Normalized&&a<1&&(m+=1),i&&(m=-m)),a*=Math.pow(10,-m)}let p="";if(r){const t=u?a+o:a+Formatter.FPV_MINTHRESHOLD;let r=Math.floor(t),s=t-r;if(u||(s=Math.abs(s)*l+o)>=l&&(r+=1,s-=l),p=Formatter.integerPartToText(r,e),u)c&&(p=p+e.format.decimalSeparator+"0");else{let t=(s=Math.floor(s)/l).toFixed(e.format.precision);t=t.substr(2).padEnd(e.format.precision,"0"),h||(t=Formatter.trimTrailingZeroes(t)),t.length>0?p=p+e.format.decimalSeparator+t:e.format.hasFormatTraitSet(n.FormatTraits.KeepDecimalPoint)&&(p+=e.format.decimalSeparator)}if(i){p+="e"+m.toFixed(0)}}else if(s){const t=new FractionalNumeric(a,e.format.precision,!0);if(p=t.getIntegralString(),!t.isZero&&t.hasFractionPart){p=p+(e.format.hasFormatTraitSet(n.FormatTraits.FractionDash)?"-":" ")+(t.getNumeratorString()+"/"+t.getDenominatorString())}}else{const t=Math.pow(10,e.format.stationOffsetSize),i=Math.floor(a),r=Math.floor(i/t),o=i-r*t,s=a-i,u=Math.floor(.5+s*l),c=r.toFixed(0)+e.format.stationSeparator+o.toFixed(0).padStart(e.format.stationOffsetSize,"0");let m="";u>0?(m=u.toFixed(0).padEnd(e.format.precision,"0"),h||(m=Formatter.trimTrailingZeroes(m)),p=c+e.format.decimalSeparator+m):(h?m=e.format.decimalSeparator+"".padEnd(e.format.precision,"0"):e.format.hasFormatTraitSet(n.FormatTraits.KeepDecimalPoint)&&(m=e.format.decimalSeparator),p=c+m)}return p}static formatQuantity(t,e){const a=t<0;let i="",r="",o="";switch(e.format.showSignOption){case n.ShowSignOption.NegativeParentheses:a&&(i="(",r=")");break;case n.ShowSignOption.OnlyNegative:a&&(i="-");break;case n.ShowSignOption.SignAlways:i=a?"-":"+";break;case n.ShowSignOption.NoSign:}let s="";return e.format.hasUnits?s=Formatter.formatComposite(t,e):(s=Formatter.formatMagnitude(t,e)).length>0&&e.unitConversions.length>0&&e.format.hasFormatTraitSet(n.FormatTraits.ShowUnitLabel)&&(s=e.format.hasFormatTraitSet(n.FormatTraits.PrependUnitLabel)?e.unitConversions[0].label+e.format.uomSeparator+s:s+e.format.uomSeparator+e.unitConversions[0].label),o=(i.length>0||r.length>0)&&s.length>0?i+s+r:s,e.format.minWidth&&e.format.minWidth<o.length&&o.padStart(e.format.minWidth," "),o}}Formatter.FPV_MINTHRESHOLD=1e-14,e.Formatter=Formatter},"./lib/Parser.js":function(t,e,a){"use strict";Object.defineProperty(e,"__esModule",{value:!0});const i=a("./lib/Exception.js"),r=a("./lib/Constants.js"),n=a("./lib/Quantity.js"),o=a("./lib/Formatter/FormatEnums.js");class ParserSpec{constructor(t,e,a){this._conversions=[],this._outUnit=t,this._format=e,this._conversions=a}get unitConversions(){return this._conversions}get format(){return this._format}get outUnit(){return this._outUnit}static async create(t,e,a){const i=await Parser.createUnitConversionSpecsForUnit(e,a);return Promise.resolve(new ParserSpec(a,t,i))}}e.ParserSpec=ParserSpec;class ParseToken{constructor(t){this.value="string"===typeof t?t.trim():t}get isString(){return"string"===typeof this.value}get isNumber(){return"number"===typeof this.value}}class ScientificToken{constructor(t,e){this.exponent="",this.index=t,e&&(this.exponent=e)}}class FractionToken{constructor(t,e){this.fraction=0,this.exponent="",this.index=t,e&&(this.fraction=e)}}class Parser{static checkForScientificNotation(t,e,a){let i="",n=t+1;for(;n<e.length;n++){const o=e.charCodeAt(n);if(!Parser.isDigit(o)&&(o!==r.QuantityConstants.CHAR_MINUS&&o!==r.QuantityConstants.CHAR_PLUS||n!==t+1)){n=a===o?n:n-1;break}i=i.concat(e[n])}return i.length>1||1===i.length&&i.charCodeAt(0)!==r.QuantityConstants.CHAR_MINUS&&i.charCodeAt(0)!==r.QuantityConstants.CHAR_PLUS?new ScientificToken(n,i):new ScientificToken(t)}static checkForFractions(t,e,a,i){let n="",o="",s=!0,u=t;for(i&&i.length>0&&(n=i,s=!1);u<e.length;u++){const t=e.charCodeAt(u);if(Parser.isDigit(t))s?n=n.concat(e[u]):o=o.concat(e[u]);else{if(!s||t!==r.QuantityConstants.CHAR_SLASH&&t!==r.QuantityConstants.CHAR_DIVISION_SLASH&&t!==r.QuantityConstants.CHAR_DIVISION_SLASH){a!==t&&(u-=1);break}s=!1}}if(n.length>0&&o.length>0){const t=parseInt(n,10),e=parseInt(o,10);return e>0?new FractionToken(u,t/e):new FractionToken(u)}return new FractionToken(t+1)}static isDigit(t){return t>=r.QuantityConstants.CHAR_DIGIT_ZERO&&t<=r.QuantityConstants.CHAR_DIGIT_NINE}static isDigitOrDecimalSeparator(t,e){return t===e.decimalSeparator.charCodeAt(0)||Parser.isDigit(t)}static parseQuantitySpecification(t,e){const a=[],i=t.trim();let n=!1,s="",u="",c=0,l=0;const h=[e.thousandSeparator.charCodeAt(0)];e.type===o.FormatType.Station&&e.stationSeparator&&1===e.stationSeparator.length&&h.push(e.stationSeparator.charCodeAt(0)),e.type===o.FormatType.Fractional&&e.hasFormatTraitSet(o.FormatTraits.FractionDash)&&(l=r.QuantityConstants.CHAR_MINUS),e.uomSeparator&&" "!==e.uomSeparator&&1===e.uomSeparator.length&&(c=e.uomSeparator.charCodeAt(0),h.push(c));for(let o=0;o<i.length;o++){const t=i.charCodeAt(o);if(Parser.isDigitOrDecimalSeparator(t,e))n||(s.length>0&&(a.push(new ParseToken(s)),s=""),n=!0),s=s.concat(i[o]);else if(n){if(t===r.QuantityConstants.CHAR_SLASH||t===r.QuantityConstants.CHAR_FRACTION_SLASH||t===r.QuantityConstants.CHAR_DIVISION_SLASH){const t=Parser.checkForFractions(o+1,i,c,s);let e=t.fraction;if(o=t.index,0!==t.fraction){s="",u.length>0&&("-"===u&&(e=0-e),u=""),a.push(new ParseToken(e)),n=!1;continue}}else{if(t===r.QuantityConstants.CHAR_SPACE||t===l){const t=Parser.checkForFractions(o+1,i,c);let e=t.fraction;if(0!==t.fraction){o=t.index,u.length>0&&(s=u+s,"-"===u&&(e=0-e),u="");const i=parseFloat(s)+e;a.push(new ParseToken(i)),n=!1,s=""}continue}if(t===r.QuantityConstants.CHAR_UPPER_E||t===r.QuantityConstants.CHAR_LOWER_E){const t=Parser.checkForScientificNotation(o,i,c);if(o=t.index,t.exponent&&t.exponent.length>0){u.length>0&&(s=u+s,u=""),s=s+"e"+t.exponent;const e=Number(s);a.push(new ParseToken(e)),n=!1,s="";continue}}}if(-1!==h.findIndex(e=>e===t))continue;u.length>0&&(s=u+s,u=""),a.push(new ParseToken(parseFloat(s))),s=o<i.length?i[o]:"",n=!1}else{if(t===r.QuantityConstants.CHAR_PLUS||t===r.QuantityConstants.CHAR_MINUS){u=i[o];continue}s=s.concat(i[o])}}return s.length>0&&(n?(u.length>0&&(s=u+s,u=""),a.push(new ParseToken(parseFloat(s))),n=!1):a.push(new ParseToken(s))),a}static async createQuantityFromParseTokens(t,e,a){const i=e.units&&e.units.length>0?e.units[0][0]:void 0;if(1===t.length){if(t[0].isNumber)return Promise.resolve(new n.Quantity(i,t[0].value));try{const e=await a.findUnit(t[0].value,i?i.unitFamily:void 0);return Promise.resolve(new n.Quantity(e))}catch(t){}}if(2===t.length){if(t[0].isNumber&&t[1].isString){const e=await a.findUnit(t[1].value,i?i.unitFamily:void 0);return Promise.resolve(new n.Quantity(e,t[0].value))}if(t[1].isNumber&&t[0].isString){const e=await a.findUnit(t[0].value,i?i.unitFamily:void 0);return Promise.resolve(new n.Quantity(e,t[1].value))}}if(t.length%2===0){let e=0,r=i;for(let n=0;n<t.length;n+=2)if(t[n].isNumber&&t[n+1].isString){const o=t[n].value,s=await a.findUnit(t[n+1].value,i?i.unitFamily:void 0);if(0===n)r=s,e+=o;else if(r){const t=await a.getConversion(s,r);e=e<0?e-o*t.factor+t.offset:e+o*t.factor+t.offset}}return Promise.resolve(new n.Quantity(r,e))}return Promise.resolve(new n.Quantity(i))}static async parseIntoQuantity(t,e,a){const i=Parser.parseQuantitySpecification(t,e);return 0===i.length?Promise.resolve(new n.Quantity):Parser.createQuantityFromParseTokens(i,e,a)}static tryFindUnitConversion(t,e){if(e.length>0){const a=t.toLocaleLowerCase();for(const t of e)if(t.parseLabels){if(-1!==t.parseLabels.findIndex(t=>t===a))return t.conversion}else console.log("ERROR: Parser expects to find parseLabels array populate with all possible unit labels for the unit.")}}static getQuantityValueFromParseTokens(t,e,a){const r=e.units&&e.units.length>0?e.units[0][0]:void 0;if(1===t.length){if(t[0].isNumber){if(r){const e=Parser.tryFindUnitConversion(r.label,a);if(e){return{value:t[0].value*e.factor+e.offset,status:i.QuantityStatus.Success}}}return{value:t[0].value,status:i.QuantityStatus.UnknownUnit}}{const e=Parser.tryFindUnitConversion(t[0].value,a);return void 0!==e?{value:e.factor+e.offset,status:i.QuantityStatus.Success}:{status:i.QuantityStatus.NoValueOrUnitFoundInString}}}if(2===t.length){if(t[0].isNumber&&t[1].isString){const e=Parser.tryFindUnitConversion(t[1].value,a);if(e){return{value:t[0].value*e.factor+e.offset,status:i.QuantityStatus.Success}}return{value:t[0].value,status:i.QuantityStatus.UnitLabelSuppliedButNotMatched}}if(t[1].isNumber&&t[0].isString){const e=Parser.tryFindUnitConversion(t[0].value,a);if(e){return{value:t[1].value*e.factor+e.offset,status:i.QuantityStatus.Success}}return{value:t[1].value,status:i.QuantityStatus.UnitLabelSuppliedButNotMatched}}}if(t.length%2===0){let e=0;for(let i=0;i<t.length;i+=2)if(t[i].isNumber&&t[i+1].isString){const r=t[i].value,n=Parser.tryFindUnitConversion(t[i+1].value,a);n&&(e=e<0?e-r*n.factor+n.offset:e+r*n.factor+n.offset)}return{value:e,status:i.QuantityStatus.Success}}return{status:i.QuantityStatus.UnableToConvertParseTokensToQuantity}}static parseQuantityString(t,e){return Parser.parseIntoQuantityValue(t,e.format,e.unitConversions)}static parseIntoQuantityValue(t,e,a){const r=Parser.parseQuantitySpecification(t,e);if(0===r.length)return{status:i.QuantityStatus.UnableToGenerateParseTokens};if(Parser._log){console.log("Parse tokens");let t=0;for(const e of r)console.log(` [${t++}] isNumber=${e.isNumber} isString=${e.isString} token=${e.value}`)}return Parser.getQuantityValueFromParseTokens(r,e,a)}static async createUnitConversionSpecsForUnit(t,e){const a=[],i=await t.getUnitsByFamily(e.unitFamily);for(const r of i){const i=await t.getConversion(r,e),n=[r.label.toLocaleLowerCase()];r.alternateLabels&&r.alternateLabels.forEach(t=>{const e=t.toLocaleLowerCase();-1===n.findIndex(t=>t===e)&&n.push(t.toLocaleLowerCase())}),a.push({name:r.name,label:r.label,conversion:i,parseLabels:n})}return Promise.resolve(a)}static async createUnitConversionSpecs(t,e,a){const i=[],r=await t.findUnitByName(e);if(!r||!r.name||0===r.name.length)return console.log(`[Parser.createUnitConversionSpecs] ERROR: Unable to locate out unit ${e}.`),Promise.resolve(i);for(const n of a){const e=await t.findUnitByName(n.unitName);if(!e||!e.name||0===e.name.length){console.log(`[Parser.createUnitConversionSpecs] ERROR: Unable to locate potential unit ${n.unitName}.`);continue}const a=await t.getConversion(e,r),o=[e.label.toLocaleLowerCase()];e.alternateLabels&&e.alternateLabels.forEach(t=>{const e=t.toLocaleLowerCase();-1===o.findIndex(t=>t===e)&&o.push(t.toLocaleLowerCase())}),n.altLabels&&n.altLabels.forEach(t=>{const e=t.toLocaleLowerCase();-1===o.findIndex(t=>t===e)&&o.push(t.toLocaleLowerCase())}),i.push({name:e.name,label:e.label,conversion:a,parseLabels:o})}return Promise.resolve(i)}}Parser._log=!1,e.Parser=Parser},"./lib/Quantity.js":function(t,e,a){"use strict";Object.defineProperty(e,"__esModule",{value:!0});class Quantity{constructor(t,e){this._magnitude=0,this._isValid=!1,void 0!==t?(this._unit=t,this._isValid=!0):this._unit={name:"unknown",label:"unknown",unitFamily:"unknown",isValid:!1},void 0!==e&&(this._magnitude=e)}get unit(){return this._unit}get magnitude(){return this._magnitude}get isValid(){return this._isValid}convertTo(t,e){const a=this.magnitude*e.factor+e.offset;return new Quantity(t,a)}}e.Quantity=Quantity},"./lib/Unit.js":function(t,e,a){"use strict";Object.defineProperty(e,"__esModule",{value:!0});e.BasicUnit=class BasicUnit{constructor(t,e,a,i){this.name="",this.label="",this.unitFamily="",this.isValid=!1,t&&t.length>0&&e&&e.length>0&&a&&a.length>0&&(this.name=t,this.label=e,this.unitFamily=a,this.alternateLabels=i,this.isValid=!0)}};e.BadUnit=class BadUnit{constructor(){this.name="",this.label="",this.unitFamily="",this.isValid=!1}}},"./lib/imodeljs-quantity.js":function(t,e,a){"use strict";function i(t){for(var a in t)e.hasOwnProperty(a)||(e[a]=t[a])}Object.defineProperty(e,"__esModule",{value:!0}),i(a("./lib/Constants.js")),i(a("./lib/Exception.js")),i(a("./lib/Parser.js")),i(a("./lib/Quantity.js")),i(a("./lib/Unit.js")),i(a("./lib/Formatter/Format.js")),i(a("./lib/Formatter/FormatEnums.js")),i(a("./lib/Formatter/Formatter.js")),"undefined"!==typeof window&&window&&(window.iModelJsVersions||(window.iModelJsVersions=new Map),window.iModelJsVersions.set("imodeljs-quantity","1.0.0"))},"@bentley/bentleyjs-core":function(e,a){e.exports=t}},[["./lib/imodeljs-quantity.js",1]]])}); | ||
//# sourceMappingURL=imodeljs-quantity.js.map |
@@ -1,3 +0,38 @@ | ||
import { QuantityProps, UnitsProvider } from "./Interfaces"; | ||
import { QuantityStatus } from "./Exception"; | ||
import { QuantityProps, UnitsProvider, UnitProps, UnitConversionSpec, PotentialParseUnit } from "./Interfaces"; | ||
import { Format } from "./Formatter/Format"; | ||
/** | ||
* Defines Results of parsing a string input by a user into its desired value type | ||
* @alpha | ||
*/ | ||
export interface ParseResult { | ||
value?: number | undefined; | ||
status: QuantityStatus; | ||
} | ||
/** A ParserSpec holds information needed to parse a string into a quantity synchronously. | ||
* @alpha | ||
*/ | ||
export declare class ParserSpec { | ||
private _outUnit; | ||
private _conversions; | ||
private _format; | ||
/** Constructor | ||
* @param outUnit The name of a format specification. | ||
* @param format Defines the output format for the quantity value. | ||
* @param conversions An array of conversion factors necessary to convert from an input unit to the units specified in the format.. | ||
*/ | ||
constructor(outUnit: UnitProps, format: Format, conversions: UnitConversionSpec[]); | ||
/** Returns an array of UnitConversionSpecs for each unit label that may be used in the input string. */ | ||
readonly unitConversions: UnitConversionSpec[]; | ||
readonly format: Format; | ||
readonly outUnit: UnitProps; | ||
/** 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 | ||
* 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 | ||
* async calls to lookup unit definitions. | ||
* @param name The name of a format specification. | ||
* @param unitsProvider The units provider is used to look up unit definitions and provide conversion information for converting between units. | ||
* @param inputUnit The unit the value to be formatted. This unit is often referred to as persistence unit. | ||
*/ | ||
static create(format: Format, unitsProvider: UnitsProvider, outUnit: UnitProps): Promise<ParserSpec>; | ||
} | ||
/** A ParseToken holds either a numeric or string token extracted from a string that represents a quantity value. | ||
@@ -16,2 +51,3 @@ * @alpha | ||
export declare class Parser { | ||
private static _log; | ||
private static checkForScientificNotation; | ||
@@ -32,4 +68,23 @@ private static checkForFractions; | ||
static parseIntoQuantity(inString: string, format: Format, unitsProvider: UnitsProvider): Promise<QuantityProps>; | ||
/** method to get the Unit Conversion given a unit label */ | ||
private static tryFindUnitConversion; | ||
private static getQuantityValueFromParseTokens; | ||
/** Method to generate a Quantity given a string that represents a quantity value. | ||
* @param inString A string that contains text represent a quantity. | ||
* @param parserSpec unit label if not explicitly defined by user. Must have matching entry in supplied array of unitsConversions. | ||
* @param defaultValue default value to return if parsing is un successful | ||
*/ | ||
static parseQuantityString(inString: string, parserSpec: ParserSpec): ParseResult; | ||
/** Method to generate a Quantity given a string that represents a quantity value and likely a unit label. | ||
* @param inString A string that contains text represent a quantity. | ||
* @param format Defines the likely format of inString. Primary unit serves as a default unit if no unit label found in string. | ||
* @param unitsConversions dictionary of conversions used to convert from unit used in inString to output quantity | ||
*/ | ||
static parseIntoQuantityValue(inString: string, format: Format, unitsConversions: UnitConversionSpec[]): ParseResult; | ||
/** Async Method used to create an array of UnitConversionSpec entries that can be used in synchronous calls to parse units. */ | ||
static createUnitConversionSpecsForUnit(unitsProvider: UnitsProvider, outUnit: UnitProps): Promise<UnitConversionSpec[]>; | ||
/** Async Method used to create an array of UnitConversionSpec entries that can be used in synchronous calls to parse units. */ | ||
static createUnitConversionSpecs(unitsProvider: UnitsProvider, outUnitName: string, potentialParseUnits: PotentialParseUnit[]): Promise<UnitConversionSpec[]>; | ||
} | ||
export {}; | ||
//# sourceMappingURL=Parser.d.ts.map |
@@ -7,5 +7,38 @@ "use strict"; | ||
*--------------------------------------------------------------------------------------------*/ | ||
const Exception_1 = require("./Exception"); | ||
const Constants_1 = require("./Constants"); | ||
const Quantity_1 = require("./Quantity"); | ||
const FormatEnums_1 = require("./Formatter/FormatEnums"); | ||
/** A ParserSpec holds information needed to parse a string into a quantity synchronously. | ||
* @alpha | ||
*/ | ||
class ParserSpec { | ||
/** Constructor | ||
* @param outUnit The name of a format specification. | ||
* @param format Defines the output format for the quantity value. | ||
* @param conversions An array of conversion factors necessary to convert from an input unit to the units specified in the format.. | ||
*/ | ||
constructor(outUnit, format, conversions) { | ||
this._conversions = []; // max four entries | ||
this._outUnit = outUnit; | ||
this._format = format; | ||
this._conversions = conversions; | ||
} | ||
/** Returns an array of UnitConversionSpecs for each unit label that may be used in the input string. */ | ||
get unitConversions() { return this._conversions; } | ||
get format() { return this._format; } | ||
get outUnit() { return this._outUnit; } | ||
/** 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 | ||
* 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 | ||
* async calls to lookup unit definitions. | ||
* @param name The name of a format specification. | ||
* @param unitsProvider The units provider is used to look up unit definitions and provide conversion information for converting between units. | ||
* @param inputUnit The unit the value to be formatted. This unit is often referred to as persistence unit. | ||
*/ | ||
static async create(format, unitsProvider, outUnit) { | ||
const conversions = await Parser.createUnitConversionSpecsForUnit(unitsProvider, outUnit); | ||
return Promise.resolve(new ParserSpec(outUnit, format, conversions)); | ||
} | ||
} | ||
exports.ParserSpec = ParserSpec; | ||
/** A ParseToken holds either a numeric or string token extracted from a string that represents a quantity value. | ||
@@ -170,4 +203,4 @@ * @alpha | ||
let fraction = fractSymbol.fraction; | ||
i = fractSymbol.index; | ||
if (fractSymbol.fraction !== 0.0) { | ||
i = fractSymbol.index; | ||
if (signToken.length > 0) { | ||
@@ -183,4 +216,4 @@ wipToken = signToken + wipToken; | ||
wipToken = ""; | ||
continue; | ||
} | ||
continue; | ||
} | ||
@@ -310,4 +343,182 @@ else { | ||
} | ||
/** method to get the Unit Conversion given a unit label */ | ||
static tryFindUnitConversion(unitLabel, unitsConversions) { | ||
if (unitsConversions.length > 0) { | ||
const label = unitLabel.toLocaleLowerCase(); | ||
for (const conversion of unitsConversions) { | ||
if (conversion.parseLabels) { | ||
if (-1 !== conversion.parseLabels.findIndex((lbl) => lbl === label)) | ||
return conversion.conversion; | ||
} | ||
else { | ||
// tslint:disable-next-line:no-console | ||
console.log("ERROR: Parser expects to find parseLabels array populate with all possible unit labels for the unit."); | ||
} | ||
} | ||
} | ||
return undefined; | ||
} | ||
static getQuantityValueFromParseTokens(tokens, format, unitsConversions) { | ||
const defaultUnit = format.units && format.units.length > 0 ? format.units[0][0] : undefined; | ||
// common case where single value is supplied | ||
if (tokens.length === 1) { | ||
if (tokens[0].isNumber) { | ||
if (defaultUnit) { | ||
const conversion = Parser.tryFindUnitConversion(defaultUnit.label, unitsConversions); | ||
if (conversion) { | ||
const value = tokens[0].value * conversion.factor + conversion.offset; | ||
return { value, status: Exception_1.QuantityStatus.Success }; | ||
} | ||
} | ||
// if no conversion or no defaultUnit, just return parsed number | ||
return { value: tokens[0].value, status: Exception_1.QuantityStatus.UnknownUnit }; | ||
} | ||
else { | ||
// only the unit label was specified so assume magnitude of 1 | ||
const conversion = Parser.tryFindUnitConversion(tokens[0].value, unitsConversions); | ||
if (undefined !== conversion) | ||
return { value: conversion.factor + conversion.offset, status: Exception_1.QuantityStatus.Success }; | ||
else | ||
return { status: Exception_1.QuantityStatus.NoValueOrUnitFoundInString }; | ||
} | ||
} | ||
// common case where single value and single label are supplied | ||
if (tokens.length === 2) { | ||
if (tokens[0].isNumber && tokens[1].isString) { | ||
const conversion = Parser.tryFindUnitConversion(tokens[1].value, unitsConversions); | ||
if (conversion) { | ||
const value = tokens[0].value * conversion.factor + conversion.offset; | ||
return { value, status: Exception_1.QuantityStatus.Success }; | ||
} | ||
// if no conversion, just return parsed number and ignore value in second token | ||
return { value: tokens[0].value, status: Exception_1.QuantityStatus.UnitLabelSuppliedButNotMatched }; | ||
} | ||
else { // unit specification comes before value (like currency) | ||
if (tokens[1].isNumber && tokens[0].isString) { | ||
const conversion = Parser.tryFindUnitConversion(tokens[0].value, unitsConversions); | ||
if (conversion) { | ||
const value = tokens[1].value * conversion.factor + conversion.offset; | ||
return { value, status: Exception_1.QuantityStatus.Success }; | ||
} | ||
// if no conversion, just return parsed number and ignore value in second token | ||
return { value: tokens[1].value, status: Exception_1.QuantityStatus.UnitLabelSuppliedButNotMatched }; | ||
} | ||
} | ||
} | ||
// common case where there are multiple value/label pairs | ||
if (tokens.length % 2 === 0) { | ||
let mag = 0.0; | ||
for (let i = 0; i < tokens.length; i = i + 2) { | ||
if (tokens[i].isNumber && tokens[i + 1].isString) { | ||
const value = tokens[i].value; | ||
const conversion = Parser.tryFindUnitConversion(tokens[i + 1].value, unitsConversions); | ||
if (conversion) { | ||
if (mag < 0.0) | ||
mag = mag - ((value * conversion.factor)) + conversion.offset; | ||
else | ||
mag = mag + ((value * conversion.factor)) + conversion.offset; | ||
} | ||
} | ||
} | ||
return { value: mag, status: Exception_1.QuantityStatus.Success }; | ||
} | ||
return { status: Exception_1.QuantityStatus.UnableToConvertParseTokensToQuantity }; | ||
} | ||
/** Method to generate a Quantity given a string that represents a quantity value. | ||
* @param inString A string that contains text represent a quantity. | ||
* @param parserSpec unit label if not explicitly defined by user. Must have matching entry in supplied array of unitsConversions. | ||
* @param defaultValue default value to return if parsing is un successful | ||
*/ | ||
static parseQuantityString(inString, parserSpec) { | ||
return Parser.parseIntoQuantityValue(inString, parserSpec.format, parserSpec.unitConversions); | ||
} | ||
/** Method to generate a Quantity given a string that represents a quantity value and likely a unit label. | ||
* @param inString A string that contains text represent a quantity. | ||
* @param format Defines the likely format of inString. Primary unit serves as a default unit if no unit label found in string. | ||
* @param unitsConversions dictionary of conversions used to convert from unit used in inString to output quantity | ||
*/ | ||
static parseIntoQuantityValue(inString, format, unitsConversions) { | ||
const tokens = Parser.parseQuantitySpecification(inString, format); | ||
if (tokens.length === 0) | ||
return { status: Exception_1.QuantityStatus.UnableToGenerateParseTokens }; | ||
if (Parser._log) { | ||
// tslint:disable-next-line:no-console | ||
console.log(`Parse tokens`); | ||
let i = 0; | ||
for (const token of tokens) { | ||
// tslint:disable-next-line:no-console | ||
console.log(` [${i++}] isNumber=${token.isNumber} isString=${token.isString} token=${token.value}`); | ||
} | ||
} | ||
return Parser.getQuantityValueFromParseTokens(tokens, format, unitsConversions); | ||
} | ||
/** Async Method used to create an array of UnitConversionSpec entries that can be used in synchronous calls to parse units. */ | ||
static async createUnitConversionSpecsForUnit(unitsProvider, outUnit) { | ||
const unitConversionSpecs = []; | ||
const familyUnits = await unitsProvider.getUnitsByFamily(outUnit.unitFamily); | ||
for (const unit of familyUnits) { | ||
const conversion = await unitsProvider.getConversion(unit, outUnit); | ||
const parseLabels = [unit.label.toLocaleLowerCase()]; | ||
// add any alternate labels that may be define by the UnitProp | ||
if (unit.alternateLabels) { | ||
unit.alternateLabels.forEach((label) => { | ||
const potentialLabel = label.toLocaleLowerCase(); | ||
if (-1 === parseLabels.findIndex((lbl) => lbl === potentialLabel)) | ||
parseLabels.push(label.toLocaleLowerCase()); | ||
}); | ||
} | ||
unitConversionSpecs.push({ | ||
name: unit.name, | ||
label: unit.label, | ||
conversion, | ||
parseLabels, | ||
}); | ||
} | ||
return Promise.resolve(unitConversionSpecs); | ||
} | ||
/** Async Method used to create an array of UnitConversionSpec entries that can be used in synchronous calls to parse units. */ | ||
static async createUnitConversionSpecs(unitsProvider, outUnitName, potentialParseUnits) { | ||
const unitConversionSpecs = []; | ||
const outUnit = await unitsProvider.findUnitByName(outUnitName); | ||
if (!outUnit || !outUnit.name || 0 === outUnit.name.length) { | ||
// tslint:disable-next-line:no-console | ||
console.log(`[Parser.createUnitConversionSpecs] ERROR: Unable to locate out unit ${outUnitName}.`); | ||
return Promise.resolve(unitConversionSpecs); | ||
} | ||
for (const potentialParseUnit of potentialParseUnits) { | ||
const unit = await unitsProvider.findUnitByName(potentialParseUnit.unitName); | ||
if (!unit || !unit.name || 0 === unit.name.length) { | ||
// tslint:disable-next-line:no-console | ||
console.log(`[Parser.createUnitConversionSpecs] ERROR: Unable to locate potential unit ${potentialParseUnit.unitName}.`); | ||
continue; | ||
} | ||
const conversion = await unitsProvider.getConversion(unit, outUnit); | ||
const parseLabels = [unit.label.toLocaleLowerCase()]; | ||
// add any alternate labels that may be define by the UnitProp | ||
if (unit.alternateLabels) { | ||
unit.alternateLabels.forEach((label) => { | ||
const potentialLabel = label.toLocaleLowerCase(); | ||
if (-1 === parseLabels.findIndex((lbl) => lbl === potentialLabel)) | ||
parseLabels.push(label.toLocaleLowerCase()); | ||
}); | ||
} | ||
if (potentialParseUnit.altLabels) { | ||
potentialParseUnit.altLabels.forEach((label) => { | ||
const potentialLabel = label.toLocaleLowerCase(); | ||
if (-1 === parseLabels.findIndex((lbl) => lbl === potentialLabel)) | ||
parseLabels.push(label.toLocaleLowerCase()); | ||
}); | ||
} | ||
unitConversionSpecs.push({ | ||
name: unit.name, | ||
label: unit.label, | ||
conversion, | ||
parseLabels, | ||
}); | ||
} | ||
return Promise.resolve(unitConversionSpecs); | ||
} | ||
} | ||
Parser._log = false; | ||
exports.Parser = Parser; | ||
//# sourceMappingURL=Parser.js.map |
{ | ||
"name": "@bentley/imodeljs-quantity", | ||
"version": "0.191.0", | ||
"version": "1.0.0", | ||
"description": "Quantity parsing, formatting and conversions for iModel.js", | ||
@@ -39,5 +39,5 @@ "license": "MIT", | ||
"devDependencies": { | ||
"@bentley/bentleyjs-core": "0.191.0", | ||
"@bentley/build-tools": "0.191.0", | ||
"@bentley/webpack-tools": "0.191.0", | ||
"@bentley/bentleyjs-core": "1.0.0", | ||
"@bentley/build-tools": "1.0.0", | ||
"@bentley/webpack-tools": "1.0.0", | ||
"@types/chai": "^4.1.4", | ||
@@ -58,3 +58,2 @@ "@types/chai-as-promised": "^7", | ||
"tslint-etc": "^1.5.2", | ||
"typedoc": "^0.14.2", | ||
"typescript": "~3.2.2" | ||
@@ -64,3 +63,3 @@ }, | ||
"peerDependencies": { | ||
"@bentley/bentleyjs-core": "^0.191.0" | ||
"@bentley/bentleyjs-core": "^1.0.0" | ||
}, | ||
@@ -67,0 +66,0 @@ "nyc": { |
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
No v1
QualityPackage is not semver >=1. This means it is not stable and does not support ^ ranges.
Found 1 instance in 1 package
358057
19
32
4427
2