{"version":3,"sources":["dimensionVector.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAE7C;;;;;;;GAOG;AACH,qBAAa,eAAgB,YAAW,cAAc,CAAC,eAAe,CAAC;IACrE,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,UAAU,CAA4C;IAE9E,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,MAAM,CAE3B;IACH,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,EAAE,CAAQ;IAElC,gBAAuB,aAAa,kBAEjC;IAEH,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,yBAAyB,CAAK;IACtD,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,sBAAsB,CAAK;IACnD,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,YAAY,CAAK;IACzC,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,wBAAwB,CAAK;IACrD,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,UAAU,CAAK;IACvC,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,iBAAiB,CAAK;IAC9C,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,UAAU,CAAK;IAEvC,OAAO,CAAC,QAAQ,CAAC,kBAAkB,CAAS;IAE5C,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAgB;WAEzB,UAAU,CACtB,kBAAkB,EAAE,MAAM,GAAG,MAAM,EAAE,GACpC,eAAe;WAIJ,EAAE,CACd,eAAe,EAAE,MAAM,GAAG,MAAM,EAAE,GACjC,eAAe,GAAG,SAAS;gBAQlB,eAAe,EAAE,MAAM,GAAG,KAAK,CAAC,MAAM,CAAC;IAanD,OAAO,CAAC,cAAc;IAgCtB,OAAO,CAAC,0BAA0B;IAelC,OAAO,CAAC,MAAM,CAAC,cAAc;IAO7B,OAAO,CAAC,MAAM,CAAC,SAAS;IAQjB,eAAe,IAAI,OAAO;IAI1B,qBAAqB,IAAI,MAAM;IAI/B,SAAS,IAAI,MAAM,EAAE;IAIrB,4BAA4B;IAG5B,0BAA0B;IAI1B,gBAAgB;IAGhB,4BAA4B;IAG5B,eAAe;IAGf,sBAAsB;IAGtB,eAAe;IAIf,QAAQ,CAAC,EAAE,EAAE,MAAM,GAAG,eAAe;IAe5C,OAAO,CAAC,MAAM,CAAC,QAAQ;IAIhB,OAAO,CAAC,KAAK,EAAE,eAAe,GAAG,eAAe;IAehD,MAAM,CAAC,CAAC,EAAE,OAAO,GAAG,OAAO;CAYnC","file":"dimensionVector.d.ts","sourcesContent":["import { QudtNamespaces } from \"./qudtNamespaces.js\";\nimport { isNullish } from \"./utils.js\";\nimport { SupportsEquals } from \"./baseTypes\";\n\n/**\n * Represents the QUDT dimension vector and allows for converting between a dimension vector IRI and\n * the numeric values, as well as for some manipulations.\n *\n * <p>Note that the last value, the 'D' dimension is special: it is only an indicator that the\n * dimension vector represents a ratio (causing all other dimensions to cancel each other out). It\n * never changes by multiplication, and its value is only 1 iff all other dimensions are 0.\n */\nexport class DimensionVector implements SupportsEquals<DimensionVector> {\n  private static readonly DIMENSIONS = [\"A\", \"E\", \"L\", \"I\", \"M\", \"H\", \"T\", \"D\"];\n  //public static final DecimalFormat FORMAT = new DecimalFormat(\"0.#\");\n  private static readonly FORMAT = new Intl.NumberFormat(\"en-US\", {\n    useGrouping: false,\n  });\n  private static readonly PT = \"pt\";\n\n  public static readonly DIMENSIONLESS = new DimensionVector([\n    0, 0, 0, 0, 0, 0, 0, 1,\n  ]);\n\n  private static readonly INDEX_AMOUNT_OF_SUBSTANCE = 0;\n  private static readonly INDEX_ELECTRIC_CURRENT = 1;\n  private static readonly INDEX_LENGTH = 2;\n  private static readonly INDEX_LUMINOUS_INTENSITY = 3;\n  private static readonly INDEX_MASS = 4;\n  private static readonly INDEX_TEMPERATURE = 5;\n  private static readonly INDEX_TIME = 6;\n\n  private readonly dimensionVectorIri: string;\n\n  private readonly values: Array<number>;\n\n  public static ofRequired(\n    dimensionVectorIri: string | number[]\n  ): DimensionVector {\n    return new DimensionVector(dimensionVectorIri);\n  }\n\n  public static of(\n    dimensionValues: string | number[]\n  ): DimensionVector | undefined {\n    try {\n      return new DimensionVector(dimensionValues);\n    } catch (e) {\n      return undefined;\n    }\n  }\n\n  constructor(dimensionVector: string | Array<number>) {\n    if (typeof dimensionVector === \"string\") {\n      this.dimensionVectorIri = dimensionVector;\n      this.values = this.parseDimValues(dimensionVector);\n    } else if (Array.isArray(dimensionVector)) {\n      this.values = dimensionVector;\n      this.dimensionVectorIri =\n        this.generateDimensionVectorIri(dimensionVector);\n    } else {\n      throw new Error(`Cannot handle constructor argument ${dimensionVector}`);\n    }\n  }\n\n  private parseDimValues(dimensionVectorIri: string): number[] {\n    if (\n      !QudtNamespaces.dimensionVector.isFullNamespaceIri(dimensionVectorIri)\n    ) {\n      throw new Error(`Not a dimension vector iri: ${dimensionVectorIri}`);\n    }\n    const localName =\n      QudtNamespaces.dimensionVector.getLocalnameIfFullNamespaceIri(\n        dimensionVectorIri\n      );\n    const dimValues = [0, 0, 0, 0, 0, 0, 0, 0];\n    const numbers = localName.split(/[AELIMHTD]/);\n    const indicators = localName.split(/-?[0-9]+p?t?[0-9]*/);\n    if (indicators.length != 9) {\n      throw new Error(\n        `Cannot process dimension vector iri ${dimensionVectorIri}: unexpected number of dimensions: ${numbers.length}`\n      );\n    } else {\n      for (let i = 0; i < 8; i++) {\n        if (indicators[i].charAt(0) != DimensionVector.DIMENSIONS[i]) {\n          throw new Error(\n            `Expected dimension indicator '${DimensionVector.DIMENSIONS[i]}', encountered '${indicators[i]}'`\n          );\n        }\n        dimValues[i] = DimensionVector.noNegativeZero(\n          Number.parseFloat(numbers[i + 1].replace(\"pt\", \".\"))\n        ); // split produces an empty first array element\n      }\n    }\n    return dimValues;\n  }\n\n  private generateDimensionVectorIri(dimensionValues: number[]): string {\n    if (dimensionValues.length != 8) {\n      throw new Error(\n        \"wrong dimensionality, expected 8, got \" + dimensionValues.length\n      );\n    }\n    let result = \"\";\n    for (let i = 0; i < 8; i++) {\n      result +=\n        DimensionVector.DIMENSIONS[i] +\n        DimensionVector.iriFormat(dimensionValues[i]);\n    }\n    return \"http://qudt.org/vocab/dimensionvector/\" + result;\n  }\n\n  private static noNegativeZero(f: number): number {\n    if (f === -0.0) {\n      return 0.0;\n    }\n    return f;\n  }\n\n  private static iriFormat(dimensionValue: number): string {\n    // Note: This handles a weird case where you may have \"-0\" as a value.\n    if (Math.abs(dimensionValue) < 0.01) {\n      return \"0\";\n    }\n    return DimensionVector.FORMAT.format(dimensionValue).replace(\".\", \"pt\");\n  }\n\n  public isDimensionless(): boolean {\n    return this.equals(DimensionVector.DIMENSIONLESS);\n  }\n\n  public getDimensionVectorIri(): string {\n    return this.dimensionVectorIri;\n  }\n\n  public getValues(): number[] {\n    return this.values;\n  }\n\n  public getAmountOfSubstanceExponent() {\n    return this.values[DimensionVector.INDEX_AMOUNT_OF_SUBSTANCE];\n  }\n  public getElectricCurrentExponent() {\n    return this.values[DimensionVector.INDEX_ELECTRIC_CURRENT];\n  }\n\n  public getLenghExponent() {\n    return this.values[DimensionVector.INDEX_LENGTH];\n  }\n  public getLuminousIntensityExponent() {\n    return this.values[DimensionVector.INDEX_LUMINOUS_INTENSITY];\n  }\n  public getMassExponent() {\n    return this.values[DimensionVector.INDEX_MASS];\n  }\n  public getTemperatureExponent() {\n    return this.values[DimensionVector.INDEX_TEMPERATURE];\n  }\n  public getTimeExponent() {\n    return this.values[DimensionVector.INDEX_TIME];\n  }\n\n  public multiply(by: number): DimensionVector {\n    const mult: number[] = [];\n    let isRatio = true;\n    for (let i = 0; i < 7; i++) {\n      const multDim = DimensionVector.noNegativeZero(this.values[i] * by);\n      mult.push(multDim);\n      if (multDim != 0) {\n        isRatio = false;\n      }\n    }\n    mult.push(0);\n    DimensionVector.setRatio(mult, isRatio);\n    return new DimensionVector(mult);\n  }\n\n  private static setRatio(values: number[], isRatio: boolean): void {\n    values[7] = isRatio ? 1 : 0;\n  }\n\n  public combine(other: DimensionVector): DimensionVector {\n    const combined: number[] = [];\n    let isRatio = true;\n    for (let i = 0; i < 7; i++) {\n      combined[i] = DimensionVector.noNegativeZero(\n        this.values[i] + other.getValues()[i]\n      );\n      if (combined[i] != 0) {\n        isRatio = false;\n      }\n    }\n    DimensionVector.setRatio(combined, isRatio);\n    return new DimensionVector(combined);\n  }\n\n  public equals(o: unknown): boolean {\n    if (isNullish(o)) {\n      return false;\n    }\n    if (this === o) return true;\n    if (!(o instanceof DimensionVector)) return false;\n    const that = o as DimensionVector;\n    return (\n      that.getDimensionVectorIri() === this.dimensionVectorIri &&\n      this.values.every((v, i) => v === that.getValues()[i])\n    );\n  }\n}\n"]}