@common.js/formatjs__icu-messageformat-parser 3.5.12 → 3.5.13

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -2,4 +2,4 @@
2
2
 
3
3
  The [@formatjs/icu-messageformat-parser](https://www.npmjs.com/package/@formatjs/icu-messageformat-parser) package exported as CommonJS modules.
4
4
 
5
- Exported from [@formatjs/icu-messageformat-parser@3.5.12](https://www.npmjs.com/package/@formatjs/icu-messageformat-parser/v/3.5.12) using https://github.com/etienne-martin/common.js.
5
+ Exported from [@formatjs/icu-messageformat-parser@3.5.13](https://www.npmjs.com/package/@formatjs/icu-messageformat-parser/v/3.5.13) using https://github.com/etienne-martin/common.js.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@common.js/formatjs__icu-messageformat-parser",
3
- "version": "3.5.12",
3
+ "version": "3.5.13",
4
4
  "license": "MIT",
5
5
  "repository": "etienne-martin/common.js",
6
6
  "type": "commonjs",
package/printer.js CHANGED
@@ -180,13 +180,28 @@ function findBraceSyntaxEnd(message, index) {
180
180
  }
181
181
  function printEscapedMessage(message) {
182
182
  var isInPlural = arguments.length > 1 && arguments[1] !== void 0 ? arguments[1] : false;
183
+ var flushQuotedToken = function flushQuotedToken() {
184
+ if (quotedStart === -1) return;
185
+ var literal = message.slice(literalStart, quotedStart);
186
+ result += literal;
187
+ if (literal.endsWith("'")) result += "'";
188
+ result += quoteSyntaxToken(message.slice(quotedStart, quotedEnd));
189
+ literalStart = quotedEnd;
190
+ quotedStart = -1;
191
+ };
183
192
  var quoteToken = function quoteToken(start, end) {
184
- result += message.slice(literalStart, start);
185
- result += quoteSyntaxToken(message.slice(start, end));
186
- literalStart = end;
193
+ if (quotedStart !== -1 && start === quotedEnd) {
194
+ quotedEnd = end;
195
+ return;
196
+ }
197
+ flushQuotedToken();
198
+ quotedStart = start;
199
+ quotedEnd = end;
187
200
  };
188
201
  var result = "";
189
202
  var literalStart = 0;
203
+ var quotedStart = -1;
204
+ var quotedEnd = -1;
190
205
  for(var i = 0; i < message.length; i++){
191
206
  var ch = message[i];
192
207
  if (ch === "{") {
@@ -200,6 +215,7 @@ function printEscapedMessage(message) {
200
215
  i = end1 - 1;
201
216
  } else if (isInPlural && ch === "#") quoteToken(i, i + 1);
202
217
  }
218
+ flushQuotedToken();
203
219
  return result + message.slice(literalStart);
204
220
  }
205
221
  function printLiteralElement(param, isInPlural, isFirstEl, isLastEl) {
package/printer.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"printer.js","names":[],"sources":["../types.ts","../printer.ts"],"sourcesContent":["import type {NumberFormatOptions} from '#packages/ecma402-abstract/types/number.js'\nimport {type NumberSkeletonToken} from '@formatjs/icu-skeleton-parser'\n\nexport interface ExtendedNumberFormatOptions extends NumberFormatOptions {\n scale?: number\n}\n\nexport enum TYPE {\n /**\n * Raw text\n */\n literal,\n /**\n * Variable w/o any format, e.g `var` in `this is a {var}`\n */\n argument,\n /**\n * Variable w/ number format\n */\n number,\n /**\n * Variable w/ date format\n */\n date,\n /**\n * Variable w/ time format\n */\n time,\n /**\n * Variable w/ select format\n */\n select,\n /**\n * Variable w/ plural format\n */\n plural,\n /**\n * Only possible within plural argument.\n * This is the `#` symbol that will be substituted with the count.\n */\n pound,\n /**\n * XML-like tag\n */\n tag,\n}\n\nexport enum SKELETON_TYPE {\n number,\n dateTime,\n}\n\nexport interface LocationDetails {\n offset: number\n line: number\n column: number\n}\nexport interface Location {\n start: LocationDetails\n end: LocationDetails\n}\n\nexport interface BaseElement<T extends TYPE> {\n type: T\n value: string\n location?: Location\n}\n\nexport type LiteralElement = BaseElement<TYPE.literal>\nexport type ArgumentElement = BaseElement<TYPE.argument>\nexport interface TagElement extends BaseElement<TYPE.tag> {\n children: MessageFormatElement[]\n}\n\nexport interface SimpleFormatElement<\n T extends TYPE,\n S extends Skeleton,\n> extends BaseElement<T> {\n style?: string | S | null\n}\n\nexport type NumberElement = SimpleFormatElement<TYPE.number, NumberSkeleton>\nexport type DateElement = SimpleFormatElement<TYPE.date, DateTimeSkeleton>\nexport type TimeElement = SimpleFormatElement<TYPE.time, DateTimeSkeleton>\n\nexport type ValidPluralRule =\n | 'zero'\n | 'one'\n | 'two'\n | 'few'\n | 'many'\n | 'other'\n | string\n\nexport interface PluralOrSelectOption {\n value: MessageFormatElement[]\n location?: Location\n}\n\nexport interface SelectElement extends BaseElement<TYPE.select> {\n options: Record<string, PluralOrSelectOption>\n}\n\nexport interface PluralElement extends BaseElement<TYPE.plural> {\n options: Record<ValidPluralRule, PluralOrSelectOption>\n offset: number\n pluralType: Intl.PluralRulesOptions['type']\n}\n\nexport interface PoundElement {\n type: TYPE.pound\n location?: Location\n}\n\nexport type MessageFormatElement =\n | ArgumentElement\n | DateElement\n | LiteralElement\n | NumberElement\n | PluralElement\n | PoundElement\n | SelectElement\n | TagElement\n | TimeElement\n\nexport interface NumberSkeleton {\n type: SKELETON_TYPE.number\n tokens: NumberSkeletonToken[]\n location?: Location\n parsedOptions: ExtendedNumberFormatOptions\n}\n\nexport interface DateTimeSkeleton {\n type: SKELETON_TYPE.dateTime\n pattern: string\n location?: Location\n parsedOptions: Intl.DateTimeFormatOptions\n}\n\nexport type Skeleton = NumberSkeleton | DateTimeSkeleton\n\n/**\n * Type Guards\n */\nexport function isLiteralElement(\n el: MessageFormatElement\n): el is LiteralElement {\n return el.type === TYPE.literal\n}\nexport function isArgumentElement(\n el: MessageFormatElement\n): el is ArgumentElement {\n return el.type === TYPE.argument\n}\nexport function isNumberElement(el: MessageFormatElement): el is NumberElement {\n return el.type === TYPE.number\n}\nexport function isDateElement(el: MessageFormatElement): el is DateElement {\n return el.type === TYPE.date\n}\nexport function isTimeElement(el: MessageFormatElement): el is TimeElement {\n return el.type === TYPE.time\n}\nexport function isSelectElement(el: MessageFormatElement): el is SelectElement {\n return el.type === TYPE.select\n}\nexport function isPluralElement(el: MessageFormatElement): el is PluralElement {\n return el.type === TYPE.plural\n}\nexport function isPoundElement(el: MessageFormatElement): el is PoundElement {\n return el.type === TYPE.pound\n}\nexport function isTagElement(el: MessageFormatElement): el is TagElement {\n return el.type === TYPE.tag\n}\nexport function isNumberSkeleton(\n el: NumberElement['style'] | Skeleton\n): el is NumberSkeleton {\n return !!(el && typeof el === 'object' && el.type === SKELETON_TYPE.number)\n}\nexport function isDateTimeSkeleton(\n el?: DateElement['style'] | TimeElement['style'] | Skeleton\n): el is DateTimeSkeleton {\n return !!(el && typeof el === 'object' && el.type === SKELETON_TYPE.dateTime)\n}\n\nexport function createLiteralElement(value: string): LiteralElement {\n return {\n type: TYPE.literal,\n value,\n }\n}\n\nexport function createNumberElement(\n value: string,\n style?: string | null\n): NumberElement {\n return {\n type: TYPE.number,\n value,\n style,\n }\n}\n","import {type NumberSkeletonToken} from '@formatjs/icu-skeleton-parser'\nimport {\n type ArgumentElement,\n type DateElement,\n type DateTimeSkeleton,\n isArgumentElement,\n isDateElement,\n isLiteralElement,\n isNumberElement,\n isPluralElement,\n isPoundElement,\n isSelectElement,\n isTagElement,\n isTimeElement,\n type LiteralElement,\n type MessageFormatElement,\n type NumberElement,\n type PluralElement,\n type SelectElement,\n type Skeleton,\n SKELETON_TYPE,\n type TagElement,\n type TimeElement,\n TYPE,\n} from '#packages/icu-messageformat-parser/types.js'\n\nexport function printAST(ast: MessageFormatElement[]): string {\n return doPrintAST(ast, false)\n}\n\nexport function doPrintAST(\n ast: MessageFormatElement[],\n isInPlural: boolean\n): string {\n const printedNodes = ast.map((el, i) => {\n if (isLiteralElement(el)) {\n return printLiteralElement(el, isInPlural, i === 0, i === ast.length - 1)\n }\n\n if (isArgumentElement(el)) {\n return printArgumentElement(el)\n }\n if (isDateElement(el) || isTimeElement(el) || isNumberElement(el)) {\n return printSimpleFormatElement(el)\n }\n\n if (isPluralElement(el)) {\n return printPluralElement(el)\n }\n\n if (isSelectElement(el)) {\n return printSelectElement(el)\n }\n\n if (isPoundElement(el)) {\n return '#'\n }\n if (isTagElement(el)) {\n return printTagElement(el)\n }\n })\n\n return printedNodes.join('')\n}\n\nfunction printTagElement(el: TagElement): string {\n return `<${el.value}>${printAST(el.children)}</${el.value}>`\n}\n\nfunction quoteSyntaxToken(token: string): string {\n return `'${token.split(\"'\").join(\"''\")}'`\n}\n\nfunction isAlpha(ch: string | undefined): boolean {\n if (!ch) {\n return false\n }\n const code = ch.charCodeAt(0)\n return (code >= 65 && code <= 90) || (code >= 97 && code <= 122)\n}\n\nfunction isTagSyntaxStart(message: string, index: number): boolean {\n if (message[index] !== '<') {\n return false\n }\n const next = message[index + 1]\n return next === '/' || isAlpha(next)\n}\n\nfunction findTagSyntaxEnd(message: string, index: number): number {\n const closingIndex = message.indexOf('>', index + 1)\n return closingIndex === -1 ? message.length : closingIndex + 1\n}\n\nfunction findBraceSyntaxEnd(message: string, index: number): number {\n const closingIndex = message.indexOf('}', index + 1)\n return closingIndex === -1 ? index + 1 : closingIndex + 1\n}\n\nfunction printEscapedMessage(message: string, isInPlural = false): string {\n let result = ''\n let literalStart = 0\n\n function quoteToken(start: number, end: number) {\n result += message.slice(literalStart, start)\n result += quoteSyntaxToken(message.slice(start, end))\n literalStart = end\n }\n\n for (let i = 0; i < message.length; i++) {\n const ch = message[i]\n if (ch === '{') {\n const end = findBraceSyntaxEnd(message, i)\n quoteToken(i, end)\n i = end - 1\n } else if (ch === '}') {\n quoteToken(i, i + 1)\n } else if (isTagSyntaxStart(message, i)) {\n const end = findTagSyntaxEnd(message, i)\n quoteToken(i, end)\n i = end - 1\n } else if (isInPlural && ch === '#') {\n quoteToken(i, i + 1)\n }\n }\n\n return result + message.slice(literalStart)\n}\n\nfunction printLiteralElement(\n {value}: LiteralElement,\n isInPlural: boolean,\n isFirstEl: boolean,\n isLastEl: boolean\n) {\n let escaped = value\n // If this literal starts with a ' and its not the 1st node, this means the node before it is non-literal\n // and the `'` needs to be unescaped\n if (!isFirstEl && escaped[0] === `'`) {\n escaped = `''${escaped.slice(1)}`\n }\n // Same logic but for last el\n if (!isLastEl && escaped[escaped.length - 1] === `'`) {\n escaped = `${escaped.slice(0, escaped.length - 1)}''`\n }\n return printEscapedMessage(escaped, isInPlural)\n}\n\nfunction printArgumentElement({value}: ArgumentElement) {\n return `{${value}}`\n}\n\nfunction printSimpleFormatElement(\n el: DateElement | TimeElement | NumberElement\n) {\n return `{${el.value}, ${TYPE[el.type]}${\n el.style ? `, ${printArgumentStyle(el.style)}` : ''\n }}`\n}\n\nfunction printNumberSkeletonToken(token: NumberSkeletonToken): string {\n const {stem, options} = token\n return options.length === 0\n ? stem\n : `${stem}${options.map(o => `/${o}`).join('')}`\n}\n\nfunction printArgumentStyle(style: string | Skeleton) {\n if (typeof style === 'string') {\n return printEscapedMessage(style)\n } else if (style.type === SKELETON_TYPE.dateTime) {\n return `::${printDateTimeSkeleton(style)}`\n } else {\n return `::${style.tokens.map(printNumberSkeletonToken).join(' ')}`\n }\n}\n\nexport function printDateTimeSkeleton(style: DateTimeSkeleton): string {\n return style.pattern\n}\n\n// Rust string ordering is UTF-8 lexicographic, which matches code point order.\nfunction compareCodePoints(a: string, b: string): number {\n const aIter = a[Symbol.iterator]()\n const bIter = b[Symbol.iterator]()\n\n while (true) {\n const aNext = aIter.next()\n const bNext = bIter.next()\n if (aNext.done || bNext.done) {\n return aNext.done === bNext.done ? 0 : aNext.done ? -1 : 1\n }\n\n const diff = aNext.value.codePointAt(0)! - bNext.value.codePointAt(0)!\n if (diff !== 0) {\n return diff\n }\n }\n}\n\nfunction printSelectElement(el: SelectElement) {\n const keys = Object.keys(el.options).sort(compareCodePoints)\n const msg = [\n el.value,\n 'select',\n keys\n .map(id => `${id}{${doPrintAST(el.options[id].value, false)}}`)\n .join(' '),\n ].join(',')\n return `{${msg}}`\n}\n\nconst PLURAL_RULE_ORDER: Record<string, number> = {\n zero: 0,\n one: 1,\n two: 2,\n few: 3,\n many: 4,\n other: 5,\n}\n\nfunction getPluralRuleSortOrder(rule: string): [number, number] {\n const categoryOrder = PLURAL_RULE_ORDER[rule]\n if (categoryOrder !== undefined) {\n return [categoryOrder, 0]\n }\n\n const exactRule = rule.replace(/^=+/, '')\n const exactValue = /^[+-]?\\d+$/.test(exactRule) ? Number(exactRule) : 0\n return [6, exactValue]\n}\n\nfunction printPluralElement(el: PluralElement) {\n const type = el.pluralType === 'cardinal' ? 'plural' : 'selectordinal'\n const keys = Object.keys(el.options).sort((a, b) => {\n const [pa, sa] = getPluralRuleSortOrder(a)\n const [pb, sb] = getPluralRuleSortOrder(b)\n return pa - pb || sa - sb\n })\n const msg = [\n el.value,\n type,\n [\n el.offset ? `offset:${el.offset}` : '',\n ...keys.map(id => `${id}{${doPrintAST(el.options[id].value, true)}}`),\n ]\n .filter(Boolean)\n .join(' '),\n ].join(',')\n return `{${msg}}`\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"printer.js","names":[],"sources":["../types.ts","../printer.ts"],"sourcesContent":["import type {NumberFormatOptions} from '#packages/ecma402-abstract/types/number.js'\nimport {type NumberSkeletonToken} from '@formatjs/icu-skeleton-parser'\n\nexport interface ExtendedNumberFormatOptions extends NumberFormatOptions {\n scale?: number\n}\n\nexport enum TYPE {\n /**\n * Raw text\n */\n literal,\n /**\n * Variable w/o any format, e.g `var` in `this is a {var}`\n */\n argument,\n /**\n * Variable w/ number format\n */\n number,\n /**\n * Variable w/ date format\n */\n date,\n /**\n * Variable w/ time format\n */\n time,\n /**\n * Variable w/ select format\n */\n select,\n /**\n * Variable w/ plural format\n */\n plural,\n /**\n * Only possible within plural argument.\n * This is the `#` symbol that will be substituted with the count.\n */\n pound,\n /**\n * XML-like tag\n */\n tag,\n}\n\nexport enum SKELETON_TYPE {\n number,\n dateTime,\n}\n\nexport interface LocationDetails {\n offset: number\n line: number\n column: number\n}\nexport interface Location {\n start: LocationDetails\n end: LocationDetails\n}\n\nexport interface BaseElement<T extends TYPE> {\n type: T\n value: string\n location?: Location\n}\n\nexport type LiteralElement = BaseElement<TYPE.literal>\nexport type ArgumentElement = BaseElement<TYPE.argument>\nexport interface TagElement extends BaseElement<TYPE.tag> {\n children: MessageFormatElement[]\n}\n\nexport interface SimpleFormatElement<\n T extends TYPE,\n S extends Skeleton,\n> extends BaseElement<T> {\n style?: string | S | null\n}\n\nexport type NumberElement = SimpleFormatElement<TYPE.number, NumberSkeleton>\nexport type DateElement = SimpleFormatElement<TYPE.date, DateTimeSkeleton>\nexport type TimeElement = SimpleFormatElement<TYPE.time, DateTimeSkeleton>\n\nexport type ValidPluralRule =\n | 'zero'\n | 'one'\n | 'two'\n | 'few'\n | 'many'\n | 'other'\n | string\n\nexport interface PluralOrSelectOption {\n value: MessageFormatElement[]\n location?: Location\n}\n\nexport interface SelectElement extends BaseElement<TYPE.select> {\n options: Record<string, PluralOrSelectOption>\n}\n\nexport interface PluralElement extends BaseElement<TYPE.plural> {\n options: Record<ValidPluralRule, PluralOrSelectOption>\n offset: number\n pluralType: Intl.PluralRulesOptions['type']\n}\n\nexport interface PoundElement {\n type: TYPE.pound\n location?: Location\n}\n\nexport type MessageFormatElement =\n | ArgumentElement\n | DateElement\n | LiteralElement\n | NumberElement\n | PluralElement\n | PoundElement\n | SelectElement\n | TagElement\n | TimeElement\n\nexport interface NumberSkeleton {\n type: SKELETON_TYPE.number\n tokens: NumberSkeletonToken[]\n location?: Location\n parsedOptions: ExtendedNumberFormatOptions\n}\n\nexport interface DateTimeSkeleton {\n type: SKELETON_TYPE.dateTime\n pattern: string\n location?: Location\n parsedOptions: Intl.DateTimeFormatOptions\n}\n\nexport type Skeleton = NumberSkeleton | DateTimeSkeleton\n\n/**\n * Type Guards\n */\nexport function isLiteralElement(\n el: MessageFormatElement\n): el is LiteralElement {\n return el.type === TYPE.literal\n}\nexport function isArgumentElement(\n el: MessageFormatElement\n): el is ArgumentElement {\n return el.type === TYPE.argument\n}\nexport function isNumberElement(el: MessageFormatElement): el is NumberElement {\n return el.type === TYPE.number\n}\nexport function isDateElement(el: MessageFormatElement): el is DateElement {\n return el.type === TYPE.date\n}\nexport function isTimeElement(el: MessageFormatElement): el is TimeElement {\n return el.type === TYPE.time\n}\nexport function isSelectElement(el: MessageFormatElement): el is SelectElement {\n return el.type === TYPE.select\n}\nexport function isPluralElement(el: MessageFormatElement): el is PluralElement {\n return el.type === TYPE.plural\n}\nexport function isPoundElement(el: MessageFormatElement): el is PoundElement {\n return el.type === TYPE.pound\n}\nexport function isTagElement(el: MessageFormatElement): el is TagElement {\n return el.type === TYPE.tag\n}\nexport function isNumberSkeleton(\n el: NumberElement['style'] | Skeleton\n): el is NumberSkeleton {\n return !!(el && typeof el === 'object' && el.type === SKELETON_TYPE.number)\n}\nexport function isDateTimeSkeleton(\n el?: DateElement['style'] | TimeElement['style'] | Skeleton\n): el is DateTimeSkeleton {\n return !!(el && typeof el === 'object' && el.type === SKELETON_TYPE.dateTime)\n}\n\nexport function createLiteralElement(value: string): LiteralElement {\n return {\n type: TYPE.literal,\n value,\n }\n}\n\nexport function createNumberElement(\n value: string,\n style?: string | null\n): NumberElement {\n return {\n type: TYPE.number,\n value,\n style,\n }\n}\n","import {type NumberSkeletonToken} from '@formatjs/icu-skeleton-parser'\nimport {\n type ArgumentElement,\n type DateElement,\n type DateTimeSkeleton,\n isArgumentElement,\n isDateElement,\n isLiteralElement,\n isNumberElement,\n isPluralElement,\n isPoundElement,\n isSelectElement,\n isTagElement,\n isTimeElement,\n type LiteralElement,\n type MessageFormatElement,\n type NumberElement,\n type PluralElement,\n type SelectElement,\n type Skeleton,\n SKELETON_TYPE,\n type TagElement,\n type TimeElement,\n TYPE,\n} from '#packages/icu-messageformat-parser/types.js'\n\nexport function printAST(ast: MessageFormatElement[]): string {\n return doPrintAST(ast, false)\n}\n\nexport function doPrintAST(\n ast: MessageFormatElement[],\n isInPlural: boolean\n): string {\n const printedNodes = ast.map((el, i) => {\n if (isLiteralElement(el)) {\n return printLiteralElement(el, isInPlural, i === 0, i === ast.length - 1)\n }\n\n if (isArgumentElement(el)) {\n return printArgumentElement(el)\n }\n if (isDateElement(el) || isTimeElement(el) || isNumberElement(el)) {\n return printSimpleFormatElement(el)\n }\n\n if (isPluralElement(el)) {\n return printPluralElement(el)\n }\n\n if (isSelectElement(el)) {\n return printSelectElement(el)\n }\n\n if (isPoundElement(el)) {\n return '#'\n }\n if (isTagElement(el)) {\n return printTagElement(el)\n }\n })\n\n return printedNodes.join('')\n}\n\nfunction printTagElement(el: TagElement): string {\n return `<${el.value}>${printAST(el.children)}</${el.value}>`\n}\n\nfunction quoteSyntaxToken(token: string): string {\n return `'${token.split(\"'\").join(\"''\")}'`\n}\n\nfunction isAlpha(ch: string | undefined): boolean {\n if (!ch) {\n return false\n }\n const code = ch.charCodeAt(0)\n return (code >= 65 && code <= 90) || (code >= 97 && code <= 122)\n}\n\nfunction isTagSyntaxStart(message: string, index: number): boolean {\n if (message[index] !== '<') {\n return false\n }\n const next = message[index + 1]\n return next === '/' || isAlpha(next)\n}\n\nfunction findTagSyntaxEnd(message: string, index: number): number {\n const closingIndex = message.indexOf('>', index + 1)\n return closingIndex === -1 ? message.length : closingIndex + 1\n}\n\nfunction findBraceSyntaxEnd(message: string, index: number): number {\n const closingIndex = message.indexOf('}', index + 1)\n return closingIndex === -1 ? index + 1 : closingIndex + 1\n}\n\nfunction printEscapedMessage(message: string, isInPlural = false): string {\n let result = ''\n let literalStart = 0\n let quotedStart = -1\n let quotedEnd = -1\n\n function flushQuotedToken() {\n if (quotedStart === -1) {\n return\n }\n\n const literal = message.slice(literalStart, quotedStart)\n result += literal\n if (literal.endsWith(\"'\")) {\n result += \"'\"\n }\n result += quoteSyntaxToken(message.slice(quotedStart, quotedEnd))\n literalStart = quotedEnd\n quotedStart = -1\n }\n\n function quoteToken(start: number, end: number) {\n if (quotedStart !== -1 && start === quotedEnd) {\n quotedEnd = end\n return\n }\n\n flushQuotedToken()\n quotedStart = start\n quotedEnd = end\n }\n\n for (let i = 0; i < message.length; i++) {\n const ch = message[i]\n if (ch === '{') {\n const end = findBraceSyntaxEnd(message, i)\n quoteToken(i, end)\n i = end - 1\n } else if (ch === '}') {\n quoteToken(i, i + 1)\n } else if (isTagSyntaxStart(message, i)) {\n const end = findTagSyntaxEnd(message, i)\n quoteToken(i, end)\n i = end - 1\n } else if (isInPlural && ch === '#') {\n quoteToken(i, i + 1)\n }\n }\n\n flushQuotedToken()\n return result + message.slice(literalStart)\n}\n\nfunction printLiteralElement(\n {value}: LiteralElement,\n isInPlural: boolean,\n isFirstEl: boolean,\n isLastEl: boolean\n) {\n let escaped = value\n // If this literal starts with a ' and its not the 1st node, this means the node before it is non-literal\n // and the `'` needs to be unescaped\n if (!isFirstEl && escaped[0] === `'`) {\n escaped = `''${escaped.slice(1)}`\n }\n // Same logic but for last el\n if (!isLastEl && escaped[escaped.length - 1] === `'`) {\n escaped = `${escaped.slice(0, escaped.length - 1)}''`\n }\n return printEscapedMessage(escaped, isInPlural)\n}\n\nfunction printArgumentElement({value}: ArgumentElement) {\n return `{${value}}`\n}\n\nfunction printSimpleFormatElement(\n el: DateElement | TimeElement | NumberElement\n) {\n return `{${el.value}, ${TYPE[el.type]}${\n el.style ? `, ${printArgumentStyle(el.style)}` : ''\n }}`\n}\n\nfunction printNumberSkeletonToken(token: NumberSkeletonToken): string {\n const {stem, options} = token\n return options.length === 0\n ? stem\n : `${stem}${options.map(o => `/${o}`).join('')}`\n}\n\nfunction printArgumentStyle(style: string | Skeleton) {\n if (typeof style === 'string') {\n return printEscapedMessage(style)\n } else if (style.type === SKELETON_TYPE.dateTime) {\n return `::${printDateTimeSkeleton(style)}`\n } else {\n return `::${style.tokens.map(printNumberSkeletonToken).join(' ')}`\n }\n}\n\nexport function printDateTimeSkeleton(style: DateTimeSkeleton): string {\n return style.pattern\n}\n\n// Rust string ordering is UTF-8 lexicographic, which matches code point order.\nfunction compareCodePoints(a: string, b: string): number {\n const aIter = a[Symbol.iterator]()\n const bIter = b[Symbol.iterator]()\n\n while (true) {\n const aNext = aIter.next()\n const bNext = bIter.next()\n if (aNext.done || bNext.done) {\n return aNext.done === bNext.done ? 0 : aNext.done ? -1 : 1\n }\n\n const diff = aNext.value.codePointAt(0)! - bNext.value.codePointAt(0)!\n if (diff !== 0) {\n return diff\n }\n }\n}\n\nfunction printSelectElement(el: SelectElement) {\n const keys = Object.keys(el.options).sort(compareCodePoints)\n const msg = [\n el.value,\n 'select',\n keys\n .map(id => `${id}{${doPrintAST(el.options[id].value, false)}}`)\n .join(' '),\n ].join(',')\n return `{${msg}}`\n}\n\nconst PLURAL_RULE_ORDER: Record<string, number> = {\n zero: 0,\n one: 1,\n two: 2,\n few: 3,\n many: 4,\n other: 5,\n}\n\nfunction getPluralRuleSortOrder(rule: string): [number, number] {\n const categoryOrder = PLURAL_RULE_ORDER[rule]\n if (categoryOrder !== undefined) {\n return [categoryOrder, 0]\n }\n\n const exactRule = rule.replace(/^=+/, '')\n const exactValue = /^[+-]?\\d+$/.test(exactRule) ? Number(exactRule) : 0\n return [6, exactValue]\n}\n\nfunction printPluralElement(el: PluralElement) {\n const type = el.pluralType === 'cardinal' ? 'plural' : 'selectordinal'\n const keys = Object.keys(el.options).sort((a, b) => {\n const [pa, sa] = getPluralRuleSortOrder(a)\n const [pb, sb] = getPluralRuleSortOrder(b)\n return pa - pb || sa - sb\n })\n const msg = [\n el.value,\n type,\n [\n el.offset ? `offset:${el.offset}` : '',\n ...keys.map(id => `${id}{${doPrintAST(el.options[id].value, true)}}`),\n ]\n .filter(Boolean)\n .join(' '),\n ].join(',')\n return `{${msg}}`\n}\n"],"mappings":"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"}