{"version":3,"file":"po.mjs","names":["insert","enu"],"sources":["../../../src/messageFormat/po.ts"],"sourcesContent":["import type { Dictionary } from '@intlayer/types/dictionary';\nimport * as NodeTypes from '@intlayer/types/nodeType';\nimport { deepTransformNode } from '../interpreter';\nimport { enu, gender, html, insert, plural } from '../transpiler';\nimport type { JsonValue } from './ICU';\n\nexport type PortableObject = {\n  msgid: string;\n  msgctxt?: string;\n  msgid_plural?: string;\n  msgstr: string[];\n};\n\n/**\n * Extracts the string value from a transformed AST node or generic object.\n */\nconst extractStringValue = (val: any): string => {\n  if (typeof val === 'string') return val;\n  if (val && typeof val === 'object' && 'msgstr' in val) {\n    return val.msgstr[0] || '';\n  }\n  return JSON.stringify(val);\n};\n\nconst intlayerToPoPlugin = {\n  canHandle: (node: any) => {\n    if (typeof node === 'string') return true;\n\n    if (\n      node &&\n      typeof node === 'object' &&\n      (node.nodeType === NodeTypes.INSERTION ||\n        node.nodeType === NodeTypes.HTML ||\n        node.nodeType === NodeTypes.ENUMERATION ||\n        node.nodeType === NodeTypes.PLURAL ||\n        node.nodeType === NodeTypes.GENDER ||\n        node.nodeType === 'composite')\n    ) {\n      return true;\n    }\n\n    // Handle structural string arrays (composite phrases)\n    if (Array.isArray(node)) {\n      if (node.length === 0) return false;\n      let hasNode = false;\n      let hasPlainObjectOrArray = false;\n\n      for (const item of node) {\n        if (typeof item === 'string') {\n        } else if (\n          item &&\n          typeof item === 'object' &&\n          (item.nodeType === NodeTypes.INSERTION ||\n            item.nodeType === NodeTypes.HTML ||\n            item.nodeType === NodeTypes.ENUMERATION ||\n            item.nodeType === NodeTypes.PLURAL ||\n            item.nodeType === NodeTypes.GENDER ||\n            item.nodeType === 'composite')\n        ) {\n          hasNode = true;\n        } else {\n          hasPlainObjectOrArray = true;\n        }\n      }\n\n      if (hasPlainObjectOrArray) return false;\n      if (!hasNode) return false;\n      return true;\n    }\n\n    return false;\n  },\n  transform: (node: any, props: any, next: any): PortableObject => {\n    // 1. Strings\n    if (typeof node === 'string') {\n      const poVal = node.replace(/\\{\\{([^}]+)\\}\\}/g, '%($1)s');\n      return { msgid: poVal, msgstr: [poVal] };\n    }\n\n    // 2. Insertions & Variables\n    if (node.nodeType === NodeTypes.INSERTION) {\n      return next(node[NodeTypes.INSERTION], props);\n    }\n\n    // 3. HTML\n    if (node.nodeType === NodeTypes.HTML) {\n      const val = node[NodeTypes.HTML];\n      return { msgid: val, msgstr: [val] };\n    }\n\n    // 4. Plurals & Enumerations\n    if (\n      node.nodeType === NodeTypes.PLURAL ||\n      node.nodeType === NodeTypes.ENUMERATION\n    ) {\n      const isPlural = node.nodeType === NodeTypes.PLURAL;\n      const options = isPlural\n        ? node[NodeTypes.PLURAL]\n        : node[NodeTypes.ENUMERATION];\n\n      const rawMsgid = isPlural\n        ? options.one || options.other || options.fallback\n        : options.fallback || options['0'];\n\n      const msgid = extractStringValue(next(rawMsgid, props));\n      const msgid_plural = isPlural\n        ? extractStringValue(\n            next(options.other || options.fallback || rawMsgid, props)\n          )\n        : extractStringValue(next(options.fallback || rawMsgid, props));\n\n      const msgstr: string[] = [];\n\n      if (isPlural) {\n        // Standard CLDR/Gettext mapping fallback\n        if ('zero' in options)\n          msgstr.push(extractStringValue(next(options.zero, props)));\n        msgstr.push(\n          extractStringValue(next(options.one || options.fallback, props))\n        );\n        if ('two' in options)\n          msgstr.push(extractStringValue(next(options.two, props)));\n        if ('few' in options)\n          msgstr.push(extractStringValue(next(options.few, props)));\n        if ('many' in options)\n          msgstr.push(extractStringValue(next(options.many, props)));\n\n        // Ensure 'other' is always the last fallback if others are missing\n        const otherVal = extractStringValue(\n          next(options.other || options.fallback, props)\n        );\n        if (!msgstr.includes(otherVal)) msgstr.push(otherVal);\n      } else {\n        // Enums don't have standard PO mapping, pack linearly\n        msgstr[0] = extractStringValue(\n          next(options.fallback || options['0'], props)\n        );\n        msgstr[1] = msgstr[0];\n      }\n\n      return {\n        msgctxt: isPlural ? undefined : 'enumeration',\n        msgid,\n        msgid_plural,\n        msgstr,\n      };\n    }\n\n    // 5. Gender (mapped to PO via msgctxt)\n    if (node.nodeType === NodeTypes.GENDER) {\n      const options = node[NodeTypes.GENDER];\n      const fallback = extractStringValue(next(options.fallback, props));\n      return {\n        msgctxt: 'gender',\n        msgid: fallback,\n        msgstr: [\n          extractStringValue(next(options.male || options.fallback, props)),\n          extractStringValue(next(options.female || options.fallback, props)),\n          fallback,\n        ],\n      };\n    }\n\n    // 6. Arrays / Composites\n    if (\n      Array.isArray(node) ||\n      (node.nodeType === 'composite' && Array.isArray(node.composite))\n    ) {\n      const arr = Array.isArray(node) ? node : node.composite;\n      const combined = arr\n        .map((item: any) => extractStringValue(next(item, props)))\n        .join('');\n      return { msgid: combined, msgstr: [combined] };\n    }\n\n    return node;\n  },\n};\n\nconst poToIntlayerPlugin = {\n  canHandle: (node: any) =>\n    node && typeof node === 'object' && 'msgid' in node && 'msgstr' in node,\n\n  transform: (node: PortableObject) => {\n    const msgstr = node.msgstr || [];\n    const isPlural = Boolean(node.msgid_plural) || msgstr.length > 1;\n\n    const processString = (str: string) => {\n      if (!str) return '';\n      // Convert Python/C-style gettext variables %(name)s or %(name)d -> {{name}}\n      const parsed = str.replace(/%\\(([a-zA-Z0-9_-]+)\\)[sdf]/g, '{{$1}}');\n\n      if (/<[a-zA-Z0-9-]+[^>]*>/.test(parsed)) return html(parsed);\n      if (parsed.includes('{{')) return insert(parsed);\n      return parsed;\n    };\n\n    // Fast-path: Single string translation\n    if (!isPlural) {\n      return processString(msgstr[0] || node.msgid || '');\n    }\n\n    // Handle Plural/Enum/Gender matrix\n    const options: Record<string, any> = {};\n\n    if (node.msgctxt === 'gender') {\n      return gender({\n        male: processString(msgstr[0] || node.msgid),\n        female: processString(msgstr[1] || msgstr[0]),\n        fallback: processString(msgstr[2] || msgstr[msgstr.length - 1]),\n      });\n    }\n\n    if (node.msgctxt === 'enumeration') {\n      return enu({\n        '0': processString(msgstr[0]),\n        fallback: processString(msgstr[msgstr.length - 1]),\n      });\n    }\n\n    // Plural Form Mapping based on array length (Gettext Plural-Forms approximation)\n    if (msgstr.length === 2) {\n      options.one = processString(msgstr[0]);\n      options.other = processString(msgstr[1]);\n    } else if (msgstr.length === 3) {\n      // E.g., Polish/Russian: one, few, many/other\n      options.one = processString(msgstr[0]);\n      options.few = processString(msgstr[1]);\n      options.other = processString(msgstr[2]);\n    } else if (msgstr.length === 6) {\n      // E.g., Arabic: zero, one, two, few, many, other\n      options.zero = processString(msgstr[0]);\n      options.one = processString(msgstr[1]);\n      options.two = processString(msgstr[2]);\n      options.few = processString(msgstr[3]);\n      options.many = processString(msgstr[4]);\n      options.other = processString(msgstr[5]);\n    } else {\n      // Generic arbitrary length mapping\n      options.one = processString(msgstr[0]);\n      options.other = processString(msgstr[msgstr.length - 1]);\n      for (let i = 1; i < msgstr.length - 1; i++) {\n        options[`${i + 1}`] = processString(msgstr[i]);\n      }\n    }\n\n    return plural(options as any);\n  },\n};\n\nexport const intlayerToPortableObjectFormatter = (\n  dictionary: Dictionary['content']\n): JsonValue => {\n  return deepTransformNode(dictionary, {\n    dictionaryKey: 'po',\n    keyPath: [],\n    plugins: [{ id: 'po', ...intlayerToPoPlugin }],\n  });\n};\n\nexport const portableObjectToIntlayerFormatter = (\n  message: JsonValue\n): Dictionary['content'] => {\n  return deepTransformNode(message, {\n    dictionaryKey: 'po',\n    keyPath: [],\n    plugins: [{ id: 'po', ...poToIntlayerPlugin }],\n  });\n};\n"],"mappings":"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"}