{"version":3,"file":"formats-CCylUHZw.mjs","names":[],"sources":["../src/batteries/media/formats.ts"],"sourcesContent":["/**\n * MIME tables and format-family classification for the media pipeline.\n *\n * @remarks\n * Internal sibling of the `@nhtio/adk/batteries/media` entry. Ported from the source server's\n * `format_families.ts` support tiers, reshaped for the DSL's verb-applicability checks:\n *\n * - Tier 1 (full read + mutate): OOXML (docx/xlsx/pptx) and ODF (odt/ods/odp, via a normalize\n *   engine), plus PDF for page-level operations.\n * - Tier 2 (extraction only): legacy Office (doc/xls/ppt) and Apple iWork — mutation verbs\n *   reject these with a reason string rather than a throw, so callers can surface\n *   model-actionable failures.\n * - Everything else classifies by top-level MIME family (image/audio/text).\n */\n\nimport type { FormatFamily } from './verbs'\n\n/** Well-known MIME constants used across the battery. */\nexport const MIME = {\n  DOCX: 'application/vnd.openxmlformats-officedocument.wordprocessingml.document',\n  XLSX: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',\n  PPTX: 'application/vnd.openxmlformats-officedocument.presentationml.presentation',\n  ODT: 'application/vnd.oasis.opendocument.text',\n  ODS: 'application/vnd.oasis.opendocument.spreadsheet',\n  ODP: 'application/vnd.oasis.opendocument.presentation',\n  PDF: 'application/pdf',\n  DOC: 'application/msword',\n  XLS: 'application/vnd.ms-excel',\n  PPT: 'application/vnd.ms-powerpoint',\n  PAGES: 'application/x-iwork-pages-sffpages',\n  NUMBERS: 'application/x-iwork-numbers-sffnumbers',\n  KEYNOTE: 'application/x-iwork-keynote-sffkey',\n  XLSM: 'application/vnd.ms-excel.sheet.macroEnabled.12',\n  XLSB: 'application/vnd.ms-excel.sheet.binary.macroEnabled.12',\n  FODS: 'application/vnd.oasis.opendocument.spreadsheet-flat-xml',\n  SYLK: 'application/x-sylk',\n  DIF: 'application/x-dif',\n  DBF: 'application/x-dbf',\n  TXT: 'text/plain',\n  MD: 'text/markdown',\n  CSV: 'text/csv',\n  HTML: 'text/html',\n  JSON: 'application/json',\n  YAML: 'application/yaml',\n  PNG: 'image/png',\n  JPEG: 'image/jpeg',\n  WEBP: 'image/webp',\n  TIFF: 'image/tiff',\n  AVIF: 'image/avif',\n  WAV: 'audio/wav',\n  MP3: 'audio/mpeg',\n} as const\n\n/** Legacy Office MIME types (extraction only — mutation is rejected). */\nexport const LEGACY_OFFICE_MIMES: ReadonlySet<string> = new Set([MIME.DOC, MIME.XLS, MIME.PPT])\n\n/** Apple iWork MIME types (extraction only — mutation is rejected). */\nexport const IWORK_MIMES: ReadonlySet<string> = new Set([MIME.PAGES, MIME.NUMBERS, MIME.KEYNOTE])\n\n/** Every MIME the battery classifies as a spreadsheet (drives verb applicability + normalize). */\nexport const SPREADSHEET_MIMES: ReadonlySet<string> = new Set([\n  MIME.XLSX,\n  MIME.XLSM,\n  MIME.XLSB,\n  MIME.ODS,\n  MIME.FODS,\n  MIME.XLS,\n  MIME.CSV,\n  MIME.NUMBERS,\n  MIME.SYLK,\n  MIME.DIF,\n  MIME.DBF,\n])\nconst PRESENTATION_MIMES: ReadonlySet<string> = new Set([\n  MIME.PPTX,\n  MIME.ODP,\n  MIME.PPT,\n  MIME.KEYNOTE,\n])\nconst DOCUMENT_MIMES: ReadonlySet<string> = new Set([\n  MIME.PDF,\n  MIME.DOCX,\n  MIME.ODT,\n  MIME.DOC,\n  MIME.PAGES,\n  MIME.TXT,\n  MIME.MD,\n  MIME.HTML,\n  MIME.JSON,\n  MIME.YAML,\n  'application/rtf',\n  'text/rtf',\n])\n\n/**\n * Classify a MIME type into the verb table's broad format family.\n *\n * @param mimeType - The media MIME type.\n * @returns The family used by verb-applicability checks.\n */\nexport const familyOf = (mimeType: string): FormatFamily => {\n  const mime = mimeType.toLowerCase().split(';')[0].trim()\n  if (SPREADSHEET_MIMES.has(mime)) return 'spreadsheet'\n  if (PRESENTATION_MIMES.has(mime)) return 'presentation'\n  if (DOCUMENT_MIMES.has(mime)) return 'document'\n  if (mime.startsWith('image/')) return 'image'\n  if (mime.startsWith('audio/')) return 'audio'\n  if (mime.startsWith('text/')) return 'document'\n  return 'document'\n}\n\n/**\n * Reason a mutation verb cannot run against this MIME type, or `undefined` when mutation is\n * allowed. Returns a reason string (not a throw) so callers compose model-actionable failures.\n *\n * @param mimeType - The media MIME type.\n * @returns A human-readable reason, or `undefined` when mutation is supported.\n */\nexport const unsupportedForMutationReason = (mimeType: string): string | undefined => {\n  const mime = mimeType.toLowerCase().split(';')[0].trim()\n  if (LEGACY_OFFICE_MIMES.has(mime)) {\n    return `legacy Office format (${mime}) cannot be mutated in place and no configured engine converts it — convert it first (e.g. convert to=docx)`\n  }\n  if (IWORK_MIMES.has(mime)) {\n    return `Apple iWork format (${mime}) cannot be mutated in place and no configured engine converts it`\n  }\n  return undefined\n}\n\n/** A small extension → MIME lookup for filenames produced by transforms. */\nexport const EXT_TO_MIME: Readonly<Record<string, string>> = {\n  pdf: MIME.PDF,\n  docx: MIME.DOCX,\n  xlsx: MIME.XLSX,\n  pptx: MIME.PPTX,\n  odt: MIME.ODT,\n  ods: MIME.ODS,\n  odp: MIME.ODP,\n  doc: MIME.DOC,\n  xls: MIME.XLS,\n  ppt: MIME.PPT,\n  xlsm: MIME.XLSM,\n  xlsb: MIME.XLSB,\n  fods: MIME.FODS,\n  sylk: MIME.SYLK,\n  dif: MIME.DIF,\n  dbf: MIME.DBF,\n  numbers: MIME.NUMBERS,\n  txt: MIME.TXT,\n  md: MIME.MD,\n  csv: MIME.CSV,\n  html: MIME.HTML,\n  json: MIME.JSON,\n  yaml: MIME.YAML,\n  yml: MIME.YAML,\n  rtf: 'application/rtf',\n  png: MIME.PNG,\n  jpg: MIME.JPEG,\n  jpeg: MIME.JPEG,\n  webp: MIME.WEBP,\n  tiff: MIME.TIFF,\n  avif: MIME.AVIF,\n  wav: MIME.WAV,\n  mp3: MIME.MP3,\n}\n\n/**\n * Replace (or add) a filename's extension.\n *\n * @param filename - The original filename.\n * @param ext - The new extension, without the dot.\n * @returns The filename with the new extension.\n */\nexport const replaceExtension = (filename: string, ext: string): string => {\n  const dot = filename.lastIndexOf('.')\n  const base = dot > 0 ? filename.slice(0, dot) : filename\n  return `${base}.${ext}`\n}\n"],"mappings":";;AAkBA,IAAa,OAAO;CAClB,MAAM;CACN,MAAM;CACN,MAAM;CACN,KAAK;CACL,KAAK;CACL,KAAK;CACL,KAAK;CACL,KAAK;CACL,KAAK;CACL,KAAK;CACL,OAAO;CACP,SAAS;CACT,SAAS;CACT,MAAM;CACN,MAAM;CACN,MAAM;CACN,MAAM;CACN,KAAK;CACL,KAAK;CACL,KAAK;CACL,IAAI;CACJ,KAAK;CACL,MAAM;CACN,MAAM;CACN,MAAM;CACN,KAAK;CACL,MAAM;CACN,MAAM;CACN,MAAM;CACN,MAAM;CACN,KAAK;CACL,KAAK;AACP;;AAGA,IAAa,sBAA2C,IAAI,IAAI;CAAC,KAAK;CAAK,KAAK;CAAK,KAAK;AAAG,CAAC;;AAG9F,IAAa,cAAmC,IAAI,IAAI;CAAC,KAAK;CAAO,KAAK;CAAS,KAAK;AAAO,CAAC;;AAGhG,IAAa,oBAAyC,IAAI,IAAI;CAC5D,KAAK;CACL,KAAK;CACL,KAAK;CACL,KAAK;CACL,KAAK;CACL,KAAK;CACL,KAAK;CACL,KAAK;CACL,KAAK;CACL,KAAK;CACL,KAAK;AACP,CAAC;AACD,IAAM,qBAA0C,IAAI,IAAI;CACtD,KAAK;CACL,KAAK;CACL,KAAK;CACL,KAAK;AACP,CAAC;AACD,IAAM,iBAAsC,IAAI,IAAI;CAClD,KAAK;CACL,KAAK;CACL,KAAK;CACL,KAAK;CACL,KAAK;CACL,KAAK;CACL,KAAK;CACL,KAAK;CACL,KAAK;CACL,KAAK;CACL;CACA;AACF,CAAC;;;;;;;AAQD,IAAa,YAAY,aAAmC;CAC1D,MAAM,OAAO,SAAS,YAAY,EAAE,MAAM,GAAG,EAAE,GAAG,KAAK;CACvD,IAAI,kBAAkB,IAAI,IAAI,GAAG,OAAO;CACxC,IAAI,mBAAmB,IAAI,IAAI,GAAG,OAAO;CACzC,IAAI,eAAe,IAAI,IAAI,GAAG,OAAO;CACrC,IAAI,KAAK,WAAW,QAAQ,GAAG,OAAO;CACtC,IAAI,KAAK,WAAW,QAAQ,GAAG,OAAO;CACtC,IAAI,KAAK,WAAW,OAAO,GAAG,OAAO;CACrC,OAAO;AACT;;;;;;;;AASA,IAAa,gCAAgC,aAAyC;CACpF,MAAM,OAAO,SAAS,YAAY,EAAE,MAAM,GAAG,EAAE,GAAG,KAAK;CACvD,IAAI,oBAAoB,IAAI,IAAI,GAC9B,OAAO,yBAAyB,KAAK;CAEvC,IAAI,YAAY,IAAI,IAAI,GACtB,OAAO,uBAAuB,KAAK;AAGvC;;AAGA,IAAa,cAAgD;CAC3D,KAAK,KAAK;CACV,MAAM,KAAK;CACX,MAAM,KAAK;CACX,MAAM,KAAK;CACX,KAAK,KAAK;CACV,KAAK,KAAK;CACV,KAAK,KAAK;CACV,KAAK,KAAK;CACV,KAAK,KAAK;CACV,KAAK,KAAK;CACV,MAAM,KAAK;CACX,MAAM,KAAK;CACX,MAAM,KAAK;CACX,MAAM,KAAK;CACX,KAAK,KAAK;CACV,KAAK,KAAK;CACV,SAAS,KAAK;CACd,KAAK,KAAK;CACV,IAAI,KAAK;CACT,KAAK,KAAK;CACV,MAAM,KAAK;CACX,MAAM,KAAK;CACX,MAAM,KAAK;CACX,KAAK,KAAK;CACV,KAAK;CACL,KAAK,KAAK;CACV,KAAK,KAAK;CACV,MAAM,KAAK;CACX,MAAM,KAAK;CACX,MAAM,KAAK;CACX,MAAM,KAAK;CACX,KAAK,KAAK;CACV,KAAK,KAAK;AACZ;;;;;;;;AASA,IAAa,oBAAoB,UAAkB,QAAwB;CACzE,MAAM,MAAM,SAAS,YAAY,GAAG;CAEpC,OAAO,GADM,MAAM,IAAI,SAAS,MAAM,GAAG,GAAG,IAAI,SACjC,GAAG;AACpB"}