@aglyn/aglyn 1.0.0-beta.197 → 1.0.0-beta.199
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/package.json +11 -11
- package/src/lib/app-utils/docs-help.generated.d.ts +1 -1
- package/src/lib/app-utils/docs-help.generated.js +1 -0
- package/src/lib/app-utils/docs-help.generated.js.map +1 -1
- package/src/lib/app-utils/docs-index.generated.js +3 -3
- package/src/lib/app-utils/docs-index.generated.js.map +1 -1
- package/src/lib/app-utils/media-embedded-fields.d.ts +471 -0
- package/src/lib/app-utils/media-embedded-fields.js +619 -0
- package/src/lib/app-utils/media-embedded-fields.js.map +1 -0
- package/src/lib/app-utils/media-embedded-metadata/exif.d.ts +160 -0
- package/src/lib/app-utils/media-embedded-metadata/exif.js +1267 -0
- package/src/lib/app-utils/media-embedded-metadata/exif.js.map +1 -0
- package/src/lib/app-utils/media-embedded-metadata/gif.d.ts +44 -0
- package/src/lib/app-utils/media-embedded-metadata/gif.js +134 -0
- package/src/lib/app-utils/media-embedded-metadata/gif.js.map +1 -0
- package/src/lib/app-utils/media-embedded-metadata/heif.d.ts +23 -0
- package/src/lib/app-utils/media-embedded-metadata/heif.js +354 -0
- package/src/lib/app-utils/media-embedded-metadata/heif.js.map +1 -0
- package/src/lib/app-utils/media-embedded-metadata/icc.d.ts +22 -0
- package/src/lib/app-utils/media-embedded-metadata/icc.js +85 -0
- package/src/lib/app-utils/media-embedded-metadata/icc.js.map +1 -0
- package/src/lib/app-utils/media-embedded-metadata/image-blocks.d.ts +145 -0
- package/src/lib/app-utils/media-embedded-metadata/image-blocks.js +200 -0
- package/src/lib/app-utils/media-embedded-metadata/image-blocks.js.map +1 -0
- package/src/lib/app-utils/media-embedded-metadata/index.d.ts +93 -0
- package/src/lib/app-utils/media-embedded-metadata/index.js +744 -0
- package/src/lib/app-utils/media-embedded-metadata/index.js.map +1 -0
- package/src/lib/app-utils/media-embedded-metadata/iptc.d.ts +59 -0
- package/src/lib/app-utils/media-embedded-metadata/iptc.js +529 -0
- package/src/lib/app-utils/media-embedded-metadata/iptc.js.map +1 -0
- package/src/lib/app-utils/media-embedded-metadata/jpeg.d.ts +43 -0
- package/src/lib/app-utils/media-embedded-metadata/jpeg.js +456 -0
- package/src/lib/app-utils/media-embedded-metadata/jpeg.js.map +1 -0
- package/src/lib/app-utils/media-embedded-metadata/mp4.d.ts +37 -0
- package/src/lib/app-utils/media-embedded-metadata/mp4.js +621 -0
- package/src/lib/app-utils/media-embedded-metadata/mp4.js.map +1 -0
- package/src/lib/app-utils/media-embedded-metadata/ooxml.d.ts +131 -0
- package/src/lib/app-utils/media-embedded-metadata/ooxml.js +1058 -0
- package/src/lib/app-utils/media-embedded-metadata/ooxml.js.map +1 -0
- package/src/lib/app-utils/media-embedded-metadata/pdf-objects.d.ts +223 -0
- package/src/lib/app-utils/media-embedded-metadata/pdf-objects.js +936 -0
- package/src/lib/app-utils/media-embedded-metadata/pdf-objects.js.map +1 -0
- package/src/lib/app-utils/media-embedded-metadata/pdf.d.ts +82 -0
- package/src/lib/app-utils/media-embedded-metadata/pdf.js +1167 -0
- package/src/lib/app-utils/media-embedded-metadata/pdf.js.map +1 -0
- package/src/lib/app-utils/media-embedded-metadata/png.d.ts +41 -0
- package/src/lib/app-utils/media-embedded-metadata/png.js +512 -0
- package/src/lib/app-utils/media-embedded-metadata/png.js.map +1 -0
- package/src/lib/app-utils/media-embedded-metadata/svg.d.ts +30 -0
- package/src/lib/app-utils/media-embedded-metadata/svg.js +154 -0
- package/src/lib/app-utils/media-embedded-metadata/svg.js.map +1 -0
- package/src/lib/app-utils/media-embedded-metadata/tiff.d.ts +40 -0
- package/src/lib/app-utils/media-embedded-metadata/tiff.js +158 -0
- package/src/lib/app-utils/media-embedded-metadata/tiff.js.map +1 -0
- package/src/lib/app-utils/media-embedded-metadata/types.d.ts +60 -0
- package/src/lib/app-utils/media-embedded-metadata/types.js +32 -0
- package/src/lib/app-utils/media-embedded-metadata/types.js.map +1 -0
- package/src/lib/app-utils/media-embedded-metadata/webm.d.ts +26 -0
- package/src/lib/app-utils/media-embedded-metadata/webm.js +417 -0
- package/src/lib/app-utils/media-embedded-metadata/webm.js.map +1 -0
- package/src/lib/app-utils/media-embedded-metadata/webp.d.ts +37 -0
- package/src/lib/app-utils/media-embedded-metadata/webp.js +272 -0
- package/src/lib/app-utils/media-embedded-metadata/webp.js.map +1 -0
- package/src/lib/app-utils/media-embedded-metadata/xml.d.ts +231 -0
- package/src/lib/app-utils/media-embedded-metadata/xml.js +598 -0
- package/src/lib/app-utils/media-embedded-metadata/xml.js.map +1 -0
- package/src/lib/app-utils/media-embedded-metadata/xmp.d.ts +100 -0
- package/src/lib/app-utils/media-embedded-metadata/xmp.js +1475 -0
- package/src/lib/app-utils/media-embedded-metadata/xmp.js.map +1 -0
- package/src/lib/app-utils/media-embedded-metadata/zip.d.ts +93 -0
- package/src/lib/app-utils/media-embedded-metadata/zip.js +531 -0
- package/src/lib/app-utils/media-embedded-metadata/zip.js.map +1 -0
- package/src/lib/app-utils/name-search.d.ts +12 -0
- package/src/lib/app-utils/name-search.js +11 -0
- package/src/lib/app-utils/name-search.js.map +1 -1
- package/src/lib/foundation/definitions/platform.types.d.ts +11 -0
- package/src/lib/foundation/definitions/platform.types.js.map +1 -1
- package/src/server.d.ts +1 -0
- package/src/server.js +7 -0
- package/src/server.js.map +1 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../../../../../libs/aglyn/src/lib/app-utils/media-embedded-metadata/xmp.ts"],"sourcesContent":["/**\n * @license\n * Copyright 2026 Aglyn LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n/**\n * Reading and surgically editing an XMP packet (AGL-3331).\n *\n * XMP is RDF/XML (ISO 16684-1, \"XMP Part 1\"; Adobe's XMP Specification\n * Part 1 is the same text). The container writers — JPEG APP1, PNG iTXt,\n * WebP `XMP `, TIFF tag 700, a PDF `/Metadata` stream — hand this module\n * the packet as a string and take a string back; none of them parses it.\n *\n * ## Reading\n *\n * {@link readXmp} finds every `rdf:RDF` by namespace URI (prefixes are the\n * file's choice), reads each `rdf:Description` — properties written as\n * child elements AND as shorthand attributes — and folds the well-known\n * ones into canonical keys. Every other simple property, or array of\n * simple values, surfaces under an `xmp|<uri>|<local>` other key unless its\n * namespace is on the deny list of technical noise. Structured values\n * (structs, arrays of structs) are skipped: nothing here could edit them,\n * and a drawer row reading \"[object]\" helps nobody.\n *\n * ## Writing\n *\n * {@link writeXmp} edits the parsed DOM in place and serializes it with the\n * faithful serializer in `xml.ts`, so everything it did not touch — a\n * Lightroom develop history, face regions, the packet's padding — comes\n * out byte for byte. A property is changed where it lives (attribute or\n * element, whichever Description holds it); a new one is appended to the\n * first `rdf:Description` as an element, indented like its neighbors.\n */\n\nimport {\n embeddedFieldLabel,\n otherEmbeddedKey,\n parseOtherEmbeddedKey,\n} from '../media-embedded-fields'\nimport {\n type EmbeddedCandidate,\n type EmbeddedPatch,\n EmbeddedWriteError,\n} from './types'\nimport {\n attributeNamespace,\n createElement,\n createText,\n createWhitespace,\n elementChildren,\n hasNonXmlCharacters,\n insertChildren,\n isNamespaceDeclaration,\n isWhitespaceText,\n parseXml,\n prefixForNamespace,\n removeAttribute,\n replaceChildren,\n resolvePrefix,\n serializeXml,\n setAttribute,\n setTextContent,\n splitQName,\n textContent,\n walkElements,\n XML_NAMESPACE,\n type XmlAttribute,\n type XmlDocument,\n type XmlElement,\n type XmlNode,\n} from './xml'\n\n/** Namespace URIs, by the prefix their specifications use. */\nexport const XMP_NAMESPACES = {\n rdf: 'http://www.w3.org/1999/02/22-rdf-syntax-ns#',\n x: 'adobe:ns:meta/',\n dc: 'http://purl.org/dc/elements/1.1/',\n xmp: 'http://ns.adobe.com/xap/1.0/',\n xmpRights: 'http://ns.adobe.com/xap/1.0/rights/',\n xmpMM: 'http://ns.adobe.com/xap/1.0/mm/',\n xmpidq: 'http://ns.adobe.com/xmp/Identifier/qual/1.0/',\n xmpNote: 'http://ns.adobe.com/xmp/note/',\n xmpG: 'http://ns.adobe.com/xap/1.0/g/',\n xmpGImg: 'http://ns.adobe.com/xap/1.0/g/img/',\n xmpTPg: 'http://ns.adobe.com/xap/1.0/t/pg/',\n stEvt: 'http://ns.adobe.com/xap/1.0/sType/ResourceEvent#',\n stRef: 'http://ns.adobe.com/xap/1.0/sType/ResourceRef#',\n stDim: 'http://ns.adobe.com/xap/1.0/sType/Dimensions#',\n stFnt: 'http://ns.adobe.com/xap/1.0/sType/Font#',\n stArea: 'http://ns.adobe.com/xmp/sType/Area#',\n photoshop: 'http://ns.adobe.com/photoshop/1.0/',\n illustrator: 'http://ns.adobe.com/illustrator/1.0/',\n crs: 'http://ns.adobe.com/camera-raw-settings/1.0/',\n crss: 'http://ns.adobe.com/camera-raw-saved-settings/1.0/',\n tiff: 'http://ns.adobe.com/tiff/1.0/',\n exif: 'http://ns.adobe.com/exif/1.0/',\n exifEX: 'http://cipa.jp/exif/1.0/',\n aux: 'http://ns.adobe.com/exif/1.0/aux/',\n pdf: 'http://ns.adobe.com/pdf/1.3/',\n pdfx: 'http://ns.adobe.com/pdfx/1.3/',\n Iptc4xmpCore: 'http://iptc.org/std/Iptc4xmpCore/1.0/xmlns/',\n 'mwg-rs': 'http://www.metadataworkinggroup.com/schemas/regions/',\n cc: 'http://creativecommons.org/ns#',\n} as const\n\nconst NS = XMP_NAMESPACES\nconst RDF = NS.rdf\n\n/**\n * The prefix a NEW declaration uses for a namespace this module writes.\n * An existing binding of the URI, under any prefix, always wins.\n */\nconst CONVENTIONAL_PREFIX: Readonly<Record<string, string>> = {\n [NS.dc]: 'dc',\n [NS.photoshop]: 'photoshop',\n [NS.xmp]: 'xmp',\n [NS.xmpRights]: 'xmpRights',\n [NS.tiff]: 'tiff',\n [NS.exif]: 'exif',\n [NS.exifEX]: 'exifEX',\n [NS.aux]: 'aux',\n [NS.pdf]: 'pdf',\n [NS.Iptc4xmpCore]: 'Iptc4xmpCore',\n}\n\n/**\n * Read-side only: the URI an UNDECLARED prefix is taken to mean. An SVG's\n * `<metadata>` fragment is often cut out from under the `<svg>` element\n * that declared `rdf:` and `dc:`; without this, that fragment reads as\n * nothing at all. A declared prefix always resolves through its\n * declaration.\n */\nconst FALLBACK_NAMESPACE: Readonly<Record<string, string>> = Object.fromEntries(\n Object.entries(NS),\n)\n\n/** Namespaces too noisy or technical to show as \"other\" fields. */\nconst DENIED_NAMESPACES: ReadonlySet<string> = new Set([\n NS.xmpMM,\n NS.stEvt,\n NS.stRef,\n NS.crs,\n NS.crss,\n NS.xmpNote,\n NS.xmpG,\n NS.xmpGImg,\n NS.xmpTPg,\n NS.stDim,\n NS.stFnt,\n NS.illustrator,\n NS['mwg-rs'],\n NS.stArea,\n NS.exif,\n NS.exifEX,\n NS.tiff,\n NS.aux,\n NS.xmpidq,\n NS.x,\n])\n\n/**\n * Single properties that are noise in a namespace that is otherwise kept.\n * `xmp:MetadataDate` is here because {@link writeXmp} stamps it on every\n * write, so an edit of it could never stick; the two digests are hashes\n * Photoshop uses to detect out-of-band edits; `pdf:PDFVersion` restates the\n * header version the PDF reader already reports as `pdfVersion`.\n */\nconst DENIED_PROPERTIES: ReadonlySet<string> = new Set([\n propertyId(NS.photoshop, 'DocumentAncestors'),\n propertyId(NS.photoshop, 'ColorMode'),\n propertyId(NS.photoshop, 'ICCProfile'),\n propertyId(NS.photoshop, 'History'),\n propertyId(NS.photoshop, 'LegacyIPTCDigest'),\n propertyId(NS.photoshop, 'EmbeddedXMPDigest'),\n propertyId(NS.xmp, 'MetadataDate'),\n propertyId(NS.pdf, 'PDFVersion'),\n])\n\nfunction propertyId(uri: string, local: string): string {\n return `${uri}\\u0000${local}`\n}\n\nexport type XmpProfile = 'image' | 'pdf'\n\nexport interface XmpReadOptions {\n /**\n * `pdf` reads `createdAt` from `xmp:CreateDate` only, as a PDF's XMP\n * mirrors the document info's `/CreationDate` there. Default `image`.\n */\n profile?: XmpProfile\n}\n\nexport interface XmpWriteOptions {\n profile: XmpProfile\n /** The instant stamped into `xmp:MetadataDate` (and PDF ModifyDate). */\n now: Date\n}\n\n// ---------------------------------------------------------------------------\n// The RDF model, as far as XMP uses it (XMP Part 1, §7 \"XMP data model\"\n// and §7.9 \"Serialization in RDF\").\n// ---------------------------------------------------------------------------\n\n/** One property occurrence, where it lives. */\ninterface XmpProperty {\n description: XmlElement\n uri: string\n local: string\n /** The prefix as written, for labels and for re-adding in place. */\n prefix: string\n attribute?: XmlAttribute\n element?: XmlElement\n}\n\ntype XmpArrayKind = 'alt' | 'bag' | 'seq'\ntype XmpShape = 'simple' | XmpArrayKind\n\ninterface XmpItem {\n value: string\n lang: string | null\n}\n\ntype XmpValue =\n | { kind: 'simple'; value: string }\n | { kind: 'array'; container: XmpArrayKind; items: XmpItem[] }\n | { kind: 'struct' }\n\n/** A namespace URI for `prefix` at `element`, falling back as above. */\nfunction resolveNs(element: XmlElement, prefix: string): string | null {\n const bound = resolvePrefix(element, prefix)\n if (bound !== null) return bound\n return prefix &&\n Object.prototype.hasOwnProperty.call(FALLBACK_NAMESPACE, prefix)\n ? (FALLBACK_NAMESPACE[prefix] ?? null)\n : null\n}\n\nfunction elementNs(element: XmlElement): string | null {\n return resolveNs(element, splitQName(element.name).prefix)\n}\n\nfunction attrNs(element: XmlElement, attr: XmlAttribute): string | null {\n if (isNamespaceDeclaration(attr)) return attributeNamespace(element, attr)\n const { prefix } = splitQName(attr.name)\n return prefix ? resolveNs(element, prefix) : null\n}\n\nfunction isRdf(element: XmlElement, local: string): boolean {\n return splitQName(element.name).local === local && elementNs(element) === RDF\n}\n\n/** An `rdf:`-namespaced attribute by local name, whatever its prefix. */\nfunction rdfAttribute(\n element: XmlElement,\n local: string,\n): XmlAttribute | undefined {\n return element.attributes.find(\n (attr) =>\n splitQName(attr.name).local === local && attrNs(element, attr) === RDF,\n )\n}\n\nfunction langOf(element: XmlElement): string | null {\n const attr = element.attributes.find(\n (candidate) =>\n splitQName(candidate.name).local === 'lang' &&\n attrNs(element, candidate) === XML_NAMESPACE,\n )\n return attr ? attr.value : null\n}\n\n/**\n * Attributes on a property element that make it a struct in RDF's\n * shorthand (XMP Part 1 §7.9.2.5, \"property attributes of an empty\n * property element\"): anything other than a namespace declaration, an\n * `xml:` attribute or an `rdf:` one.\n */\nfunction hasFieldAttributes(element: XmlElement): boolean {\n return element.attributes.some((attr) => {\n if (isNamespaceDeclaration(attr)) return false\n const uri = attrNs(element, attr)\n return uri !== XML_NAMESPACE && uri !== RDF\n })\n}\n\n/** Every `rdf:RDF`, outermost only, in document order. */\nfunction findRdfRoots(doc: XmlDocument): XmlElement[] {\n const roots: XmlElement[] = []\n walkElements(doc, (element) => {\n if (isRdf(element, 'RDF')) {\n roots.push(element)\n return false\n }\n return true\n })\n return roots\n}\n\n/**\n * The node elements that describe THIS resource: every `rdf:Description`,\n * plus a typed node (`<cc:Work rdf:about=\"\">`, what Inkscape writes into\n * an SVG) whose subject is the empty URI. A typed node about some other\n * resource — a `cc:License` — describes that resource, not the file.\n */\nfunction descriptionsOf(rdf: XmlElement): XmlElement[] {\n return elementChildren(rdf).filter((node) => {\n if (isRdf(node, 'Description')) return true\n if (elementNs(node) === RDF) return false\n return rdfAttribute(node, 'about')?.value === ''\n })\n}\n\n/** A Description's properties, attributes first, in source order. */\nfunction propertiesOf(description: XmlElement): XmpProperty[] {\n const out: XmpProperty[] = []\n for (const attr of description.attributes) {\n if (isNamespaceDeclaration(attr)) continue\n const { prefix, local } = splitQName(attr.name)\n if (!prefix) continue\n const uri = resolveNs(description, prefix)\n if (!uri || uri === RDF || uri === XML_NAMESPACE) continue\n out.push({ description, uri, local, prefix, attribute: attr })\n }\n for (const element of elementChildren(description)) {\n const uri = elementNs(element)\n if (!uri || uri === RDF || uri === XML_NAMESPACE) continue\n const { prefix, local } = splitQName(element.name)\n out.push({ description, uri, local, prefix, element })\n }\n return out\n}\n\n/** The one `rdf:Alt`/`Bag`/`Seq` an array property holds, if that is all. */\nfunction arrayContainer(\n element: XmlElement,\n): { node: XmlElement; kind: XmpArrayKind } | null {\n const children = elementChildren(element)\n const only = children[0]\n if (children.length !== 1 || !only) return null\n if (isRdf(only, 'Alt')) return { node: only, kind: 'alt' }\n if (isRdf(only, 'Bag')) return { node: only, kind: 'bag' }\n if (isRdf(only, 'Seq')) return { node: only, kind: 'seq' }\n return null\n}\n\nfunction arrayItems(container: XmlElement): XmlElement[] {\n return elementChildren(container).filter((node) => isRdf(node, 'li'))\n}\n\n/**\n * Classify a property's value (XMP Part 1 §7.9.2): a simple value (text,\n * or a URI in `rdf:resource`), an array of simple values, or anything\n * structured — `rdf:parseType=\"Resource\"`, a nested Description, field\n * attributes, an array whose items are structs.\n */\nfunction readValue(property: XmpProperty): XmpValue {\n if (property.attribute) {\n return { kind: 'simple', value: property.attribute.value }\n }\n const element = property.element\n if (!element || rdfAttribute(element, 'parseType')) return { kind: 'struct' }\n const children = elementChildren(element)\n if (!children.length) {\n if (hasFieldAttributes(element)) return { kind: 'struct' }\n const resource = rdfAttribute(element, 'resource')\n return {\n kind: 'simple',\n value: resource ? resource.value : textContent(element),\n }\n }\n const container = arrayContainer(element)\n if (!container) return { kind: 'struct' }\n const items: XmpItem[] = []\n for (const li of arrayItems(container.node)) {\n if (\n rdfAttribute(li, 'parseType') ||\n elementChildren(li).length ||\n hasFieldAttributes(li)\n ) {\n return { kind: 'struct' }\n }\n const resource = rdfAttribute(li, 'resource')\n items.push({\n value: resource ? resource.value : textContent(li),\n lang: langOf(li),\n })\n }\n return { kind: 'array', container: container.kind, items }\n}\n\n/**\n * The one value of a language alternative a reader shows: `x-default`,\n * else the first item (XMP Part 1 §8.2.2.4, \"Language alternatives\").\n */\nfunction pickAlternative(items: XmpItem[]): string {\n const preferred = items.find(\n (item) => item.lang?.toLowerCase() === 'x-default',\n )\n return (preferred ?? items[0])?.value ?? ''\n}\n\nfunction asText(value: XmpValue): string | null {\n switch (value.kind) {\n case 'simple':\n return value.value.trim() || null\n case 'array': {\n const text =\n value.container === 'alt'\n ? pickAlternative(value.items).trim()\n : value.items\n .map((item) => item.value.trim())\n .filter(Boolean)\n .join(', ')\n return text || null\n }\n default:\n return null\n }\n}\n\nfunction asList(value: XmpValue): string[] | null {\n let items: string[]\n if (value.kind === 'simple') items = [value.value]\n else if (value.kind === 'array') {\n items =\n value.container === 'alt'\n ? [pickAlternative(value.items)]\n : value.items.map((item) => item.value)\n } else return null\n const out = items.map((item) => item.trim()).filter(Boolean)\n return out.length ? out : null\n}\n\n// ---------------------------------------------------------------------------\n// Value formats (see the doc comment on MEDIA_EMBEDDED_CATALOG).\n// ---------------------------------------------------------------------------\n\n/**\n * An XMP date (XMP Part 1 §8.2.1.1: ISO 8601 as profiled by the W3C\n * datetime note) in the catalog's format. Fractional seconds are cut to\n * milliseconds, a `+0200` zone gains its colon, and the EXIF spelling\n * `2021:05:03 10:11:12` some writers put in XMP is accepted. A zone is\n * kept only when the file wrote one. Reduced precision (`2021`,\n * `2021-05`) is returned as written — a month cannot be invented.\n */\nexport function normalizeXmpDate(raw: string): string | null {\n const text = raw.trim()\n if (/^\\d{4}(?:-(?:0[1-9]|1[0-2]))?$/.test(text)) return text\n const match =\n /^(\\d{4})[-:](\\d{2})[-:](\\d{2})(?:[T ](\\d{2}):(\\d{2})(?::(\\d{2})(?:[.,](\\d+))?)?)?\\s*(Z|[+-]\\d{2}:?\\d{2})?$/i.exec(\n text,\n )\n if (!match) return null\n const [, year, month, day, hour, minute, second, fraction, zone] = match\n if (!year || !month || !day) return null\n const m = Number(month)\n const d = Number(day)\n if (m < 1 || m > 12 || d < 1 || d > 31) return null\n let out = `${year}-${month}-${day}`\n if (hour === undefined || minute === undefined) return out\n if (Number(hour) > 23 || Number(minute) > 59) return null\n out += `T${hour}:${minute}`\n if (second !== undefined) {\n if (Number(second) > 60) return null\n out += `:${second}`\n if (fraction) out += `.${fraction.slice(0, 3)}`\n }\n if (zone) {\n if (zone.toUpperCase() === 'Z') out += 'Z'\n else {\n const digits = zone.replace(':', '')\n const hours = Number(digits.slice(1, 3))\n const minutes = Number(digits.slice(3, 5))\n if (hours > 23 || minutes > 59) return null\n out += `${digits.slice(0, 3)}:${digits.slice(3, 5)}`\n }\n }\n return out\n}\n\n/** `\"0\"`–`\"5\"`, or `\"-1\"` for rejected (XMP Part 2, `xmp:Rating`). */\nfunction normalizeRating(raw: string): string | null {\n const text = raw.trim()\n if (!/^-?\\d+(?:\\.\\d+)?$/.test(text)) return null\n const rating = Math.round(Number(text))\n return rating >= -1 && rating <= 5 ? String(rating) : null\n}\n\n/** An EXIF rational as XMP writes it (`\"28/10\"`) or a plain decimal. */\nfunction parseRational(raw: string): number | null {\n const match = /^\\s*(\\d+(?:\\.\\d+)?)(?:\\s*\\/\\s*(\\d+(?:\\.\\d+)?))?\\s*$/.exec(raw)\n if (!match || match[1] === undefined) return null\n const numerator = Number(match[1])\n const denominator = match[2] === undefined ? 1 : Number(match[2])\n if (!denominator) return null\n const value = numerator / denominator\n return Number.isFinite(value) ? value : null\n}\n\nfunction trimNumber(value: number, places: number): string {\n return String(Number(value.toFixed(places)))\n}\n\n/**\n * `1/250 s`. Below a quarter second as a reciprocal, above it as decimal\n * seconds — the convention photographers read, and exiftool's.\n */\nfunction formatExposure(raw: string): string | null {\n const seconds = parseRational(raw)\n if (seconds === null || seconds <= 0) return null\n if (seconds < 0.25001) return `1/${Math.round(1 / seconds)} s`\n return `${trimNumber(seconds, 1)} s`\n}\n\nfunction formatAperture(raw: string): string | null {\n const value = parseRational(raw)\n return value && value > 0 ? `f/${trimNumber(value, 1)}` : null\n}\n\nfunction formatFocalLength(raw: string): string | null {\n const value = parseRational(raw)\n return value && value > 0 ? `${trimNumber(value, 1)} mm` : null\n}\n\n/** TIFF 6.0 tag 274 / EXIF 2.32 §4.6.4 A \"Orientation\", as exiftool words it. */\nconst ORIENTATIONS: Readonly<Record<string, string>> = {\n '1': 'Horizontal (normal)',\n '2': 'Mirror horizontal',\n '3': 'Rotate 180',\n '4': 'Mirror vertical',\n '5': 'Mirror horizontal and rotate 270 CW',\n '6': 'Rotate 90 CW',\n '7': 'Mirror horizontal and rotate 90 CW',\n '8': 'Rotate 270 CW',\n}\n\n/**\n * One GPS coordinate in the XMP form (XMP Part 2 / EXIF-in-XMP,\n * \"GPSCoordinate\"): `DDD,MM.mmmmk` or `DDD,MM,SSk` with k one of NSEW.\n * A bare signed decimal is tolerated. Null when out of range or on the\n * wrong axis (an `E` latitude).\n */\nfunction parseGpsCoordinate(raw: string, axis: 'lat' | 'lon'): number | null {\n const text = raw.trim()\n let value: number\n const match =\n /^(\\d{1,3}(?:\\.\\d+)?)(?:,(\\d{1,2}(?:\\.\\d+)?)(?:,(\\d{1,2}(?:\\.\\d+)?))?)?\\s*([NSEWnsew])$/.exec(\n text,\n )\n if (match && match[1] !== undefined && match[4] !== undefined) {\n const degrees = Number(match[1])\n const minutes = match[2] === undefined ? 0 : Number(match[2])\n const seconds = match[3] === undefined ? 0 : Number(match[3])\n if (minutes >= 60 || seconds >= 60) return null\n const ref = match[4].toUpperCase()\n if (axis === 'lat' ? !'NS'.includes(ref) : !'EW'.includes(ref)) return null\n value = degrees + minutes / 60 + seconds / 3600\n if (ref === 'S' || ref === 'W') value = -value\n } else if (/^-?\\d{1,3}(?:\\.\\d+)?$/.test(text)) {\n value = Number(text)\n } else return null\n const limit = axis === 'lat' ? 90 : 180\n if (!Number.isFinite(value) || Math.abs(value) > limit) return null\n return value\n}\n\nfunction formatDegrees(value: number): string {\n // Never print \"-0.000000\".\n return (Math.abs(value) < 5e-7 ? 0 : value).toFixed(6)\n}\n\n// ---------------------------------------------------------------------------\n// The canonical mapping.\n// ---------------------------------------------------------------------------\n\ntype ValueReader = (value: XmpValue) => string | string[] | null\n\nconst readText: ValueReader = asText\nconst readList: ValueReader = asList\nconst readDate: ValueReader = (value) => {\n const text = asText(value)\n return text ? normalizeXmpDate(text) : null\n}\nconst readRating: ValueReader = (value) => {\n const text = asText(value)\n return text ? normalizeRating(text) : null\n}\n/** `pdf:Keywords` is one string (PDF 2.0 §14.3.3, Keywords). */\nconst readKeywordString: ValueReader = (value) => {\n const text = asText(value)\n if (!text) return null\n const items = [\n ...new Set(\n text\n .split(/[,;]/)\n .map((item) => item.trim())\n .filter(Boolean),\n ),\n ]\n return items.length ? items : null\n}\nconst formatted =\n (format: (raw: string) => string | null): ValueReader =>\n (value) => {\n const text = asText(value)\n return text ? format(text) : null\n }\n/** A single number that may arrive as a one-item `rdf:Seq`. */\nconst readIso: ValueReader = (value) => {\n const first =\n value.kind === 'simple'\n ? value.value\n : value.kind === 'array'\n ? value.items[0]?.value\n : undefined\n const text = first?.trim()\n return text && /^\\d+$/.test(text) ? String(Number(text)) : null\n}\n\ninterface ReadSource {\n uri: string\n local: string\n read: ValueReader\n}\n\ninterface CanonicalRead {\n key: string\n sources: ReadSource[]\n}\n\nconst src = (uri: string, local: string, read: ValueReader): ReadSource => ({\n uri,\n local,\n read,\n})\n\n/** Canonical key → where XMP keeps it, strongest source first. */\nfunction canonicalReads(profile: XmpProfile): CanonicalRead[] {\n return [\n { key: 'title', sources: [src(NS.dc, 'title', readText)] },\n { key: 'headline', sources: [src(NS.photoshop, 'Headline', readText)] },\n { key: 'description', sources: [src(NS.dc, 'description', readText)] },\n {\n key: 'keywords',\n sources: [\n src(NS.dc, 'subject', readList),\n src(NS.pdf, 'Keywords', readKeywordString),\n ],\n },\n {\n key: 'instructions',\n sources: [src(NS.photoshop, 'Instructions', readText)],\n },\n { key: 'label', sources: [src(NS.xmp, 'Label', readText)] },\n { key: 'rating', sources: [src(NS.xmp, 'Rating', readRating)] },\n { key: 'creator', sources: [src(NS.dc, 'creator', readList)] },\n { key: 'copyright', sources: [src(NS.dc, 'rights', readText)] },\n { key: 'credit', sources: [src(NS.photoshop, 'Credit', readText)] },\n { key: 'source', sources: [src(NS.photoshop, 'Source', readText)] },\n {\n key: 'usageTerms',\n sources: [src(NS.xmpRights, 'UsageTerms', readText)],\n },\n {\n key: 'webStatement',\n sources: [src(NS.xmpRights, 'WebStatement', readText)],\n },\n { key: 'city', sources: [src(NS.photoshop, 'City', readText)] },\n { key: 'state', sources: [src(NS.photoshop, 'State', readText)] },\n { key: 'country', sources: [src(NS.photoshop, 'Country', readText)] },\n {\n key: 'createdAt',\n sources:\n profile === 'pdf'\n ? [src(NS.xmp, 'CreateDate', readDate)]\n : [\n src(NS.photoshop, 'DateCreated', readDate),\n src(NS.exif, 'DateTimeOriginal', readDate),\n src(NS.xmp, 'CreateDate', readDate),\n ],\n },\n { key: 'make', sources: [src(NS.tiff, 'Make', readText)] },\n { key: 'model', sources: [src(NS.tiff, 'Model', readText)] },\n {\n key: 'lens',\n sources: [\n src(NS.exifEX, 'LensModel', readText),\n src(NS.aux, 'Lens', readText),\n ],\n },\n {\n key: 'exposure',\n sources: [src(NS.exif, 'ExposureTime', formatted(formatExposure))],\n },\n {\n key: 'aperture',\n sources: [src(NS.exif, 'FNumber', formatted(formatAperture))],\n },\n {\n key: 'iso',\n sources: [\n src(NS.exifEX, 'PhotographicSensitivity', readIso),\n src(NS.exif, 'ISOSpeedRatings', readIso),\n ],\n },\n {\n key: 'focalLength',\n sources: [src(NS.exif, 'FocalLength', formatted(formatFocalLength))],\n },\n { key: 'modifiedAt', sources: [src(NS.xmp, 'ModifyDate', readDate)] },\n { key: 'software', sources: [src(NS.xmp, 'CreatorTool', readText)] },\n { key: 'producer', sources: [src(NS.pdf, 'Producer', readText)] },\n {\n key: 'orientation',\n sources: [\n src(\n NS.tiff,\n 'Orientation',\n formatted((raw) => ORIENTATIONS[raw.trim()] ?? null),\n ),\n ],\n },\n ]\n}\n\n/**\n * Every property the canonical mapping owns, in either profile. None of\n * them is ever offered as an \"other\" field — a shadowed fallback (an\n * `xmp:CreateDate` beside a `photoshop:DateCreated`) is the same idea as\n * the field that won, not a second field.\n */\nconst CLAIMED_PROPERTIES: ReadonlySet<string> = new Set(\n [...canonicalReads('image'), ...canonicalReads('pdf')].flatMap((entry) =>\n entry.sources.map((source) => propertyId(source.uri, source.local)),\n ),\n)\n\n/** Whether `(uri, local)` may be read or written as an \"other\" field. */\nfunction isOtherProperty(uri: string, local: string): boolean {\n if (DENIED_NAMESPACES.has(uri)) return false\n const id = propertyId(uri, local)\n if (DENIED_PROPERTIES.has(id) || CLAIMED_PROPERTIES.has(id)) return false\n // The other key is `|`-delimited; a URI containing one could not\n // round-trip through parseOtherEmbeddedKey.\n return !uri.includes('|') && !local.includes('|')\n}\n\n// ---------------------------------------------------------------------------\n// readXmp\n// ---------------------------------------------------------------------------\n\ninterface ParsedPacket {\n doc: XmlDocument\n roots: XmlElement[]\n descriptions: XmlElement[]\n}\n\nfunction openPacket(packet: string): ParsedPacket | null {\n const doc = parseXml(packet)\n if (!doc) return null\n const roots = findRdfRoots(doc)\n return { doc, roots, descriptions: roots.flatMap(descriptionsOf) }\n}\n\nfunction findProperties(\n descriptions: XmlElement[],\n uri: string,\n local: string,\n): XmpProperty[] {\n return descriptions.flatMap((description) =>\n propertiesOf(description).filter(\n (property) => property.uri === uri && property.local === local,\n ),\n )\n}\n\n/**\n * Read an XMP packet into candidates. Accepts a whole packet (`<?xpacket`\n * wrapper and `x:xmpmeta`), a bare `x:xmpmeta`, or a bare `rdf:RDF`\n * fragment. Never throws; unreadable input yields `[]`.\n */\nexport function readXmp(\n packet: string,\n options: XmpReadOptions = {},\n): EmbeddedCandidate[] {\n try {\n return read(packet, options.profile ?? 'image')\n } catch {\n // Defensive: the parser and walkers do not throw, and a reader of\n // hostile bytes must degrade to \"nothing found\" if one ever does.\n return []\n }\n}\n\nfunction read(packet: string, profile: XmpProfile): EmbeddedCandidate[] {\n if (typeof packet !== 'string') return []\n const parsed = openPacket(packet)\n if (!parsed) return []\n const properties = parsed.descriptions.flatMap(propertiesOf)\n const byId = new Map<string, XmpProperty[]>()\n for (const property of properties) {\n const id = propertyId(property.uri, property.local)\n const list = byId.get(id)\n if (list) list.push(property)\n else byId.set(id, [property])\n }\n\n const out: EmbeddedCandidate[] = []\n for (const { key, sources } of canonicalReads(profile)) {\n const value = firstValue(byId, sources)\n if (value !== null) out.push({ key, value, source: 'xmp' })\n }\n\n const gps = readGps(byId)\n if (gps) out.push({ key: 'gps', value: gps, source: 'xmp' })\n\n const seen = new Set<string>()\n for (const property of properties) {\n if (!isOtherProperty(property.uri, property.local)) continue\n const key = otherEmbeddedKey('xmp', property.uri, property.local)\n if (seen.has(key)) continue\n const value = readValue(property)\n let shown: string | string[] | null = null\n if (value.kind === 'simple') shown = value.value.trim() || null\n else if (value.kind === 'array') {\n shown =\n value.container === 'alt' ? asText(value) : (asList(value) ?? null)\n }\n if (shown === null) continue\n seen.add(key)\n out.push({\n key,\n value: shown,\n source: 'xmp',\n label: `${property.prefix || CONVENTIONAL_PREFIX[property.uri] || 'xmp'}:${property.local}`,\n })\n }\n return out\n}\n\nfunction firstValue(\n byId: Map<string, XmpProperty[]>,\n sources: ReadSource[],\n): string | string[] | null {\n for (const source of sources) {\n for (const property of byId.get(propertyId(source.uri, source.local)) ??\n []) {\n const value = source.read(readValue(property))\n if (value !== null) return value\n }\n }\n return null\n}\n\nfunction readGps(byId: Map<string, XmpProperty[]>): string | null {\n const coordinate = (local: string, axis: 'lat' | 'lon'): number | null => {\n for (const property of byId.get(propertyId(NS.exif, local)) ?? []) {\n const text = asText(readValue(property))\n const value = text ? parseGpsCoordinate(text, axis) : null\n if (value !== null) return value\n }\n return null\n }\n const lat = coordinate('GPSLatitude', 'lat')\n const lon = coordinate('GPSLongitude', 'lon')\n return lat === null || lon === null\n ? null\n : `${formatDegrees(lat)},${formatDegrees(lon)}`\n}\n\n// ---------------------------------------------------------------------------\n// writeXmp\n// ---------------------------------------------------------------------------\n\ninterface WriteTarget {\n uri: string\n local: string\n shape: XmpShape\n /**\n * Whether the property is added when the packet does not hold it.\n * False for the MWG \"update every copy that exists\" fan-out: an edit of\n * the date taken rewrites an `exif:DateTimeOriginal` that is there, and\n * does not invent one that is not.\n */\n create: boolean\n}\n\nconst target = (\n uri: string,\n local: string,\n shape: XmpShape,\n create = true,\n): WriteTarget => ({ uri, local, shape, create })\n\n/** Canonical key → the properties an edit of it writes, per profile. */\nfunction canonicalWrites(profile: XmpProfile): Record<string, WriteTarget[]> {\n const pdf = profile === 'pdf'\n return {\n title: [target(NS.dc, 'title', 'alt')],\n description: [target(NS.dc, 'description', 'alt')],\n creator: [target(NS.dc, 'creator', 'seq')],\n copyright: [target(NS.dc, 'rights', 'alt')],\n keywords: pdf\n ? [\n target(NS.pdf, 'Keywords', 'simple'),\n target(NS.dc, 'subject', 'bag', false),\n ]\n : [\n target(NS.dc, 'subject', 'bag'),\n target(NS.pdf, 'Keywords', 'simple', false),\n ],\n headline: [target(NS.photoshop, 'Headline', 'simple')],\n credit: [target(NS.photoshop, 'Credit', 'simple')],\n source: [target(NS.photoshop, 'Source', 'simple')],\n instructions: [target(NS.photoshop, 'Instructions', 'simple')],\n city: [target(NS.photoshop, 'City', 'simple')],\n state: [target(NS.photoshop, 'State', 'simple')],\n country: [target(NS.photoshop, 'Country', 'simple')],\n createdAt: pdf\n ? [target(NS.xmp, 'CreateDate', 'simple')]\n : [\n target(NS.photoshop, 'DateCreated', 'simple'),\n target(NS.exif, 'DateTimeOriginal', 'simple', false),\n target(NS.xmp, 'CreateDate', 'simple', false),\n ],\n modifiedAt: [target(NS.xmp, 'ModifyDate', 'simple')],\n software: [target(NS.xmp, 'CreatorTool', 'simple')],\n producer: [target(NS.pdf, 'Producer', 'simple')],\n label: [target(NS.xmp, 'Label', 'simple')],\n rating: [target(NS.xmp, 'Rating', 'simple')],\n usageTerms: [target(NS.xmpRights, 'UsageTerms', 'alt')],\n webStatement: [target(NS.xmpRights, 'WebStatement', 'simple')],\n make: [target(NS.tiff, 'Make', 'simple')],\n model: [target(NS.tiff, 'Model', 'simple')],\n lens: [\n target(NS.exifEX, 'LensModel', 'simple'),\n target(NS.aux, 'Lens', 'simple', false),\n ],\n }\n}\n\n/**\n * Canonical keys XMP holds but nobody edits: they describe how the bytes\n * were captured. Asking to write one is a caller bug, and says so.\n */\nconst READ_ONLY_KEYS: ReadonlySet<string> = new Set([\n 'exposure',\n 'aperture',\n 'iso',\n 'focalLength',\n 'orientation',\n])\n\n/** An XMP date (XMP Part 1 §8.2.1.1), the only thing a date field takes. */\nconst XMP_DATE =\n /^\\d{4}(?:-\\d{2}(?:-\\d{2}(?:T\\d{2}:\\d{2}(?::\\d{2}(?:\\.\\d+)?)?(?:Z|[+-]\\d{2}:\\d{2})?)?)?)?$/\n\n/** The packet {@link writeXmp} starts from when a file has none. */\nconst PACKET_HEADER =\n '<?xpacket begin=\"\\uFEFF\" id=\"W5M0MpCehiHzreSzNTczkc9d\"?>\\n' +\n '<x:xmpmeta xmlns:x=\"adobe:ns:meta/\">\\n' +\n ' <rdf:RDF xmlns:rdf=\"http://www.w3.org/1999/02/22-rdf-syntax-ns#\">\\n' +\n ' <rdf:Description rdf:about=\"\">\\n' +\n ' </rdf:Description>\\n' +\n ' </rdf:RDF>\\n' +\n '</x:xmpmeta>\\n'\n/**\n * Padding lets a later editor grow the packet in place without moving the\n * bytes after it (XMP Part 3 §1.1.1 recommends about 2 KB). Twenty lines\n * of 100 spaces is what Adobe's toolkit writes.\n */\nconst PACKET_PADDING = (' '.repeat(100) + '\\n').repeat(20)\nconst PACKET_TRAILER = '<?xpacket end=\"w\"?>'\n\ntype WriteOp =\n | {\n type: 'canonical'\n label: string\n targets: WriteTarget[]\n value: string | string[] | null\n }\n | { type: 'gps' }\n | {\n type: 'other'\n label: string\n uri: string\n local: string\n value: string | string[] | null\n }\n\n/**\n * Apply `patch` to `packet` and return the new packet.\n *\n * - `null` removes a key; a string or string[] sets it. An empty string or\n * list is a removal.\n * - Canonical keys fan out as {@link canonicalWrites} lists them. Keys XMP\n * has no place for (`subject`, a `png|…` key) are ignored — the patch is\n * shared with the file's other writers — and the camera's measurements\n * (`exposure`, …) throw.\n * - `gps: null` removes every `exif:GPS*` property. Setting it throws.\n * - An `xmp|<uri>|<local>` key edits or removes a property that already\n * exists; one that does not, or that the reader would never offer,\n * throws.\n * - `xmp:MetadataDate` is set to `now` on every write; in the `pdf`\n * profile `xmp:ModifyDate` is too, unless the patch sets `modifiedAt`.\n * - With `packet === null`, a fresh packet is created if the patch sets\n * anything XMP holds; otherwise the result is `null`.\n *\n * Throws {@link EmbeddedWriteError} when the packet cannot be parsed, has\n * no `rdf:RDF`, or the edit is not one XMP can take. Never returns a\n * packet it could not re-read.\n */\nexport function writeXmp(\n packet: string | null,\n patch: EmbeddedPatch,\n options: XmpWriteOptions,\n): string | null {\n const { profile, now } = options\n if (!(now instanceof Date) || Number.isNaN(now.getTime())) {\n throw new EmbeddedWriteError('The time of the edit is not a valid date.')\n }\n const ops = planWrite(patch, profile)\n const sets = ops.some((op) => op.type !== 'gps' && op.value !== null)\n\n if (packet === null) {\n const other = ops.find((op) => op.type === 'other')\n if (other?.type === 'other') {\n throw new EmbeddedWriteError(\n `${other.label} is not in this file's XMP metadata.`,\n )\n }\n if (!sets) return null\n }\n\n const source =\n packet === null ? PACKET_HEADER + PACKET_PADDING + PACKET_TRAILER : packet\n const parsed = openPacket(source)\n if (!parsed) {\n throw new EmbeddedWriteError(\n \"This file's XMP metadata could not be read, so it cannot be edited safely.\",\n )\n }\n const firstRoot = parsed.roots[0]\n if (!firstRoot) {\n throw new EmbeddedWriteError(\n \"This file's XMP metadata has no RDF block to edit.\",\n )\n }\n const editor = new PacketEditor(parsed.descriptions, firstRoot)\n\n for (const op of ops) {\n if (op.type === 'gps') {\n for (const property of editor.all()) {\n if (property.uri === NS.exif && property.local.startsWith('GPS')) {\n editor.remove(property)\n }\n }\n } else if (op.type === 'canonical') {\n if (op.value === null) {\n for (const each of op.targets) {\n for (const property of editor.find(each.uri, each.local)) {\n editor.remove(property)\n }\n }\n } else {\n for (const each of op.targets) editor.set(each, op.value)\n }\n } else {\n applyOther(editor, op)\n }\n }\n\n const stamp = formatXmpNow(now)\n editor.set(target(NS.xmp, 'MetadataDate', 'simple'), stamp)\n if (profile === 'pdf') {\n const modified = patch['modifiedAt']\n editor.set(\n target(NS.xmp, 'ModifyDate', 'simple'),\n typeof modified === 'string' && modified ? modified : stamp,\n )\n }\n\n const out = serializeXml(parsed.doc)\n // The promise is \"never produce a corrupt file\": prove the result parses.\n if (!parseXml(out)) {\n throw new EmbeddedWriteError(\n 'The edited XMP metadata did not re-read cleanly, so it was not written.',\n )\n }\n return out\n}\n\n/** `2026-09-24T18:04:05Z` — whole seconds, UTC, zone always present. */\nfunction formatXmpNow(now: Date): string {\n return now.toISOString().replace(/\\.\\d{3}Z$/, 'Z')\n}\n\nfunction planWrite(patch: EmbeddedPatch, profile: XmpProfile): WriteOp[] {\n if (!patch || typeof patch !== 'object' || Array.isArray(patch)) {\n throw new EmbeddedWriteError('Nothing to change.')\n }\n const writes = canonicalWrites(profile)\n const format = profile === 'pdf' ? 'pdf' : 'jpeg'\n const ops: WriteOp[] = []\n for (const [key, raw] of Object.entries(patch)) {\n const other = key.startsWith('xmp|') ? parseOtherEmbeddedKey(key) : null\n if (other) {\n const [uri, local, ...rest] = other.parts\n if (!uri || !local || rest.length || !isOtherProperty(uri, local)) {\n throw new EmbeddedWriteError(\n `${local ?? key} cannot be edited as an XMP field.`,\n )\n }\n const conventional = CONVENTIONAL_PREFIX[uri]\n const label = conventional ? `${conventional}:${local}` : local\n ops.push({\n type: 'other',\n label,\n uri,\n local,\n value: patchValue(label, raw),\n })\n continue\n }\n const label = embeddedFieldLabel(key, format)\n if (key === 'gps') {\n if (patchValue(label, raw) !== null) {\n throw new EmbeddedWriteError(`${label} can only be removed.`)\n }\n ops.push({ type: 'gps' })\n continue\n }\n if (READ_ONLY_KEYS.has(key)) {\n throw new EmbeddedWriteError(`${label} cannot be edited.`)\n }\n const targets = Object.prototype.hasOwnProperty.call(writes, key)\n ? writes[key]\n : undefined\n // Not an XMP key: another writer of this file owns it.\n if (!targets) continue\n const value = patchValue(label, raw)\n if (value !== null) validateCanonical(key, label, value)\n ops.push({ type: 'canonical', label, targets, value })\n }\n return ops\n}\n\n/** Normalize one patch value; '' and [] mean removal. */\nfunction patchValue(label: string, raw: unknown): string | string[] | null {\n if (raw === null || raw === undefined) return null\n if (typeof raw === 'string') {\n if (hasNonXmlCharacters(raw)) {\n throw new EmbeddedWriteError(\n `${label} contains characters that cannot be stored in XMP.`,\n )\n }\n return raw.trim() ? raw : null\n }\n if (Array.isArray(raw)) {\n const items: string[] = []\n for (const item of raw) {\n if (typeof item !== 'string') {\n throw new EmbeddedWriteError(`${label} must be text.`)\n }\n if (hasNonXmlCharacters(item)) {\n throw new EmbeddedWriteError(\n `${label} contains characters that cannot be stored in XMP.`,\n )\n }\n if (item.trim()) items.push(item)\n }\n return items.length ? items : null\n }\n throw new EmbeddedWriteError(`${label} must be text.`)\n}\n\nfunction validateCanonical(\n key: string,\n label: string,\n value: string | string[],\n): void {\n const text = Array.isArray(value) ? value.join(', ') : value\n if ((key === 'createdAt' || key === 'modifiedAt') && !XMP_DATE.test(text)) {\n throw new EmbeddedWriteError(`${label} must be a date.`)\n }\n if (key === 'rating' && !/^(?:-1|[0-5])$/.test(text)) {\n throw new EmbeddedWriteError(`${label} must be between 0 and 5.`)\n }\n}\n\nfunction applyOther(\n editor: PacketEditor,\n op: Extract<WriteOp, { type: 'other' }>,\n): void {\n const found = editor.find(op.uri, op.local)\n if (!found.length) {\n throw new EmbeddedWriteError(\n `${op.label} is not in this file's XMP metadata.`,\n )\n }\n if (op.value === null) {\n for (const property of found) editor.remove(property)\n return\n }\n for (const property of found) {\n const current = readValue(property)\n if (current.kind === 'struct') {\n throw new EmbeddedWriteError(\n `${op.label} is structured and cannot be edited here.`,\n )\n }\n editor.write(\n property,\n current.kind === 'array' ? current.container : 'simple',\n op.value,\n )\n }\n}\n\n/**\n * The whitespace a node is written after, or null for a packet with none.\n *\n * An indented packet has a line break and an indent, and a child sits one\n * unit deeper. A packet on ONE line — Photoshop's \"Save for Web\" output,\n * Apple's HEIC thumbnails — separates every node with the same run of\n * spaces whatever its depth; that is `lineBreak: ''` with the run in\n * `indent`, and it is reused unchanged at every depth.\n */\ninterface Layout {\n lineBreak: string\n indent: string\n}\n\n/** The layout of `node` from the whitespace text just before it. */\nfunction layoutOf(node: XmlElement): Layout | null {\n const parent = node.parent\n if (!parent) return null\n const index = parent.children.indexOf(node)\n const before = parent.children[index - 1]\n if (!isWhitespaceText(before) || !before.raw) return null\n const raw = before.raw\n const newline = raw.lastIndexOf('\\n')\n if (newline === -1) return { lineBreak: '', indent: raw }\n return {\n lineBreak: raw[newline - 1] === '\\r' ? '\\r\\n' : '\\n',\n indent: raw.slice(newline + 1),\n }\n}\n\nfunction deeper(layout: Layout | null, unit: string): Layout | null {\n if (!layout || !layout.lineBreak) return layout\n return { ...layout, indent: layout.indent + unit }\n}\n\nfunction whitespace(layout: Layout | null): XmlNode[] {\n return layout ? [createWhitespace(layout.lineBreak + layout.indent)] : []\n}\n\nfunction qualify(prefix: string, local: string): string {\n return prefix ? `${prefix}:${local}` : local\n}\n\n/**\n * The DOM surgery behind {@link writeXmp}. Holds the Descriptions and the\n * packet's indentation habits, and re-scans on every lookup so an edit is\n * always made against the tree as it is now.\n */\nclass PacketEditor {\n private readonly descriptions: XmlElement[]\n /** The first `rdf:Description`, where new properties go. */\n private readonly home: XmlElement\n /** One level of indentation, as this packet writes it. */\n private readonly unit: string\n /** The quote character this packet's attributes use. */\n private readonly quote: '\"' | \"'\"\n\n constructor(descriptions: XmlElement[], root: XmlElement) {\n const home =\n descriptions.find((node) => isRdf(node, 'Description')) ??\n this.createDescription(root)\n this.descriptions = descriptions.includes(home)\n ? descriptions\n : [...descriptions, home]\n this.home = home\n this.unit = inferIndentUnit(home)\n this.quote =\n home.attributes.find((attr) => !isNamespaceDeclaration(attr))?.quote ??\n home.attributes[0]?.quote ??\n '\"'\n }\n\n all(): XmpProperty[] {\n return this.descriptions.flatMap(propertiesOf)\n }\n\n find(uri: string, local: string): XmpProperty[] {\n return findProperties(this.descriptions, uri, local)\n }\n\n /** Set a property everywhere it lives, or add it if `create` allows. */\n set(where: WriteTarget, value: string | string[]): void {\n const found = this.find(where.uri, where.local)\n if (!found.length) {\n if (where.create) this.add(where, value)\n return\n }\n for (const property of found) this.write(property, where.shape, value)\n }\n\n /** Remove one occurrence, and the indentation that led up to it. */\n remove(property: XmpProperty): void {\n if (property.attribute) {\n removeAttribute(property.description, property.attribute.name)\n return\n }\n const element = property.element\n const parent = element?.parent\n if (!element || !parent) return\n const index = parent.children.indexOf(element)\n if (index === -1) return\n const before = parent.children[index - 1]\n if (isWhitespaceText(before)) parent.children.splice(index - 1, 2)\n else parent.children.splice(index, 1)\n element.parent = null\n }\n\n /** Write `value` into an existing occurrence, keeping its form. */\n write(\n property: XmpProperty,\n shape: XmpShape,\n value: string | string[],\n ): void {\n const items = Array.isArray(value) ? value : [value]\n const text = Array.isArray(value) ? value.join(', ') : value\n\n if (property.attribute) {\n if (shape === 'simple') {\n setAttribute(property.description, property.attribute.name, text)\n return\n }\n // An attribute cannot hold an array: move it to an element in the\n // same Description, under the prefix it was written with.\n removeAttribute(property.description, property.attribute.name)\n this.appendProperty(\n property.description,\n qualify(property.prefix, property.local),\n shape,\n items,\n )\n return\n }\n\n const element = property.element\n if (!element) return\n if (shape === 'simple') {\n const resource = rdfAttribute(element, 'resource')\n if (resource && !elementChildren(element).length) {\n setAttribute(element, resource.name, text)\n return\n }\n if (\n !elementChildren(element).length &&\n !hasFieldAttributes(element) &&\n !rdfAttribute(element, 'parseType')\n ) {\n setTextContent(element, text)\n return\n }\n this.clearValueAttributes(element)\n setTextContent(element, text)\n return\n }\n\n // Only an array of plain items is edited in place; one whose items are\n // structs (or that is no array at all) is rebuilt below.\n const current = readValue(property)\n const container = current.kind === 'array' ? arrayContainer(element) : null\n if (container) {\n if (shape === 'alt' && container.kind === 'alt') {\n this.setDefaultAlternative(container.node, text)\n return\n }\n // A Bag where a Seq belongs (or the reverse) keeps its container:\n // the order question is the file's, the values are the edit's.\n if (shape !== 'alt' && container.kind !== 'alt') {\n this.setItems(container.node, items, null)\n return\n }\n }\n // The property holds the wrong kind of value; rebuild its content.\n this.clearValueAttributes(element)\n const layout = layoutOf(element)\n const inner = deeper(layout, this.unit)\n const built = this.buildContainer(\n element,\n shape,\n shape === 'alt' ? [text] : items,\n inner,\n )\n replaceChildren(element, [\n ...whitespace(inner),\n built,\n ...whitespace(layout),\n ])\n element.selfClosing = false\n }\n\n /** Add a property that does not exist yet to the first Description. */\n private add(where: WriteTarget, value: string | string[]): void {\n const prefix = this.ensurePrefix(this.home, where.uri)\n const items = Array.isArray(value) ? value : [value]\n this.appendProperty(\n this.home,\n qualify(prefix, where.local),\n where.shape,\n where.shape === 'alt' ? [items.join(', ')] : items,\n )\n }\n\n private appendProperty(\n description: XmlElement,\n name: string,\n shape: XmpShape,\n items: string[],\n ): void {\n const { layout, insert } = this.planAppend(description)\n let element: XmlElement\n if (shape === 'simple') {\n element = createElement(name, [], [createText(items.join(', '))])\n } else {\n element = createElement(name)\n const inner = deeper(layout, this.unit)\n const container = this.buildContainer(description, shape, items, inner)\n insertChildren(element, 0, [\n ...whitespace(inner),\n container,\n ...whitespace(layout),\n ])\n }\n insert(element)\n }\n\n /**\n * Where the next child element of `parent` goes and how it is indented:\n * after the last element child, at that child's indent; or, in an empty\n * parent, one level deeper than the parent, before its closing tag.\n */\n private planAppend(parent: XmlElement): {\n layout: Layout | null\n insert: (node: XmlElement) => void\n } {\n const kids = elementChildren(parent)\n const last = kids[kids.length - 1]\n if (last) {\n const layout =\n [...kids]\n .reverse()\n .map(layoutOf)\n .find((found): found is Layout => found !== null) ?? null\n return {\n layout,\n insert: (node) =>\n insertChildren(parent, parent.children.indexOf(last) + 1, [\n ...whitespace(layout),\n node,\n ]),\n }\n }\n const own = layoutOf(parent)\n const layout = deeper(own, this.unit)\n return {\n layout,\n insert: (node) => {\n const tail = parent.children[parent.children.length - 1]\n if (layout && isWhitespaceText(tail) && tail.raw) {\n insertChildren(parent, parent.children.length - 1, [\n ...whitespace(layout),\n node,\n ])\n } else {\n insertChildren(parent, parent.children.length, [\n ...whitespace(layout),\n node,\n ...whitespace(own),\n ])\n }\n parent.selfClosing = false\n },\n }\n }\n\n /** The prefix `rdf:` elements take at `scope`. */\n private rdfPrefix(scope: XmlElement): string {\n const bound = prefixForNamespace(scope, RDF)\n if (bound !== null) return bound\n if (resolvePrefix(scope, '') === RDF) return ''\n return 'rdf'\n }\n\n private buildContainer(\n scope: XmlElement,\n shape: XmpArrayKind,\n items: string[],\n layout: Layout | null,\n ): XmlElement {\n const prefix = this.rdfPrefix(scope)\n const name = qualify(\n prefix,\n shape === 'alt' ? 'Alt' : shape === 'bag' ? 'Bag' : 'Seq',\n )\n const container = createElement(name)\n const itemLayout = deeper(layout, this.unit)\n const lang = shape === 'alt' ? 'x-default' : null\n insertChildren(container, 0, [\n ...items.flatMap((item) => [\n ...whitespace(itemLayout),\n this.buildItem(prefix, item, lang),\n ]),\n ...whitespace(layout),\n ])\n return container\n }\n\n private buildItem(\n rdfPrefix: string,\n value: string,\n lang: string | null,\n ): XmlElement {\n return createElement(\n qualify(rdfPrefix, 'li'),\n lang ? [['xml:lang', lang]] : [],\n value ? [createText(value)] : [],\n this.quote,\n )\n }\n\n /**\n * Set the `x-default` item of a language alternative. Following the\n * XMP Toolkit's `SetLocalizedText`, an item in a specific language that\n * held the same text as the old default is its twin and changes with\n * it; an item that had been translated is left alone. With no\n * `x-default` the first item — the one a reader shows — is set.\n */\n private setDefaultAlternative(container: XmlElement, value: string): void {\n const items = arrayItems(container)\n const fallback = items.find(\n (item) => langOf(item)?.toLowerCase() === 'x-default',\n )\n if (fallback) {\n const previous = textContent(fallback)\n for (const item of items) {\n if (\n item !== fallback &&\n !elementChildren(item).length &&\n textContent(item) === previous\n ) {\n setTextContent(item, value)\n }\n }\n setTextContent(fallback, value)\n return\n }\n const first = items[0]\n if (first) {\n setTextContent(first, value)\n return\n }\n this.setItems(container, [value], 'x-default')\n }\n\n /**\n * Replace an array's items, reusing the whitespace the old items were\n * laid out with so the rewritten block looks like the rest of the file.\n */\n private setItems(\n container: XmlElement,\n values: string[],\n lang: string | null,\n ): void {\n const kids = container.children\n const firstItem = kids.findIndex((node) => node.type === 'element')\n let itemSpace: string | null = null\n let closeSpace: string | null = null\n if (firstItem !== -1) {\n const before = kids[firstItem - 1]\n if (isWhitespaceText(before)) itemSpace = before.raw\n const tail = kids[kids.length - 1]\n if (isWhitespaceText(tail) && kids.length - 1 > firstItem) {\n closeSpace = tail.raw\n }\n } else {\n const layout = layoutOf(container)\n const inner = deeper(layout, this.unit)\n if (inner) itemSpace = inner.lineBreak + inner.indent\n if (layout) closeSpace = layout.lineBreak + layout.indent\n }\n const prefix = splitQName(container.name).prefix\n const nodes: XmlNode[] = []\n for (const value of values) {\n if (itemSpace !== null) nodes.push(createWhitespace(itemSpace))\n nodes.push(this.buildItem(prefix, value, lang))\n }\n if (closeSpace !== null) nodes.push(createWhitespace(closeSpace))\n replaceChildren(container, nodes)\n container.selfClosing = false\n }\n\n /**\n * Drop what made a property element structured — `rdf:parseType`,\n * `rdf:resource`, field attributes, `xml:lang` — keeping namespace\n * declarations, which descendants elsewhere may rely on.\n */\n private clearValueAttributes(element: XmlElement): void {\n element.attributes = element.attributes.filter(isNamespaceDeclaration)\n }\n\n /**\n * A prefix bound to `uri` at `scope`, declaring one on `scope` when none\n * is: the conventional prefix, or `<conventional>1`, `2`, … if a file\n * has already used that prefix for something else.\n */\n private ensurePrefix(scope: XmlElement, uri: string): string {\n const existing = prefixForNamespace(scope, uri)\n if (existing !== null) return existing\n const base = CONVENTIONAL_PREFIX[uri] ?? 'ns'\n let prefix = base\n for (let n = 1; resolvePrefix(scope, prefix) !== null; n++) {\n prefix = `${base}${n}`\n }\n const declarations = scope.attributes.filter(isNamespaceDeclaration)\n const anchor =\n declarations[declarations.length - 1] ??\n scope.attributes[scope.attributes.length - 1]\n setAttribute(scope, `xmlns:${prefix}`, uri, {\n leading: anchor?.leading ?? ' ',\n quote: anchor?.quote ?? this.quote,\n index: anchor ? scope.attributes.indexOf(anchor) + 1 : 0,\n })\n return prefix\n }\n\n /** An `rdf:Description` for an `rdf:RDF` that holds none. */\n private createDescription(root: XmlElement): XmlElement {\n const prefix = prefixForNamespace(root, RDF)\n const quote = root.attributes[0]?.quote ?? '\"'\n const description = prefix\n ? createElement(\n `${prefix}:Description`,\n [[`${prefix}:about`, '']],\n [],\n quote,\n )\n : createElement(\n 'rdf:Description',\n [\n ['xmlns:rdf', RDF],\n ['rdf:about', ''],\n ],\n [],\n quote,\n )\n const own = layoutOf(root)\n const layout = deeper(own, ' ')\n const tail = root.children[root.children.length - 1]\n if (layout && isWhitespaceText(tail) && tail.raw) {\n insertChildren(root, root.children.length - 1, [\n ...whitespace(layout),\n description,\n ])\n } else {\n insertChildren(root, root.children.length, [\n ...whitespace(layout),\n description,\n ...whitespace(own),\n ])\n }\n root.selfClosing = false\n // An empty Description reads the same either way; open it so its\n // first property lands between the tags with its own line.\n description.children = layout ? whitespace(layout) : []\n return description\n }\n}\n\n/**\n * One level of indentation as this packet writes it: Adobe's XMP Core\n * indents by one space, Photoshop's serializer by three, exiftool by one.\n * Measured from the Description's first property, else from the\n * Description against its `rdf:RDF`; one space when neither says.\n */\nfunction inferIndentUnit(description: XmlElement): string {\n const own = layoutOf(description)\n const firstChild = elementChildren(description)[0]\n const child = firstChild ? layoutOf(firstChild) : null\n if (\n own &&\n child &&\n child.indent.length > own.indent.length &&\n child.indent.startsWith(own.indent)\n ) {\n return child.indent.slice(own.indent.length)\n }\n const parent =\n description.parent?.type === 'element' ? layoutOf(description.parent) : null\n if (\n own &&\n parent &&\n own.indent.length > parent.indent.length &&\n own.indent.startsWith(parent.indent)\n ) {\n return own.indent.slice(parent.indent.length)\n }\n return ' '\n}\n"],"names":["embeddedFieldLabel","otherEmbeddedKey","parseOtherEmbeddedKey","EmbeddedWriteError","attributeNamespace","createElement","createText","createWhitespace","elementChildren","hasNonXmlCharacters","insertChildren","isNamespaceDeclaration","isWhitespaceText","parseXml","prefixForNamespace","removeAttribute","replaceChildren","resolvePrefix","serializeXml","setAttribute","setTextContent","splitQName","textContent","walkElements","XML_NAMESPACE","XMP_NAMESPACES","rdf","x","dc","xmp","xmpRights","xmpMM","xmpidq","xmpNote","xmpG","xmpGImg","xmpTPg","stEvt","stRef","stDim","stFnt","stArea","photoshop","illustrator","crs","crss","tiff","exif","exifEX","aux","pdf","pdfx","Iptc4xmpCore","cc","NS","RDF","CONVENTIONAL_PREFIX","FALLBACK_NAMESPACE","Object","fromEntries","entries","DENIED_NAMESPACES","Set","DENIED_PROPERTIES","propertyId","uri","local","resolveNs","element","prefix","bound","prototype","hasOwnProperty","call","elementNs","name","attrNs","attr","isRdf","rdfAttribute","attributes","find","langOf","candidate","value","hasFieldAttributes","some","findRdfRoots","doc","roots","push","descriptionsOf","filter","node","propertiesOf","description","out","attribute","arrayContainer","children","only","length","kind","arrayItems","container","readValue","property","resource","items","li","lang","pickAlternative","preferred","item","toLowerCase","asText","trim","text","map","Boolean","join","asList","normalizeXmpDate","raw","test","match","exec","year","month","day","hour","minute","second","fraction","zone","m","Number","d","undefined","slice","toUpperCase","digits","replace","hours","minutes","normalizeRating","rating","Math","round","String","parseRational","numerator","denominator","isFinite","trimNumber","places","toFixed","formatExposure","seconds","formatAperture","formatFocalLength","ORIENTATIONS","parseGpsCoordinate","axis","degrees","ref","includes","limit","abs","formatDegrees","readText","readList","readDate","readRating","readKeywordString","split","formatted","format","readIso","first","src","read","canonicalReads","profile","key","sources","CLAIMED_PROPERTIES","flatMap","entry","source","isOtherProperty","has","id","openPacket","packet","descriptions","findProperties","readXmp","options","parsed","properties","byId","Map","list","get","set","firstValue","gps","readGps","seen","shown","add","label","coordinate","lat","lon","target","shape","create","canonicalWrites","title","creator","copyright","keywords","headline","credit","instructions","city","state","country","createdAt","modifiedAt","software","producer","usageTerms","webStatement","make","model","lens","READ_ONLY_KEYS","XMP_DATE","PACKET_HEADER","PACKET_PADDING","repeat","PACKET_TRAILER","writeXmp","patch","now","Date","isNaN","getTime","ops","planWrite","sets","op","type","other","firstRoot","editor","PacketEditor","all","startsWith","remove","each","targets","applyOther","stamp","formatXmpNow","modified","toISOString","Array","isArray","writes","rest","parts","conventional","patchValue","validateCanonical","found","current","write","layoutOf","parent","index","indexOf","before","newline","lastIndexOf","lineBreak","indent","deeper","layout","unit","whitespace","qualify","where","splice","appendProperty","clearValueAttributes","setDefaultAlternative","setItems","inner","built","buildContainer","selfClosing","ensurePrefix","home","insert","planAppend","kids","last","reverse","own","tail","rdfPrefix","scope","itemLayout","buildItem","quote","fallback","previous","values","firstItem","findIndex","itemSpace","closeSpace","nodes","declarations","existing","base","n","anchor","leading","createDescription","root","inferIndentUnit","firstChild","child"],"mappings":";AAAA;;;;;;;;;;;;;;;CAeC,GAED;;;;;;;;;;;;;;;;;;;;;;;;;;;CA2BC,GAED,SACEA,kBAAkB,EAClBC,gBAAgB,EAChBC,qBAAqB,QAChB,8BAA0B;AACjC,SAGEC,kBAAkB,QACb,aAAS;AAChB,SACEC,kBAAkB,EAClBC,aAAa,EACbC,UAAU,EACVC,gBAAgB,EAChBC,eAAe,EACfC,mBAAmB,EACnBC,cAAc,EACdC,sBAAsB,EACtBC,gBAAgB,EAChBC,QAAQ,EACRC,kBAAkB,EAClBC,eAAe,EACfC,eAAe,EACfC,aAAa,EACbC,YAAY,EACZC,YAAY,EACZC,cAAc,EACdC,UAAU,EACVC,WAAW,EACXC,YAAY,EACZC,aAAa,QAKR,WAAO;AAEd,4DAA4D,GAC5D,OAAO,MAAMC,iBAAiB;IAC5BC,KAAK;IACLC,GAAG;IACHC,IAAI;IACJC,KAAK;IACLC,WAAW;IACXC,OAAO;IACPC,QAAQ;IACRC,SAAS;IACTC,MAAM;IACNC,SAAS;IACTC,QAAQ;IACRC,OAAO;IACPC,OAAO;IACPC,OAAO;IACPC,OAAO;IACPC,QAAQ;IACRC,WAAW;IACXC,aAAa;IACbC,KAAK;IACLC,MAAM;IACNC,MAAM;IACNC,MAAM;IACNC,QAAQ;IACRC,KAAK;IACLC,KAAK;IACLC,MAAM;IACNC,cAAc;IACd,UAAU;IACVC,IAAI;AACN,EAAU;AAEV,MAAMC,KAAK7B;AACX,MAAM8B,MAAMD,GAAG5B,GAAG;AAElB;;;CAGC,GACD,MAAM8B,sBAAwD;IAC5D,CAACF,GAAG1B,EAAE,CAAC,EAAE;IACT,CAAC0B,GAAGZ,SAAS,CAAC,EAAE;IAChB,CAACY,GAAGzB,GAAG,CAAC,EAAE;IACV,CAACyB,GAAGxB,SAAS,CAAC,EAAE;IAChB,CAACwB,GAAGR,IAAI,CAAC,EAAE;IACX,CAACQ,GAAGP,IAAI,CAAC,EAAE;IACX,CAACO,GAAGN,MAAM,CAAC,EAAE;IACb,CAACM,GAAGL,GAAG,CAAC,EAAE;IACV,CAACK,GAAGJ,GAAG,CAAC,EAAE;IACV,CAACI,GAAGF,YAAY,CAAC,EAAE;AACrB;AAEA;;;;;;CAMC,GACD,MAAMK,qBAAuDC,OAAOC,WAAW,CAC7ED,OAAOE,OAAO,CAACN;AAGjB,iEAAiE,GACjE,MAAMO,oBAAyC,IAAIC,IAAI;IACrDR,GAAGvB,KAAK;IACRuB,GAAGjB,KAAK;IACRiB,GAAGhB,KAAK;IACRgB,GAAGV,GAAG;IACNU,GAAGT,IAAI;IACPS,GAAGrB,OAAO;IACVqB,GAAGpB,IAAI;IACPoB,GAAGnB,OAAO;IACVmB,GAAGlB,MAAM;IACTkB,GAAGf,KAAK;IACRe,GAAGd,KAAK;IACRc,GAAGX,WAAW;IACdW,EAAE,CAAC,SAAS;IACZA,GAAGb,MAAM;IACTa,GAAGP,IAAI;IACPO,GAAGN,MAAM;IACTM,GAAGR,IAAI;IACPQ,GAAGL,GAAG;IACNK,GAAGtB,MAAM;IACTsB,GAAG3B,CAAC;CACL;AAED;;;;;;CAMC,GACD,MAAMoC,oBAAyC,IAAID,IAAI;IACrDE,WAAWV,GAAGZ,SAAS,EAAE;IACzBsB,WAAWV,GAAGZ,SAAS,EAAE;IACzBsB,WAAWV,GAAGZ,SAAS,EAAE;IACzBsB,WAAWV,GAAGZ,SAAS,EAAE;IACzBsB,WAAWV,GAAGZ,SAAS,EAAE;IACzBsB,WAAWV,GAAGZ,SAAS,EAAE;IACzBsB,WAAWV,GAAGzB,GAAG,EAAE;IACnBmC,WAAWV,GAAGJ,GAAG,EAAE;CACpB;AAED,SAASc,WAAWC,GAAW,EAAEC,KAAa;IAC5C,OAAO,GAAGD,IAAI,MAAM,EAAEC,OAAO;AAC/B;AA+CA,sEAAsE,GACtE,SAASC,UAAUC,OAAmB,EAAEC,MAAc;QAK/CZ;IAJL,MAAMa,QAAQrD,cAAcmD,SAASC;IACrC,IAAIC,UAAU,MAAM,OAAOA;IAC3B,OAAOD,UACLX,OAAOa,SAAS,CAACC,cAAc,CAACC,IAAI,CAAChB,oBAAoBY,WACtDZ,6BAAAA,kBAAkB,CAACY,OAAO,YAA1BZ,6BAA8B,OAC/B;AACN;AAEA,SAASiB,UAAUN,OAAmB;IACpC,OAAOD,UAAUC,SAAS/C,WAAW+C,QAAQO,IAAI,EAAEN,MAAM;AAC3D;AAEA,SAASO,OAAOR,OAAmB,EAAES,IAAkB;IACrD,IAAIlE,uBAAuBkE,OAAO,OAAOzE,mBAAmBgE,SAASS;IACrE,MAAM,EAAER,MAAM,EAAE,GAAGhD,WAAWwD,KAAKF,IAAI;IACvC,OAAON,SAASF,UAAUC,SAASC,UAAU;AAC/C;AAEA,SAASS,MAAMV,OAAmB,EAAEF,KAAa;IAC/C,OAAO7C,WAAW+C,QAAQO,IAAI,EAAET,KAAK,KAAKA,SAASQ,UAAUN,aAAab;AAC5E;AAEA,uEAAuE,GACvE,SAASwB,aACPX,OAAmB,EACnBF,KAAa;IAEb,OAAOE,QAAQY,UAAU,CAACC,IAAI,CAC5B,CAACJ,OACCxD,WAAWwD,KAAKF,IAAI,EAAET,KAAK,KAAKA,SAASU,OAAOR,SAASS,UAAUtB;AAEzE;AAEA,SAAS2B,OAAOd,OAAmB;IACjC,MAAMS,OAAOT,QAAQY,UAAU,CAACC,IAAI,CAClC,CAACE,YACC9D,WAAW8D,UAAUR,IAAI,EAAET,KAAK,KAAK,UACrCU,OAAOR,SAASe,eAAe3D;IAEnC,OAAOqD,OAAOA,KAAKO,KAAK,GAAG;AAC7B;AAEA;;;;;CAKC,GACD,SAASC,mBAAmBjB,OAAmB;IAC7C,OAAOA,QAAQY,UAAU,CAACM,IAAI,CAAC,CAACT;QAC9B,IAAIlE,uBAAuBkE,OAAO,OAAO;QACzC,MAAMZ,MAAMW,OAAOR,SAASS;QAC5B,OAAOZ,QAAQzC,iBAAiByC,QAAQV;IAC1C;AACF;AAEA,wDAAwD,GACxD,SAASgC,aAAaC,GAAgB;IACpC,MAAMC,QAAsB,EAAE;IAC9BlE,aAAaiE,KAAK,CAACpB;QACjB,IAAIU,MAAMV,SAAS,QAAQ;YACzBqB,MAAMC,IAAI,CAACtB;YACX,OAAO;QACT;QACA,OAAO;IACT;IACA,OAAOqB;AACT;AAEA;;;;;CAKC,GACD,SAASE,eAAejE,GAAe;IACrC,OAAOlB,gBAAgBkB,KAAKkE,MAAM,CAAC,CAACC;YAG3Bd;QAFP,IAAID,MAAMe,MAAM,gBAAgB,OAAO;QACvC,IAAInB,UAAUmB,UAAUtC,KAAK,OAAO;QACpC,OAAOwB,EAAAA,gBAAAA,aAAac,MAAM,6BAAnBd,cAA6BK,KAAK,MAAK;IAChD;AACF;AAEA,mEAAmE,GACnE,SAASU,aAAaC,WAAuB;IAC3C,MAAMC,MAAqB,EAAE;IAC7B,KAAK,MAAMnB,QAAQkB,YAAYf,UAAU,CAAE;QACzC,IAAIrE,uBAAuBkE,OAAO;QAClC,MAAM,EAAER,MAAM,EAAEH,KAAK,EAAE,GAAG7C,WAAWwD,KAAKF,IAAI;QAC9C,IAAI,CAACN,QAAQ;QACb,MAAMJ,MAAME,UAAU4B,aAAa1B;QACnC,IAAI,CAACJ,OAAOA,QAAQV,OAAOU,QAAQzC,eAAe;QAClDwE,IAAIN,IAAI,CAAC;YAAEK;YAAa9B;YAAKC;YAAOG;YAAQ4B,WAAWpB;QAAK;IAC9D;IACA,KAAK,MAAMT,WAAW5D,gBAAgBuF,aAAc;QAClD,MAAM9B,MAAMS,UAAUN;QACtB,IAAI,CAACH,OAAOA,QAAQV,OAAOU,QAAQzC,eAAe;QAClD,MAAM,EAAE6C,MAAM,EAAEH,KAAK,EAAE,GAAG7C,WAAW+C,QAAQO,IAAI;QACjDqB,IAAIN,IAAI,CAAC;YAAEK;YAAa9B;YAAKC;YAAOG;YAAQD;QAAQ;IACtD;IACA,OAAO4B;AACT;AAEA,2EAA2E,GAC3E,SAASE,eACP9B,OAAmB;IAEnB,MAAM+B,WAAW3F,gBAAgB4D;IACjC,MAAMgC,OAAOD,QAAQ,CAAC,EAAE;IACxB,IAAIA,SAASE,MAAM,KAAK,KAAK,CAACD,MAAM,OAAO;IAC3C,IAAItB,MAAMsB,MAAM,QAAQ,OAAO;QAAEP,MAAMO;QAAME,MAAM;IAAM;IACzD,IAAIxB,MAAMsB,MAAM,QAAQ,OAAO;QAAEP,MAAMO;QAAME,MAAM;IAAM;IACzD,IAAIxB,MAAMsB,MAAM,QAAQ,OAAO;QAAEP,MAAMO;QAAME,MAAM;IAAM;IACzD,OAAO;AACT;AAEA,SAASC,WAAWC,SAAqB;IACvC,OAAOhG,gBAAgBgG,WAAWZ,MAAM,CAAC,CAACC,OAASf,MAAMe,MAAM;AACjE;AAEA;;;;;CAKC,GACD,SAASY,UAAUC,QAAqB;IACtC,IAAIA,SAAST,SAAS,EAAE;QACtB,OAAO;YAAEK,MAAM;YAAUlB,OAAOsB,SAAST,SAAS,CAACb,KAAK;QAAC;IAC3D;IACA,MAAMhB,UAAUsC,SAAStC,OAAO;IAChC,IAAI,CAACA,WAAWW,aAAaX,SAAS,cAAc,OAAO;QAAEkC,MAAM;IAAS;IAC5E,MAAMH,WAAW3F,gBAAgB4D;IACjC,IAAI,CAAC+B,SAASE,MAAM,EAAE;QACpB,IAAIhB,mBAAmBjB,UAAU,OAAO;YAAEkC,MAAM;QAAS;QACzD,MAAMK,WAAW5B,aAAaX,SAAS;QACvC,OAAO;YACLkC,MAAM;YACNlB,OAAOuB,WAAWA,SAASvB,KAAK,GAAG9D,YAAY8C;QACjD;IACF;IACA,MAAMoC,YAAYN,eAAe9B;IACjC,IAAI,CAACoC,WAAW,OAAO;QAAEF,MAAM;IAAS;IACxC,MAAMM,QAAmB,EAAE;IAC3B,KAAK,MAAMC,MAAMN,WAAWC,UAAUX,IAAI,EAAG;QAC3C,IACEd,aAAa8B,IAAI,gBACjBrG,gBAAgBqG,IAAIR,MAAM,IAC1BhB,mBAAmBwB,KACnB;YACA,OAAO;gBAAEP,MAAM;YAAS;QAC1B;QACA,MAAMK,WAAW5B,aAAa8B,IAAI;QAClCD,MAAMlB,IAAI,CAAC;YACTN,OAAOuB,WAAWA,SAASvB,KAAK,GAAG9D,YAAYuF;YAC/CC,MAAM5B,OAAO2B;QACf;IACF;IACA,OAAO;QAAEP,MAAM;QAASE,WAAWA,UAAUF,IAAI;QAAEM;IAAM;AAC3D;AAEA;;;CAGC,GACD,SAASG,gBAAgBH,KAAgB;;QAI/BI;IAHR,MAAMA,YAAYJ,MAAM3B,IAAI,CAC1B,CAACgC;YAASA;eAAAA,EAAAA,aAAAA,KAAKH,IAAI,qBAATG,WAAWC,WAAW,QAAO;;IAEzC,gBAAQF,QAAAA,oBAAAA,YAAaJ,KAAK,CAAC,EAAE,qBAAtB,AAACI,MAAwB5B,KAAK,mBAAI;AAC3C;AAEA,SAAS+B,OAAO/B,KAAe;IAC7B,OAAQA,MAAMkB,IAAI;QAChB,KAAK;YACH,OAAOlB,MAAMA,KAAK,CAACgC,IAAI,MAAM;QAC/B,KAAK;YAAS;gBACZ,MAAMC,OACJjC,MAAMoB,SAAS,KAAK,QAChBO,gBAAgB3B,MAAMwB,KAAK,EAAEQ,IAAI,KACjChC,MAAMwB,KAAK,CACRU,GAAG,CAAC,CAACL,OAASA,KAAK7B,KAAK,CAACgC,IAAI,IAC7BxB,MAAM,CAAC2B,SACPC,IAAI,CAAC;gBACd,OAAOH,QAAQ;YACjB;QACA;YACE,OAAO;IACX;AACF;AAEA,SAASI,OAAOrC,KAAe;IAC7B,IAAIwB;IACJ,IAAIxB,MAAMkB,IAAI,KAAK,UAAUM,QAAQ;QAACxB,MAAMA,KAAK;KAAC;SAC7C,IAAIA,MAAMkB,IAAI,KAAK,SAAS;QAC/BM,QACExB,MAAMoB,SAAS,KAAK,QAChB;YAACO,gBAAgB3B,MAAMwB,KAAK;SAAE,GAC9BxB,MAAMwB,KAAK,CAACU,GAAG,CAAC,CAACL,OAASA,KAAK7B,KAAK;IAC5C,OAAO,OAAO;IACd,MAAMY,MAAMY,MAAMU,GAAG,CAAC,CAACL,OAASA,KAAKG,IAAI,IAAIxB,MAAM,CAAC2B;IACpD,OAAOvB,IAAIK,MAAM,GAAGL,MAAM;AAC5B;AAEA,8EAA8E;AAC9E,iEAAiE;AACjE,8EAA8E;AAE9E;;;;;;;CAOC,GACD,OAAO,SAAS0B,iBAAiBC,GAAW;IAC1C,MAAMN,OAAOM,IAAIP,IAAI;IACrB,IAAI,iCAAiCQ,IAAI,CAACP,OAAO,OAAOA;IACxD,MAAMQ,QACJ,8GAA8GC,IAAI,CAChHT;IAEJ,IAAI,CAACQ,OAAO,OAAO;IACnB,MAAM,GAAGE,MAAMC,OAAOC,KAAKC,MAAMC,QAAQC,QAAQC,UAAUC,KAAK,GAAGT;IACnE,IAAI,CAACE,QAAQ,CAACC,SAAS,CAACC,KAAK,OAAO;IACpC,MAAMM,IAAIC,OAAOR;IACjB,MAAMS,IAAID,OAAOP;IACjB,IAAIM,IAAI,KAAKA,IAAI,MAAME,IAAI,KAAKA,IAAI,IAAI,OAAO;IAC/C,IAAIzC,MAAM,GAAG+B,KAAK,CAAC,EAAEC,MAAM,CAAC,EAAEC,KAAK;IACnC,IAAIC,SAASQ,aAAaP,WAAWO,WAAW,OAAO1C;IACvD,IAAIwC,OAAON,QAAQ,MAAMM,OAAOL,UAAU,IAAI,OAAO;IACrDnC,OAAO,CAAC,CAAC,EAAEkC,KAAK,CAAC,EAAEC,QAAQ;IAC3B,IAAIC,WAAWM,WAAW;QACxB,IAAIF,OAAOJ,UAAU,IAAI,OAAO;QAChCpC,OAAO,CAAC,CAAC,EAAEoC,QAAQ;QACnB,IAAIC,UAAUrC,OAAO,CAAC,CAAC,EAAEqC,SAASM,KAAK,CAAC,GAAG,IAAI;IACjD;IACA,IAAIL,MAAM;QACR,IAAIA,KAAKM,WAAW,OAAO,KAAK5C,OAAO;aAClC;YACH,MAAM6C,SAASP,KAAKQ,OAAO,CAAC,KAAK;YACjC,MAAMC,QAAQP,OAAOK,OAAOF,KAAK,CAAC,GAAG;YACrC,MAAMK,UAAUR,OAAOK,OAAOF,KAAK,CAAC,GAAG;YACvC,IAAII,QAAQ,MAAMC,UAAU,IAAI,OAAO;YACvChD,OAAO,GAAG6C,OAAOF,KAAK,CAAC,GAAG,GAAG,CAAC,EAAEE,OAAOF,KAAK,CAAC,GAAG,IAAI;QACtD;IACF;IACA,OAAO3C;AACT;AAEA,oEAAoE,GACpE,SAASiD,gBAAgBtB,GAAW;IAClC,MAAMN,OAAOM,IAAIP,IAAI;IACrB,IAAI,CAAC,oBAAoBQ,IAAI,CAACP,OAAO,OAAO;IAC5C,MAAM6B,SAASC,KAAKC,KAAK,CAACZ,OAAOnB;IACjC,OAAO6B,UAAU,CAAC,KAAKA,UAAU,IAAIG,OAAOH,UAAU;AACxD;AAEA,sEAAsE,GACtE,SAASI,cAAc3B,GAAW;IAChC,MAAME,QAAQ,sDAAsDC,IAAI,CAACH;IACzE,IAAI,CAACE,SAASA,KAAK,CAAC,EAAE,KAAKa,WAAW,OAAO;IAC7C,MAAMa,YAAYf,OAAOX,KAAK,CAAC,EAAE;IACjC,MAAM2B,cAAc3B,KAAK,CAAC,EAAE,KAAKa,YAAY,IAAIF,OAAOX,KAAK,CAAC,EAAE;IAChE,IAAI,CAAC2B,aAAa,OAAO;IACzB,MAAMpE,QAAQmE,YAAYC;IAC1B,OAAOhB,OAAOiB,QAAQ,CAACrE,SAASA,QAAQ;AAC1C;AAEA,SAASsE,WAAWtE,KAAa,EAAEuE,MAAc;IAC/C,OAAON,OAAOb,OAAOpD,MAAMwE,OAAO,CAACD;AACrC;AAEA;;;CAGC,GACD,SAASE,eAAelC,GAAW;IACjC,MAAMmC,UAAUR,cAAc3B;IAC9B,IAAImC,YAAY,QAAQA,WAAW,GAAG,OAAO;IAC7C,IAAIA,UAAU,SAAS,OAAO,CAAC,EAAE,EAAEX,KAAKC,KAAK,CAAC,IAAIU,SAAS,EAAE,CAAC;IAC9D,OAAO,GAAGJ,WAAWI,SAAS,GAAG,EAAE,CAAC;AACtC;AAEA,SAASC,eAAepC,GAAW;IACjC,MAAMvC,QAAQkE,cAAc3B;IAC5B,OAAOvC,SAASA,QAAQ,IAAI,CAAC,EAAE,EAAEsE,WAAWtE,OAAO,IAAI,GAAG;AAC5D;AAEA,SAAS4E,kBAAkBrC,GAAW;IACpC,MAAMvC,QAAQkE,cAAc3B;IAC5B,OAAOvC,SAASA,QAAQ,IAAI,GAAGsE,WAAWtE,OAAO,GAAG,GAAG,CAAC,GAAG;AAC7D;AAEA,+EAA+E,GAC/E,MAAM6E,eAAiD;IACrD,KAAK;IACL,KAAK;IACL,KAAK;IACL,KAAK;IACL,KAAK;IACL,KAAK;IACL,KAAK;IACL,KAAK;AACP;AAEA;;;;;CAKC,GACD,SAASC,mBAAmBvC,GAAW,EAAEwC,IAAmB;IAC1D,MAAM9C,OAAOM,IAAIP,IAAI;IACrB,IAAIhC;IACJ,MAAMyC,QACJ,yFAAyFC,IAAI,CAC3FT;IAEJ,IAAIQ,SAASA,KAAK,CAAC,EAAE,KAAKa,aAAab,KAAK,CAAC,EAAE,KAAKa,WAAW;QAC7D,MAAM0B,UAAU5B,OAAOX,KAAK,CAAC,EAAE;QAC/B,MAAMmB,UAAUnB,KAAK,CAAC,EAAE,KAAKa,YAAY,IAAIF,OAAOX,KAAK,CAAC,EAAE;QAC5D,MAAMiC,UAAUjC,KAAK,CAAC,EAAE,KAAKa,YAAY,IAAIF,OAAOX,KAAK,CAAC,EAAE;QAC5D,IAAImB,WAAW,MAAMc,WAAW,IAAI,OAAO;QAC3C,MAAMO,MAAMxC,KAAK,CAAC,EAAE,CAACe,WAAW;QAChC,IAAIuB,SAAS,QAAQ,CAAC,KAAKG,QAAQ,CAACD,OAAO,CAAC,KAAKC,QAAQ,CAACD,MAAM,OAAO;QACvEjF,QAAQgF,UAAUpB,UAAU,KAAKc,UAAU;QAC3C,IAAIO,QAAQ,OAAOA,QAAQ,KAAKjF,QAAQ,CAACA;IAC3C,OAAO,IAAI,wBAAwBwC,IAAI,CAACP,OAAO;QAC7CjC,QAAQoD,OAAOnB;IACjB,OAAO,OAAO;IACd,MAAMkD,QAAQJ,SAAS,QAAQ,KAAK;IACpC,IAAI,CAAC3B,OAAOiB,QAAQ,CAACrE,UAAU+D,KAAKqB,GAAG,CAACpF,SAASmF,OAAO,OAAO;IAC/D,OAAOnF;AACT;AAEA,SAASqF,cAAcrF,KAAa;IAClC,2BAA2B;IAC3B,OAAO,AAAC+D,CAAAA,KAAKqB,GAAG,CAACpF,SAAS,OAAO,IAAIA,KAAI,EAAGwE,OAAO,CAAC;AACtD;AAQA,MAAMc,WAAwBvD;AAC9B,MAAMwD,WAAwBlD;AAC9B,MAAMmD,WAAwB,CAACxF;IAC7B,MAAMiC,OAAOF,OAAO/B;IACpB,OAAOiC,OAAOK,iBAAiBL,QAAQ;AACzC;AACA,MAAMwD,aAA0B,CAACzF;IAC/B,MAAMiC,OAAOF,OAAO/B;IACpB,OAAOiC,OAAO4B,gBAAgB5B,QAAQ;AACxC;AACA,8DAA8D,GAC9D,MAAMyD,oBAAiC,CAAC1F;IACtC,MAAMiC,OAAOF,OAAO/B;IACpB,IAAI,CAACiC,MAAM,OAAO;IAClB,MAAMT,QAAQ;WACT,IAAI9C,IACLuD,KACG0D,KAAK,CAAC,QACNzD,GAAG,CAAC,CAACL,OAASA,KAAKG,IAAI,IACvBxB,MAAM,CAAC2B;KAEb;IACD,OAAOX,MAAMP,MAAM,GAAGO,QAAQ;AAChC;AACA,MAAMoE,YACJ,CAACC,SACD,CAAC7F;QACC,MAAMiC,OAAOF,OAAO/B;QACpB,OAAOiC,OAAO4D,OAAO5D,QAAQ;IAC/B;AACF,6DAA6D,GAC7D,MAAM6D,UAAuB,CAAC9F;QAKpBA;IAJR,MAAM+F,QACJ/F,MAAMkB,IAAI,KAAK,WACXlB,MAAMA,KAAK,GACXA,MAAMkB,IAAI,KAAK,WACblB,gBAAAA,MAAMwB,KAAK,CAAC,EAAE,qBAAdxB,cAAgBA,KAAK,GACrBsD;IACR,MAAMrB,OAAO8D,yBAAAA,MAAO/D,IAAI;IACxB,OAAOC,QAAQ,QAAQO,IAAI,CAACP,QAAQgC,OAAOb,OAAOnB,SAAS;AAC7D;AAaA,MAAM+D,MAAM,CAACnH,KAAaC,OAAemH,OAAmC,CAAA;QAC1EpH;QACAC;QACAmH;IACF,CAAA;AAEA,gEAAgE,GAChE,SAASC,eAAeC,OAAmB;IACzC,OAAO;QACL;YAAEC,KAAK;YAASC,SAAS;gBAACL,IAAI9H,GAAG1B,EAAE,EAAE,SAAS8I;aAAU;QAAC;QACzD;YAAEc,KAAK;YAAYC,SAAS;gBAACL,IAAI9H,GAAGZ,SAAS,EAAE,YAAYgI;aAAU;QAAC;QACtE;YAAEc,KAAK;YAAeC,SAAS;gBAACL,IAAI9H,GAAG1B,EAAE,EAAE,eAAe8I;aAAU;QAAC;QACrE;YACEc,KAAK;YACLC,SAAS;gBACPL,IAAI9H,GAAG1B,EAAE,EAAE,WAAW+I;gBACtBS,IAAI9H,GAAGJ,GAAG,EAAE,YAAY4H;aACzB;QACH;QACA;YACEU,KAAK;YACLC,SAAS;gBAACL,IAAI9H,GAAGZ,SAAS,EAAE,gBAAgBgI;aAAU;QACxD;QACA;YAAEc,KAAK;YAASC,SAAS;gBAACL,IAAI9H,GAAGzB,GAAG,EAAE,SAAS6I;aAAU;QAAC;QAC1D;YAAEc,KAAK;YAAUC,SAAS;gBAACL,IAAI9H,GAAGzB,GAAG,EAAE,UAAUgJ;aAAY;QAAC;QAC9D;YAAEW,KAAK;YAAWC,SAAS;gBAACL,IAAI9H,GAAG1B,EAAE,EAAE,WAAW+I;aAAU;QAAC;QAC7D;YAAEa,KAAK;YAAaC,SAAS;gBAACL,IAAI9H,GAAG1B,EAAE,EAAE,UAAU8I;aAAU;QAAC;QAC9D;YAAEc,KAAK;YAAUC,SAAS;gBAACL,IAAI9H,GAAGZ,SAAS,EAAE,UAAUgI;aAAU;QAAC;QAClE;YAAEc,KAAK;YAAUC,SAAS;gBAACL,IAAI9H,GAAGZ,SAAS,EAAE,UAAUgI;aAAU;QAAC;QAClE;YACEc,KAAK;YACLC,SAAS;gBAACL,IAAI9H,GAAGxB,SAAS,EAAE,cAAc4I;aAAU;QACtD;QACA;YACEc,KAAK;YACLC,SAAS;gBAACL,IAAI9H,GAAGxB,SAAS,EAAE,gBAAgB4I;aAAU;QACxD;QACA;YAAEc,KAAK;YAAQC,SAAS;gBAACL,IAAI9H,GAAGZ,SAAS,EAAE,QAAQgI;aAAU;QAAC;QAC9D;YAAEc,KAAK;YAASC,SAAS;gBAACL,IAAI9H,GAAGZ,SAAS,EAAE,SAASgI;aAAU;QAAC;QAChE;YAAEc,KAAK;YAAWC,SAAS;gBAACL,IAAI9H,GAAGZ,SAAS,EAAE,WAAWgI;aAAU;QAAC;QACpE;YACEc,KAAK;YACLC,SACEF,YAAY,QACR;gBAACH,IAAI9H,GAAGzB,GAAG,EAAE,cAAc+I;aAAU,GACrC;gBACEQ,IAAI9H,GAAGZ,SAAS,EAAE,eAAekI;gBACjCQ,IAAI9H,GAAGP,IAAI,EAAE,oBAAoB6H;gBACjCQ,IAAI9H,GAAGzB,GAAG,EAAE,cAAc+I;aAC3B;QACT;QACA;YAAEY,KAAK;YAAQC,SAAS;gBAACL,IAAI9H,GAAGR,IAAI,EAAE,QAAQ4H;aAAU;QAAC;QACzD;YAAEc,KAAK;YAASC,SAAS;gBAACL,IAAI9H,GAAGR,IAAI,EAAE,SAAS4H;aAAU;QAAC;QAC3D;YACEc,KAAK;YACLC,SAAS;gBACPL,IAAI9H,GAAGN,MAAM,EAAE,aAAa0H;gBAC5BU,IAAI9H,GAAGL,GAAG,EAAE,QAAQyH;aACrB;QACH;QACA;YACEc,KAAK;YACLC,SAAS;gBAACL,IAAI9H,GAAGP,IAAI,EAAE,gBAAgBiI,UAAUnB;aAAiB;QACpE;QACA;YACE2B,KAAK;YACLC,SAAS;gBAACL,IAAI9H,GAAGP,IAAI,EAAE,WAAWiI,UAAUjB;aAAiB;QAC/D;QACA;YACEyB,KAAK;YACLC,SAAS;gBACPL,IAAI9H,GAAGN,MAAM,EAAE,2BAA2BkI;gBAC1CE,IAAI9H,GAAGP,IAAI,EAAE,mBAAmBmI;aACjC;QACH;QACA;YACEM,KAAK;YACLC,SAAS;gBAACL,IAAI9H,GAAGP,IAAI,EAAE,eAAeiI,UAAUhB;aAAoB;QACtE;QACA;YAAEwB,KAAK;YAAcC,SAAS;gBAACL,IAAI9H,GAAGzB,GAAG,EAAE,cAAc+I;aAAU;QAAC;QACpE;YAAEY,KAAK;YAAYC,SAAS;gBAACL,IAAI9H,GAAGzB,GAAG,EAAE,eAAe6I;aAAU;QAAC;QACnE;YAAEc,KAAK;YAAYC,SAAS;gBAACL,IAAI9H,GAAGJ,GAAG,EAAE,YAAYwH;aAAU;QAAC;QAChE;YACEc,KAAK;YACLC,SAAS;gBACPL,IACE9H,GAAGR,IAAI,EACP,eACAkI,UAAU,CAACrD;wBAAQsC;4BAAAA,yBAAAA,YAAY,CAACtC,IAAIP,IAAI,GAAG,YAAxB6C,yBAA4B;;aAElD;QACH;KACD;AACH;AAEA;;;;;CAKC,GACD,MAAMyB,qBAA0C,IAAI5H,IAClD;OAAIwH,eAAe;OAAaA,eAAe;CAAO,CAACK,OAAO,CAAC,CAACC,QAC9DA,MAAMH,OAAO,CAACnE,GAAG,CAAC,CAACuE,SAAW7H,WAAW6H,OAAO5H,GAAG,EAAE4H,OAAO3H,KAAK;AAIrE,uEAAuE,GACvE,SAAS4H,gBAAgB7H,GAAW,EAAEC,KAAa;IACjD,IAAIL,kBAAkBkI,GAAG,CAAC9H,MAAM,OAAO;IACvC,MAAM+H,KAAKhI,WAAWC,KAAKC;IAC3B,IAAIH,kBAAkBgI,GAAG,CAACC,OAAON,mBAAmBK,GAAG,CAACC,KAAK,OAAO;IACpE,iEAAiE;IACjE,4CAA4C;IAC5C,OAAO,CAAC/H,IAAIqG,QAAQ,CAAC,QAAQ,CAACpG,MAAMoG,QAAQ,CAAC;AAC/C;AAYA,SAAS2B,WAAWC,MAAc;IAChC,MAAM1G,MAAM3E,SAASqL;IACrB,IAAI,CAAC1G,KAAK,OAAO;IACjB,MAAMC,QAAQF,aAAaC;IAC3B,OAAO;QAAEA;QAAKC;QAAO0G,cAAc1G,MAAMkG,OAAO,CAAChG;IAAgB;AACnE;AAEA,SAASyG,eACPD,YAA0B,EAC1BlI,GAAW,EACXC,KAAa;IAEb,OAAOiI,aAAaR,OAAO,CAAC,CAAC5F,cAC3BD,aAAaC,aAAaH,MAAM,CAC9B,CAACc,WAAaA,SAASzC,GAAG,KAAKA,OAAOyC,SAASxC,KAAK,KAAKA;AAG/D;AAEA;;;;CAIC,GACD,OAAO,SAASmI,QACdH,MAAc,EACdI,UAA0B,CAAC,CAAC;IAE5B,IAAI;YACkBA;QAApB,OAAOjB,KAAKa,SAAQI,mBAAAA,QAAQf,OAAO,YAAfe,mBAAmB;IACzC,EAAE,eAAM;QACN,kEAAkE;QAClE,kEAAkE;QAClE,OAAO,EAAE;IACX;AACF;AAEA,SAASjB,KAAKa,MAAc,EAAEX,OAAmB;IAC/C,IAAI,OAAOW,WAAW,UAAU,OAAO,EAAE;IACzC,MAAMK,SAASN,WAAWC;IAC1B,IAAI,CAACK,QAAQ,OAAO,EAAE;IACtB,MAAMC,aAAaD,OAAOJ,YAAY,CAACR,OAAO,CAAC7F;IAC/C,MAAM2G,OAAO,IAAIC;IACjB,KAAK,MAAMhG,YAAY8F,WAAY;QACjC,MAAMR,KAAKhI,WAAW0C,SAASzC,GAAG,EAAEyC,SAASxC,KAAK;QAClD,MAAMyI,OAAOF,KAAKG,GAAG,CAACZ;QACtB,IAAIW,MAAMA,KAAKjH,IAAI,CAACgB;aACf+F,KAAKI,GAAG,CAACb,IAAI;YAACtF;SAAS;IAC9B;IAEA,MAAMV,MAA2B,EAAE;IACnC,KAAK,MAAM,EAAEwF,GAAG,EAAEC,OAAO,EAAE,IAAIH,eAAeC,SAAU;QACtD,MAAMnG,QAAQ0H,WAAWL,MAAMhB;QAC/B,IAAIrG,UAAU,MAAMY,IAAIN,IAAI,CAAC;YAAE8F;YAAKpG;YAAOyG,QAAQ;QAAM;IAC3D;IAEA,MAAMkB,MAAMC,QAAQP;IACpB,IAAIM,KAAK/G,IAAIN,IAAI,CAAC;QAAE8F,KAAK;QAAOpG,OAAO2H;QAAKlB,QAAQ;IAAM;IAE1D,MAAMoB,OAAO,IAAInJ;IACjB,KAAK,MAAM4C,YAAY8F,WAAY;QACjC,IAAI,CAACV,gBAAgBpF,SAASzC,GAAG,EAAEyC,SAASxC,KAAK,GAAG;QACpD,MAAMsH,MAAMvL,iBAAiB,OAAOyG,SAASzC,GAAG,EAAEyC,SAASxC,KAAK;QAChE,IAAI+I,KAAKlB,GAAG,CAACP,MAAM;QACnB,MAAMpG,QAAQqB,UAAUC;QACxB,IAAIwG,QAAkC;QACtC,IAAI9H,MAAMkB,IAAI,KAAK,UAAU4G,QAAQ9H,MAAMA,KAAK,CAACgC,IAAI,MAAM;aACtD,IAAIhC,MAAMkB,IAAI,KAAK,SAAS;gBAEgBmB;YAD/CyF,QACE9H,MAAMoB,SAAS,KAAK,QAAQW,OAAO/B,UAAUqC,UAAAA,OAAOrC,kBAAPqC,UAAiB;QAClE;QACA,IAAIyF,UAAU,MAAM;QACpBD,KAAKE,GAAG,CAAC3B;QACTxF,IAAIN,IAAI,CAAC;YACP8F;YACApG,OAAO8H;YACPrB,QAAQ;YACRuB,OAAO,GAAG1G,SAASrC,MAAM,IAAIb,mBAAmB,CAACkD,SAASzC,GAAG,CAAC,IAAI,MAAM,CAAC,EAAEyC,SAASxC,KAAK,EAAE;QAC7F;IACF;IACA,OAAO8B;AACT;AAEA,SAAS8G,WACPL,IAAgC,EAChChB,OAAqB;IAErB,KAAK,MAAMI,UAAUJ,QAAS;YACLgB;QAAvB,KAAK,MAAM/F,aAAY+F,YAAAA,KAAKG,GAAG,CAAC5I,WAAW6H,OAAO5H,GAAG,EAAE4H,OAAO3H,KAAK,cAA5CuI,YACrB,EAAE,CAAE;YACJ,MAAMrH,QAAQyG,OAAOR,IAAI,CAAC5E,UAAUC;YACpC,IAAItB,UAAU,MAAM,OAAOA;QAC7B;IACF;IACA,OAAO;AACT;AAEA,SAAS4H,QAAQP,IAAgC;IAC/C,MAAMY,aAAa,CAACnJ,OAAeiG;YACVsC;QAAvB,KAAK,MAAM/F,aAAY+F,YAAAA,KAAKG,GAAG,CAAC5I,WAAWV,GAAGP,IAAI,EAAEmB,mBAA7BuI,YAAwC,EAAE,CAAE;YACjE,MAAMpF,OAAOF,OAAOV,UAAUC;YAC9B,MAAMtB,QAAQiC,OAAO6C,mBAAmB7C,MAAM8C,QAAQ;YACtD,IAAI/E,UAAU,MAAM,OAAOA;QAC7B;QACA,OAAO;IACT;IACA,MAAMkI,MAAMD,WAAW,eAAe;IACtC,MAAME,MAAMF,WAAW,gBAAgB;IACvC,OAAOC,QAAQ,QAAQC,QAAQ,OAC3B,OACA,GAAG9C,cAAc6C,KAAK,CAAC,EAAE7C,cAAc8C,MAAM;AACnD;AAmBA,MAAMC,SAAS,CACbvJ,KACAC,OACAuJ,OACAC,SAAS,IAAI,GACI,CAAA;QAAEzJ;QAAKC;QAAOuJ;QAAOC;IAAO,CAAA;AAE/C,sEAAsE,GACtE,SAASC,gBAAgBpC,OAAmB;IAC1C,MAAMrI,MAAMqI,YAAY;IACxB,OAAO;QACLqC,OAAO;YAACJ,OAAOlK,GAAG1B,EAAE,EAAE,SAAS;SAAO;QACtCmE,aAAa;YAACyH,OAAOlK,GAAG1B,EAAE,EAAE,eAAe;SAAO;QAClDiM,SAAS;YAACL,OAAOlK,GAAG1B,EAAE,EAAE,WAAW;SAAO;QAC1CkM,WAAW;YAACN,OAAOlK,GAAG1B,EAAE,EAAE,UAAU;SAAO;QAC3CmM,UAAU7K,MACN;YACEsK,OAAOlK,GAAGJ,GAAG,EAAE,YAAY;YAC3BsK,OAAOlK,GAAG1B,EAAE,EAAE,WAAW,OAAO;SACjC,GACD;YACE4L,OAAOlK,GAAG1B,EAAE,EAAE,WAAW;YACzB4L,OAAOlK,GAAGJ,GAAG,EAAE,YAAY,UAAU;SACtC;QACL8K,UAAU;YAACR,OAAOlK,GAAGZ,SAAS,EAAE,YAAY;SAAU;QACtDuL,QAAQ;YAACT,OAAOlK,GAAGZ,SAAS,EAAE,UAAU;SAAU;QAClDmJ,QAAQ;YAAC2B,OAAOlK,GAAGZ,SAAS,EAAE,UAAU;SAAU;QAClDwL,cAAc;YAACV,OAAOlK,GAAGZ,SAAS,EAAE,gBAAgB;SAAU;QAC9DyL,MAAM;YAACX,OAAOlK,GAAGZ,SAAS,EAAE,QAAQ;SAAU;QAC9C0L,OAAO;YAACZ,OAAOlK,GAAGZ,SAAS,EAAE,SAAS;SAAU;QAChD2L,SAAS;YAACb,OAAOlK,GAAGZ,SAAS,EAAE,WAAW;SAAU;QACpD4L,WAAWpL,MACP;YAACsK,OAAOlK,GAAGzB,GAAG,EAAE,cAAc;SAAU,GACxC;YACE2L,OAAOlK,GAAGZ,SAAS,EAAE,eAAe;YACpC8K,OAAOlK,GAAGP,IAAI,EAAE,oBAAoB,UAAU;YAC9CyK,OAAOlK,GAAGzB,GAAG,EAAE,cAAc,UAAU;SACxC;QACL0M,YAAY;YAACf,OAAOlK,GAAGzB,GAAG,EAAE,cAAc;SAAU;QACpD2M,UAAU;YAAChB,OAAOlK,GAAGzB,GAAG,EAAE,eAAe;SAAU;QACnD4M,UAAU;YAACjB,OAAOlK,GAAGJ,GAAG,EAAE,YAAY;SAAU;QAChDkK,OAAO;YAACI,OAAOlK,GAAGzB,GAAG,EAAE,SAAS;SAAU;QAC1CqH,QAAQ;YAACsE,OAAOlK,GAAGzB,GAAG,EAAE,UAAU;SAAU;QAC5C6M,YAAY;YAAClB,OAAOlK,GAAGxB,SAAS,EAAE,cAAc;SAAO;QACvD6M,cAAc;YAACnB,OAAOlK,GAAGxB,SAAS,EAAE,gBAAgB;SAAU;QAC9D8M,MAAM;YAACpB,OAAOlK,GAAGR,IAAI,EAAE,QAAQ;SAAU;QACzC+L,OAAO;YAACrB,OAAOlK,GAAGR,IAAI,EAAE,SAAS;SAAU;QAC3CgM,MAAM;YACJtB,OAAOlK,GAAGN,MAAM,EAAE,aAAa;YAC/BwK,OAAOlK,GAAGL,GAAG,EAAE,QAAQ,UAAU;SAClC;IACH;AACF;AAEA;;;CAGC,GACD,MAAM8L,iBAAsC,IAAIjL,IAAI;IAClD;IACA;IACA;IACA;IACA;CACD;AAED,0EAA0E,GAC1E,MAAMkL,WACJ;AAEF,kEAAkE,GAClE,MAAMC,gBACJ,+DACA,2CACA,yEACA,uCACA,2BACA,kBACA;AACF;;;;CAIC,GACD,MAAMC,iBAAiB,AAAC,CAAA,IAAIC,MAAM,CAAC,OAAO,IAAG,EAAGA,MAAM,CAAC;AACvD,MAAMC,iBAAiB;AAkBvB;;;;;;;;;;;;;;;;;;;;;CAqBC,GACD,OAAO,SAASC,SACdnD,MAAqB,EACrBoD,KAAoB,EACpBhD,OAAwB;IAExB,MAAM,EAAEf,OAAO,EAAEgE,GAAG,EAAE,GAAGjD;IACzB,IAAI,CAAEiD,CAAAA,eAAeC,IAAG,KAAMhH,OAAOiH,KAAK,CAACF,IAAIG,OAAO,KAAK;QACzD,MAAM,IAAIvP,mBAAmB;IAC/B;IACA,MAAMwP,MAAMC,UAAUN,OAAO/D;IAC7B,MAAMsE,OAAOF,IAAIrK,IAAI,CAAC,CAACwK,KAAOA,GAAGC,IAAI,KAAK,SAASD,GAAG1K,KAAK,KAAK;IAEhE,IAAI8G,WAAW,MAAM;QACnB,MAAM8D,QAAQL,IAAI1K,IAAI,CAAC,CAAC6K,KAAOA,GAAGC,IAAI,KAAK;QAC3C,IAAIC,CAAAA,yBAAAA,MAAOD,IAAI,MAAK,SAAS;YAC3B,MAAM,IAAI5P,mBACR,GAAG6P,MAAM5C,KAAK,CAAC,oCAAoC,CAAC;QAExD;QACA,IAAI,CAACyC,MAAM,OAAO;IACpB;IAEA,MAAMhE,SACJK,WAAW,OAAO+C,gBAAgBC,iBAAiBE,iBAAiBlD;IACtE,MAAMK,SAASN,WAAWJ;IAC1B,IAAI,CAACU,QAAQ;QACX,MAAM,IAAIpM,mBACR;IAEJ;IACA,MAAM8P,YAAY1D,OAAO9G,KAAK,CAAC,EAAE;IACjC,IAAI,CAACwK,WAAW;QACd,MAAM,IAAI9P,mBACR;IAEJ;IACA,MAAM+P,SAAS,IAAIC,aAAa5D,OAAOJ,YAAY,EAAE8D;IAErD,KAAK,MAAMH,MAAMH,IAAK;QACpB,IAAIG,GAAGC,IAAI,KAAK,OAAO;YACrB,KAAK,MAAMrJ,YAAYwJ,OAAOE,GAAG,GAAI;gBACnC,IAAI1J,SAASzC,GAAG,KAAKX,GAAGP,IAAI,IAAI2D,SAASxC,KAAK,CAACmM,UAAU,CAAC,QAAQ;oBAChEH,OAAOI,MAAM,CAAC5J;gBAChB;YACF;QACF,OAAO,IAAIoJ,GAAGC,IAAI,KAAK,aAAa;YAClC,IAAID,GAAG1K,KAAK,KAAK,MAAM;gBACrB,KAAK,MAAMmL,QAAQT,GAAGU,OAAO,CAAE;oBAC7B,KAAK,MAAM9J,YAAYwJ,OAAOjL,IAAI,CAACsL,KAAKtM,GAAG,EAAEsM,KAAKrM,KAAK,EAAG;wBACxDgM,OAAOI,MAAM,CAAC5J;oBAChB;gBACF;YACF,OAAO;gBACL,KAAK,MAAM6J,QAAQT,GAAGU,OAAO,CAAEN,OAAOrD,GAAG,CAAC0D,MAAMT,GAAG1K,KAAK;YAC1D;QACF,OAAO;YACLqL,WAAWP,QAAQJ;QACrB;IACF;IAEA,MAAMY,QAAQC,aAAapB;IAC3BW,OAAOrD,GAAG,CAACW,OAAOlK,GAAGzB,GAAG,EAAE,gBAAgB,WAAW6O;IACrD,IAAInF,YAAY,OAAO;QACrB,MAAMqF,WAAWtB,KAAK,CAAC,aAAa;QACpCY,OAAOrD,GAAG,CACRW,OAAOlK,GAAGzB,GAAG,EAAE,cAAc,WAC7B,OAAO+O,aAAa,YAAYA,WAAWA,WAAWF;IAE1D;IAEA,MAAM1K,MAAM9E,aAAaqL,OAAO/G,GAAG;IACnC,0EAA0E;IAC1E,IAAI,CAAC3E,SAASmF,MAAM;QAClB,MAAM,IAAI7F,mBACR;IAEJ;IACA,OAAO6F;AACT;AAEA,sEAAsE,GACtE,SAAS2K,aAAapB,GAAS;IAC7B,OAAOA,IAAIsB,WAAW,GAAG/H,OAAO,CAAC,aAAa;AAChD;AAEA,SAAS8G,UAAUN,KAAoB,EAAE/D,OAAmB;IAC1D,IAAI,CAAC+D,SAAS,OAAOA,UAAU,YAAYwB,MAAMC,OAAO,CAACzB,QAAQ;QAC/D,MAAM,IAAInP,mBAAmB;IAC/B;IACA,MAAM6Q,SAASrD,gBAAgBpC;IAC/B,MAAMN,SAASM,YAAY,QAAQ,QAAQ;IAC3C,MAAMoE,MAAiB,EAAE;IACzB,KAAK,MAAM,CAACnE,KAAK7D,IAAI,IAAIjE,OAAOE,OAAO,CAAC0L,OAAQ;QAC9C,MAAMU,QAAQxE,IAAI6E,UAAU,CAAC,UAAUnQ,sBAAsBsL,OAAO;QACpE,IAAIwE,OAAO;YACT,MAAM,CAAC/L,KAAKC,OAAO,GAAG+M,KAAK,GAAGjB,MAAMkB,KAAK;YACzC,IAAI,CAACjN,OAAO,CAACC,SAAS+M,KAAK5K,MAAM,IAAI,CAACyF,gBAAgB7H,KAAKC,QAAQ;gBACjE,MAAM,IAAI/D,mBACR,GAAG+D,gBAAAA,QAASsH,IAAI,kCAAkC,CAAC;YAEvD;YACA,MAAM2F,eAAe3N,mBAAmB,CAACS,IAAI;YAC7C,MAAMmJ,QAAQ+D,eAAe,GAAGA,aAAa,CAAC,EAAEjN,OAAO,GAAGA;YAC1DyL,IAAIjK,IAAI,CAAC;gBACPqK,MAAM;gBACN3C;gBACAnJ;gBACAC;gBACAkB,OAAOgM,WAAWhE,OAAOzF;YAC3B;YACA;QACF;QACA,MAAMyF,QAAQpN,mBAAmBwL,KAAKP;QACtC,IAAIO,QAAQ,OAAO;YACjB,IAAI4F,WAAWhE,OAAOzF,SAAS,MAAM;gBACnC,MAAM,IAAIxH,mBAAmB,GAAGiN,MAAM,qBAAqB,CAAC;YAC9D;YACAuC,IAAIjK,IAAI,CAAC;gBAAEqK,MAAM;YAAM;YACvB;QACF;QACA,IAAIhB,eAAehD,GAAG,CAACP,MAAM;YAC3B,MAAM,IAAIrL,mBAAmB,GAAGiN,MAAM,kBAAkB,CAAC;QAC3D;QACA,MAAMoD,UAAU9M,OAAOa,SAAS,CAACC,cAAc,CAACC,IAAI,CAACuM,QAAQxF,OACzDwF,MAAM,CAACxF,IAAI,GACX9C;QACJ,uDAAuD;QACvD,IAAI,CAAC8H,SAAS;QACd,MAAMpL,QAAQgM,WAAWhE,OAAOzF;QAChC,IAAIvC,UAAU,MAAMiM,kBAAkB7F,KAAK4B,OAAOhI;QAClDuK,IAAIjK,IAAI,CAAC;YAAEqK,MAAM;YAAa3C;YAAOoD;YAASpL;QAAM;IACtD;IACA,OAAOuK;AACT;AAEA,uDAAuD,GACvD,SAASyB,WAAWhE,KAAa,EAAEzF,GAAY;IAC7C,IAAIA,QAAQ,QAAQA,QAAQe,WAAW,OAAO;IAC9C,IAAI,OAAOf,QAAQ,UAAU;QAC3B,IAAIlH,oBAAoBkH,MAAM;YAC5B,MAAM,IAAIxH,mBACR,GAAGiN,MAAM,kDAAkD,CAAC;QAEhE;QACA,OAAOzF,IAAIP,IAAI,KAAKO,MAAM;IAC5B;IACA,IAAImJ,MAAMC,OAAO,CAACpJ,MAAM;QACtB,MAAMf,QAAkB,EAAE;QAC1B,KAAK,MAAMK,QAAQU,IAAK;YACtB,IAAI,OAAOV,SAAS,UAAU;gBAC5B,MAAM,IAAI9G,mBAAmB,GAAGiN,MAAM,cAAc,CAAC;YACvD;YACA,IAAI3M,oBAAoBwG,OAAO;gBAC7B,MAAM,IAAI9G,mBACR,GAAGiN,MAAM,kDAAkD,CAAC;YAEhE;YACA,IAAInG,KAAKG,IAAI,IAAIR,MAAMlB,IAAI,CAACuB;QAC9B;QACA,OAAOL,MAAMP,MAAM,GAAGO,QAAQ;IAChC;IACA,MAAM,IAAIzG,mBAAmB,GAAGiN,MAAM,cAAc,CAAC;AACvD;AAEA,SAASiE,kBACP7F,GAAW,EACX4B,KAAa,EACbhI,KAAwB;IAExB,MAAMiC,OAAOyJ,MAAMC,OAAO,CAAC3L,SAASA,MAAMoC,IAAI,CAAC,QAAQpC;IACvD,IAAI,AAACoG,CAAAA,QAAQ,eAAeA,QAAQ,YAAW,KAAM,CAACwD,SAASpH,IAAI,CAACP,OAAO;QACzE,MAAM,IAAIlH,mBAAmB,GAAGiN,MAAM,gBAAgB,CAAC;IACzD;IACA,IAAI5B,QAAQ,YAAY,CAAC,iBAAiB5D,IAAI,CAACP,OAAO;QACpD,MAAM,IAAIlH,mBAAmB,GAAGiN,MAAM,yBAAyB,CAAC;IAClE;AACF;AAEA,SAASqD,WACPP,MAAoB,EACpBJ,EAAuC;IAEvC,MAAMwB,QAAQpB,OAAOjL,IAAI,CAAC6K,GAAG7L,GAAG,EAAE6L,GAAG5L,KAAK;IAC1C,IAAI,CAACoN,MAAMjL,MAAM,EAAE;QACjB,MAAM,IAAIlG,mBACR,GAAG2P,GAAG1C,KAAK,CAAC,oCAAoC,CAAC;IAErD;IACA,IAAI0C,GAAG1K,KAAK,KAAK,MAAM;QACrB,KAAK,MAAMsB,YAAY4K,MAAOpB,OAAOI,MAAM,CAAC5J;QAC5C;IACF;IACA,KAAK,MAAMA,YAAY4K,MAAO;QAC5B,MAAMC,UAAU9K,UAAUC;QAC1B,IAAI6K,QAAQjL,IAAI,KAAK,UAAU;YAC7B,MAAM,IAAInG,mBACR,GAAG2P,GAAG1C,KAAK,CAAC,yCAAyC,CAAC;QAE1D;QACA8C,OAAOsB,KAAK,CACV9K,UACA6K,QAAQjL,IAAI,KAAK,UAAUiL,QAAQ/K,SAAS,GAAG,UAC/CsJ,GAAG1K,KAAK;IAEZ;AACF;AAgBA,kEAAkE,GAClE,SAASqM,SAAS5L,IAAgB;IAChC,MAAM6L,SAAS7L,KAAK6L,MAAM;IAC1B,IAAI,CAACA,QAAQ,OAAO;IACpB,MAAMC,QAAQD,OAAOvL,QAAQ,CAACyL,OAAO,CAAC/L;IACtC,MAAMgM,SAASH,OAAOvL,QAAQ,CAACwL,QAAQ,EAAE;IACzC,IAAI,CAAC/Q,iBAAiBiR,WAAW,CAACA,OAAOlK,GAAG,EAAE,OAAO;IACrD,MAAMA,MAAMkK,OAAOlK,GAAG;IACtB,MAAMmK,UAAUnK,IAAIoK,WAAW,CAAC;IAChC,IAAID,YAAY,CAAC,GAAG,OAAO;QAAEE,WAAW;QAAIC,QAAQtK;IAAI;IACxD,OAAO;QACLqK,WAAWrK,GAAG,CAACmK,UAAU,EAAE,KAAK,OAAO,SAAS;QAChDG,QAAQtK,IAAIgB,KAAK,CAACmJ,UAAU;IAC9B;AACF;AAEA,SAASI,OAAOC,MAAqB,EAAEC,IAAY;IACjD,IAAI,CAACD,UAAU,CAACA,OAAOH,SAAS,EAAE,OAAOG;IACzC,OAAO,aAAKA;QAAQF,QAAQE,OAAOF,MAAM,GAAGG;;AAC9C;AAEA,SAASC,WAAWF,MAAqB;IACvC,OAAOA,SAAS;QAAC5R,iBAAiB4R,OAAOH,SAAS,GAAGG,OAAOF,MAAM;KAAE,GAAG,EAAE;AAC3E;AAEA,SAASK,QAAQjO,MAAc,EAAEH,KAAa;IAC5C,OAAOG,SAAS,GAAGA,OAAO,CAAC,EAAEH,OAAO,GAAGA;AACzC;AAEA;;;;CAIC,GACD,IAAA,AAAMiM,eAAN,MAAMA;IAwBJC,MAAqB;QACnB,OAAO,IAAI,CAACjE,YAAY,CAACR,OAAO,CAAC7F;IACnC;IAEAb,KAAKhB,GAAW,EAAEC,KAAa,EAAiB;QAC9C,OAAOkI,eAAe,IAAI,CAACD,YAAY,EAAElI,KAAKC;IAChD;IAEA,sEAAsE,GACtE2I,IAAI0F,KAAkB,EAAEnN,KAAwB,EAAQ;QACtD,MAAMkM,QAAQ,IAAI,CAACrM,IAAI,CAACsN,MAAMtO,GAAG,EAAEsO,MAAMrO,KAAK;QAC9C,IAAI,CAACoN,MAAMjL,MAAM,EAAE;YACjB,IAAIkM,MAAM7E,MAAM,EAAE,IAAI,CAACP,GAAG,CAACoF,OAAOnN;YAClC;QACF;QACA,KAAK,MAAMsB,YAAY4K,MAAO,IAAI,CAACE,KAAK,CAAC9K,UAAU6L,MAAM9E,KAAK,EAAErI;IAClE;IAEA,kEAAkE,GAClEkL,OAAO5J,QAAqB,EAAQ;QAClC,IAAIA,SAAST,SAAS,EAAE;YACtBlF,gBAAgB2F,SAASX,WAAW,EAAEW,SAAST,SAAS,CAACtB,IAAI;YAC7D;QACF;QACA,MAAMP,UAAUsC,SAAStC,OAAO;QAChC,MAAMsN,SAAStN,2BAAAA,QAASsN,MAAM;QAC9B,IAAI,CAACtN,WAAW,CAACsN,QAAQ;QACzB,MAAMC,QAAQD,OAAOvL,QAAQ,CAACyL,OAAO,CAACxN;QACtC,IAAIuN,UAAU,CAAC,GAAG;QAClB,MAAME,SAASH,OAAOvL,QAAQ,CAACwL,QAAQ,EAAE;QACzC,IAAI/Q,iBAAiBiR,SAASH,OAAOvL,QAAQ,CAACqM,MAAM,CAACb,QAAQ,GAAG;aAC3DD,OAAOvL,QAAQ,CAACqM,MAAM,CAACb,OAAO;QACnCvN,QAAQsN,MAAM,GAAG;IACnB;IAEA,iEAAiE,GACjEF,MACE9K,QAAqB,EACrB+G,KAAe,EACfrI,KAAwB,EAClB;QACN,MAAMwB,QAAQkK,MAAMC,OAAO,CAAC3L,SAASA,QAAQ;YAACA;SAAM;QACpD,MAAMiC,OAAOyJ,MAAMC,OAAO,CAAC3L,SAASA,MAAMoC,IAAI,CAAC,QAAQpC;QAEvD,IAAIsB,SAAST,SAAS,EAAE;YACtB,IAAIwH,UAAU,UAAU;gBACtBtM,aAAauF,SAASX,WAAW,EAAEW,SAAST,SAAS,CAACtB,IAAI,EAAE0C;gBAC5D;YACF;YACA,kEAAkE;YAClE,0DAA0D;YAC1DtG,gBAAgB2F,SAASX,WAAW,EAAEW,SAAST,SAAS,CAACtB,IAAI;YAC7D,IAAI,CAAC8N,cAAc,CACjB/L,SAASX,WAAW,EACpBuM,QAAQ5L,SAASrC,MAAM,EAAEqC,SAASxC,KAAK,GACvCuJ,OACA7G;YAEF;QACF;QAEA,MAAMxC,UAAUsC,SAAStC,OAAO;QAChC,IAAI,CAACA,SAAS;QACd,IAAIqJ,UAAU,UAAU;YACtB,MAAM9G,WAAW5B,aAAaX,SAAS;YACvC,IAAIuC,YAAY,CAACnG,gBAAgB4D,SAASiC,MAAM,EAAE;gBAChDlF,aAAaiD,SAASuC,SAAShC,IAAI,EAAE0C;gBACrC;YACF;YACA,IACE,CAAC7G,gBAAgB4D,SAASiC,MAAM,IAChC,CAAChB,mBAAmBjB,YACpB,CAACW,aAAaX,SAAS,cACvB;gBACAhD,eAAegD,SAASiD;gBACxB;YACF;YACA,IAAI,CAACqL,oBAAoB,CAACtO;YAC1BhD,eAAegD,SAASiD;YACxB;QACF;QAEA,uEAAuE;QACvE,yDAAyD;QACzD,MAAMkK,UAAU9K,UAAUC;QAC1B,MAAMF,YAAY+K,QAAQjL,IAAI,KAAK,UAAUJ,eAAe9B,WAAW;QACvE,IAAIoC,WAAW;YACb,IAAIiH,UAAU,SAASjH,UAAUF,IAAI,KAAK,OAAO;gBAC/C,IAAI,CAACqM,qBAAqB,CAACnM,UAAUX,IAAI,EAAEwB;gBAC3C;YACF;YACA,kEAAkE;YAClE,+DAA+D;YAC/D,IAAIoG,UAAU,SAASjH,UAAUF,IAAI,KAAK,OAAO;gBAC/C,IAAI,CAACsM,QAAQ,CAACpM,UAAUX,IAAI,EAAEe,OAAO;gBACrC;YACF;QACF;QACA,mEAAmE;QACnE,IAAI,CAAC8L,oBAAoB,CAACtO;QAC1B,MAAM+N,SAASV,SAASrN;QACxB,MAAMyO,QAAQX,OAAOC,QAAQ,IAAI,CAACC,IAAI;QACtC,MAAMU,QAAQ,IAAI,CAACC,cAAc,CAC/B3O,SACAqJ,OACAA,UAAU,QAAQ;YAACpG;SAAK,GAAGT,OAC3BiM;QAEF7R,gBAAgBoD,SAAS;eACpBiO,WAAWQ;YACdC;eACGT,WAAWF;SACf;QACD/N,QAAQ4O,WAAW,GAAG;IACxB;IAEA,qEAAqE,GACrE,AAAQ7F,IAAIoF,KAAkB,EAAEnN,KAAwB,EAAQ;QAC9D,MAAMf,SAAS,IAAI,CAAC4O,YAAY,CAAC,IAAI,CAACC,IAAI,EAAEX,MAAMtO,GAAG;QACrD,MAAM2C,QAAQkK,MAAMC,OAAO,CAAC3L,SAASA,QAAQ;YAACA;SAAM;QACpD,IAAI,CAACqN,cAAc,CACjB,IAAI,CAACS,IAAI,EACTZ,QAAQjO,QAAQkO,MAAMrO,KAAK,GAC3BqO,MAAM9E,KAAK,EACX8E,MAAM9E,KAAK,KAAK,QAAQ;YAAC7G,MAAMY,IAAI,CAAC;SAAM,GAAGZ;IAEjD;IAEQ6L,eACN1M,WAAuB,EACvBpB,IAAY,EACZ8I,KAAe,EACf7G,KAAe,EACT;QACN,MAAM,EAAEuL,MAAM,EAAEgB,MAAM,EAAE,GAAG,IAAI,CAACC,UAAU,CAACrN;QAC3C,IAAI3B;QACJ,IAAIqJ,UAAU,UAAU;YACtBrJ,UAAU/D,cAAcsE,MAAM,EAAE,EAAE;gBAACrE,WAAWsG,MAAMY,IAAI,CAAC;aAAO;QAClE,OAAO;YACLpD,UAAU/D,cAAcsE;YACxB,MAAMkO,QAAQX,OAAOC,QAAQ,IAAI,CAACC,IAAI;YACtC,MAAM5L,YAAY,IAAI,CAACuM,cAAc,CAAChN,aAAa0H,OAAO7G,OAAOiM;YACjEnS,eAAe0D,SAAS,GAAG;mBACtBiO,WAAWQ;gBACdrM;mBACG6L,WAAWF;aACf;QACH;QACAgB,OAAO/O;IACT;IAEA;;;;GAIC,GACD,AAAQgP,WAAW1B,MAAkB,EAGnC;QACA,MAAM2B,OAAO7S,gBAAgBkR;QAC7B,MAAM4B,OAAOD,IAAI,CAACA,KAAKhN,MAAM,GAAG,EAAE;QAClC,IAAIiN,MAAM;gBAEN;YADF,MAAMnB,UACJ,oBAAA;mBAAIkB;aAAK,CACNE,OAAO,GACPjM,GAAG,CAACmK,UACJxM,IAAI,CAAC,CAACqM,QAA2BA,UAAU,iBAH9C,oBAGuD;YACzD,OAAO;gBACLa;gBACAgB,QAAQ,CAACtN,OACPnF,eAAegR,QAAQA,OAAOvL,QAAQ,CAACyL,OAAO,CAAC0B,QAAQ,GAAG;2BACrDjB,WAAWF;wBACdtM;qBACD;YACL;QACF;QACA,MAAM2N,MAAM/B,SAASC;QACrB,MAAMS,SAASD,OAAOsB,KAAK,IAAI,CAACpB,IAAI;QACpC,OAAO;YACLD;YACAgB,QAAQ,CAACtN;gBACP,MAAM4N,OAAO/B,OAAOvL,QAAQ,CAACuL,OAAOvL,QAAQ,CAACE,MAAM,GAAG,EAAE;gBACxD,IAAI8L,UAAUvR,iBAAiB6S,SAASA,KAAK9L,GAAG,EAAE;oBAChDjH,eAAegR,QAAQA,OAAOvL,QAAQ,CAACE,MAAM,GAAG,GAAG;2BAC9CgM,WAAWF;wBACdtM;qBACD;gBACH,OAAO;oBACLnF,eAAegR,QAAQA,OAAOvL,QAAQ,CAACE,MAAM,EAAE;2BAC1CgM,WAAWF;wBACdtM;2BACGwM,WAAWmB;qBACf;gBACH;gBACA9B,OAAOsB,WAAW,GAAG;YACvB;QACF;IACF;IAEA,gDAAgD,GAChD,AAAQU,UAAUC,KAAiB,EAAU;QAC3C,MAAMrP,QAAQxD,mBAAmB6S,OAAOpQ;QACxC,IAAIe,UAAU,MAAM,OAAOA;QAC3B,IAAIrD,cAAc0S,OAAO,QAAQpQ,KAAK,OAAO;QAC7C,OAAO;IACT;IAEQwP,eACNY,KAAiB,EACjBlG,KAAmB,EACnB7G,KAAe,EACfuL,MAAqB,EACT;QACZ,MAAM9N,SAAS,IAAI,CAACqP,SAAS,CAACC;QAC9B,MAAMhP,OAAO2N,QACXjO,QACAoJ,UAAU,QAAQ,QAAQA,UAAU,QAAQ,QAAQ;QAEtD,MAAMjH,YAAYnG,cAAcsE;QAChC,MAAMiP,aAAa1B,OAAOC,QAAQ,IAAI,CAACC,IAAI;QAC3C,MAAMtL,OAAO2G,UAAU,QAAQ,cAAc;QAC7C/M,eAAe8F,WAAW,GAAG;eACxBI,MAAM+E,OAAO,CAAC,CAAC1E,OAAS;uBACtBoL,WAAWuB;oBACd,IAAI,CAACC,SAAS,CAACxP,QAAQ4C,MAAMH;iBAC9B;eACEuL,WAAWF;SACf;QACD,OAAO3L;IACT;IAEQqN,UACNH,SAAiB,EACjBtO,KAAa,EACb0B,IAAmB,EACP;QACZ,OAAOzG,cACLiS,QAAQoB,WAAW,OACnB5M,OAAO;YAAC;gBAAC;gBAAYA;aAAK;SAAC,GAAG,EAAE,EAChC1B,QAAQ;YAAC9E,WAAW8E;SAAO,GAAG,EAAE,EAChC,IAAI,CAAC0O,KAAK;IAEd;IAEA;;;;;;GAMC,GACD,AAAQnB,sBAAsBnM,SAAqB,EAAEpB,KAAa,EAAQ;QACxE,MAAMwB,QAAQL,WAAWC;QACzB,MAAMuN,WAAWnN,MAAM3B,IAAI,CACzB,CAACgC;gBAAS/B;mBAAAA,EAAAA,UAAAA,OAAO+B,0BAAP/B,QAAcgC,WAAW,QAAO;;QAE5C,IAAI6M,UAAU;YACZ,MAAMC,WAAW1S,YAAYyS;YAC7B,KAAK,MAAM9M,QAAQL,MAAO;gBACxB,IACEK,SAAS8M,YACT,CAACvT,gBAAgByG,MAAMZ,MAAM,IAC7B/E,YAAY2F,UAAU+M,UACtB;oBACA5S,eAAe6F,MAAM7B;gBACvB;YACF;YACAhE,eAAe2S,UAAU3O;YACzB;QACF;QACA,MAAM+F,QAAQvE,KAAK,CAAC,EAAE;QACtB,IAAIuE,OAAO;YACT/J,eAAe+J,OAAO/F;YACtB;QACF;QACA,IAAI,CAACwN,QAAQ,CAACpM,WAAW;YAACpB;SAAM,EAAE;IACpC;IAEA;;;GAGC,GACD,AAAQwN,SACNpM,SAAqB,EACrByN,MAAgB,EAChBnN,IAAmB,EACb;QACN,MAAMuM,OAAO7M,UAAUL,QAAQ;QAC/B,MAAM+N,YAAYb,KAAKc,SAAS,CAAC,CAACtO,OAASA,KAAKkK,IAAI,KAAK;QACzD,IAAIqE,YAA2B;QAC/B,IAAIC,aAA4B;QAChC,IAAIH,cAAc,CAAC,GAAG;YACpB,MAAMrC,SAASwB,IAAI,CAACa,YAAY,EAAE;YAClC,IAAItT,iBAAiBiR,SAASuC,YAAYvC,OAAOlK,GAAG;YACpD,MAAM8L,OAAOJ,IAAI,CAACA,KAAKhN,MAAM,GAAG,EAAE;YAClC,IAAIzF,iBAAiB6S,SAASJ,KAAKhN,MAAM,GAAG,IAAI6N,WAAW;gBACzDG,aAAaZ,KAAK9L,GAAG;YACvB;QACF,OAAO;YACL,MAAMwK,SAASV,SAASjL;YACxB,MAAMqM,QAAQX,OAAOC,QAAQ,IAAI,CAACC,IAAI;YACtC,IAAIS,OAAOuB,YAAYvB,MAAMb,SAAS,GAAGa,MAAMZ,MAAM;YACrD,IAAIE,QAAQkC,aAAalC,OAAOH,SAAS,GAAGG,OAAOF,MAAM;QAC3D;QACA,MAAM5N,SAAShD,WAAWmF,UAAU7B,IAAI,EAAEN,MAAM;QAChD,MAAMiQ,QAAmB,EAAE;QAC3B,KAAK,MAAMlP,SAAS6O,OAAQ;YAC1B,IAAIG,cAAc,MAAME,MAAM5O,IAAI,CAACnF,iBAAiB6T;YACpDE,MAAM5O,IAAI,CAAC,IAAI,CAACmO,SAAS,CAACxP,QAAQe,OAAO0B;QAC3C;QACA,IAAIuN,eAAe,MAAMC,MAAM5O,IAAI,CAACnF,iBAAiB8T;QACrDrT,gBAAgBwF,WAAW8N;QAC3B9N,UAAUwM,WAAW,GAAG;IAC1B;IAEA;;;;GAIC,GACD,AAAQN,qBAAqBtO,OAAmB,EAAQ;QACtDA,QAAQY,UAAU,GAAGZ,QAAQY,UAAU,CAACY,MAAM,CAACjF;IACjD;IAEA;;;;GAIC,GACD,AAAQsS,aAAaU,KAAiB,EAAE1P,GAAW,EAAU;YAG9CT,0BAOX+Q;QATF,MAAMC,WAAW1T,mBAAmB6S,OAAO1P;QAC3C,IAAIuQ,aAAa,MAAM,OAAOA;QAC9B,MAAMC,QAAOjR,2BAAAA,mBAAmB,CAACS,IAAI,YAAxBT,2BAA4B;QACzC,IAAIa,SAASoQ;QACb,IAAK,IAAIC,IAAI,GAAGzT,cAAc0S,OAAOtP,YAAY,MAAMqQ,IAAK;YAC1DrQ,SAAS,GAAGoQ,OAAOC,GAAG;QACxB;QACA,MAAMH,eAAeZ,MAAM3O,UAAU,CAACY,MAAM,CAACjF;QAC7C,MAAMgU,UACJJ,iBAAAA,YAAY,CAACA,aAAalO,MAAM,GAAG,EAAE,YAArCkO,iBACAZ,MAAM3O,UAAU,CAAC2O,MAAM3O,UAAU,CAACqB,MAAM,GAAG,EAAE;QAC/ClF,aAAawS,OAAO,CAAC,MAAM,EAAEtP,QAAQ,EAAEJ,KAAK;YAC1C2Q,OAAO,UAAED,0BAAAA,OAAQC,OAAO,mBAAI;YAC5Bd,KAAK,WAAEa,0BAAAA,OAAQb,KAAK,oBAAI,IAAI,CAACA,KAAK;YAClCnC,OAAOgD,SAAShB,MAAM3O,UAAU,CAAC4M,OAAO,CAAC+C,UAAU,IAAI;QACzD;QACA,OAAOtQ;IACT;IAEA,2DAA2D,GAC3D,AAAQwQ,kBAAkBC,IAAgB,EAAc;;YAExCA;QADd,MAAMzQ,SAASvD,mBAAmBgU,MAAMvR;QACxC,MAAMuQ,iBAAQgB,oBAAAA,KAAK9P,UAAU,CAAC,EAAE,qBAAlB8P,kBAAoBhB,KAAK,mBAAI;QAC3C,MAAM/N,cAAc1B,SAChBhE,cACE,GAAGgE,OAAO,YAAY,CAAC,EACvB;YAAC;gBAAC,GAAGA,OAAO,MAAM,CAAC;gBAAE;aAAG;SAAC,EACzB,EAAE,EACFyP,SAEFzT,cACE,mBACA;YACE;gBAAC;gBAAakD;aAAI;YAClB;gBAAC;gBAAa;aAAG;SAClB,EACD,EAAE,EACFuQ;QAEN,MAAMN,MAAM/B,SAASqD;QACrB,MAAM3C,SAASD,OAAOsB,KAAK;QAC3B,MAAMC,OAAOqB,KAAK3O,QAAQ,CAAC2O,KAAK3O,QAAQ,CAACE,MAAM,GAAG,EAAE;QACpD,IAAI8L,UAAUvR,iBAAiB6S,SAASA,KAAK9L,GAAG,EAAE;YAChDjH,eAAeoU,MAAMA,KAAK3O,QAAQ,CAACE,MAAM,GAAG,GAAG;mBAC1CgM,WAAWF;gBACdpM;aACD;QACH,OAAO;YACLrF,eAAeoU,MAAMA,KAAK3O,QAAQ,CAACE,MAAM,EAAE;mBACtCgM,WAAWF;gBACdpM;mBACGsM,WAAWmB;aACf;QACH;QACAsB,KAAK9B,WAAW,GAAG;QACnB,iEAAiE;QACjE,2DAA2D;QAC3DjN,YAAYI,QAAQ,GAAGgM,SAASE,WAAWF,UAAU,EAAE;QACvD,OAAOpM;IACT;IArZA,YAAYoG,YAA0B,EAAE2I,IAAgB,CAAE;YAEtD3I,oBAQA+G;YAAAA,uBACAA;QAVF,MAAMA,QACJ/G,qBAAAA,aAAalH,IAAI,CAAC,CAACY,OAASf,MAAMe,MAAM,2BAAxCsG,qBACA,IAAI,CAAC0I,iBAAiB,CAACC;QACzB,IAAI,CAAC3I,YAAY,GAAGA,aAAa7B,QAAQ,CAAC4I,QACtC/G,eACA;eAAIA;YAAc+G;SAAK;QAC3B,IAAI,CAACA,IAAI,GAAGA;QACZ,IAAI,CAACd,IAAI,GAAG2C,gBAAgB7B;QAC5B,IAAI,CAACY,KAAK,IACRZ,iBAAAA,wBAAAA,KAAKlO,UAAU,CAACC,IAAI,CAAC,CAACJ,OAAS,CAAClE,uBAAuBkE,2BAAvDqO,sBAA+DY,KAAK,qBACpEZ,oBAAAA,KAAKlO,UAAU,CAAC,EAAE,qBAAlBkO,kBAAoBY,KAAK,YADzBZ,OAEA;IACJ;AAyYF;AAEA;;;;;CAKC,GACD,SAAS6B,gBAAgBhP,WAAuB;QAa5CA;IAZF,MAAMyN,MAAM/B,SAAS1L;IACrB,MAAMiP,aAAaxU,gBAAgBuF,YAAY,CAAC,EAAE;IAClD,MAAMkP,QAAQD,aAAavD,SAASuD,cAAc;IAClD,IACExB,OACAyB,SACAA,MAAMhD,MAAM,CAAC5L,MAAM,GAAGmN,IAAIvB,MAAM,CAAC5L,MAAM,IACvC4O,MAAMhD,MAAM,CAAC5B,UAAU,CAACmD,IAAIvB,MAAM,GAClC;QACA,OAAOgD,MAAMhD,MAAM,CAACtJ,KAAK,CAAC6K,IAAIvB,MAAM,CAAC5L,MAAM;IAC7C;IACA,MAAMqL,SACJ3L,EAAAA,sBAAAA,YAAY2L,MAAM,qBAAlB3L,oBAAoBgK,IAAI,MAAK,YAAY0B,SAAS1L,YAAY2L,MAAM,IAAI;IAC1E,IACE8B,OACA9B,UACA8B,IAAIvB,MAAM,CAAC5L,MAAM,GAAGqL,OAAOO,MAAM,CAAC5L,MAAM,IACxCmN,IAAIvB,MAAM,CAAC5B,UAAU,CAACqB,OAAOO,MAAM,GACnC;QACA,OAAOuB,IAAIvB,MAAM,CAACtJ,KAAK,CAAC+I,OAAOO,MAAM,CAAC5L,MAAM;IAC9C;IACA,OAAO;AACT"}
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright 2026 Aglyn LLC
|
|
4
|
+
*
|
|
5
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
6
|
+
* you may not use this file except in compliance with the License.
|
|
7
|
+
* You may obtain a copy of the License at
|
|
8
|
+
*
|
|
9
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
10
|
+
*
|
|
11
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
12
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
13
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
14
|
+
* See the License for the specific language governing permissions and
|
|
15
|
+
* limitations under the License.
|
|
16
|
+
*/
|
|
17
|
+
/** The default cap on one entry's inflated size. */
|
|
18
|
+
export declare const ZIP_ENTRY_READ_MAX_BYTES: number;
|
|
19
|
+
export interface ZipEntry {
|
|
20
|
+
/**
|
|
21
|
+
* The entry name. Decoded as UTF-8 whether or not bit 11 is set (4.4.4):
|
|
22
|
+
* the alternative is IBM 437, and every writer this module meets — Office,
|
|
23
|
+
* LibreOffice, Google's exporters — writes ASCII part names either way.
|
|
24
|
+
*/
|
|
25
|
+
name: string;
|
|
26
|
+
flags: number;
|
|
27
|
+
method: number;
|
|
28
|
+
crc32: number;
|
|
29
|
+
compressedSize: number;
|
|
30
|
+
uncompressedSize: number;
|
|
31
|
+
localHeaderOffset: number;
|
|
32
|
+
/**
|
|
33
|
+
* Where the entry's stored bytes begin, from the lengths in its LOCAL
|
|
34
|
+
* header (which may differ from the central record's, 4.3.7 vs 4.3.12);
|
|
35
|
+
* `-1` when the local header is missing or runs off the archive.
|
|
36
|
+
*/
|
|
37
|
+
dataOffset: number;
|
|
38
|
+
/** Bit 0 of the flags: traditional or strong encryption (4.4.4). */
|
|
39
|
+
encrypted: boolean;
|
|
40
|
+
/** The central record carries a ZIP64 extended-information field (4.5.3). */
|
|
41
|
+
zip64: boolean;
|
|
42
|
+
/** This entry's central-directory record, verbatim (a view into the archive). */
|
|
43
|
+
centralRecord: Uint8Array;
|
|
44
|
+
}
|
|
45
|
+
export interface ZipArchive {
|
|
46
|
+
bytes: Uint8Array;
|
|
47
|
+
/** In central-directory order. */
|
|
48
|
+
entries: ZipEntry[];
|
|
49
|
+
centralDirectoryOffset: number;
|
|
50
|
+
centralDirectorySize: number;
|
|
51
|
+
endOfCentralDirectoryOffset: number;
|
|
52
|
+
/** The archive comment, verbatim. */
|
|
53
|
+
comment: Uint8Array;
|
|
54
|
+
/** The archive's own end records are ZIP64 (4.3.14, 4.3.15). */
|
|
55
|
+
zip64: boolean;
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* CRC-32 as ZIP uses it (4.4.7): the reflected IEEE 802.3 polynomial
|
|
59
|
+
* `0xEDB88320`, initial value and final XOR `0xFFFFFFFF`. Pass a previous
|
|
60
|
+
* result as `seed` to continue a running checksum.
|
|
61
|
+
*/
|
|
62
|
+
export declare function crc32(bytes: Uint8Array, seed?: number): number;
|
|
63
|
+
/**
|
|
64
|
+
* Parse an archive's central directory.
|
|
65
|
+
*
|
|
66
|
+
* Returns null for anything that is not a single-disk ZIP whose central
|
|
67
|
+
* directory reads cleanly from end to end: a partial entry list is worse
|
|
68
|
+
* than none here, because a rewrite built from it would silently drop
|
|
69
|
+
* whatever was not listed.
|
|
70
|
+
*/
|
|
71
|
+
export declare function readZip(bytes: Uint8Array): ZipArchive | null;
|
|
72
|
+
/** The first entry of that exact name. */
|
|
73
|
+
export declare function findZipEntry(archive: ZipArchive, name: string): ZipEntry | undefined;
|
|
74
|
+
/**
|
|
75
|
+
* An entry's content, inflated and CRC-checked.
|
|
76
|
+
*
|
|
77
|
+
* Null for an encrypted entry, a method other than stored or deflate, a
|
|
78
|
+
* declared size over `maxBytes`, output that disagrees with the declared
|
|
79
|
+
* size, or a CRC mismatch. `maxOutputLength` stops a deflate bomb at the
|
|
80
|
+
* declared size, whatever the stream would expand to.
|
|
81
|
+
*/
|
|
82
|
+
export declare function readZipEntry(archive: ZipArchive, entry: ZipEntry, maxBytes?: number): Uint8Array | null;
|
|
83
|
+
/**
|
|
84
|
+
* Replace (or add) entries, copying everything else through verbatim.
|
|
85
|
+
*
|
|
86
|
+
* `changes` maps an entry name to its new, uncompressed content. A name the
|
|
87
|
+
* archive already holds is replaced where it stands; a name it does not is
|
|
88
|
+
* appended as a new entry after the last one, dated `options.now` (or
|
|
89
|
+
* 1980-01-01, which is what Office stamps every part with).
|
|
90
|
+
*/
|
|
91
|
+
export declare function rewriteZip(archive: ZipArchive, changes: ReadonlyMap<string, Uint8Array>, options?: {
|
|
92
|
+
now?: Date;
|
|
93
|
+
}): Uint8Array;
|