{"version":3,"file":"css-calc.js","names":["#hasNum","#numSum","#numMul","#hasPct","#pctSum","#pctMul","#hasDim","#dimSum","#dimSub","#dimMul","#dimDiv","#hasEtc","#etcSum","#etcSub","#etcMul","#etcDiv","#calcOpts"],"sources":["../../../src/js/css-calc.ts"],"sourcesContent":["/**\n * css-calc\n */\n\nimport { calc, conversionOptions as CalcOptions } from '@csstools/css-calc';\nimport { CSSToken, TokenType, tokenize } from '@csstools/css-tokenizer';\nimport {\n  CacheItem,\n  NullObject,\n  createCacheKey,\n  getCache,\n  setCache\n} from './cache';\nimport { isString, isStringOrNumber } from './common';\nimport { resolveVar } from './css-var';\nimport { resolveLengthInPixels, roundToPrecision } from './util';\nimport { MatchedRegExp, Options } from './typedef';\n\n/* constants */\nimport {\n  ANGLE,\n  LENGTH,\n  NUM,\n  SYN_FN_CALC,\n  SYN_FN_MATH_START,\n  SYN_FN_VAR,\n  SYN_FN_VAR_START,\n  VAL_SPEC\n} from './constant';\nconst {\n  CloseParen: PAREN_CLOSE,\n  Comment: COMMENT,\n  Dimension: DIM,\n  EOF,\n  Function: FUNC,\n  OpenParen: PAREN_OPEN,\n  Whitespace: W_SPACE\n} = TokenType;\nconst NAMESPACE = 'css-calc';\n\n/* numeric constants */\nconst TRIA = 3;\nconst HEX = 16;\nconst MAX_PCT = 100;\n\n/* regexp */\nconst REG_FN_CALC = new RegExp(SYN_FN_CALC);\nconst REG_FN_CALC_NUM = new RegExp(`^calc\\\\((${NUM})\\\\)$`);\nconst REG_FN_MATH_START = new RegExp(SYN_FN_MATH_START);\nconst REG_FN_VAR = new RegExp(SYN_FN_VAR);\nconst REG_FN_VAR_START = new RegExp(SYN_FN_VAR_START);\nconst REG_OPERATOR = /\\s[*+/-]\\s/;\nconst REG_PAREN_OPEN = /\\($/;\nconst REG_TYPE_DIM = new RegExp(`^(${NUM})(${ANGLE}|${LENGTH})$`);\nconst REG_TYPE_DIM_PCT = new RegExp(`^(${NUM})(${ANGLE}|${LENGTH}|%)$`);\nconst REG_TYPE_PCT = new RegExp(`^(${NUM})%$`);\n\n/**\n * Calclator\n */\nexport class Calculator {\n  /* private */\n  // number\n  #hasNum: boolean;\n  #numSum: number[];\n  #numMul: number[];\n  // percentage\n  #hasPct: boolean;\n  #pctSum: number[];\n  #pctMul: number[];\n  // dimension\n  #hasDim: boolean;\n  #dimSum: string[];\n  #dimSub: string[];\n  #dimMul: string[];\n  #dimDiv: string[];\n  // et cetra\n  #hasEtc: boolean;\n  #etcSum: string[];\n  #etcSub: string[];\n  #etcMul: string[];\n  #etcDiv: string[];\n  // calc options\n  #calcOpts: CalcOptions;\n\n  /**\n   * constructor\n   */\n  constructor() {\n    // number\n    this.#hasNum = false;\n    this.#numSum = [];\n    this.#numMul = [];\n    // percentage\n    this.#hasPct = false;\n    this.#pctSum = [];\n    this.#pctMul = [];\n    // dimension\n    this.#hasDim = false;\n    this.#dimSum = [];\n    this.#dimSub = [];\n    this.#dimMul = [];\n    this.#dimDiv = [];\n    // et cetra\n    this.#hasEtc = false;\n    this.#etcSum = [];\n    this.#etcSub = [];\n    this.#etcMul = [];\n    this.#etcDiv = [];\n    // calc options\n    this.#calcOpts = {\n      toCanonicalUnits: true\n    };\n  }\n\n  get hasNum() {\n    return this.#hasNum;\n  }\n\n  set hasNum(value: boolean) {\n    this.#hasNum = !!value;\n  }\n\n  get numSum() {\n    return this.#numSum;\n  }\n\n  get numMul() {\n    return this.#numMul;\n  }\n\n  get hasPct() {\n    return this.#hasPct;\n  }\n\n  set hasPct(value: boolean) {\n    this.#hasPct = !!value;\n  }\n\n  get pctSum() {\n    return this.#pctSum;\n  }\n\n  get pctMul() {\n    return this.#pctMul;\n  }\n\n  get hasDim() {\n    return this.#hasDim;\n  }\n\n  set hasDim(value: boolean) {\n    this.#hasDim = !!value;\n  }\n\n  get dimSum() {\n    return this.#dimSum;\n  }\n\n  get dimSub() {\n    return this.#dimSub;\n  }\n\n  get dimMul() {\n    return this.#dimMul;\n  }\n\n  get dimDiv() {\n    return this.#dimDiv;\n  }\n\n  get hasEtc() {\n    return this.#hasEtc;\n  }\n\n  set hasEtc(value: boolean) {\n    this.#hasEtc = !!value;\n  }\n\n  get etcSum() {\n    return this.#etcSum;\n  }\n\n  get etcSub() {\n    return this.#etcSub;\n  }\n\n  get etcMul() {\n    return this.#etcMul;\n  }\n\n  get etcDiv() {\n    return this.#etcDiv;\n  }\n\n  /**\n   * clear values\n   * @returns void\n   */\n  clear() {\n    // number\n    this.#hasNum = false;\n    this.#numSum.length = 0;\n    this.#numMul.length = 0;\n    // percentage\n    this.#hasPct = false;\n    this.#pctSum.length = 0;\n    this.#pctMul.length = 0;\n    // dimension\n    this.#hasDim = false;\n    this.#dimSum.length = 0;\n    this.#dimSub.length = 0;\n    this.#dimMul.length = 0;\n    this.#dimDiv.length = 0;\n    // et cetra\n    this.#hasEtc = false;\n    this.#etcSum.length = 0;\n    this.#etcSub.length = 0;\n    this.#etcMul.length = 0;\n    this.#etcDiv.length = 0;\n  }\n\n  /**\n   * sort values\n   * @param values - values\n   * @returns sorted values\n   */\n  sort(values: string[] = []): string[] {\n    const arr = [...values];\n    if (arr.length > 1) {\n      arr.sort((a, b) => {\n        let res;\n        if (REG_TYPE_DIM_PCT.test(a) && REG_TYPE_DIM_PCT.test(b)) {\n          const [, valA, unitA] = a.match(REG_TYPE_DIM_PCT) as MatchedRegExp;\n          const [, valB, unitB] = b.match(REG_TYPE_DIM_PCT) as MatchedRegExp;\n          if (unitA === unitB) {\n            if (Number(valA) === Number(valB)) {\n              res = 0;\n            } else if (Number(valA) > Number(valB)) {\n              res = 1;\n            } else {\n              res = -1;\n            }\n          } else if (unitA > unitB) {\n            res = 1;\n          } else {\n            res = -1;\n          }\n        } else {\n          if (a === b) {\n            res = 0;\n          } else if (a > b) {\n            res = 1;\n          } else {\n            res = -1;\n          }\n        }\n        return res;\n      });\n    }\n    return arr;\n  }\n\n  /**\n   * multiply values\n   * @returns resolved value\n   */\n  multiply(): string {\n    const value = [];\n    let num;\n    if (this.#hasNum) {\n      num = 1;\n      for (const i of this.#numMul) {\n        num *= i;\n        if (num === 0 || !Number.isFinite(num) || Number.isNaN(num)) {\n          break;\n        }\n      }\n      if (!this.#hasPct && !this.#hasDim && !this.hasEtc) {\n        if (Number.isFinite(num)) {\n          num = roundToPrecision(num, HEX);\n        }\n        value.push(num);\n      }\n    }\n    if (this.#hasPct) {\n      if (typeof num !== 'number') {\n        num = 1;\n      }\n      for (const i of this.#pctMul) {\n        num *= i;\n        if (num === 0 || !Number.isFinite(num) || Number.isNaN(num)) {\n          break;\n        }\n      }\n      if (Number.isFinite(num)) {\n        num = `${roundToPrecision(num, HEX)}%`;\n      }\n      if (!this.#hasDim && !this.hasEtc) {\n        value.push(num);\n      }\n    }\n    if (this.#hasDim) {\n      let dim = '';\n      let mul = '';\n      let div = '';\n      if (this.#dimMul.length) {\n        if (this.#dimMul.length === 1) {\n          [mul] = this.#dimMul as [string];\n        } else {\n          mul = `${this.sort(this.#dimMul).join(' * ')}`;\n        }\n      }\n      if (this.#dimDiv.length) {\n        if (this.#dimDiv.length === 1) {\n          [div] = this.#dimDiv as [string];\n        } else {\n          div = `${this.sort(this.#dimDiv).join(' * ')}`;\n        }\n      }\n      if (Number.isFinite(num)) {\n        if (mul) {\n          if (div) {\n            if (div.includes('*')) {\n              dim = calc(`calc(${num} * ${mul} / (${div}))`, this.#calcOpts);\n            } else {\n              dim = calc(`calc(${num} * ${mul} / ${div})`, this.#calcOpts);\n            }\n          } else {\n            dim = calc(`calc(${num} * ${mul})`, this.#calcOpts);\n          }\n        } else if (div.includes('*')) {\n          dim = calc(`calc(${num} / (${div}))`, this.#calcOpts);\n        } else {\n          dim = calc(`calc(${num} / ${div})`, this.#calcOpts);\n        }\n        value.push(dim.replace(/^calc/, ''));\n      } else {\n        if (!value.length && num !== undefined) {\n          value.push(num);\n        }\n        if (mul) {\n          if (div) {\n            if (div.includes('*')) {\n              dim = calc(`calc(${mul} / (${div}))`, this.#calcOpts);\n            } else {\n              dim = calc(`calc(${mul} / ${div})`, this.#calcOpts);\n            }\n          } else {\n            dim = calc(`calc(${mul})`, this.#calcOpts);\n          }\n          if (value.length) {\n            value.push('*', dim.replace(/^calc/, ''));\n          } else {\n            value.push(dim.replace(/^calc/, ''));\n          }\n        } else {\n          dim = calc(`calc(${div})`, this.#calcOpts);\n          if (value.length) {\n            value.push('/', dim.replace(/^calc/, ''));\n          } else {\n            value.push('1', '/', dim.replace(/^calc/, ''));\n          }\n        }\n      }\n    }\n    if (this.#hasEtc) {\n      if (this.#etcMul.length) {\n        if (!value.length && num !== undefined) {\n          value.push(num);\n        }\n        const mul = this.sort(this.#etcMul).join(' * ');\n        if (value.length) {\n          value.push(`* ${mul}`);\n        } else {\n          value.push(`${mul}`);\n        }\n      }\n      if (this.#etcDiv.length) {\n        const div = this.sort(this.#etcDiv).join(' * ');\n        if (div.includes('*')) {\n          if (value.length) {\n            value.push(`/ (${div})`);\n          } else {\n            value.push(`1 / (${div})`);\n          }\n        } else if (value.length) {\n          value.push(`/ ${div}`);\n        } else {\n          value.push(`1 / ${div}`);\n        }\n      }\n    }\n    if (value.length) {\n      return value.join(' ');\n    }\n    return '';\n  }\n\n  /**\n   * sum values\n   * @returns resolved value\n   */\n  sum(): string {\n    const value = [];\n    if (this.#hasNum) {\n      let num = 0;\n      for (const i of this.#numSum) {\n        num += i;\n        if (!Number.isFinite(num) || Number.isNaN(num)) {\n          break;\n        }\n      }\n      value.push(num);\n    }\n    if (this.#hasPct) {\n      let num: number | string = 0;\n      for (const i of this.#pctSum) {\n        num += i;\n        if (!Number.isFinite(num)) {\n          break;\n        }\n      }\n      if (Number.isFinite(num)) {\n        num = `${num}%`;\n      }\n      if (value.length) {\n        value.push(`+ ${num}`);\n      } else {\n        value.push(num);\n      }\n    }\n    if (this.#hasDim) {\n      let dim, sum, sub;\n      if (this.#dimSum.length) {\n        sum = this.sort(this.#dimSum).join(' + ');\n      }\n      if (this.#dimSub.length) {\n        sub = this.sort(this.#dimSub).join(' + ');\n      }\n      if (sum) {\n        if (sub) {\n          if (sub.includes('-')) {\n            dim = calc(`calc(${sum} - (${sub}))`, this.#calcOpts);\n          } else {\n            dim = calc(`calc(${sum} - ${sub})`, this.#calcOpts);\n          }\n        } else {\n          dim = calc(`calc(${sum})`, this.#calcOpts);\n        }\n      } else {\n        dim = calc(`calc(-1 * (${sub}))`, this.#calcOpts);\n      }\n      if (value.length) {\n        value.push('+', dim.replace(/^calc/, ''));\n      } else {\n        value.push(dim.replace(/^calc/, ''));\n      }\n    }\n    if (this.#hasEtc) {\n      if (this.#etcSum.length) {\n        const sum = this.sort(this.#etcSum)\n          .map(item => {\n            let res;\n            if (\n              REG_OPERATOR.test(item) &&\n              !item.startsWith('(') &&\n              !item.endsWith(')')\n            ) {\n              res = `(${item})`;\n            } else {\n              res = item;\n            }\n            return res;\n          })\n          .join(' + ');\n        if (value.length) {\n          if (this.#etcSum.length > 1) {\n            value.push(`+ (${sum})`);\n          } else {\n            value.push(`+ ${sum}`);\n          }\n        } else {\n          value.push(`${sum}`);\n        }\n      }\n      if (this.#etcSub.length) {\n        const sub = this.sort(this.#etcSub)\n          .map(item => {\n            let res;\n            if (\n              REG_OPERATOR.test(item) &&\n              !item.startsWith('(') &&\n              !item.endsWith(')')\n            ) {\n              res = `(${item})`;\n            } else {\n              res = item;\n            }\n            return res;\n          })\n          .join(' + ');\n        if (value.length) {\n          if (this.#etcSub.length > 1) {\n            value.push(`- (${sub})`);\n          } else {\n            value.push(`- ${sub}`);\n          }\n        } else if (this.#etcSub.length > 1) {\n          value.push(`-1 * (${sub})`);\n        } else {\n          value.push(`-1 * ${sub}`);\n        }\n      }\n    }\n    if (value.length) {\n      return value.join(' ');\n    }\n    return '';\n  }\n}\n\n/**\n * sort calc values\n * @param values - values to sort\n * @param [finalize] - finalize values\n * @returns sorted values\n */\nexport const sortCalcValues = (\n  values: (number | string)[] = [],\n  finalize: boolean = false\n): string => {\n  if (values.length < TRIA) {\n    throw new Error(`Unexpected array length ${values.length}.`);\n  }\n  const start = values.shift();\n  if (!isString(start) || !start.endsWith('(')) {\n    throw new Error(`Unexpected token ${start}.`);\n  }\n  const end = values.pop();\n  if (end !== ')') {\n    throw new Error(`Unexpected token ${end}.`);\n  }\n  if (values.length === 1) {\n    const [value] = values;\n    if (!isStringOrNumber(value)) {\n      throw new Error(`Unexpected token ${value}.`);\n    }\n    return `${start}${value}${end}`;\n  }\n  const sortedValues = [];\n  const cal = new Calculator();\n  let operator: string = '';\n  const l = values.length;\n  // Array traversal optimization for operator check\n  let hasAddSub = false;\n  for (let i = 0; i < l; i++) {\n    const value = values[i];\n    if (!isStringOrNumber(value)) {\n      throw new Error(`Unexpected token ${value}.`);\n    }\n    if (value === '*' || value === '/') {\n      operator = value;\n    } else if (value === '+' || value === '-') {\n      const sortedValue = cal.multiply();\n      if (sortedValue) {\n        sortedValues.push(sortedValue, value);\n      }\n      // Mark presence of + or -\n      hasAddSub = true;\n      cal.clear();\n      operator = '';\n    } else {\n      const numValue = Number(value);\n      const strValue = `${value}`;\n      switch (operator) {\n        case '/': {\n          if (Number.isFinite(numValue)) {\n            cal.hasNum = true;\n            cal.numMul.push(1 / numValue);\n          } else if (REG_TYPE_PCT.test(strValue)) {\n            const [, val] = strValue.match(REG_TYPE_PCT) as MatchedRegExp;\n            cal.hasPct = true;\n            cal.pctMul.push((MAX_PCT * MAX_PCT) / Number(val));\n          } else if (REG_TYPE_DIM.test(strValue)) {\n            cal.hasDim = true;\n            cal.dimDiv.push(strValue);\n          } else {\n            cal.hasEtc = true;\n            cal.etcDiv.push(strValue);\n          }\n          break;\n        }\n        case '*':\n        default: {\n          if (Number.isFinite(numValue)) {\n            cal.hasNum = true;\n            cal.numMul.push(numValue);\n          } else if (REG_TYPE_PCT.test(strValue)) {\n            const [, val] = strValue.match(REG_TYPE_PCT) as MatchedRegExp;\n            cal.hasPct = true;\n            cal.pctMul.push(Number(val));\n          } else if (REG_TYPE_DIM.test(strValue)) {\n            cal.hasDim = true;\n            cal.dimMul.push(strValue);\n          } else {\n            cal.hasEtc = true;\n            cal.etcMul.push(strValue);\n          }\n        }\n      }\n    }\n    if (i === l - 1) {\n      const sortedValue = cal.multiply();\n      if (sortedValue) {\n        sortedValues.push(sortedValue);\n      }\n      cal.clear();\n      operator = '';\n    }\n  }\n  let resolvedValue = '';\n  if (finalize && hasAddSub) {\n    const finalizedValues = [];\n    cal.clear();\n    operator = '';\n    const l = sortedValues.length;\n    for (let i = 0; i < l; i++) {\n      const value = sortedValues[i];\n      if (isStringOrNumber(value)) {\n        if (value === '+' || value === '-') {\n          operator = value;\n        } else {\n          const numValue = Number(value);\n          const strValue = `${value}`;\n          switch (operator) {\n            case '-': {\n              if (Number.isFinite(numValue)) {\n                cal.hasNum = true;\n                cal.numSum.push(-1 * numValue);\n              } else if (REG_TYPE_PCT.test(strValue)) {\n                const [, val] = strValue.match(REG_TYPE_PCT) as MatchedRegExp;\n                cal.hasPct = true;\n                cal.pctSum.push(-1 * Number(val));\n              } else if (REG_TYPE_DIM.test(strValue)) {\n                cal.hasDim = true;\n                cal.dimSub.push(strValue);\n              } else {\n                cal.hasEtc = true;\n                cal.etcSub.push(strValue);\n              }\n              break;\n            }\n            case '+':\n            default: {\n              if (Number.isFinite(numValue)) {\n                cal.hasNum = true;\n                cal.numSum.push(numValue);\n              } else if (REG_TYPE_PCT.test(strValue)) {\n                const [, val] = strValue.match(REG_TYPE_PCT) as MatchedRegExp;\n                cal.hasPct = true;\n                cal.pctSum.push(Number(val));\n              } else if (REG_TYPE_DIM.test(strValue)) {\n                cal.hasDim = true;\n                cal.dimSum.push(strValue);\n              } else {\n                cal.hasEtc = true;\n                cal.etcSum.push(strValue);\n              }\n            }\n          }\n        }\n      }\n      if (i === l - 1) {\n        const sortedValue = cal.sum();\n        if (sortedValue) {\n          finalizedValues.push(sortedValue);\n        }\n        cal.clear();\n        operator = '';\n      }\n    }\n    resolvedValue = finalizedValues.join(' ').replace(/\\+\\s-/g, '- ');\n  } else {\n    resolvedValue = sortedValues.join(' ').replace(/\\+\\s-/g, '- ');\n  }\n  if (\n    resolvedValue.startsWith('(') &&\n    resolvedValue.endsWith(')') &&\n    resolvedValue.lastIndexOf('(') === 0 &&\n    resolvedValue.indexOf(')') === resolvedValue.length - 1\n  ) {\n    resolvedValue = resolvedValue.substring(1, resolvedValue.length - 1);\n  }\n  return `${start}${resolvedValue}${end}`;\n};\n\n/**\n * resolve AST node\n * @param node - AST node\n * @param isRoot - is root node\n * @returns resolved value\n */\nconst resolveNode = (node: any[], isRoot: boolean): string => {\n  const flatItems: string[] = [];\n  for (const item of node) {\n    if (Array.isArray(item)) {\n      flatItems.push(resolveNode(item, false));\n    } else {\n      flatItems.push(item as string);\n    }\n  }\n  if (isRoot) {\n    if (flatItems.length >= TRIA) {\n      return sortCalcValues(flatItems, true);\n    }\n    const joined = flatItems.join('');\n    return joined.startsWith('calc(') ? joined : `calc(${joined})`;\n  }\n  if (flatItems.length >= TRIA) {\n    let serialized = sortCalcValues(flatItems, false);\n    if (REG_FN_VAR_START.test(serialized)) {\n      serialized = calc(serialized, { toCanonicalUnits: true });\n    }\n    return serialized;\n  }\n  return flatItems.join('');\n};\n\n/**\n * serialize calc\n * @param value - CSS value\n * @param [opt] - options\n * @returns serialized value\n */\nexport const serializeCalc = (value: string, opt: Options = {}): string => {\n  const { format = '' } = opt;\n  if (isString(value)) {\n    if (!REG_FN_VAR_START.test(value) || format !== VAL_SPEC) {\n      return value;\n    }\n    value = value.toLowerCase().trim();\n  } else {\n    throw new TypeError(`${value} is not a string.`);\n  }\n  const cacheKey: string = createCacheKey(\n    {\n      namespace: NAMESPACE,\n      name: 'serializeCalc',\n      value\n    },\n    opt\n  );\n  const cachedResult = getCache(cacheKey);\n  if (cachedResult instanceof CacheItem) {\n    return cachedResult.item as string;\n  }\n  const items: string[] = tokenize({ css: value })\n    .map((token: CSSToken): string => {\n      const [type, val] = token as [TokenType, string];\n      let res = '';\n      if (type !== W_SPACE && type !== COMMENT) {\n        res = val;\n      }\n      return res;\n    })\n    .filter(v => v);\n  const stack: any[][] = [[]];\n  for (const item of items) {\n    if (REG_PAREN_OPEN.test(item)) {\n      const newNode = [item];\n      const parent = stack[stack.length - 1];\n      if (parent) {\n        parent.push(newNode);\n      }\n      stack.push(newNode);\n    } else if (item === ')') {\n      if (stack.length > 1) {\n        const currentLevel = stack.pop();\n        if (currentLevel) {\n          currentLevel.push(item);\n        }\n      } else {\n        const root = stack[0];\n        if (root) {\n          root.push(item);\n        }\n      }\n    } else {\n      const parent = stack[stack.length - 1];\n      if (parent) {\n        parent.push(item);\n      }\n    }\n  }\n  let serializedCalc = '';\n  const rootItems = stack[0];\n  if (rootItems) {\n    if (rootItems.length === 1 && Array.isArray(rootItems[0])) {\n      serializedCalc = resolveNode(rootItems[0], true);\n    } else {\n      const flatItems: string[] = [];\n      for (const item of rootItems) {\n        if (Array.isArray(item)) {\n          flatItems.push(resolveNode(item, false));\n        } else {\n          flatItems.push(item as string);\n        }\n      }\n      if (flatItems.length >= TRIA) {\n        serializedCalc = sortCalcValues(flatItems, true);\n      } else {\n        const firstItem = flatItems[0] || '';\n        serializedCalc =\n          isString(firstItem) && firstItem.startsWith('calc(')\n            ? firstItem\n            : `calc(${firstItem})`;\n      }\n    }\n  }\n  setCache(cacheKey, serializedCalc);\n  return serializedCalc;\n};\n\n/**\n * resolve dimension\n * @param token - CSS token\n * @param [opt] - options\n * @returns resolved value\n */\nexport const resolveDimension = (\n  token: CSSToken,\n  opt: Options = {}\n): string | NullObject => {\n  if (!Array.isArray(token)) {\n    throw new TypeError(`${token} is not an array.`);\n  }\n  const [, , , , detail = {}] = token;\n  const { unit, value } = detail as {\n    unit: string;\n    value: number;\n  };\n  if (unit === 'px') {\n    return `${value}${unit}`;\n  }\n  const pixelValue = resolveLengthInPixels(Number(value), unit, opt);\n  if (Number.isFinite(pixelValue)) {\n    return `${roundToPrecision(pixelValue, HEX)}px`;\n  }\n  return new NullObject();\n};\n\n/**\n * parse tokens\n * @param tokens - CSS tokens\n * @param [opt] - options\n * @returns parsed tokens\n */\nexport const parseTokens = (\n  tokens: CSSToken[],\n  opt: Options = {}\n): string[] => {\n  if (!Array.isArray(tokens)) {\n    throw new TypeError(`${tokens} is not an array.`);\n  }\n  const { format = '' } = opt;\n  const mathFunc = new Set();\n  let nest = 0;\n  const res: string[] = [];\n  for (const token of tokens) {\n    if (!Array.isArray(token)) {\n      throw new TypeError(`${token} is not an array.`);\n    }\n    const [type = '', value = ''] = token as [TokenType, string];\n    switch (type) {\n      case DIM: {\n        if (format === VAL_SPEC && !mathFunc.has(nest)) {\n          res.push(value);\n        } else {\n          const resolvedValue = resolveDimension(token, opt);\n          if (isString(resolvedValue)) {\n            res.push(resolvedValue);\n          } else {\n            res.push(value);\n          }\n        }\n        break;\n      }\n      case FUNC:\n      case PAREN_OPEN: {\n        res.push(value);\n        nest++;\n        if (REG_FN_MATH_START.test(value)) {\n          mathFunc.add(nest);\n        }\n        break;\n      }\n      case PAREN_CLOSE: {\n        if (res.length) {\n          const lastValue = res[res.length - 1];\n          if (lastValue === ' ') {\n            res.splice(-1, 1, value);\n          } else {\n            res.push(value);\n          }\n        } else {\n          res.push(value);\n        }\n        if (mathFunc.has(nest)) {\n          mathFunc.delete(nest);\n        }\n        nest--;\n        break;\n      }\n      case W_SPACE: {\n        if (res.length) {\n          const lastValue = res[res.length - 1];\n          if (\n            isString(lastValue) &&\n            !lastValue.endsWith('(') &&\n            lastValue !== ' '\n          ) {\n            res.push(value);\n          }\n        }\n        break;\n      }\n      default: {\n        if (type !== COMMENT && type !== EOF) {\n          res.push(value);\n        }\n      }\n    }\n  }\n  return res;\n};\n\n/**\n * CSS calc()\n * @param value - CSS value including calc()\n * @param [opt] - options\n * @returns resolved value\n */\nexport const cssCalc = (value: string, opt: Options = {}): string => {\n  const { format = '' } = opt;\n  if (isString(value)) {\n    if (REG_FN_VAR.test(value)) {\n      if (format === VAL_SPEC) {\n        return value;\n      } else {\n        const resolvedValue = resolveVar(value, opt);\n        if (isString(resolvedValue)) {\n          return resolvedValue;\n        } else {\n          return '';\n        }\n      }\n    } else if (!REG_FN_CALC.test(value)) {\n      return value;\n    }\n    value = value.toLowerCase().trim();\n  } else {\n    throw new TypeError(`${value} is not a string.`);\n  }\n  const cacheKey: string = createCacheKey(\n    {\n      namespace: NAMESPACE,\n      name: 'cssCalc',\n      value\n    },\n    opt\n  );\n  const cachedResult = getCache(cacheKey);\n  if (cachedResult instanceof CacheItem) {\n    return cachedResult.item as string;\n  }\n  const tokens = tokenize({ css: value });\n  const values = parseTokens(tokens, opt);\n  let resolvedValue: string = calc(values.join(''), {\n    toCanonicalUnits: true\n  });\n  if (REG_FN_VAR_START.test(value)) {\n    if (REG_TYPE_DIM_PCT.test(resolvedValue)) {\n      const [, val, unit] = resolvedValue.match(\n        REG_TYPE_DIM_PCT\n      ) as MatchedRegExp;\n      resolvedValue = `${roundToPrecision(Number(val), HEX)}${unit}`;\n    }\n    // wrap with `calc()`\n    if (\n      resolvedValue &&\n      !REG_FN_VAR_START.test(resolvedValue) &&\n      format === VAL_SPEC\n    ) {\n      resolvedValue = `calc(${resolvedValue})`;\n    }\n  }\n  if (format === VAL_SPEC) {\n    if (/\\s[-+*/]\\s/.test(resolvedValue) && !resolvedValue.includes('NaN')) {\n      resolvedValue = serializeCalc(resolvedValue, opt);\n    } else if (REG_FN_CALC_NUM.test(resolvedValue)) {\n      const [, val] = resolvedValue.match(REG_FN_CALC_NUM) as MatchedRegExp;\n      resolvedValue = `calc(${roundToPrecision(Number(val), HEX)})`;\n    }\n  }\n  setCache(cacheKey, resolvedValue);\n  return resolvedValue;\n};\n"],"mappings":"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"}